@felloinnovations/brand-kit 0.5.1 → 0.5.3

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.
Files changed (104) hide show
  1. package/AGENTS.md +29 -9
  2. package/CHANGELOG.md +86 -0
  3. package/README.md +10 -4
  4. package/design-system/01-how-claude-decides.md +5 -3
  5. package/design-system/03-colour.md +19 -1
  6. package/design-system/05-space-and-layout.md +2 -1
  7. package/design-system/08-choosing-components.md +20 -4
  8. package/design-system/09-charts.md +6 -3
  9. package/design-system/11-page-recipes.md +40 -1
  10. package/design-system/13-motion.md +1 -1
  11. package/design-system/15-ai-experiences.md +11 -0
  12. package/design-system/17-decisions.md +41 -0
  13. package/design-system/components/AppShell/README.md +89 -21
  14. package/design-system/components/AppShell/preview.html +148 -3
  15. package/design-system/components/AppShell/style.css +47 -0
  16. package/design-system/components/Avatar/README.md +6 -3
  17. package/design-system/components/Avatar/preview.html +2 -1
  18. package/design-system/components/Avatar/style.css +3 -0
  19. package/design-system/components/Banner/README.md +9 -5
  20. package/design-system/components/Banner/preview.html +9 -0
  21. package/design-system/components/Banner/style.css +3 -0
  22. package/design-system/components/Button/README.md +29 -2
  23. package/design-system/components/Button/preview.html +33 -1
  24. package/design-system/components/Button/style.css +21 -0
  25. package/design-system/components/Calendar/README.md +148 -0
  26. package/design-system/components/Calendar/preview.html +449 -0
  27. package/design-system/components/Calendar/style.css +61 -0
  28. package/design-system/components/Card/README.md +13 -0
  29. package/design-system/components/Card/preview.html +23 -0
  30. package/design-system/components/Card/style.css +19 -0
  31. package/design-system/components/ChatCard/README.md +74 -3
  32. package/design-system/components/ChatCard/preview.html +126 -25
  33. package/design-system/components/ChatCard/style.css +6 -0
  34. package/design-system/components/Chip/README.md +16 -7
  35. package/design-system/components/Chip/preview.html +25 -1
  36. package/design-system/components/Chip/style.css +5 -0
  37. package/design-system/components/Combobox/README.md +10 -4
  38. package/design-system/components/Combobox/preview.html +19 -4
  39. package/design-system/components/Combobox/style.css +7 -1
  40. package/design-system/components/CommentThread/README.md +138 -0
  41. package/design-system/components/CommentThread/preview.html +134 -0
  42. package/design-system/components/CommentThread/style.css +41 -0
  43. package/design-system/components/DateInput/README.md +38 -4
  44. package/design-system/components/DateInput/preview.html +50 -2
  45. package/design-system/components/DateInput/style.css +6 -0
  46. package/design-system/components/Dialog/README.md +26 -3
  47. package/design-system/components/Dialog/preview.html +80 -0
  48. package/design-system/components/Dialog/style.css +28 -3
  49. package/design-system/components/EmptyState/README.md +1 -1
  50. package/design-system/components/Fold/README.md +21 -0
  51. package/design-system/components/Fold/preview.html +44 -1
  52. package/design-system/components/Fold/style.css +30 -0
  53. package/design-system/components/InlineEdit/README.md +116 -0
  54. package/design-system/components/InlineEdit/preview.html +135 -0
  55. package/design-system/components/InlineEdit/style.css +34 -0
  56. package/design-system/components/Input/README.md +20 -1
  57. package/design-system/components/Input/preview.html +24 -0
  58. package/design-system/components/Input/style.css +13 -1
  59. package/design-system/components/KanbanBoard/README.md +68 -4
  60. package/design-system/components/KanbanBoard/preview.html +129 -0
  61. package/design-system/components/KanbanBoard/style.css +31 -0
  62. package/design-system/components/PlanTimeline/README.md +144 -0
  63. package/design-system/components/PlanTimeline/preview.html +109 -0
  64. package/design-system/components/PlanTimeline/style.css +64 -0
  65. package/design-system/components/README.md +11 -6
  66. package/design-system/components/Skeleton/README.md +66 -2
  67. package/design-system/components/Skeleton/preview.html +83 -1
  68. package/design-system/components/Starter/README.md +1 -1
  69. package/design-system/components/Starter/preview.html +1 -1
  70. package/design-system/components/Stepper/README.md +81 -5
  71. package/design-system/components/Stepper/preview.html +64 -1
  72. package/design-system/components/Stepper/style.css +29 -0
  73. package/design-system/components/StreakCalendar/README.md +1 -0
  74. package/design-system/components/Table/README.md +7 -3
  75. package/design-system/components/Table/preview.html +15 -0
  76. package/design-system/components/Table/style.css +2 -0
  77. package/design-system/components/TextDiff/README.md +96 -0
  78. package/design-system/components/TextDiff/preview.html +42 -0
  79. package/design-system/components/TextDiff/style.css +21 -0
  80. package/design-system/components/Timeline/README.md +3 -1
  81. package/design-system/components/TrendLine/README.md +38 -7
  82. package/design-system/components/TrendLine/preview.html +140 -3
  83. package/design-system/components/TrendLine/style.css +12 -2
  84. package/design-system/components/bundle.css +483 -7
  85. package/design-system/tokens.json +15 -1
  86. package/dist/fello-core.css +2 -2
  87. package/dist/fello.css +2 -2
  88. package/dist/fello.scoped.css +2 -2
  89. package/dist/index.d.ts +1 -1
  90. package/dist/scoped.js +2 -2
  91. package/dist/tokens.d.ts +8 -0
  92. package/dist/tokens.js +8 -0
  93. package/package.json +7 -2
  94. package/scripts/check-drift.mjs +325 -0
  95. package/scripts/token-model.mjs +2 -1
  96. package/tokens/_dark.css +2 -0
  97. package/tokens/_product.css +2 -0
  98. package/tokens/palettes.ts +1 -1
  99. package/tokens/shadcn-compat.css +1 -1
  100. package/tokens/shadcn-compat.hsl.css +1 -1
  101. package/tokens/tokens.css +14 -1
  102. package/tokens/tokens.md +53 -46
  103. package/tokens/tokens.root.css +14 -1
  104. package/tokens/tokens.ts +9 -1
package/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- # brand-kit for coding agents (0.5.1)
1
+ # brand-kit for coding agents (0.5.3)
2
2
 
3
3
  Read this before writing UI in any Fello project that uses `@felloinnovations/brand-kit`. It ships inside the
4
4
  package at `node_modules/@felloinnovations/brand-kit/AGENTS.md`. The HubSpot website (felix-theme) is out of scope:
@@ -22,9 +22,10 @@ All paths are under `node_modules/@felloinnovations/brand-kit/`.
22
22
  | `dist/fello.scoped.css` | The whole kit under a `.fello` root, for an app inside a host it does not own. |
23
23
  | `tokens/tokens.css` | Tokens only, as a Tailwind v4 `@theme`. |
24
24
  | `scripts/check-palette.mjs` | Checks an app's own palette file against the contract (Palettes, below). |
25
+ | `scripts/check-drift.mjs` | Lists every line of an app's source that drifted from the kit, by file and line; with a baseline, fails CI only on new drift (Checking it, below). Also `npx brand-kit-drift`. |
25
26
 
26
27
  The same guide is hosted, always current, at `https://brand-kit-site-production.up.railway.app/latest/llms.txt`
27
- (pinned copies under `/v/0.5.1/`).
28
+ (pinned copies under `/v/0.5.3/`).
28
29
 
29
30
  ---
30
31
 
