Build four form primitives from Figma references with brand-aligned creative decisions: restrained press states (scale-95 instead of highlight splashes), clean iconless Switch, and consistent error states with inline warning icons. Introduce form-control semantic tokens (--color-control-*) in tokens.css so all form components share a single source for borders, checked states, focus rings, labels, and errors. Retrofit Input to use these tokens instead of direct palette references. Update CLAUDE.md and ARCHITECTURE.md with token layer documentation, token discipline rule (no palette references in components), and component tier decision criteria. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
149 lines
6.6 KiB
Markdown
149 lines
6.6 KiB
Markdown
# ARCHITECTURE.md — SDC-Frontend
|
|
|
|
This is the living architecture document for the SDC-Frontend design system. All structural decisions are recorded here. Update this document when the architecture evolves — never let the codebase and this document drift apart.
|
|
|
|
---
|
|
|
|
## 1. Overview
|
|
|
|
SDC-Frontend is a React component library and design system that will serve as the frontend for the Research Synthesiser. It is built in phases:
|
|
|
|
1. **Design system** — tokens, primitives, composite components
|
|
2. **Application screens** — the synthesiser UI rebuilt on top of the design system
|
|
|
|
---
|
|
|
|
## 2. Token Pipeline
|
|
|
|
```
|
|
Figma (design tool)
|
|
↓ Figma MCP / get_variable_defs
|
|
src/tokens/tokens.css (@theme block)
|
|
↓ Tailwind CSS v4 reads @theme
|
|
↓ Generates utility classes + CSS custom properties
|
|
Components (use Tailwind utilities or var() references)
|
|
↓ Rendered in
|
|
Storybook (visual verification)
|
|
```
|
|
|
|
### Token Layers
|
|
Tokens are structured in three layers:
|
|
|
|
1. **Palette** — raw colour values (`--color-blue-01`, `--color-grey-03`). Not used directly in components.
|
|
2. **Semantic** — purpose-based aliases (`--color-primary`, `--color-error`, `--color-text`). General UI usage.
|
|
3. **Form control** — shared interactive-state tokens for all form components (`--color-control-border`, `--color-control-checked`, `--color-control-label`, etc.). Ensures consistent styling across Input, Checkbox, Radio, Switch, Select, and future form primitives.
|
|
|
|
### Token Categories
|
|
- **Palette colours**: `--color-{palette}-{shade}` (e.g., `--color-blue-01`, `--color-grey-03`)
|
|
- **Semantic colours**: `--color-{purpose}` (e.g., `--color-primary`, `--color-error`, `--color-text`)
|
|
- **Form control colours**: `--color-control-{role}` (e.g., `--color-control-border`, `--color-control-checked`)
|
|
- **Radii**: `--radius-*` (sm, default, lg, full)
|
|
- **Shadows**: `--shadow-*` (default, md)
|
|
|
|
### How Tailwind v4 @theme Works
|
|
Declaring `--color-primary: #2563eb` inside `@theme` in `tokens.css` automatically generates utilities like `bg-primary`, `text-primary`, `border-primary`. No JavaScript config file needed — the CSS file is the config.
|
|
|
|
---
|
|
|
|
## 3. Component Taxonomy
|
|
|
|
### `src/components/ui/` — Primitives
|
|
Atomic, reusable building blocks. Each is self-contained with no domain logic.
|
|
- Button, Input, Checkbox, Radio/RadioGroup, Switch
|
|
- Textarea, Select
|
|
- Card, Badge, Tag
|
|
- Dialog, Tooltip, Popover
|
|
|
|
### `src/components/composite/` — Composed Components
|
|
Built from primitives, may carry light domain semantics.
|
|
- StatusMessage (success/error/warning/info)
|
|
- TabBar, TabPanel
|
|
- ThemeCard (maps to synthesiser's theme display)
|
|
|
|
### `src/components/layout/` — Layout
|
|
Page-level structural components.
|
|
- AppShell (header + sidebar + content area)
|
|
- PageHeader
|
|
|
|
### Which Tier Does a Component Belong To?
|
|
|
|
| Question | If yes → |
|
|
|---|---|
|
|
| Does it wrap a single native element or a single interaction pattern (button, input, toggle)? | **ui/** (primitive) |
|
|
| Does it compose 2+ primitives into a reusable unit (e.g., a search bar = Input + Button)? | **composite/** |
|
|
| Does it carry domain-specific naming or logic (e.g., ThemeCard, ParticipantRow)? | **composite/** |
|
|
| Does it define a page-level region or shell (header, sidebar, content area)? | **layout/** |
|
|
|
|
When in doubt: start in `ui/`. Promote to `composite/` when a component begins importing other `ui/` components. If the `composite/` directory grows beyond ~15 components, consider splitting it into `molecules/` (generic compositions) and `organisms/` (domain-aware compositions).
|
|
|
|
---
|
|
|
|
## 4. Styling Approach
|
|
|
|
- **Primary**: Tailwind utility classes
|
|
- **Conditional classes**: `cn()` from `@/lib/utils` (clsx + tailwind-merge)
|
|
- **Token values**: Always from `src/tokens/tokens.css`, never hardcoded
|
|
- **Token discipline**: Components reference semantic or form-control tokens, not palette tokens. If the needed semantic token doesn't exist, add it to `tokens.css` before using a raw palette value.
|
|
- **No CSS modules, no styled-components, no inline styles** (except truly dynamic values)
|
|
- **Class ordering**: Enforced by `prettier-plugin-tailwindcss`
|
|
|
|
---
|
|
|
|
## 5. Storybook Conventions
|
|
|
|
- Every component has a co-located `.stories.tsx` file
|
|
- All stories use `tags: ['autodocs']` for auto-generated docs
|
|
- Stories cover: default state, all variants, edge cases, disabled/error states
|
|
- A11y addon runs on all stories — violations should be addressed
|
|
- MCP addon enabled at `localhost:6006/mcp` for AI-assisted development
|
|
|
|
---
|
|
|
|
## 6. Project Structure
|
|
|
|
```
|
|
src/
|
|
├── components/
|
|
│ ├── ui/ # Primitives
|
|
│ ├── composite/ # Composed components
|
|
│ └── layout/ # Layout components
|
|
├── tokens/
|
|
│ └── tokens.css # Design tokens (@theme block)
|
|
├── styles/
|
|
│ └── global.css # Tailwind imports + base styles
|
|
├── lib/
|
|
│ └── utils.ts # cn() utility
|
|
├── hooks/ # Custom React hooks
|
|
├── pages/ # App screens (Phase 2)
|
|
├── App.tsx # Root component
|
|
└── main.tsx # Vite entry point
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Design Tool Integration
|
|
|
|
### Figma
|
|
- Project file: https://www.figma.com/design/mrabO6AtxN3ektGiTk0I9c/ResearchInsights (file key: `mrabO6AtxN3ektGiTk0I9c`)
|
|
- MCP server: Official Figma Remote MCP at `https://mcp.figma.com/mcp` (HTTP transport, OAuth auth)
|
|
- Key tools: `get_design_context`, `get_variable_defs`, `get_screenshot`, `search_design_system`, `use_figma`
|
|
- Design tokens extracted via `get_variable_defs` → mapped to `@theme` values in `tokens.css`
|
|
|
|
### Code Connect
|
|
- Links Figma components to their React implementations
|
|
- Once linked, `get_design_context` returns actual component code instead of generic markup
|
|
- Mapped as we build each component via `add_code_connect_map` (label: "React")
|
|
|
|
### Storybook MCP
|
|
- Available at `localhost:6006/mcp` when Storybook dev server is running
|
|
- Provides: component listing, documentation retrieval, story generation, a11y testing
|
|
- `@storybook/addon-designs` embeds Figma frames in the story panel for side-by-side comparison
|
|
- `@storybook/addon-mcp` serves the MCP endpoint
|
|
|
|
### claude2figma Skills
|
|
- 4 skills in `.claude/skills/` that enforce design system compliance when writing to Figma
|
|
- **figma-preflight**: Validates MCP connection, audits libraries, builds a Token Map of all styles/variables
|
|
- **component-rules**: Library-first lookup, Auto Layout conventions, semantic node naming
|
|
- **figma-style-binding**: All visual values must bind to Figma Styles or Variables, never hardcoded; includes post-write QA
|
|
- **reference-interpreter**: Converts screenshots/references into structured Design Briefs mapped to design tokens
|