recipe-manager/.harness/docs/styling-token-contract.md

51 lines
2.1 KiB
Markdown

# Styling Token Contract (T02)
Date: 2026-03-27
Scope: `recipe-manager/frontend`
## Canonical token source
**Single source of truth:**
- `src/styles/tokens.css`
All design-token values (color, typography scales, spacing, radius, elevation/focus) must be authored in `tokens.css` first.
## Allowed token consumption paths
1. **Preferred in UI markup:** tokenized classes and `ui-*` primitives from `src/index.css`
- Examples: `ui-card`, `ui-btn`, `text-[var(--text)]`, `border-[var(--border)]`
2. **Tailwind theme keys** mapped to CSS vars in `tailwind.config.js`
- Examples: `bg-surface`, `text-primary`, `shadow-card`
3. **TS access layer:** `src/theme.ts`
- Must expose `var(--...)` references only.
- Must not hardcode competing token values.
## Explicit non-contract patterns
- Do **not** introduce new hardcoded design-token values in `theme.ts`.
- Do **not** define duplicate token constants in TS that can drift from `tokens.css`.
- Avoid ad-hoc palette classes (`bg-blue-*`, `text-slate-*`, etc.) in shared shell/feature UI when tokenized equivalents exist.
## `theme.ts` role after T02
`theme.ts` is now a **typed token accessor/compatibility layer**, not an independent token definition file.
- ✅ Allowed: `colors.primary = 'var(--color-primary)'`
- ❌ Not allowed: `colors.primary = '#ea580c'`
If a token does not exist yet:
1. Add it to `tokens.css`
2. (Optional) Map it in `tailwind.config.js` if utility-class access is needed
3. Expose accessor in `theme.ts` only as `var(--token-name)`
## Practical authoring guide (for future tasks)
- Use `ui-*` classes first for common controls/layout shells.
- Use tokenized Tailwind utilities or `var(--...)` references for one-off styling.
- Keep inline `style={{ ... }}` for runtime/dynamic values only (e.g., tag color from DB), not for static design tokens.
## Current known exceptions (post-T02)
- Some components/pages still import `radius`/`colors` from `theme.ts` for inline styling; values are now token references, so no hardcoded drift remains.
- `recipeAccentPalette` still includes a few non-tokenized accent hexes pending a future semantic palette pass.