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:
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).app/globals.css:
--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.[data-theme="dark"] selector overrides the base vars for dark mode.[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).--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.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.app/page.tsx to use Tailwind token classes (e.g.,
bg-background text-foreground) — no text-[var(--text)]
bracket syntax, no hardcoded hex codes.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.docs/DESIGN.md in Stitch format. The 9 canonical sections:
docs/inspiration/
folder as references. Flag the choice in the PR.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.default + one alternate like
soft or flat) to prove the mechanism. More can land in
follow-up Subtasks.--el-*) are MINIMAL (~10-15 covering only what
app/page.tsx + /tokens route actually use). Token growth
is documented as deferred to future Subtasks.bg-background, text-foreground,
bg-primary, text-muted, rounded-card,
shadow-card all work in JSX./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.data-theme and data-display-style attrs on
<html> via document.documentElement.setAttribute in
useEffect (server-rendered HTML stays clean; client hydrates and applies).app/layout.tsx.Typography:
next/font/google in app/layout.tsx:
Inter (variable, sans), Source Serif 4 (variable, serif), JetBrains Mono (variable,
mono).--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.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.Quality gates:
pnpm lint, pnpm format:check, pnpm typecheck,
pnpm build all pass with zero warnings./tokens route renders correctly on the Vercel preview deploy.npx getdesign@latest add notion and add figma fetch source files/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@theme inline, no tailwind.config.ts in the repoapp/globals.css (current state from 1.0.1 — base 8 tokens already there)