tyrell-components 1.0.0-TC41 → 1.0.0-TC42

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.
@@ -108,7 +108,6 @@
108
108
  * Bump to ~0.005 (light) / ~0.012 (dark) to warm surfaces toward brand. */
109
109
  --ty-surface-chroma: 0;
110
110
 
111
-
112
111
  /* ----------------------------------------------------------------
113
112
  * Tier 2 — PER-FLAVOR ANCHORS
114
113
  * Semantic colors (success/warning/danger/neutral) have their own
@@ -118,7 +117,6 @@
118
117
  * --ty-warning-chroma: 0.2; (more vivid)
119
118
  * --------------------------------------------------------------*/
120
119
 
121
-
122
120
  --ty-success-hue: 145;
123
121
  --ty-success-chroma: calc(var(--ty-brand-chroma) * 1.08);
124
122
 
@@ -192,6 +190,11 @@
192
190
  --ty-l-surface-input: 1;
193
191
 
194
192
  --ty-l-solid-neutral: 0.4; /* the neutral "ink" fill — dark in BOTH modes */
193
+ /* neutral+ is FULL-CONTRAST ink — near-black on light, near-white on dark
194
+ (mode block below) — not "anchor + shared offset" like other tones: the
195
+ max-emphasis monochrome button is an absolute, not a nudge. Matches the
196
+ static tyrell.css light value (#000) that predates this dial. */
197
+ --ty-l-solid-neutral-strong: 0.15;
195
198
  --ty-l-bg-neutral-strong: 0.25; /* opposes the mode: dark bg on light page */
196
199
  --ty-l-bg-neutral-faint: 0.99; /* follows the mode */
197
200
  --ty-c-bg-neutral-faint-mult: 0.4;
@@ -264,6 +267,17 @@
264
267
  --ty-solid-l: 0; /* lightness offset — negative dims */
265
268
  --ty-solid-c: 1; /* chroma multiplier — <1 desaturates */
266
269
  --ty-solid-h: 0; /* hue offset (deg) */
270
+
271
+ /* Axis C — per-flavor solid anchor lift (added to the base fill's L,
272
+ * tones/hover/active then derive from the lifted anchor). The solid
273
+ * ladder's "darker = stronger" is FALSE for the yellow family: darkened
274
+ * hue-75 is brown, so warning's whole ladder shifts UP instead — soft
275
+ * 0.82 pale amber, base 0.72 vivid orange, strong 0.66 deep orange, all
276
+ * black-text (Material treats amber the same way). Other flavors: 0. */
277
+ --ty-primary-solid-l: 0;
278
+ --ty-success-solid-l: 0;
279
+ --ty-warning-solid-l: 0.1;
280
+ --ty-danger-solid-l: 0;
267
281
  }
268
282
 
269
283
  /* Dark mode overrides for the L-curve and saturation curve. Tier 1 + 2
@@ -310,7 +324,8 @@ html[data-theme="dark"],
310
324
  --ty-l-surface-floating: 0.22;
311
325
  --ty-l-surface-input: 0.18;
312
326
 
313
- --ty-l-solid-neutral: 0.23;
327
+ --ty-l-solid-neutral: 0.18;
328
+ --ty-l-solid-neutral-strong: 0.88; /* inverted ink: white button, black text */
314
329
  --ty-l-bg-neutral-strong: 0.95;
315
330
  --ty-l-bg-neutral-faint: 0.15;
316
331
  --ty-c-bg-neutral-faint-mult: 2;
@@ -335,14 +350,21 @@ html[data-theme="dark"],
335
350
  /* Tier 6 dark — interaction offsets flip sign (press LIGHTENS on dark),
336
351
  * and the per-theme adjust dims + desaturates the fills against the
337
352
  * dark canvas. (Computed solid tokens are declared once at html:root.) */
338
- --ty-solid-hover-l: 0.04; /* :hover */
339
- --ty-solid-active-l: 0.08; /* :active */
353
+ /* Bigger than light mode's 0.04/0.08: small L deltas at the dark end of
354
+ * an emissive screen read much weaker than the same delta mid-scale, so
355
+ * dark hover needs more push to be felt at all. */
356
+ --ty-solid-hover-l: 0.07; /* :hover */
357
+ --ty-solid-active-l: 0.11; /* :active */
340
358
  --ty-solid-strong-l: 0.06; /* tone+ */
341
359
  --ty-solid-soft-l: -0.1; /* tone- */
342
360
 
343
361
  --ty-solid-l: -0.2; /* dim against dark canvas */
344
362
  --ty-solid-c: 0.7; /* desaturate against dark canvas */
