@brignano/design 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/DECISIONS.md CHANGED
@@ -215,3 +215,36 @@ with it; `--mark` does not.
215
215
  separates them; a form error is not "rust means overdue", but they are the same
216
216
  register of message.
217
217
  - Nothing amber is clickable anywhere in the system.
218
+
219
+ ---
220
+
221
+ ## ADR-0005 — Diagrams are not charts: neutral nodes, colour for state only
222
+
223
+ **Status:** accepted · 2026-10-13
224
+
225
+ ### Context
226
+
227
+ `driftwood` draws architecture diagrams and was the first consumer to need them.
228
+ Its first pass on these tokens took the chart exception (§8, ADR-0002) and tinted
229
+ each node by family (edge, compute, data, messaging…) with `--chart-1…6`. On a
230
+ real 46-resource platform that put six hues on screen before anything was wrong,
231
+ and the database that was down was one more tinted box among them.
232
+
233
+ ### Decision
234
+
235
+ A diagram follows the restraint rule. The chart exception exists because a chart
236
+ has nothing *but* colour to tell series apart; a diagram node has an icon, a name
237
+ and a kind label, so family is already carried three times. Nodes are neutral.
238
+ Colour is reserved for state: health (`--danger`, `--attention`) and what a change
239
+ did, via three new aliases — `--diff-added`, `--diff-changed`, `--diff-removed` —
240
+ over the existing state hues. No new hue enters the system.
241
+
242
+ ### Consequences
243
+
244
+ - On a healthy, unchanged system the diagram is grey, and that is correct:
245
+ nothing is asking for you.
246
+ - `--diff-changed` shares cobalt with links. Context separates them (a node edge
247
+ with a `~ changed` tag is not underlined text), the same way feedback and domain
248
+ status share hues in ADR-0004.
249
+ - Standalone exports (SVG files, Mermaid in a pull request) take the light theme's
250
+ values, resolved from `tokens.css` by the consumer at build time.
package/DESIGN.md CHANGED
@@ -159,7 +159,44 @@ rationale in [`tokens.chart.css`](./tokens.chart.css). The short version:
159
159
  - Text wears text tokens, never the series colour.
160
160
  - **Never a dual-axis chart.** Two measures of different scale → two charts.
161
161
 
162
- ## 9. Accessibility floor
162
+ ## 9. Diagrams and diffs
163
+
164
+ An architecture diagram (`driftwood`, `homelab`) is a picture of a system, read to
165
+ answer "what changed, and what is broken". It follows the restraint rule, **not**
166
+ the chart exception: node *type* is a category like event type, and is carried by
167
+ an icon and a label, never a hue. A diagram where every node is tinted by family
168
+ is thirty coloured things, and the one that is down disappears among them.
169
+
170
+ - **Nodes are neutral.** `--card` fill, `--line-strong` edge, `--radius` corners,
171
+ an icon in `--ink-soft`, the name in `--ink`, the kind in `--mono` at
172
+ `--text-xs` in `--ink-soft`. Grouping is a zone: `--line` hairline, no fill or
173
+ a faint one, a `--mono` eyebrow label.
174
+ - **Edges are `--slate`.** They are UI marks (3:1), never text.
175
+ - **Only state gets colour**, and always as a tag with a symbol and a word as well:
176
+
177
+ | Token | Means | Tag |
178
+ |---|---|---|
179
+ | `--diff-added` | this change created it | `+ added` |
180
+ | `--diff-changed` | this change modified it | `~ changed` |
181
+ | `--diff-removed` | this change removes it — dashed, struck through | `− removed` |
182
+ | `--danger` | it is down | `✕ down` |
183
+ | `--attention` | degraded, or differs from the design | `▲ degraded` |
184
+
185
+ The diff tokens alias the state hues on purpose (added is *settled*, a change is
186
+ *informational*, a removal is the change that can lose data), so a diff adds no
187
+ hue to the system. Health wins the fill (`-surface`); a diff only takes the edge.
188
+ - **Selection** is the focus treatment: a 2px `--i-ink` outline, offset. Asking
189
+ "what depends on this?" dims everything unrelated to ~30% opacity and inks the
190
+ connecting edges in `--ink`; it never introduces a colour.
191
+ - **Lead with the verdict.** A page about a deploy opens with one sentence saying
192
+ what happened and what needs you, then the pills that back it up, then the
193
+ picture.
194
+ - **Diagrams follow the theme.** On a page they use the tokens like everything
195
+ else. A diagram exported as a standalone file (an SVG, a Mermaid block in a pull
196
+ request) cannot use `var()`; it takes the **light** theme's values, resolved from
197
+ this file at build time, never typed in.
198
+
199
+ ## 10. Accessibility floor
163
200
 
