@tensor_1/tokens 2.31.0 → 2.32.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.
Files changed (38) hide show
  1. package/README.md +3 -1
  2. package/build/css/components.css +1 -1
  3. package/build/css/styles.css +1 -1
  4. package/build/css/tokens.css +66 -40
  5. package/build/tailwind/preset.cjs +15 -0
  6. package/build/tailwind/theme.css +15 -0
  7. package/build/ts/tokens.d.ts +1 -1
  8. package/build/ts/tokens.js +82 -40
  9. package/package.json +1 -1
  10. package/styles/components/alert.css +13 -2
  11. package/styles/components/calendar.css +28 -6
  12. package/styles/components/card.css +15 -1
  13. package/styles/components/combobox.css +26 -2
  14. package/styles/components/dashboard-grid.css +87 -0
  15. package/styles/components/date-range-picker.css +36 -4
  16. package/styles/components/file-upload.css +11 -4
  17. package/styles/components/labels.css +2 -1
  18. package/styles/components/list.css +2 -2
  19. package/styles/components/menu.css +7 -0
  20. package/styles/components/meter.css +5 -0
  21. package/styles/components/pipeline.css +2 -2
  22. package/styles/components/rule-builder.css +2 -0
  23. package/styles/components/scheduling-calendar.css +148 -22
  24. package/styles/components/segmented.css +2 -1
  25. package/styles/components/select.css +88 -1
  26. package/styles/components/sla.css +1 -1
  27. package/styles/components/spinner.css +2 -0
  28. package/styles/components/stat-tile.css +1 -1
  29. package/styles/components/status-pill.css +10 -2
  30. package/styles/components/steps.css +12 -0
  31. package/styles/components/table-toolbar.css +14 -7
  32. package/styles/components/tag-input.css +14 -5
  33. package/styles/components/text-diff.css +50 -0
  34. package/styles/components/toast.css +2 -2
  35. package/styles/components/view-menu.css +7 -2
  36. package/tokens/base/color.json +23 -8
  37. package/tokens/base/size.json +1 -0
  38. package/tokens/dark/color.json +43 -32
@@ -7,7 +7,7 @@
7
7
  }
8
8
  .uix-pill__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--tone-dot, currentColor); flex: none; }
9
9
  .uix-pill--neutral { --tone-bg: var(--uix-bg-active); --tone-fg: var(--uix-text-hushed); --tone-dot: var(--uix-text-muted); }
10
- .uix-pill--success { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success); --tone-dot: var(--uix-success); }
10
+ .uix-pill--success { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success-text); --tone-dot: var(--uix-success); }
11
11
  .uix-pill--info { --tone-bg: var(--uix-info-bg); --tone-fg: var(--uix-info-text); --tone-dot: var(--uix-info); }
12
12
  .uix-pill--warning { --tone-bg: var(--uix-warning-bg); --tone-fg: var(--uix-warning-text); --tone-dot: var(--uix-warning); }
13
13
  .uix-pill--danger { --tone-bg: var(--uix-danger-bg); --tone-fg: var(--uix-danger-text); --tone-dot: var(--uix-danger); }
@@ -18,7 +18,7 @@
18
18
  .uix-pill--attention { --tone-bg: var(--uix-attention-bg); --tone-fg: var(--uix-attention-text); --tone-dot: var(--uix-attention); }
19
19
  .uix-pill--overdue { --tone-bg: var(--uix-overdue-bg); --tone-fg: var(--uix-overdue-text); --tone-dot: var(--uix-overdue); }
20
20
  /* SLA tones — ok=success, at-risk=attention, breached=overdue */
21
- .uix-pill--sla-ok { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success); --tone-dot: var(--uix-success); }
21
+ .uix-pill--sla-ok { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success-text); --tone-dot: var(--uix-success); }
22
22
  .uix-pill--sla-at-risk { --tone-bg: var(--uix-attention-bg); --tone-fg: var(--uix-attention-text); --tone-dot: var(--uix-attention); }
23
23
  .uix-pill--sla-breached { --tone-bg: var(--uix-overdue-bg); --tone-fg: var(--uix-overdue-text); --tone-dot: var(--uix-overdue); }
24
24
  /* Priority/severity tones — P1=danger, P2=warning, P3=amber, P4=info, P5=neutral (complete 5-tier ramp) */
@@ -35,3 +35,11 @@
35
35
  .uix-pill--outline.uix-pill--muted { --tone-line: var(--uix-border); }
36
36
  .uix-pill--outline.uix-pill--critical { color: var(--uix-danger-text); --tone-dot: var(--uix-danger); --tone-line: color-mix(in srgb, var(--uix-danger) 60%, transparent); }
37
37
  }
