@felloinnovations/brand-kit 0.5.0 → 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.
- package/AGENTS.md +29 -9
- package/CHANGELOG.md +110 -0
- package/README.md +14 -6
- package/design-system/01-how-claude-decides.md +5 -3
- package/design-system/03-colour.md +22 -3
- package/design-system/05-space-and-layout.md +2 -1
- package/design-system/08-choosing-components.md +20 -4
- package/design-system/09-charts.md +7 -4
- package/design-system/10-patterns.md +1 -1
- package/design-system/11-page-recipes.md +40 -1
- package/design-system/13-motion.md +4 -4
- package/design-system/15-ai-experiences.md +11 -0
- package/design-system/17-decisions.md +51 -0
- package/design-system/components/AppShell/README.md +89 -21
- package/design-system/components/AppShell/preview.html +148 -3
- package/design-system/components/AppShell/style.css +47 -0
- package/design-system/components/Avatar/README.md +6 -3
- package/design-system/components/Avatar/preview.html +2 -1
- package/design-system/components/Avatar/style.css +3 -0
- package/design-system/components/Banner/README.md +9 -5
- package/design-system/components/Banner/preview.html +9 -0
- package/design-system/components/Banner/style.css +3 -0
- package/design-system/components/Button/README.md +29 -2
- package/design-system/components/Button/preview.html +33 -1
- package/design-system/components/Button/style.css +21 -0
- package/design-system/components/Calendar/README.md +148 -0
- package/design-system/components/Calendar/preview.html +449 -0
- package/design-system/components/Calendar/style.css +61 -0
- package/design-system/components/Card/README.md +13 -0
- package/design-system/components/Card/preview.html +23 -0
- package/design-system/components/Card/style.css +19 -0
- package/design-system/components/ChatCard/README.md +74 -3
- package/design-system/components/ChatCard/preview.html +126 -25
- package/design-system/components/ChatCard/style.css +6 -0
- package/design-system/components/CheckRow/README.md +1 -1
- package/design-system/components/CheckRow/preview.html +1 -1
- package/design-system/components/CheckRow/style.css +1 -1
- package/design-system/components/Chip/README.md +16 -7
- package/design-system/components/Chip/preview.html +25 -1
- package/design-system/components/Chip/style.css +5 -0
- package/design-system/components/Combobox/README.md +10 -4
- package/design-system/components/Combobox/preview.html +19 -4
- package/design-system/components/Combobox/style.css +7 -1
- package/design-system/components/CommentThread/README.md +138 -0
- package/design-system/components/CommentThread/preview.html +134 -0
- package/design-system/components/CommentThread/style.css +41 -0
- package/design-system/components/DateInput/README.md +38 -4
- package/design-system/components/DateInput/preview.html +50 -2
- package/design-system/components/DateInput/style.css +6 -0
- package/design-system/components/Dialog/README.md +26 -3
- package/design-system/components/Dialog/preview.html +80 -0
- package/design-system/components/Dialog/style.css +28 -3
- package/design-system/components/EmptyState/README.md +1 -1
- package/design-system/components/Fold/README.md +21 -0
- package/design-system/components/Fold/preview.html +44 -1
- package/design-system/components/Fold/style.css +30 -0
- package/design-system/components/InlineEdit/README.md +116 -0
- package/design-system/components/InlineEdit/preview.html +135 -0
- package/design-system/components/InlineEdit/style.css +34 -0
- package/design-system/components/Input/README.md +20 -1
- package/design-system/components/Input/preview.html +24 -0
- package/design-system/components/Input/style.css +13 -1
- package/design-system/components/KanbanBoard/README.md +69 -5
- package/design-system/components/KanbanBoard/preview.html +129 -0
- package/design-system/components/KanbanBoard/style.css +32 -1
- package/design-system/components/ListDetail/preview.html +1 -1
- package/design-system/components/Matrix/README.md +1 -1
- package/design-system/components/Matrix/preview.html +1 -1
- package/design-system/components/Motion/README.md +2 -2
- package/design-system/components/Motion/preview.html +8 -8
- package/design-system/components/PlanTimeline/README.md +144 -0
- package/design-system/components/PlanTimeline/preview.html +109 -0
- package/design-system/components/PlanTimeline/style.css +64 -0
- package/design-system/components/README.md +12 -7
- package/design-system/components/ScoreHero/README.md +2 -2
- package/design-system/components/ScoreHero/style.css +1 -1
- package/design-system/components/ShareBar/README.md +1 -1
- package/design-system/components/ShareBar/style.css +1 -1
- package/design-system/components/Skeleton/README.md +82 -17
- package/design-system/components/Skeleton/preview.html +84 -2
- package/design-system/components/Skeleton/style.css +9 -14
- package/design-system/components/Starter/README.md +1 -1
- package/design-system/components/Starter/preview.html +1 -1
- package/design-system/components/Stepper/README.md +81 -5
- package/design-system/components/Stepper/preview.html +64 -1
- package/design-system/components/Stepper/style.css +29 -0
- package/design-system/components/StreakCalendar/README.md +1 -0
- package/design-system/components/Table/README.md +8 -4
- package/design-system/components/Table/preview.html +16 -1
- package/design-system/components/Table/style.css +3 -1
- package/design-system/components/TextDiff/README.md +96 -0
- package/design-system/components/TextDiff/preview.html +42 -0
- package/design-system/components/TextDiff/style.css +21 -0
- package/design-system/components/TickStrip/README.md +1 -1
- package/design-system/components/TickStrip/preview.html +1 -1
- package/design-system/components/TickStrip/style.css +1 -1
- package/design-system/components/Timeline/README.md +4 -2
- package/design-system/components/TrendLine/README.md +38 -7
- package/design-system/components/TrendLine/preview.html +140 -3
- package/design-system/components/TrendLine/style.css +12 -2
- package/design-system/components/Well/README.md +1 -1
- package/design-system/components/Well/style.css +2 -2
- package/design-system/components/_house.css +1 -1
- package/design-system/components/bundle.css +501 -30
- package/design-system/tokens.json +17 -7
- package/dist/fello-core.css +2 -2
- package/dist/fello.css +2 -2
- package/dist/fello.scoped.css +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/scoped.js +2 -2
- package/dist/tokens.d.ts +16 -8
- package/dist/tokens.js +16 -8
- package/package.json +7 -2
- package/scripts/check-drift.mjs +325 -0
- package/scripts/token-model.mjs +2 -1
- package/tokens/_dark.css +3 -2
- package/tokens/_product.css +13 -11
- package/tokens/palettes.ts +1 -1
- package/tokens/shadcn-compat.css +1 -1
- package/tokens/shadcn-compat.hsl.css +1 -1
- package/tokens/tokens.css +23 -15
- package/tokens/tokens.md +56 -50
- package/tokens/tokens.root.css +23 -15
- package/tokens/tokens.ts +17 -9
package/AGENTS.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# brand-kit for coding agents (0.5.
|
|
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.
|
|
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
|
|
174
|
-
the
|
|
175
|
-
(`
|
|
176
|
-
|
|
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
|
-
|
|
242
|
-
the
|
|
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`
|
|
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,115 @@
|
|
|
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
|
+
|
|
89
|
+
## 0.5.1 (10 Nov 2026)
|
|
90
|
+
|
|
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
|
|
92
|
+
like the salmon, purple and green tints sweeping every grey ghost block (Decisions, 10 Nov 2026).
|
|
93
|
+
|
|
94
|
+
- **The shimmer is one neutral tone.** `--ws-shimmer` is the ghost grey with a lighter pass of the same grey, no chart
|
|
95
|
+
hues, in light, night, the navy ground and every palette. North's timing stays: 1.8 s on `--ws-loop-shimmer` and
|
|
96
|
+
`--ws-ease-shimmer`, the 300 % band at 100 deg; still under reduced motion. Every ghost that wears the shimmer
|
|
97
|
+
(Skeleton, a pending Stat, StatTiles, Table, Well, TickStrip, ShareBar, ScoreHero and the rest) changes with no
|
|
98
|
+
markup change.
|
|
99
|
+
- **One ghost grey at rest and in motion.** `--ws-shimmer-ground` is now `--ws-ghost` (#E3DFDB, the night's #273544),
|
|
100
|
+
so a ghost shows on the cream (1.29:1) and on the tray (1.13:1) alike, and the still ghost under reduced motion is the
|
|
101
|
+
same grey. Skeleton's own ground for a card's foot or band is gone.
|
|
102
|
+
- **The chart ghost's colour band is gone.** `ws-skeleton__chart`'s bars are ghosts under the same shimmer; the band
|
|
103
|
+
that crossed the drawing in blend mode colour is removed (a neutral band there would paint nothing).
|
|
104
|
+
- **The docs say so**: the Skeleton card and preview, the Motion card (the shimmer row is now Close, the chart band row
|
|
105
|
+
Not yet), Colour, Motion, Patterns, Charts, Choosing components and every loading line in the catalog.
|
|
106
|
+
- **Pinned links keep working**: `/v/0.5.0/` is kept as a snapshot (`hosted/v/0.5.0`), so a page pinned to it still
|
|
107
|
+
loads after the bump. Pinned links in the docs now point at `/v/0.5.1/`.
|
|
108
|
+
|
|
109
|
+
**Upgrading from 0.5.0**: nothing to change. A copy of the old gradient, or of #ECE8E4 as the shimmer's grey, should
|
|
110
|
+
become `var(--ws-shimmer)` or `var(--ws-shimmer-ground)`. `StatusLine`'s working words keep their colours for now (open
|
|
111
|
+
in Decisions).
|
|
112
|
+
|
|
3
113
|
## 0.5.0 (4 Nov 2026)
|
|
4
114
|
|
|
5
115
|
The kit the whole team can trust: teams kept hitting alignment, spacing and placement bugs, and Seth (the designer) has
|
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,
|
|
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.
|
|
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
|
|
@@ -183,11 +189,13 @@ is no longer maintained. Only the kit's owners (Amit and Arpan) change tokens.
|
|
|
183
189
|
|
|
184
190
|
## Releasing
|
|
185
191
|
|
|
186
|
-
CI publishes.
|
|
187
|
-
|
|
192
|
+
CI publishes. Before the bump, keep the released hosted tree: `yarn hosted`, then copy `site-dist/v/<released
|
|
193
|
+
version>` to `hosted/v/` (the gallery serves every snapshot there, so pinned links keep working). Bump `version` in
|
|
194
|
+
`package.json` and the pinned `/v/` links (`AGENTS.md`, `skill/SKILL.md`, this README, `Starter`, guide 01; the plugin is
|
|
195
|
+
unversioned), run `yarn build` and `yarn skill`, commit, then push a tag that matches:
|
|
188
196
|
|
|
189
197
|
```sh
|
|
190
|
-
git tag v0.5.
|
|
198
|
+
git tag v0.5.3 && git push origin v0.5.3
|
|
191
199
|
```
|
|
192
200
|
|
|
193
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.
|
|
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
|
|
112
|
-
|
|
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,12 +35,12 @@ 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 |
|
|
42
42
|
| An off control (a switch's track at rest) | `ws-control-off` | #7F7F7F |
|
|
43
|
-
| The loading shimmer's ground | `ws-shimmer-ground` | #
|
|
43
|
+
| The loading shimmer's ground: the ghost grey, with a lighter pass of the same grey (never a chart hue) | `ws-shimmer-ground` | #E3DFDB (`ws-ghost`) |
|
|
44
44
|
| A hero's glows, an assistant's working orb | `ws-glow-rose`, `ws-glow-pink`, `ws-glow-blue`, `ws-orb` | from the chart tones |
|
|
45
45
|
| Focus | `ws-focus-color` | navy |
|
|
46
46
|
| Behind a dialog | `ws-scrim` | navy 35% |
|
|
@@ -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
|
|
@@ -99,7 +117,8 @@ Never a state by colour alone: a word or a mark goes with it.
|
|
|
99
117
|
- **An assistant's mark** takes one of the four tones and keeps it; no other colour names it.
|
|
100
118
|
- **The AI colours** (`color-ai-*`) exist only inside an assistant's orb mark, if the product has one, and as faint washes
|
|
101
119
|
in `ws-cool-glow` and `ws-team-glow` behind a page hero. No conic rings, purple glows or gradient text, except the
|
|
102
|
-
status line's word while an answer works (`StatusLine`, in the chart colours)
|
|
120
|
+
status line's word while an answer works (`StatusLine`, in the chart colours). The loading shimmer is one neutral
|
|
121
|
+
tone, the ghost grey and a lighter pass of it, never the chart colours (0.5.1).
|
|
103
122
|
- **People are neutral**: a disc of `ws-surface-sunk` with navy initials.
|
|
104
123
|
- **Marketing pages** keep the kit's own marketing colours (its gradient button, `color-text-primary`); they never enter a
|
|
105
124
|
product screen.
|
|
@@ -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`)
|
|
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
|
|
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 (
|
|
37
|
-
line with no axis: make it thin bars, a `TrendLine` of
|
|
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
|
|
@@ -89,7 +92,7 @@ Seth draws most shares as ticks. The rules every strip follows:
|
|
|
89
92
|
|
|
90
93
|
## States
|
|
91
94
|
|
|
92
|
-
Loading and empty follow Patterns (
|
|
95
|
+
Loading and empty follow Patterns (the shimmer, one quiet grey, over the chart's ghost; the same card with its act).
|
|
93
96
|
|
|
94
97
|
| State | How |
|
|
95
98
|
| --- | --- |
|
|
@@ -58,7 +58,7 @@ moves. A state never changes a thing's size, its type size or its place, so noth
|
|
|
58
58
|
| Focus | a 2 px navy ring 2 px outside (`ws-focus-color`); inside a dense row, a well, a list or a clipped container the same ring drawn inside (`ws-focus-inset`) | `:focus-visible` only; never `outline: none` without the ring (Accessibility) |
|
|
59
59
|
| Selected, open, current | the ground changes (the sunk cream, or the well for a pill in an inset list), the words go navy or 600; a list's selected fill slides from the row it left; the dividers beside an inset pill drop | the row keeps its height and type size; `aria-selected`, `aria-current` or `aria-expanded` says it |
|
|
60
60
|
| Pending | the control keeps its width and its words; the working dot sits in its padding on the one beat; it stays focusable (`aria-disabled`, `aria-busy`) and refuses a second press | from 100 ms (Latency above); words that say what is happening ("Saving") |
|
|
61
|
-
| Loading | the region's ghost
|
|
61
|
+
| Loading | the region's ghost under the shimmer (one quiet grey), the size of what it stands for; its head shows at once | never a spinner for content; still under reduced motion, with a word |
|
|
62
62
|
| Disabled | dimmed (the component's own opacity), no pointer events, the reason said nearby | prefer leaving the act out, or keeping it focusable and saying why |
|
|
63
63
|
| Others step back | while one row, part or tile is in focus, the rest dim (a matrix's other rows to 20%, a chart's other parts to `ws-dim`); the dimmed keep their grounds and dividers. A word that must stay readable steps to muted grey instead of fading (a heatmap's other squares fade their heat and status bar, their words stay AA) | the focused one never changes |
|
|
64
64
|
|
|
@@ -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 |
|
|
@@ -193,9 +193,9 @@ of cards wears `.ws-build`; each card in it wears `.ws-build__card` with `--ws-i
|
|
|
193
193
|
|
|
194
194
|
### Loading
|
|
195
195
|
|
|
196
|
-
Content on its way is a ghost the size of what it stands for with the shimmer passing over it
|
|
197
|
-
(`Skeleton`, or `.ws-shimmer` on a block of your own:
|
|
198
|
-
a spinner. When the content lands, its details settle in top to bottom (`.ws-settle` with `--ws-i` on each, 22 ms
|
|
196
|
+
Content on its way is a ghost the size of what it stands for with the shimmer passing over it: one quiet tone, the
|
|
197
|
+
ghost grey and a lighter pass of the same grey, never a chart hue (`Skeleton`, or `.ws-shimmer` on a block of your own:
|
|
198
|
+
every `--ws-loop-shimmer`, 1.8 s, on `--ws-ease-shimmer`), never a spinner. When the content lands, its details settle in top to bottom (`.ws-settle` with `--ws-i` on each, 22 ms
|
|
199
199
|
apart). An answer at work shows a `StatusLine`; a long load with no figure a `LoadBar`; a pressed button waiting keeps
|
|
200
200
|
its width and shows its working dot on `--ws-loop`. Why: the layout is already in place, so nothing jumps when the real
|
|
201
201
|
thing arrives. Under reduced motion the shimmer stops on its ghost and the words say what is loading.
|
|
@@ -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
|