@@ -170,10 +171,12 @@ public web page, email, deck, mockup). The face sets one of two layers, never mi
170
171
  already shipped a bug. Never `--radius-xl` or `--radius-2xl` for a product corner: those are Tailwind's.
171
172
  - **Semantic tokens over primitives**: `var(--color-text-heading)`, not `var(--color-brand-navy)`, for the same job.
172
173
  The semantic layer is what lets a colour be retuned, and what turns in dark.
173
- - **Check the catalog before building a component.** Never redraw one. If the kit has nothing for it, build it in
174
- the consuming app from tokens and say what was missing, as an issue
175
- (`https://github.com/FelloInnovations/brand-kit/issues/new?template=feedback.yml`). Do not add it to brand-kit and do not open a PR against it
176
- from a consuming app; the kit's owners take it from there.
174
+ - **Check the catalog before building a component. Never build a new one in an app** (Nikhil and Amit, 10 Nov
175
+ 2026: built once in the kit, everyone uses it and raises what is missing). If the kit has nothing for it, compose
176
+ the nearest catalog parts (a `Card` with its band, a `Menu`, a `Table`, a recipe), file the gap as an issue
177
+ (`brand-feedback`, or `https://github.com/FelloInnovations/brand-kit/issues/new?template=feedback.yml`) and say in
178
+ the PR which issue the screen waits on. When the kit ships it, `brand-catchup` swaps it in. Do not add it to
179
+ brand-kit and do not open a PR against it from a consuming app; the kit's owners take it from there.
177
180
  - **Close but not exact**: pass `className` to a React export (merged through `tailwind-merge`, so your utility wins).
178
181
  Do not fork it.
179
182
  - **Layout**: one content edge per surface; numbers in fixed right-aligned columns; rows in a list share one
@@ -238,8 +241,22 @@ fold, enter and exit is already there. The situations, with markup, are in `desi
238
241
 
239
242
  ## Checking it
240
243
 
241
- The kit's own checks run in the kit's repo, for anyone changing a catalog component (only `check-palette.mjs` ships in
242
- the package; the rest show what "done" means for your own screens too):
244
+ **In an app**, the drift check reads every file of its source and lists what drifted (raw colours, each marked
245
+ against the nearest token, kit tokens redefined, kit classes restyled, px type, raw radii and shadows, hand-rolled
246
+ motion, links underlined at rest, em dashes, local copies of kit components). Run it before calling UI done, and keep
247
+ it in CI with a baseline so nothing new gets in while old drift is fixed:
248
+
249
+ ```sh
250
+ node node_modules/@felloinnovations/brand-kit/scripts/check-drift.mjs src # the report; exit 1 on any drift
251
+ node node_modules/@felloinnovations/brand-kit/scripts/check-drift.mjs src --write-baseline .brand-drift.json
252
+ node node_modules/@felloinnovations/brand-kit/scripts/check-drift.mjs src --baseline .brand-drift.json # CI: fails only on new drift
253
+ ```
254
+
255
+ A line that is right as it is carries `brand-kit-ignore: <why>` on it or the line above. Updating to a newer kit is
256
+ the `brand-catchup` skill (only what the releases changed), never `brand-adopt` again.
257
+
258
+ The kit's own checks run in the kit's repo, for anyone changing a catalog component (only `check-palette.mjs` and
259
+ `check-drift.mjs` ship in the package; the rest show what "done" means for your own screens too):
243
260
 
244
261
  ```sh
245
262
  node scripts/check-geometry.mjs --only Name1,Name2 --widths 320,390,1440 # alignment, spacing, centring, clipping, targets
@@ -249,6 +266,7 @@ node scripts/check-geometry.mjs --only Name1,Name2 --hover # res
249
266
  node scripts/check-geometry.mjs --only Name1,Name2 --hover --motion # the same with motion on: a lift that only plays then
250
267
  node scripts/check-scope.mjs # the scoped build leaks nothing; fello.css resets miss the host
251
268
  node scripts/check-palette.mjs [file.css] # the built-ins, or a palette file, against the contract
269
+ node scripts/check-drift.mjs --selftest # the drift check catches every planted drift
252
270
  ```
253
271
 
254
272
  Open every screenshot the geometry check writes. In an app, run the same eye over the screen at 320, 390 and 1440,
@@ -282,5 +300,7 @@ size, radius, shadow or duration. Motion comes with the catalog's classes (`desi
282
300
  hand-roll a transition. Check the catalog (`design-system/components/`) before building a component. Write
283
301
  `text-[color:var(--x)]`, never `text-[var(--x)]`. Dark is opt-in (`data-theme`). This app's own colours are a palette
284
302
  (`data-palette`, `design-system/20-palettes.md`), checked with `scripts/check-palette.mjs` and shipped as its