38
+
39
+ /* Sizes (HAR-1614): sm for dense cells, lg for a page header. The default is unchanged. */
40
+ @layer uix.components {
41
+ .uix-pill--sm { gap: var(--uix-space-1); padding: 0 var(--uix-space-2); font-size: var(--uix-text-eyebrow); }
42
+ .uix-pill--sm .uix-pill__dot { width: 6px; height: 6px; }
43
+ .uix-pill--lg { padding: var(--uix-space-2) var(--uix-space-4); font-size: var(--uix-text-body); }
44
+ .uix-pill--lg .uix-pill__dot { width: 9px; height: 9px; }
45
+ }
@@ -44,3 +44,15 @@
44
44
  .uix-steps--horizontal > .uix-step > .uix-step__connector { position: absolute; left: 13px; top: 30px; bottom: 4px; width: 1px; height: auto; min-width: 0; margin: 0; }
45
45
  }
46
46
  }
47
+
48
+ /* Steps that hold content (`progress={false}`, HAR-1628): numbered sections, all on screen at
49
+ once. No state is drawn, so every step reads as body text and its content fills the row. */
50
+ @layer uix.components {
51
+ .uix-steps--sections { align-items: stretch; }
52
+ .uix-steps--sections > .uix-step { color: var(--uix-text); padding-bottom: var(--uix-space-6); }
53
+ .uix-steps--sections > .uix-step:last-child { padding-bottom: 0; }
54
+ .uix-steps--sections > .uix-step > .uix-step__text { flex: 1 1 0; }
55
+ .uix-steps--sections .uix-step__title { font-size: var(--uix-text-body); font-weight: 600; }
56
+ :is(h2, h3, h4, h5, h6).uix-step__title { margin: 0; line-height: inherit; }
57
+ .uix-step__content { min-width: 0; margin-top: var(--uix-space-3); color: var(--uix-text); font-size: var(--uix-text-body); }
58
+ }
@@ -21,7 +21,8 @@
21
21
  .uix-chip__count { font-variant-numeric: tabular-nums; color: var(--uix-text-muted); }
22
22
  .uix-chip[data-on] .uix-chip__count { color: inherit; }
23
23
  .uix-filter-popover { display: grid; gap: var(--uix-space-4); min-width: 260px; padding: var(--uix-space-4); }
24
- .uix-filter-popover .uix-label { display: grid; gap: var(--uix-space-2); }
24
+ /* one element as surface + content: beat popover.css's later 8 px (HAR-1573) */
25
+ .uix-popover.uix-filter-popover { padding: var(--uix-space-4); }
25
26
  .uix-filter-popover__actions { display: flex; justify-content: flex-end; gap: var(--uix-space-2); }
26
27
  }
27
28
 
@@ -34,20 +35,24 @@
34
35
  .uix-chip__icon { display: inline-flex; flex: none; }
35
36
  .uix-chip__label { min-width: 0; overflow-wrap: anywhere; }
36
37
  .uix-chip__icon svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
37
- .uix-chip--removable { padding-inline-end: var(--uix-space-1); }
38
+ .uix-chip--removable { padding-inline-end: calc(var(--uix-space-1) / 2); }
38
39
  .uix-chip__main {
39
40
  display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: 0; border: 0;
40
41
  background: transparent; color: inherit; font: inherit; border-radius: var(--uix-radius-pill);
41
42
  }
42
43
  button.uix-chip__main, a.uix-chip__main { cursor: pointer; }
43
44
  .uix-chip__main:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
44
- /* 24 px hit area (WCAG 2.5.8) without growing the chip: the negative block margin eats the overhang */
45
+ /* remove x (HAR-1569): one spec with .uix-tag__remove, pinned by tests/dismiss-control.test.mjs */
45
46
  .uix-chip__remove {
46
- display: inline-grid; place-items: center; width: 24px; height: 24px; margin-block: calc(-1 * var(--uix-space-1)); padding: 0; flex: none;
47
- border: 0; border-radius: var(--uix-radius-pill); background: transparent; color: inherit; cursor: pointer;
47
+ position: relative; display: inline-grid; place-items: center; flex: none; width: 20px; height: 20px;
48
+ margin-block: calc(var(--uix-space-1) / -2); padding: 0; border: 0; border-radius: var(--uix-radius-pill);
49
+ background: transparent; color: inherit; font: inherit; line-height: 0; cursor: pointer;
50
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
48
51
  }
49
- .uix-chip__remove svg { width: 12px; height: 12px; }
50
- .uix-chip__remove:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
52
+ .uix-chip__remove::before { content: ""; position: absolute; inset: -2px; border-radius: inherit; }
53
+ .uix-chip__remove svg { display: block; width: 12px; height: 12px; pointer-events: none; }
54
+ .uix-chip__remove:hover { background: color-mix(in srgb, var(--uix-text) 18%, transparent); color: var(--uix-text); }
55
+ .uix-chip__remove:active { background: color-mix(in srgb, var(--uix-text) 26%, transparent); }
51
56
  .uix-chip__remove:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 1px; }
