docHub rebuilt as FreshCards-style SPA (v3)
Status: ✅ Rebuilt + redeployed at https://57663de0.docshub-1pi.pages.dev (latest). Awaiting operator Cloudflare Access config.
TL;DR
Replaced the static-file-renderer docHub with a single-page-application (SPA) shell inspired by the FreshCards substrate visual chrome:
- Card grid dashboard on home + face views, grouped by section with document counts
- Sidebar with per-face section nav + counts
- Search (live filter on title/summary/tags)
- Sort (default / name / updated)
- Detail view with frontmatter meta-bar + properly-rendered markdown (tables, numbered lists, bullet lists, blockquotes, fenced code, inline code, bold/italic, links)
- Mobile-friendly — sticky header, hamburger menu at ≤900px, single-column at ≤600px
- Three faces correctly referenced (user/dev/mavis) in all content + chrome
What was wrong before (v2)
The previous static-site renderer had these issues:
- Tables rendered as raw pipe-text (
| Step | What | Why | |---|---|---|) - Numbered lists rendered as one run-on paragraph (
1. Fetch ... 2. Read ...) - No card grid — single-column, no sidebar, no badges
- README referenced two faces (
dev/user), but the actual design is three faces (user/dev/mavis) - No visual chrome — just headings + paragraphs
- Plain HTML pages instead of SPA
The operator pointed this out after I shipped v2. Took screenshots of the original shared-docs hub (https://07bf6f81.shared-docs-4v2.pages.dev/) and the actual FVS FreshCards module (avidtech6/freshvibestudio/studio/modules/freshcards/) for reference.
Architecture (v3)
SPA shell (site/index.html)
- Single HTML file at the root. Loads all three face manifests in parallel (
/user/_meta/manifest.json,/dev/_meta/manifest.json,/mavis/_meta/manifest.json). - Hash-based routing:
#user(face view),#user/concepts(section view),#user/doc-id(doc detail). - Doc detail loads the pre-rendered HTML for each doc via fetch, extracts the
<article>body, displays it inside the meta bar + content area. - No JS framework. Plain vanilla JS. ~600 LOC.
Visual chrome (site/style.css)
Based on FreshCards substrate visual primitives:
- Card geometry — min 280px, padding 14px, radius 8px (per FreshCards
cards.geometry.base.001) - Color palette — primary
#2C5282, accent#5b8cff(matches FreshCards--accent) - Type pills — uppercase small text with colored background (per FreshCards
cards.semantic.role.001) - Status indicators — colored circles (per FreshCards
cards.lifecycle.*) - Sidebar — fixed 280px column, gradient header, section nav with counts (mirrors FreshCards workspace shell)
- Card grid —
auto-fill, minmax(280px, 1fr), 14px gap
Markdown renderer (in build-site.mjs)
Replaced the thin parser with a proper block-level parser:
- Headings
#-#### - Paragraphs (gather contiguous non-block-start lines)
- Fenced code
`lang ...` - Blockquotes
> ...(recursive) - Bullet lists
-or*(sequential lines) - Numbered lists
1.,2., etc. (sequential lines) - Tables (GFM pipe tables: header + separator + body rows)
- Horizontal rules
---,***,___ - Inline:
**bold**,*italic*, `code,text` (with optional title) - Code spans are tokenised first so other formatting inside them isn't applied
Manifest generator (build.mjs)
Added a summary field per doc — extracted from the first non-heading, non-empty, non-blockquote paragraph, with leading **Foo:** prefix stripped, capped at ~180 chars.
Build & deploy (build-site.mjs, deploy.sh)
build-site.mjsnow copiessite/index.htmlandsite/style.csstodist/(overwriting the static-renderer output)deploy.shis unchanged
Mobile-friendly
- Sticky header with search/sort
- Sidebar collapses to hamburger menu at ≤900px
- Single-column card grid at ≤600px
- All tap targets ≥44px
viewport-fit=cover,theme-color,text-size-adjust: 100%- Dark mode via
prefers-color-scheme: dark - Verified via Playwright on iPhone 13 emulation
FreshCards substrate alignment
The visual chrome mirrors FreshCards substrate primitives:
| FreshCards pact | docHub v3 |
|---|---|
cards.geometry.base.001 (min 280×120) | .freshcard { min-height: 120px } |
cards.geometry.padding.001 (4/8/12/16/24) | 14px padding (between 12 and 16) |
cards.geometry.border.001 (1px, radius 6/8/12) | border: 1px solid; border-radius: 8px |
cards.lifecycle.* (status badges) | .badge-status.complete/in-progress/planned/blocked |
cards.semantic.role.001-006 (focus/action/navigation/status/filter/info) | .badge-type.{doctrine,decision,report,plan,lane,dangerous,reference,project,concept,user-doc,bootstrap,prompt} |
FreshCards Workspace (header + card list + active display) | docHub sidebar (face nav + section nav + quick links) + main content (face cards + detail) |
FreshCards branch state (verified)
The feat-freshcards-module branch is diverged from main by 73 commits behind, 1 commit ahead. The 1-ahead commit (e1b61bf5 "feat(fix): viewport fill + card overflow + mobile doctrine Stages A/B/C") is already on main — the branch is stale, no merge action possible without rebasing first.
The actual FreshCards substrate work shipped to main via these commits:
b83c84fc2026-06-19 — FreshCards module scaffold + CardChipSystem mode callbacks43cb74f72026-06-22 — Re-align: 12 cockpit Cards → vibecoder module; substrate-only freshcards- Plus the supporting Phase 1-5 fragment-to-Card conversion work
So FreshCards is canonical at studio/modules/freshcards/ as a substrate (per D-056). docHub v3 uses the visual chrome of that substrate, adapted for static docs.
Open questions
- OQ-1: cards Mavis still parked on Region Schema sign-off. Re-pinged via
???protocol 01:09 UTC. Croncards-mavis-reply-watcherset up to auto-ping every 2 hours if no reply. - OQ-2: Old GitHub PAT
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letting expire 2026-06-24. - OQ-3: Case-variant repo cleanup — operator to confirm the 5 deleted repos were empty placeholders.
Operator action
- Cloudflare Access — email allowlist on
/dev/*and/mavis/*(5 min, instructions indev/deploy-access.md) - Cards Mavis Region Schema sign-off (OQ-1) — operator action
- Embed
<doc-hub>in an FVS app to test the embeddable face - (Optional) FVS module wrapper at
studio/modules/docshub/— the canonical export of docHub as a FreshCards-style substrate, post-deploy
Memory updates
Updated agent memory:
- docHub v3 deployed — FreshCards-style SPA, mobile-friendly, three faces
- FreshCards branch state —
feat-freshcards-modulestale, all real work on main - Markdown parser now handles tables, numbered lists, blockquotes, fenced code
Files of note
site/index.html— SPA shell (replaces the static renderer)site/style.css— FreshCards-aligned CSSbuild-site.mjs— updated markdown parser (handles tables, numbered lists)build.mjs— addssummaryfield to manifestsdev/bootstrap/README.md— updated to reference three faces (was stale two-face)mavis/reports/2026-06-23-dochub-spa-v3-rebuild.md— this report
Screenshots
screenshots/dochub-spa-v3-home.png— home view (card grid, all three faces)screenshots/dochub-spa-v3-detail.png— dev/bootstrap/README detail (tables + numbered lists work)screenshots/dochub-spa-v3-mavis-decision.png— mavis decision D-057 detail (numbered lists, consequences list)screenshots/dochub-spa-v3-mobile-home.png— mobile home view (iPhone 13, sidebar collapsed)