MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-11

1.0.5.1 Design system architecture — two-axis theme (Color + Shape), one initial palette, DESIGN.md

Done
Description

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:

  1. Fetch both source design systems: npx getdesign@latest add notion and npx getdesign@latest add figma. These drop DESIGN.md-format files into the project; identify where they land (likely ./DESIGN-notion.md / ./DESIGN-figma.md or ./design/ subfolder).
  2. 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.
  3. 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: just default and 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.
  4. Build a ThemeProvider React context at lib/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. Injects data-theme, data-color, data-display-style attrs on <html>. Wrapped around the app in app/layout.tsx.
  5. Update app/page.tsx to use Tailwind token classes (e.g., bg-background text-foreground) — no text-[var(--text)] bracket syntax, no hardcoded hex codes.
  6. 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.
  7. Write docs/DESIGN.md in Stitch format. The 9 canonical sections:
    1. Visual Theme & Atmosphere
    2. Color Palette & Roles (semantic names, hex values, when to use each)
    3. Typography Rules (font families, hierarchy, sizes, weights, line heights)
    4. Component Stylings (buttons, cards, inputs — interactive states; mostly empty initially, fills as 1.0.5.2 lands)
    5. Layout Principles (spacing scale, grid, whitespace strategy)
    6. Depth & Elevation (shadow tokens, surface tiers)
    7. Do's and Don'ts (design guardrails)
    8. Responsive Behavior (breakpoints, touch targets)
    9. 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.
  8. 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.
  9. Verify all 4 quality gates: lint, format:check, typecheck, build.

Acceptance criteria

Layered CSS architecture:

  • app/globals.css has 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 like soft or flat) to prove the mechanism. More can land in follow-up Subtasks.
  • Element tokens (--el-*) are MINIMAL (~10-15 covering only what app/page.tsx + /tokens route 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-card all work in JSX.
  • No hardcoded hex colors in /app or /components (grep-check before committing).

ThemeProvider:

  • lib/contexts/theme-context.tsx exports ThemeProvider + useTheme() hook. State: themePattern, displayStyle. Persists to localStorage; rehydrates on mount.
  • Injects data-theme and data-display-style attrs on <html> via document.documentElement.setAttribute in 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/google in app/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>.
  • @theme exposes those as Tailwind utility classes — font-sans, font-serif, font-mono all 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.tsx uses 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.tsx renders 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.md exists 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 build all pass with zero warnings.
  • CI green on the PR.
  • The /tokens route renders correctly on the Vercel preview deploy.

Context refs

  • getdesign.md — the spec collection; npx getdesign@latest add notion and add figma fetch 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 (read index.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, no tailwind.config.ts in 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
Status
Done
Type
Sub-task