52
57
  .uix-chip-group { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); }
53
58
  }
@@ -66,4 +71,6 @@
66
71
  .uix-filter-editor__list { display: grid; gap: var(--uix-space-2); max-height: 16rem; overflow-y: auto; padding: var(--uix-space-1); }
67
72
  .uix-filter-editor__note { margin: 0; font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
68
73
  .uix-filter-editor__choices { display: grid; gap: var(--uix-space-2); }
74
+ /* HAR-1505: enum presets, a toggle-chip row above the search box and options */
75
+ .uix-filter-editor__presets { padding-bottom: var(--uix-space-3); border-bottom: 1px solid var(--uix-border); }
69
76
  }
@@ -10,9 +10,18 @@
10
10
  display: inline-flex; align-items: center; gap: var(--uix-space-1); padding: var(--uix-space-1) var(--uix-space-1) var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-sm);
11
11
  background: var(--uix-bg-active); color: var(--uix-text); font-size: var(--uix-text-meta);
12
12
  }
13
- .uix-tag__remove { position: relative; display: grid; place-items: center; width: 16px; height: 16px; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-xs); }
14
- /* Invisible overlay grows the 16px visual to a 24px hit target (UIX-A11Y-3). */
15
- .uix-tag__remove::before { content: ""; position: absolute; inset: -4px; }
16
- .uix-tag__remove:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
17
- .uix-tag__remove svg { width: 12px; height: 12px; }
13
+ /* remove x (HAR-1569): one spec with .uix-chip__remove, pinned by tests/dismiss-control.test.mjs.
14
+ * 20 px circle, 2 px from the trailing edge; ::before makes a concentric 24 px hit area. */
15
+ .uix-tag:has(> .uix-tag__remove:last-child) { padding-inline-end: calc(var(--uix-space-1) / 2); }
16
+ .uix-tag__remove {
17
+ position: relative; display: inline-grid; place-items: center; flex: none; width: 20px; height: 20px;
18
+ margin-block: calc(var(--uix-space-1) / -2); padding: 0; border: 0; border-radius: var(--uix-radius-pill);
19
+ background: transparent; color: var(--uix-text-muted); font: inherit; line-height: 0; cursor: pointer;
20
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
21
+ }
22
+ .uix-tag__remove::before { content: ""; position: absolute; inset: -2px; border-radius: inherit; }
23
+ .uix-tag__remove svg { display: block; width: 12px; height: 12px; pointer-events: none; }
24
+ .uix-tag__remove:hover { background: color-mix(in srgb, var(--uix-text) 18%, transparent); color: var(--uix-text); }
25
+ .uix-tag__remove:active { background: color-mix(in srgb, var(--uix-text) 26%, transparent); }
26
+ .uix-tag__remove:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 1px; }
18
27
  }
