← All changelog entries
April 27, 2026 · Feature

Long-Form Reader Chrome — Triptych, Reading Progress, ChapterMeta, and the LFM Pipeline Everywhere

Built the v0.1 long-form reader chrome on `/read/venture-handbook/[slug]/`: a `BookReaderLayout` that wraps `BaseThemeLayout` and composes a top triptych (previous chapter card · banner with overlay · next chapter card), a `ChapterMeta` slim row, an 'In this chapter' outline, generous prose typography (drop-cap, accent rule above each H2, footnote pills, ✦ ornament on `<hr>`), and a bottom prev/next pair — all driven by container queries with four width-based modes. Introduced four reader-specific components in `src/components/read/` (`BookReaderLayout`, `ReadingProgressBar`, `ChapterMeta`, `ContentPreviewNavCard`) and a site-wide `FormattedDate` component backed by a `format-date.ts` util that handles UTC normalization (`April 26, 2026` default, plus medium / short / iso / reverse-medium / year-only). Migrated `webinars/[id].astro` from the improvised vanilla `<Content />` rendering to the canonical Lossless pipeline (`parseMarkdown` + `AstroMarkdown` + `Sources`) and added the table / footnote-pill / hr styles that were missing. Removed a duplicate-`Sources`-heading bug from chapter bodies (the LFM Sources component owns that heading; the content port was double-injecting it). Fixed a fundamental container-query mistake: `@container reader (aspect-ratio …)` reads the container's *own rendered* aspect, which is always portrait for a long scrolling page — so the Desktop layout never fired. Switched to width-only thresholds plus a viewport `@media (max-aspect-ratio: 13/10)` for the actual split-screen-on-portrait case. Dropped a brand banner above the hero on `/dojo` (Kauffman + SVG composite). Registered every new component in `/design-system` per the maintenance motion. The Agentic VC Dojo launch session now has its time, RSVP, and Format table dialed in for the kickoff.

Authors
Michael Staton
Augmented with
Claude Code on Opus 4.7
Tags
#Long-Form-Reader#BookReaderLayout#Triptych#ContentPreviewNavCard#ReadingProgressBar#ChapterMeta#FormattedDate#Container-Queries#LFM#AstroMarkdown#Lossless-Pipeline#Sources-Dedup#Webinars-Pipeline-Migration#Markdown-Tables#Dojo-Banner#Design-System-Catalog#Venture-Handbook#Kauffman-Fellows

Changelog - 2026-04-27 (01)

Long-Form Reader Chrome — Triptych, Reading Progress, and the LFM Pipeline Everywhere

Why Care?

For the firm (Mike): the Venture Handbook now has the chrome it needs to feel like a real book on the open web. Drop a chapter .md into src/content/long-form/venture-workflows/ and you get — for free — a banner with overlaid chapter title, a slim meta row (Chapter 03 · 12 min read · 5,420 words · author · updated · source), an “In this chapter” outline derived from the subsection_outline frontmatter, a top triptych showing the previous chapter card · the banner · the next chapter card, an accent rule above every H2, a violet→lime gradient drop-cap on the first paragraph, footnote refs styled as little violet pills, a ✦ ornament on every <hr>, and a bottom prev/next pair of full-fidelity preview cards. All of it tracks --color-primary and adapts across the three modes (light / dark / vibrant) without any per-mode rules.

The reader uses container queries — the reader’s own width, not the viewport’s — to switch between four layouts: Mobile (chevron-only flanking buttons), Tablet (slim cards, no tags), Half-Screen (~200px slim cards), and Desktop (full 17rem cards beside a wider 1100px outer container). That means the layout responds correctly inside split-screen panels, embedded iframes, and any other constrained context — without a single viewport @media query.

For our end users (the VCs reading): the chapter pages no longer feel like a <Content /> dump on a card. They feel like a Stripe-Press-style ebook chapter — generous typography (~70ch column at 1.7 line-height, 1.0625–1.125rem body), prev/next previews so you can see where you’ve been and where you’re going without scrolling, and a thin scroll-progress stripe at the very top of the viewport so you know how much of this chapter is left.

The webinars detail pages got the same treatment: switched from improvised <Content /> rendering to the canonical Lossless pipeline (parseMarkdown + AstroMarkdown + Sources), and gained the table / hr / footnote-pill styles they were missing. The Agentic VC Dojo launch session’s Format breakdown now renders as a proper bordered table with code-font uppercase headers and a subtle hover-row tint, instead of as raw text columns.

