Humain Ventures onboarded as the third DidiDecks client — and the onboarding surfaced six shell-worthy primitives that had been trapped in chroma-decks since the carve-out
A new TechBio investor (humain.vc) became the third client deck. The full Fund I deck — 29 slots, three competing design variants — landed end-to-end against a shell consumption contract. But the onboarding also surfaced a structural drift: six deck-generic primitives (scroll-snap + keyboard nav, per-slide shell, mode toggle + runtime, registry-derivation lib, build-status matrix) had been built inside chroma-decks before the @dididecks/shell carve-out and never lifted, so every new client risked re-implementing or copy-pasting. All six are now in the shell, humain consumes them via clean @dididecks/shell imports, and a three-mode theme architecture bug that made the mode toggle a visible no-op got named, fixed, and codified as a per-client invariant. Chroma's own migration off its local copies is deferred until humain validates the lifted versions in browser.
Why Care?
DidiDecks now has three clients in flight — calmstorm-decks, chroma-decks, humain-vc-decks — and onboarding the third surfaced a problem the first two never caught: the shared shell wasn't actually that shared. Several deck-generic primitives — scroll-snap pagination, arrow-key navigation, the section counter, the per-slide shell wrapper, the three-mode site toggle and its runtime, the registry-derivation utility that powers landing dashboards — had all been built inside client-sites/chroma-decks/src/ before apps/deck-shell/ was carved out, and never got lifted. As long as chroma was the only client-site, this was invisible. Onboarding humain made it visible the moment the dev server booted: the variants rendered, but there was no keyboard nav, no scroll-snap, no section counter, and the mode toggle clicked silently with no repaint.
Six components, one runtime, one lib, and one architectural fix later, every one of those gaps is closed and the shell finally is what it always claimed to be — the single home for behaviors that belong to "the deck" rather than "this client's branding." The next client onboards into a much shorter scaffolding sequence and inherits all six primitives for free. Chroma still runs against its local copies and is uninterrupted; its migration is held until humain validates the lifted versions in browser.
The practical upshot:
A third client is in the tree. humain-vc-decks (
https://github.com/lossless-group/humain-vc-decks) — private repo, trackingdevelopment, full DESIGN.md derived from humain.vc's production CSS bundle, three competing scroll-deck variants (proto/tech-bio-canon/lab-notebook), 29 slots each, content sourced from one canonical narrative file (context-v/narratives/Humain-Deck-Content.md) per chroma-style discipline.Six primitives lifted into the shell. PageAsDeckWrapper (scroll-snap + keyboard contract), SlideShell (per-slide wrapper with consumer-pluggable mark slot), ModeToggle + mode-switcher (per-client localStorage namespace), SlideStatusMatrix (sibling to existing DeckMatrix; reads DeckOverview), deck-overview lib. All ddd-prefixed CSS, all themable via
--ddd-*token fallback chains, all importable as@dididecks/shell/{components,runtime,lib}/*.Three-mode theme architecture got an invariant. humain's first cut of
theme.csshad empty[data-mode="dark"]and[data-mode="vibrant"]blocks; the toggle visibly did nothing because:rootcarried the light values and absent declarations don't override. Fixed in theme.css, codified in humain's DESIGN.md as a frontmattermodes:block + a load-bearing "Architectural invariant" prose section, and saved to user-level memory asfeedback_three-mode-theme-architectureso the same bug can't ship on the fourth client.
What's New?
At the deck-operating-system tier
@dididecks/shellnow ships scroll-deck pagination.apps/deck-shell/src/components/PageAsDeckWrapper.astro— promoted fromchroma-decks/src/layouts/PageAsDeckWrapper.astro(commitc87c643). Deliversscroll-snap-type: y mandatory, the full keyboard contract (↑/↓,PageUp/Down,Home,End,cchrome toggle,ffullscreen), double-click step, the floatingNN / totalsection indicator,#s-Nhash-jump on load,.reveal-itemIntersectionObserver, and thedeck:section-changed/deck:section-prev/deck:section-nextevent protocol that letsDeckChromebuttons drive the same nav as keyboard / scroll. CSS classes prefixedddd-*; theming via--ddd-scroll-*tokens with fallbacks so consumers aren't required to declare them.@dididecks/shellnow ships the per-slide wrapper.apps/deck-shell/src/components/SlideShell.astro— promoted from chroma. The original hard-coded<ChromaMark>; the shell version exposes<slot name="mark">so consumers plug their own wordmark (or omit it). Sameddd-slide-*class prefix discipline and--ddd-slide-*token fallback chain.@dididecks/shellnow ships the three-mode toggle + its runtime.apps/deck-shell/src/components/ModeToggle.astro+apps/deck-shell/src/runtime/mode-switcher.ts— promoted from chroma'ssrc/components/basics/ModeToggle.astro+src/utils/mode-switcher.js. Rewritten as a TS factorycreateModeSwitcher({ client, defaultMode, respectSystemPreference }). Theclientargument becomes the localStorage namespace ({client}:mode) so multiple decks on the same domain don't collide on mode persistence.defaultModeandrespectSystemPreferenceare per-client knobs so a light-canon brand doesn't get a dark first-visit just because the OS is in dark mode.@dididecks/shellnow ships the deck-overview lib.apps/deck-shell/src/lib/deck-overview.ts— promoted from chroma'ssrc/lib/deck-overview.ts. ReadsdecksRegistryPath+slidesComponentsRootfrom the resolved shell options onglobalThis.__dididecksShellOptionsinstead of importing the consumer's TS registries directly, so any client-site can callloadDeckOverview("pitch")without the shell knowing the consumer's import paths. Chroma's substantiation counts (people, headshots, investor firms, portfolio companies) were dropped from the shell version — those are per-client substantiation layers.@dididecks/shellnow ships the build-status matrix as a sibling to DeckMatrix.apps/deck-shell/src/components/SlideStatusMatrix.astro— promoted from chroma. Lightweight slot × variant rollup showing static-port readiness via glyphs (●static /◐legacy /◯registered /·absent). Reads theDeckOverviewshape produced bylib/deck-overview. Distinct fromDeckMatrix(which is the production audit/review surface — dual-surface ratings, TOC integration); they're siblings, not duplicates, and the plan documents which is which.@dididecks/shellpackage exports./lib/*. Added toapps/deck-shell/package.jsonsoimport { loadDeckOverview } from "@dididecks/shell/lib/deck-overview"resolves. Existing./components/*and./runtime/*exports were already there.pnpm-workspace.yamlincludes humain-vc-decks. Workspace registration so@dididecks/shell: "workspace:*"resolves on humain's side without copying the shell into the submodule.A 5-phase plan documents the lift backlog.
context-v/plans/Lift-Chroma-Decks-Generic-Code-into-Shared-Shell.md— names the bug ("chroma was built before the shell carve-out; not everything got lifted"), enumerates the audit list, scopes each phase's risk + acceptance criteria, and explicitly defers the chroma migration (Phase 3) until humain's consumption of the lifted versions is verified in browser. Phases 1, 2, 4, 5 shipped tonight; Phase 3 is held.
Inside humain-vc-decks (the substantive engagement install)
Repo created and registered as a submodule.
https://github.com/lossless-group/humain-vc-decks— private, default branchdevelopment, registered in the parent's.gitmodulesandpnpm-workspace.yaml.DESIGN.md derived from humain.vc's production CSS. Vite-built SPA; extracted the CSS bundle (
/assets/index-zwbOMG5o.css), pulled the shadcn-style HSL tokens, hex-equivalents-ed them into Tier-1 named tokens, mapped semantic Tier-2, recorded the source URLs + fetch timestamp + extraction notes incontext-v/explorations/Humain-Brand-and-Deck-Notes.md. Two-color identity captured: deep-navy#0a1326+ bio-green#29a380, plus pale-green accent. Typography: Space Grotesk (display) + Inter (body). Brand voice: TechBio-credible, pull-quote-forward.Three competing scroll-deck variants authored end-to-end. All 29 slots, all three variants:
proto— faithful PDF recreation. White surfaces, gray text, hairline borders. The baseline.tech-bio-canon— humain.vc visual vocabulary applied literally. Deep-navy gradient heroes alternating with off-white card sections, bio-green eyebrows, Space Grotesk display, pull-quote treatment on the Schmidt/Huang/Jobs chorus.lab-notebook— scientific-editorial direction. Monospace breadcrumb headershumain-ventures / pitch / lab-notebook / slot-NN,§Nsection numbers, hairline rules,dl/dt/ddmetadata, ASCII bio-pipeline diagram on the architecture slot, bio-green as margin-rule color only.
Content sourced from one canonical markdown file.
context-v/narratives/Humain-Deck-Content.md— 29 slots, PDF-verbatim. The three variant.astrofiles consume from it; they diverge in presentation, not content. Matches chroma'scontext-v/narratives/slides/discipline (one file vs. 29 small files chosen for initial-pass efficiency; can split per-slot later).Scroll-snap + keyboard nav landed via shell import. All three variant
.astrofiles wrap their sections in<PageAsDeckWrapper>imported from@dididecks/shell/components/PageAsDeckWrapper.astro. The narrow editorial column inlab-notebookis preserved via a scoped<style>rule onsection[data-variant="lab-notebook"](the oldmax-w-4xl mx-autolived on the now-removed<main>).Landing page wires ModeToggle + SlideStatusMatrix + loadDeckOverview from the shell. First fresh consumer of those three primitives — validates that the lifts work for a greenfield client that never had local copies to fall back on.
Three-mode theme architecture fixed and documented as an invariant. The original
theme.csshad:root, [data-mode="light"] { /* full mapping */ }paired with[data-mode="dark"] {}and[data-mode="vibrant"] {}empty stubs. The toggle was running but:root's light values won by default and no Tier-2 token actually changed. Refactored to three parallel mode rules — same keyset, different Tier-1 references per mode. Added Tier-1 tokens that dark/vibrant required (humain_void_black,humain_bio_green_vivid,humain_border_vivid, etc.). DESIGN.md now carries a structuredmodes:frontmatter block specifying the per-mode Tier-2 +--fx-*mappings; thetheme.cssruntime mirrors that block 1:1. A new "Architectural invariant" prose section names the bug and the rule for future-Claude. Saved to~/.claudememory asfeedback_three-mode-theme-architectureso the invariant is enforced on every future client-site onboarding, not just this fix.Auth installation is its own next plan.
client-sites/humain-vc-decks/context-v/plans/Install-Auth-Surface-from-Calmstorm-Pattern.md— full port path from chroma's auth surface (middleware + astro + arctic OAuth + magic-link + passcode), withhumain.vcseeded alongsidelossless.groupas orgs per the domain-as-id convention. Held until a deck variant is presentable enough to gate.
What's Held
Chroma migration off its local copies (Phase 3 of the lift plan). Held until humain's consumption is verified in browser. When unblocked, the cleanest path is thin shim re-exports at chroma's original local paths (
src/layouts/PageAsDeckWrapper.astro,src/utils/mode-switcher.js, etc.) so chroma's 20+ files that import those paths don't need updating; only the implementation comes from the shell. Local files get deleted only after parity is verified end-to-end.Auth surface for humain-vc-decks. Per the deck client convention, install when a variant is presentable enough to gate (v0.2). The plan is authored; the work hasn't started.
AssetsDataPanel.astroaudit (the one chroma component the lift plan marked as "needs inspection"). Separate inspection pass.
What's Next
Verify humain in browser. All four shell consumption surfaces — scroll-snap + keyboard nav across the three variants, ModeToggle cycling all three modes with visibly distinct results, SlideStatusMatrix on landing, scroll-page sections matching the
data-slotannotations the shell's slot scanner picks up.Run Phase 3 of the lift plan once humain is green — chroma's 20+ files swap implementations transparently via shim re-exports; the production deck keeps working.
First brand-iteration session for humain dark + vibrant modes. Currently first-pass scaffolds (functionally present but unrefined). DESIGN.md's
modes_iterated: [light]tracks the remaining work.Install the auth surface for humain per its dedicated plan.