@@ -0,0 +1,50 @@
1
+ /* TextDiff (HAR-1368): two-way line/word diff. Changes carry a −/+ sign, strike/underline and
2
+ spoken words as well as colour. Split view stacks below ~36rem (container query). */
3
+ @layer uix.components {
4
+ .uix-text-diff { container-type: inline-size; min-width: 0; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); color: var(--uix-text); overflow: hidden; }
5
+ .uix-text-diff__summary { margin: 0; padding: var(--uix-space-2) var(--uix-space-3); border-bottom: 1px solid var(--uix-border); font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
6
+ .uix-text-diff__heads { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid var(--uix-border); background: var(--uix-bg-subtle); font-size: var(--uix-text-meta); font-weight: 600; }
7
+ .uix-text-diff__head { padding: var(--uix-space-2) var(--uix-space-3); min-width: 0; overflow-wrap: anywhere; }
8
+ .uix-text-diff__head + .uix-text-diff__head { border-left: 1px solid var(--uix-border); }
9
+ .uix-text-diff[data-view="unified"] .uix-text-diff__heads { display: flex; flex-wrap: wrap; column-gap: var(--uix-space-3); }
10
+ .uix-text-diff[data-view="unified"] .uix-text-diff__head + .uix-text-diff__head { border-left: 0; }
11
+ .uix-text-diff__body { position: relative; overflow: auto; font-family: var(--uix-font-mono); font-size: var(--uix-text-meta); line-height: 1.6; }
12
+ .uix-text-diff__row { display: grid; grid-template-columns: 1fr 1fr; min-width: 0; }
13
+ .uix-text-diff[data-view="unified"] .uix-text-diff__row { grid-template-columns: 1fr; }
14
+ .uix-text-diff__row:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: -2px; }
15
+ .uix-text-diff__cell { display: grid; grid-template-columns: 4ch 2ch minmax(0, 1fr); min-width: 0; }
16
+ .uix-text-diff__cell + .uix-text-diff__cell { border-left: 1px solid var(--uix-border); }
17
+ .uix-text-diff__cell[data-empty] { background: var(--uix-bg-subtle); }
18
+ .uix-text-diff__cell[data-kind="delete"] { background: var(--uix-danger-bg); }
19
+ .uix-text-diff__cell[data-kind="insert"] { background: var(--uix-success-bg); }
20
+ .uix-text-diff__num { padding-inline-end: var(--uix-space-1); text-align: end; color: var(--uix-text-muted); user-select: none; }
21
+ .uix-text-diff__sign { text-align: center; color: var(--uix-text-muted); user-select: none; }
22
+ .uix-text-diff__cell[data-kind="delete"] .uix-text-diff__sign, .uix-text-diff__cell[data-kind="insert"] .uix-text-diff__sign { color: var(--uix-text); font-weight: 600; }
23
+ .uix-text-diff__text { min-width: 0; padding-inline-end: var(--uix-space-2); white-space: pre-wrap; overflow-wrap: anywhere; }
24
+ .uix-text-diff del, .uix-text-diff ins { border-radius: var(--uix-radius-sm); color: var(--uix-text); }
25
+ .uix-text-diff del { background: color-mix(in srgb, var(--uix-danger) 22%, transparent); text-decoration: line-through; }
26
+ .uix-text-diff ins { background: color-mix(in srgb, var(--uix-success) 22%, transparent); text-decoration: underline; text-underline-offset: 0.2em; }
27
+ /* A whole added/removed line: the row tint, the sign and the spoken word carry it; striking a whole line hurts reading. */
28
+ .uix-text-diff__cell del[data-whole], .uix-text-diff__cell ins[data-whole] { background: none; text-decoration: none; }
29
+ .uix-text-diff__row[data-kind="fold"] { grid-template-columns: 1fr; background: var(--uix-bg-subtle); }
30
+ .uix-text-diff__fold { justify-self: start; margin: 0; padding: var(--uix-space-1) var(--uix-space-3); border: 0; background: none; font: inherit; color: var(--uix-link); cursor: pointer; }
31
+ .uix-text-diff__fold:hover { text-decoration: underline; }
32
+ .uix-text-diff__fold:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: -2px; }
33
+ .uix-text-diff__row[data-kind="prose"] { grid-template-columns: 1fr 1fr; }
34
+ .uix-text-diff__prose { min-width: 0; padding: var(--uix-space-3); font-family: var(--uix-font-sans); font-size: var(--uix-text-body); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
35
+ .uix-text-diff__side { min-width: 0; }
36
+ .uix-text-diff__side + .uix-text-diff__side { border-left: 1px solid var(--uix-border); }
37
+ .uix-text-diff__side > .uix-text-diff__head { border-bottom: 1px solid var(--uix-border); background: var(--uix-bg-subtle); font-family: var(--uix-font-sans); font-size: var(--uix-text-meta); font-weight: 600; }
38
+ .uix-text-diff__note { margin: 0; padding: var(--uix-space-3); color: var(--uix-text-muted); }
39
+ @container (max-width: 36rem) {
40
+ .uix-text-diff[data-view="split"] .uix-text-diff__heads { display: none; }
41
+ .uix-text-diff[data-view="split"] .uix-text-diff__row { grid-template-columns: 1fr; }
42
+ .uix-text-diff[data-view="split"] .uix-text-diff__cell + .uix-text-diff__cell { border-left: 0; }
43
+ .uix-text-diff[data-view="split"] .uix-text-diff__row[data-kind="equal"] .uix-text-diff__cell[data-side="after"],
44
+ .uix-text-diff[data-view="split"] .uix-text-diff__cell[data-empty] { display: none; }
45
+ .uix-text-diff__side + .uix-text-diff__side { border-left: 0; border-top: 1px solid var(--uix-border); }
46
+ }
47
+ @media (forced-colors: active) {
48
+ .uix-text-diff del, .uix-text-diff ins { forced-color-adjust: none; background: Canvas; color: CanvasText; outline: 1px solid CanvasText; }
49
+ }
50
+ }
@@ -10,9 +10,9 @@
10
10
  @keyframes uix-toast-out { to { opacity: 0; transform: translateX(16px); } }
11
11
  .uix-toast__icon { flex: none; margin-top: 1px; }
12
12
  .uix-toast__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
13
- .uix-toast__body { flex: 1; }
13
+ .uix-toast__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--uix-space-1); }
14
14
  .uix-toast__title { font-weight: 600; font-size: var(--uix-text-body); }
15
- .uix-toast__msg { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-top: var(--uix-space-1); }
15
+ .uix-toast__msg { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
16
16
  .uix-toast__close { border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; padding: var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-xs); }
