@kolkrabbi/kol-theme 0.83.0 → 0.85.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-animation.css +355 -0
- package/kol-components-atoms.css +0 -22
- package/kol-components-chess.css +3 -42
- package/kol-components-molecules.css +16 -133
- package/kol-components-organisms.css +0 -36
- package/kol-components-styleguide.css +0 -4
- package/kol-core.css +5 -0
- package/kol-theme.css +5 -0
- package/kol-utilities.css +0 -32
- package/package.json +1 -1
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kol-animation.css — THE MOTION SHEET (user ruling 2026-08-28: "shouldn't we
|
|
3
|
+
* localise animation to its own css?" — the rule he had given before and that
|
|
4
|
+
* every agent agreed to and none of us carried out).
|
|
5
|
+
*
|
|
6
|
+
* WHY ONE FILE. Motion is read as a SET: you tune the underline, the reveal and
|
|
7
|
+
* the zoom in one sitting. Until this file it was spread across four component
|
|
8
|
+
* sheets — and the five `prefers-reduced-motion` blocks were the tell, each one
|
|
9
|
+
* written by whoever happened to be in that file. Nobody could see the estate's
|
|
10
|
+
* motion whole, so nobody could keep it consistent.
|
|
11
|
+
*
|
|
12
|
+
* WHAT LIVES HERE
|
|
13
|
+
* · every `@keyframes` in the system (the gate below enforces it)
|
|
14
|
+
* · every NAMED motion class — a class whose whole job is to move something
|
|
15
|
+
* · every `prefers-reduced-motion` block
|
|
16
|
+
* · the JS mirror of these numbers is `@kolkrabbi/kol-component/utilities/motion.js`
|
|
17
|
+
* (gsap tweens and framer springs read the same durations and curves)
|
|
18
|
+
*
|
|
19
|
+
* WHAT DOES NOT. A bare `transition:` inside a component's own rest rule —
|
|
20
|
+
* `.kol-btn`'s background-color, `.kol-card`'s border-color. Pulling those out
|
|
21
|
+
* means two rules for one selector, and two rules for one selector drift; the
|
|
22
|
+
* rest rule owns its own easing. Named animations move, per-property easing stays.
|
|
23
|
+
*
|
|
24
|
+
* THE GATE: `scripts/validate-motion.mjs` (the 23rd) fails any `@keyframes`
|
|
25
|
+
* declared outside this file, so the sheet cannot rot back into four.
|
|
26
|
+
*
|
|
27
|
+
* Imported LAST by both entries (kol-theme.css and kol-core.css), so a motion
|
|
28
|
+
* class out-ranks the component chrome it moves.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
32
|
+
* KEYFRAMES — all of them, wherever they are used
|
|
33
|
+
* ═════════════════════════════════════════════════════════════════════ */
|
|
34
|
+
|
|
35
|
+
/* The chess pack's four. RENAMED on the way in (2026-08-28): they were `pulse`,
|
|
36
|
+
* `fadeIn`, `numberTick` and `lineDraw` — unprefixed globals, against the
|
|
37
|
+
* `kol-*` namespace law, and a keyframe name is global no matter which file
|
|
38
|
+
* declares it. In one pack's sheet that was a latent collision; in the shared
|
|
39
|
+
* motion sheet it would be a live one, since every app loads this file. Their
|
|
40
|
+
* users in kol-components-chess.css move with them. */
|
|
41
|
+
@keyframes kol-chess-pulse {
|
|
42
|
+
0%, 100% {
|
|
43
|
+
opacity: 1;
|
|
44
|
+
}
|
|
45
|
+
50% {
|
|
46
|
+
opacity: 0.4;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@keyframes kol-chess-fade-in {
|
|
51
|
+
from {
|
|
52
|
+
opacity: 0;
|
|
53
|
+
transform: translateY(10px);
|
|
54
|
+
}
|
|
55
|
+
to {
|
|
56
|
+
opacity: 1;
|
|
57
|
+
transform: translateY(0);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@keyframes kol-chess-number-tick {
|
|
62
|
+
from {
|
|
63
|
+
transform: translateY(-2px);
|
|
64
|
+
opacity: 0.8;
|
|
65
|
+
}
|
|
66
|
+
to {
|
|
67
|
+
transform: translateY(0);
|
|
68
|
+
opacity: 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@keyframes kol-chess-line-draw {
|
|
73
|
+
from {
|
|
74
|
+
stroke-dashoffset: 100;
|
|
75
|
+
}
|
|
76
|
+
to {
|
|
77
|
+
stroke-dashoffset: 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@keyframes kol-combo-fade {
|
|
82
|
+
from { opacity: 0.2; transform: translateY(6px); }
|
|
83
|
+
to { opacity: 1; transform: none; }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
87
|
+
* NAMED MOTION — a class whose whole job is to move something
|
|
88
|
+
* ═════════════════════════════════════════════════════════════════════ */
|
|
89
|
+
|
|
90
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
91
|
+
* ContentCollection — src/organisms/ContentCollection.jsx (2026-08-15)
|
|
92
|
+
* The enter stagger the collection owns; cards never animate themselves.
|
|
93
|
+
* Delay is set per item inline; the curve is the house token. */
|
|
94
|
+
.kol-collection-item {
|
|
95
|
+
animation: kol-collection-in 300ms var(--kol-ease-house) both;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@keyframes kol-collection-in {
|
|
99
|
+
from { opacity: 0; transform: translateY(6px); }
|
|
100
|
+
to { opacity: 1; transform: none; }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Link underline — the animated hover affordance: draws in left→right on
|
|
104
|
+
* hover/focus, retracts right→left on leave (transform-origin swap, not a
|
|
105
|
+
* fade). Line is currentColor so it rides the text at any scale. Minted from
|
|
106
|
+
* kol-website's animations.css (NavLinkUnderline, 2026-08-12); DS version
|
|
107
|
+
* adds :focus-visible parity and reduced-motion handling.
|
|
108
|
+
* Thickness knob: --kol-link-underline-size (2px default — fine at mono-14,
|
|
109
|
+
* a heading-01 link may want 3px). */
|
|
110
|
+
.kol-link-underline {
|
|
111
|
+
position: relative;
|
|
112
|
+
}
|
|
113
|
+
.kol-link-underline::after {
|
|
114
|
+
content: '';
|
|
115
|
+
position: absolute;
|
|
116
|
+
left: 0;
|
|
117
|
+
bottom: -2px;
|
|
118
|
+
width: 100%;
|
|
119
|
+
height: var(--kol-link-underline-size, 2px);
|
|
120
|
+
background-color: currentColor;
|
|
121
|
+
transform-origin: bottom right;
|
|
122
|
+
transform: scaleX(0);
|
|
123
|
+
transition: transform 300ms cubic-bezier(0.65, 0.05, 0.36, 1);
|
|
124
|
+
}
|
|
125
|
+
.kol-link-underline:hover::after,
|
|
126
|
+
.kol-link-underline:focus-visible::after {
|
|
127
|
+
transform-origin: bottom left;
|
|
128
|
+
transform: scaleX(1);
|
|
129
|
+
}
|
|
130
|
+
@media (prefers-reduced-motion: reduce) {
|
|
131
|
+
.kol-link-underline::after {
|
|
132
|
+
transition: none;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* The ROLL mechanics — .kol-roll (ComponentTailwindSourceTrap, 2026-08-12).
|
|
137
|
+
* These were Tailwind utilities emitted in ThemeToggle's JSX (overflow-hidden,
|
|
138
|
+
* transition-transform, duration-500, ease-in-out) — and Tailwind never scans
|
|
139
|
+
* node_modules, so any consumer without the @source lines got a SILENTLY
|
|
140
|
+
* static glyph: visible, clickable, no travel, no coin-roll, no error.
|
|
141
|
+
* A component's own moving parts live HERE, in the CSS it ships — the
|
|
142
|
+
* consumer's scanner owes it nothing. Widths/transforms stay inline in JSX
|
|
143
|
+
* (they are per-render geometry, not chrome). */
|
|
144
|
+
.kol-roll {
|
|
145
|
+
position: relative;
|
|
146
|
+
display: inline-block;
|
|
147
|
+
overflow: hidden;
|
|
148
|
+
}
|
|
149
|
+
.kol-roll-strip {
|
|
150
|
+
display: flex;
|
|
151
|
+
transition: transform 500ms ease-in-out;
|
|
152
|
+
}
|
|
153
|
+
.kol-roll-slot {
|
|
154
|
+
display: inline-flex;
|
|
155
|
+
line-height: 0;
|
|
156
|
+
transition: transform 500ms ease-in-out;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* ContentCard `reveal` (TypefaceCardAndRow, kol-website 2026-08-27 — the
|
|
160
|
+
* shipped TypefaceLibraryItem's hover, verbatim): the plate and the media
|
|
161
|
+
* fade OUT, the reveal node fades IN, all 300ms on the house curve. Keyed
|
|
162
|
+
* on the card root, only when it carries a reveal (`has-reveal`). */
|
|
163
|
+
.kol-card.has-reveal .kol-card-plate,
|
|
164
|
+
.kol-card.has-reveal .kol-card-canvas-media,
|
|
165
|
+
.kol-card.has-reveal .kol-card-reveal {
|
|
166
|
+
transition: opacity 300ms var(--kol-ease-house);
|
|
167
|
+
}
|
|
168
|
+
.kol-card.has-reveal .kol-card-reveal {
|
|
169
|
+
opacity: 0;
|
|
170
|
+
}
|
|
171
|
+
@media (hover: hover) {
|
|
172
|
+
.kol-card.has-reveal:hover .kol-card-plate,
|
|
173
|
+
.kol-card.has-reveal:hover .kol-card-canvas-media {
|
|
174
|
+
opacity: 0;
|
|
175
|
+
}
|
|
176
|
+
.kol-card.has-reveal:hover .kol-card-reveal {
|
|
177
|
+
opacity: 1;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
@media (prefers-reduced-motion: reduce) {
|
|
181
|
+
.kol-card.has-reveal .kol-card-plate,
|
|
182
|
+
.kol-card.has-reveal .kol-card-canvas-media,
|
|
183
|
+
.kol-card.has-reveal .kol-card-reveal { transition: none; }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
187
|
+
* ContentMedia — the hover zoom
|
|
188
|
+
*
|
|
189
|
+
* A state the house serves on image-led cards: the artwork creeps up
|
|
190
|
+
* inside its own frame while the frame holds still. ContentMedia already
|
|
191
|
+
* clips, so the scale has something to push against — without that
|
|
192
|
+
* overflow the image just grows out of the card.
|
|
193
|
+
*
|
|
194
|
+
* Keyed off the CARD's hover, not the media's, because the whole tile is
|
|
195
|
+
* the affordance; hovering the caption must zoom too. Transform only —
|
|
196
|
+
* it is the one property that scales without relayout, and a wall of
|
|
197
|
+
* these must not thrash the grid.
|
|
198
|
+
*
|
|
199
|
+
* 1.06 and 600ms, deliberately slow and small: a zoom you can SEE
|
|
200
|
+
* happening reads as a photograph breathing; a fast one reads as a
|
|
201
|
+
* glitch.
|
|
202
|
+
* ───────────────────────────────────────────────────────────────────── */
|
|
203
|
+
/* THE TARGET IS THE WRAPPER'S CHILD, WHATEVER IT IS (CatalogCardFrameAndZoom,
|
|
204
|
+
* kol-website 2026-08-28): a catalog card whose media is an SVG glyph on a
|
|
205
|
+
* specimen plate resolves `zoom` true and got the class, the transition and no
|
|
206
|
+
* motion while this named img/video. Everything but the ring hairline. */
|
|
207
|
+
.kol-media-zoom > :not(.kol-media-ring) {
|
|
208
|
+
transition: transform 600ms var(--kol-ease-house);
|
|
209
|
+
/* THE ANCHOR IS THE CONSUMER'S (ContentMediaFocusBinding, kol-monitor
|
|
210
|
+
* 2026-08-27): `--kol-media-focus`, bound once on a repo's :root, is where
|
|
211
|
+
* the image pins for the fit (ContentMedia natural / compact read the same
|
|
212
|
+
* token, default top left) and from where the zoom grows. Unset = center,
|
|
213
|
+
* today's value. Monitor binds `top left`. */
|
|
214
|
+
transform-origin: var(--kol-media-focus, center);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@media (hover: hover) {
|
|
218
|
+
.group:hover .kol-media-zoom > :not(.kol-media-ring) {
|
|
219
|
+
transform: scale(1.06);
|
|
220
|
+
}
|
|
221
|
+
/* the HERO rung (StackCardHover, 2026-08-27 — user: "that is TOO MUCH
|
|
222
|
+
* ZOOM"): 1.06 on a ~1500px featured thumb is 90px of travel where the
|
|
223
|
+
* 500px list thumbs move 30. 1.02 on the hero is the same pixel travel.
|
|
224
|
+
* `ListingCard size="hero"` wears it; ContentMedia takes zoom="hero". */
|
|
225
|
+
.group:hover .kol-media-zoom.is-hero > :not(.kol-media-ring) {
|
|
226
|
+
transform: scale(1.02);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* ContentMedia `fade` — the image fades in on load (PrintGridCard's 500ms,
|
|
231
|
+
* carried to ContentCard print 2026-08-27). Opacity only; no relayout. */
|
|
232
|
+
.kol-media-fade {
|
|
233
|
+
opacity: 0;
|
|
234
|
+
transition: opacity 500ms var(--kol-ease-house);
|
|
235
|
+
}
|
|
236
|
+
.kol-media-fade.is-loaded {
|
|
237
|
+
opacity: 1;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
241
|
+
* ContentText — the title dim (StackCardHover, 2026-08-27)
|
|
242
|
+
*
|
|
243
|
+
* The article card's title dims to 70% on card hover, the way ListingCard's
|
|
244
|
+
* always has (`group-hover:opacity-70`, 200ms) — so the featured hero and
|
|
245
|
+
* the filtered cards under it hover the same way (user: "shouldn't it also
|
|
246
|
+
* do it to the cards in the content filter?"). Keyed off the CARD / ROW
|
|
247
|
+
* root, not any `.group` ancestor. ContentText stamps the hook on the
|
|
248
|
+
* article title in both forms.
|
|
249
|
+
* ───────────────────────────────────────────────────────────────────── */
|
|
250
|
+
.kol-content-title-dim {
|
|
251
|
+
transition: opacity 200ms var(--kol-ease-house);
|
|
252
|
+
}
|
|
253
|
+
@media (hover: hover) {
|
|
254
|
+
.kol-card:hover .kol-content-title-dim,
|
|
255
|
+
.kol-row:hover .kol-content-title-dim {
|
|
256
|
+
opacity: 0.7;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
@media (prefers-reduced-motion: reduce) {
|
|
260
|
+
.kol-content-title-dim { transition: none; }
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
@media (prefers-reduced-motion: reduce) {
|
|
264
|
+
.kol-media-zoom > :not(.kol-media-ring) {
|
|
265
|
+
transition: none;
|
|
266
|
+
}
|
|
267
|
+
.group:hover .kol-media-zoom > :not(.kol-media-ring) {
|
|
268
|
+
transform: none;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.kol-card-feature-visual {
|
|
273
|
+
transition: transform 300ms ease;
|
|
274
|
+
}
|
|
275
|
+
.kol-card-feature:hover .kol-card-feature-visual {
|
|
276
|
+
transform: scale(1.03);
|
|
277
|
+
}
|
|
278
|
+
@media (prefers-reduced-motion: reduce) {
|
|
279
|
+
.kol-card-feature-visual { transition: none; }
|
|
280
|
+
.kol-card-feature:hover .kol-card-feature-visual { transform: none; }
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* Media hover zoom — opt-in via `mediaHover` (SectionSplit ruling, 2026-08-15).
|
|
284
|
+
* The brief named "media hover treatment owned by the component", and named the
|
|
285
|
+
* defect: kol-website's HomeFoundry hover had been silently broken for months
|
|
286
|
+
* because each hand-built section re-decided it. Same numbers and the same
|
|
287
|
+
* reduced-motion guard as the CardFeatureItem zoom (CardFeatureHoverZoom,
|
|
288
|
+
* 2026-08-12) — one motion vocabulary, not two. Motion chrome is DS CSS, never
|
|
289
|
+
* a JSX utility (the ComponentTailwindSourceTrap law). The frame's own
|
|
290
|
+
* overflow-hidden + radius clip the scale. */
|
|
291
|
+
.kol-feature-split-visual.is-hoverable > :first-child,
|
|
292
|
+
.kol-section-split-visual.is-hoverable > :first-child {
|
|
293
|
+
transition: transform 300ms ease;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.kol-feature-split-visual.is-hoverable:hover > :first-child,
|
|
297
|
+
.kol-section-split-visual.is-hoverable:hover > :first-child {
|
|
298
|
+
transform: scale(1.03);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@media (prefers-reduced-motion: reduce) {
|
|
302
|
+
.kol-feature-split-visual.is-hoverable > :first-child,
|
|
303
|
+
.kol-section-split-visual.is-hoverable > :first-child { transition: none; }
|
|
304
|
+
.kol-feature-split-visual.is-hoverable:hover > :first-child,
|
|
305
|
+
.kol-section-split-visual.is-hoverable:hover > :first-child { transform: none; }
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
309
|
+
* THE GRAB PILL — the rail's resize edge (RailFlatGrabOpen, kol-mirror
|
|
310
|
+
* 2026-08-28; kol-r2b2's pill, brought over as it is there — user: "make it
|
|
311
|
+
* like it is in kol-r2b2, it has animation and gsap").
|
|
312
|
+
*
|
|
313
|
+
* The 8px strip straddles the rail's right border so the pill's centre IS the
|
|
314
|
+
* line: in a 48px border-box the 1px border sits at x 47–48, centre 47.5, so
|
|
315
|
+
* the strip is offset `right: -3.5px`. Along the line it follows
|
|
316
|
+
* `--kol-rail-grab-y`, tweened from JS (the marks and the tween live in
|
|
317
|
+
* kol-component's `utilities/motion.js`, GRAB); `clamp()` holds it half its own
|
|
318
|
+
* length from either end so it stops flush, never past.
|
|
319
|
+
*
|
|
320
|
+
* Longer and finer than the ColumnBrowser's 3 × 32 — on a rail it should read
|
|
321
|
+
* as a thickening of the line, not a tab stuck to it. The fade is long and
|
|
322
|
+
* unhurried at BOTH ends on a symmetric in-out: an ease-out popped the first
|
|
323
|
+
* 20 % and crawled the rest, which the user read as a jerk.
|
|
324
|
+
* ═════════════════════════════════════════════════════════════════════ */
|
|
325
|
+
.kol-rail-grab {
|
|
326
|
+
position: absolute;
|
|
327
|
+
top: 0;
|
|
328
|
+
bottom: 0;
|
|
329
|
+
right: -3.5px;
|
|
330
|
+
width: 8px;
|
|
331
|
+
cursor: col-resize;
|
|
332
|
+
touch-action: none;
|
|
333
|
+
}
|
|
334
|
+
.kol-rail-grab::before {
|
|
335
|
+
content: '';
|
|
336
|
+
position: absolute;
|
|
337
|
+
left: 50%;
|
|
338
|
+
top: clamp(2.25rem, var(--kol-rail-grab-y, 50%), calc(100% - 2.25rem));
|
|
339
|
+
translate: -50% -50%;
|
|
340
|
+
width: 0.125rem;
|
|
341
|
+
height: 4.5rem;
|
|
342
|
+
border-radius: var(--kol-radius-full);
|
|
343
|
+
background: var(--kol-fg-64);
|
|
344
|
+
opacity: 0;
|
|
345
|
+
transition: opacity 1800ms cubic-bezier(0.45, 0, 0.55, 1) 400ms, background-color 500ms ease;
|
|
346
|
+
}
|
|
347
|
+
/* `is-near` = the pointer is within 20px of the line (JS, hysteresis at 40) */
|
|
348
|
+
.kol-rail-grab.is-near::before,
|
|
349
|
+
.kol-rail-grab.is-dragging::before { opacity: 1; transition-delay: 40ms; }
|
|
350
|
+
.kol-rail-grab:hover::before,
|
|
351
|
+
.kol-rail-grab.is-dragging::before { background: var(--kol-fg-96); }
|
|
352
|
+
|
|
353
|
+
@media (prefers-reduced-motion: reduce) {
|
|
354
|
+
.kol-rail-grab::before { transition: none; }
|
|
355
|
+
}
|
package/kol-components-atoms.css
CHANGED
|
@@ -1211,25 +1211,3 @@ a.kol-icon-frame {
|
|
|
1211
1211
|
padding: 0;
|
|
1212
1212
|
}
|
|
1213
1213
|
|
|
1214
|
-
/* The ROLL mechanics — .kol-roll (ComponentTailwindSourceTrap, 2026-08-12).
|
|
1215
|
-
* These were Tailwind utilities emitted in ThemeToggle's JSX (overflow-hidden,
|
|
1216
|
-
* transition-transform, duration-500, ease-in-out) — and Tailwind never scans
|
|
1217
|
-
* node_modules, so any consumer without the @source lines got a SILENTLY
|
|
1218
|
-
* static glyph: visible, clickable, no travel, no coin-roll, no error.
|
|
1219
|
-
* A component's own moving parts live HERE, in the CSS it ships — the
|
|
1220
|
-
* consumer's scanner owes it nothing. Widths/transforms stay inline in JSX
|
|
1221
|
-
* (they are per-render geometry, not chrome). */
|
|
1222
|
-
.kol-roll {
|
|
1223
|
-
position: relative;
|
|
1224
|
-
display: inline-block;
|
|
1225
|
-
overflow: hidden;
|
|
1226
|
-
}
|
|
1227
|
-
.kol-roll-strip {
|
|
1228
|
-
display: flex;
|
|
1229
|
-
transition: transform 500ms ease-in-out;
|
|
1230
|
-
}
|
|
1231
|
-
.kol-roll-slot {
|
|
1232
|
-
display: inline-flex;
|
|
1233
|
-
line-height: 0;
|
|
1234
|
-
transition: transform 500ms ease-in-out;
|
|
1235
|
-
}
|
package/kol-components-chess.css
CHANGED
|
@@ -1021,55 +1021,16 @@
|
|
|
1021
1021
|
height: 6px;
|
|
1022
1022
|
border-radius: 50%;
|
|
1023
1023
|
background: #5dd27f;
|
|
1024
|
-
animation: pulse 2s ease-in-out infinite;
|
|
1024
|
+
animation: kol-chess-pulse 2s ease-in-out infinite;
|
|
1025
1025
|
}
|
|
1026
1026
|
|
|
1027
|
-
@keyframes pulse {
|
|
1028
|
-
0%, 100% {
|
|
1029
|
-
opacity: 1;
|
|
1030
|
-
}
|
|
1031
|
-
50% {
|
|
1032
|
-
opacity: 0.4;
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
@keyframes fadeIn {
|
|
1037
|
-
from {
|
|
1038
|
-
opacity: 0;
|
|
1039
|
-
transform: translateY(10px);
|
|
1040
|
-
}
|
|
1041
|
-
to {
|
|
1042
|
-
opacity: 1;
|
|
1043
|
-
transform: translateY(0);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
@keyframes numberTick {
|
|
1048
|
-
from {
|
|
1049
|
-
transform: translateY(-2px);
|
|
1050
|
-
opacity: 0.8;
|
|
1051
|
-
}
|
|
1052
|
-
to {
|
|
1053
|
-
transform: translateY(0);
|
|
1054
|
-
opacity: 1;
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
@keyframes lineDraw {
|
|
1059
|
-
from {
|
|
1060
|
-
stroke-dashoffset: 100;
|
|
1061
|
-
}
|
|
1062
|
-
to {
|
|
1063
|
-
stroke-dashoffset: 0;
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
1027
|
|
|
1067
1028
|
.animate-fade-in {
|
|
1068
|
-
animation:
|
|
1029
|
+
animation: kol-chess-fade-in 0.6s ease-out forwards;
|
|
1069
1030
|
}
|
|
1070
1031
|
|
|
1071
1032
|
.animate-number-tick {
|
|
1072
|
-
animation:
|
|
1033
|
+
animation: kol-chess-number-tick 0.3s ease-out;
|
|
1073
1034
|
}
|
|
1074
1035
|
|
|
1075
1036
|
.chess-hero__side-link {
|
|
@@ -605,16 +605,6 @@
|
|
|
605
605
|
* DS CSS (the ComponentTailwindSourceTrap law, same day). The card's own
|
|
606
606
|
* overflow-hidden + radius clip the scale.
|
|
607
607
|
* ──────────────────────────────────────────────────────────────────── */
|
|
608
|
-
.kol-card-feature-visual {
|
|
609
|
-
transition: transform 300ms ease;
|
|
610
|
-
}
|
|
611
|
-
.kol-card-feature:hover .kol-card-feature-visual {
|
|
612
|
-
transform: scale(1.03);
|
|
613
|
-
}
|
|
614
|
-
@media (prefers-reduced-motion: reduce) {
|
|
615
|
-
.kol-card-feature-visual { transition: none; }
|
|
616
|
-
.kol-card-feature:hover .kol-card-feature-visual { transform: none; }
|
|
617
|
-
}
|
|
618
608
|
|
|
619
609
|
/* the TEXT-ONLY tile (SectionCardItem with no visual — FoundrySpecimenSections,
|
|
620
610
|
* 2026-08-27): kol-website's .feature-card frame + hover, verbatim — a 1% wash
|
|
@@ -1044,32 +1034,6 @@
|
|
|
1044
1034
|
border-color 300ms var(--kol-ease-house);
|
|
1045
1035
|
}
|
|
1046
1036
|
|
|
1047
|
-
/* ContentCard `reveal` (TypefaceCardAndRow, kol-website 2026-08-27 — the
|
|
1048
|
-
* shipped TypefaceLibraryItem's hover, verbatim): the plate and the media
|
|
1049
|
-
* fade OUT, the reveal node fades IN, all 300ms on the house curve. Keyed
|
|
1050
|
-
* on the card root, only when it carries a reveal (`has-reveal`). */
|
|
1051
|
-
.kol-card.has-reveal .kol-card-plate,
|
|
1052
|
-
.kol-card.has-reveal .kol-card-canvas-media,
|
|
1053
|
-
.kol-card.has-reveal .kol-card-reveal {
|
|
1054
|
-
transition: opacity 300ms var(--kol-ease-house);
|
|
1055
|
-
}
|
|
1056
|
-
.kol-card.has-reveal .kol-card-reveal {
|
|
1057
|
-
opacity: 0;
|
|
1058
|
-
}
|
|
1059
|
-
@media (hover: hover) {
|
|
1060
|
-
.kol-card.has-reveal:hover .kol-card-plate,
|
|
1061
|
-
.kol-card.has-reveal:hover .kol-card-canvas-media {
|
|
1062
|
-
opacity: 0;
|
|
1063
|
-
}
|
|
1064
|
-
.kol-card.has-reveal:hover .kol-card-reveal {
|
|
1065
|
-
opacity: 1;
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1069
|
-
.kol-card.has-reveal .kol-card-plate,
|
|
1070
|
-
.kol-card.has-reveal .kol-card-canvas-media,
|
|
1071
|
-
.kol-card.has-reveal .kol-card-reveal { transition: none; }
|
|
1072
|
-
}
|
|
1073
1037
|
|
|
1074
1038
|
/* ─────────────────────────────────────────────────────────────────────
|
|
1075
1039
|
* The house expand — molecules/SearchInput.jsx · organisms/ContentFilters.jsx
|
|
@@ -1099,91 +1063,6 @@
|
|
|
1099
1063
|
transition: opacity 300ms var(--kol-ease-house);
|
|
1100
1064
|
}
|
|
1101
1065
|
|
|
1102
|
-
/* ─────────────────────────────────────────────────────────────────────
|
|
1103
|
-
* ContentMedia — the hover zoom
|
|
1104
|
-
*
|
|
1105
|
-
* A state the house serves on image-led cards: the artwork creeps up
|
|
1106
|
-
* inside its own frame while the frame holds still. ContentMedia already
|
|
1107
|
-
* clips, so the scale has something to push against — without that
|
|
1108
|
-
* overflow the image just grows out of the card.
|
|
1109
|
-
*
|
|
1110
|
-
* Keyed off the CARD's hover, not the media's, because the whole tile is
|
|
1111
|
-
* the affordance; hovering the caption must zoom too. Transform only —
|
|
1112
|
-
* it is the one property that scales without relayout, and a wall of
|
|
1113
|
-
* these must not thrash the grid.
|
|
1114
|
-
*
|
|
1115
|
-
* 1.06 and 600ms, deliberately slow and small: a zoom you can SEE
|
|
1116
|
-
* happening reads as a photograph breathing; a fast one reads as a
|
|
1117
|
-
* glitch.
|
|
1118
|
-
* ───────────────────────────────────────────────────────────────────── */
|
|
1119
|
-
/* THE TARGET IS THE WRAPPER'S CHILD, WHATEVER IT IS (CatalogCardFrameAndZoom,
|
|
1120
|
-
* kol-website 2026-08-28): a catalog card whose media is an SVG glyph on a
|
|
1121
|
-
* specimen plate resolves `zoom` true and got the class, the transition and no
|
|
1122
|
-
* motion while this named img/video. Everything but the ring hairline. */
|
|
1123
|
-
.kol-media-zoom > :not(.kol-media-ring) {
|
|
1124
|
-
transition: transform 600ms var(--kol-ease-house);
|
|
1125
|
-
/* THE ANCHOR IS THE CONSUMER'S (ContentMediaFocusBinding, kol-monitor
|
|
1126
|
-
* 2026-08-27): `--kol-media-focus`, bound once on a repo's :root, is where
|
|
1127
|
-
* the image pins for the fit (ContentMedia natural / compact read the same
|
|
1128
|
-
* token, default top left) and from where the zoom grows. Unset = center,
|
|
1129
|
-
* today's value. Monitor binds `top left`. */
|
|
1130
|
-
transform-origin: var(--kol-media-focus, center);
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
@media (hover: hover) {
|
|
1134
|
-
.group:hover .kol-media-zoom > :not(.kol-media-ring) {
|
|
1135
|
-
transform: scale(1.06);
|
|
1136
|
-
}
|
|
1137
|
-
/* the HERO rung (StackCardHover, 2026-08-27 — user: "that is TOO MUCH
|
|
1138
|
-
* ZOOM"): 1.06 on a ~1500px featured thumb is 90px of travel where the
|
|
1139
|
-
* 500px list thumbs move 30. 1.02 on the hero is the same pixel travel.
|
|
1140
|
-
* `ListingCard size="hero"` wears it; ContentMedia takes zoom="hero". */
|
|
1141
|
-
.group:hover .kol-media-zoom.is-hero > :not(.kol-media-ring) {
|
|
1142
|
-
transform: scale(1.02);
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
/* ContentMedia `fade` — the image fades in on load (PrintGridCard's 500ms,
|
|
1147
|
-
* carried to ContentCard print 2026-08-27). Opacity only; no relayout. */
|
|
1148
|
-
.kol-media-fade {
|
|
1149
|
-
opacity: 0;
|
|
1150
|
-
transition: opacity 500ms var(--kol-ease-house);
|
|
1151
|
-
}
|
|
1152
|
-
.kol-media-fade.is-loaded {
|
|
1153
|
-
opacity: 1;
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
/* ─────────────────────────────────────────────────────────────────────
|
|
1157
|
-
* ContentText — the title dim (StackCardHover, 2026-08-27)
|
|
1158
|
-
*
|
|
1159
|
-
* The article card's title dims to 70% on card hover, the way ListingCard's
|
|
1160
|
-
* always has (`group-hover:opacity-70`, 200ms) — so the featured hero and
|
|
1161
|
-
* the filtered cards under it hover the same way (user: "shouldn't it also
|
|
1162
|
-
* do it to the cards in the content filter?"). Keyed off the CARD / ROW
|
|
1163
|
-
* root, not any `.group` ancestor. ContentText stamps the hook on the
|
|
1164
|
-
* article title in both forms.
|
|
1165
|
-
* ───────────────────────────────────────────────────────────────────── */
|
|
1166
|
-
.kol-content-title-dim {
|
|
1167
|
-
transition: opacity 200ms var(--kol-ease-house);
|
|
1168
|
-
}
|
|
1169
|
-
@media (hover: hover) {
|
|
1170
|
-
.kol-card:hover .kol-content-title-dim,
|
|
1171
|
-
.kol-row:hover .kol-content-title-dim {
|
|
1172
|
-
opacity: 0.7;
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1176
|
-
.kol-content-title-dim { transition: none; }
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1180
|
-
.kol-media-zoom > :not(.kol-media-ring) {
|
|
1181
|
-
transition: none;
|
|
1182
|
-
}
|
|
1183
|
-
.group:hover .kol-media-zoom > :not(.kol-media-ring) {
|
|
1184
|
-
transform: none;
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
1066
|
|
|
1188
1067
|
/* Markdown is BOUNDED where it renders (SettingsPanelApproved, kol-r2b2
|
|
1189
1068
|
* 2026-08-27): in the 320px column preview a document scaled to the frame; in
|
|
@@ -1340,23 +1219,27 @@
|
|
|
1340
1219
|
* so a consumer never restates them (brand hand-wrote the fill and GUESSED
|
|
1341
1220
|
* the ink for its two icon buttons — that fork is what widening the set ends).
|
|
1342
1221
|
*
|
|
1343
|
-
* THE SET: well `fg-
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1222
|
+
* THE SET: well `fg-inverse-96` (user ruling 2026-08-28, swapped from
|
|
1223
|
+
* `fg-absolute-24` — measured on the dark theme, where the inverse tier is the
|
|
1224
|
+
* one that DARKENS: on the #121215 page inverse-96 lands ~14.2 against
|
|
1225
|
+
* absolute-24's 13.7, half a level apart. Unlike absolute it follows the
|
|
1226
|
+
* theme, so the light-theme well flips to the near-white inverse anchor) ·
|
|
1227
|
+
* active chip `fg-08` (user ruling 2026-08-28, down from the 0.78.1 fg-16) ·
|
|
1228
|
+
* inactive hover absolute-white @ 8% (a dark well wants a LIGHTER hover) ·
|
|
1229
|
+
* ink `fg-96`. `.kol-tone-inverse` stays selected for any class
|
|
1347
1230
|
* hand-stamped on the old name.
|
|
1348
1231
|
* ───────────────────────────────────────────────────────────────────── */
|
|
1349
|
-
.kol-view-toggle.kol-tone-sunken, .kol-view-toggle.kol-tone-inverse { background-color: var(--kol-fg-
|
|
1232
|
+
.kol-view-toggle.kol-tone-sunken, .kol-view-toggle.kol-tone-inverse { background-color: var(--kol-fg-inverse-96); }
|
|
1350
1233
|
.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); }
|
|
1351
1234
|
.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); }
|
|
1352
|
-
.kol-control.kol-tone-sunken, .kol-control.kol-tone-inverse { background-color: var(--kol-fg-
|
|
1353
|
-
.kol-expand.kol-tone-sunken, .kol-expand.kol-tone-inverse { background-color: var(--kol-fg-
|
|
1235
|
+
.kol-control.kol-tone-sunken, .kol-control.kol-tone-inverse { background-color: var(--kol-fg-inverse-96); }
|
|
1236
|
+
.kol-expand.kol-tone-sunken, .kol-expand.kol-tone-inverse { background-color: var(--kol-fg-inverse-96); }
|
|
1354
1237
|
/* the trigger: rest and open are its only states — the pin-back rules above
|
|
1355
1238
|
* paint surface-secondary on hover/active, so the tone pins its own chip */
|
|
1356
1239
|
.kol-dd-trigger.kol-tone-sunken, .kol-dd-trigger.kol-tone-inverse,
|
|
1357
1240
|
.kol-dd-trigger.kol-tone-sunken:not(:disabled):hover, .kol-dd-trigger.kol-tone-inverse:not(:disabled):hover,
|
|
1358
|
-
.kol-dd-trigger.kol-tone-sunken:not(:disabled):active, .kol-dd-trigger.kol-tone-inverse:not(:disabled):active { background-color: var(--kol-fg-
|
|
1359
|
-
.kol-dd-panel.kol-tone-sunken, .kol-dd-panel.kol-tone-inverse { background-color: var(--kol-fg-
|
|
1241
|
+
.kol-dd-trigger.kol-tone-sunken:not(:disabled):active, .kol-dd-trigger.kol-tone-inverse:not(:disabled):active { background-color: var(--kol-fg-inverse-96); }
|
|
1242
|
+
.kol-dd-panel.kol-tone-sunken, .kol-dd-panel.kol-tone-inverse { background-color: var(--kol-fg-inverse-96); }
|
|
1360
1243
|
/* the rest of the set — Button (icon-only especially), IconFrame, ThemeToggle:
|
|
1361
1244
|
* the well, transparent edge, fg-96 ink; hover the white wash, pressed the
|
|
1362
1245
|
* fg-08 chip — both LAYERED over the well (a gradient image over the fill),
|
|
@@ -1364,20 +1247,20 @@
|
|
|
1364
1247
|
.kol-btn.kol-tone-sunken,
|
|
1365
1248
|
.kol-icon-frame.kol-tone-sunken,
|
|
1366
1249
|
.kol-theme-toggle.kol-tone-sunken {
|
|
1367
|
-
background-color: var(--kol-fg-
|
|
1250
|
+
background-color: var(--kol-fg-inverse-96);
|
|
1368
1251
|
border-color: transparent;
|
|
1369
1252
|
color: var(--kol-fg-96);
|
|
1370
1253
|
}
|
|
1371
1254
|
@media (hover: hover) {
|
|
1372
1255
|
.kol-btn.kol-tone-sunken:not(.kol-btn-animate):not(:disabled):hover {
|
|
1373
|
-
background-color: var(--kol-fg-
|
|
1256
|
+
background-color: var(--kol-fg-inverse-96);
|
|
1374
1257
|
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));
|
|
1375
1258
|
color: var(--kol-fg-96);
|
|
1376
1259
|
}
|
|
1377
1260
|
}
|
|
1378
1261
|
.kol-btn.kol-tone-sunken.kol-btn-pressed,
|
|
1379
1262
|
.kol-btn.kol-tone-sunken:not(:disabled):active {
|
|
1380
|
-
background-color: var(--kol-fg-
|
|
1263
|
+
background-color: var(--kol-fg-inverse-96);
|
|
1381
1264
|
background-image: linear-gradient(var(--kol-fg-08), var(--kol-fg-08));
|
|
1382
1265
|
color: var(--kol-fg-96);
|
|
1383
1266
|
}
|
|
@@ -375,30 +375,6 @@
|
|
|
375
375
|
display: block;
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
-
/* Media hover zoom — opt-in via `mediaHover` (SectionSplit ruling, 2026-08-15).
|
|
379
|
-
* The brief named "media hover treatment owned by the component", and named the
|
|
380
|
-
* defect: kol-website's HomeFoundry hover had been silently broken for months
|
|
381
|
-
* because each hand-built section re-decided it. Same numbers and the same
|
|
382
|
-
* reduced-motion guard as the CardFeatureItem zoom (CardFeatureHoverZoom,
|
|
383
|
-
* 2026-08-12) — one motion vocabulary, not two. Motion chrome is DS CSS, never
|
|
384
|
-
* a JSX utility (the ComponentTailwindSourceTrap law). The frame's own
|
|
385
|
-
* overflow-hidden + radius clip the scale. */
|
|
386
|
-
.kol-feature-split-visual.is-hoverable > :first-child,
|
|
387
|
-
.kol-section-split-visual.is-hoverable > :first-child {
|
|
388
|
-
transition: transform 300ms ease;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
.kol-feature-split-visual.is-hoverable:hover > :first-child,
|
|
392
|
-
.kol-section-split-visual.is-hoverable:hover > :first-child {
|
|
393
|
-
transform: scale(1.03);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
@media (prefers-reduced-motion: reduce) {
|
|
397
|
-
.kol-feature-split-visual.is-hoverable > :first-child,
|
|
398
|
-
.kol-section-split-visual.is-hoverable > :first-child { transition: none; }
|
|
399
|
-
.kol-feature-split-visual.is-hoverable:hover > :first-child,
|
|
400
|
-
.kol-section-split-visual.is-hoverable:hover > :first-child { transform: none; }
|
|
401
|
-
}
|
|
402
378
|
|
|
403
379
|
.kol-feature-split-visual-veil,
|
|
404
380
|
.kol-section-split-visual-veil {
|
|
@@ -699,15 +675,3 @@
|
|
|
699
675
|
width: calc((100cqw - 120px) / 6);
|
|
700
676
|
}
|
|
701
677
|
|
|
702
|
-
/* ─────────────────────────────────────────────────────────────────────
|
|
703
|
-
* ContentCollection — src/organisms/ContentCollection.jsx (2026-08-15)
|
|
704
|
-
* The enter stagger the collection owns; cards never animate themselves.
|
|
705
|
-
* Delay is set per item inline; the curve is the house token. */
|
|
706
|
-
.kol-collection-item {
|
|
707
|
-
animation: kol-collection-in 300ms var(--kol-ease-house) both;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
@keyframes kol-collection-in {
|
|
711
|
-
from { opacity: 0; transform: translateY(6px); }
|
|
712
|
-
to { opacity: 1; transform: none; }
|
|
713
|
-
}
|
|
@@ -281,10 +281,6 @@
|
|
|
281
281
|
.kol-page--fullbleed .kol-combo-lab { flex: 1; }
|
|
282
282
|
.kol-page--fullbleed .kol-combo-stage-wrap { min-height: 520px; }
|
|
283
283
|
|
|
284
|
-
@keyframes kol-combo-fade {
|
|
285
|
-
from { opacity: 0.2; transform: translateY(6px); }
|
|
286
|
-
to { opacity: 1; transform: none; }
|
|
287
|
-
}
|
|
288
284
|
|
|
289
285
|
.kol-combo-readout {
|
|
290
286
|
display: grid;
|
package/kol-core.css
CHANGED
|
@@ -32,3 +32,8 @@
|
|
|
32
32
|
@import "./kol-components-organisms.css" layer(components);
|
|
33
33
|
@import "./kol-components-shell.css" layer(components);
|
|
34
34
|
@import "./kol-design-tokens.css" layer(components);
|
|
35
|
+
|
|
36
|
+
/* MOTION — last, so a named motion class out-ranks the chrome it moves
|
|
37
|
+
* (kol-animation.css, 2026-08-28: every keyframe, every named motion class,
|
|
38
|
+
* every reduced-motion block, one file). */
|
|
39
|
+
@import "./kol-animation.css" layer(components);
|
package/kol-theme.css
CHANGED
|
@@ -52,3 +52,8 @@
|
|
|
52
52
|
/* Theme-level design tokens — LAST, as they always were (lifted into their own
|
|
53
53
|
* file 2026-08-27 so kol-core.css shares them; emitted CSS unchanged). */
|
|
54
54
|
@import "./kol-design-tokens.css" layer(components);
|
|
55
|
+
|
|
56
|
+
/* MOTION — last, so a named motion class out-ranks the chrome it moves
|
|
57
|
+
* (kol-animation.css, 2026-08-28: every keyframe, every named motion class,
|
|
58
|
+
* every reduced-motion block, one file). */
|
|
59
|
+
@import "./kol-animation.css" layer(components);
|
package/kol-utilities.css
CHANGED
|
@@ -91,38 +91,6 @@
|
|
|
91
91
|
-moz-appearance: textfield;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
/* Link underline — the animated hover affordance: draws in left→right on
|
|
95
|
-
* hover/focus, retracts right→left on leave (transform-origin swap, not a
|
|
96
|
-
* fade). Line is currentColor so it rides the text at any scale. Minted from
|
|
97
|
-
* kol-website's animations.css (NavLinkUnderline, 2026-08-12); DS version
|
|
98
|
-
* adds :focus-visible parity and reduced-motion handling.
|
|
99
|
-
* Thickness knob: --kol-link-underline-size (2px default — fine at mono-14,
|
|
100
|
-
* a heading-01 link may want 3px). */
|
|
101
|
-
.kol-link-underline {
|
|
102
|
-
position: relative;
|
|
103
|
-
}
|
|
104
|
-
.kol-link-underline::after {
|
|
105
|
-
content: '';
|
|
106
|
-
position: absolute;
|
|
107
|
-
left: 0;
|
|
108
|
-
bottom: -2px;
|
|
109
|
-
width: 100%;
|
|
110
|
-
height: var(--kol-link-underline-size, 2px);
|
|
111
|
-
background-color: currentColor;
|
|
112
|
-
transform-origin: bottom right;
|
|
113
|
-
transform: scaleX(0);
|
|
114
|
-
transition: transform 300ms cubic-bezier(0.65, 0.05, 0.36, 1);
|
|
115
|
-
}
|
|
116
|
-
.kol-link-underline:hover::after,
|
|
117
|
-
.kol-link-underline:focus-visible::after {
|
|
118
|
-
transform-origin: bottom left;
|
|
119
|
-
transform: scaleX(1);
|
|
120
|
-
}
|
|
121
|
-
@media (prefers-reduced-motion: reduce) {
|
|
122
|
-
.kol-link-underline::after {
|
|
123
|
-
transition: none;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
94
|
|
|
127
95
|
/* Placeholder prose — the ONE gate (GatedEmptyState, kol-fxr 2026-08-15).
|
|
128
96
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolkrabbi/kol-theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.85.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",
|