@spark-web/design-system 5.0.99 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md ADDED
@@ -0,0 +1,274 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with
4
+ code in this repository.
5
+
6
+ ## Overview
7
+
8
+ Spark Web is the Brighte Design System — a React component library organized as
9
+ a Yarn monorepo (~50 packages). It uses Preconstruct for bundling, Emotion for
10
+ CSS-in-JS, and Changesets for versioning.
11
+
12
+ ## Common Commands
13
+
14
+ ```bash
15
+ # Development
16
+ yarn dev # Run docs, playroom, and storybook concurrently
17
+ yarn dev:storybook # Storybook only (port 6006)
18
+ yarn dev:docs # Next.js docs site only
19
+ yarn dev:playroom # Playroom only
20
+
21
+ # Testing
22
+ yarn test:unit # Run all Jest tests
23
+ yarn test:unit -- --testPathPatterns=packages/alert # Run tests for a specific package
24
+ yarn check # Run format + lint + package + type checks
25
+
26
+ # Linting & Formatting
27
+ yarn check:lint # ESLint check
28
+ yarn fix:lint # ESLint autofix
29
+ yarn check:format # Prettier check
30
+ yarn fix:format # Prettier autoformat
31
+
32
+ # Build
33
+ yarn build:packages # Build all packages via Preconstruct
34
+ yarn build:docs # Build docs site
35
+
36
+ # Package management
37
+ yarn new:package # Scaffold a new component package via Plop
38
+ yarn release # Build + publish to npm (CI only)
39
+ ```
40
+
41
+ ## How to approach any build task
42
+
43
+ When given any build task — whether a PRD, a feature description, or a prompt —
44
+ always follow this sequence before writing any code. Do not skip steps. Do not
45
+ ask for clarification before completing step 1.
46
+
47
+ ### Step 1 — Classify the surface
48
+
49
+ Read node_modules/@spark-web/design-system/patterns/CLAUDE.md in full. Determine
50
+ which surface type the task is for based on language in the PRD:
51
+
52
+ - "admin portal", "admin", "internal", "back office", "manage", "ops" → Internal
53
+ admin
54
+ - "vendor portal", "vendor", "accreditation", "installer" → Vendor portal (not
55
+ yet defined — flag to team)
56
+ - "website", "marketing", "landing page", "public" → Website (not yet defined —
57
+ flag to team)
58
+ - "mobile", "app", "iOS", "Android" → Mobile app (not yet defined — flag to
59
+ team)
60
+
61
+ If the surface cannot be determined from the PRD, flag it and ask before
62
+ proceeding. Do not assume.
63
+
64
+ ### Step 2 — Read the surface rules
65
+
66
+ Read the surface rules file for the classified surface. For internal admin: read
67
+ node_modules/@spark-web/design-system/patterns/internal-admin/CLAUDE.md in full.
68
+ Surface rules take precedence over all component rules.
69
+
70
+ If the surface is not yet defined, flag it to the team and do not proceed with
71
+ building until the surface rules exist.
72
+
73
+ ### Step 3 — Identify the feature type and read the pattern file
74
+
75
+ Match the task to a pattern file in the surface folder:
76
+
77
+ - List of records, manage, view all, search, filter →
78
+ node_modules/@spark-web/design-system/patterns/internal-admin/list-page.md
79
+ - Create or edit a record, form →
80
+ node_modules/@spark-web/design-system/patterns/internal-admin/form-page.md
81
+ (not yet defined)
82
+ - Record detail, view details, drill down →
83
+ node_modules/@spark-web/design-system/patterns/internal-admin/detail-page.md
84
+ (not yet defined)
85
+
86
+ Read the pattern file in full. It defines which components to assemble, in what
87
+ order, and with what rules. Follow it exactly.
88
+
89
+ If no pattern file exists for the feature type, use the surface rules and
90
+ component documentation to make the best decision, then flag that a pattern file
91
+ should be created for this feature type before the next similar build.
92
+
93
+ ### Step 4 — Read the relevant component CLAUDE.md files
94
+
95
+ Only read the components the pattern file tells you to use. Do not read all
96
+ component files — only the ones needed for this specific feature.
97
+
98
+ ### Step 5 — Read the component stories
99
+
100
+ Read the Storybook story file for each component you will use. Stories show
101
+ correct real-world usage examples that the CLAUDE.md documentation alone may not
102
+ fully cover.
103
+
104
+ ### Step 6 — Assemble, do not invent
105
+
106
+ Use only components that exist in packages/. Do not build custom components or
107
+ apply custom styling outside of the documented exceptions in each component
108
+ CLAUDE.md.
109
+
110
+ If a feature requires something that does not exist in packages/:
111
+
112
+ - Use the closest available Spark primitive as a placeholder
113
+ - Add a comment in the generated code: // COMPONENT GAP: [ComponentName] needed
114
+ — not yet in Spark
115
+ - Flag it clearly in your response as a gap to be formalised into the design
116
+ system before this feature ships
117
+
118
+ ### Step 7 — Validate before marking complete
119
+
120
+ Run the validation checklist from the pattern file before marking the task
121
+ complete. Fix all violations before responding. A task is not complete until all
122
+ checklist items pass.
123
+
124
+ ---
125
+
126
+ ## Uplift protocol
127
+
128
+ When uplifting an existing page to match a pattern, follow the same 7 steps but
129
+ with these additions:
130
+
131
+ Before Step 6, run the pattern's validation checklist against the existing file.
132
+ Report every PASS and FAIL. This is mandatory — do not skip it.
133
+
134
+ If any checklist failure requires changing the component tree structure — such
135
+ as replacing a custom component with a Spark component, restructuring how
136
+ columns are defined, or replacing a custom loading/empty pattern with a built-in
137
+ prop — scaffold a new file using the structural skeleton from the pattern file
138
+ and migrate data and logic into it. Do not patch the existing file
139
+ incrementally.
140
+
141
+ If all failures are prop-level or styling fixes that do not change the component
142
+ tree, you may modify the existing file in place.
143
+
144
+ In either case, the pattern file is authoritative. Do not preserve existing
145
+ structure that conflicts with the pattern. Treat the current implementation as
146
+ data input (what fields exist, what the page does), not as a structural
147
+ reference.
148
+
149
+ Before writing any code, state whether you are (a) rebuilding from the pattern's
150
+ structural skeleton or (b) modifying in place, and justify your choice by
151
+ listing which failures are structural versus prop-level.
152
+
153
+ ---
154
+
155
+ ## Architecture
156
+
157
+ The agent reading order for any build task is defined in "How to approach any
158
+ build task" above. Always follow that sequence. Never jump directly to component
159
+ documentation without first reading the surface classifier and pattern files.
160
+
161
+ ### Monorepo Structure
162
+
163
+ - `packages/` — ~50 component packages, each published as `@spark-web/{name}`
164
+ - `docs/` — Next.js documentation site with Storybook, Playroom, and
165
+ Contentlayer
166
+ - `examples/` — Reference Next.js apps (example-site, preapprovals)
167
+ - `scripts/` + `plop-templates/` — Package scaffolding
168
+
169
+ ### Dependency Layers
170
+
171
+ **Foundation** (no internal deps): `utils`, `theme`, `ssr`
172
+
173
+ **Core components**: `a11y`, `box`, `text`, `icon` — depend on foundation
174
+
175
+ **Composition layer**: Layout (`stack`, `row`, `columns`, `container`,
176
+ `inline`), form inputs, complex components — compose from core
177
+
178
+ **Integration**: `next-utils`, `design-system` (barrel re-export of all
179
+ packages)
180
+
181
+ ### Component Package Structure
182
+
183
+ Each package under `packages/{name}/src/` typically contains:
184
+
185
+ - `{ComponentName}.tsx` — Main component
186
+ - `{component-name}.stories.tsx` — Storybook stories
187
+ - `{component-name}.test.tsx` — Jest + Testing Library unit tests
188
+ - `types.ts` — Shared type definitions
189
+ - `index.ts` — Public exports
190
+
191
+ Preconstruct generates dual CJS/ESM bundles in `dist/`.
192
+
193
+ ### Styling
194
+
195
+ All styling uses Emotion (CSS-in-JS). Components access the design token system
196
+ via `useTheme()` from `@spark-web/theme`. The theme provides color tones
197
+ (primary, secondary, positive, caution, critical, info), typography scales, and
198
+ spacing utilities. Never use raw CSS values — always use theme tokens.
199
+
200
+ ### Key Patterns
201
+
202
+ - **Composition**: Components are built by composing smaller components (Box,
203
+ Text, Icon, Row, Stack)
204
+ - **Responsive**: Use theme utilities and Facepaint for responsive styles — not
205
+ media query literals
206
+ - **Accessibility**: All components include proper ARIA attributes; use
207
+ `@spark-web/a11y` utilities
208
+ - **`data` prop**: Components support a `data` prop for test selectors and
209
+ analytics
210
+ - **TypeScript discriminated unions**: Used for related props that must appear
211
+ together (e.g., `onClose` requires `closeLabel`)
212
+ - **`forwardRef`**: Used on all interactive/DOM-exposed components
213
+
214
+ ### Releases
215
+
216
+ Changesets manages versioning. To add a changeset for your PR: `yarn changeset`.
217
+ Snapshot releases can be triggered on a PR by commenting `/snapit`.
218
+
219
+ ### Pattern library
220
+
221
+ Agent pattern and surface rules live in
222
+ `node_modules/@spark-web/design-system/patterns/`. Always read
223
+ `node_modules/@spark-web/design-system/patterns/CLAUDE.md` before any build
224
+ task.
225
+
226
+ ## New packages (in progress)
227
+
228
+ ### data-table
229
+
230
+ TanStack Table v8-based table. See node_modules/@spark-web/data-table/CLAUDE.md
231
+ before writing any code using this package. Exports a single `DataTable`
232
+ component — not composable sub-components.
233
+
234
+ Key rules:
235
+
236
+ - Single `DataTable` component, not composable sub-components
237
+ - Use `createColumnHelper` from this package for type-safe column defs
238
+ - Pagination handled externally — never put pagination inside DataTable
239
+ - All values from useTheme() tokens — never raw hex, px, or Tailwind
240
+
241
+ ### meatball-menu
242
+
243
+ Three-dot dropdown for 2+ record-level actions. See
244
+ node_modules/@spark-web/meatball-menu/CLAUDE.md. Usage rules:
245
+ node_modules/@spark-web/design-system/patterns/internal-admin/CLAUDE.md.
246
+
247
+ ### section-header
248
+
249
+ Section-level heading bar with optional action. See
250
+ node_modules/@spark-web/section-header/CLAUDE.md. Depends on:
251
+ @spark-web/status-badge, @spark-web/meatball-menu.
252
+
253
+ ### status-badge
254
+
255
+ Standalone label pill with colored background and optional icon. No dot. See
256
+ node_modules/@spark-web/status-badge/CLAUDE.md. Tones: accent, positive,
257
+ caution, critical, info, neutral. Only used in PageHeader and SectionHeader via
258
+ their `statusBadge` prop — never in table status columns. Use @spark-web/badge
259
+ for table status columns and any dot+label pattern.
260
+
261
+ ### base-edit-modal
262
+
263
+ Reusable modal shell for all edit and action modals. Pinned header + scrollable
264
+ body + pinned footer. Depends on: @spark-web/modal-dialog. Never pass
265
+ scrollable={false}. Never use control as a prop.
266
+
267
+ ### portal-table
268
+
269
+ Label/value display component for structured record data in admin interfaces.
270
+ Not a data table — use @spark-web/data-table for sortable paginated lists.
271
+ Depends on: @spark-web/stack, @spark-web/box, @spark-web/row,
272
+ @spark-web/heading, @spark-web/button, @spark-web/text-link, @spark-web/text,
273
+ @spark-web/meatball-menu, @spark-web/inline. rows prop is a typed array — never
274
+ JSX children.
@@ -0,0 +1,158 @@
1
+ # Layer 1 — Root CLAUDE.md
2
+
3
+ ## What this layer is
4
+
5
+ The root `CLAUDE.md` sits at the top of the repository. It is the first file an
6
+ AI agent reads in any session. Its job is to orient the agent: what this repo
7
+ is, how it is structured, and — most importantly — **what reading order to
8
+ follow before writing any code**.
9
+
10
+ Think of it as the agent's onboarding document. Without it, an agent has no
11
+ contract to work from and will make assumptions. With it, every build task
12
+ starts from the same controlled entry point.
13
+
14
+ ---
15
+
16
+ ## Where it lives
17
+
18
+ ```
19
+ /CLAUDE.md ← root of the repository
20
+ ```
21
+
22
+ ---
23
+
24
+ ## What it must contain
25
+
26
+ ### 1. Repo overview (2–4 sentences)
27
+
28
+ A plain-language description of what the codebase is — the tech stack, the
29
+ package structure, and the general purpose. This gives the agent enough context
30
+ to interpret file paths and package names correctly.
31
+
32
+ ```markdown
33
+ ## Overview
34
+
35
+ Spark Web is the Brighte Design System — a React component library organized as
36
+ a Yarn monorepo (~50 packages). It uses Preconstruct for bundling, Emotion for
37
+ CSS-in-JS, and Changesets for versioning.
38
+ ```
39
+
40
+ ### 2. Common commands
41
+
42
+ Shell commands the agent can run for development, testing, building, and
43
+ linting. These prevent the agent from guessing or inventing commands.
44
+
45
+ ```markdown
46
+ ## Common Commands
47
+
48
+ yarn test:unit yarn check yarn build:packages
49
+ ```
50
+
51
+ ### 3. The build task reading order — the most critical section
52
+
53
+ This is the mechanism that enforces layered reading. It is a numbered sequence
54
+ of steps the agent **must** follow before writing any code. Each step references
55
+ a specific file or layer. The agent is explicitly told never to skip steps.
56
+
57
+ ```markdown
58
+ ## How to approach any build task
59
+
60
+ ### Step 1 — Classify the surface
61
+
62
+ Read docs/patterns/CLAUDE.md in full. Determine which surface type the task is
63
+ for based on language in the PRD.
64
+
65
+ ### Step 2 — Read the surface rules
66
+
67
+ Read the surface rules file for the classified surface.
68
+
69
+ ### Step 3 — Identify the feature type and read the pattern file
70
+
71
+ Match the task to a pattern file in the surface folder.
72
+
73
+ ### Step 4 — Read the relevant component CLAUDE.md files
74
+
75
+ Only read the components the pattern file tells you to use.
76
+
77
+ ### Step 5 — Read the component stories
78
+
79
+ Read the Storybook story file for each component you will use.
80
+
81
+ ### Step 6 — Assemble, do not invent
82
+
83
+ Use only components that exist in packages/. Do not build custom components.
84
+
85
+ ### Step 7 — Validate before marking complete
86
+
87
+ Run the validation checklist from the pattern file before marking the task
88
+ complete.
89
+ ```
90
+
91
+ ### 4. Architecture section
92
+
93
+ A description of the monorepo structure, dependency layers, and key patterns
94
+ (styling, accessibility, TypeScript conventions). This prevents the agent from
95
+ making incorrect assumptions about how components relate to each other.
96
+
97
+ ### 5. New packages index
98
+
99
+ A brief entry for each new or in-progress package — its purpose, its
100
+ sub-components, and its key rules. This acts as a registry so the agent knows
101
+ what exists without having to explore the filesystem.
102
+
103
+ ```markdown
104
+ ## New packages (in progress)
105
+
106
+ ### table
107
+
108
+ Composable table component. See packages/table/CLAUDE.md before writing any
109
+ code. Sub-components: Table, TableHeaderRow, TableHeaderCell, TableRow,
110
+ TableCell, TablePagination.
111
+
112
+ ### status-badge
113
+
114
+ Pill badge with a colored status dot and text label. See
115
+ packages/status-badge/CLAUDE.md. Tones: positive, caution, critical, neutral,
116
+ pending.
117
+ ```
118
+
119
+ ---
120
+
121
+ ## How it connects to the other layers
122
+
123
+ The root file does not define _how_ to use any component. It only tells the
124
+ agent **what order to read things in**. Every rule lives in the layer it belongs
125
+ to:
126
+
127
+ | Concern | Lives in |
128
+ | ---------------------------- | -------------------------------------- |
129
+ | Surface classification logic | `docs/patterns/CLAUDE.md` |
130
+ | Surface interaction rules | `docs/patterns/[surface]/CLAUDE.md` |
131
+ | Feature assembly patterns | `docs/patterns/[surface]/[pattern].md` |
132
+ | Component-specific rules | `packages/[component]/CLAUDE.md` |
133
+
134
+ The root file is the table of contents. The other layers are the chapters.
135
+
136
+ ---
137
+
138
+ ## What happens if this layer is missing or incomplete
139
+
140
+ - The agent skips directly to component documentation and assembles UI without
141
+ understanding which surface it is building for.
142
+ - Surface-level interaction rules (hover states, overflow menus, badge tones)
143
+ are ignored.
144
+ - The agent invents components or custom styles that do not exist in the design
145
+ system.
146
+
147
+ ---
148
+
149
+ ## Implementation notes
150
+
151
+ - Keep this file short. Its job is orientation and reading-order enforcement,
152
+ not documentation.
153
+ - The build task steps should be imperatives, not suggestions: "Read X before Y.
154
+ Never skip steps."
155
+ - The new packages index should stay in sync with `packages/` — add an entry
156
+ here whenever a new package is scaffolded, even if it is not yet published.
157
+ - Do not duplicate rules here that already live in a lower layer. If a rule
158
+ belongs to a component, keep it in the component's CLAUDE.md.
@@ -0,0 +1,236 @@
1
+ # Layer 2 — Surface & Pattern files
2
+
3
+ ## What this layer is
4
+
5
+ The surface and pattern layer sits between the root and individual component
6
+ rules. It has two responsibilities:
7
+
8
+ 1. **Surface classifier** — determines _which product_ is being built before any
9
+ component is touched.
10
+ 2. **Surface rules** — defines interaction behaviour that applies globally
11
+ across all components on that surface.
12
+
13
+ Together they answer: _"For this surface, what are the rules that override
14
+ component defaults?"_
15
+
16
+ ---
17
+
18
+ ## Where these files live
19
+
20
+ ```
21
+ docs/patterns/
22
+ CLAUDE.md ← surface classifier (always read first)
23
+ internal-admin/
24
+ CLAUDE.md ← surface rules for internal admin
25
+ list-page.md ← feature pattern: list of records
26
+ form-page.md ← feature pattern: create / edit (coming soon)
27
+ detail-page.md ← feature pattern: record detail (coming soon)
28
+ customer-portal/ ← not yet defined
29
+ website/ ← not yet defined
30
+ ```
31
+
32
+ ---
33
+
34
+ ## File 1 — The surface classifier (`docs/patterns/CLAUDE.md`)
35
+
36
+ ### What it does
37
+
38
+ This is the agent's second read (after the root). Its only job is to map signals
39
+ from a PRD or feature brief to a named surface, then point the agent at the
40
+ correct surface rules file.
41
+
42
+ ### What it must contain
43
+
44
+ **A signal-to-surface lookup table.** Words or phrases that appear in a PRD,
45
+ mapped to the surface they indicate:
46
+
47
+ | Signal in PRD | Surface |
48
+ | ---------------------------------------------------------------- | --------------- |
49
+ | "admin", "internal", "back office", "ops", "manage", "dashboard" | Internal admin |
50
+ | "customer", "portal", "my account", "self-service" | Customer portal |
51
+ | "website", "marketing", "landing page", "public" | Website |
52
+ | "mobile", "app", "iOS", "Android" | Mobile app |
53
+
54
+ **A pointer to the surface rules file for each defined surface.** Undefined
55
+ surfaces should be flagged explicitly so the agent stops and asks rather than
56
+ guessing:
57
+
58
+ ```markdown
59
+ | Surface | Rules location |
60
+ | --------------- | -------------------------------------- |
61
+ | Internal admin | docs/patterns/internal-admin/CLAUDE.md |
62
+ | Customer portal | Not yet defined — flag to the team |
63
+ ```
64
+
65
+ **A pointer to feature pattern files** for each surface:
66
+
67
+ ```markdown
68
+ | Feature type | Pattern file |
69
+ | ---------------------------- | ----------------------------------------- |
70
+ | List of records with actions | docs/patterns/internal-admin/list-page.md |
71
+ | Create or edit a record | docs/patterns/internal-admin/form-page.md |
72
+ ```
73
+
74
+ **The canonical reading order** — a numbered list reinforcing the full sequence
75
+ from root to component. This is intentional redundancy: the more times the agent
76
+ sees the reading order, the less likely it is to skip steps.
77
+
78
+ ```markdown
79
+ 1. docs/patterns/CLAUDE.md ← surface classifier (this file)
80
+ 2. docs/patterns/[surface]/CLAUDE.md ← surface rules
81
+ 3. docs/patterns/[surface]/[pattern].md ← feature pattern (if exists)
82
+ 4. packages/[component]/CLAUDE.md ← component rules
83
+ 5. packages/[component]/src/[component].stories.tsx ← usage examples
84
+ ```
85
+
86
+ ---
87
+
88
+ ## File 2 — Surface rules (`docs/patterns/[surface]/CLAUDE.md`)
89
+
90
+ ### What it does
91
+
92
+ Defines interaction and visual rules that apply across **all** components when
93
+ building for this surface. These rules sit above component-level CLAUDE.md
94
+ files. When a conflict exists between a surface rule and a component rule, the
95
+ surface rule wins.
96
+
97
+ ### What it must contain
98
+
99
+ Rules that are **cross-component** in nature — things that would otherwise be
100
+ decided inconsistently component by component. Examples from the internal admin
101
+ surface:
102
+
103
+ **Row interaction rules**
104
+
105
+ Whether a table row is clickable, and what that implies for hover state.
106
+ Connecting row clickability to the data model (does a detail page exist?) rather
107
+ than leaving it to the agent to infer:
108
+
109
+ ```markdown
110
+ ### Clickable rows
111
+
112
+ - If the PRD describes a detail page, record view, or drill-down → row is
113
+ clickable
114
+ - If the PRD describes a read-only display with no destination → row is not
115
+ clickable
116
+ - If unsure, default to clickable
117
+
118
+ ### Hover state
119
+
120
+ - Row is clickable → hover state always applied
121
+ - Row is not clickable → hover state never applied, no exceptions
122
+ ```
123
+
124
+ **Overflow menu rules**
125
+
126
+ A decision tree for when a row gets an overflow menu vs. an inline button vs.
127
+ nothing:
128
+
129
+ ```markdown
130
+ Does the row have actions? No → no overflow menu, no action column Yes → how
131
+ many actions? 1 action + row is NOT clickable → inline button or icon 1 action +
132
+ row IS clickable → overflow menu 2+ actions → always overflow menu
133
+ ```
134
+
135
+ **Badge and pill rules**
136
+
137
+ When to use a status badge, and how to map status values to visual tones.
138
+ Explicit tone definitions prevent the agent from inventing tones:
139
+
140
+ ```markdown
141
+ - Positive / active / approved / complete → `positive`
142
+ - Warning / approaching limit / expiring → `caution`
143
+ - Critical / rejected / failed / overdue → `critical`
144
+ - Neutral / inactive / archived / unknown → `neutral`
145
+ - Pending / in review / awaiting approval → `pending`
146
+ ```
147
+
148
+ ### What it must NOT contain
149
+
150
+ - Component-specific implementation rules (those live in component CLAUDE.md)
151
+ - Rules that only apply to one feature type (those live in pattern files)
152
+ - Duplication of anything that already lives in a lower layer
153
+
154
+ ---
155
+
156
+ ## File 3 — Feature pattern file (`[surface]/[pattern].md`)
157
+
158
+ ### What it does
159
+
160
+ Describes how to assemble a specific type of page or feature — which components
161
+ to use, in what order, with what configuration. It is a recipe, not a reference.
162
+
163
+ The agent reads this _after_ the surface rules and _before_ component docs.
164
+
165
+ ### What it must contain
166
+
167
+ - **Component list** — the exact packages to use for this feature type
168
+ - **Assembly order** — the layout structure from outermost to innermost
169
+ - **Per-component configuration** — which props to set, what to avoid
170
+ - **A validation checklist** — the agent must run this before marking the task
171
+ complete
172
+
173
+ Example structure for a list page:
174
+
175
+ ```markdown
176
+ ## Components required
177
+
178
+ - @spark-web/header
179
+ - @spark-web/table (Table, TableHeaderRow, TableHeaderCell, TableRow, TableCell)
180
+ - @spark-web/status-badge (if status column present)
181
+ - @spark-web/meatball (if row actions present)
182
+ - @spark-web/table (TablePagination, outside Table)
183
+
184
+ ## Assembly order
185
+
186
+ 1. Header
187
+ 2. Table a. TableHeaderRow → TableHeaderCell (one per column) b. TableRow (one
188
+ per record) → TableCell
189
+ 3. TablePagination (sibling of Table, never inside it)
190
+
191
+ ## Validation checklist
192
+
193
+ - [ ] Header has a title prop
194
+ - [ ] Hover state matches row clickability (see surface rules)
195
+ - [ ] Meatball only present when 2+ row actions exist
196
+ - [ ] Status cells use StatusBadge — no inline styling
197
+ - [ ] TablePagination is outside Table
198
+ ```
199
+
200
+ ---
201
+
202
+ ## How this layer connects to the others
203
+
204
+ | Layer | Reads from | Overrides |
205
+ | ------------------- | ------------------------------- | ---------------------------------------- |
206
+ | Root CLAUDE.md | Nothing — entry point | — |
207
+ | Surface classifier | Root (via reading order) | — |
208
+ | Surface rules | Surface classifier | Component defaults |
209
+ | Feature pattern | Surface rules | Nothing — it assembles, doesn't override |
210
+ | Component CLAUDE.md | Feature pattern (per component) | Nothing for this surface |
211
+
212
+ ---
213
+
214
+ ## How to add a new surface
215
+
216
+ 1. Create a folder at `docs/patterns/[surface-name]/`.
217
+ 2. Create `CLAUDE.md` inside it with the surface rules (row behaviour, badge
218
+ rules, any globally applicable interaction patterns).
219
+ 3. Add a row to the signal table in `docs/patterns/CLAUDE.md` pointing to the
220
+ new file.
221
+ 4. Update the root `CLAUDE.md` if needed to note the new surface.
222
+ 5. Create pattern files (list, form, detail, etc.) as features are designed.
223
+
224
+ Do not build for a surface until its rules file exists. An undefined surface
225
+ means the agent has no contract and will make assumptions.
226
+
227
+ ---
228
+
229
+ ## What happens if this layer is missing or incomplete
230
+
231
+ - The agent applies component defaults regardless of surface context — hover
232
+ states, overflow menus, and badge tones become inconsistent across pages.
233
+ - Surface-level rules that conflict with component defaults are silently
234
+ ignored.
235
+ - Two agents working on the same surface independently will produce different
236
+ interaction patterns.