345
363
  --ty-solid-h: 0; /* hue offset */
364
+
365
+ /* Axis C — dark warning fills are already dim enough not to brown out
366
+ * (and browns read intentional on dark); no lift needed. */
367
+ --ty-warning-solid-l: 0;
346
368
  }
347
369
 
348
370
  /* =====================================================================
@@ -756,19 +778,23 @@ html:root,
756
778
  [data-ty-theme] {
757
779
  /* base fill per flavor (= flavor color, theme-adjusted by Axis B) */
758
780
  --ty-solid-primary: oklch(
759
- from var(--ty-color-primary) calc(l + var(--ty-solid-l))
781
+ from var(--ty-color-primary)
782
+ calc(l + var(--ty-solid-l) + var(--ty-primary-solid-l, 0))
760
783
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
761
784
  );
762
785
  --ty-solid-success: oklch(
763
- from var(--ty-color-success) calc(l + var(--ty-solid-l))
786
+ from var(--ty-color-success)
787
+ calc(l + var(--ty-solid-l) + var(--ty-success-solid-l, 0))
764
788
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
765
789
  );
766
790
  --ty-solid-danger: oklch(
767
- from var(--ty-color-danger) calc(l + var(--ty-solid-l))
791
+ from var(--ty-color-danger)
792
+ calc(l + var(--ty-solid-l) + var(--ty-danger-solid-l, 0))
768
793
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
769
794
  );
770
795
  --ty-solid-warning: oklch(
771
- from var(--ty-color-warning) calc(l + var(--ty-solid-l))
796
+ from var(--ty-color-warning)
797
+ calc(l + var(--ty-solid-l) + var(--ty-warning-solid-l, 0))
772
798
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
773
799
  );
774
800
  /* neutral is a deliberate dark grey fill, not the neutral text color */
@@ -814,7 +840,6 @@ html:root,
814
840
  clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
815
841
  );
816
842
 
817
-
818
843
  --ty-solid-success-fg: oklch(
819
844
  from var(--ty-solid-success)
820
845
  clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
@@ -881,7 +906,6 @@ html:root,
881
906
  from var(--ty-solid-primary) calc(l + var(--ty-solid-soft-l)) c h
882
907
  );
883
908
 
884
-
885
909
  --ty-solid-success-hover: oklch(
886
910
  from var(--ty-solid-success) calc(l + var(--ty-solid-hover-l)) c h
887
911
  );
@@ -927,15 +951,17 @@ html:root,
927
951
  --ty-solid-neutral-active: oklch(
928
952
  from var(--ty-solid-neutral) calc(l + var(--ty-solid-active-l)) c h
929
953
  );
954
+ /* neutral+ reads its own absolute L dial, not anchor + shared offset —
955
+ it's the full-contrast ink endpoint (see --ty-l-solid-neutral-strong). */
930
956
  --ty-solid-neutral-strong: oklch(
931
- from var(--ty-solid-neutral) calc(l + var(--ty-solid-strong-l)) c h
957
+ from var(--ty-neutral-seed-resolved) var(--ty-l-solid-neutral-strong)
958
+ calc(c * var(--ty-c-strong-mult)) h
932
959
  );
933
960
  --ty-solid-neutral-soft: oklch(
934
961
  from var(--ty-solid-neutral) calc(l + var(--ty-solid-soft-l)) c h
935
962
  );
936
963
  }
937
964
 