285
- `--emit` writes it, never tokens retuned on `:root`. Run `design-system/18-checklist.md` before calling UI done.
303
+ `--emit` writes it, never tokens retuned on `:root`. Run `design-system/18-checklist.md` and
304
+ `node node_modules/@felloinnovations/brand-kit/scripts/check-drift.mjs src --baseline .brand-drift.json` before calling
305
+ UI done. To take a newer kit, use the `brand-catchup` skill, not `brand-adopt`.
286
306
  ```
package/CHANGELOG.md CHANGED
@@ -1,5 +1,91 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.3 (11 Nov 2026)
4
+
5
+ Madan's eighteen gaps from moving Marketing OS onto the kit (#15 to #32), and Hemanth's sidebar. Nikhil (10 Nov):
6
+ Marketing OS shows the new UI to Stephen before Thursday, and apps never build a missing component with Claude, so the
7
+ kit carries each of these. Everything adds; nothing that exists changes how it looks. Rulings in Decisions, 11 Nov 2026.
8
+
9
+ - **New components**: `Calendar` (things on dates in a month or a week, an agenda in a narrow column; #23),
10
+ `PlanTimeline` (a plan's phases and tasks as bars on one date scale, today one line through every row; #24),
11
+ `InlineEdit` (words that become a field in place, nothing jumps; #25), `CommentThread` (remarks anchored to content,
12
+ one level of replies, mentions, resolve; #26), `TextDiff` (what was removed and what was added, by line or inline,
13
+ never by colour alone; #28).
14
+ - **`AppShell`'s sidebar holds sections**: `__section` folds a page's own pages open in place, one level in, its
15
+ chevron turning; folded, a section is a button that opens its pages as a Menu panel beside the rail (`__fly`,
16
+ `__panel`); the person at the foot opens the account menu (`__me`). Enough for Customer Value to drop its own rail.
17
+ - **Fields**: `DateInput` jumps to a far month or year (`__jump`) and has Today and Clear in a foot (`__foot`; #20), and
18
+ takes a time and a date with a time on the browser's own picker (#27); `Combobox` ticks the chosen row and keeps the
19
+ sunk ground for the keyboard's (#19); `ws-colour-field`, a swatch beside its hex, in `Input` (#29).
20
+ - **Acts and tags**: `ws-btn-join` joins an act to a caret that opens a menu of its other forms (#22); `Chip --sm` (20
21
+ tall, 12 px words) for several tags together (#30); `Avatar --xs` (20) for dense pickers (#16).
22
+ - **Surfaces**: `ws-dialog--mounted` with `ws-dialog__scrim`, so a dialog Radix mounts enters and leaves like the
23
+ native one, out on `data-state="closed"` (#18); `Fold` gains acts beside the summary, an end status, words shown only
24
+ while folded (`ws-fold__peek`) and three tones (#31); `ws-card__media` rounds its own corners and `ws-card--ring`
25
+ with `ws-card__tick` marks a chosen tile in a grid (#32); `ws-table__prose` wraps a short prose cell with no 200 px
26
+ floor (#21). A button card no longer carries the browser's default button padding.
27
+ - **Status colours and two tokens**: error, warning, success and info map onto the kit's alert, needs, positive and
28
+ working tones (the "Status sets" table in Colour; #15). New `--ws-tint-alert` (the ground of an error status, with
29
+ `Banner --alert` and `Chip --alert`) and `--ws-shadow-rise` (a drawer rising from a pane; #17), both following every
30
+ palette, light, night and navy.
31
+ - **Pinned links keep working**: `/v/0.5.2/` is kept as a snapshot (`hosted/v/0.5.2`). Pinned links now point at
32
+ `/v/0.5.3/`.
33
+
34
+ **Upgrading from 0.5.2**: nothing to change; take it with `brand-catchup`. Then, on a yes, swap what the app hand-built:
35
+ a calendar, a Gantt, an editable title, a comment list, a diff, a split button, a nested sidebar or a dialog's own
36
+ animation for the kit's; a local warning or info colour for the status sets; a button card's padding reset can go.
37
+
38
+ ## 0.5.2 (10 Nov 2026)
39
+
40
+ What Hemanth was missing when he built the Customer Value app on the kit (10 Nov call with Amit). Everything here adds;
41
+ nothing that exists changes how it looks (the look stays locked at 0.5). Rulings in Decisions, 10 Nov 2026.
42
+
43
+ - **Update with `brand-catchup`, never a second adopt.** A new skill brings an app already on the kit up to the newest
44
+ release: it reads this changelog from the app's version to the latest, bumps the package (or re-fetches a guest app's
45
+ vendored scoped CSS), applies each release's "Upgrading from" notes and nothing else, lists where the app hand-built
46
+ something the kit now has (and swaps it only on a yes), and proves nothing new drifted.
47
+ - **`check-drift` lists every drifted line, so adopt stops stopping halfway.** `scripts/check-drift.mjs` ships in the
48
+ package (also `npx brand-kit-drift`): raw colours (each marked as matching a token, close to one, or no token),
49
+ Tailwind palette classes, kit tokens redefined, kit classes restyled, px type, raw radii and shadows, the
50
+ `text-[var(--x)]` trap, hand-rolled motion and hover lifts, links underlined at rest, em dashes in markup and local
51
+ copies of kit components, every one by file and line. `--baseline .brand-drift.json` makes it a CI check that fails
52
+ only on new drift; `brand-kit-ignore: <why>` keeps a line that is right; `--selftest` proves each rule. `brand-adopt`
53
+ is done only when it finds nothing left (or names every leftover), then leaves the baseline in CI; `brand-audit`'s
54
+ static half runs it first.
55
+ - **A whole page's loader.** `Skeleton` documents the page ghost it promised: the page's own `PageBar` with its name
56
+ shown at once and its data-bound words and act as ghosts, then a board of tile and card skeletons where the real
57
+ ones land, so nothing jumps. No new CSS. List and board pages use `Table`'s and `KanbanBoard`'s own ghosts.
58
+ - **`TrendLine` draws up to three series** in one unit on one axis: a `__series` box per extra line, navy, teal then
59
+ purple, a key (`__key--2`, `__key--3`), a column per series in the table, and a hover that reads every series for
60
+ the period. Several series are lines only. Different units, or one series more than four times another: two
61
+ TrendLines stacked in one card on the same periods, never two value axes.
62
+ - **`Stepper` reads across and holds milestones.** `--across` lays a thing's stages left to right in equal columns, the
63
+ in-hand stage opening in view on a track that scrolls on a phone; `--milestones` puts dated points on one row with
64
+ the measure on each ("First value 15 days") and one quiet act on one not yet reached; `__late` says a stall or a late
65
+ milestone in needs-you words ("Stalled 40 days").
66
+ - **One card for every board.** `KanbanBoard` documents the standard card (`ws-kanban-board__card`): the kind and its
67
+ figure with the time in stage (`__age`, `--stalled`), the title as the card's link covering it, meta, up to three
68
+ chips, a foot with people, a tally and one icon act, and one well act (`__card-act`) when the stage waits on the
69
+ person. Ticket and onboarding examples in the preview; a card-tall ghost for loading.
70
+ - **Calvin's desk.** `ChatCard` gains four kinds: Email, Call and Text (the time at the head's right, the sender's words
71
+ quoted on a sunk plate, three lines at most; Reply, or Listen for a call) and Account (its standing as a rating chip,
72
+ its numbers on the stats plate, one navy act). Page recipe 25, "An agent desk: one thread per account", composes the
73
+ threads by account, the open thread, the daily briefing on top and the layouts at 1440 and 390 from catalog parts.
74
+ - `check-geometry` counts a title whose cover spans its card as the card's target.
75
+ - **Next.js imports `fello.css` from the root layout** (`brand-adopt`, `brand-new`): under Turbopack an `@import` in
76
+ `globals.css` put its font `@import` after rules and `next dev` failed on every page (#14).
77
+ - **Apps never build a missing component** (Nikhil and Amit, 10 Nov): compose the nearest catalog parts, file the gap
78
+ with `brand-feedback`, name the issue in the PR; the kit builds it once and `brand-catchup` swaps it in. AGENTS.md,
79
+ How Claude decides and `brand-feedback` say so.
80
+ - **Pinned links keep working**: `/v/0.5.1/` is kept as a snapshot (`hosted/v/0.5.1`). Pinned links in the docs now
81
+ point at `/v/0.5.2/`.
82
+
83
+ **Upgrading from 0.5.1**: nothing to change; take it with `brand-catchup`. Then, in an app that hand-built any of these,
84
+ swap on a yes: a page loader made of divs for the page ghost (`Skeleton`); a second chart line drawn in its own SVG for
85
+ `TrendLine`'s `__series`; a horizontal stage track or milestone row for `Stepper --across` or `--milestones`; a board
86
+ card per board (column rails, stage hues, underlined titles) for `ws-kanban-board__card`; email, call or text bubbles
87
+ in a chat for the `ChatCard` message kinds. Add `check-drift` to CI with a baseline (`brand-adopt`, stage 8).
88
+
3
89
  ## 0.5.1 (10 Nov 2026)
4
90
 
5
91
  Loaders are calm: the shimmer is one quiet grey. Amit looked at the skeletons in an app built on the kit and did not
package/README.md CHANGED
@@ -59,11 +59,17 @@ The plugin carries the same `fello-brand-kit` skill as claude.ai, plus four comm
59
59
  | Command | What it does |
60
60
  | --- | --- |
61
61
  | `/brand-kit:brand-audit` | Read-only report: raw values, drift from tokens, pages that cannot scroll, fields with no white ground, small targets, contrast, console errors. |
62
- | `/brand-kit:brand-adopt` | Migrates an existing app onto the kit, in stages, building between each. |
62
+ | `/brand-kit:brand-adopt` | Migrates an existing app onto the kit, in stages, until the drift check finds nothing left, then guards it in CI. |
63
+ | `/brand-kit:brand-catchup` | Brings an app already on the kit up to the newest release: only what the releases changed, never a second adopt. |
63
64
  | `/brand-kit:brand-new` | Scaffolds a new app already on the kit. |
64
65
  | `/brand-kit:brand-feedback` | Sends what the kit was missing or got wrong as one issue per gap on this repo. The other skills offer it when they finish. |
65
66
 
66
- Audit before adopt, so someone who does not read code sees what is wrong before anything is rewritten.
67
+ Audit before adopt, so someone who does not read code sees what is wrong before anything is rewritten. Adopt once;
68
+ after that, catch up.
69
+
70
+ `npx brand-kit-drift src` (or `node node_modules/@felloinnovations/brand-kit/scripts/check-drift.mjs src`) lists every
71
+ line of an app that drifted from the kit; `--baseline .brand-drift.json` makes it a CI check that fails only on new
72
+ drift.
67
73
 
68
74
  ### In code
69
75
 
@@ -112,7 +118,7 @@ Then point the repo's agents at the guide: paste the block at the end of [AGENTS
112
118
  One line, pinned to a version:
113
119
 
114
120
  ```html
