← Corpus / dididecks-ai / plan
Init Chroma Decks Client-Site
Stand up `client-sites/chroma-decks` for an early-growth-stage portfolio company raising a round — radically improve the founder's existing materials, marry them with MemoPop-generated investment memos and market research, and use the engagement to harden the calmstorm-decks template into a reusable client-site baseline.
- Path
- plans/Init-Chroma-Decks-Client-Site.md
- Authors
- Michael Staton
- Augmented with
- Claude Code on Claude Opus 4.7
- Tags
- Plan · Client-Site · Chroma · Founder-Fundraise · MemoPop-Integration · Calmstorm-Decks-Derivative · Three-Modes-Discipline
Init Chroma Decks Client-Site
Plan of record for scaffolding
dididecks-ai/client-sites/chroma-decksas a private GitHub repo under thelossless-grouporg, derived from thecalmstorm-decksinfrastructure but rebuilt from scratch with the structural lessons baked in. The engagement is a friend-of-the-house founder fundraise — most of the round is already committed, materials are the rate-limiter, and Chroma’s existing webUI does not yet honor the three-modes (dark / light / vibrant) discipline. This plan covers init through a presentable v0.1; deck-content authoring is downstream.
Engagement context (read this first)
- Client. Chroma (the vector-DB / embeddings company). The founder is known, trusted, and a friend. We use the product.
- Fundraise posture. Early-growth stage. Most of the round is committed before materials needed to be polished — so the bar is radical improvement of an already-good story, not create from nothing under panic. The slack on timeline is real but not infinite; treat as a 1–2 week sprint, not a 6-day burn.
- Audience asymmetry. Unlike
calmstorm-decks(a VC firm pitching LPs),chroma-decksis a startup pitching VCs. Same DD-focused use case — startup DD still demands technical depth, ARR/usage curves, retention, design partners, infra economics, AI-era positioning — but the bar is a bit lower here because much of the round is already committed and the founder is trusted-relationship-funded, not cold-pitching. Pragmatic implication: no yak shaving. We move quickly, ship the scroll surface, and leave perfectionism for the next deck. - Existing prior art. Founder’s deck exists. Chroma’s brand exists. Neither follows the Lossless three-modes discipline (dark / light / vibrant) — they have a single visual register. We scaffold all three modes from day one because retrofitting tokens later causes painful refactor loops; the second and third modes will be designed in a separate, dedicated session where we iterate with the user to converge a three-mode palette that respects Chroma’s identity. Not in scope for this plan.
- MemoPop already ran on Chroma. Multiple investment-memo variants exist from prior MemoPop work. Those + the company’s own materials will live in a
corpus/folder inside the new client-site (mirrors how we putcontext-vfiles into Chroma for context-vigilance work — same pattern, inverted direction). Do not block this plan on integrating the corpus — scaffold the folder, drop the materials in later.
Pseudomonorepo discipline this plan honors
- Inline-first, submodule-when-stable. The strict pattern is “each client-site is its own GitHub repo, attached as a submodule.” For speed, we will create the GitHub repo and the submodule pointer up front (cheap to do, expensive to retrofit). The work happens on
developmentfrom minute one. See [[Init-DidiDecks-as-core-Submodule-of-AI-Labs]] for the precedent. - Three-tier branch model from day one.
development→main→master. All three branches created at repo init so we don’t pay the cost later.developmentis the working branch. - Branch alignment vigilance. Per the pseudomonorepos skill: “we need to try to keep
mainandmasterat parity over time.” Document a promotion rhythm in the changelog (Phase 6 below) rather than letting them drift silently. - Universal directories.
context-v/andchangelog/as siblings at the repo root from day one. - Rollup-readiness.
branch = developmentindididecks-ai’s.gitmodules. Conventionalcontext-v/andchangelog/shapes so the dididecks-ai splash (and ai-labs splash above it) can later surface this repo’s content via the GitHub Content API.
What we are deliberately keeping vs. rebuilding from calmstorm-decks
calmstorm-decks is the most recent, most-evolved client-site we’ve shipped. It is the substrate, not the template. We keep its primitives and rebuild its content surface with the lessons learned.
Keep (copy verbatim, then adapt)
astro.config.mjsshape — Astro 6 + Tailwind v4 via@tailwindcss/vite+@astrojs/vercelstatic + Astro Fonts API.tsconfig.json,.npmrc,.gitignore,pnpm-workspace.yamlshape.src/layouts/SlideLayout.astroandsrc/layouts/PageAsDeckWrapper.astroas the deck primitives.src/layouts/sections/pattern for reusable section wrappers.src/components/basics/andsrc/components/markdown/— generic UI atoms and LFM renderers.src/pages/api/andsrc/pages/changelog/patterns.src/pages/drafts/{slug}/{slug}-vN.astrovariant-page pattern — the non-destructive iteration discipline (Design Principle #3 of the parent spec).scripts/export-decks.ts— Playwright-based Keynote-grade export (Design Principle #6).DESIGN.mdas a Stitch-spec document. Re-author its contents for Chroma; keep the structure.context-v/directory roles (specs / explorations / narratives / changelogs / sitemap).package.jsonmetadata pattern (thecalmstorm: { ... }site-surfaces block becomeschroma: { ... }).
Rebuild (do not copy)
- All
src/pages/{topic}/route folders — those are Calm/Storm-specific surfaces (thesis, identity-pillars, fund-terms, LPAC, etc.). Chroma’s routes will reflect a startup pitch, not a fund teaser. src/slides/by-title/— entirely Calm/Storm slide variants.src/data/*.ts— calmstorm-specific structured data (LPAC members, venture team, portfolio snapshot). Chroma will have its own typed data (design partners, customers, infra metrics, team).context-v/narratives/01-…-17-*.md— the Calm/Storm slide-by-slide narrative source-of-truth. Chroma will write its own narrative set, numbered to match its slide order.draft-palette__CalmStorm.json— replaced withdraft-palette__Chroma.jsondriven by Chroma’s brand.vercel.json— verify and adapt for the new project.
Introduce (new for this engagement)
/scrolland/playare thumb-gallery indexes, not auto-launching slideshows. Both/scroll/index.astroand/play/index.astrorender a gallery of available decks (thumbnail cards with title, lede, last-updated). The user clicks a card to enter a deck. The format-namespace is not a single deck. Individual decks live at/scroll/{deck-slug}/and/play/{deck-slug}/. This pattern travels — a client engagement often produces multiple decks (teaser, full pitch, board update, audience-specific variants) and the format-index is where they coexist./scrollis the v0.1 surface — not/thesis. Calmstorm uses/thesisfor its scroll-deck routes;thesisis a fund-side word. Chroma uses/scroll— the format name travels better for a startup deck. The rate-limiter for v0.1 is:/scroll/(gallery) and/scroll/{first-deck-slug}/(one real deck) both build and render. Everything else is paced to land after this./playdeferred — pull from calmstorm-decks later. The Reveal-style “play” runtime (left/right slide-by-slide navigation, presenter mode) lives in calmstorm-decks. We do not port it during v0.1. A stub/play/index.astroexists rendering an empty gallery state (“no play decks yet”), so the route shape is reserved, but the runtime and any actual play decks are lifted from calmstorm in a later pass. Deliberate ordering: scroll first, play later, not both at once. (This is the no-yak-shave posture.)corpus/folder at the repo root. Holds MemoPop-generated investment memos, market-research artifacts, the founder’s original deck, and any source material the deck draws from. Not deployed. This is the substantiation layer — the DD-bar evidence behind every claim that surfaces insrc/. Mirrors the way we putcontext-vfiles into Chroma the database for context-vigilance work, but inverted: here Chroma-the-company’s source material lives in a folder namedcorpus/and feeds the deck. (See Phase 5 for.gitignoreposture.)- Three-modes scaffolding from day one — load-bearing. Stand up
theme.csswithlight,dark,vibrantmodes immediately. Reason: retrofitting tokens into components later causes painful refactor loops — every component has to be revisited and re-wired. Cheaper to scaffold all three slots up front, even if two are stubs, than to add the third mode after the fact. Chroma’s current visual register fills one of the three slots (TBD which — to be decided in the brand-iteration session below). - Chroma three-mode palette is OUT OF SCOPE here — separate session. Chroma’s brand does not currently carry a three-mode palette. Designing one that respects their identity is its own dedicated session with the user, not part of this scaffold plan. For v0.1, Chroma’s existing register fills one slot; the other two carry placeholder tokens marked
TBDso the build does not break. Converging the real three-mode palette is a follow-up — do not block this plan on it. - No three-modes toggle in the UI yet. Build the token system; defer the user-facing toggle until the brand-iteration session lands modes 2 and 3.
Phase 1 — Create the empty GitHub repo (private, lossless-group org)
Final location of the working tree: ai-labs/dididecks-ai/client-sites/chroma-decks/.
Final location on GitHub: https://github.com/lossless-group/chroma-decks (private).
Actions
- Create the GitHub repo via
ghwhile it is still empty. No README/license/gitignore from GitHub — we will seed those locally in Phase 2.gh repo create lossless-group/chroma-decks --private --description "Chroma · founder fundraise materials — Astro-driven, private, gated workspace presenting the company's positioning, traction, team, and round terms to a controlled audience of prospective VCs." - Verify the repo exists and is private.
gh repo view lossless-group/chroma-decks --json visibility,defaultBranchRef - Do not clone yet. Phase 2 builds the working tree locally, then pushes.
Constraints / verification
- Confirm
gh auth statusis logged in under the user (mpstaton) withlossless-grouporg access. (Already true per the user’s note.) - Default branch on GitHub will get overwritten when we push
developmentin Phase 3 — don’t worry about it beingmainat creation.
Phase 2 — Scaffold the working tree locally (copy-then-strip from calmstorm-decks)
Goal: A buildable Astro project at ai-labs/dididecks-ai/client-sites/chroma-decks/ with the calmstorm primitives kept, the calmstorm content stripped, and the Chroma-specific stubs in place.
Actions
- Create the directory under
client-sites/.mkdir -p ai-labs/dididecks-ai/client-sites/chroma-decks - Copy the keep-list from
calmstorm-decks(see the “Keep” section above). Usecp -Rfor directories; copy files individually so we are intentional.- Config files:
astro.config.mjs,tsconfig.json,.npmrc,.gitignore,pnpm-workspace.yaml,vercel.json,.env.example. src/layouts/(the whole folder).src/components/basics/,src/components/markdown/(skipsrc/components/slides/— those are calmstorm-specific).src/pages/api/,src/pages/changelog/,src/pages/drafts/(keep folder, replace contents with a placeholder draft).src/styles/— keep token scaffolding (theme.css,globals.css), strip calmstorm palette specifics.scripts/export-decks.ts.
- Config files:
- Strip calmstorm-specific content. Delete all
src/pages/{topic}/folders exceptapi/,changelog/,drafts/. Deletesrc/slides/. Deletesrc/data/*.ts. Deletecontext-v/narratives/*. Deletedraft-palette__CalmStorm.json. Note/thesisgoes — Chroma uses/scrollinstead (see step 3a below). 3a. Stand up/scrolland/playas thumb-gallery indexes plus one real/scrolldeck.src/pages/scroll/index.astro— renders a thumbnail gallery of available scroll decks. Cards show title, lede, last-updated, and a thumbnail image (placeholder svg for v0.1; real thumbs come later). Pulls from a typedsrc/data/decks.ts(or Astro content collection) so adding a deck is a data-only change.src/pages/scroll/{deck-slug}/index.astro— at least one real deck route at v0.1 (pick a working slug, e.g.chroma-fund-iv-teaseror whatever the founder’s current deck is named). This is wherePageAsDeckWrapper.astro+SlideLayout.astroactually compose into a scroll deck. Empty-but-valid is fine for v0.1; content lands in the next plan.src/pages/play/index.astro— renders an empty-state thumbnail gallery (“no play decks yet — coming after/scrolllands”). Route reserved; runtime deferred.src/pages/index.astro— minimal landing page linking to/scrolland/play.- Thumbnail asset convention: thumbs live at
public/thumbs/{deck-slug}.{webp|svg}; the data file points at them. SVG placeholders for v0.1 to keep moving — real thumbs (Playwright screenshots of slide 1, à la calmstorm’sexport-decks.ts) are a later pass. - Do not build variant pages or slide-by-slide chooser routes yet — those come from calmstorm-decks in a later pass.
- Rewrite
package.json— rename tochroma-decks, version0.0.1.0, keywords reframed for Chroma fundraise,chroma: { ... }block describing site surfaces (TBD pending narrative outline), homepage TBD (Vercel preview will populate). - Rewrite
DESIGN.mdas a Chroma-flavored Stitch spec. Source values are already extracted in [[../explorations/Chroma-Brand-and-Deck-Notes]] (color tokens from production CSS, typography, geometry, anti-patterns). Promote that file’s §2–§7 substance intochroma-decks/DESIGN.md. Thelightmode carries the real production values;darkandvibrantare documentedTBDslots awaiting the brand-iteration session. Note: trychroma.com uses shadcn-style semantic tokens (--background,--foreground,--primary, etc.) not Material/M3 (surface,on-surface); chroma-decks adopts the shadcn shape (see notes §1 for the rationale). (Invokemaintain-design-mdskill when writing this.) - Create
draft-palette__Chroma.jsonwith the extracted tokens (mirrors the table in notes §2). Save the wordmark fromhttps://www.trychroma.com/_next/static/media/chroma-wordmark.0~1c352v-zy35.svgtopublic/brand/chroma-wordmark.svg. - Stub
context-v/with the conventional subdirectories:specs/,explorations/,narratives/,changelogs/,sitemap/. Empty except for aREADME.mdin each explaining its role (lifted from thecontext-vigilanceskill). - Stub
changelog/at the repo root with an inaugural entry:changelog/2026-05-11__chroma-decks-init.md. Follow thechangelog-conventionsskill format. - Create
corpus/at the repo root with aREADME.mdexplaining it holds investment memos, market research, and the founder’s original materials. Addcorpus/to.gitignorefor now — we will decide later whether parts of it should be committed (likely not; this is the private substantiation layer, not part of the deployed site). Note: this is intentionally distinct fromsrc/andcontext-v/. - Install dependencies with pnpm to make sure the scaffolded
package.jsonresolves cleanly.cd ai-labs/dididecks-ai/client-sites/chroma-decks pnpm install pnpm run build # confirm the empty-shell scaffold compiles
Constraints / verification
- The empty shell must
pnpm run buildcleanly before Phase 3. Do not push a broken scaffold. - No calmstorm content should be reachable in a grep over
client-sites/chroma-decks/src/. (grep -r -i "calmstorm\|calm/storm\|EuVECA\|Fund III" src/should return zero hits.)
Phase 3 — Init git, three-tier branches, push to GitHub
Goal: Working tree under git, three branches (development, main, master) all pointing at the same inaugural commit, pushed to the remote.
Actions
git initinsideclient-sites/chroma-decks/.- Stage and commit the inaugural scaffold. Commit message per
git-conventionsskill.git add . git commit -m "init(scaffold): chroma-decks derived from calmstorm-decks substrate Scaffolds the chroma-decks client-site as a private Astro project under lossless-group/dididecks-ai/client-sites/. Keeps the calmstorm-decks structural primitives (layouts, draft-variant pattern, export script, three-modes-aware theme.css) and rebuilds the content surface (pages, slides, narratives, data) from scratch for the Chroma fundraise. " - Create all three tier branches from this single commit so they start at parity.
git branch -M development # rename default to development git branch main development git branch master development - Add the remote and push all three branches.
git remote add origin git@github.com:lossless-group/chroma-decks.git git push -u origin development git push origin main git push origin master - Set
developmentas the default branch on GitHub.gh repo edit lossless-group/chroma-decks --default-branch development
Constraints / verification
git log development main master --onelineshould show all three tips at the same commit.gh repo view lossless-group/chroma-decks --json defaultBranchRefshould reportdevelopment.
Phase 4 — Attach as a submodule of dididecks-ai
Goal: dididecks-ai/.gitmodules carries an entry for client-sites/chroma-decks with branch = development, the gitlink commits cleanly, and git submodule status reports the working-tree commit.
Actions
- From the
dididecks-airepo root (one level up),cdand run:
This will (a) clone the remote into the existing path if the path is empty or (b) recognize the existing local tree ifcd ai-labs/dididecks-ai git submodule add -b development git@github.com:lossless-group/chroma-decks.git client-sites/chroma-decksgit submodule adddetects it. If the local tree already exists andsubmodule addrefuses, the safe path is:- Move the working tree aside (
mv client-sites/chroma-decks /tmp/chroma-decks-stash), - Run
git submodule add -b development ...to clone fresh, - Confirm the clone matches the stashed tree,
- Delete the stash.
- Move the working tree aside (
- Verify
.gitmodulescarriesbranch = developmenton the new entry. If missing, add it manually and rungit submodule sync. - Commit the submodule add at the
dididecks-ailevel.git add .gitmodules client-sites/chroma-decks git commit -m "add(submodule): client-sites/chroma-decks tracking development" - Do NOT auto-bump the parent ai-labs gitlink. Per the user’s submodule-propagation feedback, the parent pseudomonorepo’s gitlink is tidied deliberately, not as a side effect. Leave
ai-labs’s pointer alone.
Constraints / verification
git submodule status client-sites/chroma-decksshows the SHA, the path, and the tracked branch.cat .gitmodules | grep -A2 chroma-decksincludes abranch = developmentline.
Phase 5 — Wire the corpus, environment, and Vercel preview
Goal: The substantiation layer is in place (even if mostly empty), env conventions are documented, and there is a live preview URL to iterate against.
Actions
corpus/posture. Add to.gitignore. Document its role incorpus/README.md:- Holds the MemoPop-generated Chroma investment memos (multiple variants).
- Holds the founder’s original deck and any raw materials he shares.
- Holds market-research artifacts surfaced during the engagement.
- Is the DD-bar substantiation layer. Every non-obvious claim in
src/should be traceable to acorpus/source. - Is not deployed. Decide later whether selected corpus items get committed in a separate private mirror; default is git-ignored.
.env.examplecarries placeholder rows forSITE_URLand any future LLM/API keys. No secrets committed.- Vercel project setup.
- Create a new Vercel project linked to
lossless-group/chroma-decks. - Default deployment branch:
development(so the preview URL tracks active work). - Production branch:
main(so promotion is deliberate). - Add
SITE_URLto the Vercel env panel once the production domain is decided.
- Create a new Vercel project linked to
- Confirm the first preview deploy lands cleanly. A blank-but-buildable Astro shell should produce a preview URL.
Constraints / verification
- The preview URL is reachable and renders the placeholder homepage.
.gitignoreincludescorpus/(andnode_modules/,.env,.DS_Store, etc. inherited from calmstorm-decks).
Phase 6 — Establish the working rhythm (and document main/master parity)
Goal: A documented rhythm for how this engagement runs day-to-day, including the discipline for keeping main and master near parity over time (per the user’s note).
Actions
- Write
context-v/specs/Working-Rhythm-Chroma-Decks.md— short, lived-with doc that captures:- Daily working branch is
development. - Promote
development→mainwhen a milestone is presentable (an investor sees it, founder signs off on a section, etc.). - Promote
main→masterwhen the dust has settled — usually after the meeting it was prepped for has happened and the next round of edits has not yet kicked off. Cadence target: at minimum weekly during active iteration, immediately after each milestone meeting. - Parity bias: when in doubt, fast-forward
mainandmasterup — never roll them backwards. If divergence appears, stop and reconcile rather than papering over.
- Daily working branch is
- Inaugural changelog entry at
chroma-decks/changelog/2026-05-11__init.mdreferences this spec. - Reflective entry at the parent level — once the scaffold is shipped, write a short note in
dididecks-ai/context-v/explorations/Client-Site-Baseline-v2.mdcapturing what we kept, what we dropped, and what we changed betweencalmstorm-decksandchroma-decks. This is the closure of the “we keep rebuilding from scratch” loop the parent spec ([[../specs/Dididecks-AI-Slide-Decks-as-Code]]) calls out. The third client-site we scaffold should start from this exploration, not from another fresh copy of calmstorm.
Constraints / verification
Working-Rhythm-Chroma-Decks.mdexists with the parity rule written down.Client-Site-Baseline-v2.mdexists and links both upstream specs (the Dididecks parent spec) and downstream sites (calmstorm-decks, chroma-decks).
Out of scope (explicitly deferred — no yak shaving)
These are real, but not this plan. Timeline is short; the goal is /scroll shippable, not perfect.
/playruntime. Reveal-style slide-by-slide navigation, presenter mode, keyboard nav. Pull from calmstorm-decks in a later pass, after/scrollis presentable.- Variant pages (
/drafts/{slug}/{slug}-vN). Pattern is kept in the scaffold (folder exists) but no variants are authored in v0.1. - Slide-by-slide variant chooser routes (
/{slug}per slide). Calmstorm’s pattern; deferred until needed. - Deck content authoring. Narratives, slides, data structures — all downstream of this scaffold. A separate plan or spec frames the slide-by-slide content sprint once
/scrollis live. - Chroma three-mode palette design. Dedicated session with the user. The token system is scaffolded here; the palette values for modes 2 and 3 are decided separately.
- Three-modes UI toggle. Token system is built; user-facing toggle waits on the palette-iteration session.
- MemoPop integration mechanics. The
corpus/folder is provisioned; how MemoPop outputs flow into the deck is its own design. - Native-app side (NS-1) and live-player (NS-2). Per the parent spec, these are the DidiDecks-AI north stars, not this engagement.
- Splash page for chroma-decks itself. A
splash/directory is not part of v0.1. If the dididecks-ai splash needs to surface chroma-decks, it does so via rollup, not by chroma-decks shipping its own splash.
Risks and mitigations
| Risk | Mitigation |
|---|---|
| Brand mismatch — Chroma’s existing visual register is not three-modes-aware; pushing all three modes from day one may feel like overreach to the founder. | Build the three-mode token system internally; ship only their current register in the UI; introduce light/vibrant only after a directed proposal he approves. |
| Calmstorm primitives carry hidden Calm/Storm assumptions that are not obvious in copy-then-strip. | Phase 2 verification step: grep -r -i "calmstorm|calm/storm|EuVECA|Fund III" src/ must be empty before Phase 3 commit. |
| The corpus folder grows large quickly (PDFs, transcripts, video clips). Adding it to git would balloon the repo. | corpus/ is .gitignore’d. Substantiation tracking happens via filename references in narratives/data, not via committing the source material. |
development / main / master drift starts immediately and never gets caught up. | Phase 6 writes the parity rhythm down. The reflective entry at the dididecks-ai level (Client-Site-Baseline-v2.md) explicitly captures whether the rhythm held — feedback for the next client-site. |
Submodule pointer in dididecks-ai gets out of sync with the working branch. | .gitmodules declares branch = development. Verification step in Phase 4 enforces it. |
Done definition (for v0.1 of this plan)
https://github.com/lossless-group/chroma-decksexists, private, default branchdevelopment, three tier branches at parity.- Working tree at
ai-labs/dididecks-ai/client-sites/chroma-decks/builds cleanly withpnpm run build. /scroll/renders a thumb-gallery index (at least one card visible),/scroll/{deck-slug}/renders one empty-but-valid scroll deck, and/play/renders an empty-state gallery (“no play decks yet”). All three routes resolve inpnpm run devand in the Vercel preview. This is the load-bearing v0.1 signal — without it, nothing else matters.- Calmstorm content fully stripped; Chroma-flavored DESIGN.md and palette in place; three-modes tokens scaffolded in
theme.csswith all three slots present even though only one is filled with real values (the other two areTBDplaceholders, settled in a follow-up session). corpus/exists, is git-ignored, has a README explaining its role.- Submodule entry in
dididecks-ai/.gitmodulescarriesbranch = development. - Vercel preview URL is live and shows the empty-but-buildable shell with
/scrollreachable. context-v/specs/Working-Rhythm-Chroma-Decks.mddocuments the development → main → master parity rhythm.dididecks-ai/context-v/explorations/Client-Site-Baseline-v2.mdcaptures the kept/dropped/changed delta vs. calmstorm-decks.
When all nine are true, Phase 1 of the engagement is done. Deck-content authoring (and /play port from calmstorm-decks) begins under a separate plan.