reach-edu-hub onboards to @dididecks/shell — and a deck-collections pattern worth lifting
reach-edu-hub becomes the shell's fourth consumer, joining chroma, humain, and lossless. The onboarding also produced two reusable ideas the shell doesn't have yet: deck collections (a menu layer above single-deck convergence) and a token-driven deck-primitives system — both prototyped in reach as lift candidates. The pass also surfaced one concrete shell limitation: the slot registry is keyed by variant slug alone, so sibling decks can't reuse a variant name.
Why Care?
reach-edu-hub was the last client-site standing outside the shared shell — its own deck chrome, not in the workspace, zero @dididecks/shell references. That meant every shell improvement (review TOC, in-deck ranking, the play runtime) skipped it, and any fix had to be made twice.
It now consumes @dididecks/shell like the other three client-sites. That's the headline: four consumers on one shell. The full onboarding lives in reach's own repo and changelog; this entry records the platform-level milestone and the two patterns the work generated that the shell should eventually absorb.
What's New?
reach is in the workspace. Added client-sites/reach-edu-hub to pnpm-workspace.yaml (so workspace:* resolves the shell) and bumped the submodule pointer to reach's onboarding commit. The reach repo carries the actual integration — registries, /scroll/[deck]/[variant] routes, section annotations.
A plan of record. context-v/plans/Integrate-Reach-Edu-Hub-into-Dididecks-Shell.md documents the onboarding (phases A–D, all shipped + verified) and the one design change forced along the way: client-sites consuming the shell must use Astro output: 'server', because the shell's injected routes run esbuild.transform during prerender, which a static build crashes on. (Other consumers used server for auth reasons, which masked that it's actually a shell requirement.)
Patterns to lift into the shell
Two things prototyped in reach belong in @dididecks/shell once they settle:
Deck collections — a menu layer above single-deck convergence. The shell today perfects one deck through variants; collections group several peer decks (different narratives) behind a menu. Reach implements
collections.ts+ aDeckCollectionMenucomponent + per-collection routes. Concept doc:client-sites/reach-edu-hub/context-v/explorations/Deck-Collections-A-Menu-Layer-Above-Single-Deck-Convergence.md.deck-primitives.css— a token-driven, mode-aware section vocabulary that reads only Tier-2 semantic +--fx-*tokens, so decks stay on-brand and respond to light/dark/vibrant with no per-element variant classes. The drag-and-drop convergence target.
Limitation surfaced
The shell keys the slot registry by variant slug alone (SLOTS[variantSlug]), not by deck/variant. Sibling decks therefore can't reuse a variant name (every deck wanting v1/baseline collides). reach works around it for now by keeping variant slugs globally unique; the proper fix is to scope SLOTS by deckSlug + variantSlug in apps/deck-shell. Filed as the next shared-tooling task.
What's Next?
Scope the shell's
SLOTSlookup by deck+variant.Promote
DeckCollectionMenu, thecollections.tsshape, anddeck-primitives.cssinto the shell after reach exercises them.
