@momoi-labs/kiso 0.9.0 → 0.11.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/kiso/ui.css CHANGED
@@ -298,6 +298,36 @@ a:hover, .link:hover { text-decoration: underline; }
298
298
  /* ===========================================================================
299
299
  Form controls
300
300
  =========================================================================== */
301
+ /* Forms own composition; consumers own values, validation and submission. */
302
+ .form { display: flex; flex-direction: column; min-inline-size: 0; min-block-size: 100%; }
303
+ .form-body { display: grid; gap: var(--spacing-xl); padding: var(--spacing-lg); min-inline-size: 0; }
304
+ fieldset.form-body { border: 0; margin: 0; }
305
+ .form-actions {
306
+ display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-md) var(--spacing-lg);
307
+ margin-block-start: auto;
308
+ padding: var(--spacing-md) var(--spacing-lg);
309
+ border-block-start: 1px solid var(--color-border);
310
+ background: var(--color-card);
311
+ color: var(--color-card-foreground);
312
+ border-end-start-radius: inherit; border-end-end-radius: inherit;
313
+ }
314
+ .form-actions[data-sticky="true"] { position: sticky; inset-block-end: 0; z-index: 1; }
315
+ .form-actions[data-tone="warning"] {
316
+ background: linear-gradient(var(--color-warning-surface), var(--color-warning-surface)), var(--color-card);
317
+ border-block-start-color: var(--color-warning-border);
318
+ }
319
+ .form-actions[data-tone="danger"] {
320
+ background: linear-gradient(var(--color-danger-surface), var(--color-danger-surface)), var(--color-card);
321
+ border-block-start-color: var(--color-danger-border);
322
+ }
323
+ .form-actions-message { flex: 1 1 12rem; min-inline-size: 0; overflow-wrap: anywhere; font-size: var(--type-size-label); }
324
+ /* Keep the live region mounted and available to assistive technology. */
325
+ .form-actions-message:empty { flex: 0 0 0; }
326
+ .form-actions-message strong { font-weight: var(--type-weight-semibold); }
327
+ .form-actions-buttons { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--spacing-sm); margin-inline-start: auto; }
328
+ .form-scroll { min-block-size: 0; overflow: auto; scroll-padding-block-end: calc(var(--spacing-4xl) * 2); }
329
+ .form :is(input, textarea, select, button, [tabindex]) { scroll-margin-block: var(--spacing-lg) calc(var(--spacing-4xl) * 2); }
330
+
301
331
  .field { display: grid; gap: var(--spacing-xs); }
302
332
  .field > label, .label {
303
333
  font-size: var(--type-size-label);
@@ -593,6 +623,12 @@ a:hover, .link:hover { text-decoration: underline; }
593
623
  }
594
624
  .stat-foot { font-size: var(--type-size-label); color: var(--color-muted-foreground); margin-block-start: var(--spacing-sm); }
595
625
  .stat-delta { display: inline-flex; align-items: center; gap: var(--spacing-xs); font-size: var(--type-size-metadata); font-weight: var(--type-weight-medium); }
626
+ /* The delta keeps the outline treatment: only text and frame take the status
627
+ colour. Declared after .badge-outline so the variant wins the cascade. */
628
+ .stat-delta.info { color: var(--color-info); border-color: var(--color-info-border); }
629
+ .stat-delta.success { color: var(--color-success); border-color: var(--color-success-border); }
630
+ .stat-delta.warning { color: var(--color-warning); border-color: var(--color-warning-border); }
631
+ .stat-delta.danger { color: var(--color-danger); border-color: var(--color-danger-border); }
596
632
 
597
633
  /* ===========================================================================
598
634
  Table
@@ -1010,7 +1046,7 @@ pre code { display: block; overflow-x: auto; padding: 0; background: none; borde
1010
1046
  .logview .log-error{ color: var(--color-danger-on-dark); }
1011
1047
  .logview .log-info { color: var(--color-info-on-dark); }
1012
1048
 
1013
- /* Sparkline / bar chart placeholders, neutral-only per the brand rules. */
1049
+ /* Legacy compact bars remain neutral. Framed charts use categorical roles. */
1014
1050
  .bars { display: flex; align-items: flex-end; gap: 3px; height: 40px; }
1015
1051
  .bars i { flex: 1; background: var(--color-border-strong); border-radius: var(--radius-xs); }
1016
1052
  .bars i.on { background: var(--color-primary); }
