@misoto22/design 0.8.0 → 0.10.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/dist/agent/Accordion.md +1 -1
- package/dist/agent/Alert.md +1 -1
- package/dist/agent/AppShell.md +1 -1
- package/dist/agent/ArchitectureFigure.md +1 -1
- package/dist/agent/AreaChart.md +1 -1
- package/dist/agent/Article.md +1 -1
- package/dist/agent/AspectRatio.md +1 -1
- package/dist/agent/Avatar.md +1 -1
- package/dist/agent/Badge.md +1 -1
- package/dist/agent/BarChart.md +1 -1
- package/dist/agent/BarList.md +1 -1
- package/dist/agent/BigNumber.md +1 -1
- package/dist/agent/BoxPlot.md +1 -1
- package/dist/agent/Breadcrumb.md +1 -1
- package/dist/agent/BulletChart.md +1 -1
- package/dist/agent/Button.md +1 -1
- package/dist/agent/Calendar.md +1 -1
- package/dist/agent/Card.md +1 -1
- package/dist/agent/Checkbox.md +1 -1
- package/dist/agent/Code.md +1 -1
- package/dist/agent/CodeBlock.md +1 -1
- package/dist/agent/Collapsible.md +1 -1
- package/dist/agent/ColorPicker.md +75 -0
- package/dist/agent/Combobox.md +1 -1
- package/dist/agent/Command.md +1 -1
- package/dist/agent/ComposedChart.md +1 -1
- package/dist/agent/ContextMenu.md +1 -1
- package/dist/agent/DataflowFigure.md +1 -1
- package/dist/agent/DatePicker.md +1 -1
- package/dist/agent/DescriptionList.md +1 -1
- package/dist/agent/Diagram.md +1 -1
- package/dist/agent/DiagramCanvas.md +1 -1
- package/dist/agent/DiagramExportMenu.md +1 -1
- package/dist/agent/DiagramInspector.md +1 -1
- package/dist/agent/DiagramLegend.md +1 -1
- package/dist/agent/DiagramMinimap.md +1 -1
- package/dist/agent/DiagramToolbar.md +1 -1
- package/dist/agent/Dialog.md +1 -1
- package/dist/agent/DropdownMenu.md +1 -1
- package/dist/agent/EmptyState.md +1 -1
- package/dist/agent/ErrorState.md +1 -1
- package/dist/agent/Facet.md +1 -1
- package/dist/agent/Field.md +1 -1
- package/dist/agent/FigureBand.md +1 -1
- package/dist/agent/FloatingIconButton.md +1 -1
- package/dist/agent/FunnelChart.md +1 -1
- package/dist/agent/Heading.md +1 -1
- package/dist/agent/Heatmap.md +1 -1
- package/dist/agent/Histogram.md +1 -1
- package/dist/agent/Input.md +1 -1
- package/dist/agent/Kbd.md +2 -2
- package/dist/agent/LifecycleFigure.md +1 -1
- package/dist/agent/LineChart.md +1 -1
- package/dist/agent/LinkArrow.md +1 -1
- package/dist/agent/Markdown.md +1 -1
- package/dist/agent/NativeSelect.md +1 -1
- package/dist/agent/NavItem.md +1 -1
- package/dist/agent/NumberField.md +72 -0
- package/dist/agent/Pagination.md +1 -1
- package/dist/agent/PieChart.md +1 -1
- package/dist/agent/Popover.md +1 -1
- package/dist/agent/Progress.md +1 -1
- package/dist/agent/RadarChart.md +1 -1
- package/dist/agent/RadialChart.md +1 -1
- package/dist/agent/RadioGroup.md +1 -1
- package/dist/agent/SankeyChart.md +1 -1
- package/dist/agent/ScatterChart.md +1 -1
- package/dist/agent/ScrollArea.md +1 -1
- package/dist/agent/SearchableMenu.md +1 -1
- package/dist/agent/Select.md +1 -1
- package/dist/agent/Separator.md +1 -1
- package/dist/agent/SequenceFigure.md +1 -1
- package/dist/agent/Sheet.md +1 -1
- package/dist/agent/Sidebar.md +193 -0
- package/dist/agent/Skeleton.md +1 -1
- package/dist/agent/Slider.md +7 -3
- package/dist/agent/Sparkline.md +1 -1
- package/dist/agent/Spinner.md +1 -1
- package/dist/agent/StatusDot.md +1 -1
- package/dist/agent/StatusPill.md +1 -1
- package/dist/agent/Steps.md +1 -1
- package/dist/agent/Switch.md +1 -1
- package/dist/agent/Table.md +3 -1
- package/dist/agent/Tabs.md +1 -1
- package/dist/agent/Tag.md +1 -1
- package/dist/agent/Text.md +1 -1
- package/dist/agent/Textarea.md +1 -1
- package/dist/agent/Timestamp.md +1 -1
- package/dist/agent/Toast.md +1 -1
- package/dist/agent/ToggleGroup.md +1 -1
- package/dist/agent/Toolbar.md +1 -1
- package/dist/agent/Tooltip.md +1 -1
- package/dist/agent/TreemapChart.md +1 -1
- package/dist/agent/WaterfallChart.md +1 -1
- package/dist/agent/WorkflowFigure.md +1 -1
- package/dist/agent/catalog.json +362 -2
- package/dist/agent/index.md +9 -6
- package/dist/charts/BulletChart/BulletChart.js +16 -2
- package/dist/charts/BulletChart/BulletChart.js.map +1 -1
- package/dist/charts/RadarChart/RadarChart.js +4 -2
- package/dist/charts/RadarChart/RadarChart.js.map +1 -1
- package/dist/charts/lib/chart.js +16 -1
- package/dist/charts/lib/chart.js.map +1 -1
- package/dist/components/AppShell/AppShell.js +2 -2
- package/dist/components/AppShell/AppShell.js.map +1 -1
- package/dist/components/Button/Button.js +3 -3
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/ColorPicker/ColorPicker.d.ts +67 -0
- package/dist/components/ColorPicker/ColorPicker.js +334 -0
- package/dist/components/ColorPicker/ColorPicker.js.map +1 -0
- package/dist/components/Command/Command.js +1 -1
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js +1 -1
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/components/Dialog/Dialog.js +1 -1
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/ErrorState/ErrorState.js +1 -1
- package/dist/components/ErrorState/ErrorState.js.map +1 -1
- package/dist/components/Kbd/Kbd.d.ts +7 -0
- package/dist/components/Kbd/Kbd.js +1 -1
- package/dist/components/Kbd/Kbd.js.map +1 -1
- package/dist/components/NavItem/NavItem.js +1 -1
- package/dist/components/NavItem/NavItem.js.map +1 -1
- package/dist/components/NumberField/NumberField.d.ts +69 -0
- package/dist/components/NumberField/NumberField.js +162 -0
- package/dist/components/NumberField/NumberField.js.map +1 -0
- package/dist/components/Popover/Popover.js +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Select/Select.js +1 -1
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Sheet/Sheet.js +1 -1
- package/dist/components/Sheet/Sheet.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.d.ts +357 -0
- package/dist/components/Sidebar/Sidebar.js +455 -0
- package/dist/components/Sidebar/Sidebar.js.map +1 -0
- package/dist/components/Slider/Slider.d.ts +22 -1
- package/dist/components/Slider/Slider.js +72 -8
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Table/Table.d.ts +14 -0
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Tabs/Tabs.js +7 -1
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/diagrams/lib/route.d.ts +22 -1
- package/dist/diagrams/lib/route.js +24 -1
- package/dist/diagrams/lib/route.js.map +1 -1
- package/dist/diagrams/lib/wires.js +9 -5
- package/dist/diagrams/lib/wires.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/color.d.ts +80 -0
- package/dist/lib/color.js +189 -0
- package/dist/lib/color.js.map +1 -0
- package/dist/lib/numeric.d.ts +35 -0
- package/dist/lib/numeric.js +29 -0
- package/dist/lib/numeric.js.map +1 -0
- package/dist/semantic.css +4 -2
- package/dist/styles.css +1 -1
- package/dist/themes.css +99 -0
- package/dist/tokens.css +133 -4
- package/dist/tokens.d.ts +5 -0
- package/dist/tokens.js +31 -3
- package/dist/tokens.json +31 -3
- package/package.json +1 -1
- package/skills/misoto22-design/rules/forms.md +3 -1
package/dist/tokens.css
CHANGED
|
@@ -19,8 +19,22 @@
|
|
|
19
19
|
holds the two in sync.
|
|
20
20
|
========================================================================== */
|
|
21
21
|
|
|
22
|
+
/* `[data-surface='paper']` is the surface axis's own default, WRITTEN. Every
|
|
23
|
+
other axis value has a name; this one was "leave the attribute off", which
|
|
24
|
+
works exactly once — at the root. A subtree cannot say "the White Reset"
|
|
25
|
+
inside a page whose root is warm, so five theme specimens on one page each
|
|
26
|
+
inherited whichever surface the reader had applied to the site and every one
|
|
27
|
+
of them showed the same colours. Naming the default is what lets a subtree
|
|
28
|
+
opt out of an ancestor's theme rather than only into a different one.
|
|
29
|
+
|
|
30
|
+
It sits on the ROOT's own rule rather than restating the values, so there is
|
|
31
|
+
nothing here to drift. Specificity ties with `[data-surface='warm']` in
|
|
32
|
+
themes.css and loses on source order, which is correct: a wrapper that says
|
|
33
|
+
`warm` does not match this selector at all. */
|
|
22
34
|
:root,
|
|
23
|
-
[data-mode='light']
|
|
35
|
+
[data-mode='light'],
|
|
36
|
+
[data-surface='paper'],
|
|
37
|
+
[data-rules='hairline'] {
|
|
24
38
|
--paper: #ffffff;
|
|
25
39
|
--paper-2: #f7f7f5;
|
|
26
40
|
--bar: var(--stone);
|
|
@@ -101,7 +115,9 @@
|
|
|
101
115
|
|
|
102
116
|
A consumer who genuinely needs hue does not hand-pick hexes: it sets
|
|
103
117
|
`data-chart-palette="chroma"` (see themes.css), which re-points these
|
|
104
|
-
eight names onto a categorical palette validated against both grounds
|
|
118
|
+
eight names onto a categorical palette validated against both grounds —
|
|
119
|
+
or `"accent"`, which ladders the same eight names out of `--clay` when
|
|
120
|
+
what the charts have to carry is a brand rather than eight categories. */
|
|
105
121
|
--series-1: #101010;
|
|
106
122
|
--series-2: #565656;
|
|
107
123
|
--series-3: #202020;
|
|
@@ -132,7 +148,20 @@
|
|
|
132
148
|
color-scheme: light;
|
|
133
149
|
}
|
|
134
150
|
|
|
135
|
-
|
|
151
|
+
/* The dark half of the same reset. Without it, `paper` inside a dark page
|
|
152
|
+
would match the light rule above and light up one specimen in the middle of
|
|
153
|
+
a dark gallery. */
|
|
154
|
+
[data-mode='dark'],
|
|
155
|
+
/* BOTH forms, the way every dark rule in `themes.css` is written. The compound
|
|
156
|
+
is not the same selector as the descendant, and the compound is the one that
|
|
157
|
+
matters most: an app puts `data-mode` and its theme axes on the SAME element
|
|
158
|
+
— `<html data-mode="dark" data-surface="paper">` — where a descendant
|
|
159
|
+
selector matches nothing. Written descendant-only, every dark page took the
|
|
160
|
+
light rule above and painted light ink on a dark ground. */
|
|
161
|
+
[data-mode='dark'][data-surface='paper'],
|
|
162
|
+
[data-mode='dark'] [data-surface='paper'],
|
|
163
|
+
[data-mode='dark'][data-rules='hairline'],
|
|
164
|
+
[data-mode='dark'] [data-rules='hairline'] {
|
|
136
165
|
--paper: #0d0d0d;
|
|
137
166
|
--paper-2: #161616;
|
|
138
167
|
--bar: var(--stone);
|
|
@@ -322,7 +351,15 @@
|
|
|
322
351
|
--radius-frame: calc(var(--radius-lg) + 1rem * var(--radius-gate)); /* a frame 16px outside a panel */
|
|
323
352
|
}
|
|
324
353
|
|
|
325
|
-
|
|
354
|
+
/* The density axis's own default, named — and on a rule that holds NOTHING
|
|
355
|
+
but density. It was on the block above, which also carries the status
|
|
356
|
+
colours, the floating surfaces and the motion steps: every element that
|
|
357
|
+
said `data-density="comfortable"` therefore re-declared the whole LIGHT
|
|
358
|
+
palette on itself, and in dark mode every example canvas on the site
|
|
359
|
+
painted a light --danger on a dark ground. A neutral value may only
|
|
360
|
+
restate the axis it belongs to. */
|
|
361
|
+
:root,
|
|
362
|
+
[data-density='comfortable'] {
|
|
326
363
|
/* ─── Density ────────────────────────────────────────────────────────────
|
|
327
364
|
The second theming axis, and the only other one. Light/dark swaps colour;
|
|
328
365
|
density swaps the size of anything a finger or a pointer has to hit.
|
|
@@ -350,6 +387,21 @@
|
|
|
350
387
|
--control-py-sm: 0.5rem;
|
|
351
388
|
--control-py-md: 0.75rem;
|
|
352
389
|
--control-py-lg: 0.75rem;
|
|
390
|
+
/* And so is the LEADING, which is the term that guard was missing.
|
|
391
|
+
`min-height` is a floor, and what has to stay under it is the whole box:
|
|
392
|
+
the line, the padding and the border. The padding was scaled and the line
|
|
393
|
+
was left inheriting the body's 1.6 — so `sm` measured 20.8 + 16 + 2 = 38.8
|
|
394
|
+
against a 36px token, `md` 46 against 44 and `lg` 50 against 48. Every
|
|
395
|
+
text button in the system was two to three pixels taller than the number
|
|
396
|
+
documenting it, and the floor never bound because the box had already
|
|
397
|
+
cleared it.
|
|
398
|
+
|
|
399
|
+
One value on both densities: the font sizes do not move with density, only
|
|
400
|
+
the padding and the heights do, so this does not have to. It is not a
|
|
401
|
+
reading leading — a control's label is one line, and 1.2 leaves every size
|
|
402
|
+
at every density inside its own height with room to spare. The test in
|
|
403
|
+
`tokens.test.ts` is what keeps that true. */
|
|
404
|
+
--control-lh: 1.2;
|
|
353
405
|
--control-gap: 0.625rem;
|
|
354
406
|
/* Text inputs are measured separately: they are read as much as they are
|
|
355
407
|
hit, so their padding tracks the type rather than the target. */
|
|
@@ -364,6 +416,55 @@
|
|
|
364
416
|
zero makes `calc(0 + 1.5rem)` invalid at computed-value time — the whole
|
|
365
417
|
declaration is dropped and every column loses its gutter in silence. */
|
|
366
418
|
--table-pad-x: 0px;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
:root {
|
|
422
|
+
|
|
423
|
+
/* ─── Sidebar ────────────────────────────────────────────────────────────
|
|
424
|
+
The two widths a navigation rail has, and the reason they are tokens
|
|
425
|
+
rather than numbers inside the component: an application shell has to
|
|
426
|
+
reserve exactly this much beside its content, and a shell that hard-codes
|
|
427
|
+
17rem while the rail believes something else is a gap or an overlap that
|
|
428
|
+
appears only at one window size. Both sides read the same name.
|
|
429
|
+
|
|
430
|
+
`--sidebar-w-icon` is what is left when the rail collapses to icons. It is
|
|
431
|
+
`--control-h-md` plus the rail's own padding, so a 44px pointer target
|
|
432
|
+
still fits inside it at comfortable density — a collapsed rail whose rows
|
|
433
|
+
are too small to hit is a rail nobody can use in the state it spends most
|
|
434
|
+
of its life in. */
|
|
435
|
+
--sidebar-w: 16rem;
|
|
436
|
+
--sidebar-w-icon: 3.5rem;
|
|
437
|
+
|
|
438
|
+
/* ─── Bar ────────────────────────────────────────────────────────────────
|
|
439
|
+
How tall the band across the top of an application is — the masthead, and
|
|
440
|
+
the head of the rail beside it, which has to line up with it or the two
|
|
441
|
+
rules meeting at the corner are two different rules.
|
|
442
|
+
|
|
443
|
+
Derived, not typed. A bar is a row of controls and the air around them, so
|
|
444
|
+
it is the control it seats plus six pixels above and below — the same
|
|
445
|
+
twelve `--sidebar-w-icon` adds to a rail's collapsed width, for the same
|
|
446
|
+
reason.
|
|
447
|
+
|
|
448
|
+
WHICH control depends on the pointer, and that is the whole of the second
|
|
449
|
+
block. A bar is chrome: its controls are `sm`, the density this system
|
|
450
|
+
documents as a deliberate below-the-floor size for a mouse. A finger is
|
|
451
|
+
not a mouse, so on a coarse pointer they grow to the 44px target WCAG
|
|
452
|
+
2.5.5 asks for, and the bar has to grow with them or it clips what it
|
|
453
|
+
seats. Sizing it from `--control-h-md` on both is what made it too tall:
|
|
454
|
+
56px of bar around 39px of search field, holding room for a target that is
|
|
455
|
+
not on screen when a mouse is.
|
|
456
|
+
|
|
457
|
+
48px comfortable / 42px compact with a pointer, 56px / 48px with a finger.
|
|
458
|
+
A bar cannot be set to a height its own controls do not fit in.
|
|
459
|
+
|
|
460
|
+
It was five literals before, in two packages, and they did not agree:
|
|
461
|
+
`AppShell` said `h-14` and the documentation site said `h-16`, so the same
|
|
462
|
+
role was 56px in the component this system ships and 64px on the site
|
|
463
|
+
documenting it. `--scroll-offset` in `semantic.css` is a sixth, and the
|
|
464
|
+
one that shows why this matters — it is "a masthead plus a line of air"
|
|
465
|
+
and was written as `88px`, a number derived by hand from whichever of the
|
|
466
|
+
two answers its author had on screen. It now derives from this. */
|
|
467
|
+
--bar-h: calc(var(--control-h-sm) + 0.75rem);
|
|
367
468
|
|
|
368
469
|
/* ─── Floating surfaces ──────────────────────────────────────────────────
|
|
369
470
|
What a panel that FLOATS fills with, and what it does to whatever is
|
|
@@ -385,6 +486,16 @@
|
|
|
385
486
|
--panel-border: var(--rule-2);
|
|
386
487
|
--panel-filter: none;
|
|
387
488
|
|
|
489
|
+
/* The offset under a floating panel, and it does not break Law 2: the law
|
|
490
|
+
says a box-shadow is never BLURRED, not that there is never one. This is
|
|
491
|
+
the same hard-offset idiom as `--lift`, in the rule colour rather than the
|
|
492
|
+
accent — every menu in the system wearing a clay drop shadow would be a
|
|
493
|
+
louder claim than "this sits above the page".
|
|
494
|
+
Two steps, because one reads as a second border: a firm edge just below the
|
|
495
|
+
panel and a softer one below that is a stack seen from the front, which is
|
|
496
|
+
the flattest way to say depth without drawing light. */
|
|
497
|
+
--panel-lift: 0 2px 0 0 var(--rule-2), 0 5px 0 -1px var(--rule);
|
|
498
|
+
|
|
388
499
|
/* ─── Motion ─── */
|
|
389
500
|
--ease: cubic-bezier(0.2, 0.7, 0.3, 1);
|
|
390
501
|
--fast: 0.13s;
|
|
@@ -449,6 +560,24 @@
|
|
|
449
560
|
--scrim: color-mix(in srgb, #000 72%, transparent);
|
|
450
561
|
}
|
|
451
562
|
|
|
563
|
+
/* The bar, on a finger.
|
|
564
|
+
*
|
|
565
|
+
* A bar's controls are `sm` — the size this system documents as a deliberate
|
|
566
|
+
* below-the-floor density for a mouse — and a coarse pointer grows them to the
|
|
567
|
+
* 44px target WCAG 2.5.5 asks for. The bar grows with them, or it clips what it
|
|
568
|
+
* seats. Declared on the ROOT like the base value, so the substitution argument
|
|
569
|
+
* above still holds: one answer, resolved once, inherited by a rail that pins
|
|
570
|
+
* its own density.
|
|
571
|
+
*/
|
|
572
|
+
@media (pointer: coarse) {
|
|
573
|
+
:root,
|
|
574
|
+
[data-mode='light'],
|
|
575
|
+
[data-surface='paper'],
|
|
576
|
+
[data-rules='hairline'] {
|
|
577
|
+
--bar-h: calc(var(--control-h-md) + 0.75rem);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
452
581
|
[data-density='compact'] {
|
|
453
582
|
--control-h-sm: 1.875rem; /* 30px */
|
|
454
583
|
--control-h-md: 2.25rem; /* 36px — clears WCAG 2.5.8, not 2.5.5 */
|
package/dist/tokens.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type TokenName =
|
|
|
23
23
|
| 'background-elevated'
|
|
24
24
|
| 'bar'
|
|
25
25
|
| 'bar-2'
|
|
26
|
+
| 'bar-h'
|
|
26
27
|
| 'border-color'
|
|
27
28
|
| 'border-subtle'
|
|
28
29
|
| 'brand-plate'
|
|
@@ -45,6 +46,7 @@ export type TokenName =
|
|
|
45
46
|
| 'control-h-lg'
|
|
46
47
|
| 'control-h-md'
|
|
47
48
|
| 'control-h-sm'
|
|
49
|
+
| 'control-lh'
|
|
48
50
|
| 'control-px-lg'
|
|
49
51
|
| 'control-px-md'
|
|
50
52
|
| 'control-px-sm'
|
|
@@ -125,6 +127,7 @@ export type TokenName =
|
|
|
125
127
|
| 'panel-bg'
|
|
126
128
|
| 'panel-border'
|
|
127
129
|
| 'panel-filter'
|
|
130
|
+
| 'panel-lift'
|
|
128
131
|
| 'paper'
|
|
129
132
|
| 'paper-2'
|
|
130
133
|
| 'photo-caption-surface'
|
|
@@ -169,6 +172,8 @@ export type TokenName =
|
|
|
169
172
|
| 'shadow-lg'
|
|
170
173
|
| 'shadow-offset'
|
|
171
174
|
| 'shadow-sm'
|
|
175
|
+
| 'sidebar-w'
|
|
176
|
+
| 'sidebar-w-icon'
|
|
172
177
|
| 'slow'
|
|
173
178
|
| 'stone'
|
|
174
179
|
| 'success'
|
package/dist/tokens.js
CHANGED
|
@@ -172,7 +172,7 @@ export const TOKENS = {
|
|
|
172
172
|
"layer": "tokens",
|
|
173
173
|
"category": "data",
|
|
174
174
|
"light": "#101010",
|
|
175
|
-
"comment": "─── Data ─────────────────────────────────────────────────────────────── The series ramp a chart paints with, and the one place the White Reset has to answer a question a monochrome system would rather not be asked: how do you tell six lines apart with no hue left to spend? The answer is that hue was never the primary carrier here — TEXTURE is. Every chart primitive ships a fill variant (hatched, dotted, lines, stripped, duotone) and the series ramp below is the SECOND encoding, not the first. That ordering is what makes the set legible to a colour-blind reader, in greyscale print, and under forced-colours, none of which a hue-first categorical palette survives. The eight steps are interleaved rather than sequential — light, dark, light, dark — so neighbouring series sit as far apart on the lightness ramp as eight steps allow. Adjacent separation is ΔE 21.0 (OKLab ×100) against a 15 floor, and every step clears 3:1 on its own ground. Two checks a chromatic palette would pass fail here BY DESIGN, and are stated rather than hidden: the chroma floor (these are greys) and the lightness band (--series-1 is ink, and ink is the darkest mark the system has). Texture plus a legend is the relief, and both are mandatory — `Chart.Legend` is not optional above one series. A consumer who genuinely needs hue does not hand-pick hexes: it sets `data-chart-palette=\"chroma\"` (see themes.css), which re-points these eight names onto a categorical palette validated against both grounds.",
|
|
175
|
+
"comment": "─── Data ─────────────────────────────────────────────────────────────── The series ramp a chart paints with, and the one place the White Reset has to answer a question a monochrome system would rather not be asked: how do you tell six lines apart with no hue left to spend? The answer is that hue was never the primary carrier here — TEXTURE is. Every chart primitive ships a fill variant (hatched, dotted, lines, stripped, duotone) and the series ramp below is the SECOND encoding, not the first. That ordering is what makes the set legible to a colour-blind reader, in greyscale print, and under forced-colours, none of which a hue-first categorical palette survives. The eight steps are interleaved rather than sequential — light, dark, light, dark — so neighbouring series sit as far apart on the lightness ramp as eight steps allow. Adjacent separation is ΔE 21.0 (OKLab ×100) against a 15 floor, and every step clears 3:1 on its own ground. Two checks a chromatic palette would pass fail here BY DESIGN, and are stated rather than hidden: the chroma floor (these are greys) and the lightness band (--series-1 is ink, and ink is the darkest mark the system has). Texture plus a legend is the relief, and both are mandatory — `Chart.Legend` is not optional above one series. A consumer who genuinely needs hue does not hand-pick hexes: it sets `data-chart-palette=\"chroma\"` (see themes.css), which re-points these eight names onto a categorical palette validated against both grounds — or `\"accent\"`, which ladders the same eight names out of `--clay` when what the charts have to carry is a brand rather than eight categories.",
|
|
176
176
|
"dark": "CanvasText"
|
|
177
177
|
},
|
|
178
178
|
"series-2": {
|
|
@@ -441,6 +441,12 @@ export const TOKENS = {
|
|
|
441
441
|
"category": "density",
|
|
442
442
|
"light": "0.75rem"
|
|
443
443
|
},
|
|
444
|
+
"control-lh": {
|
|
445
|
+
"layer": "tokens",
|
|
446
|
+
"category": "density",
|
|
447
|
+
"light": "1.2",
|
|
448
|
+
"comment": "And so is the LEADING, which is the term that guard was missing. `min-height` is a floor, and what has to stay under it is the whole box: the line, the padding and the border. The padding was scaled and the line was left inheriting the body's 1.6 — so `sm` measured 20.8 + 16 + 2 = 38.8 against a 36px token, `md` 46 against 44 and `lg` 50 against 48. Every text button in the system was two to three pixels taller than the number documenting it, and the floor never bound because the box had already cleared it. One value on both densities: the font sizes do not move with density, only the padding and the heights do, so this does not have to. It is not a reading leading — a control's label is one line, and 1.2 leaves every size at every density inside its own height with room to spare. The test in `tokens.test.ts` is what keeps that true."
|
|
449
|
+
},
|
|
444
450
|
"control-gap": {
|
|
445
451
|
"layer": "tokens",
|
|
446
452
|
"category": "density",
|
|
@@ -469,6 +475,22 @@ export const TOKENS = {
|
|
|
469
475
|
"light": "0px",
|
|
470
476
|
"comment": "`0px`, not `0`. The cell rule adds to this inside a calc, and a unitless zero makes `calc(0 + 1.5rem)` invalid at computed-value time — the whole declaration is dropped and every column loses its gutter in silence."
|
|
471
477
|
},
|
|
478
|
+
"sidebar-w": {
|
|
479
|
+
"layer": "tokens",
|
|
480
|
+
"category": "other",
|
|
481
|
+
"light": "16rem",
|
|
482
|
+
"comment": "─── Sidebar ──────────────────────────────────────────────────────────── The two widths a navigation rail has, and the reason they are tokens rather than numbers inside the component: an application shell has to reserve exactly this much beside its content, and a shell that hard-codes 17rem while the rail believes something else is a gap or an overlap that appears only at one window size. Both sides read the same name. `--sidebar-w-icon` is what is left when the rail collapses to icons. It is `--control-h-md` plus the rail's own padding, so a 44px pointer target still fits inside it at comfortable density — a collapsed rail whose rows are too small to hit is a rail nobody can use in the state it spends most of its life in."
|
|
483
|
+
},
|
|
484
|
+
"sidebar-w-icon": {
|
|
485
|
+
"layer": "tokens",
|
|
486
|
+
"category": "other",
|
|
487
|
+
"light": "3.5rem"
|
|
488
|
+
},
|
|
489
|
+
"bar-h": {
|
|
490
|
+
"layer": "tokens",
|
|
491
|
+
"category": "space",
|
|
492
|
+
"light": "calc(var(--control-h-md) + 0.75rem)"
|
|
493
|
+
},
|
|
472
494
|
"panel-bg": {
|
|
473
495
|
"layer": "tokens",
|
|
474
496
|
"category": "other",
|
|
@@ -485,6 +507,12 @@ export const TOKENS = {
|
|
|
485
507
|
"category": "other",
|
|
486
508
|
"light": "none"
|
|
487
509
|
},
|
|
510
|
+
"panel-lift": {
|
|
511
|
+
"layer": "tokens",
|
|
512
|
+
"category": "other",
|
|
513
|
+
"light": "0 2px 0 0 var(--rule-2), 0 5px 0 -1px var(--rule)",
|
|
514
|
+
"comment": "The offset under a floating panel, and it does not break Law 2: the law says a box-shadow is never BLURRED, not that there is never one. This is the same hard-offset idiom as `--lift`, in the rule colour rather than the accent — every menu in the system wearing a clay drop shadow would be a louder claim than \"this sits above the page\". Two steps, because one reads as a second border: a firm edge just below the panel and a softer one below that is a stack seen from the front, which is the flattest way to say depth without drawing light."
|
|
515
|
+
},
|
|
488
516
|
"ease": {
|
|
489
517
|
"layer": "tokens",
|
|
490
518
|
"category": "motion",
|
|
@@ -991,7 +1019,7 @@ export const TOKENS = {
|
|
|
991
1019
|
"scroll-offset": {
|
|
992
1020
|
"layer": "semantic",
|
|
993
1021
|
"category": "space",
|
|
994
|
-
"light": "
|
|
995
|
-
"comment": "How far below the viewport top an anchored heading comes to rest — a fixed masthead plus a line of air."
|
|
1022
|
+
"light": "calc(var(--bar-h) + 1.5rem)",
|
|
1023
|
+
"comment": "How far below the viewport top an anchored heading comes to rest — a fixed masthead plus a line of air. Both halves are now named: the masthead is `--bar-h`, so a bar that moves takes its anchors with it, where `88px` was a number somebody derived once by hand and nothing kept in step."
|
|
996
1024
|
}
|
|
997
1025
|
}
|
package/dist/tokens.json
CHANGED
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
"layer": "tokens",
|
|
172
172
|
"category": "data",
|
|
173
173
|
"light": "#101010",
|
|
174
|
-
"comment": "─── Data ─────────────────────────────────────────────────────────────── The series ramp a chart paints with, and the one place the White Reset has to answer a question a monochrome system would rather not be asked: how do you tell six lines apart with no hue left to spend? The answer is that hue was never the primary carrier here — TEXTURE is. Every chart primitive ships a fill variant (hatched, dotted, lines, stripped, duotone) and the series ramp below is the SECOND encoding, not the first. That ordering is what makes the set legible to a colour-blind reader, in greyscale print, and under forced-colours, none of which a hue-first categorical palette survives. The eight steps are interleaved rather than sequential — light, dark, light, dark — so neighbouring series sit as far apart on the lightness ramp as eight steps allow. Adjacent separation is ΔE 21.0 (OKLab ×100) against a 15 floor, and every step clears 3:1 on its own ground. Two checks a chromatic palette would pass fail here BY DESIGN, and are stated rather than hidden: the chroma floor (these are greys) and the lightness band (--series-1 is ink, and ink is the darkest mark the system has). Texture plus a legend is the relief, and both are mandatory — `Chart.Legend` is not optional above one series. A consumer who genuinely needs hue does not hand-pick hexes: it sets `data-chart-palette=\"chroma\"` (see themes.css), which re-points these eight names onto a categorical palette validated against both grounds.",
|
|
174
|
+
"comment": "─── Data ─────────────────────────────────────────────────────────────── The series ramp a chart paints with, and the one place the White Reset has to answer a question a monochrome system would rather not be asked: how do you tell six lines apart with no hue left to spend? The answer is that hue was never the primary carrier here — TEXTURE is. Every chart primitive ships a fill variant (hatched, dotted, lines, stripped, duotone) and the series ramp below is the SECOND encoding, not the first. That ordering is what makes the set legible to a colour-blind reader, in greyscale print, and under forced-colours, none of which a hue-first categorical palette survives. The eight steps are interleaved rather than sequential — light, dark, light, dark — so neighbouring series sit as far apart on the lightness ramp as eight steps allow. Adjacent separation is ΔE 21.0 (OKLab ×100) against a 15 floor, and every step clears 3:1 on its own ground. Two checks a chromatic palette would pass fail here BY DESIGN, and are stated rather than hidden: the chroma floor (these are greys) and the lightness band (--series-1 is ink, and ink is the darkest mark the system has). Texture plus a legend is the relief, and both are mandatory — `Chart.Legend` is not optional above one series. A consumer who genuinely needs hue does not hand-pick hexes: it sets `data-chart-palette=\"chroma\"` (see themes.css), which re-points these eight names onto a categorical palette validated against both grounds — or `\"accent\"`, which ladders the same eight names out of `--clay` when what the charts have to carry is a brand rather than eight categories.",
|
|
175
175
|
"dark": "CanvasText"
|
|
176
176
|
},
|
|
177
177
|
"series-2": {
|
|
@@ -440,6 +440,12 @@
|
|
|
440
440
|
"category": "density",
|
|
441
441
|
"light": "0.75rem"
|
|
442
442
|
},
|
|
443
|
+
"control-lh": {
|
|
444
|
+
"layer": "tokens",
|
|
445
|
+
"category": "density",
|
|
446
|
+
"light": "1.2",
|
|
447
|
+
"comment": "And so is the LEADING, which is the term that guard was missing. `min-height` is a floor, and what has to stay under it is the whole box: the line, the padding and the border. The padding was scaled and the line was left inheriting the body's 1.6 — so `sm` measured 20.8 + 16 + 2 = 38.8 against a 36px token, `md` 46 against 44 and `lg` 50 against 48. Every text button in the system was two to three pixels taller than the number documenting it, and the floor never bound because the box had already cleared it. One value on both densities: the font sizes do not move with density, only the padding and the heights do, so this does not have to. It is not a reading leading — a control's label is one line, and 1.2 leaves every size at every density inside its own height with room to spare. The test in `tokens.test.ts` is what keeps that true."
|
|
448
|
+
},
|
|
443
449
|
"control-gap": {
|
|
444
450
|
"layer": "tokens",
|
|
445
451
|
"category": "density",
|
|
@@ -468,6 +474,22 @@
|
|
|
468
474
|
"light": "0px",
|
|
469
475
|
"comment": "`0px`, not `0`. The cell rule adds to this inside a calc, and a unitless zero makes `calc(0 + 1.5rem)` invalid at computed-value time — the whole declaration is dropped and every column loses its gutter in silence."
|
|
470
476
|
},
|
|
477
|
+
"sidebar-w": {
|
|
478
|
+
"layer": "tokens",
|
|
479
|
+
"category": "other",
|
|
480
|
+
"light": "16rem",
|
|
481
|
+
"comment": "─── Sidebar ──────────────────────────────────────────────────────────── The two widths a navigation rail has, and the reason they are tokens rather than numbers inside the component: an application shell has to reserve exactly this much beside its content, and a shell that hard-codes 17rem while the rail believes something else is a gap or an overlap that appears only at one window size. Both sides read the same name. `--sidebar-w-icon` is what is left when the rail collapses to icons. It is `--control-h-md` plus the rail's own padding, so a 44px pointer target still fits inside it at comfortable density — a collapsed rail whose rows are too small to hit is a rail nobody can use in the state it spends most of its life in."
|
|
482
|
+
},
|
|
483
|
+
"sidebar-w-icon": {
|
|
484
|
+
"layer": "tokens",
|
|
485
|
+
"category": "other",
|
|
486
|
+
"light": "3.5rem"
|
|
487
|
+
},
|
|
488
|
+
"bar-h": {
|
|
489
|
+
"layer": "tokens",
|
|
490
|
+
"category": "space",
|
|
491
|
+
"light": "calc(var(--control-h-md) + 0.75rem)"
|
|
492
|
+
},
|
|
471
493
|
"panel-bg": {
|
|
472
494
|
"layer": "tokens",
|
|
473
495
|
"category": "other",
|
|
@@ -484,6 +506,12 @@
|
|
|
484
506
|
"category": "other",
|
|
485
507
|
"light": "none"
|
|
486
508
|
},
|
|
509
|
+
"panel-lift": {
|
|
510
|
+
"layer": "tokens",
|
|
511
|
+
"category": "other",
|
|
512
|
+
"light": "0 2px 0 0 var(--rule-2), 0 5px 0 -1px var(--rule)",
|
|
513
|
+
"comment": "The offset under a floating panel, and it does not break Law 2: the law says a box-shadow is never BLURRED, not that there is never one. This is the same hard-offset idiom as `--lift`, in the rule colour rather than the accent — every menu in the system wearing a clay drop shadow would be a louder claim than \"this sits above the page\". Two steps, because one reads as a second border: a firm edge just below the panel and a softer one below that is a stack seen from the front, which is the flattest way to say depth without drawing light."
|
|
514
|
+
},
|
|
487
515
|
"ease": {
|
|
488
516
|
"layer": "tokens",
|
|
489
517
|
"category": "motion",
|
|
@@ -990,7 +1018,7 @@
|
|
|
990
1018
|
"scroll-offset": {
|
|
991
1019
|
"layer": "semantic",
|
|
992
1020
|
"category": "space",
|
|
993
|
-
"light": "
|
|
994
|
-
"comment": "How far below the viewport top an anchored heading comes to rest — a fixed masthead plus a line of air."
|
|
1021
|
+
"light": "calc(var(--bar-h) + 1.5rem)",
|
|
1022
|
+
"comment": "How far below the viewport top an anchored heading comes to rest — a fixed masthead plus a line of air. Both halves are now named: the masthead is `--bar-h`, so a bar that moves takes its anchors with it, where `88px` was a number somebody derived once by hand and nothing kept in step."
|
|
995
1023
|
}
|
|
996
1024
|
}
|
package/package.json
CHANGED
|
@@ -89,7 +89,9 @@ and nothing is wired — the label points at an id that is on nothing.
|
|
|
89
89
|
| Boolean, applied immediately | `Switch` | |
|
|
90
90
|
| One of 2–7 visible options | `RadioGroup` + `RadioGroupItem` | |
|
|
91
91
|
| One of 2–7, as a toolbar | `ToggleGroup` + `ToggleGroupItem` | |
|
|
92
|
-
| A number in a range | `Slider` | |
|
|
92
|
+
| A number in a range | `Slider` | `editable` adds a box to type the exact figure into |
|
|
93
|
+
| A number that is tuned | `NumberField` | Drag the grip to sweep; `min`/`max`/`step` are honoured on the way out |
|
|
94
|
+
| A colour | `ColorPicker` | OKLCH panel; `label` is **required** |
|
|
93
95
|
| A date | `DatePicker` / `DateRangePicker` | |
|
|
94
96
|
|
|
95
97
|
`Select` and `Combobox` take `label` even inside a `Field` — it is the
|