@kolkrabbi/kol-theme 0.162.0 → 0.164.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/kol-color.css CHANGED
@@ -221,6 +221,12 @@
221
221
  color: var(--kol-surface-on-inverse);
222
222
  }
223
223
 
224
+ /* the sunken surface had a token and no class (2026-10-01) — the preview stage reached for
225
+ * `bg-[var(--kol-surface-sunken)]`. Ground only: what sits in a well keeps its own ink. */
226
+ .bg-surface-sunken {
227
+ background-color: var(--kol-surface-sunken);
228
+ }
229
+
224
230
  /* ---------------------------------------------------------------------------
225
231
  * Elevation Utilities
226
232
  * --------------------------------------------------------------------------- */
@@ -1315,7 +1315,7 @@ a.kol-icon-frame {
1315
1315
  * field to the token's line-height (h-4 / h-[18px] / h-[22px]), so a 16px face
1316
1316
  * in an unlifted 16px box would clip. */
1317
1317
  /* `.kol-control--bare` is a MARKER, not chrome (OverlaySearchFieldZoomsIOS,
1318
- * 2026-09-01): SearchInput's `bare` body plan — the overlay palette's field —
1318
+ * 2026-09-01): SearchInput's `bare` body plan — the search modal's field —
1319
1319
  * sits in a plain <label>, outside both shells, and was the field that put a
1320
1320
  * whole mobile review in a zoomed page. The marker carries no rules of its
1321
1321
  * own; it exists so the floor below keys on every body plan the DS ships,
@@ -1324,9 +1324,14 @@ a.kol-icon-frame {
1324
1324
  /* THE TOUCH RUNG (D5, 2026-09-29 — see kol-base-tokens.css): every text control types 16 / 22 on
1325
1325
  * touch, so a derived box grows exactly as the pinned tokens do — xs/sm 4+4+22+2 = 32, md
1326
1326
  * 6+6+22+2 = 36, lg 40. Two classes, so it outranks the size's own kol-mono-* class. */
1327
- .kol-btn.kol-btn-xs, .kol-btn.kol-btn-sm, .kol-btn.kol-btn-md, .kol-btn.kol-btn-lg,
1327
+ /* NOT INSIDE A HARDWARE PANEL (2026-10-02, kol-monitor's Patch module): a module is drawn at the
1328
+ * rack's own zoom, and its `xs` controls are the PANEL rung — 8px type in a 22px box on a 96px
1329
+ * plate. The rung lifted its dropdown to 16 / 32 and it no longer fitted. `.kol-hw-panel` marks
1330
+ * the plate (ModuleFrame) and a list portalled out of one (Dropdown); `:where()` keeps the
1331
+ * rule's specificity where it was. The box tokens are pinned back in kol-components-controls.css. */
1332
+ :is(.kol-btn.kol-btn-xs, .kol-btn.kol-btn-sm, .kol-btn.kol-btn-md, .kol-btn.kol-btn-lg,
1328
1333
  .kol-control.kol-control-xs, .kol-control.kol-control-sm, .kol-control.kol-control-md, .kol-control.kol-control-lg,
1329
- .kol-seg .kol-seg-cell, .kol-menu-btn.kol-menu-btn {
1334
+ .kol-seg .kol-seg-cell, .kol-menu-btn.kol-menu-btn):where(:not(.kol-hw-panel, .kol-hw-panel *)) {
1330
1335
  font-size: 16px;
1331
1336
  line-height: 22px;
1332
1337
  }
@@ -34,3 +34,28 @@
34
34
  --kol-ctl-signal-input: #4ade80;
35
35
  --kol-ctl-cv-attenuate: #497DA2;
36
36
  }
37
+
38
+ /* A HARDWARE PANEL KEEPS ITS DESK SIZES ON TOUCH (2026-10-02). The touch rung (kol-base-tokens.css)
39
+ * grows every control box on a coarse pointer — xs 22 → 32 — so a finger can hit app chrome. A
40
+ * module is not app chrome: it is drawn at the rack's zoom, which is how it is made reachable, and
41
+ * its controls are sized to the plate. `.kol-hw-panel` is ModuleFrame's root, and Dropdown puts it
42
+ * on a list it portals out of one. The type half of the rung skips the same marker
43
+ * (kol-components-atoms.css). */
44
+ @media (pointer: coarse) {
45
+ .kol-hw-panel {
46
+ --kol-ctl-xs: 22px;
47
+ --kol-ctl-sm: 26px;
48
+ --kol-ctl-md: 32px;
49
+ --kol-ctl-lg: 40px;
50
+ }
51
+ }
52
+
53
+ /* THE PLATE IS THE GROUND (2026-10-02, kol-monitor's Patch module). An outline or ghost dropdown
54
+ * paints its list in `--kol-tone-ground` — "the ground it sits on", `surface-primary` unless
55
+ * something says otherwise (kol-components-molecules.css, TONE). A module's plate is
56
+ * `surface-secondary`, so the list came out page-coloured, darker than the trigger above it. The
57
+ * default plate says what it is; a consumer that passes its own plate class sets the ground with it. */
58
+ .kol-hw-panel.bg-surface-secondary {
59
+ --kol-tone-ground: var(--kol-surface-secondary);
60
+ }
61
+
@@ -211,79 +211,14 @@
211
211
  font-size: 0.7rem;
212
212
  }