17
17
  .uix-toast__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
18
18
  .uix-toast--success .uix-toast__icon { color: var(--uix-success); }
@@ -18,8 +18,13 @@
18
18
  }
19
19
  .uix-view-menu__row { display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-3); font-size: var(--uix-text-body); color: var(--uix-text); cursor: pointer; }
20
20
  .uix-view-menu__row + .uix-view-menu__row { margin-top: var(--uix-space-3); }
21
- .uix-view-menu .uix-segmented { display: flex; width: 100%; }
22
- .uix-view-menu .uix-segmented__option { flex: 1; text-align: center; }
21
+ /* HAR-1601: three equal options in a 304 px panel are 84 px each, and "Großzügig" did not fit
22
+ its option: the Segmented's `overflow-wrap: anywhere` then split it after the 8th letter.
23
+ Here an option is never narrower than its longest word (overflow-wrap: normal makes
24
+ min-content that word), the padding is tighter, and options that still do not fit in one
25
+ row wrap as whole options. */
26
+ .uix-view-menu .uix-segmented { display: flex; flex-wrap: wrap; width: 100%; }
27
+ .uix-view-menu .uix-segmented__option { flex: 1 1 0; min-width: min-content; padding-inline: var(--uix-space-2); text-align: center; overflow-wrap: normal; hyphens: manual; }
23
28
  .uix-view-menu__cols { display: flex; flex-direction: column; margin: 0 calc(-1 * var(--uix-space-1)); padding: 0; list-style: none; }
24
29
  .uix-view-menu__footer { border-top: 1px solid var(--uix-border); padding: var(--uix-space-1) 0 0; }
25
30
  /* Column rows. Hover paints the WHOLE row (grip, checkbox, name, ⋯ together), never just the label. */
@@ -28,6 +28,7 @@
28
28
  "success": { "$type": "color", "$value": "#047857" },
29
29
  "success-fg": { "$type": "color", "$value": "#FFFFFF" },
30
30
  "success-bg": { "$type": "color", "$value": "#D0FAE5" },
31
+ "success-text": { "$type": "color", "$value": "var(--uix-success)", "$description": "Success-toned TEXT (pill, alert icon, stat trend, SLA ok). Light aliases --uix-success (#047857, already AA on the pale tint), so a theme's light success override still reaches text; dark sets its own value in the calibrated status-text band (HAR-1562). Paint text with this, not with --uix-success, which is the solid/dot role on dark." },
31
32
  "warning": { "$type": "color", "$value": "#F99C00" },
32
33
  "warning-fg": { "$type": "color", "$value": "#1A1A1A" },
33
34
  "warning-bg": { "$type": "color", "$value": "#FEF3D6" },
@@ -68,15 +69,29 @@
68
69
  "info-solid": { "$type": "color", "$value": "#2563EB", "$description": "SOLID status role (see success-solid)." },
69
70
  "danger-solid": { "$type": "color", "$value": "#EF4444", "$description": "SOLID status role (see success-solid)." },
70
71
 
71
- "chart-1": { "$type": "color", "$value": "#2563EB" },
72
- "chart-2": { "$type": "color", "$value": "#0891B2" },
73
- "chart-3": { "$type": "color", "$value": "#16A34A" },
74
- "chart-4": { "$type": "color", "$value": "#F59E0B" },
75
- "chart-5": { "$type": "color", "$value": "#EA580C" },
76
- "chart-6": { "$type": "color", "$value": "#E11D48" },
77
- "chart-7": { "$type": "color", "$value": "#7C3AED" },
78
- "chart-8": { "$type": "color", "$value": "#DB2777" },
72
+ "neutral-solid": { "$type": "color", "$value": "#8A8A8A", "$description": "NEUTRAL status family (HAR-1562): the default, non-alarming status tone (open, scheduled, draft, in progress). Solid = the dot/fill, 3:1 non-text on white. Dark overrides." },
73
+ "neutral-text": { "$type": "color", "$value": "var(--uix-text-hushed)", "$description": "Neutral status TEXT, alias of --uix-text-hushed. var() reference, no dark override needed." },
74
+ "neutral-bg": { "$type": "color", "$value": "var(--uix-bg-active)", "$description": "Neutral status tint, alias of --uix-bg-active." },
75
+ "neutral-border": { "$type": "color", "$value": "var(--uix-border-strong)", "$description": "Neutral status outline, alias of --uix-border-strong." },
76
+
77
+ "chart-1": { "$type": "color", "$value": "#0455E6", "$description": "Categorical palette, light. Fixed hue order (blue, cyan, green, ochre, orange, crimson, violet, pink), re-stepped so the dataviz validator passes on --uix-surface and --uix-bg-app: L 0.43-0.77, C >= 0.10, adjacent CVD dE >= 8, normal-vision dE >= 15, >= 3:1 (HAR-1552)." },
78
+ "chart-2": { "$type": "color", "$value": "#249BC8" },
79
+ "chart-3": { "$type": "color", "$value": "#06A543" },
80
+ "chart-4": { "$type": "color", "$value": "#905709" },
81
+ "chart-5": { "$type": "color", "$value": "#F25C1B" },
82
+ "chart-6": { "$type": "color", "$value": "#B00825" },
83
+ "chart-7": { "$type": "color", "$value": "#8143E6" },
84
+ "chart-8": { "$type": "color", "$value": "#DB2579" },
79
85
  "chart-neutral": { "$type": "color", "$value": "#64748B" },