164
201
  Non-negotiable in both themes:
165
202
 
@@ -171,7 +208,7 @@ Non-negotiable in both themes:
171
208
  - Measured ratios sit next to their values in `tokens.css`. Changing a value means
172
209
  re-measuring it.
173
210
 
174
- ## 10. Integrating with a Tailwind consumer
211
+ ## 11. Integrating with a Tailwind consumer
175
212
 
176
213
  Tailwind's dark variant keys off a `.dark` class; these tokens key off
177
214
  `[data-theme]`. **Both must be set together**, by the same code, in both places
@@ -200,7 +237,7 @@ Import order matters — Tailwind first, then tokens, then the bridge:
200
237
  @import "@brignano/design/tailwind.css";
201
238
  ```
202
239
 
203
- ## 11. The one rule that keeps this true
240
+ ## 12. The one rule that keeps this true
204
241
 
205
242
  **Never hardcode a hex outside `tokens.css`.**
206
243
 
package/README.md CHANGED
@@ -9,6 +9,7 @@ The shared design system for every brignano surface — `brignano.io`, `life`,
9
9
  | [`DECISIONS.md`](./DECISIONS.md) | Why the values are what they are. ADRs. |
10
10
  | [`tokens.css`](./tokens.css) | Single source of truth for colour, type, space, shape, motion. |
11
11
  | [`tokens.chart.css`](./tokens.chart.css) | Validated categorical palette for data viz. |
12
+ | [`previews/`](./previews) | Live swatches. Open one in a browser to see the tokens render. |
12
13
 
13
14
  ## The shape of it
14
15
 
@@ -35,6 +36,31 @@ The tool tier is the default. A marketing surface opts in with
35
36
  `class="tier-marketing"` on `<html>`, which unlocks the display face and opens the
36
37
  type scale. Colour is identical across tiers.
37
38
 
39
+ ## Previews
40
+
41
+ `previews/` holds a page per area — colour, type, elevation, controls, feedback, diagrams,
42
+ status. Each renders its subject twice, once in the viewer's theme and once on a
43
+ forced-dark ground, so drift between the two shows up without toggling anything.
44
+ No build step: open the file.
45
+
46
+ Every preview opens with a card marker:
47
+
48
+ ```html
49
+ <!-- @dsCard group="Foundations" -->
50
+ ```
51
+
52
+ That first line is what a [claude.ai/design][ds] design-system project reads to
53
+ build its card index — `group` becomes the section heading in the Design System
54
+ pane. The markers are comments, so they cost nothing when the page is opened
55
+ locally.
56
+
57
+ **A sync to such a project keeps this layout** — `tokens.css` at the project
58
+ root, `previews/` one level below it. `_preview.css` reaches it with
59
+ `@import '../tokens.css'` rather than carrying its own copy, because a second
60
+ copy of the tokens is the drift this repo exists to prevent. The trade is that
61
+ the parent reference is load-bearing: flatten the uploaded bundle and every
62
+ preview renders unstyled.
63
+
38
64
  ## For agents
39
65
 
40
66
  Read `DESIGN.md` before styling anything. Use the tokens. **Never hardcode a hex
@@ -84,4 +110,5 @@ and repo, workflow filename `publish.yml`, and **environment name blank**, since
84
110
  these workflows declare no `environment:`. Configure it before the first tag, or
85
111
  the first publish fails the way this one did.
86
112
 
113
+ [ds]: https://claude.ai/design
87
114
  [tp]: https://docs.npmjs.com/trusted-publishers/
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@brignano/design",
3
- "version": "0.1.2",
4
- "description": "Shared design system for brignano surfaces \u2014 colour, type, space, shape, motion.",
3
+ "version": "0.2.0",
4
+ "description": "Shared design system for brignano surfaces — colour, type, space, shape, motion.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
package/tokens.css CHANGED
@@ -136,6 +136,26 @@
136
136
  --danger-line: color-mix(in srgb, var(--danger) 32%, transparent);
137
137
  --info-line: var(--i-line);
138
138
 
139
+ /* ── Diff ─────────────────────────────────────────────────────────────
140
+ What a change did to a thing: a deploy, a plan, a pull request. Aliases
141
+ of the state hues, so a diff adds no hue of its own (DESIGN.md §9):
142
+
143
+ --diff-added created by this change success — settled
144
+ --diff-changed modified by this change interactive — informational
145
+ --diff-removed removed by this change danger — can lose data
146
+
147
+ Always with a symbol and a word (+ added, ~ changed, − removed). Aliased
148
+ in this block only: these resolve against whichever theme block wins. */
149
+ --diff-added: var(--success);
150
+ --diff-added-ink: var(--success-ink);
151
+ --diff-added-surface: var(--success-surface);
152
+ --diff-changed: var(--i);
153
+ --diff-changed-ink: var(--i-ink);
154
+ --diff-changed-surface: var(--i-surface);
155
+ --diff-removed: var(--danger);
156
+ --diff-removed-ink: var(--danger-ink);
157
+ --diff-removed-surface: var(--danger-surface);
158
+
139
159
  /* ── Mark — identity ──────────────────────────────────────────────────
140
160
  Inks a GRAPHIC: the trail line, the A|B monogram, a hero rule. That is
141
161
  the entire permitted use.
@@ -331,6 +351,23 @@
331
351
  --scrim: rgba(0, 0, 0, 0.68);
332
352
  }
333
353
 
354
+ :root {
355
+ /* Tool-tier scale — compact, because scanning beats reading.
356
+ Declared BEFORE the marketing tier on purpose: `:root` and
357
+ `.tier-marketing` have the same specificity, so on <html> whichever
358
+ comes later wins. With this block last, the class did nothing. */
359
+ --text-xs: 0.6875rem;
360
+ --text-sm: 0.8125rem;
361
+ --text-base: 0.9375rem;
362
+ --text-lg: 1.0625rem;
363
+ --text-xl: 1.25rem;
364
+ --text-2xl: 1.5rem;
365
+ --text-3xl: 1.875rem;
366
+ --text-4xl: 2.25rem;
367
+ --section-gap: var(--s6);
368
+ --measure: 780px;
369
+ }
370
+
334
371
  /* ── Marketing tier ─────────────────────────────────────────────────────
335
372
  `class="tier-marketing"` on <html> (brignano.io). Unlocks the display
336
373
  face and opens the type scale. COLOUR IS IDENTICAL ACROSS TIERS — that
@@ -349,20 +386,6 @@
349
386
  --measure: 68ch;
350
387
  }
351
388
 
352
- :root {
353
- /* Tool-tier scale — compact, because scanning beats reading. */
354
- --text-xs: 0.6875rem;
355
- --text-sm: 0.8125rem;
356
- --text-base: 0.9375rem;
357
- --text-lg: 1.0625rem;
358
- --text-xl: 1.25rem;
359
- --text-2xl: 1.5rem;
360
- --text-3xl: 1.875rem;
361
- --text-4xl: 2.25rem;
362
- --section-gap: var(--s6);
363
- --measure: 780px;
364
- }
365
-
366
389
  ::selection {
367
390
  background: var(--i-selection);
368
391
  }