New Capability: Dynamic Manifesto Presentations

New Capability: Dynamic Manifesto Presentations

Date: 2026-04-10 Origin: Unified Canonical Architecture project -- eliminating hardcoded HTML that drifted from Sanity CMS source data across 10 manifesto presentation pages Impact: All 10 manifesto presentations now render commitment slides from Sanity, ensuring canonical content stays in sync without manual HTML maintenance


What Was Built

The ManifestoPresentation layout was refactored from a static slot-based system to a dynamic rendering architecture. Previously, each of the 10 manifesto presentation pages contained 7+ hardcoded HTML slides with commitment titles and body text duplicated from Sanity CMS valueReality documents. This content drifted over time because edits to the canonical Sanity documents had no effect on the presentation slides.

The layout now accepts a commitments prop -- an array of {number, title, actions[]} objects fetched from Sanity at build time. Slides 2 through N+1 are generated dynamically: each renders the commitment number, canonical title, a "This means we will:" label, and 5 action items as bullets. The effectiveSlideCount is computed from the commitments array length, which handles variation naturally (Measurement has 8 commitments while the other 9 manifestos have 7 each). If commitments are not provided, the layout falls back to <slot /> for backward compatibility.

A new query function getManifestoByPresentationSlug(presSlug) was added to the methodology query layer. It maps presentation slugs (e.g., 'partner') to Sanity valueReality documents (e.g., 'value-first-partner') using the existing manifestoPresentationSlug() helper that strips the value-first- prefix. The underlying GROQ query joins valueReality documents to their countersTrap, relatedShow (with hosts), and relatedArticle references for the full ManifestoFullData shape. All 14 valueReality documents in Sanity are populated with commitment arrays, headlines, and cross-references.

Infrastructure Changes

Change Before After
Manifesto page files ~80 lines each with hardcoded HTML slides 17 lines each -- import, fetch, render
Commitment content source Duplicated in page HTML Queried from Sanity valueReality documents at build time
Slide count Hardcoded slideCount in config Computed effectiveSlideCount from commitments.length + 2
Content drift risk High -- Sanity edits invisible to presentations Eliminated -- single source of truth
Total hardcoded HTML ~762 lines across 10 pages 0 lines -- all dynamic

Implementation

File Purpose
apps/website/src/layouts/ManifestoPresentation.astro Layout accepts optional commitments prop, renders slides dynamically or falls back to <slot />
apps/website/src/styles/presentations/manifesto-presentation.css New CSS classes: .commitment-label, .commitment-actions, .commitment-actions li with Tron:Ares aesthetic
apps/website/src/lib/sanity/methodology.ts Added getManifestoByPresentationSlug() and getManifestoFullData() with manifestoFullQuery GROQ
apps/website/src/pages/presentations/manifesto-ai.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-communication.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-content.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-culture.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-delivery.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-humans.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-leadership.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-measurement.astro Refactored to 17 lines (dynamic commitments, 8 commitments handled automatically)
apps/website/src/pages/presentations/manifesto-partner.astro Refactored to 17 lines (dynamic commitments)
apps/website/src/pages/presentations/manifesto-platform.astro Refactored to 17 lines (dynamic commitments)

Usage

No new commands or scripts. The capability is embedded in the build pipeline. When Sanity valueReality documents are updated (commitment titles, action items, or new commitments added), the next Vercel deploy renders the changes automatically.

Each page file follows the same pattern:

---
import ManifestoPresentation from '../../layouts/ManifestoPresentation.astro';
import { getManifestoPresentation, getManifestoByPresentationSlug } from '../../lib/sanity/methodology';

const config = await getManifestoPresentation('partner');
const fullData = await getManifestoByPresentationSlug('partner');
const commitments = fullData?.commitments || [];
---

<ManifestoPresentation config={config} commitments={commitments}>
  <p slot="intro-text" class="content-text" style="text-align: center;">
    {Manifesto-specific intro text}
  </p>
  <span slot="closing-title">{Manifesto-specific closing}</span>
  <span slot="closing-text">{Manifesto-specific closing text}</span>
</ManifestoPresentation>

The GROQ query (manifestoFullQuery) fetches all valueReality documents with populated commitments, joins countersTrap, relatedShow (with hosts), and relatedArticle references:

*[_type == "valueReality" && count(commitments) > 0] | order(number asc) {
  _id, name, "sanitySlug": slug.current, manifestoTitle, headline,
  "showSlug": relatedShow->slug.current,
  "showName": relatedShow->name,
  "trapName": countersTrap->name,
  commitments[] | order(number asc) { number, title, actions }
}

Leader Applications

V (Operations)

V benefits directly from the reduced maintenance surface. When methodology content evolves, the presentations stay current without requiring 10-file HTML edits. Build verification is simpler: one layout file and one query function versus 10 independent page implementations. The 762-line elimination also reduces merge conflict surface in the presentations directory.

Sage (Customer)

Sage benefits from content integrity. When preparing relationship briefs or referencing Value-First methodology in session materials, the manifesto presentations now reflect exactly what Sanity contains. There is no risk of a presentation showing outdated commitment language that contradicts what Sage communicates in relationship contexts.

Pax (Finance)

No direct application. The manifesto presentations are methodology content, not financial instruments.


Dependencies

Dependency Status Notes
Sanity valueReality documents with commitments array Confirmed 14 documents populated with commitment data (7 each, Measurement has 8)
methodology.ts query layer Confirmed getManifestoByPresentationSlug() and getManifestoFullData() operational
ManifestoPresentation layout commitments prop Confirmed Optional prop with <slot /> fallback for backward compatibility
manifesto-presentation.css commitment styles Confirmed .commitment-label, .commitment-actions, .commitment-actions li with Tron:Ares aesthetic
Astro 5 build pipeline Confirmed Build completed in 177 seconds, zero errors

Verification

  1. Build passes: pnpm build in apps/website/ completes without errors (verified: 177 seconds, zero errors)
  2. All 10 pages at 17 lines: wc -l apps/website/src/pages/presentations/manifesto-*.astro confirms 170 total (17 each)
  3. Dynamic rendering: Visit any /presentations/manifesto-{slug} page -- commitment slides render with numbered headers, canonical titles, and bulleted action items
  4. Measurement exception: /presentations/manifesto-measurement renders 8 commitment slides (not 7) without any special-case code -- effectiveSlideCount computes 8 + 2 = 10 automatically
  5. Backward compatibility: If a page omits the commitments prop, the layout renders <slot /> content instead -- no breaking change to the layout interface
  6. Content sync: Edit a commitment title in the Sanity valueReality document, trigger a deploy, and confirm the presentation reflects the change