Options — showcase website candidates
Four genuinely different shapes for the internal showcase site (program overview + 5 factory product pages), all sourced from the existing markdown corpus in plans/ + research/ (86 files, ~13.9k lines, GFM tables + 43 mermaid fences, zero Obsidian-specific syntax — so GFM + mermaid fidelity is the requirement, Obsidian fidelity is not). Common frame shared by every candidate:
- Content plane — the existing md files, never modified for the site’s sake.
- Presentation plane — a new
site/directory holding everything the candidate installs or builds. - Curation layer — explicit include/exclude config enforcing the confidential exclusions (
analysis/monorepo-development/,research/11,research/14,repos/never).
A is the do-less vault-publish lane; B is the bespoke curated lane; C is the house-stack lane; D is the markdown-native lane. Cost estimates are DESIGN-gated throughout: “per new page” means a page that has passed the impeccable/anti-template review, not a first draft.
Option A — Quartz v5 sidecar (vault-publish, do-less lane)
Essence: site/ is a pinned clone of jackyzha0/quartz (v5 branch, 12.8k stars, MIT). content/ holds symlinks to ../plans and ../research (plus analysis/legacy/SYNTHESIS.md and docs/llm-runs.md); ignorePatterns / ExplicitPublish handle the confidential excludes. The whole wiki chrome — full-text search, graph view, backlinks, file explorer — comes free. Product pages are custom Preact components / page types written against the new v5 API. Serve: npx quartz build --serve on :8080. Known friction: v5 shipped in 2026, post-training-data, so agents write against an API they have not seen; and the corpus uses none of Quartz’s Obsidian superpowers (no wikilinks, no callouts), so the tool’s core value proposition is partially unused.
flowchart LR
subgraph CP[content plane - untouched]
P[plans/]; R[research/]; S[analysis/legacy/SYNTHESIS.md]; L[docs/llm-runs.md]
end
subgraph SITE[site/ - pinned quartz v5 clone]
SYM[content/ symlinks]; IG[ignorePatterns +<br/>ExplicitPublish excludes]
Q[quartz build<br/>md -> Preact SSG]; PP[custom Preact<br/>product page types]
WC[free wiki chrome:<br/>search / graph / backlinks / explorer]
end
CP --> SYM --> IG --> Q --> PP & WC --> D[(public/ static)]
D --> SV[quartz --serve :8080]
Boundary map
- Content plane: untouched — symlinks only, nothing copied or rewritten.
- Presentation plane: the entire (near-forked) Quartz clone; upstream upgrades arrive as git merges against a pinned base.
- Curation layer:
ignorePatterns/ ExplicitPublish insidequartz.config.ts— excludes live in one site-config file, one place to audit.
Test seams
- Build-as-test:
quartz buildfails on broken markdown; the build is the first gate. - Link check: Quartz’s own broken-link handling, plus a small crawl script over
public/for anchors. - Mermaid: renders natively client-side — a real render check needs a headless page-load pass, not just a green build.
- Visual gate: impeccable skill against served pages; caveat — the post-cutoff Preact/v5 component model is the least familiar surface of the four for agents iterating on design.
Evolution path / exit cost
- Evolution: lean into wiki features (backlinks, graph) if the corpus ever grows wikilinks; ceiling = fighting Quartz’s docs-site opinions when product pages need fully bespoke design.
- Exit: cheap — content was never touched; delete
site/, keep nothing.
Rough cost (estimates, design-gated)
- Install-to-first-page: ~1–2 h — clone, pin, symlinks, excludes, first build; the wiki chrome means the library view is done at that point.
- Per new product page: ~2–4 h — the page itself is fast, but clearing the anti-template bar inside an unfamiliar post-cutoff Preact API is where agent time goes; budget extra impeccable-gate iterations.
Option B — Astro 7 + Tailwind v4 bespoke (curated product pages)
Essence: site/ is an Astro 7.1 app. Content Layer glob() loaders with base: ../plans and ../research — out-of-tree content is documented first-class, no symlinks needed. Markdown pipeline pinned to @astrojs/markdown-remark (restores the remark/rehype ecosystem, avoids Satteri’s newness) + astro-mermaid + Tailwind v4 via @tailwindcss/vite, with design tokens locked in a DESIGN.md. Pages: program overview, /products/<x> as hand-crafted .astro pages composing collection entries, /library/* auto-rendering the full included corpus. Output = static dist/; authoring loop = astro dev --background (7.0 shipped this explicitly for AI agents); serve via python http.server or a systemd –user unit. Known agent failure modes — the deprecated @astrojs/tailwind reflex, Satteri/remark confusion, the legacy collections API — are all pinnable in CLAUDE.md.
flowchart LR
subgraph CP[content plane - untouched]
P[plans/]; R[research/]
end
subgraph SITE[site/ - Astro 7.1 app]
GL[Content Layer glob loaders<br/>base: ../ + exclude patterns]
MR[markdown-remark pinned +<br/>astro-mermaid + Tailwind v4 vite]
DT[DESIGN.md-locked tokens]
PR[/products/x hand-crafted .astro/]; LB[/library/* auto-rendered corpus/]
end
CP --> GL --> MR --> PR & LB --> D[(dist/ static)]
DT -.constrains.-> PR
D --> SV[http.server or systemd-user unit :8080]
Boundary map
- Content plane: untouched — no symlinks; loader
basepoints out of tree, documented first-class. - Presentation plane:
site/withDESIGN.md-locked tokens; product pages are composed.astrofiles, library pages are one dynamic route. - Curation layer: glob include/exclude patterns in
content.config.ts, colocated with the loaders that consume them.
Test seams
- Build-as-test:
astro buildfails loudly on bad frontmatter or collection misuse — good failure legibility for agents. - Link check: rehype plugin in the pinned pipeline, or a dist crawl script.
- Mermaid:
astro-mermaid— checkable at build if pre-rendered, else one headless pass overdist/. - Visual gate: impeccable against the dev server;
.astro+ Tailwind is a surface agents iterate quickly, and the token lockfile gives the anti-template rule teeth.
Evolution path / exit cost
- Evolution: islands/SSR adapters if interactivity is ever needed; each product page hardens into a reusable pattern library for the next one.
- Exit: delete
site/; content andDESIGN.mdsurvive as plain files. Sunk cost = the.astropages themselves.
Rough cost (estimates, design-gated)
- Install-to-first-page: ~2–4 h — scaffold, pin the pipeline, loaders + excludes,
DESIGN.md, first overview page through the gate. - Per new product page: ~1–2 h once tokens and the first exemplar page exist; the known failure modes must be pinned in
CLAUDE.mdor agents burn the savings on the deprecated-integration reflex.
Option C — Next.js 16 static export (house stack)
Essence: site/ is a Next 16.2 app with output: 'export'. Content via the content-collections library, or a ~100-line fs+remark pipeline. Product pages are React components — the one candidate with possible component sharing with velin (house stack is Next; the Groupon monorepo is Next). Everything markdown is DIY: mermaid, GFM pipeline, link handling all assembled by hand. Footprint ~300–500 MB node_modules; Next’s monthly security-patch cadence applies even to a static internal site. Evolution is the headline: flip output: 'export' off and it becomes a full app with zero migration.
flowchart LR
subgraph CP[content plane - untouched]
P[plans/]; R[research/]
end
subgraph SITE[site/ - Next 16.2, output: export]
CC[content-collections lib or<br/>~100-line fs+remark pipeline<br/>+ hand-rolled exclude list]
MM[DIY md assembly:<br/>GFM + mermaid + links]
RP[React product pages<br/>possible velin component sharing]
end
CP --> CC --> MM --> RP --> D[(out/ static)]
D --> SV[http.server :8080]
Boundary map
- Content plane: untouched — read by the pipeline at build time.
- Presentation plane:
site/React components, sharing design language (and possibly components) with the rest of the house stack. - Curation layer: the exclude list inside the DIY content pipeline — hand-rolled code, so it must be tested, not just configured.
Test seams
- Build-as-test: the export fails on bad pages, though Next build errors are the least legible of the four candidates.
- Link + mermaid checks: fully DIY — the hand-rolled pipeline needs its own small test suite.
- Confidentiality check: mandatory here — one assert that no excluded path ever reaches
out/, because the fence is bespoke code rather than a framework config key. - Visual gate: impeccable against
next dev; React is maximum agent familiarity, the fastest design-iteration loop of the four.
Evolution path / exit cost
- Evolution: best-in-class — flip export off → full app, zero migration; components portable to velin.
- Exit: delete
site/, but sunk cost is the highest (the DIY pipeline is owned bespoke code), and staying costs a monthly patch cadence + the heaviest install.
Rough cost (estimates, design-gated)
- Install-to-first-page: ~4–8 h — the md/mermaid pipeline is built, not installed, and it gates everything downstream.
- Per new product page: ~1–2 h once the pipeline exists — house-stack React makes this the cheapest per-page iteration loop.
Option D — VitePress 1.6.4 custom theme (markdown-native lane)
Essence: site/ is VitePress pinned at 1.6.4 (2.0 is alpha — do not chase it). Markdown-it pipeline: GFM alerts native, mermaid via vitepress-plugin-mermaid in one config block. Content enters via symlinked src dirs. A custom theme with its own Layout.vue kills the default docs chrome; layout: page gives a blank canvas for product pages, polished with Vue SFCs. The off-stack fact: the house is React, so Vue SFC polish is the one place agents work off the home stack. Builds in seconds; ~100–150 MB footprint.
flowchart LR
subgraph CP[content plane - untouched]
P[plans/]; R[research/]
end
subgraph SITE[site/ - VitePress 1.6.4 pinned]
SYM[symlinked src dirs<br/>+ srcExclude patterns]
MI[markdown-it: GFM alerts native +<br/>vitepress-plugin-mermaid one block]
TH[custom theme Layout.vue<br/>kills docs chrome]
VS[layout: page blank canvas<br/>Vue SFC product pages]
end
CP --> SYM --> MI --> TH --> VS --> D[(dist/ static)]
D --> SV[vitepress preview / http.server :8080]
Boundary map
- Content plane: untouched behind symlinks.
- Presentation plane: the custom theme (
Layout.vue) + SFC product pages. - Curation layer:
srcExcludepatterns inconfig.ts— one array, easy to audit; but with symlinks in place that array is the only fence, so it deserves its own check.
Test seams
- Build-as-test: VitePress fails the build on dead links by default — the strongest free link check of the four.
- Mermaid: rendered via the plugin at build time; a green build covers the 43 fences.
- Loop speed: seconds-fast builds make the whole check loop the cheapest here.
- Visual gate: impeccable against
vitepress dev; caveat — every design iteration happens in Vue, off the house stack.
Evolution path / exit cost
- Evolution: stays a content site — that is what it is; interactivity beyond islands of Vue means replatforming.
- Exit: delete
site/; content untouched, theme CSS partially portable, Vue components are not.
Rough cost (estimates, design-gated)
- Install-to-first-page: ~1–3 h — install, pin, symlinks,
srcExclude, kill the chrome via customLayout.vue. - Per new product page: ~2–3 h — the blank canvas is real, but agents pay a Vue tax on every polish pass, and the impeccable gate multiplies exactly that iteration count.