Skip to content
GRPNR.

005 — Showcase Website: Phase-1 Deep Dive

plan: 005-showcase-website
type: deep-dive
status: phase-1-complete
created: 2026-07-19
owner: Robert

Consolidates research packets R-C1 (content inventory), R-D1 (Astro), R-D2 (Quartz), R-D3 (Next.js/VitePress), R-H1 (serving+repo), R-R1 (rules port). All facts dated 2026-07-19; VERIFIED = checked today (filesystem, web fetch, npm registry), ASSUMPTION = training knowledge or judgment, not re-verified.

1. Question & Scope

Question: Which stack and markdown→site pipeline should power an internal showcase website for the Groupon rebuild program and its 5 factory products, sourced from the existing markdown in plans/ + research/?

Optimization target: speed at which Claude Code agents author NEW awesome-looking product pages, under the anti-template design rule (§5) — not raw serving performance, not SEO, not scale.

In scope: SSG/stack choice, md-source pipeline (content outside src/), mermaid + GFM rendering, localhost serving + persistence, repo/git setup, rules port per stack.

Out of scope: the products themselves (they have their own plans folders); auth; cloud hosting beyond a forward path — one paragraph: if Tomas needs access later, the two candidates are Cloudflare Pages/Workers static assets gated by CF Access (free ≤50 users, creds already in ~/s/.env.master) or Tailscale into the WSL node (strongest confidentiality, zero pipeline change, Tomas installs Tailscale). Both consume the same static dist/; decision deferred until the need is real. grpn.site domain: unverified, ASSUMPTION only — confirm ownership before planning around it. [R-H1]

2. Corpus Ground Truth (load-bearing)

Direct filesystem inspection of /home/rob/groupon/refactor, 2026-07-19. All VERIFIED unless noted.

2.1 Markdown corpus

Folder .md files Lines Notes
plans/001-factory-apps-validation 6 588 SYNTHESIS, deep-dive, case-studies, options, steelman
plans/002-dual-run-parity-harness 16 3,338 full product pack (prd, architecture, ux-ui, pre-mortem, north-star…)
plans/002-work-ledger-product 12 2,428 numbered pack 01–11 (duplicate 002- prefix)
plans/003-atlas-intelligence-layer 20 5,154 product pack + evidence/ (memos r1–r8)
plans/004-fleet-monitor 9 1,244 00-SYNTHESIS, prd, architecture, ux-ui, pre-mortem
plans/ total 63 12,752
research/ 19 976 short memos ~30–80 lines; + 2 raw .json
docs/ 1 11 llm-runs.md
analysis/ subdirs 3 190 legacy/SYNTHESIS+census, monorepo-development/ASSESSMENT; rest JSON

Total ≈ 86 md files, ~13.9k lines. Small — any SSG, or even a single-file renderer, handles it.

2.2 Obsidian-syntax reality: the corpus is plain CommonMark + GFM + mermaid