115
- <link rel="stylesheet" href="https://brand-kit-site-production.up.railway.app/v/0.5.1/fello.css">
121
+ <link rel="stylesheet" href="https://brand-kit-site-production.up.railway.app/v/0.5.3/fello.css">
116
122
  ```
117
123
 
118
124
  Then use the `ws-*` classes and `var(--token)`; the markup for each component is in the gallery. `/latest/` exists
@@ -189,7 +195,7 @@ version>` to `hosted/v/` (the gallery serves every snapshot there, so pinned lin
189
195
  unversioned), run `yarn build` and `yarn skill`, commit, then push a tag that matches:
190
196
 
191
197
  ```sh
192
- git tag v0.5.1 && git push origin v0.5.1
198
+ git tag v0.5.3 && git push origin v0.5.3
193
199
  ```
194
200
 
195
201
  `.github/workflows/publish.yml` checks the tag matches `package.json`, builds, and publishes to npm through npm's
@@ -57,7 +57,7 @@ rest; a mockup about to ship takes all steps.
57
57
  | Where | Setup |
58
58
  | --- | --- |
59
59
  | A claude.ai artifact | inline `fello-core.css` plus the styles of only the components used, in one `<style>` (an artifact loads stylesheets only from Google Fonts; the whole `fello.css` is too big to paste) |
