Skip to main content

Design System

What does the brand look like, what components ship, and how does a landing page sequence work?

This page covers the four things unique to this repo: the brand identity, the component inventory, the landing page sequence, and the Docusaurus IFM cascade fix. For tokens and composition rules see Design Language. For numbers see the Hard Thresholds Table.

Operational Bible

The runtime source of truth for this design system is src/components/DESIGN.md — a Google Labs design.md file living beside the components it governs. Every primitive listed below is documented there in machine-readable YAML (colors, typography, spacing, components) plus human prose (do's and don'ts). Agents working in src/components/ read this file first.

# Lint the operational bible before shipping
npx @google/design.md lint src/components/DESIGN.md

The bible aligns with tailwind.config.js (the build-time token surface). Drift between the two is a blueprint failure — patch the bible, the config, and any consumer in one PR.

Full standard, four-scope rules (system / per-venture / per-workchart / per-deck), section order, and lint enforcement live in Design System Standards §The DESIGN.md Standard.


Brand Identity

The Dreamineering logo is a P&ID (Process & Instrumentation Diagram) — the same visual language used to draw factories. Four shapes form a feedback loop that doubles as a question mark.

ShapeP&ID elementFunctionAsset
TrapezoidHopperCapturedrmg-dream.svg
TrianglePumpActdrmg-act.svg
CircleGaugeMeasuredrmg-measure.svg
CurveControllerQuestiondrmg-learn.svg

Logo variants

FileUse
logo.svgFull mark, currentColor fill
logo-home-red.svgWhite shapes on red — homepage nav
logo-home-white.svgRed shapes on white
logo-white.svgWhite fill — dark backgrounds

All assets at /static/img/brand/.

The logo is a diagram, not decoration. Every appearance should feel like a system, not a brand mark.


Component Inventory

Three design system primitives wrap everything else. The component catalogue lives in Design Language → Primitive Catalogue.

Section

Vertical padding wrapper. Outputs <section>.

<Section spacing="lg" className="bg-stone-50">
{children}
</Section>

Spacing scale: none 0 · sm 24/32 · md 32/48 · lg 48/64 · xl 64/80 (mobile / desktop). Default lg.

Container

Max-width + horizontal padding wrapper. Outputs <div>.

<Container size="md">{children}</Container>

Sizes: sm 640px · md 768px (default for landing) · lg 1024px · xl 1280px. Padding px-4 md:px-6.

SectionHeader

Label + heading + description in consistent sizing and spacing.

<SectionHeader
label="The Tight Five"
heading="Five questions that change everything."
description="Optional supporting text."
dark={false}
/>

Renders: label (mono uppercase) → <h2> (bold) → <p> (muted). Centered, max-width 576px.

Button

<Button variant="primary" size="lg" to="/docs/intention/">
Explore the mental model →
</Button>

Variants: primary (bg-brand · white) · secondary (bg-paper-muted · text-ink) · ghost (transparent · text-ink) · outline (transparent · text-ink · border-edge). Sizes: sm md lg. All rounded-full.


Multi-page venture packages need persistent nav so readers don't lose their place on long pages.

Component: ProposalNavigation — JSON-driven, two-row, sticky.

<ProposalNavigation venture={ventureJson} currentPage="business-plan" />

Structure:

Row 1 (always): ← Ventures | Venture Name | Section tabs
Row 2 (context): Sub-tabs — only when the active section has children

Key decisions:

DecisionChoiceWhy
Data sourceventure.nav.sections JSONOne component, every venture
Stickysticky top-0 z-50Long pages — nav must persist
Active indicatorborder-b-2 border-brandUnderline pattern, no fill
Accessibilityaria-current="page" on active tabWCAG 2.2 — screen reader orientation
Containerrole="navigation" + aria-label={venture.name}Multiple navs on page — must be labelled
Children triggerAny section with children[] shows Row 2Data-driven, no special casing

Nav schema in venture JSON:

"nav": {
"sections": [
{ "id": "overview", "label": "Overview", "path": "/ventures/{slug}/" },
{ "id": "business-plan", "label": "Think Slow", "path": "/ventures/{slug}/business-plan/",
"children": [
{ "id": "business-plan", "label": "Business Plan", "path": "..." },
{ "id": "pitch", "label": "Pitch", "path": "..." }
]
},
{ "id": "prompt-deck", "label": "Act Fast", "path": "/ventures/{slug}/prompt-deck/" }
]
}

Labels teach the mental model: Overview (what) → Think Slow (why) → Act Fast (do). The tab names are not arbitrary — they communicate the proposal arc before the reader clicks.


Landing Page Sequence

Every section follows this exact structure:

<Section spacing="lg" className={/* bg-stone-50 for alternating */}>
<Container size="md">
<div className="space-y-8">
<SectionHeader label="..." heading="..." description="..." />
{/* section content */}
</div>
</Container>
</Section>

Section sequence

#SectionRoleBackground
1HeroHookbg-ink
2EnemyFearwhite
3ProblemTensionwhite
4LoopVisual transitionwhite
5Control SystemFramebg-stone-50
6Tight FiveProtocolwhite
7BeingsEdgebg-stone-50
8BelongingCommunitywhite
9FactoriesProofbg-stone-50
10CTAActionbg-ink

Narrative arc: problem → mechanism → framework → application → community → action.

Background alternation

bg-ink → Hero, CTA (dark bookends)
white → Primary content sections
bg-stone-50 → Alternating content sections (warm gray)

bg-stone-50 is a Tailwind default, not a custom token. Used for warmth over bg-gray-50.


Global

All links: font-weight: 600, no underline by default. On hover: color: brand, underline 2px with 3px offset.

On dark backgrounds

text-chalk underline hover:text-chalk-light

Links on bg-ink sections are always underlined (no other affordance on dark). This is the explicit exception to the "no underline by default" rule — context-driven, not a contradiction.

text-brand hover:underline font-medium

Used inline where the link IS the emphasis.

All rounded-full elements suppress underline on hover via CSS override.


Docusaurus IFM Cascade Fix

Infima's unlayered CSS rules override Tailwind's @layer utilities. Compound selectors with !important are required for headings and links on landing pages:

h1.text-chalk {
color: var(--color-chalk) !important;
}
a.text-brand {
color: var(--color-brand) !important;
}

These live in custom.css. Do not remove them — without the !important overrides, Infima reverts colours and the landing page looks broken on dark sections.

IFM variable mapping

Design tokens map to Docusaurus Infima variables in :root:

Our tokenMaps to
--color-brand--ifm-color-primary
--color-brand-dark--ifm-color-primary-dark
--color-brand-light--ifm-color-primary-light
--font-sans--ifm-font-family-base
--font-mono--ifm-font-family-monospace
--color-ink--ifm-link-color
--color-brand--ifm-link-hover-color

CSS load order (this repo)

@tailwind base/components/utilities ← Framework first (required for v3)
:root { } ← Token definitions
Infima cascade fix ← !important overrides
IFM variable mapping ← var(--color-*) → --ifm-*
Component styles ← Navbar, footer, links

For Tailwind v4 (greenfield apps, not this repo), @import "tailwindcss" replaces the three @tailwind directives and the layer order shifts. See Tailwind v4 Theme. For this repo's v3 specifics see src/css/CLAUDE.md.


Light Mode Only

Dark mode is disabled. The colour mode toggle is hidden via CSS. No dark: classes are used anywhere on the site.

The amended rule allowing deliberate dark themes per component (when WCAG-cached + runtime-gated) lives in Design Language → No Dark Mode Amended. The site-wide rule stands; per-component themes earn their exception.


Context