213
213
 
214
- .font-viewer-slider-group input[type='range'] {
215
- flex: 1;
216
- height: 15px;
217
- padding: 7px 0;
218
- cursor: pointer;
219
- background: linear-gradient(var(--fv-black), var(--fv-black)) center/100% 1px no-repeat;
220
- -webkit-appearance: none;
221
- appearance: none;
222
- }
223
-
224
- .font-viewer-slider-group input[type='range']::-webkit-slider-runnable-track,
225
- .font-viewer-slider-group input[type='range']::-moz-range-track {
226
- width: 100%;
227
- height: 1px;
228
- background: transparent;
229
- }
230
-
231
- .font-viewer-slider-group input[type='range']::-webkit-slider-runnable-track {
232
- border-radius: 9999px;
233
- }
234
-
235
- .font-viewer-slider-group input[type='range']::-webkit-slider-thumb {
236
- -webkit-appearance: none;
237
- appearance: none;
238
- height: 15px;
239
- width: 15px;
240
- border-radius: 50%;
241
- background: var(--fv-black);
242
- cursor: pointer;
243
- margin-top: 0;
244
- }
245
-
246
- .font-viewer-slider-group input[type='range']::-moz-range-thumb {
247
- height: 15px;
248
- width: 15px;
249
- border-radius: 50%;
250
- background: var(--fv-black);
251
- cursor: pointer;
252
- }
253
-
254
- .font-viewer-slider-group input[type='range']::-moz-range-track {
255
- border-radius: 9999px;
256
- }
257
-
258
- .font-viewer-slider-group input[type='range']::-ms-track {
259
- width: 100%;
260
- height: 1px;
261
- background: transparent;
262
- border-color: transparent;
263
- color: transparent;
264
- }
265
-
266
- .font-viewer-slider-group input[type='range']::-ms-fill-lower,
267
- .font-viewer-slider-group input[type='range']::-ms-fill-upper {
268
- background: var(--fv-black);
269
- }
270
-
271
- .font-viewer-slider-group input[type='range']::-ms-thumb {
272
- height: 15px;
273
- width: 15px;
274
- border-radius: 50%;
275
- background: var(--fv-black);
276
- cursor: pointer;
277
- }
278
-
279
- .font-viewer-slider-group input[type='range']::-webkit-slider-thumb,
280
- .font-viewer-slider-group input[type='range']::-moz-range-thumb {
281
- height: 15px;
282
- width: 15px;
283
- border-radius: 50%;
284
- background: var(--fv-black);
285
- cursor: pointer;
286
- }
214
+ /* The range is `Slider` now (2026-10-02 — the ~65 lines that drew one here are in
215
+ * `_tmp/2026-10-02-foundry-slider-css/`). The viewer keeps its own two-color scheme (`--fv-*`,
216
+ * swapped at runtime), so the slider's track, knob and readout are bound to it here. */
217
+ .font-viewer-slider-group { --kol-slider-track: var(--fv-black); }
218
+ .font-viewer-slider-group .slider-black::-webkit-slider-thumb { background: var(--fv-black); }
219
+ .font-viewer-slider-group .slider-black::-moz-range-thumb { background: var(--fv-black); }
220
+ .font-viewer-slider-group label,
221
+ .font-viewer-slider-group span { color: var(--fv-black); background: transparent; padding: 0; }
287
222
 