60
- | A plain HTML page or a static site | link the pinned file: `https://brand-kit-site-production.up.railway.app/v/0.5.1/fello.css` |
60
+ | A plain HTML page or a static site | link the pinned file: `https://brand-kit-site-production.up.railway.app/v/0.5.3/fello.css` |
61
61
  | A Next, Vite or Turbo app that owns its page | install `@felloinnovations/brand-kit`, import `fello.css` (it sits in Tailwind's layers, so utilities win) or `tokens.css` (Tailwind v4), with the Instrument Sans `@import` first (before `@import "tailwindcss"`) or a `<link>`; read its `AGENTS.md` |
62
62
  | An app inside a host it does not own (a shared bundle, a platform's guest app), or any Tailwind v3 app | the scoped build: `fello.scoped.css`, or the string from `@felloinnovations/brand-kit/scoped` injected in a `<style>`, under `class="fello"` on the app's root and on every portal's root; nothing outside it changes; it carries no font, so link Instrument Sans (the `brand-adopt` skill has the steps) |
63
63
  | Claude Design or Slides | this system is the organisation's default; nothing to load |
@@ -108,8 +108,10 @@ Choose the recipe first and adapt it (Page recipes); then the pattern (Patterns)
108
108
  and any chart (Charts). Do not invent a new surface; marketing and product pieces never cross faces.
109
109
 
110
110
  **When no product has a precedent**, decide it from the system (its principles, tokens, the nearest rule) rather than
111
- leave it out. A switch is navy when on because the tab thumb and a selected toggle are. A new component is built from tokens in the consuming project and listed in
112
- Decisions with the rules it derives from, so the kit's owners can take it.
111
+ leave it out. A switch is navy when on because the tab thumb and a selected toggle are. **A missing component is never
112
+ built in the app** (Nikhil and Amit, 10 Nov 2026): compose the nearest catalog parts in its place, file the gap
113
+ (`brand-feedback`) with the rules it would derive from, and name the issue in the PR. The kit's owners build it once,
114
+ in the kit, and `brand-catchup` swaps it in.
113
115
 
114
116
  ## 5. Apply the foundations
115
117
 
@@ -35,7 +35,7 @@ positive. Marks keep Seth's exact tones; a word in a tone takes its AA step on t
35
35
  | Under halfway marks, needs-you dots | `ws-chart-under-half`, `color-brand-salmon` | salmon #FF725C |
36
36
  | Needs work marks | `ws-chart-needs-work` | pink #F370A4 |
37
37
  | Alert marks | `ws-chart-alert` | #B1042F |
38
- | Chip tints: needs you, done, needs work | `ws-tint-needs`, `ws-tint-live`, `ws-tint-needs-work` | |
38
+ | Chip and banner tints: needs you, done, needs work, alert | `ws-tint-needs`, `ws-tint-live`, `ws-tint-needs-work`, `ws-tint-alert` | |
39
39
  | Hover washes (navy at .03, .05, .06) | `ws-hover-faint`, `ws-hover`, `ws-hover-strong` | |
40
40
  | The ink of a wash, a ring or a line of your own; the tint of a drop | `ws-ink`, `ws-shade` | navy (in dark, the heading's light ink and black) |
41
41
  | A floating navy message (a toast, the note tip) and the footer, and their words | `ws-inverse`, `ws-on-inverse` | the act and its words; in dark the brand navy and white |
@@ -83,6 +83,24 @@ A strip of ticks or a bar takes the band's one tone; its words take the band's w
83
83
 
84
84
  Never a state by colour alone: a word or a mark goes with it.
85
85
 
86
+ ## Status sets: error, warning, success, info
87
+
88
+ An app whose statuses are named error, warning, success and info (a badge, a banner, an inline message) maps each onto
89
+ the kit's tones; there are no separate status colours (#15).
90
+
91
+ | Status | Means | Words | Ground (a chip, a banner) | Mark, icon or edge | Banner, Chip |
92
+ | --- | --- | --- | --- | --- | --- |
93
+ | Error | something is wrong now: failed, rejected, blocked | `ws-word-alert` | `ws-tint-alert` | `ws-chart-alert` | `--alert` |
94
+ | Warning | needs the person: something to fix, ending soon | `ws-word-needs` | `ws-tint-needs` | `ws-chart-under-half` (salmon) | `--needs` |
95
+ | Success | done, passed, gone well | `ws-word-positive` | `ws-tint-live` | `ws-chart-finished` (teal) | `--positive` / `--live` |
96
+ | Info | working, still running, a plain note | `color-text-interactive` | `ws-card-tint-blue` (a chip: the plate) | `color-text-interactive` | `--working` / `--accent` |
97
+
98
+ - **No solid status fills.** A status is its tint, its words and its mark; a solid fill with white words is navy's alone
99
+ (a count, the one act), and salmon and mid blue are never a fill.
100
+ - **A field's error stays "needs"**: a salmon edge and `ws-word-needs` words under the field (Input), since the person
101
+ fixes it. Error red is for a thing that went wrong, not a field to correct.
102
+ - A neutral status ("Draft", "Scheduled") is the plain chip or the `neutral` banner, never a tone.
103
+
86
104
  ## Rules
87
105
 
88
106
  - **Navy is for words, the one button and a few named fills**: the tab or segmented thumb, a selected toggle, a checked
@@ -136,7 +136,8 @@ A public page's `KitCard` is 4.
136
136
 
137
137
  Everything is flat at rest. What floats lifts on one family of shadows, a single soft drop each: a popover
138
138
  (`ws-shadow-pop`), a menu (`ws-shadow-menu`), a tooltip or hover card (`ws-shadow-tip`), a floating chat or a tile opened
139
- out of its slot (`ws-shadow-float`). In dark each carries a 0.5 px light rim. Buttons never lift. Layers: `z-dropdown`
139
+ out of its slot (`ws-shadow-float`), and a drawer that rises from the bottom of a pane (`ws-shadow-rise`, the menu's
140
+ drop cast upward: the pane's content sits above it, so the shade falls on it). In dark each carries a 0.5 px light rim. Buttons never lift. Layers: `z-dropdown`
140
141
  for menus and tips, `z-modal` for a dialog or drawer, `z-toast` for a toast.
141
142
 
142
143
  ## The frame
@@ -14,6 +14,7 @@ Components new in 0.5.0 are marked (new).
14
14
  | A label that may be wider than its column (a long link act, a translation) | `Button` with `ws-btn--wrap` | a button is one line and never shrinks beside its row's words; only an opted-in label wraps, in balanced lines (a link, text or ghost reads from its start) |
15
15
  | Words that act inside a sentence | `Button` link (mid blue: goes somewhere or shows more) or text (navy: a quiet act) | never a boxed button in running words |
16
16
  | Go somewhere | `Button` as a link (`ButtonLink`), or `ws-link` | a link is a link in the markup, whatever it looks like |
17
+ | One act with a few other forms of itself (approve now, approve and schedule) | `Button` joined with its caret (`ws-btn-join`) opening a `Menu` | the plain act is the common one; other acts go in a three-dots `Menu` |
17
18
  | An act with no words (send, close, more, previous, next) | `IconButton` with a label | |
18
19
  | Turn something on or off, stays on | `Button selected` or `IconButton selected` (navy) | a toggle's state is `aria-pressed` |
19
20
  | Switch between a few views of one thing | `Segmented` (a switch) | inside the card it filters |
@@ -23,6 +24,7 @@ Components new in 0.5.0 are marked (new).
23
24
  | Know where you are in a deep hierarchy | `Breadcrumb` | the root crumb never shrinks; collapse the middle over four levels |
24
25
  | Move through a long collection | `Pagination` in the card's foot | |
25
26
  | A product of several pages that is not chat-first | `AppShell` (with its sidebar) and `TopBar` | the same rows, gutters and one navy button as the chat shell |
27
+ | A page with a few pages of its own, in the sidebar | `AppShell`'s section (`__section`) | folds in place, one level only; folded, a panel beside the rail; never a hand-built sidebar |
26
28
  | A single page: an artifact, a report, an internal page | `Page` with a `PageBar` | no shell; its board holds the cards; start from `Starter` |
27
29
  | A thread or app page in place of the chat | `PageBar`'s 56 px thread header | the page's name, the app's name, its acts, the way back |
28
30
  | Open the one thing's details | a link `Card`, a `Well` row, a `CheckRow`, a table row | it opens in the panel beside the chat, a drawer, or the page's side pane |
@@ -38,9 +40,11 @@ Components new in 0.5.0 are marked (new).
38
40
  | --- | --- | --- |
39
41
  | Type a short value | `Input` with a label above | the error under it with a warning mark |
40
42
  | Type several lines | `TextArea` | |
43
+ | Change one value where it is read (a title, a brief's fact) | `InlineEdit` | the same box and type at rest and editing; Enter or blur saves, Escape reverts; one value at a time |
41
44
  | Choose one of a few visible options | `Radio` group with a legend | up to about 5; make them easy to compare |
42
45
  | Choose one of many | `Select` | over 5 options, or a choice that changes the data rather than the view |
43
46
  | Choose one of many with search, or several as tags | `Combobox` | over about 20 options, or when the list is open-ended ("Create 'Pine Street'") |
47
+ | Choose a picture, a template or an asset from a grid | `Card` buttons with `ws-card__media`, `ws-card--ring` when chosen | a group of `aria-pressed` buttons (several) or a `radiogroup` (one); the tick and the ring, never a tab under a tile |
44
48
  | A number with a unit or steps | `NumberInput` | |
45
49
  | A value on a range (a team size, a share) | `Slider` (new) | the value said in words beside it |
46
50
  | A password | `PasswordInput` | |
@@ -48,8 +52,10 @@ Components new in 0.5.0 are marked (new).
48
52
  | Choose several | `Checkbox` | independent choices; the label is part of the target |
49
53
  | A setting that applies at once | `Switch`, with "Saved" shown for a moment | the whole row is the target |
50
54
  | Talk or type to an agent | `Composer` | the one chat box; a drawer's small ask field is its compact look |
51
- | Pick a date or a range | `DateInput` (native first, with its popover month grid) | |
55
+ | Pick a date or a range | `DateInput` (native first, with its popover month grid) | a far date: the month and year selects (`__jump`); an optional one: Clear in the foot |
56
+ | Pick a time, or a date with a time | `DateInput` on `type="time"` or `type="datetime-local"` (the platform's picker) | a zone other than the person's is named in the label |
52
57
  | Search a list | `Input` with the search icon, in the card it searches | (Patterns) |
58
+ | Set a colour (brand colours, a palette) | `Input`'s colour field: a swatch that opens the picker, the hex beside it | the hex validates as it is typed; an invalid one keeps the last good swatch |
53
59
 
54
60
  ## Showing things
55
61
 
@@ -69,17 +75,23 @@ Components new in 0.5.0 are marked (new).
69
75
  | What to do next, one row a person or thing ("who needs a nudge") | `ActionList` in a `Card` | the reason in words with its figures; one secondary act per row; a bulk act in the band |
70
76
  | What happened, in order | `Timeline` | |
71
77
  | Things moving through stages | `KanbanBoard` | a card glides between stages |
78
+ | Where one thing is in its stages | `Stepper --across` | the in-hand stage ringed, a stall in needs-you words under it |
79
+ | One thing's dated milestones (signed, first value) | `Stepper --milestones` | the measure on each milestone; a late one in needs-you words |
80
+ | Things on dates (posts, sends, tasks, touches by day) | `Calendar` (new) | a month or a week, Monday first; a narrow column reads it as an agenda |
81
+ | A plan's phases and tasks across their dates | `PlanTimeline` (new) | a bar from start to end on one scale, the phase in hand navy, today one line through every row |
72
82
  | A few facts about one thing | a `Plate` of label and value rows | inside the card |
73
83
  | A score that answers a report | `ScoreHero` (new) | the 96 px score, its strip, the rating word and one sentence; one per report |
74
84
  | A number that matters | `GoalTicks` (the 72 px number with its change chip) or `StatTiles` (several figures) | one hero figure per card; tiles only where the answer is numbers |
75
85
  | A key metric that opens across its row | `MetricTile` (new) | closed: label, figure, pace bar, foot; open: its chart and side column |
76
86
  | Progress against a pace or a target | `PaceBar` (new) | the fill, the pace mark, the figure in words beside |
77
87
  | A change since when | `ChangeChip` (in `Chip`) | an arrow and words, never colour alone |
78
- | A count, a kind, a state | `Chip` | a rating's tag takes the rating's tint and word |
79
- | A disclosure ("Why", "All details", a chapter) | `Fold` (card, quiet or row) | the one disclosure; never a custom accordion |
88
+ | A count, a kind, a state | `Chip` | a rating's tag takes the rating's tint and word; several on one card or in one cell: `--sm` (20) |
89
+ | A disclosure ("Why", "All details", a chapter) | `Fold` (card, quiet or row) | the one disclosure; never a custom accordion. An act in its head that must not toggle it, words shown only while folded, or a notice's tone: the card look's `ws-fold__act`, `ws-fold__peek`, `ws-fold--needs` |
80
90
  | A small group inside a card | `Section` | |
81
91
  | A tile in a bento, or the row of what an app can do | `Tile` | the tile row sits on the well, each tile a door or the step it waits on |
82
92
  | People | `Avatar` (and its stack) | |
93
+ | People commenting on a thing, with replies, mentions and resolve | `CommentThread` | anchored to the stretch it is on; one level of replies; a mention of you on the needs tint |
94
+ | What changed between two versions of a text | `TextDiff` (by line or inline) | never colour alone: a sign, a strike, an underline |
83
95
  | An agent | the assistant's own mark, drawn by the designer (no catalog piece) | still outside the chat (AI experiences) |
84
96
  | A short tip on hover or focus | `Tooltip` | never the only place a label lives; its navy note holds a cell's full words |
85
97
  | A reading of a chart's mark under the pointer | `HoverCard` (new) | a caret to its mark; the value is still written beside the mark |
@@ -94,10 +106,14 @@ Components new in 0.5.0 are marked (new).
94
106
  | Inspect one thing while keeping the list or chat | `Panel` (440 beside the chat, or a rimmed drawer beside a report) or a page's side pane | the same view component in each |
95
107
  | The chat as a bar, docked beside a page, floating or full screen | `ChatShell` (new) | one chat; it moves between its modes as itself |
96
108
  | One long conversation, marked by topic | `TopicRail` (new) with `ChatShell` | the topics as a rail; the conversation stays one thread |
109
+ | An email, a call or a text in the chat | `ChatCard`'s message kinds (Email, Call, Text) | only one to read or answer now; the rest named in the agent's words with the source |
110
+ | An account that needs a decision, in the chat | `ChatCard`'s Account kind | its standing as a rating `Chip`, its numbers on a stats plate, one navy act |
111
+ | A thread per account, with a daily briefing | Page recipes, 25 (`ListDetail` of threads, the thread, `Composer`) | one chat kept by the thing it is about; the briefing is the one time the agent speaks first |
97
112
  | A short blocking task (confirm, name, one field) | `Dialog` | sparingly; head, content, foot with the one primary last |
98
113
  | A list of acts | `Menu` | the three dots open it |
99
114
  | A quiet confirmation of a background act | `Toast` | essential information lives elsewhere |
100
115
  | A state of the whole page or card (offline, a trial ending, a job done) | `Banner` | never for a field's error |
116
+ | An error, warning, success or info status on a badge, a banner or a line | `Chip` or `Banner` in the status's tone | error `alert`, warning `needs`, success `positive` (a chip `live`), info `working` (a chip `accent`) (Colour, Status sets) |
101
117
  | Something that cannot be undone | `ConfirmDialog` | as Patterns' editing table says |
102
118
  | A page that is not there, offline, an error | `StatusScreen` | plain words, one act; never a status code |
103
119
  | Something that needs you later | a chat card in its app's chat and a row in Needs you | never a popup |
@@ -106,7 +122,7 @@ Components new in 0.5.0 are marked (new).
106
122
 
107
123
  | Need | Component | Rule |
108
124
  | --- | --- | --- |
109
- | Content on its way | `Skeleton` (the shimmer, one quiet grey, over ghost shapes) | never a spinner for content |
125
+ | Content on its way | `Skeleton` (the shimmer, one quiet grey, over ghost shapes) | never a spinner for content; a whole page keeps its own bar, its name shown at once, over a board of card skeletons (the page ghost) |
110
126
  | An answer at work | `StatusLine` (new) | the agent, what it is doing, the step |
111
127
  | A long load with no figure | `LoadBar` (new) | it never claims to finish before it has |
112
128
  | A press waiting on its answer | `Button pending` | keeps its width; a second press waits; the button stays focusable |
@@ -18,7 +18,7 @@ piece.
18
18
  | A key number that opens into its story | a tile: label, figure, pace bar or a mini chart (columns of the periods behind it, or a line with dots), foot; it grows across its row into a chart and a side column | `MetricTile` (new) |
19
19
  | Where a whole goes (a bill, a team's time) | one stacked bar, 1 px cuts between parts, a key under it | `ShareBar` (new) |
20
20
  | How a value changes over time, against a reference | a step line, the reference dotted, the gap between them hatched, events marked | `StepLine` (new) |
21
- | How a value moves over periods (a month's ARR, a week's calls), read on an axis | a line with its dots and the hatched area under it, or columns, switching between the two by a morph; a plan as a dotted salmon line | `TrendLine` (new) |
21
+ | How a value moves over periods (a month's ARR, a week's calls), read on an axis | a line with its dots and the hatched area under it, or columns, switching between the two by a morph; a plan as a dotted salmon line; two or three series in one unit as lines with a key | `TrendLine` (new) |
22
22
  | How several groups do on several measures | lanes by measures, each cell a tone and a figure | `Heatmap` (new) |
23
23
  | Compare a few categories (calls by kind) | horizontal bars with a fade, the number and label at the right | `GoalBars` |
24
24
  | Compare a few categories where height reads better (a hero) | vertical tubes with the number on a stalk | `GoalTubes` |
@@ -33,8 +33,8 @@ piece.
33
33
  | Yes or no across a few sources | a matrix of tone cells | `Matrix` (new) |
34
34
  | A sequence or a wait | steps on a line that fills | `Stepper` |
35
35
 
36
- Do not use: a pie with more than three parts (make it bars or a `ShareBar`), a free line chart (two series or more, or a
37
- line with no axis: make it thin bars, a `TrendLine` of one series over periods, or a `StepLine` where a designer draws
36
+ Do not use: a pie with more than three parts (make it bars or a `ShareBar`), a free line chart (more than three series,
37
+ or a line with no axis: make it thin bars, a `TrendLine` of up to three series in one unit over periods, or a `StepLine` where a designer draws
38
38
  a bill or a level over time; a `MetricTile`'s mini line with dots for a rate that holds near its target), an axis or a
39
39
  grid where thin bars suffice, stacked bars
40
40
  across categories (make two rows; one `ShareBar` for one whole is fine), a donut for a single number (make it the goal
@@ -74,6 +74,9 @@ Seth draws most shares as ticks. The rules every strip follows:
74
74
  labels, 12 before the plot; a `TrendLine` keeps 0.5 px value rules and right-aligned value labels, 12 before the plot,
75
75
  its columns starting at zero.
76
76
  - **A hover card may add detail, never be the only reading**: the value is written beside the mark.
77
+ - **One value axis, never two.** Series in different units, or one more than four times another, are two `TrendLine`s
78
+ stacked in one card on the same periods, each with its own axis and a key of one, the period names only under the
79
+ last. Up to three series that share a unit share one axis, a line each, with a key; a hover reads every series.
77
80
  - One chart per card; one hero figure per card; a change is a `ChangeChip` (in `Chip`).
78
81
 
79
82
  ## Data rules
@@ -161,7 +161,8 @@ What a person sees the first time they open an app's thread (issue #12, Seth's v
161
161
  interactive). The row wraps; a tile is never narrower than 168.
162
162
  4. **The composer** at the foot, with a few starters (`SuggestionChip`).
163
163
 
164
- Nothing proactive arrives on a first open; the agent speaks when asked.
164
+ Nothing proactive arrives on a first open; the agent speaks when asked. (The daily briefing, recipe 25, starts once
165
+ there is data to brief on.)
165
166
 
166
167
  ## 23. A report with its drawer
167
168
 
@@ -209,6 +210,44 @@ Seth's Grow review inbox (Figma 313:2671).
209
210
  - **Keyboard**: arrow keys move through the list; Previous and Next move the item and the chosen row together.
210
211
  - **On a phone** the tiles stack, the list is the screen and the item is its own screen with Back.
211
212
 
213
+ ## 25. An agent desk: one thread per account
214
+
215
+ An agent that works a book of accounts with the person (Calvin in Customer Value): one chat, its threads kept by the
216
+ account they are about, the day's briefing on top. Every part is in the catalog.
217
+
218
+ - **The frame**: `AppShell`, the app's pages in its nav; the desk's row carries the count of what waits on the person.
219
+ The stage's wide body (`ws-app-shell__body ws-app-shell__body--wide`) holds one filled `ListDetail`
220
+ (`ws-list-detail ws-list-detail--fill`, joined), the list at North's 362 (`--ws-list-detail-list`): the threads,
221
+ then the open thread.
222
+ - **The threads** (the list): its head holds the filter (`Segmented --clear --stretch`: "Waits on you" and "All", each
223
+ with its count); its scroller holds `SideList`'s picks, one per thread, the latest activity first. "Today", the
224
+ briefing, is always the first. Then one pick per account the person has talked about: the dot in the account's
225
+ rating tone (teal healthy, mid blue watch, pink at risk: Colour's rating tones, never salmon), the account's name,
226
+ its last line as the sub (the person's last question or the agent's last act), when at the end, and what waits on
227
+ the person there in salmon's AA word. Questions about the whole book go to one "Your book" thread. There is no "New
228
+ chat": a thread starts from the account ("Ask about this" on its page) or from the composer naming it.
229
+ - **The open thread** (the detail): its head (`__top`) holds the account's name (`ws-section`) and its rating `Chip`,
230
+ "Open the account" at the right. Then the turns (`ChatTurn`): the person's in a bubble, the agent's as plain words,
231
+ each answer words plus at most one card (`ChatCard`): an email, a call or a text to read or answer now (the message
232
+ kinds), the Account card when a decision is due, a Suggestion holding a draft `Plate` for a reply it wrote. Every
233
+ other message is named in its words with its source ("From the 9 Nov call"); the full history is the account's
234
+ page. A long thread is marked by topic (`TopicRail`). The `Composer` sits at the detail's foot (where recipe 24's
235
+ acts sit), its starters for this account ("Catch me up", "Draft a reply to Jordan").
236
+ - **The briefing** ("Today"): written once a day at the hour the person set (6:00 by default, in their own time zone),
237
+ and the desk opens on it. One sentence on the day ("Morning, Halli. Three accounts need you and two replies are ready
238
+ to send."), then what needs the person as one `Well` (Home's Needs you, recipe 1): a row per account and its one
239
+ ask, the state word at the right, each row opening that account's thread at the card it means. Then at most one card,
240
+ the most pressing (a ready reply to send). Nothing else is copied in: each account's cards stay in its own thread. A
241
+ day with nothing due says so in one line. Before there is data, the desk's first open is recipe 22.
242
+ - **At 1440**: the nav open (232), the list 362, the thread the rest, about the chat's 760 reading column; cards at most
243
+ 556, their trays at 80.
244
+ - **At 390**: the nav is the bar's menu (AppShell's phone form); the list is the screen and the briefing its first
245
+ pick; a thread opens as its own screen with Back (recipe 24's phone form); the composer at the foot, clear of the
246
+ safe area; cards fill the column, their trays at 64.
247
+ - **Everywhere else in the app**: "Ask about this" on an account opens its own thread docked (`ChatShell`), the same
248
+ thread the desk shows. One chat, never a second assistant on the page.
249
+ - **Keyboard**: arrow keys move through the threads (recipe 24); `/` puts the focus in the composer.
250
+
212
251
  ## What every recipe shares
213
252
 
214
253
  One primary per page (navy in a product, the salmon gradient on a public page). The gutter is the stage's; one content
@@ -105,7 +105,7 @@ follows cause to effect on the way in; on the way out the person has already mov
105
105
  | Component | Enters | Leaves | How the exit gets to play |
106
106
  | --- | --- | --- | --- |
107
107
  | `Menu`, `Popover` | out of the corner it hangs from, 4 px toward its control, from `--ws-open-scale` (0.97), on `--ws-spring-settle` ("Messages and steps settle") | back into that corner over `--ws-duration-exit` (120 ms) on `--ws-ease-exit` | a native `popover`: `@starting-style` and `allow-discrete` keep its box while it leaves, and a close mid-entrance turns back. Mounted by the app: `data-leaving`, then remove it |
108
- | `Dialog` | the scrim fades; the window rises 14 px out of `--ws-open-scale-pane` (0.98) on `--ws-spring-settle`, its parts settling in after it | 8 px down over `--ws-duration-exit` | a native `<dialog>` (`showModal()`, `close()`), the same way. A drawer slides in from its edge over `--ws-duration-grow` on `--ws-ease-grow` and back over `--ws-duration-shrink` |
108
+ | `Dialog` | the scrim fades; the window rises 14 px out of `--ws-open-scale-pane` (0.98) on `--ws-spring-settle`, its parts settling in after it | 8 px down over `--ws-duration-exit` | a native `<dialog>` (`showModal()`, `close()`), the same way. A drawer slides in from its edge over `--ws-duration-grow` on `--ws-ease-grow` and back over `--ws-duration-shrink`. Mounted by a library (`ws-dialog--mounted` and `ws-dialog__scrim`): Radix's `data-state="closed"`, or `data-leaving`, then remove it |
109
109
  | `Toast` | up out of `--ws-open-scale-toast` (0.96) on `--ws-spring-settle` | 4 px down over `--ws-duration-exit` | `data-leaving`, then remove it |
110
110
  | `Tooltip` | pops from 0.9, 4 px toward its control, on `--ws-spring-pop` ("Tooltip pop-in"), after the 40 ms hover intent; at once on keyboard focus | fades off over 180 ms | CSS alone: hover, focus or `ws-tooltip--open` |
111
111
  | `HoverCard` | pops from 0.9 on `--ws-spring-pop`, its rows settling 45 ms apart; `--follow` glides after the pointer on `--ws-spring-follow`, which never bounces | to `--ws-pop-scale` over `--ws-duration-exit` | `data-leaving`, then remove it |
@@ -19,6 +19,17 @@ sit in a bubble with navy text (`ChatTurn` has the sizes). Starters sit under th
19
19
  conversation is marked by topic (`TopicRail`), never split into threads the person did not ask for. A reply is words plus at most one card, never both saying the
20
20
  same thing. An act is a one-line receipt ("Drafted the opener for Nellie"), not a paragraph. A question is not echoed back.
21
21
 
22
+ ## Threads by account, and the daily briefing
23
+
24
+ An agent that works a book of things with the person (accounts, deals) keeps one thread per thing, because the person
25
+ works them one at a time: the thread belongs to the account, is opened from it or by naming it, and is never a split
26
+ the person did not ask for. Inside one thread, subjects are still marked by topic (Page recipes, 25).
27
+
28
+ The one time an agent speaks first is the daily briefing the person set up: once a day, at their hour, as the first
29
+ turn of "Today". One sentence on the day, what needs them as one list, at most one card. Plain words with no bubble,
30
+ nothing that says "AI", no popup or push of its own: the desk's count is the only notice. It never copies what each
31
+ thread already holds, and it stays quiet until there is data to brief on.
32
+
22
33
  ## Streaming, working and cancelling
23
34
 
24
35
  A reply arrives as it is written; while it works, a status line (`StatusLine`) says who is working, what it is doing and
@@ -504,3 +504,44 @@ every grey ghost block. He wants loaders calm and neutral.
504
504
  | 10 Nov 2026 | Amit (via Claude) | Loading is one quiet tone: the shimmer (`--ws-shimmer`) is the ghost grey with a lighter pass of the same grey, never a chart hue, in light, night, the navy ground and every palette. Overturns D7's "loading is a shimmer in the chart colours", the Motion row "The skeleton breathes" (4 Nov) for its colours, and the loading shimmer as an exception to "no gradient text" in Colour. North's timing stays: the 300 % band at 100 deg over 1.8 s (`--ws-loop-shimmer` on `--ws-ease-shimmer`), still under reduced motion | Skeleton, Motion, Colour, Patterns, every `ws-shimmer` ghost |
505
505
  | 10 Nov 2026 | Amit (via Claude, open to veto) | How it is drawn. The ground is the ghost grey itself (`--ws-shimmer-ground` is now `--ws-ghost`: #E3DFDB, the night's #273544), the same at rest and in motion, so a ghost shows on the cream (1.29:1) and on the tray (1.13:1) in every theme and Skeleton's own ground for a card's foot is gone. The pass is the ghost 70 % of the way to the cream in light (#F6F3F0: 1.07:1 off the cream, 1.06:1 off the tray, so it shows on both) and 7 % toward the ink in dark (#354250; #364351 on the navy ground), the same step by eye (CIEDE2000 4.3); it derives from the ghost, the page and the ink, so a palette moves it. The chart ghost's colour band is dropped, not made neutral: in blend mode colour a neutral band has no hue and paints nothing, and in normal blend it would paint the card between the bars. Each bar is now a ghost under the same shimmer, so one token drives every loader | tokens (`_product.css`, `_dark.css`), Skeleton, the Motion card (its two rows now Close and Not yet) |
506
506
  | 10 Nov 2026 | Open, for Amit to rule | Not changed: `StatusLine`'s working words still pass through the AA steps of salmon, purple and teal. They are words at work, not a ghost; if "loaders" covers them too, they take a neutral pass next | StatusLine |
507
+
508
+ ## Rulings added 10 Nov 2026 (Hemanth's feedback, kit 0.5.2)
509
+
510
+ Hemanth built the Customer Value app on the kit (10 Nov call with Amit) and found what it was missing: two lines at
511
+ once on one chart (the kit said "two lines are two cards"), a whole page's loader, a stage track and a milestone row
512
+ for an onboarding, one card for two boards, a chat page for Calvin, and a way to update without re-running adopt,
513
+ which had stopped after 10 to 15 files. The look stays locked at 0.5 (Seth, Nikhil and Amit): everything here adds,
514
+ nothing restyles.
515
+
516
+ | Date | By | Decision | Where it bites |
517
+ | --- | --- | --- | --- |
518
+ | 10 Nov 2026 | Amit (via Claude, open to veto) | `TrendLine` draws up to three series in one unit on one axis (`__series`), navy, teal, purple, with a key; a hover reads every series for the period. Several series are lines only: no hatch, no Bars / Line switch. Different units, or one series more than four times another, are two TrendLines stacked in one card on the same periods; never two value axes. Overturns the 5 Nov "two series stay two cards" | Charts, `TrendLine` |
519
+ | 10 Nov 2026 | Amit (via Claude, open to veto) | A whole page loading is the page's own bar and board, not a new shape: the `PageBar` with its name at once, its data-bound words and act as ghosts, and the board holding tile and card skeletons where the real ones land (no new CSS). A list or a board page uses `Table`'s and `KanbanBoard`'s own ghosts | `Skeleton`, `EmptyState` |
520
+ | 10 Nov 2026 | Amit (via Claude, open to veto) | A thing's stages read across (`Stepper --across`), the in-hand stage opening in view; dated points are a milestone row (`--milestones`), the measure on each milestone, one quiet act on one not yet reached. A stall or a late milestone is words in needs-you (`__late`); the ring stays navy. `Timeline` stays the feed of what happened | `Stepper`, `Timeline`, Choosing components |
521
+ | 10 Nov 2026 | Amit (via Claude, open to veto) | Every board wears one card, its slots in a fixed order (kind and figure, time in stage, the title as the card's link, meta, up to three chips, a foot with people, a tally and one icon act, one well act when the stage waits on the person). Never a rail per column, a stage hue, an underlined title or a navy button on a card: a board is many cards, and one navy per page | `KanbanBoard` |
522
+ | 10 Nov 2026 | Amit (via Claude, open to veto) | An email, a call and a text are `ChatCard` kinds (the sender's words quoted on a sunk plate, three lines at most; Reply, or Listen for a call), and an account is a kind with its standing as a rating chip and one navy act. An agent that works a book of accounts keeps one thread per account and a daily briefing on top, the one time it speaks first (recipe 25) | `ChatCard`, Page recipes, AI experiences |
523
+ | 10 Nov 2026 | Amit (via Claude) | An app already on the kit takes a newer release with `brand-catchup` (only what the releases changed), never a second adopt. Adopt is done when `check-drift` finds nothing left or every leftover is named, and it leaves a baseline in CI so nothing new drifts in | `brand-catchup`, `brand-adopt`, `brand-audit`, `check-drift`, AGENTS.md |
524
+
525
+ ## Rulings added 11 Nov 2026 (Madan's Marketing OS feedback and Hemanth's sidebar, kit 0.5.3)
526
+
527
+ Madan filed eighteen gaps from moving Marketing OS (ContentOS) onto the kit, and Hemanth asked for a sidebar that holds
528
+ sections. Nikhil (10 Nov): Marketing OS shows the new UI to Stephen before Thursday, and apps never build a missing
529
+ component with Claude, so the kit carries each of these. Everything adds; nothing that exists changes how it looks.
530
+
531
+ | Date | By | Decision | Where it bites |
532
+ | --- | --- | --- | --- |
533
+ | 10 Nov 2026 | Amit (via Claude, open to veto) | AppShell's sidebar holds sections: a page's own pages fold in place, one level only. Folded, a section opens a Menu panel beside the rail, and the person at the foot opens the account menu. A group stays always open | `AppShell`, Choosing components |
534
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A chosen option is a tick at the row's end, never the sunk cream (that is the keyboard's) | `Combobox` |
535
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A far month or year is two small native selects in the picker's head; Today and Clear sit in a foot under Menu's line | `DateInput` |
536
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A time, and a date with a time, are the native field in DateInput's shell; no kit picker draws hours | `DateInput`, Choosing components |
537
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A joined act's caret holds the act's other forms, never other acts; a navy joined act is the surface's one navy act | `Button` |
538
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | Chip `--sm` (20) and Avatar `--xs` (20) are the dense steps; a chip that acts keeps 24 | `Chip`, `Avatar` |
539
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | Error, warning, success and info map onto the kit's tones (alert, needs, positive, working): no separate status colours, no solid status fills, and a field's error stays needs. `--ws-tint-alert`, the alert red at 8 %, is the ground of an error status | Colour, `Banner`, `Chip`, tokens |
540
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A drawer rising from a pane casts `--ws-shadow-rise`, the menu's drop upward | Space and layout, tokens |
541
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A dialog a library mounts is `ws-dialog--mounted` with `ws-dialog__scrim`: placed by the kit, the same moves as keyframes, out on `data-state="closed"` or `data-leaving` | `Dialog`, Motion |
542
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A card fold's acts sit beside the summary, never inside it; `ws-fold__peek` shows only while folded; tones are Banner's three | `Fold` |
543
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A picture rounds its own corners and the card never clips; a grid choice is a flush ring plus a tick, never the tab | `Card`, Choosing components |
544
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | An InlineEdit has the same box and type at rest and editing; its focus ring is drawn inside the box; the pencil always shows on touch | `InlineEdit` |
545
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A mention is mid blue words with no fill; only a mention of you takes the needs tint. The comment marker on content is the blue card tint, never an underline | `CommentThread` |
546
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | A diff never says it with colour alone: a sign, and an underline for what was added; removed lines are not struck, so the old words stay readable | `TextDiff` |
547
+ | 11 Nov 2026 | Amit (via Claude, open to veto) | Things on dates are a `Calendar`; a plan across its window is a `PlanTimeline`. Today is the one salmon mark in both; tones follow the palette; neither restyles `Stepper`, which keeps steps and milestones without a date axis | `Calendar`, `PlanTimeline`, Choosing components |