1.0.5.1 Design system architecture — two-axis theme (Color + Shape), one initial palette, DESIGN.md
Estimate: 30m · Depends on: 1.0.1
Set up Motir's two-axis theme architecture (Color × Shape, mirroring dooooWeb's implementation) and ship ONE initial palette + display style. Write Motir's DESIGN.md in Google Stitch format (9 sections) as the planner-agent reference document — Epic 4 will inject this into every design-type Subtask prompt.
Why this architecture: users want to customize their workspace look. Hard-coding one palette into globals.css would force a rebuild for every theme change. The two-axis pattern lets users flip data-palette="warm" or data-display-style="soft" on <html> and the entire UI updates via CSS only — no React re-render. dooooWeb proved this works at scale.
Source for the initial palette: Motir's first palette is a blend of Notion's colors (warm earthy minimalism — terracotta, ochre, sage, soft surfaces) and Figma's shape language (vibrant, playful, energetic component shapes). The coding agent fetches both via npx getdesign@latest add notion and add figma, then synthesizes. The DESIGN.md documents Motir's blended choices, not Notion's or Figma's verbatim.
Typography stack (locked): Inter (variable) for sans body + UI, Source Serif 4 (variable) for serif headings — Adobe's humanist serif made for the Notion-style pairing, JetBrains Mono (variable) for code blocks + IDs. All loaded via next/font/google as variable fonts (~150 KB total for all weights, vs ~500 KB if loaded as separate weight files). Each is open-source. See notes.html mistake #1 framing: this is a deliberate choice with reasoning, not a default-by-accident.
Why "warm not cold": per Yue's direction, AI-native ≠ technical-cold. Notion's warm minimalism is the explicit antidote to the "AI tools look like terminals" aesthetic. Figma's shape personality adds energy without sacrificing approachability.
Token-growth principle (anti-overplanning): dooooWeb has ~700 lines of element tokens (--el-*) because it has a full UI. Motir has ZERO real UI components yet. Start with the bare minimum (~10-15 element tokens covering page bg / text / accent / surface / border). As Story 1.0.5's component primitives (1.0.5.2: Button/Input/Card/etc.) land, each one ADDS its own element tokens. Do NOT front-load tokens for components that don't exist. See notes.html mistake #20 on not re-deriving generic boilerplate.
What you'll do:
- Fetch both source design systems:
npx getdesign@latest add notionandnpx getdesign@latest add figma. These drop DESIGN.md-format files into the project; identify where they land (likely./DESIGN-notion.md/./DESIGN-figma.mdor./design/subfolder). - Synthesize ONE palette from Notion's colors + Figma's shape tokens. Pull concrete hex values from Notion's file (light + dark mode if both are documented) and shape/radius/shadow/spacing values from Figma's.
- Build the layered CSS architecture in
app/globals.css:- Tier 0 — Base @theme block:
--color-*(primary, secondary, accent, background, foreground, surface, muted, border, etc.) +--radius-*+--shadow-*+--spacing-*+ typography (--font-sans,--font-serif,--font-size-*). These get auto-exposed as Tailwind utility classes (bg-primary, rounded-card, shadow-elevated, etc.) by Tailwind v4's @theme inline. - Tier 1 — Light/dark base:
[data-theme="dark"]selector overrides the base vars for dark mode. - Tier 2 — Display style overrides:
[data-display-style="soft"],[data-display-style="flat"],[data-display-style="pill"]overrides radius/shadow/spacing tokens (initially: justdefaultand one alternate to prove the mechanism works; more can be added later). - Tier 3 — Element-token layer:
--el-*tokens for page/surface/text/border, referencing Tier 0's--color-*. Keep minimal — 10-15 tokens for what currently exists. This is the abstraction layer that future palettes will override.
- Tier 0 — Base @theme block:
- Build a
ThemeProviderReact context atlib/contexts/theme-context.tsx(mirroring dooooWeb's pattern). Three state values:themePattern(system | light | dark),themeColor(the accent color, initially just one option),displayStyle(default | one alternate). Persists to localStorage. Injectsdata-theme,data-color,data-display-styleattrs on<html>. Wrapped around the app inapp/layout.tsx. - Update
app/page.tsxto use Tailwind token classes (e.g.,bg-background text-foreground) — notext-[var(--text)]bracket syntax, no hardcoded hex codes. - Build
app/tokens/page.tsx— the design-system reference route at/tokens. Renders: all color swatches with names + hex, type scale samples (xs/sm/base/lg/xl with line heights visible), radius samples (each--radius-*rendered as a box), shadow samples, a button stub in each display-style to visually compare. This is the live spec; 1.0.5.5 will screenshot it. - Write
docs/DESIGN.mdin Stitch format. The 9 canonical sections:- Visual Theme & Atmosphere
- Color Palette & Roles (semantic names, hex values, when to use each)
- Typography Rules (font families, hierarchy, sizes, weights, line heights)
- Component Stylings (buttons, cards, inputs — interactive states; mostly empty initially, fills as 1.0.5.2 lands)
- Layout Principles (spacing scale, grid, whitespace strategy)
- Depth & Elevation (shadow tokens, surface tiers)
- Do's and Don'ts (design guardrails)
- Responsive Behavior (breakpoints, touch targets)
- Agent Prompt Guide (color references for AI use — what to inject into Subtask prompts) Reference DESIGN-notion.md and DESIGN-figma.md as inspiration sources at the top.
- Optional cleanup: delete the fetched DESIGN-notion.md / DESIGN-figma.md files if
they're not useful long-term; OR keep them in a
docs/inspiration/folder as references. Flag the choice in the PR. - Verify all 4 quality gates: lint, format:check, typecheck, build.
Acceptance criteria
Layered CSS architecture:
app/globals.csshas all four tiers (@theme base; light/dark; display-style overrides;--el-*element tokens) with comments explaining each tier.- At minimum 2 display styles wired up (
default+ one alternate likesoftorflat) to prove the mechanism. More can land in follow-up Subtasks. - Element tokens (
--el-*) are MINIMAL (~10-15 covering only whatapp/page.tsx+/tokensroute actually use). Token growth is documented as deferred to future Subtasks. - Tailwind classes like
bg-background,text-foreground,bg-primary,text-muted,rounded-card,shadow-cardall work in JSX. - No hardcoded hex colors in
/appor/components(grep-check before committing).
ThemeProvider:
lib/contexts/theme-context.tsxexportsThemeProvider+useTheme()hook. State:themePattern,displayStyle. Persists to localStorage; rehydrates on mount.- Injects
data-themeanddata-display-styleattrs on<html>viadocument.documentElement.setAttributein useEffect (server-rendered HTML stays clean; client hydrates and applies). - Wrapped around the app in
app/layout.tsx.
Typography:
- Three fonts loaded via
next/font/googleinapp/layout.tsx: Inter (variable, sans), Source Serif 4 (variable, serif), JetBrains Mono (variable, mono). - Each font assigned a CSS variable (
--font-sans,--font-serif,--font-mono) via the next/font className pattern on<html>. @themeexposes those as Tailwind utility classes —font-sans,font-serif,font-monoall work.- Body text uses Inter by default. Headings (h1, h2, h3) use Source Serif 4 by default — set via a base CSS rule or Tailwind plugin.
Pages:
app/page.tsxuses Tailwind token classes; the wordmark renders in Source Serif 4 (the headline font); visual matches Notion's warm minimalism with Figma's shape personality.app/tokens/page.tsxrenders all color swatches, type scale (each size labeled with its name + font family), radius/shadow samples, and a button stub per display-style.
DESIGN.md:
docs/DESIGN.mdexists in Google Stitch's 9-section format.- Content reflects Motir's blended choices, not Notion's or Figma's verbatim. The top of the file credits both as inspiration sources.
- The "Agent Prompt Guide" section is concrete enough that Epic 4's planner can inject it directly into design-type Subtask prompts.
Quality gates:
pnpm lint,pnpm format:check,pnpm typecheck,pnpm buildall pass with zero warnings.- CI green on the PR.
- The
/tokensroute renders correctly on the Vercel preview deploy.
Context refs
- getdesign.md — the spec collection;
npx getdesign@latest add notionandadd figmafetch source files - Google Stitch DESIGN.md format — the 9-section spec
- voltagent/awesome-design-md — collection of real DESIGN.md examples
/Users/yuezhu/projects/doooo/dooooWeb/src/styles/— reference implementation of the two-axis architecture (readindex.css+element-tokens.css+ a palette file)/Users/yuezhu/projects/doooo/dooooWeb/src/lib/contexts/theme-context.tsx— reference for the React provider pattern- Tailwind v4 (NOT v3) — theme tokens live in CSS via
@theme inline, notailwind.config.tsin the repo app/globals.css(current state from 1.0.1 — base 8 tokens already there)- Next.js next/font docs — loading + CSS variables pattern
- Inter, Source Serif 4, JetBrains Mono — the three variable fonts to load