288
223
  .font-viewer-variable-axes {
289
224
  margin-top: 12px;
@@ -142,6 +142,12 @@
142
142
  * variables on the panel; the list scrolls at the ceiling as it always could. */
143
143
  .kol-dd-list {
144
144
  padding: var(--kol-spacing-1);
145
+ /* THE ROWS SIT ON THE TRIGGER'S TEXT EDGE (2026-10-02). The trigger always carries a 1px border
146
+ * (transparent on a filled tone); the panel carries one only on outline. So a filled panel's
147
+ * rows stood 1px left of the trigger's text. The list makes up the difference: 4px, plus the
148
+ * trigger's 1, less whatever border the panel has. (`0px`, not `0`, in the tone bundles — a
149
+ * unitless zero cannot be subtracted from a length.) */
150
+ padding-inline: calc(var(--kol-spacing-1) + 1px - var(--kol-tone-panel-border-w, 0px));
145
151
  overflow-y: auto;
146
152
  min-height: 0;
147
153
  max-height: calc(var(--kol-dd-max-rows, 10) * var(--kol-dd-row-h, 2rem) + var(--kol-spacing-1) * 2);
@@ -944,7 +950,7 @@
944
950
  color: var(--kol-oq-96);
945
951
  /* NO BORDER, NO SHADOW (user 2026-08-01). Both were tried and both were
946
952
  * wrong: the shadow was another product's floating-card idiom, and the
947
- * hairline left an empty palette reading as a bordered empty box. The SCRIM
953
+ * hairline left an empty search modal reading as a bordered empty box. The SCRIM
948
954
  * is the separation — a 60% tint is already a stronger edge than an
949
955
  * 8%-opacity line. */
950
956
  /* `sm` — the radius this repo's chrome actually uses. */
@@ -1628,8 +1634,8 @@
1628
1634
  /* THE QUICKTIME BAR (PlaybackBarAndAudioSheet, kol-r2b2 2026-08-27 — ruled
1629
1635
  * against the reference). White glyphs on the frosted strip whatever the theme:
1630
1636
  * the ghost IconFrame paints --kol-oq-48, a theme color, and the bar sits on
1631
- * media, not on the theme. The scrubber is a native range — a 2px track at 40 %
1632
- * white, a tall 4 × 28 white pill for the knob — pseudo-elements, so CSS. */
1637
+ * media, not on the theme. The scrubber is a native range — a 2px track, a tall
1638
+ * 4 × 28 pill for the knob — pseudo-elements, so CSS. */
1633
1639
  .kol-playback-bar .kol-icon-frame { color: var(--kol-color-ab-white); opacity: 0.8; }
1634
1640
  .kol-playback-bar .kol-icon-frame:hover,
1635
1641
  .kol-playback-bar .kol-icon-frame:focus-visible { opacity: 1; }
@@ -1641,18 +1647,21 @@
1641
1647
  outline: none;
1642
1648
  cursor: pointer;
1643
1649
  }
1644
- .kol-playback-scrub::-webkit-slider-runnable-track { height: 2px; border-radius: 1px; background: color-mix(in srgb, var(--kol-color-ab-white) 40%, transparent); }
1645
- .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); }
1646
- .kol-playback-scrub::-moz-range-track { height: 2px; border-radius: 1px; background: color-mix(in srgb, var(--kol-color-ab-white) 40%, transparent); }
1647
- .kol-playback-scrub::-moz-range-thumb { width: 4px; height: 28px; border: 0; border-radius: 2px; background: var(--kol-color-ab-white); }
1650
+ /* THE SCRUBBER IS A SLIDER VARIANT (2026-10-02, `Slider variant="scrub"`), so at rest it takes the
1651
+ * THEME's ink — an opaque rail and knob, the look the docked bar already had — and reads the
1652
+ * slider's own `--kol-slider-track` seam. Only the bar FLOATING over media paints it white. */
1653
+ .kol-playback-scrub::-webkit-slider-runnable-track { height: 2px; border-radius: 1px; background: var(--kol-slider-track, var(--kol-oq-24)); }
1654
+ .kol-playback-scrub::-webkit-slider-thumb { -webkit-appearance: none; width: 4px; height: 28px; margin-top: -13px; border-radius: 2px; background: var(--kol-oq-80); }
1655
+ .kol-playback-scrub::-moz-range-track { height: 2px; border-radius: 1px; background: var(--kol-slider-track, var(--kol-oq-24)); }
1656
+ .kol-playback-scrub::-moz-range-thumb { width: 4px; height: 28px; border: 0; border-radius: 2px; background: var(--kol-oq-80); }
1657
+ .kol-playback-bar:not(.kol-playback-bar--docked) .kol-playback-scrub::-webkit-slider-runnable-track { background: color-mix(in srgb, var(--kol-color-ab-white) 40%, transparent); }
1658
+ .kol-playback-bar:not(.kol-playback-bar--docked) .kol-playback-scrub::-webkit-slider-thumb { background: var(--kol-color-ab-white); }
1659
+ .kol-playback-bar:not(.kol-playback-bar--docked) .kol-playback-scrub::-moz-range-track { background: color-mix(in srgb, var(--kol-color-ab-white) 40%, transparent); }
1660
+ .kol-playback-bar:not(.kol-playback-bar--docked) .kol-playback-scrub::-moz-range-thumb { background: var(--kol-color-ab-white); }
1648
1661
  /* DOCKED (2026-09-23) — the bar in the Quick Look window's footer. It sits on the window, not on
1649
1662
  * media, so it takes the theme's ink on an opaque plate instead of white on a dark wash. */