938
-
939
965
  /* =====================================================================
940
966
  * SECTION 3 — THEME TRANSITIONS
941
967
  * =====================================================================
@@ -1148,6 +1174,11 @@ html:root,
1148
1174
  inherits: true;
1149
1175
  initial-value: 0.4;
1150
1176
  }
1177
+ @property --ty-l-solid-neutral-strong {
1178
+ syntax: "<number>";
1179
+ inherits: true;
1180
+ initial-value: 0.15;
1181
+ }
1151
1182
  @property --ty-l-bg-neutral-strong {
1152
1183
  syntax: "<number>";
1153
1184
  inherits: true;
@@ -1228,6 +1259,55 @@ html:root,
1228
1259
  inherits: true;
1229
1260
  initial-value: 1;
1230
1261
  }
1262
+ /* Typography + button-depth dials (defined in tyrell.css, mode-flipped
1263
+ there). Registered here so they interpolate on theme switch: with a
1264
+ variable font, text weight crossfades along with the colors, and the
1265
+ solid-button depth chrome (border offset) glides rather than snaps. */
1266
+ @property --ty-weight-action {
1267
+ syntax: "<number>";
1268
+ inherits: true;
1269
+ initial-value: 510;
1270
+ }
1271
+ @property --ty-weight-label {
1272
+ syntax: "<number>";
1273
+ inherits: true;
1274
+ initial-value: 440;
1275
+ }
1276
+ @property --ty-button-depth {
1277
+ syntax: "<number>";
1278
+ inherits: true;
1279
+ initial-value: 0.35;
1280
+ }
1281
+ @property --ty-button-border-l {
1282
+ syntax: "<number>";
1283
+ inherits: true;
1284
+ initial-value: -0.08;
1285
+ }
1286
+ @property --ty-button-border-l-neutral {
1287
+ syntax: "<number>";
1288
+ inherits: true;
1289
+ initial-value: -0.25;
1290
+ }
1291
+ @property --ty-primary-solid-l {
1292
+ syntax: "<number>";
1293
+ inherits: true;
1294
+ initial-value: 0;
1295
+ }
1296
+ @property --ty-success-solid-l {
1297
+ syntax: "<number>";
1298
+ inherits: true;
1299
+ initial-value: 0;
1300
+ }
1301
+ @property --ty-warning-solid-l {
1302
+ syntax: "<number>";
1303
+ inherits: true;
1304
+ initial-value: 0.1;
1305
+ }
1306
+ @property --ty-danger-solid-l {
1307
+ syntax: "<number>";
1308
+ inherits: true;
1309
+ initial-value: 0;
1310
+ }
1231
1311
  @property --ty-solid-hover-l {
1232
1312
  syntax: "<number>";
1233
1313
  inherits: true;
@@ -1304,69 +1384,29 @@ html:root,
1304
1384
  html,
1305
1385
  [data-ty-theme] {
1306
1386
  transition-property:
1307
- --ty-brand-hue,
1308
- --ty-brand-chroma,
1309
- --ty-surface-chroma,
1310
- --ty-success-hue,
1311
- --ty-success-chroma,
1312
- --ty-warning-hue,
1313
- --ty-warning-chroma,
1314
- --ty-danger-hue,
1315
- --ty-danger-chroma,
1316
- --ty-neutral-hue,
1317
- --ty-neutral-chroma,
1318
- --ty-l-strong,
1319
- --ty-l-bold,
1320
- --ty-l-base,
1321
- --ty-l-soft,
1322
- --ty-l-faint,
1323
- --ty-l-bg-base,
1324
- --ty-l-bg-bold,
1325
- --ty-l-bg-soft,
1326
- --ty-l-text-strong,
1327
- --ty-l-text-bold,
1328
- --ty-l-text-base,
1329
- --ty-l-text-soft,
1330
- --ty-l-text-faint,
1331
- --ty-l-border-content,
1332
- --ty-l-border-elevated,
1333
- --ty-l-border-floating,
1334
- --ty-l-border-strong,
1335
- --ty-l-border-bold,
1336
- --ty-l-border,
1337
- --ty-l-border-soft,
1338
- --ty-l-border-faint,
1339
- --ty-l-surface-canvas,
1340
- --ty-l-surface-content,
1341
- --ty-l-surface-elevated,
1342
- --ty-l-surface-floating,
1343
- --ty-l-surface-input,
1344
- --ty-l-solid-neutral,
1345
- --ty-l-bg-neutral-strong,
1346
- --ty-l-bg-neutral-faint,
1347
- --ty-c-bg-neutral-faint-mult,
1348
- --ty-c-strong-mult,
1349
- --ty-c-bold-mult,
1350
- --ty-c-base-mult,
1351
- --ty-c-soft-mult,
1352
- --ty-c-faint-mult,
1353
- --ty-c-bg-base-mult,
1354
- --ty-c-bg-bold-mult,
1355
- --ty-c-bg-soft-mult,
1356
- --ty-primary-l-factor,
1357
- --ty-success-l-factor,
1358
- --ty-warning-l-factor,
1359
- --ty-danger-l-factor,
1360
- --ty-neutral-l-factor,
1361
- --ty-solid-hover-l,
1362
- --ty-solid-active-l,
1363
- --ty-solid-strong-l,
1364
- --ty-solid-soft-l,
1365
- --ty-solid-l,
1366
- --ty-solid-c,
1367
- --ty-solid-h,
1368
- --ty-solid-fg-threshold,
1369
- --ty-focus-ring-alpha;
1387
+ --ty-brand-hue, --ty-brand-chroma, --ty-surface-chroma, --ty-success-hue,
1388
+ --ty-success-chroma, --ty-warning-hue, --ty-warning-chroma,
1389
+ --ty-danger-hue, --ty-danger-chroma, --ty-neutral-hue,
1390
+ --ty-neutral-chroma, --ty-l-strong, --ty-l-bold, --ty-l-base, --ty-l-soft,
1391
+ --ty-l-faint, --ty-l-bg-base, --ty-l-bg-bold, --ty-l-bg-soft,
1392
+ --ty-l-text-strong, --ty-l-text-bold, --ty-l-text-base, --ty-l-text-soft,
1393
+ --ty-l-text-faint, --ty-l-border-content, --ty-l-border-elevated,
1394
+ --ty-l-border-floating, --ty-l-border-strong, --ty-l-border-bold,
1395
+ --ty-l-border, --ty-l-border-soft, --ty-l-border-faint,
1396
+ --ty-l-surface-canvas, --ty-l-surface-content, --ty-l-surface-elevated,
1397
+ --ty-l-surface-floating, --ty-l-surface-input, --ty-l-solid-neutral,
1398
+ --ty-l-solid-neutral-strong, --ty-l-bg-neutral-strong,
1399
+ --ty-l-bg-neutral-faint, --ty-c-bg-neutral-faint-mult, --ty-c-strong-mult,
1400
+ --ty-c-bold-mult, --ty-c-base-mult, --ty-c-soft-mult, --ty-c-faint-mult,
1401
+ --ty-c-bg-base-mult, --ty-c-bg-bold-mult, --ty-c-bg-soft-mult,
1402
+ --ty-primary-l-factor, --ty-success-l-factor, --ty-warning-l-factor,
1403
+ --ty-danger-l-factor, --ty-neutral-l-factor, --ty-primary-solid-l,
1404
+ --ty-success-solid-l, --ty-warning-solid-l, --ty-danger-solid-l,
1405
+ --ty-solid-hover-l, --ty-solid-active-l, --ty-solid-strong-l,
1406
+ --ty-solid-soft-l, --ty-solid-l, --ty-solid-c, --ty-solid-h,
1407
+ --ty-solid-fg-threshold, --ty-focus-ring-alpha, --ty-weight-action,
1408
+ --ty-weight-label, --ty-button-depth, --ty-button-border-l,
1409
+ --ty-button-border-l-neutral;
1370
1410
  transition-duration: var(--ty-theme-transition, 0.45s);
1371
1411
  transition-timing-function: ease;
1372
1412
  }
package/css/tyrell.css CHANGED
@@ -499,6 +499,39 @@ DESIGN SYSTEM TOKENS
499
499
  --ty-font-bold: 680;
500
500
  --ty-font-extrabold: 800;
501
501
 
502
+ /* Semantic weight dials — MODE-FLIPPED (see the html.dark block).
503
+ Light text on dark surfaces optically blooms (halation), so dark mode
504
+ wants genuinely lighter weights than light mode; a single fixed weight
505
+ can't be right in both. Components consume these instead of the raw
506
+ scale above:
507
+ --ty-weight-action buttons, interactive chrome
508
+ --ty-weight-label tags, chips, badges
509
+ Theme these like any other token — per :root, html.dark, a named theme
510
+ pack, or one element. The theme layer registers them as typed numbers,
511
+ so with a variable font, weight crossfades during theme transitions
512
+ along with the colors. */
513
+ --ty-weight-action: var(--ty-font-medium);
514
+ --ty-weight-label: 440;
515
+
516
+ /* Solid-button depth chrome (consumed in button.ts):
517
+ --ty-button-depth master intensity 0–1. 0 = pixel-flat (the old
518
+ look), 1 = full tactile gloss. Scales the
519
+ derived border offset, top sheen and drop
520
+ shadow together. Themable per mode / theme
521
+ pack / element like any other dial.
522
+ --ty-button-border-l L-offset of the fill-derived 1px border,
523
+ mode-flipped below: dark mode needs a LIGHTER-
524
+ than-fill hairline (solids wash out against
525
+ dark surfaces without a lit edge), light mode
526
+ a slightly darker one. */
527
+ --ty-button-depth: 0.35;
528
+ --ty-button-border-l: -0.08;
529
+ /* Neutral (ink) gets its own, stronger edge: it has no hue separating it
530
+ from the canvas, so the same offset that reads fine on colored fills
531
+ nearly vanishes on it — especially in dark mode, where the ink fill
532
+ sits close to the page. */
533
+ --ty-button-border-l-neutral: -0.25;
534
+
502
535
  --ty-line-height-none: 1;
503
536
  --ty-line-height-tight: 1.25;
504
537
  --ty-line-height-snug: 1.375;
@@ -608,6 +641,21 @@ html[data-theme="dark"] {
608
641
  Emphasis logic inverts: lighter = more emphasis
609
642
  ================================================================= */
610
643
 
644
+ /* Weight dials flip with the mode — light-on-dark text blooms, so dark
645
+ mode runs genuinely lighter. See the :root definitions. */
646
+ --ty-weight-action: var(--ty-font-normal);
647
+ --ty-weight-label: var(--ty-font-normal);
648
+
649
+ /* Colored solid buttons: no border in dark mode — border color equals
650
+ the fill exactly, so it's geometrically present (depth 0 keeps
651
+ geometry stable) but invisible. Neutral keeps its own separate,
652
+ stronger dial (below) since its dark ink fill needs the lit edge to
653
+ read as a shape at all against a near-black canvas; colored fills
654
+ don't have that problem (their own hue/saturation already separates
655
+ them from the page), so no border reads as cleaner. */
656
+ --ty-button-border-l: 0;
657
+ --ty-button-border-l-neutral: 0.5;
658
+
611
659
  /* Primary */
612
660
  --ty-color-primary-strong: #9cbde5;
613
661
  --ty-color-primary-bold: #6c9bd5;
@@ -763,12 +811,17 @@ Emphasis logic inverts: lighter = more emphasis
763
811
  --ty-solid-warning-soft-fg: white;
764
812
 
765
813
  --ty-solid-neutral: #414141;
766
- --ty-solid-neutral-strong: #4c4c4c;
814
+ /* neutral+ = inverted ink (white button, black text) — the dark-mode
815
+ mirror of light's #000. Max-emphasis monochrome CTA (Geist-style).
816
+ hover/active are pinned to the OLD strong literal, not the alias:
817
+ aliasing var(--ty-solid-neutral-strong) would flash the BASE button
818
+ white on hover. */
819
+ --ty-solid-neutral-strong: #f5f5f5;
767
820
  --ty-solid-neutral-soft: #2a2a2a;
768
- --ty-solid-neutral-hover: var(--ty-solid-neutral-strong);
769
- --ty-solid-neutral-active: var(--ty-solid-neutral-strong);
821
+ --ty-solid-neutral-hover: #4c4c4c;
822
+ --ty-solid-neutral-active: #4c4c4c;
770
823
  --ty-solid-neutral-fg: white;
771
- --ty-solid-neutral-strong-fg: white;
824
+ --ty-solid-neutral-strong-fg: black;
772
825
  --ty-solid-neutral-soft-fg: white;
773
826
 
774
827
  /* Input component tokens - dark mode */
@@ -108,7 +108,6 @@
108
108
  * Bump to ~0.005 (light) / ~0.012 (dark) to warm surfaces toward brand. */
109
109
  --ty-surface-chroma: 0;
110
110
 
111
-
112
111
  /* ----------------------------------------------------------------
113
112
  * Tier 2 — PER-FLAVOR ANCHORS
114
113
  * Semantic colors (success/warning/danger/neutral) have their own
@@ -118,7 +117,6 @@
118
117
  * --ty-warning-chroma: 0.2; (more vivid)
119
118
  * --------------------------------------------------------------*/
120
119
 
121
-
122
120
  --ty-success-hue: 145;
123
121
  --ty-success-chroma: calc(var(--ty-brand-chroma) * 1.08);
124
122
 
@@ -192,6 +190,11 @@
192
190
  --ty-l-surface-input: 1;
193
191
 
194
192
  --ty-l-solid-neutral: 0.4; /* the neutral "ink" fill — dark in BOTH modes */
193
+ /* neutral+ is FULL-CONTRAST ink — near-black on light, near-white on dark
194
+ (mode block below) — not "anchor + shared offset" like other tones: the
195
+ max-emphasis monochrome button is an absolute, not a nudge. Matches the
196
+ static tyrell.css light value (#000) that predates this dial. */
197
+ --ty-l-solid-neutral-strong: 0.15;
195
198
  --ty-l-bg-neutral-strong: 0.25; /* opposes the mode: dark bg on light page */
196
199
  --ty-l-bg-neutral-faint: 0.99; /* follows the mode */
197
200
  --ty-c-bg-neutral-faint-mult: 0.4;
@@ -264,6 +267,17 @@
264
267
  --ty-solid-l: 0; /* lightness offset — negative dims */
265
268
  --ty-solid-c: 1; /* chroma multiplier — <1 desaturates */
266
269
  --ty-solid-h: 0; /* hue offset (deg) */
270
+
271
+ /* Axis C — per-flavor solid anchor lift (added to the base fill's L,
272
+ * tones/hover/active then derive from the lifted anchor). The solid
273
+ * ladder's "darker = stronger" is FALSE for the yellow family: darkened
274
+ * hue-75 is brown, so warning's whole ladder shifts UP instead — soft
275
+ * 0.82 pale amber, base 0.72 vivid orange, strong 0.66 deep orange, all
276
+ * black-text (Material treats amber the same way). Other flavors: 0. */
277
+ --ty-primary-solid-l: 0;
278
+ --ty-success-solid-l: 0;
279
+ --ty-warning-solid-l: 0.1;
280
+ --ty-danger-solid-l: 0;
267
281
  }
268
282
 
269
283
  /* Dark mode overrides for the L-curve and saturation curve. Tier 1 + 2
@@ -310,7 +324,8 @@ html[data-theme="dark"],
310
324
  --ty-l-surface-floating: 0.22;
311
325
  --ty-l-surface-input: 0.18;
312
326
 
313
- --ty-l-solid-neutral: 0.23;
327
+ --ty-l-solid-neutral: 0.18;
328
+ --ty-l-solid-neutral-strong: 0.88; /* inverted ink: white button, black text */
314
329
  --ty-l-bg-neutral-strong: 0.95;
315
330
  --ty-l-bg-neutral-faint: 0.15;
316
331
  --ty-c-bg-neutral-faint-mult: 2;
@@ -335,14 +350,21 @@ html[data-theme="dark"],
335
350
  /* Tier 6 dark — interaction offsets flip sign (press LIGHTENS on dark),
336
351
  * and the per-theme adjust dims + desaturates the fills against the
337
352
  * dark canvas. (Computed solid tokens are declared once at html:root.) */
338
- --ty-solid-hover-l: 0.04; /* :hover */
339
- --ty-solid-active-l: 0.08; /* :active */
353
+ /* Bigger than light mode's 0.04/0.08: small L deltas at the dark end of
354
+ * an emissive screen read much weaker than the same delta mid-scale, so
355
+ * dark hover needs more push to be felt at all. */
356
+ --ty-solid-hover-l: 0.07; /* :hover */
357
+ --ty-solid-active-l: 0.11; /* :active */
340
358
  --ty-solid-strong-l: 0.06; /* tone+ */
341
359
  --ty-solid-soft-l: -0.1; /* tone- */
342
360
 
343
361
  --ty-solid-l: -0.2; /* dim against dark canvas */
344
362
  --ty-solid-c: 0.7; /* desaturate against dark canvas */
345
363
  --ty-solid-h: 0; /* hue offset */
364
+
365
+ /* Axis C — dark warning fills are already dim enough not to brown out
366
+ * (and browns read intentional on dark); no lift needed. */
367
+ --ty-warning-solid-l: 0;
346
368
  }