86
+ "chart-grid": { "$type": "color", "$value": "#EDEDED", "$description": "Chart gridline: a SOLID 1px hairline, recessive. Dashes are reserved for projections and thresholds (HAR-1552)." },
87
+ "chart-axis": { "$type": "color", "$value": "#D4D4D4", "$description": "Chart axis line (labels use --uix-text-muted)." },
88
+ "chart-reference": { "$type": "color", "$value": "#525252", "$description": "Neutral ink for target, budget and baseline reference lines: 7.8:1 on --uix-surface. Not a status colour." },
89
+ "chart-zone-warning": { "$type": "color", "$value": "rgba(217,119,6,.10)", "$description": "Alpha fill for a warning threshold zone behind the series." },
90
+ "chart-zone-danger": { "$type": "color", "$value": "rgba(228,0,20,.07)", "$description": "Alpha fill for a danger threshold zone behind the series." },
91
+ "chart-forecast-band": { "$type": "color", "$value": "rgba(10,10,10,.06)", "$description": "Alpha fill for a forecast / confidence band; neutral so it works under any series hue." },
92
+ "chart-event": { "$type": "color", "$value": "#737373", "$description": "Event-marker line and label ink (deploys, incidents, releases): 4.7:1 on --uix-surface." },
93
+ "chart-partial": { "$type": "color", "$value": "rgba(10,10,10,.10)", "$description": "Hatch base for a partial (incomplete) period." },
94
+ "chart-comparison": { "$type": "color", "$value": "#B8B8B8", "$description": "Muted ghost line for the comparison period (last week, last year)." },
80
95
 
81
96
  "row": { "$type": "color", "$value": "#FFFFFF" },
82
97
  "row-alt": { "$type": "color", "$value": "#FAFAFA" },
@@ -3,6 +3,7 @@
3
3
  "radius-sm": { "$type": "dimension", "$value": "8px" },
4
4
  "radius-md": { "$type": "dimension", "$value": "12px" },
5
5
  "radius-lg": { "$type": "dimension", "$value": "16px" },
6
+ "radius-xl": { "$type": "dimension", "$value": "24px", "$description": "Largest corner radius below pill: hero cards, sheets, large dialogs (HAR-1384, shipped with HAR-1562)." },
6
7
  "radius-pill": { "$type": "dimension", "$value": "999px" },
7
8
 
8
9
  "row-h": { "$type": "dimension", "$value": "56px" },
@@ -20,51 +20,62 @@
20
20
  "ring": { "$type": "color", "$value": "var(--uix-brand,#3080FF)" },
21
21
  "brand-muted": { "$type": "color", "$value": "color-mix(in srgb, var(--uix-accent) 16%, transparent)" },
22
22
 
23
- "success": { "$type": "color", "$value": "#00D294" },
23
+ "success": { "$type": "color", "$value": "#49AF7E", "$description": "Calibrated (HAR-1562): dark status TEXT tokens share one lightness band (OKLCH L 74-80%, C <= 0.10) near --uix-text-hushed, SOLIDS C <= 0.14, tints = solid at 12% alpha. The old #00D294 (C 0.165) glowed against dark surfaces." },
24
24
  "success-fg": { "$type": "color", "$value": "#002C22" },
25
- "success-bg": { "$type": "color", "$value": "rgba(0,210,148,.15)" },
26
- "warning": { "$type": "color", "$value": "#FCBB00" },
25
+ "success-bg": { "$type": "color", "$value": "rgba(73,175,126,.12)" },
26
+ "success-text": { "$type": "color", "$value": "#7CC79F", "$description": "Success-toned TEXT on dark: 9.5:1 on --uix-surface, 8.0:1 on its own tint." },
27
+ "warning": { "$type": "color", "$value": "#D7B672", "$description": "On dark --uix-warning carries the calibrated warning TEXT value, because --uix-warning-text chains to it (var(--uix-warning,...)) and that chain is part of the contract. The fill/dot role is --uix-warning-solid." },
27
28
  "warning-fg": { "$type": "color", "$value": "#1A1A1A" },