1650
1663
  .kol-playback-bar--docked { background: var(--kol-oq-08); color: var(--kol-oq-80); }
1651
1664
  .kol-playback-bar--docked .kol-icon-frame { color: var(--kol-oq-80); }
1652
- .kol-playback-bar--docked .kol-playback-scrub::-webkit-slider-runnable-track { background: var(--kol-oq-24); }
1653
- .kol-playback-bar--docked .kol-playback-scrub::-webkit-slider-thumb { background: var(--kol-oq-80); }
1654
- .kol-playback-bar--docked .kol-playback-scrub::-moz-range-track { background: var(--kol-oq-24); }
1655
- .kol-playback-bar--docked .kol-playback-scrub::-moz-range-thumb { background: var(--kol-oq-80); }
1656
1665
 
1657
1666
  /* ColumnBrowser rows — ONE SELECTED STATE (ColumnBrowserSeams, kol-r2b2
1658
1667
  * 2026-08-28; user: "ONLY one selected state can exist, not TWO"). The row's
@@ -1983,7 +1992,7 @@
1983
1992
  --kol-tone-pressed-image: none;
1984
1993
  --kol-tone-pressed-fg: var(--kol-surface-primary);
1985
1994
  --kol-tone-panel-bg: var(--kol-surface-secondary);
1986
- --kol-tone-panel-border-w: 0;
1995
+ --kol-tone-panel-border-w: 0px;
1987
1996
  --kol-tone-panel-border: transparent;
1988
1997
  }
1989
1998
  /* `secondary` PAINTS THE PAGE SURFACE (tone-secondary-is-inverse, kol-client-olina
@@ -2008,7 +2017,7 @@
2008
2017
  --kol-tone-pressed-image: none;
2009
2018
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2010
2019
  --kol-tone-panel-bg: var(--kol-surface-primary);
2011
- --kol-tone-panel-border-w: 0;
2020
+ --kol-tone-panel-border-w: 0px;
2012
2021
  --kol-tone-panel-border: transparent;
2013
2022
  }
2014
2023
  /* `inverted` — the text color as fill: Button's / IconFrame's `secondary`
@@ -2032,7 +2041,7 @@
2032
2041
  --kol-tone-pressed-image: none;
2033
2042
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2034
2043
  --kol-tone-panel-bg: var(--kol-surface-on-primary);
2035
- --kol-tone-panel-border-w: 0;
2044
+ --kol-tone-panel-border-w: 0px;
2036
2045
  --kol-tone-panel-border: transparent;
2037
2046
  }
2038
2047
  .kol-tone-outline,
@@ -2070,7 +2079,7 @@
2070
2079
  --kol-tone-pressed-image: none;
2071
2080
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2072
2081
  --kol-tone-panel-bg: var(--kol-tone-ground, var(--kol-surface-primary));
2073
- --kol-tone-panel-border-w: 0;
2082
+ --kol-tone-panel-border-w: 0px;
2074
2083
  --kol-tone-panel-border: transparent;
2075
2084
  }
2076
2085
  .kol-tone-grey,
@@ -2089,7 +2098,7 @@
2089
2098
  --kol-tone-pressed-image: none;
2090
2099
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2091
2100
  --kol-tone-panel-bg: var(--kol-oq-12);
2092
- --kol-tone-panel-border-w: 0;
2101
+ --kol-tone-panel-border-w: 0px;
2093
2102
  --kol-tone-panel-border: transparent;
2094
2103
  }
2095
2104
  .kol-tone-sunken,
@@ -2108,7 +2117,7 @@
2108
2117
  --kol-tone-pressed-image: linear-gradient(var(--kol-fg-08), var(--kol-fg-08));
2109
2118
  --kol-tone-pressed-fg: var(--kol-fg-96);
2110
2119
  --kol-tone-panel-bg: var(--kol-surface-sunken);
2111
- --kol-tone-panel-border-w: 0;
2120
+ --kol-tone-panel-border-w: 0px;
2112
2121
  --kol-tone-panel-border: transparent;
2113
2122
  }
2114
2123
  :where(.kol-btn-nav) {
@@ -2126,7 +2135,7 @@
2126
2135
  --kol-tone-pressed-image: none;
2127
2136
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2128
2137
  --kol-tone-panel-bg: var(--kol-tone-ground, var(--kol-surface-primary));
2129
- --kol-tone-panel-border-w: 0;
2138
+ --kol-tone-panel-border-w: 0px;
2130
2139
  --kol-tone-panel-border: transparent;
2131
2140
  }
2132
2141
  :where(.kol-icon-frame-nav) {
@@ -2144,7 +2153,7 @@
2144
2153
  --kol-tone-pressed-image: none;
2145
2154
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2146
2155
  --kol-tone-panel-bg: var(--kol-tone-ground, var(--kol-surface-primary));
2147
- --kol-tone-panel-border-w: 0;
2156
+ --kol-tone-panel-border-w: 0px;
2148
2157
  --kol-tone-panel-border: transparent;
2149
2158
  }
2150
2159
  :where(.kol-control--plain) {
@@ -2162,7 +2171,7 @@
2162
2171
  --kol-tone-pressed-image: none;
2163
2172
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2164
2173
  --kol-tone-panel-bg: var(--kol-tone-ground, var(--kol-surface-primary));
2165
- --kol-tone-panel-border-w: 0;
2174
+ --kol-tone-panel-border-w: 0px;
2166
2175
  --kol-tone-panel-border: transparent;
2167
2176
  }
2168
2177
  :where(.kol-btn-danger, .kol-icon-frame-danger) {
@@ -2180,7 +2189,7 @@
2180
2189
  --kol-tone-pressed-image: none;
2181
2190
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2182
2191
  --kol-tone-panel-bg: var(--ui-error);
2183
- --kol-tone-panel-border-w: 0;
2192
+ --kol-tone-panel-border-w: 0px;
2184
2193
  --kol-tone-panel-border: transparent;
2185
2194
  }
2186
2195
  :where(.kol-btn-accent, .kol-icon-frame-accent) {
@@ -2198,14 +2207,14 @@
2198
2207
  --kol-tone-pressed-image: none;
2199
2208
  --kol-tone-pressed-fg: var(--kol-surface-primary);
2200
2209
  --kol-tone-panel-bg: var(--kol-accent-primary);
2201
- --kol-tone-panel-border-w: 0;
2210
+ --kol-tone-panel-border-w: 0px;
2202
2211
  --kol-tone-panel-border: transparent;
2203
2212
  }
2204
2213
 
2205
2214
  /* ─── the families that keep their own plates ─── */