347
369
 
348
370
  /* =====================================================================
@@ -756,19 +778,23 @@ html:root,
756
778
  [data-ty-theme] {
757
779
  /* base fill per flavor (= flavor color, theme-adjusted by Axis B) */
758
780
  --ty-solid-primary: oklch(
759
- from var(--ty-color-primary) calc(l + var(--ty-solid-l))
781
+ from var(--ty-color-primary)
782
+ calc(l + var(--ty-solid-l) + var(--ty-primary-solid-l, 0))
760
783
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
761
784
  );
762
785
  --ty-solid-success: oklch(
763
- from var(--ty-color-success) calc(l + var(--ty-solid-l))
786
+ from var(--ty-color-success)
787
+ calc(l + var(--ty-solid-l) + var(--ty-success-solid-l, 0))
764
788
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
765
789
  );
766
790
  --ty-solid-danger: oklch(
767
- from var(--ty-color-danger) calc(l + var(--ty-solid-l))
791
+ from var(--ty-color-danger)
792
+ calc(l + var(--ty-solid-l) + var(--ty-danger-solid-l, 0))
768
793
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
769
794
  );
770
795
  --ty-solid-warning: oklch(
771
- from var(--ty-color-warning) calc(l + var(--ty-solid-l))
796
+ from var(--ty-color-warning)
797
+ calc(l + var(--ty-solid-l) + var(--ty-warning-solid-l, 0))
772
798
  calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
773
799
  );