Folder [[ wikilinks > [! callouts ```mermaid YAML frontmatter images
plans/ 2* 0 41 10/63 files 0
research/ 0 0 2 0/19 0
docs/, analysis/ 0 0 0 0 0

* Both [[ hits are mermaid node syntax in plans/002-dual-run-parity-harness/architecture.md (lines 218, 321). True wikilink count: 0. Callouts: 0. Embeds/images: 0. Frontmatter where present is trivial (plan/status/owner/created/type).

Conclusion: Obsidian-syntax fidelity does NOT matter. The hard pipeline requirement is GFM tables (heavy — decision matrices, scorecards throughout) + 43 mermaid fences + trivial YAML frontmatter. Any candidate scored on wikilink/callout support is being scored on a non-requirement.

2.3 Confidentiality map

Never publish / never leave localhost or reach any public remote:

  • repos/ (12G) — cloned confidential Groupon repos. Exclude from site AND gitignore before any git init (no .git exists yet, VERIFIED).
  • analysis/monorepo-development/ASSESSMENT.md — self-declares CONFIDENTIAL (unannounced org plans, compensation, named-person scoring). Excluded even from the internal site unless Robert opts in.
  • research/14-answer-draft-tomas.md, research/11-monorepo-development-assessment-plan.md — person-directed drafts (ASSUMPTION: exclude from curated site).
  • analysis/legacy/ quotes confidential repo internals — fine for localhost, not for anything beyond Robert/Tomas.

Curated INCLUDE set: plans/00* product packs, research/00–10 + 12–13, analysis/legacy/SYNTHESIS.md, docs/llm-runs.md.

2.4 Source docs per product page

Page Primary sources
Program overview plans/001.../00-SYNTHESIS.md; research/00-executive-summary.md; research/06-six-app-blueprint.md
Fleet monitor plans/004-fleet-monitor/ 00-SYNTHESIS, 04-prd, 06-architecture, 05-ux-ui; research/12
Work-ledger plans/002-work-ledger-product/ 01, 10-architecture, 09-north-star, 07-ux-ui
Dual-run harness plans/002-dual-run-parity-harness/ prd, architecture (mermaid-heavy), north-star, made-to-stick
Triage inbox folded into Atlas: plans/003.../ 01, 02, 09; research/08
Atlas plans/003.../ 01, 10-architecture, 09-north-star, evidence/r1–r8
(bonus) Legacy estate analysis/legacy/SYNTHESIS.md + graph/graph.mmd

2.5 Tooling on box (VERIFIED)

node v24.18.0, npm 12.0.1, pnpm 11.9.0 (store warm), bun 1.3.14 — no installs needed for any mainstream SSG.

3. Candidate Technology Facts

3.1 Astro 7 [R-D1]

  • Astro 7.1 current (2026-07-16); 7.0 released 2026-06-22. Rust compiler, Vite 8 + Rolldown, builds 15–61% faster. VERIFIED — astro.build/blog, Astro 7.0 post.
  • Content from arbitrary folders is first-class: Content Layer glob({ pattern, base: "../plans" }) documented as loading “from anywhere on the filesystem”. VERIFIED — Content Loader API. Dev-server watching of out-of-src dirs: ASSUMPTION (worked in v5, not re-verified for v7).
  • ⚠ Key decision point — v7 markdown pipeline changed: default processor is now Sätteri (Rust; npm satteri 0.9.5, 2026-07-08), which does not run remark/rehype plugins. Official escape hatch: install @astrojs/markdown-remark → old remarkPlugins/rehypePlugins config works as before. At ~100 files the lost Rust speed is irrelevant. VERIFIED — first-party blog, byteiota analysis. Sätteri builds in GFM, heading IDs, smart punctuation natively — with zero wikilinks/callouts in the corpus (§2.2), the stock Sätteri pipeline may already suffice.
  • Mermaid: astro-mermaid 2.1.0 (2026-06-24, active, client-side, auto theme-switch) — simplest. Build-time rehype-mermaid 3.0.0 needs Playwright headless + unified pipeline; viable (bundled Chromium exists) but two extra moving parts. VERIFIED (npm). Verdict: client-side for 2 viewers.
  • Tailwind v4: npx astro add tailwind@tailwindcss/vite; old @astrojs/tailwind deprecated. VERIFIED — tailwindcss.com Astro guide.
  • Agentic DX: astro dev --background shipped in 7.0 explicitly “for AI agent compatibility” + JSON structured logging. VERIFIED. Training data is heavy but at Astro 4/5 level — predictable agent failure modes to pin in CLAUDE.md (ASSUMPTION, high confidence): deprecated @astrojs/tailwind; assuming remark plugins run by default; legacy src/content/ collections; v7 strict-HTML build errors (fail-loud — actually good).
  • Starlight: docs chrome (sidebar/search); workable but you fight its skin for a showcase. Verdict: skip — plain Astro + Tailwind v4 + one layout file. VERIFIED — starlight docs.

3.2 Quartz v5 [R-D2]

  • Mid v4→v5 transition: default branch is v5, homepage announces v5.0.0, active commits through 2026-06-16, but last tagged release is v4.0.8 (2023). v5 shipped via branch flip in 2026 — post-dates every current model’s training data. 12.8k stars, MIT. VERIFIED — github.com/jackyzha0/quartz, quartz.jzhao.xyz.
  • Full Obsidian syntax (wikilinks, callouts, mermaid, graph view, backlinks, search) — VERIFIED, but per §2.2 this is capability the corpus doesn’t need.
  • Fork-as-app model: you clone the Quartz repo and put content in its fixed content/ dir; subset publishing via symlinks (content/plans → ../../plans) is a standard community pattern. Node ≥22. VERIFIED + low-risk ASSUMPTION on the two-symlink setup.
  • Customization ceiling: Preact JSX + SCSS components, v5 pushes toward external plugin packages. ASSUMPTION: “excellent knowledge garden, mediocre product/marketing pages” — bespoke pages mean custom Preact emitters against a brand-new v5 API.
  • Agentic risk (the real one): agents know v4 cold; v5 config (YAML), plugin registry, and page types have zero training presence → expect v4/v5 API hallucination on any site-customization task. ASSUMPTION, high confidence.
  • Sidebar alternative: obsidian-export (Rust, v25.3.0, active) converts Obsidian md → CommonMark as a decoupling shim — not a site generator. VERIFIED — github.com/zoni/obsidian-export.

3.3 Next.js 16 static export [R-D3]

  • Stable 16.2.10 (2026-07-01); monthly security-patch cadence. VERIFIED — releasebot.io.
  • output: 'export' → plain static out/; no ISR/Server Actions/default image loader in export mode. VERIFIED — static-exports guide.
  • No first-class content layer for md outside app/: choices are content-collections (active successor to unmaintained Contentlayer; Dub migrated — VERIFIED dub.co/blog) or ~100 hand-rolled lines (ASSUMPTION, standard pattern). Mermaid: DIY (ASSUMPTION). Heavy install (300–500 MB), 20–60 s builds (ASSUMPTION).
  • Nextra 4 escape hatch exists but is docs-shaped chrome. VERIFIED — nextra.site.
  • Verdict [ASSUMPTION/judgment]: house-stack familiarity real (Groupon monorepo + velin are Next), React page ceiling highest — but right call only if the showcase shares components with velin or graduates into an app. Evolution: flip off output: 'export' → full app, zero migration.

3.4 VitePress [R-D3]

  • Stable 1.6.4; 2.0.0-alpha.18 (2026-07-06) not production-ready — pin 1.6.4. VERIFIED — vitepress releases.
  • markdown-it pipeline; GitHub alerts (> [!NOTE], 5 types) built in; mermaid via vitepress-plugin-mermaid (maintained, one config block). VERIFIED — vitepress.dev/guide/markdown, plugin docs.
  • Custom themes fully supported (layout: page = blank canvas; Vue SFCs inline in md). VERIFIED — custom-theme guide. But polish lives in Vue — off-stack for this house (Next/React everywhere else) and less agent muscle memory than React (ASSUMPTION/judgment).
  • Light (~100–150 MB, seconds-fast builds — ASSUMPTION, widely reported). Massive 1.x training-data presence.
  • Net [ASSUMPTION/synthesis]: wins “markdown in, good page out, minutes not hours”; ceiling for bespoke showcase pages = writing Vue.

4. Serving + Repo Facts [R-H1]

  • ui-bridge (:1337) CAN serve a static buildGET /p/<project>/<subpath> resolves sibling files; registry persists. Caveats: no index.html auto-resolution on directory URLs, thin MIME map (no woff2/webp), no traversal guard, /p/<project>/ prefix requires base-prefixed URLs. Currently not running. VERIFIED (source read).
  • Plain static serving: python3 -m http.server -d dist (zero-install) or npx serve (proper MIME + index + SPA fallback). No caddy/pm2/serve installed. Dev-server mode (astro dev/vite) equally viable for 2 viewers. VERIFIED.
  • Persistence: systemctl --user responds (state degraded but functional) → user-scoped systemd unit is the boring persistent option, same unit for dev-server or static-server ExecStart. VERIFIED + ASSUMPTION on WSL2 session survival.
  • Repo: no .git at /home/rob/groupon/refactor (VERIFIED). repos/ is 12G of confidential checkouts — must be gitignored before init. Suggested .gitignore seed: repos/, .playwright-cli/, .claude/scheduled_tasks.lock, node_modules/, dist/. Git author configured (Robert / robert@soulfire.cz); nothing blocks git init + first commit today. Main-branch-only, no public remote (confidentiality map §2.3).

5. Rules Port + Anti-Template Design Rule [R-R1]

Vault: /mnt/f/OH/Notes/Global Code Settings/Coding Rules/ → port to refactor/rules/ (frontmatter carries applies-to, copy as-is). Vault has 1 Astro rule, 6 Next.js rules, 0 Quartz rules.

Rule group (vault path) Astro Quartz Next
web/design-quality.md (anti-template — see below) x x x
astro/framework-conventions.md x
nextjs/ app-router, server-client-components, layouts-and-metadata, data-fetching x
nextjs/ api-routes, opennext-cloudflare opt (skip for local static)
typescript/ strict-typing, type-inference, nullability, enums-alternatives, module-structure x x x
typescript/ rest (generics, branded types…) opt opt opt
react/ component-structure, props-design, design-tokens (Tailwind v4 @theme) islands only x
seo/ meta-tags, performance (json-ld/lighthouse skipped — internal, 2 viewers) x x x
accessibility/ keyboard-nav, screen-readers x x x
animation/ entry-animations, scroll-reveals, performance-and-a11y x x x
testing/trophy-model.md; tools/ plans, git-commit-workflow x x x
clean-code/ subset (DRY, design-twice, obvious-design, readability, component-size, general-purpose, mobile-optimization, ts-patterns) x x x
architecture/project-file-organization.md only (rest is backend-scale, YAGNI) x x x

Port burden: Quartz lightest (~20 generic files), Astro +1, Next +4–6 plus react/ subset (~25–28). Quartz column mappings + skip judgments are ASSUMPTION; applies-to values verbatim (VERIFIED).

Always-pinned (via @rules/... imports in repo CLAUDE.md): File Headers (actual location Agent Rules/File Headers.md — crossroads.md’s root link is broken, VERIFIED; fix reference when porting), security/owasp-compliance.md, security/security-testing.md.

Anti-template design rule (web/design-quality.md, read fully, VERIFIED): frontend must look “intentional, opinionated, and specific to the product.” Bans: uniform card grids, stock centered-headline + gradient-blob heroes, unmodified Tailwind/shadcn defaults, flat no-depth layouts, uniform radius/spacing/shadow, gray-on-white + one accent, dashboard-by-numbers, default font stacks. Every meaningful surface needs ≥4 of 10 qualities (scale-contrast hierarchy, spacing rhythm, depth/layering, real type pairing, semantic color, designed interaction states, grid-breaking composition, texture/atmosphere, clarifying motion, dataviz as design-system citizen). Before coding: pick a specific style direction, define palette + typography deliberately, gather references, don’t default to dark mode. The rule names the impeccable skill as the live gate when available — it IS available in this environment, so it (plus frontend-design) is the enforcement mechanism for every new product page.