28
- "warning-bg": { "$type": "color", "$value": "rgba(249,156,0,.16)" },
29
+ "warning-bg": { "$type": "color", "$value": "rgba(217,164,64,.12)" },
29
30
  "warning-border": { "$type": "color", "$value": "#CA8A04", "$description": "On dark, a deeper amber than the bright --uix-warning so the outline reads as a tone rather than a highlight; 6:1 on --uix-surface #111111." },
30
- "warning-text": { "$type": "color", "$value": "var(--uix-warning,#FCBB00)", "$description": "On dark the faint bg is dark enough that the bright warning hue reads as text — track --uix-warning live (fallback to the dark warning value)." },
31
+ "warning-text": { "$type": "color", "$value": "var(--uix-warning,#D7B672)", "$description": "On dark, warning text tracks --uix-warning live (fallback to the dark warning value, calibrated by HAR-1562: 9.7:1 on --uix-surface, 8.1:1 on its own tint)." },
31
32
  "info": { "$type": "color", "$value": "#2563EB" },
32
33
  "info-fg": { "$type": "color", "$value": "#FFFFFF" },
33
- "info-bg": { "$type": "color", "$value": "rgba(48,128,255,.16)" },
34
- "info-text": { "$type": "color", "$value": "#60A5FA", "$description": "On dark, the deep --uix-info #2563EB fails as text on the faint info tint — brightened so info pill/alert/node text reads AA." },
35
- "danger": { "$type": "color", "$value": "#DC2626" },
34
+ "info-bg": { "$type": "color", "$value": "rgba(98,147,219,.12)" },
35
+ "info-text": { "$type": "color", "$value": "#8DB4E7", "$description": "On dark, the deep --uix-info #2563EB (a fill with white text, unchanged) fails as text on the faint info tint. Calibrated (HAR-1562): 8.8:1 on --uix-surface, 7.6:1 on its own tint." },
36
+ "danger": { "$type": "color", "$value": "#BE3A41", "$description": "The dark danger FILL (critical pill, danger button) with white --uix-danger-fg on it: 5.4:1. Calmer than the old #DC2626 (C 0.215)." },
36
37
  "danger-fg": { "$type": "color", "$value": "#FFFFFF" },
37
- "danger-bg": { "$type": "color", "$value": "rgba(220,38,38,.20)" },
38
- "danger-border": { "$type": "color", "$value": "#DC2626", "$description": "On dark, the solid danger red as an outline; 4.3:1 on --uix-surface #111111." },
39
- "danger-text": { "$type": "color", "$value": "#F87171", "$description": "On dark, the deep --uix-danger #DC2626 fails as text on the faint danger tint and on plain surfaces — brightened so pill/field-error/stat-trend/menu/node/audit text reads AA. --uix-danger stays the solid critical-pill / button bg (with white --uix-danger-fg)." },
38
+ "danger-bg": { "$type": "color", "$value": "rgba(218,108,108,.12)" },
39
+ "danger-border": { "$type": "color", "$value": "#DA6C6C", "$description": "On dark, the danger solid as an outline; 5.7:1 on --uix-surface #111111." },
40
+ "danger-text": { "$type": "color", "$value": "#E69593", "$description": "On dark, danger-toned TEXT for pill/field-error/stat-trend/menu/node/audit. Calibrated (HAR-1562): 8.2:1 on --uix-surface, 7.1:1 on its own tint. --uix-danger stays the solid critical-pill / button bg (with white --uix-danger-fg)." },
40
41
  "amber": { "$type": "color", "$value": "#E6B25C", "$description": "SEV-3 tone lightened for dark surfaces (the light-mode ochre #C98A1E is too dark on dark)." },
41
- "amber-text": { "$type": "color", "$value": "#E6B25C", "$description": "On dark the lightened amber reads as text directly — tracks --uix-amber." },
42
+ "amber-text": { "$type": "color", "$value": "#DDB370", "$description": "On dark, amber TEXT in the calibrated status-text band (HAR-1562: C <= 0.10; the old #E6B25C was C 0.12)." },
42
43
  "amber-bg": { "$type": "color", "$value": "rgba(201,138,30,.14)" },
43
44
 
44
- "attention": { "$type": "color", "$value": "#FB923C", "$description": "Orange-400 — brightened for dark surfaces (the light-mode #EA580C is too dark on dark)." },
45
- "attention-bg": { "$type": "color", "$value": "rgba(234,88,12,.16)" },
46
- "attention-text": { "$type": "color", "$value": "#FDBA74", "$description": "On dark, orange text tracks --uix-attention (brightened); reads AA on the faint attention-bg." },
47
- "attention-solid": { "$type": "color", "$value": "#F97316" },
45
+ "attention": { "$type": "color", "$value": "#DD854C", "$description": "Dark attention solid (HAR-1562 calibration; the light-mode #EA580C is too dark on dark)." },
46
+ "attention-bg": { "$type": "color", "$value": "rgba(221,133,76,.12)" },
47
+ "attention-text": { "$type": "color", "$value": "#DFA779", "$description": "On dark, attention TEXT: 8.9:1 on --uix-surface, reads AA on the faint attention-bg." },
48
+ "attention-solid": { "$type": "color", "$value": "#DD854C" },
48
49
 