774
800
  /* neutral is a deliberate dark grey fill, not the neutral text color */
@@ -814,7 +840,6 @@ html:root,
814
840
  clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
815
841
  );
816
842
 
817
-
818
843
  --ty-solid-success-fg: oklch(
819
844
  from var(--ty-solid-success)
820
845
  clamp(0, (var(--ty-solid-fg-threshold) - l) * 1000, 1) 0 0
@@ -881,7 +906,6 @@ html:root,
881
906
  from var(--ty-solid-primary) calc(l + var(--ty-solid-soft-l)) c h
882
907
  );
883
908
 
884
-
885
909
  --ty-solid-success-hover: oklch(
886
910
  from var(--ty-solid-success) calc(l + var(--ty-solid-hover-l)) c h
887
911
  );
@@ -927,15 +951,17 @@ html:root,
927
951
  --ty-solid-neutral-active: oklch(
928
952
  from var(--ty-solid-neutral) calc(l + var(--ty-solid-active-l)) c h
929
953
  );
954
+ /* neutral+ reads its own absolute L dial, not anchor + shared offset —
955
+ it's the full-contrast ink endpoint (see --ty-l-solid-neutral-strong). */
930
956
  --ty-solid-neutral-strong: oklch(
931
- from var(--ty-solid-neutral) calc(l + var(--ty-solid-strong-l)) c h
957
+ from var(--ty-neutral-seed-resolved) var(--ty-l-solid-neutral-strong)
958
+ calc(c * var(--ty-c-strong-mult)) h
932
959
  );