2206
2215
  .kol-view-toggle { background-color: var(--kol-tone-bg, var(--kol-surface-secondary)); }
2207
2216
  /* keyboard focus in the well wears the DS ring, not the browser's blue (a button regains focus when
2208
- * the search palette it opened closes, 2026-09-23) */
2217
+ * the search modal it opened closes, 2026-09-23) */
2209
2218
  .kol-view-toggle button:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--kol-oq-24); }
2210
2219
  /* the sunken well's chip ladder (rest · +fg-04 hover · +fg-08 selected) — on the
2211
2220
  * element, or inherited from a sunken wrapper */
@@ -134,6 +134,36 @@
134
134
  padding-inline-start: var(--kol-pad-chrome-x);
135
135
  }
136
136
 
137
+ /* THE RAIL'S THIRD STATE — ICONS (user ruling 2026-10-02: *"I wanted that icon state on the rails"*).
138
+ * Beside visible and hidden: the left rail as a strip, one glyph per group. Its grid track is the
139
+ * framework's collapsed-rail width (`--kol-sidenav-w-collapsed`, set in ShellLayout), so the strip
140
+ * drops the open rail's inner inset and centres its glyphs.
141
+ *
142
+ * HOVER OPENS IT OVER THE PAGE (`.is-peek`, stamped by ShellNavColumn): the column grows to the
143
+ * open rail's width past its own track, on the sticky tier with the page's surface behind it, so
144
+ * the page under it does not reflow — a hover must not move the thing you are reading. */
145
+ .shell-rail--icons {
146
+ padding-inline-end: 0;
147
+ }
148
+ .shell-rail--icons.is-peek {
149
+ width: var(--kol-shell-nav-w);
150
+ z-index: var(--kol-z-sticky);
151
+ background: var(--kol-surface-primary);
152
+ padding-inline-end: var(--kol-pad-chrome-x);
153
+ }
154
+ .shell-rail-icons {
155
+ display: flex;
156
+ flex-direction: column;
157
+ align-items: center;
158
+ gap: var(--kol-spacing-1);
159
+ }
160
+ /* the group you are in: the rail's active wash HELD ON (the 2026-08-12 ruling `.kol-shell-rail`
161
+ * already carries — navigation is location, never a pressed tool) */
162
+ .shell-rail-icons .kol-btn-nav[aria-current="page"] {
163
+ background-color: var(--kol-oq-04);
164
+ color: var(--kol-oq-96);
165
+ }
166
+
137
167
  .shell-main {
138
168
  min-width: 0;
139
169
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-theme",
3
- "version": "0.162.0",
3
+ "version": "0.164.0",
4
4
  "description": "Tokens and base CSS",
5
5
  "license": "MIT",
6
6
  "type": "module",