@@ -1131,10 +1167,8 @@ pre::after {
1131
1167
  .splitter::after { content: ""; position: absolute; inset-block: 0; inset-inline: -3px; }
1132
1168
  .splitter:hover, .splitter.dragging { background: var(--color-ring); }
1133
1169
 
1134
- /* Chart frame: deliberate presentation, one featured series in primary,
1135
- gridlines at border strength. The area is the line color at low opacity, a
1136
- flat token fill: no document-level gradient id for a component to forget
1137
- to define. Supporting, incidental series belong in `.sparkline` instead. */
1170
+ /* Legacy single-series SVG helpers. Interactive metrics use .framed-chart
1171
+ below; these selectors remain compatible with existing consumers. */
1138
1172
  .chart { width: 100%; height: 200px; display: block; overflow: visible; color: var(--color-primary); }
1139
1173
  .chart .grid { stroke: var(--color-border); stroke-width: 1; }
1140
1174
  .chart .line { fill: none; stroke: currentColor; stroke-width: 1.5; }
@@ -1152,3 +1186,122 @@ pre::after {
1152
1186
  .sparkline { display: block; width: 100%; color: var(--color-border-strong); }
1153
1187
  .sparkline.primary { color: var(--color-primary); }
1154
1188
  .sparkline svg { display: block; overflow: visible; }
1189
+
1190
+ /* Metrics dashboard, issue #93. Series colors encode identity, not status. */
1191
+ .framed-chart { margin: 0; display: grid; gap: var(--spacing-sm); min-width: 0; }
1192
+ .chart-help { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
1193
+ .chart-plot { width: 100%; min-width: 0; font-size: var(--type-size-metadata); }
1194
+ .chart-plot :focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
1195
+ .chart-empty { display: grid; place-items: center; padding: var(--spacing-md); color: var(--color-muted-foreground); }
1196
+ .chart-table-scroll { max-width: 100%; overflow-x: auto; }
1197
+ .chart-table { width: 100%; border-collapse: collapse; font-size: var(--type-size-label); font-variant-numeric: tabular-nums; }
1198
+ .chart-table caption { text-align: start; color: var(--color-muted-foreground); padding-block: var(--spacing-xs); }
1199
+ .chart-table th, .chart-table td { padding: var(--spacing-xs) var(--spacing-sm); border-bottom: 1px solid var(--color-border); white-space: nowrap; text-align: end; }
1200
+ .chart-table th:first-child { text-align: start; }
1201
+ .chart-table th { font-weight: var(--type-weight-medium); }
1202
+ .chart-series-label { display: inline-flex; align-items: center; gap: var(--spacing-xs); }
1203
+ .chart-series-label svg { flex: none; }
1204
+ .chart-inspection { padding: var(--spacing-sm); border: 1px solid var(--color-border); background: var(--color-elevated-surface); color: var(--color-foreground); box-shadow: var(--shadow-md); font-size: var(--type-size-label); }
1205
+ .chart-inspection dl { display: grid; grid-template-columns: auto auto; gap: var(--spacing-xs) var(--spacing-md); margin-block: var(--spacing-xs) 0; }
1206
+ .chart-inspection dd { margin: 0; text-align: end; font-variant-numeric: tabular-nums; }
1207
+ .meter, .bar-gauge { display: grid; gap: var(--spacing-sm); min-width: 0; }
1208
+ .bar-gauge { gap: var(--spacing-md); }
1209
+ .meter-label { display: flex; justify-content: space-between; gap: var(--spacing-md); font-size: var(--type-size-label); }
1210
+ .meter-label > :last-child { text-align: end; font-variant-numeric: tabular-nums; }
1211
+ .meter-track { height: calc(var(--spacing-xs) + var(--spacing-2xs)); border-radius: var(--radius-xs); background-color: var(--color-secondary); overflow: hidden; }
1212
+ .meter-track > span { display: block; height: 100%; background: var(--color-secondary-foreground); }
1213
+ .disclosure { min-width: 0; }
1214
+ .disclosure > summary { padding: var(--spacing-sm) 0; cursor: pointer; font-weight: var(--type-weight-medium); }
1215
+ .disclosure > summary:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
1216
+ .disclosure-content { padding: var(--spacing-sm) 0; }
1217
+ .time-range-trigger { justify-self: start; width: fit-content; max-width: 100%; white-space: normal; height: auto; min-height: var(--size-control-md); text-align: start; }
1218
+ .time-range-content { width: min(26rem, calc(100vw - 2 * var(--spacing-md))); }
1219
+ .time-range-presets { display: grid; gap: var(--spacing-xs); }
1220
+ .time-range-presets > button { height: auto; min-height: var(--size-touch-min); display: flex; align-items: flex-start; flex-direction: column; text-align: start; }
1221
+ .time-range-presets small { color: var(--color-muted-foreground); font-weight: var(--type-weight-regular); }
1222
+ .meter[data-slot="progress"] .meter-track > span { background: var(--color-chart-1); }
1223
+ .dashboard-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--spacing-lg); }
1224
+ .dashboard-panel { grid-column: span var(--dashboard-span, 6); min-width: 0; display: grid; } /* the panel is a grid so its single child stretches to the row */
1225
+ @media (max-width: 1024px) {
1226
+ .dashboard-panel { grid-column: span 6; }
1227
+ .dashboard-panel[data-span="12"] { grid-column: span 12; }
1228
+ }
1229
+ @media (max-width: 640px) {
1230
+ .dashboard-grid { grid-template-columns: minmax(0, 1fr); }
1231
+ .dashboard-panel, .dashboard-panel[data-span="12"] { grid-column: 1; }
1232
+ }
1233
+ @media (pointer: coarse) {
1234
+ .disclosure > summary { min-height: var(--size-touch-min); display: list-item; align-content: center; }
1235
+ }
1236
+
1237
+ /* StepList and StepBar, issue #98. A run's steps, walked by a machine and
1238
+ read by a person. The rail is the progress: each connector takes the state
1239
+ of the step below it, so the line fills as the run advances. Running is the
1240
+ success colour because it is alive; neutral is what is not happening. */
1241
+ .step-list { list-style: none; margin: 0; padding: 0; display: grid; }
1242
+ .step { display: grid; grid-template-columns: var(--spacing-xl) minmax(0, 1fr); column-gap: var(--spacing-sm); }
1243
+ .step-rail { position: relative; display: grid; justify-items: center; }
1244
+ .step-rail::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 3px; translate: -50% 0; background: var(--color-secondary); }
1245
+ .step:first-child .step-rail::before { top: 12px; }
1246
+ .step:last-child .step-rail::before { bottom: auto; height: 12px; }
1247
+ .step[data-state="done"] .step-rail::before, .step[data-state="skipped"] .step-rail::before { background: var(--color-success); }
1248
+ .step[data-state="running"] .step-rail::before { background: linear-gradient(var(--color-success) 0 12px, var(--color-secondary) 12px 100%); }
1249
+ .step[data-state="failed"] .step-rail::before { background: linear-gradient(var(--color-success) 0 12px, var(--color-danger) 12px 100%); }
1250
+ .step-mark { position: relative; z-index: 1; width: 12px; height: 12px; margin-top: 6px; border-radius: var(--radius-full); background: var(--color-card); border: 3px solid var(--color-border-strong); }
1251
+ .step[data-state="done"] .step-mark { background: var(--color-success); border-color: var(--color-success); }
1252
+ .step[data-state="skipped"] .step-mark { border-color: var(--color-success); }
1253
+ .step[data-state="running"] .step-mark { border-color: var(--color-success); box-shadow: 0 0 0 4px var(--color-success-surface); animation: step-pulse 1.4s var(--motion-easing-standard) infinite; }
1254
+ .step[data-state="failed"] .step-mark { background: var(--color-danger); border-color: var(--color-danger); }
1255
+ /* 12px dot plus 6px of glow fits the 24px rail column, which a Pane clips at its edge. */
1256
+ @keyframes step-pulse { 50% { box-shadow: 0 0 0 6px transparent; } }
1257
+ .step-body { min-width: 0; padding-bottom: var(--spacing-sm); }
1258
+ .step-row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-md); width: 100%; min-height: 24px; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: start; }
1259
+ button.step-row { cursor: pointer; }
1260
+ button.step-row:hover .step-label { text-decoration: underline; text-underline-offset: var(--spacing-2xs); }
1261
+ button.step-row:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; border-radius: var(--radius-sm); }
1262
+ .step-label { font-size: var(--type-size-label); font-weight: var(--type-weight-medium); }
1263
+ .step[data-state="pending"] .step-label, .step[data-state="skipped"] .step-label { color: var(--color-muted-foreground); font-weight: var(--type-weight-regular); }
1264
+ .step[data-state="running"] .step-label, .step[data-state="failed"] .step-label { font-weight: var(--type-weight-semibold); }
1265
+ .step[data-state="failed"] .step-label { color: var(--color-danger); }
1266
+ .step-row[aria-pressed="true"] .step-label { text-decoration: underline; text-underline-offset: var(--spacing-2xs); }
1267
+ .step-meta { font-family: var(--font-mono); font-size: var(--type-size-label); color: var(--color-muted-foreground); white-space: nowrap; font-variant-numeric: tabular-nums; }
1268
+ .step-detail { margin-top: var(--spacing-sm); }
1269
+ @media (pointer: coarse) {
1270
+ button.step-row { min-height: var(--size-touch-min); }
1271
+ }
1272
+ @media (prefers-reduced-motion: reduce) {
1273
+ .step[data-state="running"] .step-mark { animation: none; }
1274
+ }
1275
+
1276
+ .step-bar { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--spacing-2xs); height: var(--spacing-xs); min-width: 0; }
1277
+ .step-bar > span { border-radius: var(--radius-xs); background: var(--color-secondary); }
1278
+ .step-bar > span[data-state="done"] { background: var(--color-success); }
1279
+ .step-bar > span[data-state="running"] { background: linear-gradient(90deg, var(--color-success) 0 var(--step-progress, 100%), var(--color-success-surface) var(--step-progress, 100%) 100%); }
1280
+ .step-bar > span[data-state="skipped"] { background: repeating-linear-gradient(45deg, var(--color-success) 0 2px, transparent 2px 5px); }
1281
+ .step-bar > span[data-state="failed"] { background: var(--color-danger); }
1282
+
1283
+ /* Chart presentation options. Exact values remain available in every layout. */
1284
+ .chart-body, .chart-plots { min-width: 0; }
1285
+ .framed-chart[data-legend="sidebar"] .chart-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(140px, 180px); gap: var(--spacing-lg); }
1286
+ .framed-chart[data-layout="compact"] { gap: var(--spacing-xs); }
1287
+ .chart-lane + .chart-lane { margin-top: var(--spacing-sm); }
1288
+ .chart-lane-heading { display: flex; justify-content: space-between; gap: var(--spacing-sm); font-size: var(--type-size-label); font-variant-numeric: tabular-nums; }
1289
+ .chart-legend { font-size: var(--type-size-label); }
1290
+ .chart-legend-caption { color: var(--color-muted-foreground); overflow-wrap: anywhere; }
1291
+ .chart-legend dl { margin: 0; }
1292
+ .chart-legend dl > div { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-sm); }
1293
+ .chart-legend dd { margin: 0; font-variant-numeric: tabular-nums; }
1294
+ .chart-legend-inline { display: flex; align-items: center; flex-wrap: wrap; gap: var(--spacing-sm) var(--spacing-md); }
1295
+ .chart-legend-inline dl { display: flex; flex-wrap: wrap; gap: var(--spacing-sm) var(--spacing-lg); }
1296
+ .chart-legend-sidebar { border-left: 1px solid var(--color-border); padding-left: var(--spacing-md); }
1297
+ .chart-legend-sidebar dl { display: grid; gap: var(--spacing-sm); margin-top: var(--spacing-sm); }
1298
+ .chart-series-button { display: inline-flex; align-items: center; padding: var(--spacing-2xs) 0; border: 0; background: transparent; color: var(--color-foreground); font: inherit; text-align: start; cursor: pointer; }
1299
+ .chart-series-button[aria-pressed="true"] { text-decoration: underline; text-underline-offset: var(--spacing-2xs); }
1300
+ .chart-series-button:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
1301
+ @media (max-width: 640px) {
1302
+ .framed-chart[data-legend="sidebar"] .chart-body { grid-template-columns: minmax(0, 1fr); }
1303
+ .chart-legend-sidebar { border-left: 0; padding-left: 0; border-top: 1px solid var(--color-border); padding-top: var(--spacing-sm); }
1304
+ }
1305
+ @media (pointer: coarse) {
1306
+ .chart-series-button { min-height: var(--size-touch-min); min-width: var(--size-touch-min); }
1307
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momoi-labs/kiso",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Kiso design-system contracts and generated design tokens",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -15,21 +15,6 @@
15
15
  --color-neutral-800: #26252b;
16
16
  --color-neutral-900: #1b1a1e;
17
17
  --color-neutral-950: #131217;
18
- --color-accent-50: #f7f4ff;
19
- --color-accent-200: #ede8fd;
20
- --color-accent-300: #ded5fb;
21
- --color-accent-400: #c4b4f5;
22
- --color-accent-500: #a690ea;
23
- --color-accent-600: #7d68d1;
24
- --color-accent-700: #6552b8;
25
- --color-accent-800: #46309e;
26
- --color-accent-900: #2e2170;
27
- --color-accent-950: #211741;
28
- --color-accent-base: light-dark(#5b3fc4, #a793f4);
29
- --color-status-success: light-dark(#0c6b43, #5bd295);
30
- --color-status-warning: light-dark(#7a5000, #efc05b);
31
- --color-status-danger: light-dark(#ad2f29, #f5807f);
32
- --color-status-info: light-dark(#15559e, #75c4fa);
33
18
  --color-dark-50: #f8f6f3;
34
19
  --color-dark-100: #eeece9;
35
20
  --color-dark-200: #d9d7d3;
@@ -42,6 +27,65 @@
42
27
  --color-dark-800: #2d2b28;
43
28
  --color-dark-900: #211f1c;
44
29
  --color-dark-950: #151411;
30
+ --color-violet-50: #f7f4ff;
31
+ --color-violet-200: #ede8fd;
32
+ --color-violet-300: #ded5fb;
33
+ --color-violet-400: #c4b4f5;
34
+ --color-violet-500: #a690ea;
35
+ --color-violet-600: #7d68d1;
36
+ --color-violet-700: #6552b8;
37
+ --color-violet-800: #46309e;
38
+ --color-violet-900: #2e2170;
39
+ --color-violet-950: #211741;
40
+ --color-violet-base: light-dark(#5b3fc4, #a793f4);
41
+ --color-terracotta-50: #fef4ef;
42
+ --color-terracotta-200: #fde6db;
43
+ --color-terracotta-300: #f9d2be;
44
+ --color-terracotta-400: #f1ae8c;
45
+ --color-terracotta-500: #e28655;
46
+ --color-terracotta-600: #c3590b;
47
+ --color-terracotta-700: #a44700;
48
+ --color-terracotta-800: #783100;
49
+ --color-terracotta-900: #561f00;
50
+ --color-terracotta-950: #3b1100;
51
+ --color-terracotta-base: light-dark(#974000, #ef8c56);
52
+ --color-teal-50: #ecfaf7;
53
+ --color-teal-200: #d7f2ee;
54
+ --color-teal-300: #b6e7e0;
55
+ --color-teal-400: #75d3c7;
56
+ --color-teal-500: #08baab;
57
+ --color-teal-600: #009084;
58
+ --color-teal-700: #00776d;
59
+ --color-teal-800: #00564e;
60
+ --color-teal-900: #003c36;
61
+ --color-teal-950: #002723;
62
+ --color-teal-base: light-dark(#006d64, #05c3b4);
63
+ --color-cobalt-50: #f1f7ff;
64
+ --color-cobalt-200: #e1edfe;
65
+ --color-cobalt-300: #c7ddfe;
66
+ --color-cobalt-400: #9bc2fb;
67
+ --color-cobalt-500: #6ca2f1;
68
+ --color-cobalt-600: #3b7bd7;
69
+ --color-cobalt-700: #2463bd;
70
+ --color-cobalt-800: #00449b;
71
+ --color-cobalt-900: #002d72;
72
+ --color-cobalt-950: #051f43;
73
+ --color-cobalt-base: light-dark(#0057c1, #71aafe);
74
+ --color-accent-50: var(--color-violet-50);
75
+ --color-accent-200: var(--color-violet-200);
76
+ --color-accent-300: var(--color-violet-300);
77
+ --color-accent-400: var(--color-violet-400);
78
+ --color-accent-500: var(--color-violet-500);
79
+ --color-accent-600: var(--color-violet-600);
80
+ --color-accent-700: var(--color-violet-700);
81
+ --color-accent-800: var(--color-violet-800);
82
+ --color-accent-900: var(--color-violet-900);
83
+ --color-accent-950: var(--color-violet-950);
84
+ --color-accent-base: var(--color-violet-base);
85
+ --color-status-success: light-dark(#0c6b43, #5bd295);
86
+ --color-status-warning: light-dark(#7a5000, #efc05b);
87
+ --color-status-danger: light-dark(#ad2f29, #f5807f);
88
+ --color-status-info: light-dark(#15559e, #75c4fa);
45
89
  --color-background: light-dark(var(--color-neutral-200), var(--color-dark-900));
46
90
  --color-surface: light-dark(var(--color-neutral-100), var(--color-dark-800));
47
91
  --color-elevated-surface: light-dark(var(--color-white), var(--color-dark-700));
@@ -96,6 +140,11 @@
96
140
  --color-warning-on-dark: #efc05b;
97
141
  --color-danger-on-dark: #f5807f;
98
142
  --color-info-on-dark: #75c4fa;
143
+ --color-chart-1: var(--color-violet-base);
144
+ --color-chart-2: var(--color-status-success);
145
+ --color-chart-3: var(--color-status-warning);
146
+ --color-chart-4: var(--color-status-info);
147
+ --color-chart-5: var(--color-status-danger);
99
148
  --font-heading: Inter, system-ui, sans-serif;
100
149
  --font-body: Inter, system-ui, sans-serif;
101
150
  --font-mono: JetBrains Mono, ui-monospace, monospace;
@@ -207,6 +256,125 @@
207
256
  color-scheme: dark;
208
257
  }
209
258
 
259
+ [data-accent="violet"] {
260
+ --color-accent-50: var(--color-violet-50);
261
+ --color-accent-200: var(--color-violet-200);
262
+ --color-accent-300: var(--color-violet-300);
263
+ --color-accent-400: var(--color-violet-400);
264
+ --color-accent-500: var(--color-violet-500);
265
+ --color-accent-600: var(--color-violet-600);
266
+ --color-accent-700: var(--color-violet-700);
267
+ --color-accent-800: var(--color-violet-800);
268
+ --color-accent-900: var(--color-violet-900);
269
+ --color-accent-950: var(--color-violet-950);
270
+ --color-accent-base: var(--color-violet-base);
271
+ --color-primary: light-dark(var(--color-violet-base), #684bb5);
272
+ --color-primary-hover: light-dark(var(--color-violet-800), #795dc9);
273
+ --color-primary-foreground: light-dark(var(--color-white), #f7f5fe);
274
+ --color-accent-surface: light-dark(var(--color-violet-50), #2d2843);
275
+ --color-accent-surface-hover: light-dark(var(--color-violet-200), #3a3356);
276
+ --color-selected: light-dark(var(--color-violet-300), #49406d);
277
+ }
278
+
279
+ [data-accent="terracotta"] {
280
+ --color-accent-50: var(--color-terracotta-50);
281
+ --color-accent-200: var(--color-terracotta-200);
282
+ --color-accent-300: var(--color-terracotta-300);
283
+ --color-accent-400: var(--color-terracotta-400);
284
+ --color-accent-500: var(--color-terracotta-500);
285
+ --color-accent-600: var(--color-terracotta-600);
286
+ --color-accent-700: var(--color-terracotta-700);
287
+ --color-accent-800: var(--color-terracotta-800);
288
+ --color-accent-900: var(--color-terracotta-900);
289
+ --color-accent-950: var(--color-terracotta-950);
290
+ --color-accent-base: var(--color-terracotta-base);
291
+ --color-primary: light-dark(var(--color-terracotta-base), #9f4400);
292
+ --color-primary-hover: light-dark(var(--color-terracotta-800), #b95100);
293
+ --color-primary-foreground: light-dark(var(--color-white), #fef4f0);
294
+ --color-accent-surface: light-dark(var(--color-terracotta-50), #402516);
295
+ --color-accent-surface-hover: light-dark(var(--color-terracotta-200), #532f1c);
296
+ --color-selected: light-dark(var(--color-terracotta-300), #683a22);
297
+ }
298
+
299
+ [data-accent="teal"] {
300
+ --color-accent-50: var(--color-teal-50);
301
+ --color-accent-200: var(--color-teal-200);
302
+ --color-accent-300: var(--color-teal-300);
303
+ --color-accent-400: var(--color-teal-400);
304
+ --color-accent-500: var(--color-teal-500);
305
+ --color-accent-600: var(--color-teal-600);
306
+ --color-accent-700: var(--color-teal-700);
307
+ --color-accent-800: var(--color-teal-800);
308
+ --color-accent-900: var(--color-teal-900);
309
+ --color-accent-950: var(--color-teal-950);
310
+ --color-accent-base: var(--color-teal-base);
311
+ --color-primary: light-dark(var(--color-teal-base), #00736a);
312
+ --color-primary-hover: light-dark(var(--color-teal-800), #00877c);
313
+ --color-primary-foreground: light-dark(var(--color-white), #eef9f7);
314
+ --color-accent-surface: light-dark(var(--color-teal-50), #053430);
315
+ --color-accent-surface-hover: light-dark(var(--color-teal-200), #00433d);
316
+ --color-selected: light-dark(var(--color-teal-300), #00544d);
317
+ }
318
+
319
+ [data-accent="cobalt"] {
320
+ --color-accent-50: var(--color-cobalt-50);
321
+ --color-accent-200: var(--color-cobalt-200);
322
+ --color-accent-300: var(--color-cobalt-300);
323
+ --color-accent-400: var(--color-cobalt-400);
324
+ --color-accent-500: var(--color-cobalt-500);
325
+ --color-accent-600: var(--color-cobalt-600);
326
+ --color-accent-700: var(--color-cobalt-700);
327
+ --color-accent-800: var(--color-cobalt-800);
328
+ --color-accent-900: var(--color-cobalt-900);
329
+ --color-accent-950: var(--color-cobalt-950);
330
+ --color-accent-base: var(--color-cobalt-base);
331
+ --color-primary: light-dark(var(--color-cobalt-base), #1c5fbc);
332
+ --color-primary-hover: light-dark(var(--color-cobalt-800), #2f72d0);
333
+ --color-primary-foreground: light-dark(var(--color-white), #f2f7ff);
334
+ --color-accent-surface: light-dark(var(--color-cobalt-50), #1d2d45);
335
+ --color-accent-surface-hover: light-dark(var(--color-cobalt-200), #253a59);
336
+ --color-selected: light-dark(var(--color-cobalt-300), #2d4870);
337
+ }
338
+
339
+ [data-accent="nocturne"] {
340
+ --color-accent-50: var(--color-violet-50);
341
+ --color-accent-200: var(--color-violet-200);
342
+ --color-accent-300: var(--color-violet-300);
343
+ --color-accent-400: var(--color-violet-400);
344
+ --color-accent-500: var(--color-violet-500);
345
+ --color-accent-600: var(--color-violet-600);
346
+ --color-accent-700: var(--color-violet-700);
347
+ --color-accent-800: var(--color-violet-800);
348
+ --color-accent-900: var(--color-violet-900);
349
+ --color-accent-950: var(--color-violet-950);
350
+ --color-accent-base: light-dark(#5348ab, #b4a9e6);
351
+ --color-primary: light-dark(#5f52ba, #6d5fc2);
352
+ --color-primary-hover: light-dark(var(--color-violet-800), #7e71d6);
353
+ --color-primary-foreground: light-dark(var(--color-white), #f7f5fe);
354
+ --color-accent-surface: light-dark(var(--color-violet-50), #2a2944);
355
+ --color-accent-surface-hover: light-dark(var(--color-violet-200), #373457);
356
+ --color-selected: light-dark(#ddd8f5, #372f6b);
357
+ --color-focus: light-dark(#5f52ba, #9184d9);
358
+ --color-background: light-dark(#f2f3f8, #161826);
359
+ --color-surface: light-dark(#ffffff, #232532);
360
+ --color-elevated-surface: light-dark(#ffffff, #292b31);
361
+ --color-muted: light-dark(#ebe7f0, #292b31);
362
+ --color-sidebar: light-dark(#ffffff, #0d0e1b);
363
+ --color-card: var(--color-surface);
364
+ --color-popover: var(--color-elevated-surface);
365
+ --color-foreground: light-dark(#1b1c24, #e9e9ed);
366
+ --color-muted-foreground: light-dark(#4d4954, #9a9aa6);
367
+ --color-subtle-foreground: light-dark(#6a6572, #74747f);
368
+ --color-border: light-dark(#ded9e4, #3f424d);
369
+ --color-border-strong: light-dark(#84858d, #8f919f);
370
+ --color-secondary: light-dark(#dadce5, #363743);
371
+ --color-secondary-hover: light-dark(#b1b2bb, #454752);
372
+ --color-disabled: light-dark(#b1b2bb, #454752);
373
+ --color-disabled-surface: light-dark(#f1f2f8, #292b35);
374
+ --color-skeleton: light-dark(#dadce5, #363743);
375
+ --color-hatch: light-dark(#dadce5, #363743);
376
+ }
377
+
210
378
  @media (prefers-reduced-motion: reduce) {
211
379
  :root {
212
380
  --motion-duration-fast: 0s;
@@ -19,6 +19,79 @@ export const colorNeutral800: string;
19
19
  export const colorNeutral900: string;
20
20
  /** Darkest neutral. Retained for compatibility; the dark theme's sidebar is dark.950. */
21
21
  export const colorNeutral950: string;
22
+ /** Lightest dark-ramp step. */
23
+ export const colorDark50: string;
24
+ /** Foreground on dark. Text-eligible: passes WCAG AA 4.5:1 on every dark surface. */
25
+ export const colorDark100: string;
26
+ export const colorDark200: string;
27
+ export const colorDark300: string;
28
+ /** Muted foreground on dark. */
29
+ export const colorDark400: string;
30
+ /** Half step. Strong lines and subtle text share it on dark (border-strong, subtle-foreground), as neutral.500 does for both roles on light: dark.500 misses the 3:1 non-text gate on dark.800 and dark.700. */
31
+ export const colorDark450: string;
32
+ /** Free step between the 450 split and the border pair. Not referenced by the semantic layer: 2.6:1 on dark.800 fails the 3:1 non-text gate. */
33
+ export const colorDark500: string;
34
+ /** Borders and inputs on dark. */
35
+ export const colorDark600: string;
36
+ /** Elevated surfaces, muted and secondary fills on dark. */
37
+ export const colorDark700: string;
38
+ /** Surface and card on dark. */
39
+ export const colorDark800: string;
40
+ /** Background on dark. */
41
+ export const colorDark900: string;
42
+ /** Darkest step. Sidebar on dark, and danger-foreground on a danger fill. */
43
+ export const colorDark950: string;
44
+ /** Lightest lilac. Light-theme tinted surface (row hover, ghost hover). */
45
+ export const colorViolet50: string;
46
+ export const colorViolet200: string;
47
+ export const colorViolet300: string;
48
+ export const colorViolet400: string;
49
+ /** Mid lilac. Closes the ramp between 400 and 600; accent.base stays the mode-aware base. */
50
+ export const colorViolet500: string;
51
+ export const colorViolet600: string;
52
+ export const colorViolet700: string;
53
+ export const colorViolet800: string;
54
+ export const colorViolet900: string;
55
+ /** Darkest lilac. Retained ramp step; the dark accent tints are dedicated literals on the semantic layer. */
56
+ export const colorViolet950: string;
57
+ /** Base accent primitive and the theme ink: deeper violet on light (6.36:1 on background), light lilac on dark (6.36:1 on background, 5.5:1 on surface). Flows into link and focus; the deep fill role lives on semantic.primary. */
58
+ export const colorVioletBase: string;
59
+ export const colorTerracotta50: string;
60
+ export const colorTerracotta200: string;
61
+ export const colorTerracotta300: string;
62
+ export const colorTerracotta400: string;
63
+ export const colorTerracotta500: string;
64
+ export const colorTerracotta600: string;
65
+ export const colorTerracotta700: string;
66
+ export const colorTerracotta800: string;
67
+ export const colorTerracotta900: string;
68
+ export const colorTerracotta950: string;
69
+ /** The terracotta ink: text-eligible in both themes. */
70
+ export const colorTerracottaBase: string;
71
+ export const colorTeal50: string;
72
+ export const colorTeal200: string;
73
+ export const colorTeal300: string;
74
+ export const colorTeal400: string;
75
+ export const colorTeal500: string;
76
+ export const colorTeal600: string;
77
+ export const colorTeal700: string;
78
+ export const colorTeal800: string;
79
+ export const colorTeal900: string;
80
+ export const colorTeal950: string;
81
+ /** The teal ink: text-eligible in both themes. */
82
+ export const colorTealBase: string;
83
+ export const colorCobalt50: string;
84
+ export const colorCobalt200: string;
85
+ export const colorCobalt300: string;
86
+ export const colorCobalt400: string;
87
+ export const colorCobalt500: string;
88
+ export const colorCobalt600: string;
89
+ export const colorCobalt700: string;
90
+ export const colorCobalt800: string;
91
+ export const colorCobalt900: string;
92
+ export const colorCobalt950: string;
93
+ /** The cobalt ink: text-eligible in both themes. */
94
+ export const colorCobaltBase: string;
22
95
  /** Lightest lilac. Light-theme tinted surface (row hover, ghost hover). */
23
96
  export const colorAccent50: string;
24
97
  export const colorAccent200: string;
@@ -42,28 +115,6 @@ export const colorStatusWarning: string;
42
115
  export const colorStatusDanger: string;
43
116
  /** Info status primitive. */
44
117
  export const colorStatusInfo: string;
45
- /** Lightest dark-ramp step. */
46
- export const colorDark50: string;
47
- /** Foreground on dark. Text-eligible: passes WCAG AA 4.5:1 on every dark surface. */
48
- export const colorDark100: string;
49
- export const colorDark200: string;
50
- export const colorDark300: string;
51
- /** Muted foreground on dark. */
52
- export const colorDark400: string;
53
- /** Half step. Strong lines and subtle text share it on dark (border-strong, subtle-foreground), as neutral.500 does for both roles on light: dark.500 misses the 3:1 non-text gate on dark.800 and dark.700. */
54
- export const colorDark450: string;
55
- /** Free step between the 450 split and the border pair. Not referenced by the semantic layer: 2.6:1 on dark.800 fails the 3:1 non-text gate. */
56
- export const colorDark500: string;
57
- /** Borders and inputs on dark. */
58
- export const colorDark600: string;
59
- /** Elevated surfaces, muted and secondary fills on dark. */
60
- export const colorDark700: string;
61
- /** Surface and card on dark. */
62
- export const colorDark800: string;
63
- /** Background on dark. */
64
- export const colorDark900: string;
65
- /** Darkest step. Sidebar on dark, and danger-foreground on a danger fill. */
66
- export const colorDark950: string;
67
118
  /** App canvas. Surface role, never text. */
68
119
  export const semanticBackground: string;
69
120
  /** Cards, panels, table rows. Surface role. */
@@ -172,6 +223,126 @@ export const semanticWarningOnDark: string;
172
223
  export const semanticDangerOnDark: string;
173
224
  /** Info on a permanently dark surface (log view, terminal). Theme-invariant on purpose: the surface does not follow color-scheme, so neither can the text. */
174
225
  export const semanticInfoOnDark: string;
226
+ /** Categorical chart series 1. Identity only, never status. Pair with its numbered label, interactive highlighting, and exact values. Pinned to the violet ink: chart series do not follow the accent, so the palette stays distinguishable from the status series under every accent. */
227
+ export const semanticChart1: string;
228
+ /** Categorical chart series 2. Identity only, never status. Pair with its numbered label, interactive highlighting, and exact values. */
229
+ export const semanticChart2: string;
230
+ /** Categorical chart series 3. Identity only, never status. Pair with its numbered label, interactive highlighting, and exact values. */
231
+ export const semanticChart3: string;
232
+ /** Categorical chart series 4. Identity only, never status. Pair with its numbered label, interactive highlighting, and exact values. */
233
+ export const semanticChart4: string;
234
+ /** Categorical chart series 5. Identity only, never status. Pair with its numbered label, interactive highlighting, and exact values. */
235
+ export const semanticChart5: string;
236
+ export const accentVioletAccent50: string;
237
+ export const accentVioletAccent200: string;
238
+ export const accentVioletAccent300: string;
239
+ export const accentVioletAccent400: string;
240
+ export const accentVioletAccent500: string;
241
+ export const accentVioletAccent600: string;
242
+ export const accentVioletAccent700: string;
243
+ export const accentVioletAccent800: string;
244
+ export const accentVioletAccent900: string;
245
+ export const accentVioletAccent950: string;
246
+ export const accentVioletAccentBase: string;
247
+ /** The primary fill. Light: the ink. Dark: a deeper fill that is not text-eligible. */
248
+ export const accentVioletPrimary: string;
249
+ export const accentVioletPrimaryHover: string;
250
+ export const accentVioletPrimaryForeground: string;
251
+ export const accentVioletAccentSurface: string;
252
+ export const accentVioletAccentSurfaceHover: string;
253
+ export const accentVioletSelected: string;
254
+ export const accentTerracottaAccent50: string;
255
+ export const accentTerracottaAccent200: string;
256
+ export const accentTerracottaAccent300: string;
257
+ export const accentTerracottaAccent400: string;
258
+ export const accentTerracottaAccent500: string;
259
+ export const accentTerracottaAccent600: string;
260
+ export const accentTerracottaAccent700: string;
261
+ export const accentTerracottaAccent800: string;
262
+ export const accentTerracottaAccent900: string;
263
+ export const accentTerracottaAccent950: string;
264
+ export const accentTerracottaAccentBase: string;
265
+ /** The primary fill. Light: the ink. Dark: a deeper fill that is not text-eligible. */
266
+ export const accentTerracottaPrimary: string;
267
+ export const accentTerracottaPrimaryHover: string;
268
+ export const accentTerracottaPrimaryForeground: string;
269
+ export const accentTerracottaAccentSurface: string;
270
+ export const accentTerracottaAccentSurfaceHover: string;
271
+ export const accentTerracottaSelected: string;
272
+ export const accentTealAccent50: string;
273
+ export const accentTealAccent200: string;
274
+ export const accentTealAccent300: string;
275
+ export const accentTealAccent400: string;
276
+ export const accentTealAccent500: string;
277
+ export const accentTealAccent600: string;
278
+ export const accentTealAccent700: string;
279
+ export const accentTealAccent800: string;
280
+ export const accentTealAccent900: string;
281
+ export const accentTealAccent950: string;
282
+ export const accentTealAccentBase: string;
283
+ /** The primary fill. Light: the ink. Dark: a deeper fill that is not text-eligible. */
284
+ export const accentTealPrimary: string;
285
+ export const accentTealPrimaryHover: string;
286
+ export const accentTealPrimaryForeground: string;
287
+ export const accentTealAccentSurface: string;
288
+ export const accentTealAccentSurfaceHover: string;
289
+ export const accentTealSelected: string;
290
+ export const accentCobaltAccent50: string;
291
+ export const accentCobaltAccent200: string;
292
+ export const accentCobaltAccent300: string;
293
+ export const accentCobaltAccent400: string;
294
+ export const accentCobaltAccent500: string;
295
+ export const accentCobaltAccent600: string;
296
+ export const accentCobaltAccent700: string;
297
+ export const accentCobaltAccent800: string;
298
+ export const accentCobaltAccent900: string;
299
+ export const accentCobaltAccent950: string;
300
+ export const accentCobaltAccentBase: string;
301
+ /** The primary fill. Light: the ink. Dark: a deeper fill that is not text-eligible. */
302
+ export const accentCobaltPrimary: string;
303
+ export const accentCobaltPrimaryHover: string;
304
+ export const accentCobaltPrimaryForeground: string;
305
+ export const accentCobaltAccentSurface: string;
306
+ export const accentCobaltAccentSurfaceHover: string;
307
+ export const accentCobaltSelected: string;
308
+ export const accentNocturneAccent50: string;
309
+ export const accentNocturneAccent200: string;
310
+ export const accentNocturneAccent300: string;
311
+ export const accentNocturneAccent400: string;
312
+ export const accentNocturneAccent500: string;
313
+ export const accentNocturneAccent600: string;
314
+ export const accentNocturneAccent700: string;
315
+ export const accentNocturneAccent800: string;
316
+ export const accentNocturneAccent900: string;
317
+ export const accentNocturneAccent950: string;
318
+ /** The nocturne ink: the site's link colour, text-eligible in both themes. */
319
+ export const accentNocturneAccentBase: string;
320
+ /** The site's primary fill. */
321
+ export const accentNocturnePrimary: string;
322
+ export const accentNocturnePrimaryHover: string;
323
+ export const accentNocturnePrimaryForeground: string;
324
+ export const accentNocturneAccentSurface: string;
325
+ export const accentNocturneAccentSurfaceHover: string;
326
+ export const accentNocturneSelected: string;
327
+ export const accentNocturneFocus: string;
328
+ export const accentNocturneBackground: string;
329
+ export const accentNocturneSurface: string;
330
+ export const accentNocturneElevatedSurface: string;
331
+ export const accentNocturneMuted: string;
332
+ export const accentNocturneSidebar: string;
333
+ export const accentNocturneCard: string;
334
+ export const accentNocturnePopover: string;
335
+ export const accentNocturneForeground: string;
336
+ export const accentNocturneMutedForeground: string;
337
+ export const accentNocturneSubtleForeground: string;
338
+ export const accentNocturneBorder: string;
339
+ export const accentNocturneBorderStrong: string;
340
+ export const accentNocturneSecondary: string;
341
+ export const accentNocturneSecondaryHover: string;
342
+ export const accentNocturneDisabled: string;
343
+ export const accentNocturneDisabledSurface: string;
344
+ export const accentNocturneSkeleton: string;
345
+ export const accentNocturneHatch: string;
175
346
  /** Heading family. Inter, same as body; headings differentiate by size and weight. */
176
347
  export const fontHeading: string;
177
348
  /** Body family. Inter for interface text. */