933
960
  --ty-solid-neutral-soft: oklch(
934
961
  from var(--ty-solid-neutral) calc(l + var(--ty-solid-soft-l)) c h
935
962
  );
936
963
  }
937
964
 
938
-
939
965
  /* =====================================================================
940
966
  * SECTION 3 — THEME TRANSITIONS
941
967
  * =====================================================================
@@ -1148,6 +1174,11 @@ html:root,
1148
1174
  inherits: true;
1149
1175
  initial-value: 0.4;
1150
1176
  }
1177
+ @property --ty-l-solid-neutral-strong {
1178
+ syntax: "<number>";
1179
+ inherits: true;
1180
+ initial-value: 0.15;
1181
+ }
1151
1182
  @property --ty-l-bg-neutral-strong {
1152
1183
  syntax: "<number>";
1153
1184
  inherits: true;
@@ -1228,6 +1259,55 @@ html:root,
1228
1259
  inherits: true;
1229
1260
  initial-value: 1;
1230
1261
  }
1262
+ /* Typography + button-depth dials (defined in tyrell.css, mode-flipped
1263
+ there). Registered here so they interpolate on theme switch: with a
1264
+ variable font, text weight crossfades along with the colors, and the
1265
+ solid-button depth chrome (border offset) glides rather than snaps. */
1266
+ @property --ty-weight-action {
1267
+ syntax: "<number>";
1268
+ inherits: true;
1269
+ initial-value: 510;
1270
+ }
1271
+ @property --ty-weight-label {
1272
+ syntax: "<number>";
1273
+ inherits: true;
1274
+ initial-value: 440;
1275
+ }
1276
+ @property --ty-button-depth {
1277
+ syntax: "<number>";
1278
+ inherits: true;
1279
+ initial-value: 0.35;
1280
+ }
1281
+ @property --ty-button-border-l {
1282
+ syntax: "<number>";
1283
+ inherits: true;
1284
+ initial-value: -0.08;
1285
+ }
1286
+ @property --ty-button-border-l-neutral {
1287
+ syntax: "<number>";
1288
+ inherits: true;
1289
+ initial-value: -0.25;
1290
+ }
1291
+ @property --ty-primary-solid-l {
1292
+ syntax: "<number>";
1293
+ inherits: true;
1294
+ initial-value: 0;
1295
+ }
1296
+ @property --ty-success-solid-l {
1297
+ syntax: "<number>";
1298
+ inherits: true;
1299
+ initial-value: 0;
1300
+ }
1301
+ @property --ty-warning-solid-l {
1302
+ syntax: "<number>";
1303
+ inherits: true;
1304
+ initial-value: 0.1;
1305
+ }
1306
+ @property --ty-danger-solid-l {
1307
+ syntax: "<number>";
1308
+ inherits: true;
1309
+ initial-value: 0;
1310
+ }
1231
1311
  @property --ty-solid-hover-l {
1232
1312
  syntax: "<number>";
1233
1313
  inherits: true;
@@ -1304,69 +1384,29 @@ html:root,
1304
1384
  html,
1305
1385
  [data-ty-theme] {
1306
1386
  transition-property:
1307
- --ty-brand-hue,
1308
- --ty-brand-chroma,
1309
- --ty-surface-chroma,
1310
- --ty-success-hue,
1311
- --ty-success-chroma,
1312
- --ty-warning-hue,
1313
- --ty-warning-chroma,
1314
- --ty-danger-hue,
1315
- --ty-danger-chroma,
1316
- --ty-neutral-hue,
1317
- --ty-neutral-chroma,
1318
- --ty-l-strong,
1319
- --ty-l-bold,
1320
- --ty-l-base,
1321
- --ty-l-soft,
1322
- --ty-l-faint,
1323
- --ty-l-bg-base,
1324
- --ty-l-bg-bold,
1325
- --ty-l-bg-soft,
1326
- --ty-l-text-strong,
1327
- --ty-l-text-bold,
1328
- --ty-l-text-base,
1329
- --ty-l-text-soft,
1330
- --ty-l-text-faint,
1331
- --ty-l-border-content,
1332
- --ty-l-border-elevated,
1333
- --ty-l-border-floating,
1334
- --ty-l-border-strong,
1335
- --ty-l-border-bold,
1336
- --ty-l-border,
1337
- --ty-l-border-soft,
1338
- --ty-l-border-faint,
1339
- --ty-l-surface-canvas,
1340
- --ty-l-surface-content,
1341
- --ty-l-surface-elevated,
1342
- --ty-l-surface-floating,
1343
- --ty-l-surface-input,
1344
- --ty-l-solid-neutral,
1345
- --ty-l-bg-neutral-strong,
1346
- --ty-l-bg-neutral-faint,
1347
- --ty-c-bg-neutral-faint-mult,
1348
- --ty-c-strong-mult,
1349
- --ty-c-bold-mult,
1350
- --ty-c-base-mult,
1351
- --ty-c-soft-mult,
1352
- --ty-c-faint-mult,
1353
- --ty-c-bg-base-mult,
1354
- --ty-c-bg-bold-mult,
1355
- --ty-c-bg-soft-mult,
1356
- --ty-primary-l-factor,
1357
- --ty-success-l-factor,
1358
- --ty-warning-l-factor,
1359
- --ty-danger-l-factor,
1360
- --ty-neutral-l-factor,
1361
- --ty-solid-hover-l,
1362
- --ty-solid-active-l,
1363
- --ty-solid-strong-l,
1364
- --ty-solid-soft-l,
1365
- --ty-solid-l,
1366
- --ty-solid-c,
1367
- --ty-solid-h,
1368
- --ty-solid-fg-threshold,
1369
- --ty-focus-ring-alpha;
1387
+ --ty-brand-hue, --ty-brand-chroma, --ty-surface-chroma, --ty-success-hue,
1388
+ --ty-success-chroma, --ty-warning-hue, --ty-warning-chroma,
1389
+ --ty-danger-hue, --ty-danger-chroma, --ty-neutral-hue,
1390
+ --ty-neutral-chroma, --ty-l-strong, --ty-l-bold, --ty-l-base, --ty-l-soft,
1391
+ --ty-l-faint, --ty-l-bg-base, --ty-l-bg-bold, --ty-l-bg-soft,
1392
+ --ty-l-text-strong, --ty-l-text-bold, --ty-l-text-base, --ty-l-text-soft,
1393
+ --ty-l-text-faint, --ty-l-border-content, --ty-l-border-elevated,
1394
+ --ty-l-border-floating, --ty-l-border-strong, --ty-l-border-bold,
1395
+ --ty-l-border, --ty-l-border-soft, --ty-l-border-faint,
1396
+ --ty-l-surface-canvas, --ty-l-surface-content, --ty-l-surface-elevated,
1397
+ --ty-l-surface-floating, --ty-l-surface-input, --ty-l-solid-neutral,
1398
+ --ty-l-solid-neutral-strong, --ty-l-bg-neutral-strong,
1399
+ --ty-l-bg-neutral-faint, --ty-c-bg-neutral-faint-mult, --ty-c-strong-mult,
1400
+ --ty-c-bold-mult, --ty-c-base-mult, --ty-c-soft-mult, --ty-c-faint-mult,
1401
+ --ty-c-bg-base-mult, --ty-c-bg-bold-mult, --ty-c-bg-soft-mult,
1402
+ --ty-primary-l-factor, --ty-success-l-factor, --ty-warning-l-factor,
1403
+ --ty-danger-l-factor, --ty-neutral-l-factor, --ty-primary-solid-l,
1404
+ --ty-success-solid-l, --ty-warning-solid-l, --ty-danger-solid-l,
1405
+ --ty-solid-hover-l, --ty-solid-active-l, --ty-solid-strong-l,
1406
+ --ty-solid-soft-l, --ty-solid-l, --ty-solid-c, --ty-solid-h,
1407
+ --ty-solid-fg-threshold, --ty-focus-ring-alpha, --ty-weight-action,
1408
+ --ty-weight-label, --ty-button-depth, --ty-button-border-l,
1409
+ --ty-button-border-l-neutral;
1370
1410
  transition-duration: var(--ty-theme-transition, 0.45s);
1371
1411
  transition-timing-function: ease;
1372
1412
  }