What Got Built

BookReaderLayout (new — src/layouts/BookReaderLayout.astro)

Wraps BaseThemeLayout. Receives the chapter entry plus optional prev/next entries. Composes:

  • ReadingProgressBar (3px stripe)
  • Skip-to-content link (a11y)
  • Top triptych: [ContentPreviewNavCard variant="inline"] · [BannerWithOverlay] · [ContentPreviewNavCard variant="inline"] — when a side is missing (chapter 1 or 10), a layout-stable spacer sits in its place
  • ChapterMeta slim row (Chapter NN · X min read · X,XXX words · Author · Updated · Source)
  • Tag chip row (#Train-Case)
  • “In this chapter” outline aside (from frontmatter subsection_outline)
  • The article body slot (where AstroMarkdown + Sources go)
  • Bottom prev/next pair (full-fidelity ContentPreviewNavCard variant="block")

Banner image source resolves through hero_image → og_image → /og-default.png, so chapters with only the OG image populated still get a real banner. The triptych cell stretches the banner to the cards’ height (the banner figure’s intrinsic 3:1 is overridden in this context); the image inside still uses object-fit: cover so 3:1 generated banners look right and off-aspect fallbacks crop instead of stretching.

Container query modes (width-only, plus a viewport @media fallback for portrait split-screen):

  • Mobile (cw < 768px): chevron-only flanking buttons, single-column bottom nav
  • Tablet (768–1023): medium cards (no tags, 2-line lede)
  • Half-Screen (1024–1279): slim ~200px cards (3-line lede, max 2 tags)
  • Desktop (≥ 1280): full 17rem cards, --reader-outer: 1100px, --reader-prose-size: 1.125rem

Print stylesheet polished: progress bar / triptych / nav suppressed, page-break before each <h2>.

ContentPreviewNavCard (new — src/components/read/)

Direction-aware preview card. variant="inline" adapts to the reader container size (full → slim → chevron-only); variant="block" is always full. Visually echoes AreasOfVentureGrid (same --fx-card-* tokens, same number-in-corner motif, same lede + tags rhythm). The chevron sits in the corner that matches travel direction ( top-left for prev, top-right for next); on hover the chevron slides toward its direction by 2px. Whole card is a single <a>.

ChapterMeta (new — src/components/read/)

Slim code-font row immediately below the banner. Renders Chapter NN · reading time · word count · author · updated date · source organization as a horizontal definition-list. Reading time computed by the caller as ceil(words / 220); word count stripped of code fences and footnote definitions before the count.

ReadingProgressBar (new — src/components/read/)

Fixed 3px top stripe. Tracks scroll position relative to the article body’s bounding rect — not the viewport — so the bar reaches 100% when you’ve scrolled past the last paragraph, not when you hit the bottom of the page including the prev/next cards. requestAnimationFrame-throttled scroll listener; prefers-reduced-motion: reduce kills the width transition.

FormattedDate + format-date.ts (new — src/components/ui/, src/lib/)

Common date formatter usable anywhere. Accepts Date | string | null, returns the date in one of: 'long' (April 26, 2026 — default), 'medium' (Apr 26, 2026), 'short' (Apr. 26, 2026), 'iso' (2026-04-26), 'reverse-medium' (2026, Apr. 26), 'year-only' (2026). UTC-normalized so 2026-04-26 doesn’t shift to 2026-04-25 for negative-offset readers — that ambiguity has bitten the site before. The Astro component wraps the output in a semantic <time datetime="YYYY-MM-DD">.

Webinars detail page migrated to the LFM pipeline

src/pages/webinars/[id].astro was using the improvised vanilla-Astro <Content /> rendering. Switched to the canonical pattern: parseMarkdown(entry.body)<AstroMarkdown node={tree} /><Sources citations={citations} />. Added the table / footnote-pill / <hr> styles that the body was missing — the Format table on the launch session now has proper borders, padded cells, code-font uppercase headers, and a subtle hover-row tint. Cleared 3 pre-existing TS-check errors while in the file.

Dojo page brand banner

Dropped a full-width brand banner above the hero on /dojo (Kauffman-logo composite + SVG overlay you spent the time on at /og-default.png). Tasteful card surface treatment via --fx-card-*; 5rem gap below preserves the existing hero / Areas grid rhythm.

Design system catalog updated

Five new catalog entries land in /design-system per the maintenance motion: BookReaderLayout, ReadingProgressBar, ChapterMeta, ContentPreviewNavCard, FormattedDate. ContentPreviewNavCard also gets a live preview section showing both block and inline variants side by side.

Bugs Fixed

  • Duplicate <h2>Sources</h2> on every chapter page. The content port had injected *** + ## Sources as a divider into 8 chapter bodies; LFM’s parseMarkdown also populates tree.data.citations.ordered from the numeric [^N]: … defs, and the <Sources /> component renders its own <h2>Sources</h2> from that. Two headings, both legit. Fix: stripped the injected wrapper from all 8 chapters; footnote defs themselves remain (LFM consumes them); <Sources /> is now the sole source of the heading. Verified: chapter 5 now renders exactly 1 <h2>Sources</h2> and 4 source-* anchors.
  • Container-query Desktop layout never firing. @container reader (aspect-ratio >= 13/10) was reading the container’s own rendered aspect — which for a long scrolling page is always portrait — so the Desktop rule was a dead branch and full-screen laptops were falling through to Half-Screen. Fix: width-only thresholds in the container queries; one viewport @media (min-width: 1280px) and (max-aspect-ratio: 13/10) clamps wide-but-tall split-screen windows to the slim density (the case the spec actually wanted aspect-ratio for). Both BookReaderLayout and ContentPreviewNavCard rules updated.
  • Banner figure not filling the triptych cell on Desktop. The figure’s intrinsic aspect-ratio: 3/1 was making it shorter than the cards beside it. Fix: in the triptych context only, override to aspect-ratio: auto; height: 100%; width: 100%. Image inside still uses object-fit: cover so 3:1 banners look right and off-aspect fallbacks crop gracefully.

Authoring affordances

  • New chapters need only frontmatter + body. The layout handles banner / meta / outline / prev-next from chapter_number sequencing. No manual prev/next wiring.
  • New webinar markdown can use full GFM (tables, footnotes, callouts via the :::callout directive once that lands) — the body now flows through the same renderer as chapters and essays.
  • Date strings in frontmatter render through <FormattedDate> for human-legible output; pass style="reverse-medium" for the year-first variant where desired.

Yak-Shaving Deferred

  • Foreword (00-foreword.md) and appendix (99-perspectives.md) chapters not yet filed.
  • Image directive migration — the chapter bodies still carry backticked ![][image6] markers that need to be unwrapped and resolved to the /read/venture-handbook/images/ PNGs (the 29 images are extracted and in place; the rewrite is one mechanical pass).
  • Mobile collapsing ToC bar (port from lossless-group/site per spec § Mobile ToC).
  • Desktop ToC sidebar (right-margin sticky, IntersectionObserver-driven).
  • Section-share / quote-share buttons + the /share/ SSR endpoint.
  • Save-my-place via localStorage.
  • Per-chapter banner generation pass (currently all chapters fall back to the OG image via the new fallback chain).

Files Touched

See frontmatter files_modified. Chapters listed as a glob since all 10 had the duplicate-Sources fix applied.

Files modified (17)
  • sites/fullstack-vc/src/layouts/BookReaderLayout.astro
  • sites/fullstack-vc/src/components/read/ReadingProgressBar.astro
  • sites/fullstack-vc/src/components/read/ChapterMeta.astro
  • sites/fullstack-vc/src/components/read/ContentPreviewNavCard.astro
  • sites/fullstack-vc/src/components/ui/FormattedDate.astro
  • sites/fullstack-vc/src/lib/format-date.ts
  • sites/fullstack-vc/src/pages/read/venture-handbook/[slug].astro
  • sites/fullstack-vc/src/pages/webinars/[id].astro
  • sites/fullstack-vc/src/pages/webinars/index.astro
  • sites/fullstack-vc/src/pages/dojo/index.astro
  • sites/fullstack-vc/src/pages/design-system/index.astro
  • sites/fullstack-vc/src/content/webinars/2026-05_agentic-vc-dojo-launch.md
  • sites/fullstack-vc/src/content/long-form/venture-workflows/*.md
  • sites/fullstack-vc/src/layouts/BoilerPlateHTML.astro
  • sites/fullstack-vc/src/styles/theme.css
  • sites/fullstack-vc/astro.config.mjs
  • sites/fullstack-vc/scripts/generate-content-banners-on-dir.ts