@kolkrabbi/kol-framework 0.1.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/README.md +30 -0
- package/kol-brand-color.css +151 -0
- package/kol-framework.css +1225 -0
- package/package.json +46 -0
- package/src/AppShell.jsx +46 -0
- package/src/BrandHero.jsx +14 -0
- package/src/Layout.jsx +20 -0
- package/src/PageSection.jsx +24 -0
- package/src/PortalFooter.jsx +22 -0
- package/src/ScrollToTop.jsx +17 -0
- package/src/SideNav.jsx +205 -0
- package/src/SubPageHero.jsx +27 -0
- package/src/ThemeToggle.jsx +95 -0
- package/src/index.js +18 -0
|
@@ -0,0 +1,1225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kol-client — site-local structural rules only.
|
|
3
|
+
*
|
|
4
|
+
* This file holds layout / positioning / sizing that the Kolkrabbi DS doesn't
|
|
5
|
+
* cover. Color, typography, borders, and state come from DS utilities
|
|
6
|
+
* (bg-fg-*, border-fg-*, text-fg-*, bg-surface-*, kol-display-*, kol-heading-*,
|
|
7
|
+
* kol-text-*, kol-helper-*) on JSX. No `__` BEM, no `color-mix()` for chrome.
|
|
8
|
+
*
|
|
9
|
+
* Global rule: border-radius never exceeds 4px.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
html,
|
|
13
|
+
body {
|
|
14
|
+
background: var(--kol-surface-primary);
|
|
15
|
+
color: var(--kol-surface-on-primary);
|
|
16
|
+
|
|
17
|
+
/* Editor-style app — selection is mostly meaningless on chrome. Default
|
|
18
|
+
* to non-selectable; opt back in for prose, tables, inputs, code below. */
|
|
19
|
+
-webkit-user-select: none;
|
|
20
|
+
user-select: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Allowlist — surfaces where reading / copying matters. */
|
|
24
|
+
input, textarea, [contenteditable="true"],
|
|
25
|
+
.kol-prose, .kol-prose *,
|
|
26
|
+
.kol-table, .kol-table *,
|
|
27
|
+
code, pre {
|
|
28
|
+
-webkit-user-select: text;
|
|
29
|
+
user-select: text;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Selection highlight uses brand-primary so it reads on-brand when it appears. */
|
|
33
|
+
::selection {
|
|
34
|
+
background-color: var(--kol-accent-primary);
|
|
35
|
+
color: var(--kol-accent-on-primary);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
:root {
|
|
39
|
+
--kol-topnav-h: 0px;
|
|
40
|
+
--kol-sidenav-w: 260px;
|
|
41
|
+
--kol-sidenav-w-collapsed: 56px;
|
|
42
|
+
--kol-container-max: 100%;
|
|
43
|
+
|
|
44
|
+
/* Opacity tokens (--kol-fg-*) + text-role tokens (--kol-text-*) live in
|
|
45
|
+
kol-opacity.css — see that file for the full 14-stop scale + inverse tier
|
|
46
|
+
+ hover variants + role utility classes. */
|
|
47
|
+
|
|
48
|
+
/* CTA / button transition shortcut (matches prevailing ease curve in site CSS).
|
|
49
|
+
Distinct from DS --kol-transition-base (which uses a Material cubic-bezier).
|
|
50
|
+
Intentional: site chrome uses browser-ease for a softer feel. */
|
|
51
|
+
--kol-t-btn: background 200ms ease, color 200ms ease, border-color 200ms ease;
|
|
52
|
+
|
|
53
|
+
/* Stepped page / section / band padding tokens.
|
|
54
|
+
Used by chrome (topnav, sidenav) and landing bands. Scaled at 768 / 1024
|
|
55
|
+
breakpoints so one set of rules covers mobile → desktop without clamp(). */
|
|
56
|
+
--kol-pad-page-x: 20px;
|
|
57
|
+
--kol-pad-page-y: 64px;
|
|
58
|
+
--kol-pad-section-x: 20px;
|
|
59
|
+
--kol-pad-section-y: 48px;
|
|
60
|
+
--kol-pad-band-y: 56px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@media (min-width: 768px) {
|
|
64
|
+
:root {
|
|
65
|
+
--kol-pad-page-x: 32px;
|
|
66
|
+
--kol-pad-page-y: 96px;
|
|
67
|
+
--kol-pad-section-x: 32px;
|
|
68
|
+
--kol-pad-section-y: 64px;
|
|
69
|
+
--kol-pad-band-y: 80px;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@media (min-width: 1024px) {
|
|
74
|
+
:root {
|
|
75
|
+
--kol-container-max: 1400px;
|
|
76
|
+
--kol-pad-page-x: 56px;
|
|
77
|
+
--kol-pad-page-y: 128px;
|
|
78
|
+
--kol-pad-section-x: 48px;
|
|
79
|
+
--kol-pad-section-y: 80px;
|
|
80
|
+
--kol-pad-band-y: 104px;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@media (min-width: 1280px) { :root { --kol-container-max: 1600px; } }
|
|
85
|
+
|
|
86
|
+
:root[data-sidenav="collapsed"] { --kol-sidenav-w: var(--kol-sidenav-w-collapsed); }
|
|
87
|
+
|
|
88
|
+
/* ───── Brand doc layout (sidebar + content) ─────
|
|
89
|
+
The grid lives in CSS for its dynamic --kol-sidenav-w + transition. */
|
|
90
|
+
|
|
91
|
+
.kol-brand-layout {
|
|
92
|
+
display: grid;
|
|
93
|
+
grid-template-columns: var(--kol-sidenav-w) minmax(0, 1fr);
|
|
94
|
+
transition: grid-template-columns 180ms ease;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@media (max-width: 1024px) {
|
|
98
|
+
/* Force rail mode below lg — keep nav accessible, hide panels + labels.
|
|
99
|
+
User's localStorage expand preference is overridden while viewport is narrow;
|
|
100
|
+
restored once they cross back over the threshold. */
|
|
101
|
+
.kol-brand-layout { grid-template-columns: var(--kol-sidenav-w-collapsed) minmax(0, 1fr); }
|
|
102
|
+
.kol-sidenav-toggle { display: none; }
|
|
103
|
+
.kol-sidenav-hops { padding: 0 0 16px; margin-bottom: 16px; }
|
|
104
|
+
.kol-sidenav-hop { padding: 8px 0; justify-content: center; gap: 0; }
|
|
105
|
+
.kol-sidenav-hop-label { display: none; }
|
|
106
|
+
.kol-sidenav-body { display: none; }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@media (max-width: 767px) {
|
|
110
|
+
/* Mobile drawer mode: hide the sidebar from the layout grid entirely.
|
|
111
|
+
SideNav repositions as a fixed slide-in panel triggered by the hamburger
|
|
112
|
+
in BrandLayout. Backdrop is the sibling .kol-sidenav-backdrop. */
|
|
113
|
+
.kol-brand-layout { grid-template-columns: minmax(0, 1fr); }
|
|
114
|
+
.kol-sidenav {
|
|
115
|
+
position: fixed;
|
|
116
|
+
inset: 0 auto 0 0;
|
|
117
|
+
width: min(80vw, 280px);
|
|
118
|
+
transform: translateX(-100%);
|
|
119
|
+
transition: transform 220ms ease;
|
|
120
|
+
}
|
|
121
|
+
.kol-sidenav.is-drawer-open { transform: translateX(0); }
|
|
122
|
+
/* Restore expanded labels + body inside the open drawer (override the rail rules above). */
|
|
123
|
+
.kol-sidenav.is-drawer-open .kol-sidenav-hop { padding: 8px 0; justify-content: flex-start; gap: 12px; }
|
|
124
|
+
.kol-sidenav.is-drawer-open .kol-sidenav-hop-label { display: inline; }
|
|
125
|
+
.kol-sidenav.is-drawer-open .kol-sidenav-body { display: block; }
|
|
126
|
+
.kol-brand-layout[data-drawer-open="true"] .kol-sidenav-backdrop {
|
|
127
|
+
opacity: 1;
|
|
128
|
+
pointer-events: auto;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* SideNav primitives (.kol-sidenav-hop, -hop-icon, -hop-label, -link,
|
|
133
|
+
* -group) promoted to kol-components-atoms.css 2026-04-30. The .is-collapsed
|
|
134
|
+
* responsive cascade rules below stay here — they're page-grid concerns,
|
|
135
|
+
* not component chrome. */
|
|
136
|
+
|
|
137
|
+
/* ───── SideNav collapsed (rail mode) — overrides inlined hop padding/gap ───── */
|
|
138
|
+
|
|
139
|
+
.kol-sidenav.is-collapsed .kol-sidenav-hops {
|
|
140
|
+
padding: 0 0 16px;
|
|
141
|
+
margin-bottom: 16px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.kol-sidenav.is-collapsed .kol-sidenav-hop {
|
|
145
|
+
padding: 8px 0;
|
|
146
|
+
justify-content: center;
|
|
147
|
+
gap: 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.kol-sidenav.is-collapsed .kol-sidenav-hop-label {
|
|
151
|
+
display: none;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.kol-sidenav.is-collapsed .kol-sidenav-body {
|
|
155
|
+
display: none;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* ───── Page scaffold ───── */
|
|
159
|
+
|
|
160
|
+
.kol-page {
|
|
161
|
+
max-width: var(--kol-container-max);
|
|
162
|
+
margin: 0 auto;
|
|
163
|
+
padding: 64px var(--kol-pad-section-x);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.kol-page-hero {
|
|
167
|
+
min-height: 72dvh;
|
|
168
|
+
display: flex;
|
|
169
|
+
flex-direction: column;
|
|
170
|
+
justify-content: center;
|
|
171
|
+
align-items: flex-start;
|
|
172
|
+
padding: 48px var(--kol-pad-section-x);
|
|
173
|
+
max-width: var(--kol-container-max);
|
|
174
|
+
margin: 0 auto;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* .kol-page-section-divider promoted to kol-components-atoms.css 2026-04-30. */
|
|
178
|
+
|
|
179
|
+
.kol-page--fullbleed {
|
|
180
|
+
max-width: none !important;
|
|
181
|
+
min-height: 100vh;
|
|
182
|
+
padding: 64px 0;
|
|
183
|
+
display: flex;
|
|
184
|
+
flex-direction: column;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* ───── Standard 4-col content grid ─────
|
|
188
|
+
The page-wide grid all chapter content lays out against. Always 4 cols.
|
|
189
|
+
Rows size to content; children control their own height via aspect-ratio
|
|
190
|
+
or explicit sizing. Use col-span-N / row-span-N utilities for spans. */
|
|
191
|
+
.kol-grid {
|
|
192
|
+
display: grid;
|
|
193
|
+
grid-template-columns: repeat(4, 1fr);
|
|
194
|
+
gap: 1.5rem;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.kol-grid--tight-y { row-gap: 0.75rem; }
|
|
198
|
+
|
|
199
|
+
/* Editor + compose rail rules moved to src/editor/styles/kol-editor.css.
|
|
200
|
+
Canvas patterns (.kol-grid-bg, .kol-checker) moved with them. */
|
|
201
|
+
|
|
202
|
+
@media (max-width: 768px) { .kol-grid { grid-template-columns: repeat(2, 1fr); } }
|
|
203
|
+
@media (max-width: 480px) { .kol-grid { grid-template-columns: 1fr; } }
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
/* ───── Asset figure / grid ─────
|
|
207
|
+
Wrappers (figure margin via Preflight, frame radius/overflow, grid base
|
|
208
|
+
display+gap+margin) inlined in AssetFigure.jsx + AssetGrid.jsx. CSS retains
|
|
209
|
+
the responsive column-count variants and the descendant img sizing. */
|
|
210
|
+
|
|
211
|
+
.kol-asset-figure-frame img {
|
|
212
|
+
width: 100%;
|
|
213
|
+
height: auto;
|
|
214
|
+
display: block;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.kol-asset-grid-2col { grid-template-columns: repeat(2, 1fr); }
|
|
218
|
+
.kol-asset-grid-3col { grid-template-columns: repeat(3, 1fr); }
|
|
219
|
+
.kol-asset-grid-4col { grid-template-columns: repeat(4, 1fr); }
|
|
220
|
+
|
|
221
|
+
@media (max-width: 768px) {
|
|
222
|
+
.kol-asset-grid-3col,
|
|
223
|
+
.kol-asset-grid-4col { grid-template-columns: repeat(2, 1fr); }
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@media (max-width: 480px) {
|
|
227
|
+
.kol-asset-grid-2col,
|
|
228
|
+
.kol-asset-grid-3col,
|
|
229
|
+
.kol-asset-grid-4col { grid-template-columns: 1fr; }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* ───── Mood tile (image + overlay logomark) ─────
|
|
233
|
+
Wrappers inlined in MoodTile.jsx. CSS retains descendant img positioning
|
|
234
|
+
(cover-crop the photo) + overlay logo sizing. */
|
|
235
|
+
|
|
236
|
+
.kol-mood-tile-frame img {
|
|
237
|
+
position: absolute;
|
|
238
|
+
inset: 0;
|
|
239
|
+
width: 100%;
|
|
240
|
+
height: 100%;
|
|
241
|
+
object-fit: cover;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.kol-mood-tile-overlay .kol-brand-logo {
|
|
245
|
+
width: 32%;
|
|
246
|
+
max-width: 180px;
|
|
247
|
+
display: inline-flex;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.kol-mood-tile-overlay svg {
|
|
251
|
+
width: 100%;
|
|
252
|
+
height: auto;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* ───── Swatch / Ramp (color specimens) ───── */
|
|
256
|
+
|
|
257
|
+
.kol-swatch {
|
|
258
|
+
display: flex;
|
|
259
|
+
flex-direction: column;
|
|
260
|
+
gap: 6px;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.kol-swatch-chip {
|
|
264
|
+
height: 96px;
|
|
265
|
+
border-radius: 4px;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.kol-swatch-meta {
|
|
269
|
+
display: flex;
|
|
270
|
+
flex-direction: row;
|
|
271
|
+
justify-content: space-between;
|
|
272
|
+
align-items: baseline;
|
|
273
|
+
flex-wrap: wrap;
|
|
274
|
+
gap: 4px 12px;
|
|
275
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.kol-ramp-chips {
|
|
279
|
+
display: grid;
|
|
280
|
+
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
|
281
|
+
gap: 4px;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* ───── Type sample (brand type specimen) ─────
|
|
285
|
+
Wrapper padding inlined in TypeSample.jsx; body margin handled by Preflight.
|
|
286
|
+
CSS retains the adjacent-sibling border-top that separates stacked samples. */
|
|
287
|
+
|
|
288
|
+
.kol-type-sample + .kol-type-sample {
|
|
289
|
+
border-top: 1px solid var(--kol-fg-08);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* Prose moved to DS typography — see kol-typography-mono.css.
|
|
293
|
+
See docs/documentation/06-framework/06-amendments.md 2026-04-23. */
|
|
294
|
+
|
|
295
|
+
.kol-prose-indented {
|
|
296
|
+
padding-left: 32px;
|
|
297
|
+
border-left: 1px solid var(--kol-fg-16);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.kol-prose pre {
|
|
301
|
+
margin: 0 0 24px;
|
|
302
|
+
padding: 16px;
|
|
303
|
+
border-radius: 4px;
|
|
304
|
+
font-family: 'Right Grotesk Mono', monospace;
|
|
305
|
+
font-size: 16px;
|
|
306
|
+
line-height: 24px;
|
|
307
|
+
overflow-x: auto;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.kol-prose code {
|
|
311
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
312
|
+
font-size: 0.9em;
|
|
313
|
+
padding: 1px 4px;
|
|
314
|
+
border-radius: 3px;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.kol-prose pre code {
|
|
318
|
+
padding: 0;
|
|
319
|
+
background: none;
|
|
320
|
+
border-radius: 0;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.kol-prose-pullout {
|
|
324
|
+
padding: 16px 0;
|
|
325
|
+
margin: 32px 0;
|
|
326
|
+
border-top: 1px solid var(--kol-fg-08);
|
|
327
|
+
border-bottom: 1px solid var(--kol-fg-08);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* ───── Fullscreen overlay ───── */
|
|
331
|
+
|
|
332
|
+
.kol-overlay {
|
|
333
|
+
position: fixed;
|
|
334
|
+
inset: 0;
|
|
335
|
+
z-index: var(--kol-z-modal, 100);
|
|
336
|
+
background: color-mix(in srgb, var(--kol-surface-inverse) 88%, transparent);
|
|
337
|
+
display: flex;
|
|
338
|
+
align-items: center;
|
|
339
|
+
justify-content: center;
|
|
340
|
+
padding: 48px 24px;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.kol-overlay-sheet {
|
|
344
|
+
position: relative;
|
|
345
|
+
max-width: var(--kol-container-max);
|
|
346
|
+
max-height: 100%;
|
|
347
|
+
width: 100%;
|
|
348
|
+
display: flex;
|
|
349
|
+
align-items: center;
|
|
350
|
+
justify-content: center;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.kol-overlay-sheet img {
|
|
354
|
+
max-width: 100%;
|
|
355
|
+
max-height: 90vh;
|
|
356
|
+
object-fit: contain;
|
|
357
|
+
display: block;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.kol-overlay-close {
|
|
361
|
+
position: absolute;
|
|
362
|
+
top: -48px;
|
|
363
|
+
right: 0;
|
|
364
|
+
width: 40px;
|
|
365
|
+
height: 40px;
|
|
366
|
+
border-radius: 4px;
|
|
367
|
+
background: transparent;
|
|
368
|
+
border: 1px solid color-mix(in srgb, var(--kol-surface-on-inverse) 32%, transparent);
|
|
369
|
+
color: var(--kol-surface-on-inverse);
|
|
370
|
+
cursor: pointer;
|
|
371
|
+
font-size: 24px;
|
|
372
|
+
line-height: 1;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.kol-overlay-close:hover {
|
|
376
|
+
background: color-mix(in srgb, var(--kol-surface-on-inverse) 8%, transparent);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* ───── Carousel (embla) ───── */
|
|
380
|
+
|
|
381
|
+
.kol-embla { overflow: hidden; }
|
|
382
|
+
.kol-embla-viewport { overflow: hidden; }
|
|
383
|
+
.kol-embla-container {
|
|
384
|
+
display: flex;
|
|
385
|
+
gap: 16px;
|
|
386
|
+
}
|
|
387
|
+
.kol-embla-slide {
|
|
388
|
+
flex: 0 0 auto;
|
|
389
|
+
width: clamp(260px, 32vw, 420px);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.kol-embla.is-slides .kol-embla-slide {
|
|
393
|
+
width: clamp(320px, 72vw, 900px);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.kol-embla-controls {
|
|
397
|
+
display: flex;
|
|
398
|
+
gap: 8px;
|
|
399
|
+
justify-content: flex-end;
|
|
400
|
+
margin-top: 16px;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.kol-embla-btn {
|
|
404
|
+
width: 40px;
|
|
405
|
+
height: 40px;
|
|
406
|
+
border-radius: 4px;
|
|
407
|
+
background: transparent;
|
|
408
|
+
cursor: pointer;
|
|
409
|
+
font-size: 16px;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.kol-embla-btn:disabled {
|
|
413
|
+
opacity: 0.3;
|
|
414
|
+
cursor: not-allowed;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/* ───── Asset carousel + card tiles ─────
|
|
418
|
+
Section owns the height: the carousel viewport is a fixed box, and cards
|
|
419
|
+
flex to fill it. Frame holds the image, caption sits under it at natural
|
|
420
|
+
height. Image mode: default `contain` (artwork/diagrams), opt-in `.is-cover`
|
|
421
|
+
(photos, screenshots) crops to the top. */
|
|
422
|
+
|
|
423
|
+
.kol-embla.kol-asset-carousel .kol-embla-viewport {
|
|
424
|
+
height: 440px;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.kol-embla.kol-asset-carousel.is-slides .kol-embla-viewport {
|
|
428
|
+
height: 560px;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.kol-embla.kol-asset-carousel .kol-embla-container {
|
|
432
|
+
height: 100%;
|
|
433
|
+
align-items: stretch;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.kol-embla.kol-asset-carousel .kol-embla-slide {
|
|
437
|
+
height: 100%;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.kol-asset-card {
|
|
441
|
+
margin: 0;
|
|
442
|
+
height: 100%;
|
|
443
|
+
display: flex;
|
|
444
|
+
flex-direction: column;
|
|
445
|
+
gap: 8px;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.kol-asset-card-frame {
|
|
449
|
+
position: relative;
|
|
450
|
+
display: block;
|
|
451
|
+
width: 100%;
|
|
452
|
+
flex: 1;
|
|
453
|
+
min-height: 0;
|
|
454
|
+
padding: 0;
|
|
455
|
+
border: 1px solid var(--kol-fg-08);
|
|
456
|
+
border-radius: 4px;
|
|
457
|
+
overflow: hidden;
|
|
458
|
+
background: var(--kol-fg-04);
|
|
459
|
+
cursor: zoom-in;
|
|
460
|
+
transition: border-color 200ms ease;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.kol-asset-card-frame:hover {
|
|
464
|
+
border-color: var(--kol-fg-24);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.kol-asset-card-frame img {
|
|
468
|
+
width: 100%;
|
|
469
|
+
height: 100%;
|
|
470
|
+
object-fit: contain;
|
|
471
|
+
object-position: center;
|
|
472
|
+
display: block;
|
|
473
|
+
padding: 16px;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.kol-asset-card-frame.is-cover img {
|
|
477
|
+
object-fit: cover;
|
|
478
|
+
object-position: top center;
|
|
479
|
+
padding: 0;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
.kol-asset-card-overlay {
|
|
483
|
+
position: absolute;
|
|
484
|
+
inset: 0;
|
|
485
|
+
display: flex;
|
|
486
|
+
align-items: center;
|
|
487
|
+
justify-content: center;
|
|
488
|
+
color: var(--kol-fg-96);
|
|
489
|
+
pointer-events: none;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.kol-asset-card-overlay .kol-brand-logo { width: 24%; }
|
|
493
|
+
|
|
494
|
+
/* ───── Website preview ───── */
|
|
495
|
+
|
|
496
|
+
.kol-website-preview { margin-bottom: 32px; }
|
|
497
|
+
.kol-website-preview .kol-asset-figure-frame {
|
|
498
|
+
background: var(--kol-fg-02);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/* ───── Brand logo base ───── */
|
|
502
|
+
|
|
503
|
+
.kol-brand-logo {
|
|
504
|
+
display: inline-flex;
|
|
505
|
+
line-height: 0;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.kol-brand-logo svg {
|
|
509
|
+
display: block;
|
|
510
|
+
width: 100%;
|
|
511
|
+
height: auto;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/* ───── Kolkrabbi DS logo base ───── */
|
|
515
|
+
|
|
516
|
+
.kol-logomark {
|
|
517
|
+
display: inline-flex;
|
|
518
|
+
line-height: 0;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.kol-logomark svg {
|
|
522
|
+
display: block;
|
|
523
|
+
height: 100%;
|
|
524
|
+
width: auto;
|
|
525
|
+
max-width: 100%;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/* ───── Typography spec card (meta panel + live sample) ─────
|
|
529
|
+
Wrappers + meta-row grid + responsive layout inlined in TypeSpecCard.jsx.
|
|
530
|
+
CSS retains the descendant <p> overrides for sample prose (Preflight zeros
|
|
531
|
+
<p> margin; specs need 16px gap between paragraphs). */
|
|
532
|
+
|
|
533
|
+
.kol-type-spec-sample p { margin: 0 0 16px; }
|
|
534
|
+
.kol-type-spec-sample p:last-child { margin-bottom: 0; }
|
|
535
|
+
|
|
536
|
+
/* ───── Exit preview (floating × button on client surfaces) ───── */
|
|
537
|
+
|
|
538
|
+
.kol-exit-preview {
|
|
539
|
+
position: fixed;
|
|
540
|
+
bottom: 24px;
|
|
541
|
+
left: 24px;
|
|
542
|
+
z-index: 9999;
|
|
543
|
+
display: inline-flex;
|
|
544
|
+
align-items: center;
|
|
545
|
+
height: 48px;
|
|
546
|
+
background: var(--kol-surface-inverse);
|
|
547
|
+
color: var(--kol-surface-on-inverse);
|
|
548
|
+
border: 1px solid color-mix(in srgb, var(--kol-surface-on-inverse) 16%, transparent);
|
|
549
|
+
border-radius: 4px;
|
|
550
|
+
overflow: hidden;
|
|
551
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
552
|
+
font-size: 12px;
|
|
553
|
+
font-weight: 500;
|
|
554
|
+
letter-spacing: 0.12em;
|
|
555
|
+
text-transform: uppercase;
|
|
556
|
+
text-decoration: none;
|
|
557
|
+
cursor: pointer;
|
|
558
|
+
transition: background 200ms ease, border-color 200ms ease;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
.kol-exit-preview:hover {
|
|
562
|
+
border-color: color-mix(in srgb, var(--kol-surface-on-inverse) 32%, transparent);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
.kol-exit-preview-icon {
|
|
566
|
+
display: flex;
|
|
567
|
+
align-items: center;
|
|
568
|
+
justify-content: center;
|
|
569
|
+
width: 48px;
|
|
570
|
+
height: 48px;
|
|
571
|
+
font-size: 22px;
|
|
572
|
+
flex-shrink: 0;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.kol-exit-preview-label {
|
|
576
|
+
max-width: 0;
|
|
577
|
+
overflow: hidden;
|
|
578
|
+
white-space: nowrap;
|
|
579
|
+
transition: max-width 220ms ease, padding-right 220ms ease;
|
|
580
|
+
padding-right: 0;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.kol-exit-preview:hover .kol-exit-preview-label {
|
|
584
|
+
max-width: 120px;
|
|
585
|
+
padding-right: 20px;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/* ───── Portal footer (simple — Kolkrabbi wordmark + year) ───── */
|
|
589
|
+
|
|
590
|
+
.kol-portal-footer {
|
|
591
|
+
display: flex;
|
|
592
|
+
flex-direction: column;
|
|
593
|
+
align-items: center;
|
|
594
|
+
justify-content: center;
|
|
595
|
+
gap: 12px;
|
|
596
|
+
padding: 48px 24px;
|
|
597
|
+
border-top: 1px solid var(--kol-fg-08);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.kol-portal-footer p { margin: 0; }
|
|
601
|
+
|
|
602
|
+
.kol-portal-footer a { text-decoration: none; transition: opacity 150ms ease; }
|
|
603
|
+
.kol-portal-footer a:hover { opacity: 0.8; }
|
|
604
|
+
|
|
605
|
+
/* ───── Back link (structural only; use kol-helper-xs uppercase tracking-widest text-fg-64 on JSX) ───── */
|
|
606
|
+
|
|
607
|
+
.kol-back-link {
|
|
608
|
+
display: inline-flex;
|
|
609
|
+
align-items: center;
|
|
610
|
+
gap: 8px;
|
|
611
|
+
margin-bottom: 32px;
|
|
612
|
+
text-decoration: none;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* ───── Code block (rich-text + prose) ───── */
|
|
616
|
+
|
|
617
|
+
.kol-codeblock {
|
|
618
|
+
position: relative;
|
|
619
|
+
margin: 16px 0;
|
|
620
|
+
border: 1px solid var(--kol-fg-16);
|
|
621
|
+
border-radius: 4px;
|
|
622
|
+
background: var(--kol-fg-04);
|
|
623
|
+
overflow: hidden;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.kol-codeblock pre {
|
|
627
|
+
margin: 0;
|
|
628
|
+
padding: 20px 24px 20px 24px;
|
|
629
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
630
|
+
font-size: 13px;
|
|
631
|
+
line-height: 1.55;
|
|
632
|
+
overflow-x: auto;
|
|
633
|
+
color: var(--kol-surface-on-primary);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
.kol-codeblock pre code {
|
|
637
|
+
font-family: inherit;
|
|
638
|
+
padding: 0;
|
|
639
|
+
background: none;
|
|
640
|
+
border: none;
|
|
641
|
+
color: inherit;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
.kol-codeblock-lang {
|
|
645
|
+
position: absolute;
|
|
646
|
+
top: 8px;
|
|
647
|
+
left: 12px;
|
|
648
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
649
|
+
font-size: 10px;
|
|
650
|
+
font-weight: 600;
|
|
651
|
+
letter-spacing: 0.08em;
|
|
652
|
+
text-transform: uppercase;
|
|
653
|
+
color: var(--kol-fg-40);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
.kol-codeblock-lang + pre {
|
|
657
|
+
padding-top: 32px;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
.kol-codeblock-copy {
|
|
661
|
+
position: absolute;
|
|
662
|
+
top: 8px;
|
|
663
|
+
right: 8px;
|
|
664
|
+
display: inline-flex;
|
|
665
|
+
align-items: center;
|
|
666
|
+
gap: 6px;
|
|
667
|
+
padding: 6px 10px;
|
|
668
|
+
background: color-mix(in srgb, var(--kol-surface-primary) 80%, transparent);
|
|
669
|
+
border: 1px solid var(--kol-fg-16);
|
|
670
|
+
border-radius: 3px;
|
|
671
|
+
color: var(--kol-fg-64);
|
|
672
|
+
cursor: pointer;
|
|
673
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
674
|
+
font-size: 10px;
|
|
675
|
+
font-weight: 600;
|
|
676
|
+
letter-spacing: 0.08em;
|
|
677
|
+
text-transform: uppercase;
|
|
678
|
+
transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
.kol-codeblock-copy:hover {
|
|
682
|
+
color: var(--kol-surface-on-primary);
|
|
683
|
+
border-color: var(--kol-fg-48);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/* ───── Reveal utility ───── */
|
|
687
|
+
|
|
688
|
+
[data-reveal] {
|
|
689
|
+
opacity: 0;
|
|
690
|
+
transform: translateY(12px);
|
|
691
|
+
transition: opacity 600ms ease, transform 600ms ease;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
[data-reveal].is-revealed {
|
|
695
|
+
opacity: 1;
|
|
696
|
+
transform: none;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/* Text-role utility classes (.text-emphasis/.text-lede/.text-body/.text-meta/.text-subtle
|
|
700
|
+
+ hover variants) and .hover:border-fg-* variants live in kol-opacity.css. */
|
|
701
|
+
/**
|
|
702
|
+
* foundations.css — /foundations page specific styles.
|
|
703
|
+
*
|
|
704
|
+
* Color anatomy spectrum, color tokens table, and combo lab rules.
|
|
705
|
+
* Portal chrome (sidebar, topnav, page scaffold) stays in app.css.
|
|
706
|
+
*/
|
|
707
|
+
|
|
708
|
+
/* ───── Foundations · typography specimens ─────
|
|
709
|
+
Wrappers fully inlined in TypographySections.jsx. */
|
|
710
|
+
|
|
711
|
+
/* ───── Combo Lab layout primitives — shared structure classes ───── */
|
|
712
|
+
|
|
713
|
+
.kol-combo-frame {
|
|
714
|
+
border-radius: 4px;
|
|
715
|
+
overflow: hidden;
|
|
716
|
+
transition: background-color 400ms ease, border-color 400ms ease;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.kol-combo-slab {
|
|
720
|
+
padding: 16px;
|
|
721
|
+
display: flex;
|
|
722
|
+
flex-direction: column;
|
|
723
|
+
justify-content: space-between;
|
|
724
|
+
min-height: 0;
|
|
725
|
+
transition: background-color 400ms ease, color 400ms ease;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.kol-combo-slab--end { justify-content: flex-end; }
|
|
729
|
+
.kol-combo-slab--between { justify-content: space-between; }
|
|
730
|
+
|
|
731
|
+
.kol-combo-label {
|
|
732
|
+
font-family: 'Right Grotesk Compact', sans-serif;
|
|
733
|
+
font-size: 12px;
|
|
734
|
+
font-weight: 500;
|
|
735
|
+
line-height: 100%;
|
|
736
|
+
letter-spacing: 0.08em;
|
|
737
|
+
text-transform: uppercase;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.kol-combo-number {
|
|
741
|
+
font-family: 'Right Grotesk', sans-serif;
|
|
742
|
+
font-size: 16px;
|
|
743
|
+
font-weight: 700;
|
|
744
|
+
line-height: 100%;
|
|
745
|
+
letter-spacing: 0.02em;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
.kol-combo-stage--fill {
|
|
749
|
+
height: 100%;
|
|
750
|
+
min-height: 360px;
|
|
751
|
+
width: 100%;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
.kol-combo-logo {
|
|
755
|
+
display: inline-flex;
|
|
756
|
+
color: currentColor;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/* 60 / 30 / 10 */
|
|
760
|
+
.kol-combo-stage--ratio { display: flex; }
|
|
761
|
+
.kol-combo-stage--ratio > :nth-child(1) { flex: 1; }
|
|
762
|
+
.kol-combo-stage--ratio > :nth-child(2) { flex: 3; }
|
|
763
|
+
.kol-combo-stage--ratio > :nth-child(3) { flex: 6; }
|
|
764
|
+
|
|
765
|
+
/* Tower */
|
|
766
|
+
.kol-combo-stage--tower {
|
|
767
|
+
display: flex;
|
|
768
|
+
flex-direction: column;
|
|
769
|
+
height: 100%;
|
|
770
|
+
width: 100%;
|
|
771
|
+
}
|
|
772
|
+
.kol-combo-stage--tower > * { flex: 1; }
|
|
773
|
+
|
|
774
|
+
/* Quad split */
|
|
775
|
+
.kol-combo-stage--quad { display: flex; }
|
|
776
|
+
.kol-combo-stage--quad > * { flex: 1; }
|
|
777
|
+
|
|
778
|
+
.kol-combo-quad-col {
|
|
779
|
+
display: flex;
|
|
780
|
+
flex-direction: column;
|
|
781
|
+
}
|
|
782
|
+
.kol-combo-quad-col > * { flex: 1; }
|
|
783
|
+
|
|
784
|
+
/* Card row */
|
|
785
|
+
.kol-combo-stage--card-row {
|
|
786
|
+
display: grid;
|
|
787
|
+
grid-template-columns: repeat(4, 1fr);
|
|
788
|
+
gap: 16px;
|
|
789
|
+
height: 100%;
|
|
790
|
+
min-height: 360px;
|
|
791
|
+
width: 100%;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
.kol-combo-card {
|
|
795
|
+
flex: 1;
|
|
796
|
+
min-height: 240px;
|
|
797
|
+
padding: 20px;
|
|
798
|
+
display: flex;
|
|
799
|
+
flex-direction: column;
|
|
800
|
+
transition: background-color 400ms ease, color 400ms ease;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
.kol-combo-card--end { justify-content: flex-end; }
|
|
804
|
+
.kol-combo-card--between { justify-content: space-between; }
|
|
805
|
+
|
|
806
|
+
/* Stripe row */
|
|
807
|
+
.kol-combo-stage--stripe-row {
|
|
808
|
+
display: flex;
|
|
809
|
+
flex-direction: column;
|
|
810
|
+
gap: 16px;
|
|
811
|
+
height: 100%;
|
|
812
|
+
min-height: 360px;
|
|
813
|
+
width: 100%;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
.kol-combo-stripe-row {
|
|
817
|
+
display: flex;
|
|
818
|
+
flex: 1;
|
|
819
|
+
align-items: stretch;
|
|
820
|
+
width: 100%;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
.kol-combo-stripe-bar {
|
|
824
|
+
display: flex;
|
|
825
|
+
flex: 1;
|
|
826
|
+
position: relative;
|
|
827
|
+
width: 100%;
|
|
828
|
+
height: 100%;
|
|
829
|
+
border-radius: 4px;
|
|
830
|
+
overflow: hidden;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
.kol-combo-stripe-seg { transition: background-color 400ms ease; }
|
|
834
|
+
.kol-combo-stripe-seg--6 { flex: 6; }
|
|
835
|
+
.kol-combo-stripe-seg--3 { flex: 3; }
|
|
836
|
+
.kol-combo-stripe-seg--1 { flex: 1; }
|
|
837
|
+
|
|
838
|
+
.kol-combo-stripe-group { display: flex; }
|
|
839
|
+
.kol-combo-stripe-group--3 { flex: 3; }
|
|
840
|
+
.kol-combo-stripe-group--1 { flex: 1; }
|
|
841
|
+
|
|
842
|
+
.kol-combo-stripe-neutral {
|
|
843
|
+
border-top: 1px solid var(--stripe-rule, transparent);
|
|
844
|
+
border-bottom: 1px solid var(--stripe-rule, transparent);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
.kol-combo-stripe-accent-border {
|
|
848
|
+
border: 1.73px solid var(--stripe-accent, transparent);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
.kol-combo-stripe-method {
|
|
852
|
+
position: absolute;
|
|
853
|
+
top: 12px;
|
|
854
|
+
left: 12px;
|
|
855
|
+
font-family: 'Right Grotesk Compact', sans-serif;
|
|
856
|
+
font-size: 12px;
|
|
857
|
+
font-weight: 500;
|
|
858
|
+
letter-spacing: 0.08em;
|
|
859
|
+
line-height: 100%;
|
|
860
|
+
text-transform: uppercase;
|
|
861
|
+
color: white;
|
|
862
|
+
pointer-events: none;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/* Applied card */
|
|
866
|
+
.kol-combo-stage--applied {
|
|
867
|
+
display: flex;
|
|
868
|
+
height: 100%;
|
|
869
|
+
min-height: 360px;
|
|
870
|
+
width: 100%;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
.kol-combo-applied-plate {
|
|
874
|
+
flex: 2;
|
|
875
|
+
padding: 32px;
|
|
876
|
+
display: flex;
|
|
877
|
+
flex-direction: column;
|
|
878
|
+
justify-content: space-between;
|
|
879
|
+
transition: background-color 400ms ease, color 400ms ease;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.kol-combo-applied-col {
|
|
883
|
+
flex: 1;
|
|
884
|
+
display: flex;
|
|
885
|
+
flex-direction: column;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
.kol-combo-applied-surface { flex: 3; }
|
|
889
|
+
.kol-combo-applied-band--lg { flex: 2; }
|
|
890
|
+
.kol-combo-applied-band--sm { flex: 1; }
|
|
891
|
+
.kol-combo-applied-band { transition: background-color 400ms ease; }
|
|
892
|
+
|
|
893
|
+
.kol-combo-applied-accent-strip {
|
|
894
|
+
display: flex;
|
|
895
|
+
gap: 8px;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.kol-combo-applied-accent-chip {
|
|
899
|
+
width: 20px;
|
|
900
|
+
height: 20px;
|
|
901
|
+
border-radius: 2px;
|
|
902
|
+
transition: background-color 400ms ease;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/* ───── Foundations · combo lab ───── */
|
|
906
|
+
|
|
907
|
+
.kol-combo-lab {
|
|
908
|
+
display: flex;
|
|
909
|
+
flex-direction: column;
|
|
910
|
+
flex: 1;
|
|
911
|
+
padding: 24px;
|
|
912
|
+
border: 1px solid var(--kol-fg-08);
|
|
913
|
+
border-radius: 4px;
|
|
914
|
+
background: var(--kol-fg-02);
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
.kol-combo-controls { margin-bottom: 24px; }
|
|
918
|
+
|
|
919
|
+
.kol-combo-stage-wrap {
|
|
920
|
+
flex: 1;
|
|
921
|
+
margin-bottom: 24px;
|
|
922
|
+
padding: 32px;
|
|
923
|
+
background: var(--kol-fg-02);
|
|
924
|
+
border-radius: 4px;
|
|
925
|
+
min-height: 440px;
|
|
926
|
+
display: flex;
|
|
927
|
+
align-items: stretch;
|
|
928
|
+
justify-content: center;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
.kol-combo-stage-anim {
|
|
932
|
+
width: 100%;
|
|
933
|
+
height: 100%;
|
|
934
|
+
animation: kol-combo-fade 260ms ease;
|
|
935
|
+
display: flex;
|
|
936
|
+
align-items: stretch;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.kol-combo-stage-anim > * { width: 100%; height: 100%; }
|
|
940
|
+
|
|
941
|
+
/* In fullbleed mode, let the lab fill the section */
|
|
942
|
+
.kol-page--fullbleed .kol-combo-lab { flex: 1; }
|
|
943
|
+
.kol-page--fullbleed .kol-combo-stage-wrap { min-height: 520px; }
|
|
944
|
+
|
|
945
|
+
@keyframes kol-combo-fade {
|
|
946
|
+
from { opacity: 0.2; transform: translateY(6px); }
|
|
947
|
+
to { opacity: 1; transform: none; }
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
.kol-combo-readout {
|
|
951
|
+
display: grid;
|
|
952
|
+
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
|
953
|
+
gap: 8px 32px;
|
|
954
|
+
padding-top: 16px;
|
|
955
|
+
border-top: 1px solid var(--kol-fg-08);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/* Combo Lab — control rows (Layout / Palette / Logo selectors) */
|
|
959
|
+
.kol-combo-row {
|
|
960
|
+
display: flex;
|
|
961
|
+
align-items: center;
|
|
962
|
+
gap: 16px;
|
|
963
|
+
flex-wrap: wrap;
|
|
964
|
+
margin-bottom: 12px;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
.kol-combo-row-label { min-width: 72px; }
|
|
968
|
+
|
|
969
|
+
.kol-combo-row-controls {
|
|
970
|
+
display: flex;
|
|
971
|
+
flex-wrap: wrap;
|
|
972
|
+
gap: 6px;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.kol-combo-footer {
|
|
976
|
+
display: flex;
|
|
977
|
+
align-items: center;
|
|
978
|
+
gap: 16px;
|
|
979
|
+
margin-top: 8px;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
.kol-combo-footer-desc { flex: 1; }
|
|
983
|
+
|
|
984
|
+
.kol-combo-randomize {
|
|
985
|
+
padding: 8px 16px;
|
|
986
|
+
background: transparent;
|
|
987
|
+
color: var(--kol-fg-80);
|
|
988
|
+
border: 1px solid var(--kol-fg-16);
|
|
989
|
+
border-radius: 4px;
|
|
990
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
991
|
+
font-weight: 600;
|
|
992
|
+
cursor: pointer;
|
|
993
|
+
transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
.kol-combo-randomize:hover {
|
|
997
|
+
color: var(--kol-surface-on-primary);
|
|
998
|
+
border-color: var(--kol-fg-48);
|
|
999
|
+
background: var(--kol-fg-04);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/* Combo Lab — live palette readout rows */
|
|
1003
|
+
.kol-combo-swatch-row {
|
|
1004
|
+
display: flex;
|
|
1005
|
+
align-items: center;
|
|
1006
|
+
gap: 12px;
|
|
1007
|
+
padding: 6px 0;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
.kol-combo-swatch-chip {
|
|
1011
|
+
width: 24px;
|
|
1012
|
+
height: 24px;
|
|
1013
|
+
flex-shrink: 0;
|
|
1014
|
+
border-radius: 3px;
|
|
1015
|
+
transition: background 400ms ease;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
.kol-combo-swatch-label {
|
|
1019
|
+
min-width: 88px;
|
|
1020
|
+
font-weight: 600;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
.kol-combo-swatch-hex {
|
|
1024
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
1025
|
+
text-transform: uppercase;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
.kol-combo-summary { margin-top: 16px; }
|
|
1029
|
+
|
|
1030
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
1031
|
+
SpectrumGrid — matrix color-token grid (9 ramps × 10 stops)
|
|
1032
|
+
═════════════════════════════════════════════════════════════════════ */
|
|
1033
|
+
|
|
1034
|
+
.kol-spectrum-grid {
|
|
1035
|
+
display: grid;
|
|
1036
|
+
grid-template-columns: 100px repeat(10, minmax(0, 1fr));
|
|
1037
|
+
gap: 4px;
|
|
1038
|
+
width: 100%;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
.kol-spectrum-grid--loading {
|
|
1042
|
+
min-height: 400px;
|
|
1043
|
+
background: var(--kol-fg-02);
|
|
1044
|
+
border-radius: 6px;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
.kol-spectrum-grid-head {
|
|
1048
|
+
display: contents;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
.kol-spectrum-grid-corner {
|
|
1052
|
+
grid-column: 1;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
.kol-spectrum-grid-stop-label {
|
|
1056
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
1057
|
+
font-size: 11px;
|
|
1058
|
+
text-transform: uppercase;
|
|
1059
|
+
letter-spacing: 0.08em;
|
|
1060
|
+
color: var(--kol-fg-48);
|
|
1061
|
+
padding: 4px 6px;
|
|
1062
|
+
text-align: center;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
.kol-spectrum-grid-row {
|
|
1066
|
+
display: contents;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
.kol-spectrum-grid-row-label {
|
|
1070
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
1071
|
+
font-size: 12px;
|
|
1072
|
+
font-weight: 500;
|
|
1073
|
+
letter-spacing: 0.02em;
|
|
1074
|
+
color: var(--kol-surface-on-primary);
|
|
1075
|
+
align-self: center;
|
|
1076
|
+
padding-right: 12px;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
.kol-spectrum-grid-row-label::first-letter {
|
|
1080
|
+
text-transform: uppercase;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
.kol-spectrum-grid-cell {
|
|
1084
|
+
position: relative;
|
|
1085
|
+
aspect-ratio: 5 / 3;
|
|
1086
|
+
min-width: 0;
|
|
1087
|
+
border-radius: 4px;
|
|
1088
|
+
padding: 6px 8px;
|
|
1089
|
+
display: flex;
|
|
1090
|
+
flex-direction: column;
|
|
1091
|
+
justify-content: space-between;
|
|
1092
|
+
transition: transform 120ms ease;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
.kol-spectrum-grid-cell-marker {
|
|
1096
|
+
position: absolute;
|
|
1097
|
+
top: 50%;
|
|
1098
|
+
left: 50%;
|
|
1099
|
+
transform: translate(-50%, -50%);
|
|
1100
|
+
width: 10px;
|
|
1101
|
+
height: 10px;
|
|
1102
|
+
border-radius: 50%;
|
|
1103
|
+
background: currentColor;
|
|
1104
|
+
opacity: 0.85;
|
|
1105
|
+
pointer-events: none;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
.kol-spectrum-grid-cell:hover {
|
|
1109
|
+
transform: scale(1.04);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
.kol-spectrum-grid-cell-stop {
|
|
1113
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
1114
|
+
font-weight: 700;
|
|
1115
|
+
font-size: 12px;
|
|
1116
|
+
letter-spacing: 0.04em;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
.kol-spectrum-grid-cell-hex {
|
|
1120
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
1121
|
+
font-size: 9px;
|
|
1122
|
+
text-transform: uppercase;
|
|
1123
|
+
opacity: 0.78;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
@media (max-width: 900px) {
|
|
1127
|
+
.kol-spectrum-grid {
|
|
1128
|
+
grid-template-columns: 72px repeat(10, minmax(0, 1fr));
|
|
1129
|
+
gap: 2px;
|
|
1130
|
+
}
|
|
1131
|
+
.kol-spectrum-grid-cell {
|
|
1132
|
+
padding: 4px;
|
|
1133
|
+
}
|
|
1134
|
+
.kol-spectrum-grid-cell-hex {
|
|
1135
|
+
display: none;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
1141
|
+
Color Anatomy — token composition samples
|
|
1142
|
+
|
|
1143
|
+
Wrappers inlined in ColorAnatomy.jsx; figure margin via Preflight.
|
|
1144
|
+
CSS retains the descendant typography for figcaption + inline <code>.
|
|
1145
|
+
═════════════════════════════════════════════════════════════════════ */
|
|
1146
|
+
|
|
1147
|
+
.kol-anatomy-sample figcaption {
|
|
1148
|
+
margin-top: 12px;
|
|
1149
|
+
font-size: 12px;
|
|
1150
|
+
color: var(--kol-fg-48);
|
|
1151
|
+
font-style: italic;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
.kol-anatomy-sample code {
|
|
1155
|
+
font-family: var(--kol-font-family-mono, monospace);
|
|
1156
|
+
font-size: 11px;
|
|
1157
|
+
background: color-mix(in srgb, currentColor 18%, transparent);
|
|
1158
|
+
padding: 1px 4px;
|
|
1159
|
+
border-radius: 3px;
|
|
1160
|
+
opacity: 1;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
1165
|
+
Accordion — collapsible panel group
|
|
1166
|
+
|
|
1167
|
+
Wrapper, panel borders, trigger button reset, title/meta/chevron typography
|
|
1168
|
+
all inlined in Accordion.jsx. CSS retains the two state cascades:
|
|
1169
|
+
- .is-open chevron color flip
|
|
1170
|
+
- :has(meta) chevron margin reset (so meta + chevron sit together)
|
|
1171
|
+
═════════════════════════════════════════════════════════════════════ */
|
|
1172
|
+
|
|
1173
|
+
.kol-accordion-panel.is-open .kol-accordion-chevron {
|
|
1174
|
+
color: var(--kol-surface-on-primary);
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
.kol-accordion-trigger:has(.kol-accordion-meta) .kol-accordion-chevron {
|
|
1178
|
+
margin-left: 0;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
1182
|
+
AssetPlaceholder — deliberate missing/pending fallback frame
|
|
1183
|
+
Wrappers + label typography inlined in AssetPlaceholder.jsx.
|
|
1184
|
+
═════════════════════════════════════════════════════════════════════ */
|
|
1185
|
+
|
|
1186
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
1187
|
+
Graphic wrapper
|
|
1188
|
+
|
|
1189
|
+
Base wrapper inlined in Graphic.jsx. CSS retains:
|
|
1190
|
+
- descendant SVG sizing (svg comes from dangerouslySetInnerHTML — no
|
|
1191
|
+
way to apply utility classes inside the raw markup)
|
|
1192
|
+
- .kol-graphic--native modifier (opt-in: respect SVG's intrinsic
|
|
1193
|
+
width/height attributes instead of the default fluid 100%)
|
|
1194
|
+
═════════════════════════════════════════════════════════════════════ */
|
|
1195
|
+
|
|
1196
|
+
.kol-graphic svg {
|
|
1197
|
+
width: 100%;
|
|
1198
|
+
height: auto;
|
|
1199
|
+
display: block;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
.kol-graphic--native { width: auto; }
|
|
1203
|
+
.kol-graphic--native svg { width: auto; height: auto; }
|
|
1204
|
+
|
|
1205
|
+
/* Image wrapper inlined in Image.jsx. Graphics registry tiles
|
|
1206
|
+
(.kol-graphic-tile) deleted — zero JSX consumers. */
|
|
1207
|
+
|
|
1208
|
+
/* ═════════════════════════════════════════════════════════════════════
|
|
1209
|
+
Logo subsections — consistent rhythm inside sections
|
|
1210
|
+
|
|
1211
|
+
Wrappers + subhead title typography inlined in Logo.jsx (SubSection fn).
|
|
1212
|
+
CSS retains the descendant <p> rule for body prose (Preflight zeros <p>
|
|
1213
|
+
margin; logo-section paragraphs need explicit typography + measure cap).
|
|
1214
|
+
═════════════════════════════════════════════════════════════════════ */
|
|
1215
|
+
|
|
1216
|
+
.kol-logo-subsection-body p {
|
|
1217
|
+
font-family: var(--kol-font-family-mono);
|
|
1218
|
+
font-size: var(--kol-text-body-03);
|
|
1219
|
+
line-height: 1.6;
|
|
1220
|
+
color: var(--kol-fg-64);
|
|
1221
|
+
max-width: 70ch;
|
|
1222
|
+
margin: 0;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/* .kol-checker + .kol-grid-bg — moved to src/editor/styles/kol-editor.css */
|