49
- "overdue": { "$type": "color", "$value": "#F87171", "$description": "Red-400 — brightened overdue for dark surfaces (the light-mode #DC2626 fails on dark)." },
50
- "overdue-bg": { "$type": "color", "$value": "rgba(220,38,38,.18)" },
51
- "overdue-text": { "$type": "color", "$value": "#FCA5A5", "$description": "On dark, brightened red text reads AA on the faint overdue-bg." },
52
- "overdue-solid": { "$type": "color", "$value": "#F87171" },
50
+ "overdue": { "$type": "color", "$value": "#DA6C6C", "$description": "Dark overdue solid (HAR-1562 calibration; the light-mode #DC2626 fails on dark)." },
51
+ "overdue-bg": { "$type": "color", "$value": "rgba(218,108,108,.12)" },
52
+ "overdue-text": { "$type": "color", "$value": "#E89D9F", "$description": "On dark, overdue TEXT: 8.8:1 on --uix-surface, reads AA on the faint overdue-bg." },
53
+ "overdue-solid": { "$type": "color", "$value": "#DA6C6C" },
53
54
 
54
- "success-solid": { "$type": "color", "$value": "#34D399" },
55
- "warning-solid": { "$type": "color", "$value": "#FBBF24" },
56
- "info-solid": { "$type": "color", "$value": "#3B82F6" },
57
- "danger-solid": { "$type": "color", "$value": "#F87171" },
55
+ "success-solid": { "$type": "color", "$value": "#49AF7E" },
56
+ "warning-solid": { "$type": "color", "$value": "#D9A440" },
57
+ "info-solid": { "$type": "color", "$value": "#6293DB" },
58
+ "danger-solid": { "$type": "color", "$value": "#DA6C6C" },
59
+ "neutral-solid": { "$type": "color", "$value": "#868686", "$description": "Dark neutral status solid (dot/fill): 5.2:1 on --uix-surface." },
58
60
 
59
- "chart-1": { "$type": "color", "$value": "#3080FF" },
60
- "chart-2": { "$type": "color", "$value": "#00C2B0" },
61
- "chart-3": { "$type": "color", "$value": "#00D294" },
62
- "chart-4": { "$type": "color", "$value": "#FCBB00" },
63
- "chart-5": { "$type": "color", "$value": "#FF8B1A" },
64
- "chart-6": { "$type": "color", "$value": "#FF6568" },
65
- "chart-7": { "$type": "color", "$value": "#A685FF" },
66
- "chart-8": { "$type": "color", "$value": "#FF667F" },
61
+ "chart-1": { "$type": "color", "$value": "#3280FC", "$description": "Categorical palette, dark: the same eight hues stepped for the dark band (L 0.48-0.67) and validated against --uix-surface #111111 (HAR-1552)." },
62
+ "chart-2": { "$type": "color", "$value": "#15A7A4" },
63
+ "chart-3": { "$type": "color", "$value": "#127A3D" },
64
+ "chart-4": { "$type": "color", "$value": "#AB9017" },
65
+ "chart-5": { "$type": "color", "$value": "#8F530C" },
66
+ "chart-6": { "$type": "color", "$value": "#CD766F" },
67
+ "chart-7": { "$type": "color", "$value": "#9A77F4" },
68
+ "chart-8": { "$type": "color", "$value": "#FB416A" },
67
69
  "chart-neutral": { "$type": "color", "$value": "#A1A1A1" },
70
+ "chart-grid": { "$type": "color", "$value": "#232323" },
71
+ "chart-axis": { "$type": "color", "$value": "#3A3A3A" },
72
+ "chart-reference": { "$type": "color", "$value": "#B3B3B3" },
73
+ "chart-zone-warning": { "$type": "color", "$value": "rgba(217,164,64,.10)" },
74
+ "chart-zone-danger": { "$type": "color", "$value": "rgba(218,108,108,.10)" },
75
+ "chart-forecast-band": { "$type": "color", "$value": "rgba(250,250,250,.06)" },
76
+ "chart-event": { "$type": "color", "$value": "#8C8C8C" },
77
+ "chart-partial": { "$type": "color", "$value": "rgba(250,250,250,.12)" },
78
+ "chart-comparison": { "$type": "color", "$value": "#5C5C5C" },
68
79
 
69
80
  "row": { "$type": "color", "$value": "#111111" },
70
81
  "row-alt": { "$type": "color", "$value": "#161616" },