Marketing site reskin — Vite + Tailwind v4 foundation + homepage port
2026-04-20
What We Built
First-pass refactor of brainstormrouter.com from a pile of 25 hand-duplicated static HTML pages into a Vite multipage build with Tailwind v4 design tokens ported from brainstorm-gtm, Handlebars partials for shared chrome, and a legacy-merge trampoline that keeps every un-ported page live during the incremental port.
Design system anchor: a new homepage using GTM's dark-graphite palette (surface-0 → surface-4), Fraunces display type, orb + conic-glow hero, staggered scroll-reveals, and glow-card mouse tracking. Six-card value grid, five-pillar governance section (Identity / Auth / Runtime / Economics / Evidence), a counterfactual-receipt proof panel, and a CTA close.
Phase 0 (infra) and Phase 1 (design system + partials) and the first page of Phase 2 (homepage) ship in this commit. 24 additional marketing pages follow in subsequent commits; they stay live via scripts/merge-legacy.mjs which fills dist/ gaps from site/legacy/.
Why It Matters
The old site was 25 separate HTML files copy-pasting the same navbar, footer, and layout markup. Any UI change was a 25-file edit; any new component was written twice before it shipped. That made the marketing surface slow to iterate and visually drifting — exactly opposite the discipline that sells a "governed control plane."
GTM's design language is the one we've been refining across the ecosystem. One visual system across brainstorm-gtm and brainstormrouter means every surface reads as one product family, and every future landing page reuses components instead of regenerating them.
How It Works
├── src/
│ ├── index.html # Vite HTML entry — includes {{> head}} {{> nav}} {{> footer}}
│ ├── _partials/ # Handlebars partials (underscore-prefixed; not scanned as pages)
│ ├── _styles/globals.css # @import "tailwindcss"; @theme { … GTM tokens … }
│ ├── _styles/components.css # nav, hero, stat-tile, feature-card
│ └── _scripts/ # TS modules: scroll-reveal, glow-card mouse-tracking, nav
├── public/ # .well-known/, llms*.txt, openapi.*, robots, sitemap — verbatim passthrough
├── legacy/ # old HTML — merged into dist/ for un-ported routes
├── dashboard/ # untouched Vite SaaS app; built separately and copied to dist/dashboard-built/
├── scripts/merge-legacy.mjs # post-vite-build step
└── vite.config.ts # multipage (rollupOptions.input from globSync) + handlebars + tailwind v4
Build pipeline (npm run build in site/):
vite build— emitsdist/index.html+ hashed CSS/JS fromsrc/*.htmlscripts/merge-legacy.mjs— walkslegacy/, copies any file not already indist/npm run build:dashboard— builds the Vite SaaS app and copies todist/dashboard-built/
Handlebars context: the plugin passes a URL-shaped path (/features/index.html), not a filesystem path — vite.config.ts normalizes to a routing key (/features) and looks up per-page title/description in a static pageMeta map. Pages not in the map fall back to generic meta.
Tailwind v4 @theme block lives inline in globals.css. No tailwind.config.ts needed — @tailwindcss/vite reads tokens directly from the CSS. Utilities like bg-surface-0, text-fg, border-[var(--ink-line)] all work without further config.
The Numbers
| Legacy | New | |
|---|---|---|
| Homepage HTML | 165 KB (2289 lines) | 22.3 KB (411 lines after handlebars resolve) |
| CSS | style.css 99 KB hand-crafted | 24.5 KB Tailwind-tree-shaken |
| JS | main.js 22 KB (inlined many concerns) | 2.2 KB (3 small modules, tree-shaken) |
| Pages sharing nav markup | 0 (all copy-pasted) | 25 (one Handlebars partial) |
Build time: ~110 ms (Vite) + ~20 ms (legacy merge).
Competitive Edge
This is table-stakes — not a shipped feature. What it unlocks: every future marketing moment (new models, a launch, a case study) becomes a single-file add in src/ instead of a copy-paste across every route. The design-system drift that plagued the old site can't recur because the tokens and partials are centralized.
Lockstep Checklist
> Marketing-only change. No API/SDK/MCP surfaces touched — lockstep N/A.
- [x] API Routes: no change.
- [x] TS SDK: no change.
- [x] Python SDK: no change.
- [x] MCP Schemas: no change.
- [x] Master Record: not a new capability; design-system refactor only.