@kolkrabbi/kol-theme 0.92.0 → 0.94.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.
@@ -25,8 +25,8 @@
25
25
  :root,
26
26
  :is([data-theme="light"], .light) {
27
27
  /* Absolutes (theme-invariant) */
28
- --kol-color-absolute-white: #ffffff;
29
- --kol-color-absolute-black: #000000;
28
+ --kol-color-ab-white: #ffffff;
29
+ --kol-color-ab-black: #000000;
30
30
 
31
31
  /* Surface tiers (page-level) — Light Mode (default) */
32
32
  --kol-surface-primary: #fafafa;
package/kol-color.css CHANGED
@@ -310,20 +310,20 @@
310
310
  * Absolute Colors
311
311
  * --------------------------------------------------------------------------- */
312
312
 
313
- .bg-absolute-white {
314
- background-color: var(--kol-color-absolute-white);
313
+ .bg-ab-white {
314
+ background-color: var(--kol-color-ab-white);
315
315
  }
316
316
 
317
- .bg-absolute-black {
318
- background-color: var(--kol-color-absolute-black);
317
+ .bg-ab-black {
318
+ background-color: var(--kol-color-ab-black);
319
319
  }
320
320
 
321
- .text-absolute-white {
322
- color: var(--kol-color-absolute-white);
321
+ .text-ab-white {
322
+ color: var(--kol-color-ab-white);
323
323
  }
324
324
 
325
- .text-absolute-black {
326
- color: var(--kol-color-absolute-black);
325
+ .text-ab-black {
326
+ color: var(--kol-color-ab-black);
327
327
  }
328
328
 
329
329
  /* =============================================================================
@@ -71,7 +71,7 @@
71
71
  /* DEPRECATED (2026-07-08 chrome law) — ghost folded into outline; Input
72
72
  * aliases variant="ghost" → outline. Rule kept only for stray direct
73
73
  * class consumers; do not use in new code. Opaque 4% black on surface. */
74
- background-color: color-mix(in srgb, var(--kol-color-absolute-black) 4%, var(--kol-surface-primary));
74
+ background-color: color-mix(in srgb, var(--kol-color-ab-black) 4%, var(--kol-surface-primary));
75
75
  color: var(--kol-fg-meta);
76
76
  }
77
77
  .kol-control--ghost:hover,
@@ -355,14 +355,14 @@
355
355
  * (error red carries it in both themes). */
356
356
  .kol-btn-danger {
357
357
  background: var(--ui-error);
358
- color: var(--kol-color-absolute-white);
358
+ color: var(--kol-color-ab-white);
359
359
  border: 1px solid transparent;
360
360
  font-weight: 500;
361
361
  }
362
362
  @media (hover: hover) {
363
363
  .kol-btn-danger:not(.kol-btn-animate):not(.kol-dd-trigger):hover {
364
364
  background-color: color-mix(in srgb, var(--ui-error) 80%, var(--kol-surface-primary));
365
- color: var(--kol-color-absolute-white);
365
+ color: var(--kol-color-ab-white);
366
366
  }
367
367
  }
368
368
 
@@ -465,7 +465,7 @@
465
465
  *
466
466
  * Custom-shape control (not shell-based — slidey indicator geometry).
467
467
  * Default + plain variants. ON state inverts: pill bg
468
- * absolute-white, indicator absolute-black (theme-invariant).
468
+ * ab-white, indicator ab-black (theme-invariant).
469
469
  * ═══════════════════════════════════════════════════════════════ */
470
470
 
471
471
  /* Toggle Switch — atoms/ToggleSwitch.jsx (2026-07-08 chrome law rewrite).
@@ -575,8 +575,8 @@
575
575
  /* ═══════════════════════════════════════════════════════════════
576
576
  * Toggle Checkbox — atoms/ToggleCheckbox.jsx
577
577
  *
578
- * Custom-shape control. Active state inverts: box bg absolute-white,
579
- * no border, check stroke absolute-black (theme-invariant).
578
+ * Custom-shape control. Active state inverts: box bg ab-white,
579
+ * no border, check stroke ab-black (theme-invariant).
580
580
  * ═══════════════════════════════════════════════════════════════ */
581
581
 
582
582
  .toggle-checkbox {
@@ -606,13 +606,13 @@
606
606
  .toggle-checkbox-indicator svg {
607
607
  width: 10px;
608
608
  height: 8px;
609
- stroke: var(--kol-color-absolute-black);
609
+ stroke: var(--kol-color-ab-black);
610
610
  opacity: 0;
611
611
  transition: opacity var(--kol-transition-base);
612
612
  }
613
613
 
614
614
  .toggle-checkbox.is-active .toggle-checkbox-indicator {
615
- background-color: var(--kol-color-absolute-white);
615
+ background-color: var(--kol-color-ab-white);
616
616
  border-color: transparent;
617
617
  }
618
618
 
@@ -629,7 +629,7 @@
629
629
  border-color: transparent;
630
630
  }
631
631
  .toggle-checkbox--media.is-active .toggle-checkbox-indicator {
632
- background-color: var(--kol-color-absolute-white);
632
+ background-color: var(--kol-color-ab-white);
633
633
  }
634
634
 
635
635
 
@@ -1135,7 +1135,7 @@ a.kol-icon-frame {
1135
1135
  * legible over arbitrary pixels, and no Button variant covers it. Values are
1136
1136
  * MediaCard's, which is the instance the doc names. */
1137
1137
  .kol-icon-frame-plate {
1138
- background: var(--kol-fg-absolute-12, rgba(0, 0, 0, 0.4));
1138
+ background: var(--kol-fg-ab-12, rgba(0, 0, 0, 0.4));
1139
1139
  backdrop-filter: blur(4px);
1140
1140
  color: var(--kol-surface-on-primary);
1141
1141
  }
@@ -1147,7 +1147,7 @@ a.kol-icon-frame {
1147
1147
  }
1148
1148
  .kol-icon-frame-danger {
1149
1149
  background: var(--ui-error);
1150
- color: var(--kol-color-absolute-white);
1150
+ color: var(--kol-color-ab-white);
1151
1151
  border: 1px solid transparent;
1152
1152
  }
1153
1153
 
@@ -1161,7 +1161,7 @@ a.kol-icon-frame {
1161
1161
  * artwork's saturation jumps (Chrome). */
1162
1162
  .kol-play-disc {
1163
1163
  background-color: color-mix(in srgb, var(--kol-surface-on-inverse) 64%, transparent);
1164
- color: var(--kol-color-absolute-white);
1164
+ color: var(--kol-color-ab-white);
1165
1165
  border: 2px solid color-mix(in srgb, var(--kol-surface-on-primary) 96%, transparent);
1166
1166
  box-shadow: 0 0 4px 3.5px rgba(0, 0, 0, 0.4);
1167
1167
  opacity: 0;
@@ -1148,7 +1148,7 @@
1148
1148
  * the ghost IconFrame paints --kol-oq-48, a theme colour, and the bar sits on
1149
1149
  * media, not on the theme. The scrubber is a native range — a 2px track at 40 %
1150
1150
  * white, a tall 4 × 28 white pill for the knob — pseudo-elements, so CSS. */
1151
- .kol-playback-bar .kol-icon-frame { color: var(--kol-color-absolute-white); opacity: 0.8; }
1151
+ .kol-playback-bar .kol-icon-frame { color: var(--kol-color-ab-white); opacity: 0.8; }
1152
1152
  .kol-playback-bar .kol-icon-frame:hover,
1153
1153
  .kol-playback-bar .kol-icon-frame:focus-visible { opacity: 1; }
1154
1154
  .kol-playback-scrub {
@@ -1159,10 +1159,10 @@
1159
1159
  outline: none;
1160
1160
  cursor: pointer;
1161
1161
  }
1162
- .kol-playback-scrub::-webkit-slider-runnable-track { height: 2px; border-radius: 1px; background: color-mix(in srgb, var(--kol-color-absolute-white) 40%, transparent); }
1163
- .kol-playback-scrub::-webkit-slider-thumb { -webkit-appearance: none; width: 4px; height: 28px; margin-top: -13px; border-radius: 2px; background: var(--kol-color-absolute-white); }
1164
- .kol-playback-scrub::-moz-range-track { height: 2px; border-radius: 1px; background: color-mix(in srgb, var(--kol-color-absolute-white) 40%, transparent); }
1165
- .kol-playback-scrub::-moz-range-thumb { width: 4px; height: 28px; border: 0; border-radius: 2px; background: var(--kol-color-absolute-white); }
1162
+ .kol-playback-scrub::-webkit-slider-runnable-track { height: 2px; border-radius: 1px; background: color-mix(in srgb, var(--kol-color-ab-white) 40%, transparent); }
1163
+ .kol-playback-scrub::-webkit-slider-thumb { -webkit-appearance: none; width: 4px; height: 28px; margin-top: -13px; border-radius: 2px; background: var(--kol-color-ab-white); }
1164
+ .kol-playback-scrub::-moz-range-track { height: 2px; border-radius: 1px; background: color-mix(in srgb, var(--kol-color-ab-white) 40%, transparent); }
1165
+ .kol-playback-scrub::-moz-range-thumb { width: 4px; height: 28px; border: 0; border-radius: 2px; background: var(--kol-color-ab-white); }
1166
1166
 
1167
1167
  /* ColumnBrowser rows — ONE SELECTED STATE (ColumnBrowserSeams, kol-r2b2
1168
1168
  * 2026-08-28; user: "ONLY one selected state can exist, not TWO"). The row's
@@ -1253,22 +1253,22 @@
1253
1253
  * the ink for its two icon buttons — that fork is what widening the set ends).
1254
1254
  *
1255
1255
  * THE SET: well `fg-inverse-96` (user ruling 2026-08-28, swapped from
1256
- * `fg-absolute-24` — measured on the dark theme, where the inverse tier is the
1256
+ * `fg-ab-24` — measured on the dark theme, where the inverse tier is the
1257
1257
  * one that DARKENS: on the #121215 page inverse-96 lands ~14.2 against
1258
1258
  * absolute-24's 13.7, half a level apart. Unlike absolute it follows the
1259
1259
  * theme, so the light-theme well flips to the near-white inverse anchor) ·
1260
1260
  * active chip `fg-08` (user ruling 2026-08-28, down from the 0.78.1 fg-16) ·
1261
- * inactive hover absolute-white @ 8% (a dark well wants a LIGHTER hover) ·
1261
+ * inactive hover ab-white @ 8% (a dark well wants a LIGHTER hover) ·
1262
1262
  * ink `fg-96`. `.kol-tone-inverse` stays selected for any class
1263
1263
  * hand-stamped on the old name.
1264
1264
  * ───────────────────────────────────────────────────────────────────── */
1265
- .kol-view-toggle.kol-tone-sunken, .kol-view-toggle.kol-tone-inverse { background-color: var(--kol-tone-sunken-bg); }
1265
+ .kol-view-toggle.kol-tone-sunken, .kol-view-toggle.kol-tone-inverse { background-color: var(--kol-oq-inverse-96); }
1266
1266
  .kol-view-toggle.kol-tone-sunken > button[aria-pressed="true"], .kol-view-toggle.kol-tone-inverse > button[aria-pressed="true"] { background-color: var(--kol-fg-08); }
1267
- .kol-view-toggle.kol-tone-sunken > button:not([aria-pressed="true"]):hover, .kol-view-toggle.kol-tone-inverse > button:not([aria-pressed="true"]):hover { background-color: color-mix(in srgb, var(--kol-color-absolute-white) 8%, transparent); }
1268
- .kol-control.kol-tone-sunken, .kol-control.kol-tone-inverse { background-color: var(--kol-tone-sunken-bg); }
1269
- .kol-expand.kol-tone-sunken, .kol-expand.kol-tone-inverse { background-color: var(--kol-tone-sunken-bg); }
1267
+ .kol-view-toggle.kol-tone-sunken > button:not([aria-pressed="true"]):hover, .kol-view-toggle.kol-tone-inverse > button:not([aria-pressed="true"]):hover { background-color: color-mix(in srgb, var(--kol-color-ab-white) 8%, transparent); }
1268
+ .kol-control.kol-tone-sunken, .kol-control.kol-tone-inverse { background-color: var(--kol-oq-inverse-96); }
1269
+ .kol-expand.kol-tone-sunken, .kol-expand.kol-tone-inverse { background-color: var(--kol-oq-inverse-96); }
1270
1270
  /* the tone's fill, one selector — nothing left to cancel (2026-08-28) */
1271
- .kol-dd-trigger.kol-tone-sunken, .kol-dd-trigger.kol-tone-inverse { background-color: var(--kol-tone-sunken-bg); }
1271
+ .kol-dd-trigger.kol-tone-sunken, .kol-dd-trigger.kol-tone-inverse { background-color: var(--kol-oq-inverse-96); }
1272
1272
  /* THE PANEL IS OPAQUE (user 2026-08-28: "transparent doesn't work for
1273
1273
  * dropdown") — it floats over page content, and every `fg-*` stop is an alpha
1274
1274
  * wash that the content reads through. `oq-inverse-*`, the opaque tier, bakes
@@ -1276,7 +1276,7 @@
1276
1276
  * lands ~23.5 against the #121215 page's 18: lighter than the page, the wrong
1277
1277
  * side of it. `surface-tertiary` is the flat twin of what the trigger renders:
1278
1278
  * #0e0e11 (14.0) in dark against the trigger's 14.2, #ffffff in light. */
1279
- .kol-dd-panel.kol-tone-sunken, .kol-dd-panel.kol-tone-inverse { background-color: var(--kol-tone-sunken-bg); }
1279
+ .kol-dd-panel.kol-tone-sunken, .kol-dd-panel.kol-tone-inverse { background-color: var(--kol-oq-inverse-96); }
1280
1280
  /* the rest of the set — Button (icon-only especially), IconFrame, ThemeToggle:
1281
1281
  * the well, transparent edge, fg-96 ink; hover the white wash, pressed the
1282
1282
  * fg-08 chip — both LAYERED over the well (a gradient image over the fill),
@@ -1284,20 +1284,20 @@
1284
1284
  .kol-btn.kol-tone-sunken,
1285
1285
  .kol-icon-frame.kol-tone-sunken,
1286
1286
  .kol-theme-toggle.kol-tone-sunken {
1287
- background-color: var(--kol-tone-sunken-bg);
1287
+ background-color: var(--kol-oq-inverse-96);
1288
1288
  border-color: transparent;
1289
1289
  color: var(--kol-fg-96);
1290
1290
  }
1291
1291
  @media (hover: hover) {
1292
1292
  .kol-btn.kol-tone-sunken:not(.kol-btn-animate):not(:disabled):hover {
1293
- background-color: var(--kol-tone-sunken-bg);
1294
- background-image: linear-gradient(color-mix(in srgb, var(--kol-color-absolute-white) 8%, transparent), color-mix(in srgb, var(--kol-color-absolute-white) 8%, transparent));
1293
+ background-color: var(--kol-oq-inverse-96);
1294
+ background-image: linear-gradient(color-mix(in srgb, var(--kol-color-ab-white) 8%, transparent), color-mix(in srgb, var(--kol-color-ab-white) 8%, transparent));
1295
1295
  color: var(--kol-fg-96);
1296
1296
  }
1297
1297
  }
1298
1298
  .kol-btn.kol-tone-sunken.kol-btn-pressed,
1299
1299
  .kol-btn.kol-tone-sunken:not(:disabled):active {
1300
- background-color: var(--kol-tone-sunken-bg);
1300
+ background-color: var(--kol-oq-inverse-96);
1301
1301
  background-image: linear-gradient(var(--kol-fg-08), var(--kol-fg-08));
1302
1302
  color: var(--kol-fg-96);
1303
1303
  }
@@ -74,19 +74,6 @@
74
74
  * first fifth of the duration and the rest on a settle you cannot see — so
75
75
  * every motion read as instant no matter what duration it was given, and a
76
76
  * small hover affordance never showed its move at all. */
77
- /* THE SUNKEN PLATE (ControlToneSunken, user ruling 2026-08-28) — the one fill
78
- * every `tone="sunken"` control paints: ViewToggle's well, Input, SearchInput,
79
- * the Dropdown trigger AND its panel, Button, IconFrame, ThemeToggle.
80
- *
81
- * OPAQUE and theme-invariant, and both halves are the ruling: "opaque so it
82
- * doesn't bleed". A translucent well renders whatever is under it, which is
83
- * how this went wrong twice in a day — `fg-absolute-24` and `fg-inverse-96`
84
- * are washes, and the second one also follows the theme stamp, so an app
85
- * painting a dark page without stamping `data-theme` got a near-white control
86
- * row. Sunken means BELOW the plane; a plate that changes with the plane
87
- * cannot say that. Ship one colour and let it be the same everywhere. */
88
- --kol-tone-sunken-bg: color-mix(in srgb, var(--kol-color-absolute-white) 11%, var(--kol-color-absolute-black));
89
-
90
77
  --kol-ease-house: cubic-bezier(0.4, 0, 0.2, 1);
91
78
  /* the bounce — overshoots past its target and settles back (y > 1 is what
92
79
  * makes it bounce; house only decelerates). For a press that should feel
package/kol-opacity.css CHANGED
@@ -50,6 +50,7 @@
50
50
  --kol-fg-40: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 40%, transparent);
51
51
  --kol-fg-48: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 48%, transparent);
52
52
  --kol-fg-64: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 64%, transparent);
53
+ --kol-fg-72: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent);
53
54
  /* 72 — THE ONE OFF-RAMP STOP (user ruling 2026-08-01). The scale is a
54
55
  * 14-stop signature and this makes it 15, deliberately and in ONE tier only:
55
56
  * the eight TEXT roles below needed a step between body (64) and strong (80)
@@ -67,20 +68,21 @@
67
68
  * TOKENS — Absolute tier (theme-independent black, fixed opacity stops)
68
69
  * ============================================================================ */
69
70
 
70
- --kol-fg-absolute-01: color-mix(in srgb, var(--kol-color-absolute-black) 1%, transparent);
71
- --kol-fg-absolute-02: color-mix(in srgb, var(--kol-color-absolute-black) 2%, transparent);
72
- --kol-fg-absolute-04: color-mix(in srgb, var(--kol-color-absolute-black) 4%, transparent);
73
- --kol-fg-absolute-08: color-mix(in srgb, var(--kol-color-absolute-black) 8%, transparent);
74
- --kol-fg-absolute-12: color-mix(in srgb, var(--kol-color-absolute-black) 12%, transparent);
75
- --kol-fg-absolute-16: color-mix(in srgb, var(--kol-color-absolute-black) 16%, transparent);
76
- --kol-fg-absolute-24: color-mix(in srgb, var(--kol-color-absolute-black) 24%, transparent);
77
- --kol-fg-absolute-32: color-mix(in srgb, var(--kol-color-absolute-black) 32%, transparent);
78
- --kol-fg-absolute-40: color-mix(in srgb, var(--kol-color-absolute-black) 40%, transparent);
79
- --kol-fg-absolute-48: color-mix(in srgb, var(--kol-color-absolute-black) 48%, transparent);
80
- --kol-fg-absolute-64: color-mix(in srgb, var(--kol-color-absolute-black) 64%, transparent);
81
- --kol-fg-absolute-80: color-mix(in srgb, var(--kol-color-absolute-black) 80%, transparent);
82
- --kol-fg-absolute-88: color-mix(in srgb, var(--kol-color-absolute-black) 88%, transparent);
83
- --kol-fg-absolute-96: color-mix(in srgb, var(--kol-color-absolute-black) 96%, transparent);
71
+ --kol-fg-ab-01: color-mix(in srgb, var(--kol-color-ab-black) 1%, transparent);
72
+ --kol-fg-ab-02: color-mix(in srgb, var(--kol-color-ab-black) 2%, transparent);
73
+ --kol-fg-ab-04: color-mix(in srgb, var(--kol-color-ab-black) 4%, transparent);
74
+ --kol-fg-ab-08: color-mix(in srgb, var(--kol-color-ab-black) 8%, transparent);
75
+ --kol-fg-ab-12: color-mix(in srgb, var(--kol-color-ab-black) 12%, transparent);
76
+ --kol-fg-ab-16: color-mix(in srgb, var(--kol-color-ab-black) 16%, transparent);
77
+ --kol-fg-ab-24: color-mix(in srgb, var(--kol-color-ab-black) 24%, transparent);
78
+ --kol-fg-ab-32: color-mix(in srgb, var(--kol-color-ab-black) 32%, transparent);
79
+ --kol-fg-ab-40: color-mix(in srgb, var(--kol-color-ab-black) 40%, transparent);
80
+ --kol-fg-ab-48: color-mix(in srgb, var(--kol-color-ab-black) 48%, transparent);
81
+ --kol-fg-ab-64: color-mix(in srgb, var(--kol-color-ab-black) 64%, transparent);
82
+ --kol-fg-ab-72: color-mix(in srgb, var(--kol-color-ab-black) 72%, transparent);
83
+ --kol-fg-ab-80: color-mix(in srgb, var(--kol-color-ab-black) 80%, transparent);
84
+ --kol-fg-ab-88: color-mix(in srgb, var(--kol-color-ab-black) 88%, transparent);
85
+ --kol-fg-ab-96: color-mix(in srgb, var(--kol-color-ab-black) 96%, transparent);
84
86
 
85
87
  /* ============================================================================
86
88
  * TOKENS — Inverse tier (foreground on inverse surface)
@@ -97,6 +99,7 @@
97
99
  --kol-fg-inverse-40: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 40%, transparent);
98
100
  --kol-fg-inverse-48: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 48%, transparent);
99
101
  --kol-fg-inverse-64: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 64%, transparent);
102
+ --kol-fg-inverse-72: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 72%, transparent);
100
103
  --kol-fg-inverse-80: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 80%, transparent);
101
104
  --kol-fg-inverse-88: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 88%, transparent);
102
105
  --kol-fg-inverse-96: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 96%, transparent);
@@ -134,6 +137,7 @@
134
137
  .bg-fg-48 { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 48%, transparent); }
135
138
  .bg-fg-64 { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 64%, transparent); }
136
139
  .bg-fg-72 { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
140
+ .bg-fg-72 { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
137
141
  .bg-fg-80 { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 80%, transparent); }
138
142
  .bg-fg-88 { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 88%, transparent); }
139
143
  .bg-fg-96 { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 96%, transparent); }
@@ -153,6 +157,7 @@
153
157
  .bg-fg-inverse-40 { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 40%, transparent); }
154
158
  .bg-fg-inverse-48 { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 48%, transparent); }
155
159
  .bg-fg-inverse-64 { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 64%, transparent); }
160
+ .bg-fg-inverse-72 { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 72%, transparent); }
156
161
  .bg-fg-inverse-80 { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 80%, transparent); }
157
162
  .bg-fg-inverse-88 { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 88%, transparent); }
158
163
  .bg-fg-inverse-96 { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 96%, transparent); }
@@ -161,20 +166,21 @@
161
166
  * CLASSES — Background opacity (absolute tier — fixed black, theme-independent)
162
167
  * ============================================================================== */
163
168
 
164
- .bg-fg-absolute-01 { background-color: var(--kol-fg-absolute-01); }
165
- .bg-fg-absolute-02 { background-color: var(--kol-fg-absolute-02); }
166
- .bg-fg-absolute-04 { background-color: var(--kol-fg-absolute-04); }
167
- .bg-fg-absolute-08 { background-color: var(--kol-fg-absolute-08); }
168
- .bg-fg-absolute-12 { background-color: var(--kol-fg-absolute-12); }
169
- .bg-fg-absolute-16 { background-color: var(--kol-fg-absolute-16); }
170
- .bg-fg-absolute-24 { background-color: var(--kol-fg-absolute-24); }
171
- .bg-fg-absolute-32 { background-color: var(--kol-fg-absolute-32); }
172
- .bg-fg-absolute-40 { background-color: var(--kol-fg-absolute-40); }
173
- .bg-fg-absolute-48 { background-color: var(--kol-fg-absolute-48); }
174
- .bg-fg-absolute-64 { background-color: var(--kol-fg-absolute-64); }
175
- .bg-fg-absolute-80 { background-color: var(--kol-fg-absolute-80); }
176
- .bg-fg-absolute-88 { background-color: var(--kol-fg-absolute-88); }
177
- .bg-fg-absolute-96 { background-color: var(--kol-fg-absolute-96); }
169
+ .bg-fg-ab-01 { background-color: var(--kol-fg-ab-01); }
170
+ .bg-fg-ab-02 { background-color: var(--kol-fg-ab-02); }
171
+ .bg-fg-ab-04 { background-color: var(--kol-fg-ab-04); }
172
+ .bg-fg-ab-08 { background-color: var(--kol-fg-ab-08); }
173
+ .bg-fg-ab-12 { background-color: var(--kol-fg-ab-12); }
174
+ .bg-fg-ab-16 { background-color: var(--kol-fg-ab-16); }
175
+ .bg-fg-ab-24 { background-color: var(--kol-fg-ab-24); }
176
+ .bg-fg-ab-32 { background-color: var(--kol-fg-ab-32); }
177
+ .bg-fg-ab-40 { background-color: var(--kol-fg-ab-40); }
178
+ .bg-fg-ab-48 { background-color: var(--kol-fg-ab-48); }
179
+ .bg-fg-ab-64 { background-color: var(--kol-fg-ab-64); }
180
+ .bg-fg-ab-72 { background-color: var(--kol-fg-ab-72); }
181
+ .bg-fg-ab-80 { background-color: var(--kol-fg-ab-80); }
182
+ .bg-fg-ab-88 { background-color: var(--kol-fg-ab-88); }
183
+ .bg-fg-ab-96 { background-color: var(--kol-fg-ab-96); }
178
184
 
179
185
  /* ==============================================================================
180
186
  * CLASSES — Background hover (standard + inverse)
@@ -192,6 +198,7 @@
192
198
  .hover\:bg-fg-48:hover { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 48%, transparent); }
193
199
  .hover\:bg-fg-64:hover { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 64%, transparent); }
194
200
  .hover\:bg-fg-72:hover { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
201
+ .hover\:bg-fg-72:hover { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
195
202
  .hover\:bg-fg-80:hover { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 80%, transparent); }
196
203
  .hover\:bg-fg-88:hover { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 88%, transparent); }
197
204
  .hover\:bg-fg-96:hover { background-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 96%, transparent); }
@@ -207,6 +214,7 @@
207
214
  .hover\:bg-fg-inverse-40:hover { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 40%, transparent); }
208
215
  .hover\:bg-fg-inverse-48:hover { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 48%, transparent); }
209
216
  .hover\:bg-fg-inverse-64:hover { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 64%, transparent); }
217
+ .hover\:bg-fg-inverse-72:hover { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 72%, transparent); }
210
218
  .hover\:bg-fg-inverse-80:hover { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 80%, transparent); }
211
219
  .hover\:bg-fg-inverse-88:hover { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 88%, transparent); }
212
220
  .hover\:bg-fg-inverse-96:hover { background-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 96%, transparent); }
@@ -227,6 +235,7 @@
227
235
  .text-fg-48 { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 48%, transparent); }
228
236
  .text-fg-64 { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 64%, transparent); }
229
237
  .text-fg-72 { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
238
+ .text-fg-72 { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
230
239
  .text-fg-80 { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 80%, transparent); }
231
240
  .text-fg-88 { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 88%, transparent); }
232
241
  .text-fg-96 { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 96%, transparent); }
@@ -242,6 +251,7 @@
242
251
  .text-fg-inverse-40 { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 40%, transparent); }
243
252
  .text-fg-inverse-48 { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 48%, transparent); }
244
253
  .text-fg-inverse-64 { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 64%, transparent); }
254
+ .text-fg-inverse-72 { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 72%, transparent); }
245
255
  .text-fg-inverse-80 { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 80%, transparent); }
246
256
  .text-fg-inverse-88 { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 88%, transparent); }
247
257
  .text-fg-inverse-96 { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 96%, transparent); }
@@ -262,6 +272,7 @@
262
272
  .hover\:text-fg-48:hover { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 48%, transparent); }
263
273
  .hover\:text-fg-64:hover { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 64%, transparent); }
264
274
  .hover\:text-fg-72:hover { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
275
+ .hover\:text-fg-72:hover { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
265
276
  .hover\:text-fg-80:hover { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 80%, transparent); }
266
277
  .hover\:text-fg-88:hover { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 88%, transparent); }
267
278
  .hover\:text-fg-96:hover { color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 96%, transparent); }
@@ -277,6 +288,7 @@
277
288
  .hover\:text-fg-inverse-40:hover { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 40%, transparent); }
278
289
  .hover\:text-fg-inverse-48:hover { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 48%, transparent); }
279
290
  .hover\:text-fg-inverse-64:hover { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 64%, transparent); }
291
+ .hover\:text-fg-inverse-72:hover { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 72%, transparent); }
280
292
  .hover\:text-fg-inverse-80:hover { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 80%, transparent); }
281
293
  .hover\:text-fg-inverse-88:hover { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 88%, transparent); }
282
294
  .hover\:text-fg-inverse-96:hover { color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 96%, transparent); }
@@ -297,6 +309,7 @@
297
309
  .border-fg-48 { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 48%, transparent); }
298
310
  .border-fg-64 { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 64%, transparent); }
299
311
  .border-fg-72 { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
312
+ .border-fg-72 { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
300
313
  .border-fg-80 { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 80%, transparent); }
301
314
  .border-fg-88 { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 88%, transparent); }
302
315
  .border-fg-96 { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 96%, transparent); }
@@ -312,6 +325,7 @@
312
325
  .border-fg-inverse-40 { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 40%, transparent); }
313
326
  .border-fg-inverse-48 { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 48%, transparent); }
314
327
  .border-fg-inverse-64 { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 64%, transparent); }
328
+ .border-fg-inverse-72 { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 72%, transparent); }
315
329
  .border-fg-inverse-80 { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 80%, transparent); }
316
330
  .border-fg-inverse-88 { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 88%, transparent); }
317
331
  .border-fg-inverse-96 { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 96%, transparent); }
@@ -332,6 +346,7 @@
332
346
  .hover\:border-fg-48:hover { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 48%, transparent); }
333
347
  .hover\:border-fg-64:hover { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 64%, transparent); }
334
348
  .hover\:border-fg-72:hover { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
349
+ .hover\:border-fg-72:hover { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 72%, transparent); }
335
350
  .hover\:border-fg-80:hover { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 80%, transparent); }
336
351
  .hover\:border-fg-88:hover { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 88%, transparent); }
337
352
  .hover\:border-fg-96:hover { border-color: color-mix(in srgb, var(--kol-surface-on-primary, currentColor) 96%, transparent); }
@@ -347,6 +362,7 @@
347
362
  .hover\:border-fg-inverse-40:hover { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 40%, transparent); }
348
363
  .hover\:border-fg-inverse-48:hover { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 48%, transparent); }
349
364
  .hover\:border-fg-inverse-64:hover { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 64%, transparent); }
365
+ .hover\:border-fg-inverse-72:hover { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 72%, transparent); }
350
366
  .hover\:border-fg-inverse-80:hover { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 80%, transparent); }
351
367
  .hover\:border-fg-inverse-88:hover { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 88%, transparent); }
352
368
  .hover\:border-fg-inverse-96:hover { border-color: color-mix(in srgb, var(--kol-surface-on-inverse, currentColor) 96%, transparent); }
@@ -391,6 +407,7 @@
391
407
  --kol-fg-subtle: var(--kol-fg-24);
392
408
  --kol-fg-meta: var(--kol-fg-48);
393
409
  --kol-fg-body: var(--kol-fg-64);
410
+ --kol-fg-body: var(--kol-fg-72);
394
411
  --kol-fg-lede: var(--kol-fg-72);
395
412
  --kol-fg-strong: var(--kol-fg-80);
396
413
  --kol-fg-shout: var(--kol-fg-88);
@@ -428,3 +445,45 @@
428
445
  .hover\:text-scream:hover { color: var(--kol-fg-scream); }
429
446
  .hover\:text-emphasis:hover { color: var(--kol-fg-emphasis); }
430
447
  .hover\:text-default:hover { color: var(--kol-fg-body); }
448
+
449
+ /* ============================================================================
450
+ * ALIASES — the old `absolute` spelling (renamed to `ab`, user ruling 2026-08-28)
451
+ *
452
+ * Kept so no consumer breaks silently on a name change: `--kol-fg-absolute-NN`
453
+ * and `.bg-fg-absolute-NN` still resolve, to the same value as before. New code
454
+ * writes `ab`. Drop these once the estate has moved.
455
+ * ============================================================================ */
456
+ :root {
457
+ --kol-fg-absolute-01: var(--kol-fg-ab-01);
458
+ --kol-fg-absolute-02: var(--kol-fg-ab-02);
459
+ --kol-fg-absolute-04: var(--kol-fg-ab-04);
460
+ --kol-fg-absolute-08: var(--kol-fg-ab-08);
461
+ --kol-fg-absolute-12: var(--kol-fg-ab-12);
462
+ --kol-fg-absolute-16: var(--kol-fg-ab-16);
463
+ --kol-fg-absolute-24: var(--kol-fg-ab-24);
464
+ --kol-fg-absolute-32: var(--kol-fg-ab-32);
465
+ --kol-fg-absolute-40: var(--kol-fg-ab-40);
466
+ --kol-fg-absolute-48: var(--kol-fg-ab-48);
467
+ --kol-fg-absolute-64: var(--kol-fg-ab-64);
468
+ --kol-fg-absolute-72: var(--kol-fg-ab-72);
469
+ --kol-fg-absolute-80: var(--kol-fg-ab-80);
470
+ --kol-fg-absolute-88: var(--kol-fg-ab-88);
471
+ --kol-fg-absolute-96: var(--kol-fg-ab-96);
472
+ --kol-color-absolute-black: var(--kol-color-ab-black);
473
+ --kol-color-absolute-white: var(--kol-color-ab-white);
474
+ }
475
+ .bg-fg-absolute-01 { background-color: var(--kol-fg-ab-01); }
476
+ .bg-fg-absolute-02 { background-color: var(--kol-fg-ab-02); }
477
+ .bg-fg-absolute-04 { background-color: var(--kol-fg-ab-04); }
478
+ .bg-fg-absolute-08 { background-color: var(--kol-fg-ab-08); }
479
+ .bg-fg-absolute-12 { background-color: var(--kol-fg-ab-12); }
480
+ .bg-fg-absolute-16 { background-color: var(--kol-fg-ab-16); }
481
+ .bg-fg-absolute-24 { background-color: var(--kol-fg-ab-24); }
482
+ .bg-fg-absolute-32 { background-color: var(--kol-fg-ab-32); }
483
+ .bg-fg-absolute-40 { background-color: var(--kol-fg-ab-40); }
484
+ .bg-fg-absolute-48 { background-color: var(--kol-fg-ab-48); }
485
+ .bg-fg-absolute-64 { background-color: var(--kol-fg-ab-64); }
486
+ .bg-fg-absolute-72 { background-color: var(--kol-fg-ab-72); }
487
+ .bg-fg-absolute-80 { background-color: var(--kol-fg-ab-80); }
488
+ .bg-fg-absolute-88 { background-color: var(--kol-fg-ab-88); }
489
+ .bg-fg-absolute-96 { background-color: var(--kol-fg-ab-96); }
package/kol-opaque.css CHANGED
@@ -22,6 +22,8 @@
22
22
  * Tier pairs:
23
23
  * - Standard (ink-on-primary flattened onto --kol-surface-primary)
24
24
  * - Inverse (ink-on-inverse flattened onto --kol-surface-inverse)
25
+ * - Absolute (ab / ab-inverse — black and white against each other, so the
26
+ * grey is opaque AND theme-invariant; 2026-08-28)
25
27
  *
26
28
  * Layers:
27
29
  * - Tokens (--kol-oq-*, --kol-oq-inverse-*) for use in CSS rules
@@ -46,6 +48,7 @@
46
48
  --kol-oq-40: color-mix(in srgb, var(--kol-surface-on-primary) 40%, var(--kol-surface-primary));
47
49
  --kol-oq-48: color-mix(in srgb, var(--kol-surface-on-primary) 48%, var(--kol-surface-primary));
48
50
  --kol-oq-64: color-mix(in srgb, var(--kol-surface-on-primary) 64%, var(--kol-surface-primary));
51
+ --kol-oq-72: color-mix(in srgb, var(--kol-surface-on-primary) 72%, var(--kol-surface-primary));
49
52
  --kol-oq-80: color-mix(in srgb, var(--kol-surface-on-primary) 80%, var(--kol-surface-primary));
50
53
  --kol-oq-88: color-mix(in srgb, var(--kol-surface-on-primary) 88%, var(--kol-surface-primary));
51
54
  --kol-oq-96: color-mix(in srgb, var(--kol-surface-on-primary) 96%, var(--kol-surface-primary));
@@ -65,6 +68,7 @@
65
68
  --kol-oq-inverse-40: color-mix(in srgb, var(--kol-surface-on-inverse) 40%, var(--kol-surface-inverse));
66
69
  --kol-oq-inverse-48: color-mix(in srgb, var(--kol-surface-on-inverse) 48%, var(--kol-surface-inverse));
67
70
  --kol-oq-inverse-64: color-mix(in srgb, var(--kol-surface-on-inverse) 64%, var(--kol-surface-inverse));
71
+ --kol-oq-inverse-72: color-mix(in srgb, var(--kol-surface-on-inverse) 72%, var(--kol-surface-inverse));
68
72
  --kol-oq-inverse-80: color-mix(in srgb, var(--kol-surface-on-inverse) 80%, var(--kol-surface-inverse));
69
73
  --kol-oq-inverse-88: color-mix(in srgb, var(--kol-surface-on-inverse) 88%, var(--kol-surface-inverse));
70
74
  --kol-oq-inverse-96: color-mix(in srgb, var(--kol-surface-on-inverse) 96%, var(--kol-surface-inverse));
@@ -85,6 +89,7 @@
85
89
  .bg-oq-40 { background-color: var(--kol-oq-40); }
86
90
  .bg-oq-48 { background-color: var(--kol-oq-48); }
87
91
  .bg-oq-64 { background-color: var(--kol-oq-64); }
92
+ .bg-oq-72 { background-color: var(--kol-oq-72); }
88
93
  .bg-oq-80 { background-color: var(--kol-oq-80); }
89
94
  .bg-oq-88 { background-color: var(--kol-oq-88); }
90
95
  .bg-oq-96 { background-color: var(--kol-oq-96); }
@@ -100,6 +105,7 @@
100
105
  .bg-oq-inverse-40 { background-color: var(--kol-oq-inverse-40); }
101
106
  .bg-oq-inverse-48 { background-color: var(--kol-oq-inverse-48); }
102
107
  .bg-oq-inverse-64 { background-color: var(--kol-oq-inverse-64); }
108
+ .bg-oq-inverse-72 { background-color: var(--kol-oq-inverse-72); }
103
109
  .bg-oq-inverse-80 { background-color: var(--kol-oq-inverse-80); }
104
110
  .bg-oq-inverse-88 { background-color: var(--kol-oq-inverse-88); }
105
111
  .bg-oq-inverse-96 { background-color: var(--kol-oq-inverse-96); }
@@ -119,6 +125,7 @@
119
125
  .hover\:bg-oq-40:hover { background-color: var(--kol-oq-40); }
120
126
  .hover\:bg-oq-48:hover { background-color: var(--kol-oq-48); }
121
127
  .hover\:bg-oq-64:hover { background-color: var(--kol-oq-64); }
128
+ .hover\:bg-oq-72:hover { background-color: var(--kol-oq-72); }
122
129
  .hover\:bg-oq-80:hover { background-color: var(--kol-oq-80); }
123
130
  .hover\:bg-oq-88:hover { background-color: var(--kol-oq-88); }
124
131
  .hover\:bg-oq-96:hover { background-color: var(--kol-oq-96); }
@@ -134,6 +141,7 @@
134
141
  .hover\:bg-oq-inverse-40:hover { background-color: var(--kol-oq-inverse-40); }
135
142
  .hover\:bg-oq-inverse-48:hover { background-color: var(--kol-oq-inverse-48); }
136
143
  .hover\:bg-oq-inverse-64:hover { background-color: var(--kol-oq-inverse-64); }
144
+ .hover\:bg-oq-inverse-72:hover { background-color: var(--kol-oq-inverse-72); }
137
145
  .hover\:bg-oq-inverse-80:hover { background-color: var(--kol-oq-inverse-80); }
138
146
  .hover\:bg-oq-inverse-88:hover { background-color: var(--kol-oq-inverse-88); }
139
147
  .hover\:bg-oq-inverse-96:hover { background-color: var(--kol-oq-inverse-96); }
@@ -153,6 +161,7 @@
153
161
  .text-oq-40 { color: var(--kol-oq-40); }
154
162
  .text-oq-48 { color: var(--kol-oq-48); }
155
163
  .text-oq-64 { color: var(--kol-oq-64); }
164
+ .text-oq-72 { color: var(--kol-oq-72); }
156
165
  .text-oq-80 { color: var(--kol-oq-80); }
157
166
  .text-oq-88 { color: var(--kol-oq-88); }
158
167
  .text-oq-96 { color: var(--kol-oq-96); }
@@ -168,6 +177,7 @@
168
177
  .text-oq-inverse-40 { color: var(--kol-oq-inverse-40); }
169
178
  .text-oq-inverse-48 { color: var(--kol-oq-inverse-48); }
170
179
  .text-oq-inverse-64 { color: var(--kol-oq-inverse-64); }
180
+ .text-oq-inverse-72 { color: var(--kol-oq-inverse-72); }
171
181
  .text-oq-inverse-80 { color: var(--kol-oq-inverse-80); }
172
182
  .text-oq-inverse-88 { color: var(--kol-oq-inverse-88); }
173
183
  .text-oq-inverse-96 { color: var(--kol-oq-inverse-96); }
@@ -187,6 +197,7 @@
187
197
  .border-oq-40 { border-color: var(--kol-oq-40); }
188
198
  .border-oq-48 { border-color: var(--kol-oq-48); }
189
199
  .border-oq-64 { border-color: var(--kol-oq-64); }
200
+ .border-oq-72 { border-color: var(--kol-oq-72); }
190
201
  .border-oq-80 { border-color: var(--kol-oq-80); }
191
202
  .border-oq-88 { border-color: var(--kol-oq-88); }
192
203
  .border-oq-96 { border-color: var(--kol-oq-96); }
@@ -202,6 +213,186 @@
202
213
  .border-oq-inverse-40 { border-color: var(--kol-oq-inverse-40); }
203
214
  .border-oq-inverse-48 { border-color: var(--kol-oq-inverse-48); }
204
215
  .border-oq-inverse-64 { border-color: var(--kol-oq-inverse-64); }
216
+ .border-oq-inverse-72 { border-color: var(--kol-oq-inverse-72); }
205
217
  .border-oq-inverse-80 { border-color: var(--kol-oq-inverse-80); }
206
218
  .border-oq-inverse-88 { border-color: var(--kol-oq-inverse-88); }
207
219
  .border-oq-inverse-96 { border-color: var(--kol-oq-inverse-96); }
220
+
221
+ /* ============================================================================
222
+ * TOKENS — ABSOLUTE tiers (user ruling 2026-08-28: "you can make bg-oq-ab-*
223
+ * and bg-oq-ab-inverse-*")
224
+ *
225
+ * The gap they close: the estate had opaque greys that FOLLOW the theme
226
+ * (`oq-*`, `oq-inverse-*` — baked onto a surface token) and absolute inks that
227
+ * are theme-invariant but TRANSLUCENT (`fg-ab-*`). "Opaque and theme-invariant"
228
+ * was not expressible, which is exactly what a sunken control wants: a plate
229
+ * that is darker than its plane, on both themes, that nothing bleeds through.
230
+ *
231
+ * Same construction as the tiers above, with the absolutes standing in for the
232
+ * surface pair — so these are flat greys that never move:
233
+ * oq-ab-NN black NN% into WHITE — a light ground darkening
234
+ * oq-ab-inverse-NN white NN% into BLACK — a dark ground lightening
235
+ * ============================================================================ */
236
+
237
+ :root {
238
+ --kol-oq-ab-01: color-mix(in srgb, var(--kol-color-ab-black) 1%, var(--kol-color-ab-white));
239
+ --kol-oq-ab-02: color-mix(in srgb, var(--kol-color-ab-black) 2%, var(--kol-color-ab-white));
240
+ --kol-oq-ab-04: color-mix(in srgb, var(--kol-color-ab-black) 4%, var(--kol-color-ab-white));
241
+ --kol-oq-ab-08: color-mix(in srgb, var(--kol-color-ab-black) 8%, var(--kol-color-ab-white));
242
+ --kol-oq-ab-12: color-mix(in srgb, var(--kol-color-ab-black) 12%, var(--kol-color-ab-white));
243
+ --kol-oq-ab-16: color-mix(in srgb, var(--kol-color-ab-black) 16%, var(--kol-color-ab-white));
244
+ --kol-oq-ab-24: color-mix(in srgb, var(--kol-color-ab-black) 24%, var(--kol-color-ab-white));
245
+ --kol-oq-ab-32: color-mix(in srgb, var(--kol-color-ab-black) 32%, var(--kol-color-ab-white));
246
+ --kol-oq-ab-40: color-mix(in srgb, var(--kol-color-ab-black) 40%, var(--kol-color-ab-white));
247
+ --kol-oq-ab-48: color-mix(in srgb, var(--kol-color-ab-black) 48%, var(--kol-color-ab-white));
248
+ --kol-oq-ab-64: color-mix(in srgb, var(--kol-color-ab-black) 64%, var(--kol-color-ab-white));
249
+ --kol-oq-ab-72: color-mix(in srgb, var(--kol-color-ab-black) 72%, var(--kol-color-ab-white));
250
+ --kol-oq-ab-80: color-mix(in srgb, var(--kol-color-ab-black) 80%, var(--kol-color-ab-white));
251
+ --kol-oq-ab-88: color-mix(in srgb, var(--kol-color-ab-black) 88%, var(--kol-color-ab-white));
252
+ --kol-oq-ab-96: color-mix(in srgb, var(--kol-color-ab-black) 96%, var(--kol-color-ab-white));
253
+
254
+ --kol-oq-ab-inverse-01: color-mix(in srgb, var(--kol-color-ab-white) 1%, var(--kol-color-ab-black));
255
+ --kol-oq-ab-inverse-02: color-mix(in srgb, var(--kol-color-ab-white) 2%, var(--kol-color-ab-black));
256
+ --kol-oq-ab-inverse-04: color-mix(in srgb, var(--kol-color-ab-white) 4%, var(--kol-color-ab-black));
257
+ --kol-oq-ab-inverse-08: color-mix(in srgb, var(--kol-color-ab-white) 8%, var(--kol-color-ab-black));
258
+ --kol-oq-ab-inverse-12: color-mix(in srgb, var(--kol-color-ab-white) 12%, var(--kol-color-ab-black));
259
+ --kol-oq-ab-inverse-16: color-mix(in srgb, var(--kol-color-ab-white) 16%, var(--kol-color-ab-black));
260
+ --kol-oq-ab-inverse-24: color-mix(in srgb, var(--kol-color-ab-white) 24%, var(--kol-color-ab-black));
261
+ --kol-oq-ab-inverse-32: color-mix(in srgb, var(--kol-color-ab-white) 32%, var(--kol-color-ab-black));
262
+ --kol-oq-ab-inverse-40: color-mix(in srgb, var(--kol-color-ab-white) 40%, var(--kol-color-ab-black));
263
+ --kol-oq-ab-inverse-48: color-mix(in srgb, var(--kol-color-ab-white) 48%, var(--kol-color-ab-black));
264
+ --kol-oq-ab-inverse-64: color-mix(in srgb, var(--kol-color-ab-white) 64%, var(--kol-color-ab-black));
265
+ --kol-oq-ab-inverse-72: color-mix(in srgb, var(--kol-color-ab-white) 72%, var(--kol-color-ab-black));
266
+ --kol-oq-ab-inverse-80: color-mix(in srgb, var(--kol-color-ab-white) 80%, var(--kol-color-ab-black));
267
+ --kol-oq-ab-inverse-88: color-mix(in srgb, var(--kol-color-ab-white) 88%, var(--kol-color-ab-black));
268
+ --kol-oq-ab-inverse-96: color-mix(in srgb, var(--kol-color-ab-white) 96%, var(--kol-color-ab-black));
269
+ }
270
+
271
+ /* CLASSES — absolute tiers */
272
+ .bg-oq-ab-01 { background-color: var(--kol-oq-ab-01); }
273
+ .bg-oq-ab-02 { background-color: var(--kol-oq-ab-02); }
274
+ .bg-oq-ab-04 { background-color: var(--kol-oq-ab-04); }
275
+ .bg-oq-ab-08 { background-color: var(--kol-oq-ab-08); }
276
+ .bg-oq-ab-12 { background-color: var(--kol-oq-ab-12); }
277
+ .bg-oq-ab-16 { background-color: var(--kol-oq-ab-16); }
278
+ .bg-oq-ab-24 { background-color: var(--kol-oq-ab-24); }
279
+ .bg-oq-ab-32 { background-color: var(--kol-oq-ab-32); }
280
+ .bg-oq-ab-40 { background-color: var(--kol-oq-ab-40); }
281
+ .bg-oq-ab-48 { background-color: var(--kol-oq-ab-48); }
282
+ .bg-oq-ab-64 { background-color: var(--kol-oq-ab-64); }
283
+ .bg-oq-ab-72 { background-color: var(--kol-oq-ab-72); }
284
+ .bg-oq-ab-80 { background-color: var(--kol-oq-ab-80); }
285
+ .bg-oq-ab-88 { background-color: var(--kol-oq-ab-88); }
286
+ .bg-oq-ab-96 { background-color: var(--kol-oq-ab-96); }
287
+
288
+ .bg-oq-ab-inverse-01 { background-color: var(--kol-oq-ab-inverse-01); }
289
+ .bg-oq-ab-inverse-02 { background-color: var(--kol-oq-ab-inverse-02); }
290
+ .bg-oq-ab-inverse-04 { background-color: var(--kol-oq-ab-inverse-04); }
291
+ .bg-oq-ab-inverse-08 { background-color: var(--kol-oq-ab-inverse-08); }
292
+ .bg-oq-ab-inverse-12 { background-color: var(--kol-oq-ab-inverse-12); }
293
+ .bg-oq-ab-inverse-16 { background-color: var(--kol-oq-ab-inverse-16); }
294
+ .bg-oq-ab-inverse-24 { background-color: var(--kol-oq-ab-inverse-24); }
295
+ .bg-oq-ab-inverse-32 { background-color: var(--kol-oq-ab-inverse-32); }
296
+ .bg-oq-ab-inverse-40 { background-color: var(--kol-oq-ab-inverse-40); }
297
+ .bg-oq-ab-inverse-48 { background-color: var(--kol-oq-ab-inverse-48); }
298
+ .bg-oq-ab-inverse-64 { background-color: var(--kol-oq-ab-inverse-64); }
299
+ .bg-oq-ab-inverse-72 { background-color: var(--kol-oq-ab-inverse-72); }
300
+ .bg-oq-ab-inverse-80 { background-color: var(--kol-oq-ab-inverse-80); }
301
+ .bg-oq-ab-inverse-88 { background-color: var(--kol-oq-ab-inverse-88); }
302
+ .bg-oq-ab-inverse-96 { background-color: var(--kol-oq-ab-inverse-96); }
303
+
304
+ .hover\:bg-oq-ab-01:hover { background-color: var(--kol-oq-ab-01); }
305
+ .hover\:bg-oq-ab-02:hover { background-color: var(--kol-oq-ab-02); }
306
+ .hover\:bg-oq-ab-04:hover { background-color: var(--kol-oq-ab-04); }
307
+ .hover\:bg-oq-ab-08:hover { background-color: var(--kol-oq-ab-08); }
308
+ .hover\:bg-oq-ab-12:hover { background-color: var(--kol-oq-ab-12); }
309
+ .hover\:bg-oq-ab-16:hover { background-color: var(--kol-oq-ab-16); }
310
+ .hover\:bg-oq-ab-24:hover { background-color: var(--kol-oq-ab-24); }
311
+ .hover\:bg-oq-ab-32:hover { background-color: var(--kol-oq-ab-32); }
312
+ .hover\:bg-oq-ab-40:hover { background-color: var(--kol-oq-ab-40); }
313
+ .hover\:bg-oq-ab-48:hover { background-color: var(--kol-oq-ab-48); }
314
+ .hover\:bg-oq-ab-64:hover { background-color: var(--kol-oq-ab-64); }
315
+ .hover\:bg-oq-ab-72:hover { background-color: var(--kol-oq-ab-72); }
316
+ .hover\:bg-oq-ab-80:hover { background-color: var(--kol-oq-ab-80); }
317
+ .hover\:bg-oq-ab-88:hover { background-color: var(--kol-oq-ab-88); }
318
+ .hover\:bg-oq-ab-96:hover { background-color: var(--kol-oq-ab-96); }
319
+
320
+ .hover\:bg-oq-ab-inverse-01:hover { background-color: var(--kol-oq-ab-inverse-01); }
321
+ .hover\:bg-oq-ab-inverse-02:hover { background-color: var(--kol-oq-ab-inverse-02); }
322
+ .hover\:bg-oq-ab-inverse-04:hover { background-color: var(--kol-oq-ab-inverse-04); }
323
+ .hover\:bg-oq-ab-inverse-08:hover { background-color: var(--kol-oq-ab-inverse-08); }
324
+ .hover\:bg-oq-ab-inverse-12:hover { background-color: var(--kol-oq-ab-inverse-12); }
325
+ .hover\:bg-oq-ab-inverse-16:hover { background-color: var(--kol-oq-ab-inverse-16); }
326
+ .hover\:bg-oq-ab-inverse-24:hover { background-color: var(--kol-oq-ab-inverse-24); }
327
+ .hover\:bg-oq-ab-inverse-32:hover { background-color: var(--kol-oq-ab-inverse-32); }
328
+ .hover\:bg-oq-ab-inverse-40:hover { background-color: var(--kol-oq-ab-inverse-40); }
329
+ .hover\:bg-oq-ab-inverse-48:hover { background-color: var(--kol-oq-ab-inverse-48); }
330
+ .hover\:bg-oq-ab-inverse-64:hover { background-color: var(--kol-oq-ab-inverse-64); }
331
+ .hover\:bg-oq-ab-inverse-72:hover { background-color: var(--kol-oq-ab-inverse-72); }
332
+ .hover\:bg-oq-ab-inverse-80:hover { background-color: var(--kol-oq-ab-inverse-80); }
333
+ .hover\:bg-oq-ab-inverse-88:hover { background-color: var(--kol-oq-ab-inverse-88); }
334
+ .hover\:bg-oq-ab-inverse-96:hover { background-color: var(--kol-oq-ab-inverse-96); }
335
+
336
+ .text-oq-ab-01 { color: var(--kol-oq-ab-01); }
337
+ .text-oq-ab-02 { color: var(--kol-oq-ab-02); }
338
+ .text-oq-ab-04 { color: var(--kol-oq-ab-04); }
339
+ .text-oq-ab-08 { color: var(--kol-oq-ab-08); }
340
+ .text-oq-ab-12 { color: var(--kol-oq-ab-12); }
341
+ .text-oq-ab-16 { color: var(--kol-oq-ab-16); }
342
+ .text-oq-ab-24 { color: var(--kol-oq-ab-24); }
343
+ .text-oq-ab-32 { color: var(--kol-oq-ab-32); }
344
+ .text-oq-ab-40 { color: var(--kol-oq-ab-40); }
345
+ .text-oq-ab-48 { color: var(--kol-oq-ab-48); }
346
+ .text-oq-ab-64 { color: var(--kol-oq-ab-64); }
347
+ .text-oq-ab-72 { color: var(--kol-oq-ab-72); }
348
+ .text-oq-ab-80 { color: var(--kol-oq-ab-80); }
349
+ .text-oq-ab-88 { color: var(--kol-oq-ab-88); }
350
+ .text-oq-ab-96 { color: var(--kol-oq-ab-96); }
351
+
352
+ .text-oq-ab-inverse-01 { color: var(--kol-oq-ab-inverse-01); }
353
+ .text-oq-ab-inverse-02 { color: var(--kol-oq-ab-inverse-02); }
354
+ .text-oq-ab-inverse-04 { color: var(--kol-oq-ab-inverse-04); }
355
+ .text-oq-ab-inverse-08 { color: var(--kol-oq-ab-inverse-08); }
356
+ .text-oq-ab-inverse-12 { color: var(--kol-oq-ab-inverse-12); }
357
+ .text-oq-ab-inverse-16 { color: var(--kol-oq-ab-inverse-16); }
358
+ .text-oq-ab-inverse-24 { color: var(--kol-oq-ab-inverse-24); }
359
+ .text-oq-ab-inverse-32 { color: var(--kol-oq-ab-inverse-32); }
360
+ .text-oq-ab-inverse-40 { color: var(--kol-oq-ab-inverse-40); }
361
+ .text-oq-ab-inverse-48 { color: var(--kol-oq-ab-inverse-48); }
362
+ .text-oq-ab-inverse-64 { color: var(--kol-oq-ab-inverse-64); }
363
+ .text-oq-ab-inverse-72 { color: var(--kol-oq-ab-inverse-72); }
364
+ .text-oq-ab-inverse-80 { color: var(--kol-oq-ab-inverse-80); }
365
+ .text-oq-ab-inverse-88 { color: var(--kol-oq-ab-inverse-88); }
366
+ .text-oq-ab-inverse-96 { color: var(--kol-oq-ab-inverse-96); }
367
+
368
+ .border-oq-ab-01 { border-color: var(--kol-oq-ab-01); }
369
+ .border-oq-ab-02 { border-color: var(--kol-oq-ab-02); }
370
+ .border-oq-ab-04 { border-color: var(--kol-oq-ab-04); }
371
+ .border-oq-ab-08 { border-color: var(--kol-oq-ab-08); }
372
+ .border-oq-ab-12 { border-color: var(--kol-oq-ab-12); }
373
+ .border-oq-ab-16 { border-color: var(--kol-oq-ab-16); }
374
+ .border-oq-ab-24 { border-color: var(--kol-oq-ab-24); }
375
+ .border-oq-ab-32 { border-color: var(--kol-oq-ab-32); }
376
+ .border-oq-ab-40 { border-color: var(--kol-oq-ab-40); }
377
+ .border-oq-ab-48 { border-color: var(--kol-oq-ab-48); }
378
+ .border-oq-ab-64 { border-color: var(--kol-oq-ab-64); }
379
+ .border-oq-ab-72 { border-color: var(--kol-oq-ab-72); }
380
+ .border-oq-ab-80 { border-color: var(--kol-oq-ab-80); }
381
+ .border-oq-ab-88 { border-color: var(--kol-oq-ab-88); }
382
+ .border-oq-ab-96 { border-color: var(--kol-oq-ab-96); }
383
+
384
+ .border-oq-ab-inverse-01 { border-color: var(--kol-oq-ab-inverse-01); }
385
+ .border-oq-ab-inverse-02 { border-color: var(--kol-oq-ab-inverse-02); }
386
+ .border-oq-ab-inverse-04 { border-color: var(--kol-oq-ab-inverse-04); }
387
+ .border-oq-ab-inverse-08 { border-color: var(--kol-oq-ab-inverse-08); }
388
+ .border-oq-ab-inverse-12 { border-color: var(--kol-oq-ab-inverse-12); }
389
+ .border-oq-ab-inverse-16 { border-color: var(--kol-oq-ab-inverse-16); }
390
+ .border-oq-ab-inverse-24 { border-color: var(--kol-oq-ab-inverse-24); }
391
+ .border-oq-ab-inverse-32 { border-color: var(--kol-oq-ab-inverse-32); }
392
+ .border-oq-ab-inverse-40 { border-color: var(--kol-oq-ab-inverse-40); }
393
+ .border-oq-ab-inverse-48 { border-color: var(--kol-oq-ab-inverse-48); }
394
+ .border-oq-ab-inverse-64 { border-color: var(--kol-oq-ab-inverse-64); }
395
+ .border-oq-ab-inverse-72 { border-color: var(--kol-oq-ab-inverse-72); }
396
+ .border-oq-ab-inverse-80 { border-color: var(--kol-oq-ab-inverse-80); }
397
+ .border-oq-ab-inverse-88 { border-color: var(--kol-oq-ab-inverse-88); }
398
+ .border-oq-ab-inverse-96 { border-color: var(--kol-oq-ab-inverse-96); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-theme",
3
- "version": "0.92.0",
3
+ "version": "0.94.0",
4
4
  "description": "KOL (Kolkrabbi) design-system tokens + base CSS — brand-neutral. The canonical token/cascade layer every other KOL package and consumer builds on.",
5
5
  "license": "MIT",
6
6
  "type": "module",