@stnd/styles 0.5.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/CHANGELOG.md +25 -0
- package/README.md +116 -0
- package/TOKENS.md +415 -0
- package/_standard-00-reset.scss +74 -0
- package/_standard-00-variables.scss +54 -0
- package/_standard-01-token.scss +287 -0
- package/_standard-02-color.scss +683 -0
- package/_standard-03-typography.scss +411 -0
- package/_standard-04-grid.scss +314 -0
- package/_standard-05-rhythm.scss +57 -0
- package/_standard-06-prose.scss +289 -0
- package/_standard-07-base.scss +216 -0
- package/_standard-08-media.scss +216 -0
- package/_standard-09-lists.scss +103 -0
- package/_standard-10-tables.scss +49 -0
- package/_standard-11-forms.scss +343 -0
- package/_standard-12-code.scss +204 -0
- package/_standard-13-components.scss +1261 -0
- package/_standard-14-analog.scss +48 -0
- package/_standard-30-contrast.scss +42 -0
- package/_standard-31-print.scss +97 -0
- package/_standard-32-eink.scss +78 -0
- package/_standard-50-utilities.scss +1117 -0
- package/_standard-99-debug.scss +474 -0
- package/dist/obsidian.css +31 -0
- package/dist/obsidian.css.map +1 -0
- package/dist/standard.css +20 -0
- package/dist/standard.css.map +1 -0
- package/index.js +1 -0
- package/obsidian.scss +18 -0
- package/package.json +46 -0
- package/standard.scss +52 -0
|
@@ -0,0 +1,1261 @@
|
|
|
1
|
+
@use "standard-00-variables" as *;
|
|
2
|
+
|
|
3
|
+
/* =========================== */
|
|
4
|
+
/* BUTTONS */
|
|
5
|
+
/* =========================== */
|
|
6
|
+
|
|
7
|
+
.loader {
|
|
8
|
+
width: var(--size-lg);
|
|
9
|
+
height: var(--size-lg);
|
|
10
|
+
border: var(--space-d3) solid transparent;
|
|
11
|
+
background: transparent;
|
|
12
|
+
border-radius: 50%;
|
|
13
|
+
display: inline-block;
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
filter: blur(0.3px);
|
|
16
|
+
animation: rotation 0.25s linear infinite;
|
|
17
|
+
|
|
18
|
+
--color-loading-mix: color-mix(in oklch, var(--color-accent) 100%, black);
|
|
19
|
+
--color-loading: oklch(from var(--color-loading-mix) l c h / 0.25);
|
|
20
|
+
border-bottom-color: var(--color-loading);
|
|
21
|
+
box-shadow:
|
|
22
|
+
0px 4px 6px -2px var(--color-loading),
|
|
23
|
+
inset 0px -4px 6px -2px var(--color-loading);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@keyframes rotation {
|
|
27
|
+
0% {
|
|
28
|
+
transform: rotate(0deg);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
100% {
|
|
32
|
+
transform: rotate(360deg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
kbd {
|
|
37
|
+
background-color: var(--color-surface);
|
|
38
|
+
background-image: var(--effect-grain);
|
|
39
|
+
border: none;
|
|
40
|
+
border-radius: var(--radius);
|
|
41
|
+
/* Button-like raised effect */
|
|
42
|
+
box-shadow: var(--shadow-raised);
|
|
43
|
+
padding: var(--space-d6) var(--space-d3);
|
|
44
|
+
font-family: var(--font-monospace);
|
|
45
|
+
font-size: var(--size-xs);
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
$types: "secondary", "outline", "destructive", "ghost", "icon";
|
|
50
|
+
|
|
51
|
+
:where(button),
|
|
52
|
+
a.btn {
|
|
53
|
+
@extend %surface;
|
|
54
|
+
@extend %padding-text;
|
|
55
|
+
padding: var(--space-d6) var(--space-d2);
|
|
56
|
+
display: inline-flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
justify-content: center;
|
|
59
|
+
font-family: var(--font-interface);
|
|
60
|
+
font-weight: var(--font-weight-bold);
|
|
61
|
+
line-height: var(--line-height);
|
|
62
|
+
font-size: 1em;
|
|
63
|
+
user-select: none;
|
|
64
|
+
background-color: var(--color-surface-high);
|
|
65
|
+
color: var(--color-foreground);
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
gap: var(--space-d3);
|
|
68
|
+
text-align: center;
|
|
69
|
+
min-height: 1em;
|
|
70
|
+
|
|
71
|
+
/* shadcn-style raised effect */
|
|
72
|
+
box-shadow: var(--shadow-raised);
|
|
73
|
+
border: var(--border);
|
|
74
|
+
|
|
75
|
+
transition: all var(--transition-fast);
|
|
76
|
+
|
|
77
|
+
text-box-trim: trim-both;
|
|
78
|
+
text-box-edge: cap alphabetic;
|
|
79
|
+
|
|
80
|
+
text-decoration: none !important;
|
|
81
|
+
|
|
82
|
+
&:hover {
|
|
83
|
+
background-color: var(--color-surface-highest);
|
|
84
|
+
/* Lift shadow slightly on hover */
|
|
85
|
+
color: var(--color-foreground);
|
|
86
|
+
box-shadow: var(--shadow-raised), var(--shadow-lg);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&:active {
|
|
90
|
+
background-color: var(--color-surface-low);
|
|
91
|
+
/* Flatten shadow on press */
|
|
92
|
+
box-shadow: var(--shadow-inset), var(--shadow-ring);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Loop through the list to create .badge-outline, .badge-ghost, etc. */
|
|
96
|
+
@each $type in $types {
|
|
97
|
+
&.#{$type} {
|
|
98
|
+
@extend .btn;
|
|
99
|
+
@extend button;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
:where(button):focus-visible,
|
|
105
|
+
a.btn:focus-visible {
|
|
106
|
+
outline: 2px solid var(--color-accent);
|
|
107
|
+
outline-offset: 2px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
:where(button).destructive,
|
|
111
|
+
a.btn.destructive {
|
|
112
|
+
color: color-mix(in srgb, var(--color-error) 75%, transparent);
|
|
113
|
+
|
|
114
|
+
&:hover {
|
|
115
|
+
background-color: var(--color-error);
|
|
116
|
+
color: var(--color-on-accent);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
:where(button).secondary,
|
|
121
|
+
a.btn.secondary {
|
|
122
|
+
background-color: var(--color-accent);
|
|
123
|
+
color: var(--color-on-accent);
|
|
124
|
+
|
|
125
|
+
&:hover {
|
|
126
|
+
color: var(--color-accent);
|
|
127
|
+
background-color: var(--color-surface-high);
|
|
128
|
+
box-shadow: var(--shadow-raised), var(--shadow-glow);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&:active {
|
|
132
|
+
background-color: var(--color-surface);
|
|
133
|
+
/* Flatten shadow on press */
|
|
134
|
+
box-shadow: var(--shadow-inset), var(--shadow-ring), var(--shadow-glow);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:where(button).link,
|
|
139
|
+
a.btn.link {
|
|
140
|
+
background-color: var(--color-surface);
|
|
141
|
+
color: var(--color-link);
|
|
142
|
+
|
|
143
|
+
&:hover {
|
|
144
|
+
background: color-mix(in srgb, currentColor 10%, var(--color-surface));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
&:active {
|
|
148
|
+
background-color: var(--color-surface);
|
|
149
|
+
/* Flatten shadow on press */
|
|
150
|
+
box-shadow: var(--shadow-inset), var(--shadow-ring);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
:where(button).outline,
|
|
155
|
+
a.btn.outline {
|
|
156
|
+
background-color: transparent;
|
|
157
|
+
backdrop-filter: var(--filter-blur);
|
|
158
|
+
color: var(--color-subtle);
|
|
159
|
+
|
|
160
|
+
&:hover {
|
|
161
|
+
color: var(--color-foreground);
|
|
162
|
+
background-color: var(--color-surface-higher);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
&:active {
|
|
166
|
+
color: var(--color-foreground);
|
|
167
|
+
background-color: var(--color-surface-lower);
|
|
168
|
+
/* Flatten shadow on press */
|
|
169
|
+
box-shadow: var(--shadow-inset), var(--shadow-ring);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
:where(button).ghost,
|
|
174
|
+
a.btn.ghost {
|
|
175
|
+
background: none;
|
|
176
|
+
border: none;
|
|
177
|
+
box-shadow: none;
|
|
178
|
+
color: var(--color-muted);
|
|
179
|
+
|
|
180
|
+
&:hover {
|
|
181
|
+
color: var(--color-foreground);
|
|
182
|
+
background-color: var(--color-surface-higher);
|
|
183
|
+
box-shadow: var(--shadow-raised), var(--shadow-lg);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
&:active {
|
|
187
|
+
background-color: var(--color-surface);
|
|
188
|
+
/* Flatten shadow on press */
|
|
189
|
+
box-shadow: var(--shadow-inset), var(--shadow-ring);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
:where(button).large,
|
|
194
|
+
a.btn.large {
|
|
195
|
+
padding: var(--space) var(--space-2);
|
|
196
|
+
font-size: var(--size-base);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
:where(button).small,
|
|
200
|
+
a.btn.small {
|
|
201
|
+
padding: var(--space-d6) var(--space-d2);
|
|
202
|
+
font-size: var(--size-xs);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
:where(button).smaller,
|
|
206
|
+
a.btn.smaller {
|
|
207
|
+
padding: var(--space-d6) var(--space-d3);
|
|
208
|
+
font-size: var(--size-xs);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
:where(button).icon,
|
|
212
|
+
a.btn.icon {
|
|
213
|
+
display: flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
justify-content: center;
|
|
216
|
+
padding: var(--leading);
|
|
217
|
+
margin: 0;
|
|
218
|
+
aspect-ratio: 1/1;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
:where(button).disabled,
|
|
222
|
+
:where(button):disabled,
|
|
223
|
+
a.btn.disabled,
|
|
224
|
+
a.btn:disabled {
|
|
225
|
+
opacity: 0.5 !important;
|
|
226
|
+
color: var(--color-subtle) !important;
|
|
227
|
+
cursor: not-allowed !important;
|
|
228
|
+
pointer-events: none !important;
|
|
229
|
+
}
|
|
230
|
+
/*
|
|
231
|
+
:is(:where(button), .btn) svg {
|
|
232
|
+
height: 100%;
|
|
233
|
+
width: auto;
|
|
234
|
+
fill: currentColor;
|
|
235
|
+
}
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
.tag {
|
|
239
|
+
color: var(--color-muted);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.tag:hover {
|
|
243
|
+
color: var(--color-accent);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.badge {
|
|
247
|
+
padding: 0 var(--space-d3);
|
|
248
|
+
background-color: color-mix(in oklch, currentColor 15%, transparent);
|
|
249
|
+
color: var(--color-accent);
|
|
250
|
+
border-radius: 999px;
|
|
251
|
+
border: var(--stroke-width) solid
|
|
252
|
+
color-mix(in oklch, currentColor 30%, transparent);
|
|
253
|
+
font-size: var(--size-xs);
|
|
254
|
+
display: inline-flex;
|
|
255
|
+
align-items: center;
|
|
256
|
+
gap: var(--space-d3);
|
|
257
|
+
text-box-trim: trim-both;
|
|
258
|
+
text-box-edge: cap alphabetic;
|
|
259
|
+
text-decoration: none;
|
|
260
|
+
font-weight: 500;
|
|
261
|
+
font-family: var(--font-interface);
|
|
262
|
+
user-select: none;
|
|
263
|
+
transition: all var(--transition-fast);
|
|
264
|
+
box-shadow: var(--shadow-ring);
|
|
265
|
+
width: fit-content;
|
|
266
|
+
|
|
267
|
+
font-variation-settings: "wdth" 900;
|
|
268
|
+
|
|
269
|
+
&.small {
|
|
270
|
+
padding: 0 var(--space-d4) !important;
|
|
271
|
+
font-size: var(--size-xs);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
&.smaller {
|
|
275
|
+
padding: 0 var(--space-d4) !important;
|
|
276
|
+
font-size: var(--size-2xs);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
::selection {
|
|
280
|
+
background: transparent;
|
|
281
|
+
color: currentColor;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
a {
|
|
285
|
+
text-decoration-color: oklch(from currentColor l c h / 0.5);
|
|
286
|
+
text-decoration-thickness: 0.112em;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* Loop through the list to create .badge-outline, .badge-ghost, etc. */
|
|
290
|
+
@each $type in $types {
|
|
291
|
+
&.#{$type} {
|
|
292
|
+
@extend .badge;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
a.badge:hover,
|
|
298
|
+
.badge a:hover {
|
|
299
|
+
color: var(--color-on-accent);
|
|
300
|
+
background: color-mix(
|
|
301
|
+
in oklch,
|
|
302
|
+
var(--color-accent) 70%,
|
|
303
|
+
var(--color-surface)
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.badge.secondary,
|
|
308
|
+
a.badge.secondary {
|
|
309
|
+
background-color: var(--color-surface);
|
|
310
|
+
color: var(--color-foreground);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
a.badge.secondary:hover,
|
|
314
|
+
.badge.secondary a:hover {
|
|
315
|
+
color: var(--color-accent);
|
|
316
|
+
background: color-mix(in oklch, currentColor 5%, var(--color-surface));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.badge.outline {
|
|
320
|
+
background-color: transparent;
|
|
321
|
+
color: var(--color-muted);
|
|
322
|
+
|
|
323
|
+
&:hover,
|
|
324
|
+
a:hover {
|
|
325
|
+
color: var(--color-foreground);
|
|
326
|
+
background: var(--color-surface);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.badge.ghost {
|
|
331
|
+
background-color: transparent;
|
|
332
|
+
border-color: transparent;
|
|
333
|
+
color: var(--color-muted);
|
|
334
|
+
|
|
335
|
+
&:hover {
|
|
336
|
+
color: var(--color-foreground);
|
|
337
|
+
background: var(--color-surface);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.badge.destructive {
|
|
342
|
+
background-color: var(--color-surface);
|
|
343
|
+
border-color: color-mix(
|
|
344
|
+
in oklch,
|
|
345
|
+
var(--color-error) 10%,
|
|
346
|
+
var(--color-border)
|
|
347
|
+
);
|
|
348
|
+
color: var(--color-error);
|
|
349
|
+
|
|
350
|
+
&:hover,
|
|
351
|
+
a:hover {
|
|
352
|
+
background-color: var(--color-error);
|
|
353
|
+
color: var(--color-on-accent);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.alert {
|
|
358
|
+
font-family: var(--font-interface);
|
|
359
|
+
--color-alert: var(--color-accent);
|
|
360
|
+
padding: var(--space-d2);
|
|
361
|
+
color: color-mix(
|
|
362
|
+
in oklch,
|
|
363
|
+
var(--color-alert) 25%,
|
|
364
|
+
var(--color-foreground)
|
|
365
|
+
) !important;
|
|
366
|
+
/* Alpha overlay works consistently on both light and dark backgrounds:
|
|
367
|
+
light bg → pale tint, dark bg → visible colored tint */
|
|
368
|
+
background: oklch(from var(--color-alert) l c h / 0.1);
|
|
369
|
+
border-left: var(--stroke-width) solid
|
|
370
|
+
oklch(from var(--color-alert) l c h / 0.5);
|
|
371
|
+
box-shadow: var(--shadow-raised);
|
|
372
|
+
text-shadow: none !important;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Callout Color Variants
|
|
376
|
+
.alert.warning {
|
|
377
|
+
--color-alert: var(--color-warning);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.alert.error {
|
|
381
|
+
--color-alert: var(--color-error);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.alert.success {
|
|
385
|
+
--color-alert: var(--color-success);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.alert.info {
|
|
389
|
+
--color-alert: var(--color-info);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* @name Card Component
|
|
394
|
+
* @group components-layout
|
|
395
|
+
* @author Francis Fontaine
|
|
396
|
+
* @since 0.11.0
|
|
397
|
+
*
|
|
398
|
+
* In 1991, Edward Tufte published "Envisioning Information" and introduced
|
|
399
|
+
* the concept of "small multiples"—the idea that human brains excel at
|
|
400
|
+
* comparing information when it's presented in identical visual containers.
|
|
401
|
+
* Show someone seven weather forecasts in seven different layouts, and they'll
|
|
402
|
+
* struggle. Show them seven identical cards with different data, and patterns
|
|
403
|
+
* emerge instantly. The structure disappears, the content shines.
|
|
404
|
+
*
|
|
405
|
+
* But here's the catch: small multiples only work when they're truly identical.
|
|
406
|
+
* One card with 16px padding, another with 20px, a third with 18px—your brain
|
|
407
|
+
* registers the inconsistency before it processes the content. This component
|
|
408
|
+
* solves that problem by providing a single source of truth for card structure.
|
|
409
|
+
* Every card gets the same padding, the same borders, the same rhythm. Build
|
|
410
|
+
* one card or build a hundred—they'll feel like family.
|
|
411
|
+
*
|
|
412
|
+
* The Swiss designers understood this in the 1950s. Josef Müller-Brockmann's
|
|
413
|
+
* concert posters used rigid grids not to constrain creativity, but to amplify
|
|
414
|
+
* it. When the structure is invisible, when it just works, your content can
|
|
415
|
+
* breathe. That's what `.card` does—it handles the boring consistency so you
|
|
416
|
+
* can focus on making something beautiful.
|
|
417
|
+
*
|
|
418
|
+
* ### Future Improvements
|
|
419
|
+
*
|
|
420
|
+
* - Elevation variants (flat, raised, floating) with shadow scales
|
|
421
|
+
* - Interactive hover states for clickable cards with smooth transitions
|
|
422
|
+
* - Horizontal card layout variant for image + content side-by-side
|
|
423
|
+
* - Dark mode shadow adjustments for better depth perception
|
|
424
|
+
* - Optional card image hero with object-fit controls
|
|
425
|
+
*
|
|
426
|
+
* @see {class} .grid - Often used to layout multiple cards in columns
|
|
427
|
+
* @see {variable} --base - Controls internal spacing rhythm
|
|
428
|
+
* @see {class} .prose - Can be used inside card-body for rich content
|
|
429
|
+
*
|
|
430
|
+
* @link https://en.wikipedia.org/wiki/Edward_Tufte Information Design Pioneer
|
|
431
|
+
* @link https://www.nngroup.com/articles/cards-component/ NN/g Cards Research
|
|
432
|
+
*
|
|
433
|
+
* @example html - Basic card structure
|
|
434
|
+
* <article class="card">
|
|
435
|
+
* <header class="card-header">
|
|
436
|
+
* <h3>Card Title</h3>
|
|
437
|
+
* </header>
|
|
438
|
+
* <div class="card-body">
|
|
439
|
+
* <p>Card content with automatic spacing and rhythm.</p>
|
|
440
|
+
* </div>
|
|
441
|
+
* <footer class="card-footer">
|
|
442
|
+
* <a href="#">Read more →</a>
|
|
443
|
+
* </footer>
|
|
444
|
+
* </article>
|
|
445
|
+
*
|
|
446
|
+
* @example html - Cards in grid layout (3-column responsive)
|
|
447
|
+
* <div class="grid">
|
|
448
|
+
* <article class="card col-4 col-sm-12">
|
|
449
|
+
* <div class="card-body">
|
|
450
|
+
* <h3>Feature One</h3>
|
|
451
|
+
* <p>Description...</p>
|
|
452
|
+
* </div>
|
|
453
|
+
* </article>
|
|
454
|
+
* <article class="card col-4 col-sm-12">...</article>
|
|
455
|
+
* <article class="card col-4 col-sm-12">...</article>
|
|
456
|
+
* </div>
|
|
457
|
+
*
|
|
458
|
+
* @example html - Clickable card (entire card is a link)
|
|
459
|
+
* <a href="/article" class="card card-clickable">
|
|
460
|
+
* <div class="card-body">
|
|
461
|
+
* <h3>Article Title</h3>
|
|
462
|
+
* <p>Preview text that entices you to click...</p>
|
|
463
|
+
* </div>
|
|
464
|
+
* </a>
|
|
465
|
+
*
|
|
466
|
+
* @example scss - Customizing card via CSS variables
|
|
467
|
+
* .card.custom {
|
|
468
|
+
* --card-border-color: var(--color-accent);
|
|
469
|
+
* --card-padding: var(--size-lg);
|
|
470
|
+
* --card-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
471
|
+
* }
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* @name Clickable Card Variant
|
|
476
|
+
* @group components-layout
|
|
477
|
+
* @since 0.11.0
|
|
478
|
+
*
|
|
479
|
+
* Sometimes your entire card should be clickable—a blog post preview, a product
|
|
480
|
+
* listing, a project showcase. This variant ensures proper hover states, focus
|
|
481
|
+
* indicators, and cursor feedback while maintaining the card's structural integrity.
|
|
482
|
+
*
|
|
483
|
+
* The subtle lift on hover (2px translateY) and enhanced shadow create the
|
|
484
|
+
* illusion of depth—like the card is rising toward you. It's a tactile metaphor
|
|
485
|
+
* for "this is interactive." The focus-visible outline ensures keyboard users
|
|
486
|
+
* can see exactly where they are.
|
|
487
|
+
*
|
|
488
|
+
* Accessibility note: When using clickable cards, ensure the link text is
|
|
489
|
+
* descriptive. "Read more" alone isn't enough—screen readers need context.
|
|
490
|
+
* Use "Read more about [article title]" or aria-label.
|
|
491
|
+
*
|
|
492
|
+
* @see {class} .card - Base component
|
|
493
|
+
* @see {element} a - Applied to anchor tag wrapping card content
|
|
494
|
+
*
|
|
495
|
+
* @example html - Accessible clickable card
|
|
496
|
+
* <a href="/article/typography-history" class="card card-clickable"
|
|
497
|
+
* aria-label="Read full article about Typography History">
|
|
498
|
+
* <div class="card-body">
|
|
499
|
+
* <h3>Typography History</h3>
|
|
500
|
+
* <p>The evolution of type from Gutenberg to now...</p>
|
|
501
|
+
* </div>
|
|
502
|
+
* <div class="card-footer">
|
|
503
|
+
* Read more →
|
|
504
|
+
* </div>
|
|
505
|
+
* </a>
|
|
506
|
+
*/
|
|
507
|
+
.card {
|
|
508
|
+
@extend %surface;
|
|
509
|
+
padding: var(--space);
|
|
510
|
+
box-shadow: var(--shadow-raised), var(--shadow-lift);
|
|
511
|
+
background-color: var(--color-surface);
|
|
512
|
+
transition: all var(--transition);
|
|
513
|
+
border-radius: var(--radius);
|
|
514
|
+
border: var(--border);
|
|
515
|
+
|
|
516
|
+
&.hero {
|
|
517
|
+
border-radius: 0;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
h3 {
|
|
521
|
+
font-size: var(--scale-2);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
h2 {
|
|
525
|
+
font-size: var(--scale-3);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
h1 {
|
|
529
|
+
font-size: var(--scale-4);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.card > header:first-child {
|
|
534
|
+
background: var(--color-surface);
|
|
535
|
+
box-shadow: var(--shadow-lift);
|
|
536
|
+
border-bottom: var(--border);
|
|
537
|
+
border-radius: var(--radius) var(--radius) 0 0;
|
|
538
|
+
padding: var(--space);
|
|
539
|
+
margin: calc(var(--space) * -1);
|
|
540
|
+
margin-block-end: 0;
|
|
541
|
+
|
|
542
|
+
:is(h1, h2, h3, h4, h5, h6) {
|
|
543
|
+
margin-block: 0;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
&.surface {
|
|
547
|
+
margin-bottom: 0;
|
|
548
|
+
border-bottom: var(--border);
|
|
549
|
+
|
|
550
|
+
box-shadow: var(--shadow);
|
|
551
|
+
background-color: var(--color-surface);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
p {
|
|
555
|
+
margin-top: var(--space-d2);
|
|
556
|
+
color: var(--color-muted);
|
|
557
|
+
font-size: var(--size-sm);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
+ * {
|
|
561
|
+
margin-block-start: var(--space);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
.card > header:has(svg):first-child {
|
|
566
|
+
display: flex;
|
|
567
|
+
align-items: center;
|
|
568
|
+
justify-content: space-between;
|
|
569
|
+
a {
|
|
570
|
+
margin-top: 0;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.card > footer:last-child {
|
|
575
|
+
background: var(--color-surface-low);
|
|
576
|
+
border-top: var(--border);
|
|
577
|
+
border-radius: 0 0 var(--radius) var(--radius);
|
|
578
|
+
padding: var(--space-d2) var(--space);
|
|
579
|
+
font-size: var(--size-sm);
|
|
580
|
+
margin: calc(var(--space) * -1);
|
|
581
|
+
margin-top: var(--space);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
.card.clickable {
|
|
585
|
+
a {
|
|
586
|
+
text-decoration: none;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
color: inherit;
|
|
590
|
+
cursor: pointer;
|
|
591
|
+
|
|
592
|
+
&:hover {
|
|
593
|
+
transform: translateY(-2px);
|
|
594
|
+
/* Subtle lift with shadow preset */
|
|
595
|
+
box-shadow: var(--shadow-lg);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
&:focus-visible {
|
|
599
|
+
outline: 3px solid var(--color-accent);
|
|
600
|
+
outline-offset: 2px;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
&:active {
|
|
604
|
+
transform: translateY(0);
|
|
605
|
+
/* Press down on click */
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.inset,
|
|
610
|
+
card.inset {
|
|
611
|
+
box-shadow: inset var(--shadow) !important;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
.callout {
|
|
615
|
+
/* Raised effect for callout cards */
|
|
616
|
+
box-shadow: var(--shadow-raised), var(--shadow-ring);
|
|
617
|
+
|
|
618
|
+
border-radius: var(--radius-sm);
|
|
619
|
+
padding: var(--space-d8);
|
|
620
|
+
padding-top: 0;
|
|
621
|
+
--color-callout: var(--color-surface);
|
|
622
|
+
--color-border: oklch(from var(--color-callout) l c h / 0.15);
|
|
623
|
+
background: color-mix(
|
|
624
|
+
in srgb,
|
|
625
|
+
var(--color-callout) 10%,
|
|
626
|
+
var(--color-surface-high)
|
|
627
|
+
);
|
|
628
|
+
font-size: var(--size-sm);
|
|
629
|
+
|
|
630
|
+
.callout-title,
|
|
631
|
+
> summary {
|
|
632
|
+
position: relative;
|
|
633
|
+
color: color-mix(
|
|
634
|
+
in oklch,
|
|
635
|
+
var(--color-callout) 50%,
|
|
636
|
+
var(--color-foreground)
|
|
637
|
+
);
|
|
638
|
+
display: flex;
|
|
639
|
+
gap: var(--leading);
|
|
640
|
+
font-weight: var(--font-weight-bold, bold);
|
|
641
|
+
|
|
642
|
+
user-select: none;
|
|
643
|
+
padding: var(--space-d2);
|
|
644
|
+
margin: 0 !important;
|
|
645
|
+
|
|
646
|
+
.callout-title-inner {
|
|
647
|
+
margin: 0;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
.callout-content:has(> p:empty:only-child) {
|
|
652
|
+
display: none;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.callout-content {
|
|
656
|
+
color: var(--color-foreground);
|
|
657
|
+
background: color-mix(
|
|
658
|
+
in srgb,
|
|
659
|
+
var(--color-callout) 10%,
|
|
660
|
+
var(--color-surface-low)
|
|
661
|
+
);
|
|
662
|
+
line-height: var(--line-height-compact);
|
|
663
|
+
box-shadow: var(--shadow-inset), var(--shadow-ring);
|
|
664
|
+
border-radius: var(--radius-sm);
|
|
665
|
+
padding: var(--space-d2);
|
|
666
|
+
margin-top: 0;
|
|
667
|
+
margin-left: 0;
|
|
668
|
+
text-align: left;
|
|
669
|
+
|
|
670
|
+
p:first-child,
|
|
671
|
+
p:first-child:empty + p {
|
|
672
|
+
margin-top: 0 !important;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
p:last-child {
|
|
676
|
+
margin-bottom: 0 !important;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
ul,
|
|
680
|
+
ol {
|
|
681
|
+
padding: 0 var(--space-d2);
|
|
682
|
+
list-style: none;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
pre {
|
|
686
|
+
margin: var(--space-d2) 0;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
> .callout {
|
|
690
|
+
margin: calc(var(--space) * -1);
|
|
691
|
+
|
|
692
|
+
.callout-content {
|
|
693
|
+
padding: var(--space);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.callout-title {
|
|
697
|
+
padding-left: var(--space);
|
|
698
|
+
padding-right: var(--space);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.callout-title-icon {
|
|
704
|
+
display: none;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
img {
|
|
708
|
+
margin-left: 0;
|
|
709
|
+
margin-right: 0;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// Callout Color Variants
|
|
714
|
+
.callout[data-callout="warning" i] {
|
|
715
|
+
--color-callout: var(--color-red);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
.callout[data-callout="important" i] {
|
|
719
|
+
--color-callout: var(--color-orange);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// Notion Color Variants
|
|
723
|
+
.callout[data-callout*="gray" i] {
|
|
724
|
+
--color-callout: var(--color-foreground);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
.callout[data-callout*="red" i] {
|
|
728
|
+
--color-callout: var(--color-red);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
.callout[data-callout*="brown" i] {
|
|
732
|
+
--color-callout: var(--color-brown);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
.callout[data-callout*="orange" i] {
|
|
736
|
+
--color-callout: var(--color-orange);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
.callout[data-callout*="yellow" i] {
|
|
740
|
+
--color-callout: var(--color-yellow);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
.callout[data-callout*="green" i] {
|
|
744
|
+
--color-callout: var(--color-green);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.callout[data-callout*="cyan" i] {
|
|
748
|
+
--color-callout: var(--color-cyan);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.callout[data-callout*="blue" i] {
|
|
752
|
+
--color-callout: var(--color-blue);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
.callout[data-callout*="magenta" i] {
|
|
756
|
+
--color-callout: var(--color-magenta);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.callout[data-callout*="purple" i] {
|
|
760
|
+
--color-callout: var(--color-purple);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
.callout[data-callout*="pink" i] {
|
|
764
|
+
--color-callout: var(--color-pink);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Details/Summary specific callout styles
|
|
768
|
+
details > summary {
|
|
769
|
+
list-style: none;
|
|
770
|
+
/* removes marker in Firefox */
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
details .callout-title::before {
|
|
774
|
+
content: "▸";
|
|
775
|
+
display: inline-block;
|
|
776
|
+
transform: rotate(0deg);
|
|
777
|
+
margin-right: 0;
|
|
778
|
+
text-align: center;
|
|
779
|
+
text-box-trim: trim-both;
|
|
780
|
+
text-box-edge: cap alphabetic;
|
|
781
|
+
transform-origin: center;
|
|
782
|
+
transition: all var(--transition);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
details[open] .callout-title::before {
|
|
786
|
+
transform: rotate(90deg);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
details .callout-title-inner {
|
|
790
|
+
display: inline;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
details.callout {
|
|
794
|
+
interpolate-size: allow-keywords;
|
|
795
|
+
|
|
796
|
+
&::details-content {
|
|
797
|
+
height: 0;
|
|
798
|
+
overflow: hidden;
|
|
799
|
+
transition:
|
|
800
|
+
height var(--transition),
|
|
801
|
+
content-visibility var(--transition) allow-discrete;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
&[open]::details-content {
|
|
805
|
+
height: auto;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
details .callout-fold {
|
|
810
|
+
margin: 0;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// Caption Callout (after an image)
|
|
814
|
+
p:has(img) + .callout[data-callout="caption" i] {
|
|
815
|
+
padding: 0;
|
|
816
|
+
background: none;
|
|
817
|
+
padding-block-start: var(--gap);
|
|
818
|
+
border: none;
|
|
819
|
+
margin: 0 var(--space);
|
|
820
|
+
box-shadow: none;
|
|
821
|
+
|
|
822
|
+
.callout-title {
|
|
823
|
+
display: none;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
.callout-content {
|
|
827
|
+
padding: 0;
|
|
828
|
+
background: none;
|
|
829
|
+
color: var(--color-muted);
|
|
830
|
+
border: none;
|
|
831
|
+
|
|
832
|
+
box-shadow: none;
|
|
833
|
+
text-align: center;
|
|
834
|
+
text-wrap: balance;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
details .callout-title-inner {
|
|
839
|
+
display: inline;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
details .callout-content {
|
|
843
|
+
max-height: 0;
|
|
844
|
+
opacity: 0;
|
|
845
|
+
overflow: hidden;
|
|
846
|
+
transition:
|
|
847
|
+
max-height var(--transition),
|
|
848
|
+
opacity var(--transition);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
details[open] .callout-content {
|
|
852
|
+
max-height: 1000px;
|
|
853
|
+
opacity: 1;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
details .callout-fold {
|
|
857
|
+
margin: 0;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* @name Comments
|
|
862
|
+
* @group comments
|
|
863
|
+
* @since 0.11.0
|
|
864
|
+
*/
|
|
865
|
+
|
|
866
|
+
#comments {
|
|
867
|
+
* {
|
|
868
|
+
margin-block-end: 0;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
font-size: var(--size-sm);
|
|
872
|
+
|
|
873
|
+
.comment {
|
|
874
|
+
border: var(--border);
|
|
875
|
+
box-shadow: var(--shadow);
|
|
876
|
+
border-radius: var(--radius);
|
|
877
|
+
background: var(--color-surface);
|
|
878
|
+
padding: var(--space) var(--space-d2);
|
|
879
|
+
margin-block-end: var(--space);
|
|
880
|
+
|
|
881
|
+
.comment-header {
|
|
882
|
+
display: flex;
|
|
883
|
+
align-items: baseline;
|
|
884
|
+
gap: var(--space-d2);
|
|
885
|
+
|
|
886
|
+
.comment-author {
|
|
887
|
+
font-weight: var(--font-weight-bold);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.comment-date,
|
|
891
|
+
.comment-pending {
|
|
892
|
+
color: var(--color-subtle);
|
|
893
|
+
font-size: var(--size-xs);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
.comment-pending {
|
|
897
|
+
font-style: italic;
|
|
898
|
+
color: var(--color-orange);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
.comment-content {
|
|
903
|
+
margin-inline: var(--space-d2);
|
|
904
|
+
margin-block-start: var(--space-d2);
|
|
905
|
+
border-left: var(--border);
|
|
906
|
+
padding: var(--space-d2);
|
|
907
|
+
color: var(--color-muted);
|
|
908
|
+
font-size: var(--size-sm);
|
|
909
|
+
line-height: var(--line-height-compact);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
:last-child {
|
|
914
|
+
margin-block-end: 0;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* @name Alert Action Links
|
|
920
|
+
* @group components-feedback
|
|
921
|
+
* @since 0.11.0
|
|
922
|
+
*
|
|
923
|
+
* Actions within alerts (links, buttons) should be visually distinct but not
|
|
924
|
+
* overwhelming. This provides subtle styling that inherits the alert's color.
|
|
925
|
+
*/
|
|
926
|
+
.alert-action {
|
|
927
|
+
display: inline-block;
|
|
928
|
+
margin-inline-start: var(--space-d2);
|
|
929
|
+
color: var(--alert-border-color);
|
|
930
|
+
text-decoration: underline;
|
|
931
|
+
font-weight: var(--font-weight-bold);
|
|
932
|
+
|
|
933
|
+
&:hover {
|
|
934
|
+
text-decoration-thickness: 0.15em;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
a.skip-link {
|
|
939
|
+
/* Positioning - absolute to top-left corner */
|
|
940
|
+
position: absolute;
|
|
941
|
+
top: var(--space-d3);
|
|
942
|
+
left: var(--space-d3);
|
|
943
|
+
z-index: var(--z-modal);
|
|
944
|
+
/* Above everything else */
|
|
945
|
+
|
|
946
|
+
/* Styling - high contrast, unmissable */
|
|
947
|
+
background: var(--color-accent);
|
|
948
|
+
color: var(--color-background);
|
|
949
|
+
padding: var(--space-d3);
|
|
950
|
+
border-radius: var(--radius);
|
|
951
|
+
font-weight: var(--font-weight-bold);
|
|
952
|
+
font-size: var(--size-sm);
|
|
953
|
+
text-decoration: none;
|
|
954
|
+
box-shadow: var(--shadow-xl);
|
|
955
|
+
|
|
956
|
+
/* Animation */
|
|
957
|
+
|
|
958
|
+
/* Hidden by default (accessible hiding) */
|
|
959
|
+
transform: translateY(-120%);
|
|
960
|
+
opacity: 0;
|
|
961
|
+
|
|
962
|
+
/* Visible on focus (Tab key) */
|
|
963
|
+
&:focus {
|
|
964
|
+
transform: translateY(0);
|
|
965
|
+
opacity: 1;
|
|
966
|
+
outline: 3px solid var(--color-background);
|
|
967
|
+
outline-offset: 2px;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/* Hover state (if user moves mouse while focused) */
|
|
971
|
+
&:hover {
|
|
972
|
+
background: color-mix(
|
|
973
|
+
in srgb,
|
|
974
|
+
var(--color-accent) 90%,
|
|
975
|
+
var(--color-background)
|
|
976
|
+
);
|
|
977
|
+
color: var(--color-background);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/* Active state (on click) */
|
|
981
|
+
&:active {
|
|
982
|
+
transform: translateY(0) scale(0.98);
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
.skip-links {
|
|
987
|
+
position: absolute;
|
|
988
|
+
top: 0;
|
|
989
|
+
left: 0;
|
|
990
|
+
z-index: var(--z-modal);
|
|
991
|
+
display: flex;
|
|
992
|
+
flex-direction: column;
|
|
993
|
+
gap: var(--space);
|
|
994
|
+
padding: var(--space-d3);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/* =========================== */
|
|
998
|
+
/* MENUS / POPOVERS */
|
|
999
|
+
/* =========================== */
|
|
1000
|
+
|
|
1001
|
+
@keyframes std-menu-in {
|
|
1002
|
+
from {
|
|
1003
|
+
opacity: 0;
|
|
1004
|
+
transform: scale(0.95) translateY(-5px);
|
|
1005
|
+
}
|
|
1006
|
+
to {
|
|
1007
|
+
opacity: 1;
|
|
1008
|
+
transform: scale(1) translateY(0);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
.std-menu-content {
|
|
1013
|
+
padding: var(--space-d4);
|
|
1014
|
+
background: var(--color-surface-high);
|
|
1015
|
+
border: none;
|
|
1016
|
+
border-radius: var(--radius-sm);
|
|
1017
|
+
box-shadow: var(--shadow-raised), var(--shadow-glow);
|
|
1018
|
+
display: flex;
|
|
1019
|
+
flex-direction: column;
|
|
1020
|
+
z-index: var(--z-dropdown);
|
|
1021
|
+
animation: std-menu-in var(--transition-fast);
|
|
1022
|
+
transform-origin: top left;
|
|
1023
|
+
|
|
1024
|
+
* {
|
|
1025
|
+
text-shadow: none !important;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.std-menu-label {
|
|
1030
|
+
padding: var(--space-d4);
|
|
1031
|
+
font-family: var(--font-interface);
|
|
1032
|
+
font-size: var(--size-2xs);
|
|
1033
|
+
font-weight: var(--font-weight);
|
|
1034
|
+
color: var(--color-subtle);
|
|
1035
|
+
user-select: none;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
.std-menu-separator {
|
|
1039
|
+
all: unset;
|
|
1040
|
+
display: block;
|
|
1041
|
+
height: var(--stroke-width);
|
|
1042
|
+
background: var(--color-border) !important;
|
|
1043
|
+
margin: var(--space-d4) 0;
|
|
1044
|
+
opacity: 1;
|
|
1045
|
+
|
|
1046
|
+
&::after {
|
|
1047
|
+
display: none;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
.std-menu-item {
|
|
1052
|
+
all: unset;
|
|
1053
|
+
display: flex;
|
|
1054
|
+
width: 100%;
|
|
1055
|
+
box-sizing: border-box;
|
|
1056
|
+
align-items: center;
|
|
1057
|
+
gap: var(--space-d4);
|
|
1058
|
+
padding: 0 var(--space-d4);
|
|
1059
|
+
border-radius: var(--radius-sm);
|
|
1060
|
+
font-size: var(--size-sm);
|
|
1061
|
+
font-family: var(--font-interface);
|
|
1062
|
+
color: var(--color-foreground);
|
|
1063
|
+
cursor: pointer;
|
|
1064
|
+
user-select: none;
|
|
1065
|
+
transition: all var(--transition-fast);
|
|
1066
|
+
min-height: var(--space);
|
|
1067
|
+
text-decoration: none;
|
|
1068
|
+
|
|
1069
|
+
&:hover:not(.disabled) {
|
|
1070
|
+
background: var(--color-surface-highest);
|
|
1071
|
+
box-shadow: var(--shadow-raised);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
&:active:not(.disabled) {
|
|
1075
|
+
background: var(--color-surface-low);
|
|
1076
|
+
box-shadow: var(--shadow-inset);
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
&.disabled {
|
|
1080
|
+
opacity: 0.5;
|
|
1081
|
+
cursor: not-allowed;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
&.destructive {
|
|
1085
|
+
color: var(--color-red);
|
|
1086
|
+
|
|
1087
|
+
&:hover {
|
|
1088
|
+
background: var(--color-red);
|
|
1089
|
+
color: var(--color-on-accent);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
.item-icon {
|
|
1094
|
+
display: flex;
|
|
1095
|
+
align-items: center;
|
|
1096
|
+
justify-content: center;
|
|
1097
|
+
color: var(--color-muted);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
&:hover .item-icon {
|
|
1101
|
+
color: var(--color-foreground);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
.item-label {
|
|
1105
|
+
flex: 1;
|
|
1106
|
+
white-space: nowrap;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
.item-shortcut {
|
|
1110
|
+
font-size: var(--size-3xs);
|
|
1111
|
+
color: var(--color-muted);
|
|
1112
|
+
letter-spacing: 0.1em;
|
|
1113
|
+
padding-left: var(--space);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
.scroll {
|
|
1118
|
+
/* Container styling */
|
|
1119
|
+
position: relative;
|
|
1120
|
+
width: 100%;
|
|
1121
|
+
overflow-x: auto;
|
|
1122
|
+
overflow-y: auto;
|
|
1123
|
+
|
|
1124
|
+
/* Smooth scrolling with momentum */
|
|
1125
|
+
|
|
1126
|
+
&::before,
|
|
1127
|
+
&::after {
|
|
1128
|
+
content: "";
|
|
1129
|
+
position: absolute;
|
|
1130
|
+
top: 0;
|
|
1131
|
+
bottom: 0;
|
|
1132
|
+
z-index: 2;
|
|
1133
|
+
pointer-events: none;
|
|
1134
|
+
width: var(--space);
|
|
1135
|
+
opacity: 0;
|
|
1136
|
+
box-shadow: var(--shadow-ring), var(--shadow-glow);
|
|
1137
|
+
transition: box-shadow var(--transition);
|
|
1138
|
+
|
|
1139
|
+
/* Not sure if I like the whole idea but dont want to lose the code so I've hidden it for now */
|
|
1140
|
+
display: none;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
&::before {
|
|
1144
|
+
left: calc((var(--space) * -1) + 1px);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
/* Define the Right Shadow (initially visible) */
|
|
1148
|
+
&::after {
|
|
1149
|
+
right: calc((var(--space) * -1) + 1px);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/* When this class is added, the left shadow fades in. */
|
|
1153
|
+
&.show-left-shadow::before {
|
|
1154
|
+
opacity: 1;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
/* When this class is added, the right shadow fades in. */
|
|
1158
|
+
&.show-right-shadow::after {
|
|
1159
|
+
opacity: 1;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
& > * {
|
|
1163
|
+
margin-block-end: 0;
|
|
1164
|
+
/* Remove table's own margin */
|
|
1165
|
+
min-width: 100%;
|
|
1166
|
+
/* Ensure table fills wrapper */
|
|
1167
|
+
width: max-content;
|
|
1168
|
+
/* Allow table to grow beyond wrapper */
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.field {
|
|
1173
|
+
/* Field container */
|
|
1174
|
+
display: flex;
|
|
1175
|
+
flex-direction: column;
|
|
1176
|
+
gap: var(--space);
|
|
1177
|
+
|
|
1178
|
+
/* Label styling */
|
|
1179
|
+
label {
|
|
1180
|
+
font-weight: var(--font-weight-bold);
|
|
1181
|
+
font-size: var(--size-sm);
|
|
1182
|
+
color: var(--color-foreground);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
[data-tooltip] {
|
|
1187
|
+
position: relative;
|
|
1188
|
+
cursor: help;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/* The tooltip bubble */
|
|
1192
|
+
[data-tooltip]::after {
|
|
1193
|
+
content: attr(data-tooltip);
|
|
1194
|
+
position: absolute;
|
|
1195
|
+
bottom: 100%;
|
|
1196
|
+
left: 50%;
|
|
1197
|
+
transform: translateX(-50%) translateY(10px) scale(0.95);
|
|
1198
|
+
|
|
1199
|
+
background: var(--tooltip-background);
|
|
1200
|
+
color: var(--tooltip-text);
|
|
1201
|
+
padding: 6px 12px;
|
|
1202
|
+
border-radius: 4px;
|
|
1203
|
+
font-size: 0.75rem;
|
|
1204
|
+
font-weight: 500;
|
|
1205
|
+
white-space: normal;
|
|
1206
|
+
pointer-events: none;
|
|
1207
|
+
z-index: 1000;
|
|
1208
|
+
box-shadow: var(--shadow-lg), var(--shadow-glow);
|
|
1209
|
+
|
|
1210
|
+
/* Hidden state */
|
|
1211
|
+
opacity: 0;
|
|
1212
|
+
visibility: hidden;
|
|
1213
|
+
width: 200px;
|
|
1214
|
+
transition: opacity var(--transition);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
/* The arrow */
|
|
1218
|
+
[data-tooltip]::before {
|
|
1219
|
+
content: "";
|
|
1220
|
+
position: absolute;
|
|
1221
|
+
bottom: 100%;
|
|
1222
|
+
left: 50%;
|
|
1223
|
+
transform: translateX(-50%) translateY(10px);
|
|
1224
|
+
border: 5px solid transparent;
|
|
1225
|
+
border-top-color: var(--tooltip-background);
|
|
1226
|
+
margin-bottom: -10px;
|
|
1227
|
+
opacity: 0;
|
|
1228
|
+
visibility: hidden;
|
|
1229
|
+
pointer-events: none;
|
|
1230
|
+
z-index: 1000;
|
|
1231
|
+
transition: opacity var(--transition);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/* Hover state */
|
|
1235
|
+
[data-tooltip]:hover::after,
|
|
1236
|
+
[data-tooltip]:hover::before {
|
|
1237
|
+
opacity: 1;
|
|
1238
|
+
visibility: visible;
|
|
1239
|
+
transform: translateX(-50%) translateY(-8px) scale(1);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
/* Bottom position variant */
|
|
1243
|
+
[data-tooltip-pos="bottom"]::after {
|
|
1244
|
+
bottom: auto;
|
|
1245
|
+
top: 100%;
|
|
1246
|
+
transform: translateX(-50%) translateY(-10px) scale(0.95);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
[data-tooltip-pos="bottom"]::before {
|
|
1250
|
+
bottom: auto;
|
|
1251
|
+
top: 100%;
|
|
1252
|
+
border-top-color: transparent;
|
|
1253
|
+
border-bottom-color: var(--tooltip-background);
|
|
1254
|
+
margin-bottom: 0;
|
|
1255
|
+
margin-top: -10px;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
[data-tooltip-pos="bottom"]:hover::after,
|
|
1259
|
+
[data-tooltip-pos="bottom"]:hover::before {
|
|
1260
|
+
transform: translateX(-50%) translateY(8px) scale(1);
|
|
1261
|
+
}
|