@stnd/styles 0.5.0 → 0.5.2
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 +6 -0
- package/LICENSE +21 -0
- package/README.md +114 -21
- package/TOKENS.md +20 -2
- package/_standard-00-reset.scss +46 -5
- package/_standard-00-variables.scss +25 -4
- package/_standard-01-token.scss +55 -22
- package/_standard-02-color.scss +23 -3
- package/_standard-03-typography.scss +19 -14
- package/_standard-04-grid.scss +25 -28
- package/_standard-05-rhythm.scss +21 -0
- package/_standard-06-prose.scss +14 -8
- package/_standard-07-base.scss +29 -9
- package/_standard-08-media.scss +14 -6
- package/_standard-09-lists.scss +16 -5
- package/_standard-10-tables.scss +8 -1
- package/_standard-11-forms.scss +14 -10
- package/_standard-12-code.scss +2 -1
- package/_standard-13-components.scss +7 -16
- package/_standard-14-analog.scss +10 -3
- package/_standard-30-contrast.scss +11 -0
- package/_standard-31-print.scss +9 -1
- package/_standard-32-eink.scss +15 -3
- package/_standard-50-utilities.scss +31 -36
- package/_standard-99-debug.scss +15 -11
- package/obsidian.scss +4 -3
- package/package.json +5 -5
- package/dist/obsidian.css +0 -31
- package/dist/obsidian.css.map +0 -1
- package/dist/standard.css +0 -20
- package/dist/standard.css.map +0 -1
package/_standard-02-color.scss
CHANGED
|
@@ -327,6 +327,10 @@
|
|
|
327
327
|
--color-bold: var(--color-light-bold, var(--color-foreground));
|
|
328
328
|
--color-on-accent: var(--color-background);
|
|
329
329
|
|
|
330
|
+
/* Fixed 2026-07-14 — purple/pink/brown now correctly switch to dark
|
|
331
|
+
variants in all three dark-mode contexts, plus added missing
|
|
332
|
+
non-OKLCH fallbacks. */
|
|
333
|
+
|
|
330
334
|
/* ===================================================================
|
|
331
335
|
STAGE 4: COMPUTED SEMANTIC COLORS
|
|
332
336
|
Derived from the scheme-aware --color-foreground/--color-background.
|
|
@@ -375,8 +379,9 @@
|
|
|
375
379
|
inset 0 1px 0 0 var(--color-highlight), 0 0 0 1px var(--color-border),
|
|
376
380
|
var(--shadow-ambient);
|
|
377
381
|
|
|
378
|
-
/* Composed presets
|
|
379
|
-
|
|
382
|
+
/* Composed presets. Fixed 2026-07-14 — was accidentally doubled, now
|
|
383
|
+
matches the --shadow-lg/-xl progressive pattern (one layer). */
|
|
384
|
+
--shadow: var(--shadow-ambient);
|
|
380
385
|
--shadow-lg: var(--shadow-ambient), var(--shadow-lift);
|
|
381
386
|
--shadow-xl: var(--shadow-ambient), var(--shadow-lift), var(--shadow-glow);
|
|
382
387
|
|
|
@@ -407,7 +412,6 @@
|
|
|
407
412
|
/* ===================================================================
|
|
408
413
|
STAGE 6: DESIGN TOKENS (Border Shorthands)
|
|
409
414
|
=================================================================== */
|
|
410
|
-
--border: 0 solid transparent;
|
|
411
415
|
--border-transparent: var(--stroke-width) solid transparent;
|
|
412
416
|
--border-accent: var(--stroke-width) solid
|
|
413
417
|
oklch(from var(--color-accent) l c h / 0.07);
|
|
@@ -443,6 +447,9 @@
|
|
|
443
447
|
--color-cyan: var(--color-dark-cyan);
|
|
444
448
|
--color-blue: var(--color-dark-blue);
|
|
445
449
|
--color-magenta: var(--color-dark-magenta);
|
|
450
|
+
--color-purple: var(--color-dark-purple);
|
|
451
|
+
--color-pink: var(--color-dark-pink);
|
|
452
|
+
--color-brown: var(--color-dark-brown);
|
|
446
453
|
|
|
447
454
|
--color-link: var(--color-dark-link);
|
|
448
455
|
--color-italic: var(--color-dark-italic, var(--color-foreground));
|
|
@@ -570,6 +577,9 @@
|
|
|
570
577
|
--color-cyan: var(--color-dark-cyan);
|
|
571
578
|
--color-blue: var(--color-dark-blue);
|
|
572
579
|
--color-magenta: var(--color-dark-magenta);
|
|
580
|
+
--color-purple: var(--color-dark-purple);
|
|
581
|
+
--color-pink: var(--color-dark-pink);
|
|
582
|
+
--color-brown: var(--color-dark-brown);
|
|
573
583
|
--color-link: var(--color-dark-link);
|
|
574
584
|
--color-italic: var(--color-dark-italic, var(--color-foreground));
|
|
575
585
|
--color-bold: var(--color-dark-bold, var(--color-foreground));
|
|
@@ -588,6 +598,9 @@
|
|
|
588
598
|
--color-cyan: var(--color-dark-cyan);
|
|
589
599
|
--color-blue: var(--color-dark-blue);
|
|
590
600
|
--color-magenta: var(--color-dark-magenta);
|
|
601
|
+
--color-purple: var(--color-dark-purple);
|
|
602
|
+
--color-pink: var(--color-dark-pink);
|
|
603
|
+
--color-brown: var(--color-dark-brown);
|
|
591
604
|
--color-link: var(--color-dark-link);
|
|
592
605
|
--color-italic: var(--color-dark-italic, var(--color-foreground));
|
|
593
606
|
--color-bold: var(--color-dark-bold, var(--color-foreground));
|
|
@@ -614,6 +627,9 @@
|
|
|
614
627
|
STAGE 8: FALLBACKS — Graceful Degradation
|
|
615
628
|
Browsers without OKLCH support (Safari <16.4, Chrome <111, FF <113)
|
|
616
629
|
get concrete color values so the UI remains usable.
|
|
630
|
+
|
|
631
|
+
Fixed 2026-07-14 — added missing light/dark purple & pink fallbacks
|
|
632
|
+
below.
|
|
617
633
|
===================================================================== */
|
|
618
634
|
@supports not (color: oklch(50% 0.2 180)) {
|
|
619
635
|
#{$stnd-theme-scope} {
|
|
@@ -629,6 +645,8 @@
|
|
|
629
645
|
--color-light-cyan: #2a8a8a;
|
|
630
646
|
--color-light-blue: #3a60b0;
|
|
631
647
|
--color-light-magenta: #9040a0;
|
|
648
|
+
--color-light-purple: #8050b0;
|
|
649
|
+
--color-light-pink: #c05090;
|
|
632
650
|
--color-light-accent: #2a8a8a;
|
|
633
651
|
|
|
634
652
|
/* Dark palette fallbacks */
|
|
@@ -639,6 +657,8 @@
|
|
|
639
657
|
--color-dark-cyan: #50b0b0;
|
|
640
658
|
--color-dark-blue: #6080d0;
|
|
641
659
|
--color-dark-magenta: #b060c0;
|
|
660
|
+
--color-dark-purple: #a070d0;
|
|
661
|
+
--color-dark-pink: #d070a0;
|
|
642
662
|
--color-dark-accent: #50b0b0;
|
|
643
663
|
|
|
644
664
|
/* Computed fallbacks */
|
|
@@ -105,6 +105,11 @@ h6 {
|
|
|
105
105
|
max-width: 100%;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
/* Fixed 2026-07-14 — the mixin's --target-lh now reads
|
|
109
|
+
--font-header-line-height as an override. The line-height set below
|
|
110
|
+
for h1/h2/h3 is still always overridden further down by
|
|
111
|
+
@include grid-line-height(...) (~line 393), which is what actually
|
|
112
|
+
controls heading line-height now. */
|
|
108
113
|
h1 {
|
|
109
114
|
font-weight: var(--font-weight-h1);
|
|
110
115
|
font-size: clamp(var(--size-xl), 5.5vw, var(--size-2xl));
|
|
@@ -314,26 +319,27 @@ sup {
|
|
|
314
319
|
vertical-align: super;
|
|
315
320
|
}
|
|
316
321
|
|
|
322
|
+
/* Duplicate of the `em` rule at line 82 (same --color-italic), this copy
|
|
323
|
+
additionally sets font-style — harmless overlap, not a conflict. */
|
|
317
324
|
em {
|
|
318
325
|
color: var(--color-italic);
|
|
319
326
|
font-style: italic;
|
|
320
327
|
}
|
|
321
328
|
|
|
322
|
-
.font-interface {
|
|
323
|
-
font-family: var(--font-interface), system-ui, sans-serif;
|
|
324
|
-
font-variation-settings: var(--font-interface-variation);
|
|
325
|
-
font-feature-settings: var(--font-interface-feature);
|
|
326
|
-
font-size: 12px;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
329
|
/**
|
|
330
330
|
* @component Design Tokens
|
|
331
331
|
* @category Foundation
|
|
332
332
|
* @description Primitive design tokens forming the foundation of the design system.
|
|
333
333
|
* Includes "Self-Aware" fluid typography that scales based on the Optical Ratio.
|
|
334
|
+
*
|
|
335
|
+
* This block redeclares --font-size and --line-height, silently superseding
|
|
336
|
+
* the flat --font-size: 1rem set in _standard-01-token.scss (same selector,
|
|
337
|
+
* this file loads later in standard.scss's @use order, so this wins) —
|
|
338
|
+
* deliberate layering (naive default → fluid enhancement), not a conflict,
|
|
339
|
+
* but non-obvious without reading both files.
|
|
334
340
|
*/
|
|
335
341
|
|
|
336
|
-
#{$stnd-scope} {
|
|
342
|
+
#{$stnd-theme-scope} {
|
|
337
343
|
/* ===== 2. THE META-COGNITION (Fluid Slopes) =====
|
|
338
344
|
Instead of magic numbers, we use the Ratio to determine "Physics".
|
|
339
345
|
|
|
@@ -345,7 +351,7 @@ em {
|
|
|
345
351
|
|
|
346
352
|
/* Growth Factor: How aggressive is the resizing?
|
|
347
353
|
We multiply the slope by 1vw to create a viewport-relative unit. */
|
|
348
|
-
--fluid-growth: calc(var(--physics-slope) * 0.
|
|
354
|
+
--fluid-growth: calc(var(--physics-slope) * 0.5vw);
|
|
349
355
|
|
|
350
356
|
/* Tension Factor: How much do we tighten leading as we grow?
|
|
351
357
|
Higher ratios need more tension to keep large text readable. */
|
|
@@ -355,7 +361,7 @@ em {
|
|
|
355
361
|
Base size starts at 1rem and grows according to the Physics Slope.
|
|
356
362
|
*/
|
|
357
363
|
--base-size: var(--font-text-size, 1rem);
|
|
358
|
-
|
|
364
|
+
|
|
359
365
|
--font-size: clamp(
|
|
360
366
|
var(--base-size),
|
|
361
367
|
calc(var(--base-size) + var(--fluid-growth)),
|
|
@@ -377,11 +383,10 @@ em {
|
|
|
377
383
|
);
|
|
378
384
|
}
|
|
379
385
|
|
|
380
|
-
|
|
381
|
-
|
|
382
386
|
@mixin grid-line-height($tightness: 1.1) {
|
|
383
|
-
/* The "Target" is simply the font-size * tightness
|
|
384
|
-
|
|
387
|
+
/* The "Target" is simply the font-size * tightness, unless a note
|
|
388
|
+
overrides it via --font-header-line-height in frontmatter */
|
|
389
|
+
--target-lh: calc(1em * var(--font-header-line-height, #{$tightness}));
|
|
385
390
|
|
|
386
391
|
/* The Snap: Force it to be a multiple of --baseline */
|
|
387
392
|
line-height: round(up, var(--target-lh), var(--baseline)) !important;
|
package/_standard-04-grid.scss
CHANGED
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
* All gaps align to the vertical rhythm system.
|
|
10
10
|
*
|
|
11
11
|
* @prop {class} .grid 12-column grid container
|
|
12
|
-
* @prop {class} .
|
|
13
|
-
* @prop {class} .col
|
|
14
|
-
* @prop {class} .col
|
|
15
|
-
* @prop {class} .col-lg-* Responsive columns at 1024px+
|
|
12
|
+
* @prop {class} .col-1 through .col-12 Column span modifiers (direct children of .grid)
|
|
13
|
+
* @prop {class} .sm\:col-* Responsive columns at max-width 768px (mobile)
|
|
14
|
+
* @prop {class} .lg\:col-* Responsive columns at min-width 1024px (desktop)
|
|
16
15
|
* @prop {class} .start-{n} Start column position (1-12)
|
|
17
|
-
* @prop {class} .gap
|
|
18
|
-
* @prop {class} .
|
|
16
|
+
* @prop {class} .grid.no-gap Removes row-gap
|
|
17
|
+
* @prop {class} .grid.compact Compact gap (--trim)
|
|
18
|
+
* @prop {class} .grid.relaxed Wide gap (--space)
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
21
|
* // Basic 12-column grid with equal width columns
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
*
|
|
29
29
|
* // Responsive grid layout
|
|
30
30
|
* <div class="grid">
|
|
31
|
-
* <div class="col-12 col-
|
|
32
|
-
* <div class="col-12 col-
|
|
31
|
+
* <div class="col-12 sm:col-6 lg:col-3">Card</div>
|
|
32
|
+
* <div class="col-12 sm:col-6 lg:col-3">Card</div>
|
|
33
33
|
* </div>
|
|
34
34
|
*
|
|
35
35
|
* // Main content + sidebar layout
|
|
@@ -47,10 +47,15 @@
|
|
|
47
47
|
Relies on logical properties and Harmony tokens: --base, calc(var(--space) / 4), --base-2, borders, etc.
|
|
48
48
|
*/
|
|
49
49
|
|
|
50
|
-
/*
|
|
51
|
-
.
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
/* Fixed 2026-07-14 — was attribute selectors (order-dependent), now an
|
|
51
|
+
explicit selector list built once via $grid-selectors (order-independent). */
|
|
52
|
+
$grid-selectors: ".grid, .grid-row";
|
|
53
|
+
@for $i from 1 through 12 {
|
|
54
|
+
$grid-selectors: $grid-selectors + ", .grid-#{$i}";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Grid container. */
|
|
58
|
+
#{$grid-selectors} {
|
|
54
59
|
display: grid;
|
|
55
60
|
grid-auto-columns: 1fr;
|
|
56
61
|
grid-auto-flow: column;
|
|
@@ -58,8 +63,7 @@
|
|
|
58
63
|
row-gap: var(--gap);
|
|
59
64
|
}
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
[class^="grid-"] {
|
|
66
|
+
#{$grid-selectors} {
|
|
63
67
|
> * {
|
|
64
68
|
margin: 0;
|
|
65
69
|
}
|
|
@@ -73,25 +77,26 @@
|
|
|
73
77
|
/* TYPOGRAPHIC NUANCES */
|
|
74
78
|
/* =========================== */
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
#{$grid-selectors} > * {
|
|
77
81
|
min-width: 0;
|
|
78
82
|
/* ← Force items to shrink below content size */
|
|
79
83
|
margin-block: 0;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
@media (max-width: #{$mobile}) {
|
|
83
|
-
|
|
87
|
+
#{$grid-selectors} > * {
|
|
84
88
|
min-width: 0;
|
|
85
89
|
}
|
|
86
90
|
}
|
|
87
91
|
|
|
88
|
-
|
|
92
|
+
#{$grid-selectors} {
|
|
89
93
|
.card {
|
|
90
94
|
margin: 0;
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
/* Gap variants aligned to rhythm
|
|
98
|
+
/* Gap variants aligned to rhythm — this is the LIVE definition (sets --gap,
|
|
99
|
+
the property actually consumed by column-gap/row-gap above). */
|
|
95
100
|
:is(.grid, [class^="grid-"]).compact {
|
|
96
101
|
--gap: var(--trim);
|
|
97
102
|
}
|
|
@@ -267,19 +272,11 @@ hr.col-row {
|
|
|
267
272
|
z-index: 1;
|
|
268
273
|
}
|
|
269
274
|
|
|
270
|
-
/* Row gap utilities for grid system */
|
|
275
|
+
/* Row gap utilities for grid system. */
|
|
271
276
|
.grid.no-gap {
|
|
272
277
|
row-gap: 0;
|
|
273
278
|
}
|
|
274
279
|
|
|
275
|
-
.grid.compact {
|
|
276
|
-
--grid-gap: var(--leading);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
.grid.relaxed {
|
|
280
|
-
--grid-gap: var(--space-2);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
280
|
/* Common layout containers inherit rhythm to cascade deeper */
|
|
284
281
|
.box,
|
|
285
282
|
.grid > .col-1,
|
|
@@ -309,6 +306,6 @@ hr.col-row {
|
|
|
309
306
|
}
|
|
310
307
|
}
|
|
311
308
|
|
|
312
|
-
|
|
309
|
+
#{$grid-selectors} .container-hero {
|
|
313
310
|
margin-inline: 0;
|
|
314
311
|
}
|
package/_standard-05-rhythm.scss
CHANGED
|
@@ -9,6 +9,24 @@
|
|
|
9
9
|
Think of it as "overflow: hidden" but without clipping content. */
|
|
10
10
|
display: flow-root;
|
|
11
11
|
|
|
12
|
+
/* Every selector below is wrapped in :where(), including .rhythm itself
|
|
13
|
+
— that's zero specificity everywhere, by design (easy for any other
|
|
14
|
+
rule to override). Which means SOURCE ORDER is the only tiebreaker
|
|
15
|
+
when more than one of these rules matches the same element (e.g. a
|
|
16
|
+
paragraph immediately before an h1 matches both the base 1x rule
|
|
17
|
+
below AND the heading exception further down — the exception wins
|
|
18
|
+
purely because it's declared later). Do not reorder this block
|
|
19
|
+
without checking every rule still resolves the way you expect. */
|
|
20
|
+
|
|
21
|
+
/* AUDIT FLAG (2026-07-14): this base rule has no `>` — it applies at
|
|
22
|
+
ANY nesting depth inside .rhythm, not just direct children. Every
|
|
23
|
+
other rule in this block (the double-tag 2x rule right below, and
|
|
24
|
+
all EXCEPTIONS) is `>`-scoped to direct children only. So a heading
|
|
25
|
+
nested two levels deep (inside a .callout, say) gets the base 1x
|
|
26
|
+
spacing but never the heading-specific 2x/3x exceptions a top-level
|
|
27
|
+
heading would get. Possibly intentional (exceptions are for
|
|
28
|
+
top-level document flow only) — flagging since the asymmetry itself
|
|
29
|
+
isn't declared anywhere, just falls out of one missing `>`. */
|
|
12
30
|
:where(:is(#{$rhythm-tags})) + :where(:is(#{$rhythm-tags})) {
|
|
13
31
|
margin-block-start: calc(var(--gap) * 1);
|
|
14
32
|
}
|
|
@@ -46,6 +64,9 @@
|
|
|
46
64
|
|
|
47
65
|
//*/
|
|
48
66
|
|
|
67
|
+
/* Flex children use `gap` for spacing, not margin (see cheat sheet:
|
|
68
|
+
"gap on the parent, not margin on children") — zero out any rhythm
|
|
69
|
+
margin that would otherwise stack with the flex gap. */
|
|
49
70
|
.flex > * {
|
|
50
71
|
margin-block-start: 0;
|
|
51
72
|
}
|
package/_standard-06-prose.scss
CHANGED
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
transition: grid-template-columns var(--transition);
|
|
76
76
|
|
|
77
77
|
position: relative;
|
|
78
|
-
max-width: var(--
|
|
78
|
+
max-width: var(--body-max-width);
|
|
79
79
|
/*z-index: var(--z-base);*/
|
|
80
80
|
/* Default content positioning */
|
|
81
81
|
|
|
@@ -88,6 +88,13 @@
|
|
|
88
88
|
padding-inline var(--transition);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/* Astro islands render as <astro-island> with display:contents, so their
|
|
92
|
+
children — not the island — are the grid items and need placement too. */
|
|
93
|
+
> astro-island > * {
|
|
94
|
+
grid-column: content;
|
|
95
|
+
min-width: 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
91
98
|
> .small,
|
|
92
99
|
> .container-small,
|
|
93
100
|
> .callout,
|
|
@@ -196,9 +203,6 @@
|
|
|
196
203
|
margin-inline: 0 !important;
|
|
197
204
|
}
|
|
198
205
|
|
|
199
|
-
/* Note: Page's main title h1:first-child retains spacing via direct child selector */
|
|
200
|
-
/* The > h1:first-child selector in h1 rule ensures it overrides rhythm's > * margin-reset */
|
|
201
|
-
|
|
202
206
|
/* Basic media styling */
|
|
203
207
|
img,
|
|
204
208
|
audio,
|
|
@@ -260,17 +264,19 @@
|
|
|
260
264
|
overflow-wrap: break-word;
|
|
261
265
|
}
|
|
262
266
|
|
|
267
|
+
/* Fixed 2026-07-14 — swapped undefined tokens for their real equivalents
|
|
268
|
+
(--color-muted, --color-accent, --color-surface-high). */
|
|
263
269
|
.mycelial-graft {
|
|
264
270
|
text-decoration: none;
|
|
265
|
-
border-bottom: 1px dotted var(--color-
|
|
271
|
+
border-bottom: 1px dotted var(--color-muted);
|
|
266
272
|
color: inherit;
|
|
267
273
|
cursor: help;
|
|
268
274
|
transition: all 0.2s ease;
|
|
269
275
|
|
|
270
276
|
&:hover {
|
|
271
|
-
color: var(--color-
|
|
272
|
-
border-bottom: 1px solid var(--color-
|
|
273
|
-
background-color: var(--color-surface-
|
|
277
|
+
color: var(--color-accent);
|
|
278
|
+
border-bottom: 1px solid var(--color-accent);
|
|
279
|
+
background-color: var(--color-surface-high);
|
|
274
280
|
}
|
|
275
281
|
}
|
|
276
282
|
}
|
package/_standard-07-base.scss
CHANGED
|
@@ -64,7 +64,7 @@ body {
|
|
|
64
64
|
padding: var(--gap-body);
|
|
65
65
|
padding-top: var(--gap-header);
|
|
66
66
|
padding-bottom: var(--gap-footer);
|
|
67
|
-
max-width: var(--body-max-width
|
|
67
|
+
max-width: var(--body-max-width);
|
|
68
68
|
margin-inline: auto;
|
|
69
69
|
|
|
70
70
|
transition:
|
|
@@ -75,8 +75,8 @@ body {
|
|
|
75
75
|
margin var(--transition);
|
|
76
76
|
|
|
77
77
|
[id] {
|
|
78
|
+
/* Keeps anchor-linked headings from landing under the sticky header. */
|
|
78
79
|
scroll-margin-top: calc(var(--space-2) + var(--gap-header));
|
|
79
|
-
/* Adjust value as needed background: var(--color-surface-highest); background: var(--color-surface-highest); background: var(--color-surface-highest); background: var(--color-surface-highest); */
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -141,6 +141,10 @@ mark {
|
|
|
141
141
|
|
|
142
142
|
section.container-hero {
|
|
143
143
|
padding-block: var(--space-2);
|
|
144
|
+
/* --border currently resolves to `none` — see the AUDIT FLAG in
|
|
145
|
+
_standard-02-color.scss (duplicate --border declaration, "0 solid
|
|
146
|
+
transparent" then "none" wins). This section's top/bottom border is
|
|
147
|
+
invisible today as a result — real-world impact of that flag. */
|
|
144
148
|
border-top: var(--border);
|
|
145
149
|
border-bottom: var(--border);
|
|
146
150
|
box-shadow: var(--shadow);
|
|
@@ -166,15 +170,28 @@ dt {
|
|
|
166
170
|
/* =========================== */
|
|
167
171
|
|
|
168
172
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
173
|
+
* AUDIT NOTE (2026-07-14): this docblock previously described a
|
|
174
|
+
* .negate-body-padding / .negate-body-padding-full / .negate-body-padding-bottom
|
|
175
|
+
* API — those class names don't exist anywhere in this file or the
|
|
176
|
+
* codebase (grepped), never did as far as git history in this session
|
|
177
|
+
* shows. The real, implemented class is .no-body-margin, and it's far
|
|
178
|
+
* narrower than "footers, headers, or other elements" implied: it only
|
|
179
|
+
* matches <footer>/<header> that are DIRECT children of <body> AND the
|
|
180
|
+
* first/last element of that type (body > footer.no-body-margin:last-of-type
|
|
181
|
+
* / body > header.no-body-margin:first-of-type). Neither the old
|
|
182
|
+
* (fictional) nor the real class name is used anywhere in apps/ today —
|
|
183
|
+
* corrected the docs to match reality rather than delete the utility.
|
|
171
184
|
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
185
|
+
* Utilities to negate body padding for a direct-child header/footer that
|
|
186
|
+
* should extend to the viewport edges.
|
|
187
|
+
*
|
|
188
|
+
* .no-body-margin — on a <footer> or <header> that is a direct child of
|
|
189
|
+
* <body> and the last/first element of its type, respectively. Negates
|
|
190
|
+
* horizontal body padding (both variants); the footer variant also
|
|
191
|
+
* negates the extra 1.5× bottom padding, the header variant the top.
|
|
175
192
|
*
|
|
176
193
|
* Usage:
|
|
177
|
-
* <footer class="
|
|
194
|
+
* <footer class="no-body-margin">
|
|
178
195
|
* Full-width footer content
|
|
179
196
|
* </footer>
|
|
180
197
|
*/
|
|
@@ -207,10 +224,13 @@ body > footer.no-body-margin:last-of-type {
|
|
|
207
224
|
}
|
|
208
225
|
}
|
|
209
226
|
|
|
227
|
+
/* Fixed 2026-07-14 — was margin-block-end (wrong property, copy-paste
|
|
228
|
+
typo), now correctly overrides margin-block-start to match the footer's
|
|
229
|
+
symmetric pattern. */
|
|
210
230
|
body > header.no-body-margin:first-of-type {
|
|
211
231
|
margin-block-start: calc(var(--gap-body) * -1);
|
|
212
232
|
|
|
213
233
|
@media (max-width: #{$small}) {
|
|
214
|
-
margin-block-
|
|
234
|
+
margin-block-start: calc(var(--gap-body-mobile) * -1);
|
|
215
235
|
}
|
|
216
236
|
}
|
package/_standard-08-media.scss
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
/* MEDIA */
|
|
5
5
|
/* =========================== */
|
|
6
6
|
|
|
7
|
+
/* --border currently resolves to `none` everywhere it's used in this file
|
|
8
|
+
(3 places) — see the AUDIT FLAG in _standard-02-color.scss (duplicate
|
|
9
|
+
--border declaration; the "none" copy wins). Media elements here get no
|
|
10
|
+
visible border as a result. */
|
|
7
11
|
img,
|
|
8
12
|
video,
|
|
9
13
|
audio,
|
|
@@ -23,7 +27,11 @@ iframe,
|
|
|
23
27
|
/* =========================== */
|
|
24
28
|
.video-container:has(video) {
|
|
25
29
|
position: relative;
|
|
26
|
-
/*
|
|
30
|
+
/* Unlike the iframe variant in _standard-06-prose.scss, this one holds a
|
|
31
|
+
native <video> element, which has real intrinsic dimensions — the
|
|
32
|
+
legacy padding-bottom:56.25% aspect-ratio hack (disabled below) isn't
|
|
33
|
+
needed the way it is for iframes. */
|
|
34
|
+
/* padding-bottom: 56.25% — 16:9 aspect ratio, disabled, see above */
|
|
27
35
|
border: none;
|
|
28
36
|
box-shadow: none;
|
|
29
37
|
overflow: hidden;
|
|
@@ -160,11 +168,10 @@ html:not(.js-image-zoom-enabled):has(img:active)::before {
|
|
|
160
168
|
/* lightbox experience with keyboard navigation, etc. */
|
|
161
169
|
/* ================================================================ */
|
|
162
170
|
|
|
163
|
-
/* Lock the page scroll when the JS overlay is active
|
|
171
|
+
/* Lock the page scroll when the JS overlay is active */
|
|
164
172
|
html.image-zoomed-active {
|
|
165
|
-
|
|
173
|
+
overflow: hidden;
|
|
166
174
|
}
|
|
167
|
-
*/
|
|
168
175
|
/* The overlay container created by the JS */
|
|
169
176
|
.image-zoom-overlay {
|
|
170
177
|
position: fixed;
|
|
@@ -175,7 +182,6 @@ html.image-zoomed-active {
|
|
|
175
182
|
display: flex;
|
|
176
183
|
align-items: center;
|
|
177
184
|
justify-content: center;
|
|
178
|
-
padding: var(--gap-body);
|
|
179
185
|
padding: var(--space-4);
|
|
180
186
|
margin: 0;
|
|
181
187
|
opacity: 0;
|
|
@@ -208,7 +214,9 @@ html.image-zoomed-active {
|
|
|
208
214
|
transform: scale(1);
|
|
209
215
|
}
|
|
210
216
|
|
|
211
|
-
|
|
217
|
+
/* Uses #{$small} — same breakpoint variable as everywhere else in the
|
|
218
|
+
framework. */
|
|
219
|
+
@media (min-width: #{$small}) {
|
|
212
220
|
/* Global zoomable image cursor */
|
|
213
221
|
img:not([data-no-zoom]) {
|
|
214
222
|
cursor: zoom-in !important;
|
package/_standard-09-lists.scss
CHANGED
|
@@ -62,9 +62,11 @@ ol > li::before {
|
|
|
62
62
|
font-size: var(--size-sm);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/* Fixed 2026-07-14 — was checking for .display-flex (not a real class
|
|
66
|
+
anywhere), now correctly checks .flex. */
|
|
65
67
|
/* Inline lists override - protects layouts using flex */
|
|
66
|
-
ul:where(.
|
|
67
|
-
ol:where(.
|
|
68
|
+
ul:where(.flex, [style*="display: flex"], [style*="display:flex"]) li,
|
|
69
|
+
ol:where(.flex, [style*="display: flex"], [style*="display:flex"]) li {
|
|
68
70
|
margin-block-end: 0;
|
|
69
71
|
}
|
|
70
72
|
|
|
@@ -81,22 +83,31 @@ ol:where(.display-flex, [style*="display: flex"], [style*="display:flex"]) li {
|
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
/* AUDIT FLAG (2026-07-14): .compact and .relaxed are bare, unnamespaced
|
|
87
|
+
class names also defined in _standard-50-utilities.scss (different
|
|
88
|
+
rules) and — for .compact/.relaxed specifically — in
|
|
89
|
+
_standard-04-grid.scss as .grid.compact/.grid.relaxed (qualified, so
|
|
90
|
+
that one doesn't collide). An element with class="compact" containing
|
|
91
|
+
<li> children gets BOTH this file's li+li spacing AND whatever
|
|
92
|
+
_standard-50-utilities.scss's .compact does, unconditionally — no way
|
|
93
|
+
to opt into one without the other. Flagging the collision rather than
|
|
94
|
+
renaming; not obvious which file should own the name. (The dead
|
|
95
|
+
--base-gap sub-issue previously flagged here has been cleaned up: the
|
|
96
|
+
declarations were removed from this file and from
|
|
97
|
+
_standard-50-utilities.scss.) */
|
|
84
98
|
.compact {
|
|
85
|
-
--base-gap: var(--space-d2);
|
|
86
99
|
li + li {
|
|
87
100
|
margin-block-start: var(--space-d2);
|
|
88
101
|
}
|
|
89
102
|
}
|
|
90
103
|
|
|
91
104
|
.tight {
|
|
92
|
-
--base-gap: var(--space-d3);
|
|
93
105
|
li {
|
|
94
106
|
margin-block-end: var(--space-d3);
|
|
95
107
|
}
|
|
96
108
|
}
|
|
97
109
|
|
|
98
110
|
.relaxed {
|
|
99
|
-
--base-gap: var(--space-2);
|
|
100
111
|
li {
|
|
101
112
|
margin-block-end: var(--space-2);
|
|
102
113
|
}
|
package/_standard-10-tables.scss
CHANGED
|
@@ -9,6 +9,9 @@ table {
|
|
|
9
9
|
width: 100%;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/* padding/margin on <tr> have no effect — table rows don't support box
|
|
13
|
+
model properties in the CSS table layout spec, browsers ignore these.
|
|
14
|
+
Harmless no-op, not fixing since it's inert either way. */
|
|
12
15
|
tr {
|
|
13
16
|
padding: 0;
|
|
14
17
|
margin: 0;
|
|
@@ -17,11 +20,15 @@ tr {
|
|
|
17
20
|
th,
|
|
18
21
|
td {
|
|
19
22
|
text-align: left;
|
|
23
|
+
/* --border currently resolves to `none` — see the AUDIT FLAG in
|
|
24
|
+
_standard-02-color.scss (duplicate --border declaration). */
|
|
20
25
|
border: var(--border);
|
|
21
26
|
line-height: var(--line-height-compact);
|
|
22
27
|
padding: var(--space-d2);
|
|
23
28
|
font-size: var(--size-sm);
|
|
24
|
-
min-height
|
|
29
|
+
/* Fixed 2026-07-14 — was an invalid unitless min-height, now derives a
|
|
30
|
+
real length from the line-height already set above. */
|
|
31
|
+
min-height: calc(1em * var(--line-height-compact));
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
th {
|
package/_standard-11-forms.scss
CHANGED
|
@@ -49,9 +49,13 @@ textarea {
|
|
|
49
49
|
border-radius: var(--radius-sm);
|
|
50
50
|
color: var(--color-foreground);
|
|
51
51
|
background: var(--color-surface);
|
|
52
|
-
/* shadcn-style raised effect
|
|
52
|
+
/* shadcn-style raised effect. --border currently resolves to `none` —
|
|
53
|
+
see the AUDIT FLAG in _standard-02-color.scss. */
|
|
53
54
|
border: var(--border);
|
|
54
55
|
box-shadow: var(--shadow-raised);
|
|
56
|
+
/* Transparent outline at full width reserves the space a real focus
|
|
57
|
+
outline (set on :focus below) will need — prevents layout shift when
|
|
58
|
+
the outline color actually appears. */
|
|
55
59
|
outline: var(--stroke-width) solid transparent;
|
|
56
60
|
outline-offset: var(--stroke-width);
|
|
57
61
|
transition: all var(--transition-fast);
|
|
@@ -66,7 +70,6 @@ textarea {
|
|
|
66
70
|
select {
|
|
67
71
|
width: 100%;
|
|
68
72
|
font-family: var(--font-interface), system-ui, sans-serif;
|
|
69
|
-
font-family: var(--font-interface), system-ui, sans-serif;
|
|
70
73
|
font-weight: var(--font-weight);
|
|
71
74
|
padding: var(--space-d8) var(--space-d4);
|
|
72
75
|
font-size: 1em;
|
|
@@ -276,9 +279,11 @@ input[type="checkbox"][role="switch"] {
|
|
|
276
279
|
}
|
|
277
280
|
}
|
|
278
281
|
|
|
282
|
+
/* Fixed 2026-07-14 — was a typo (--color-on-cce), corrected to
|
|
283
|
+
--color-on-accent. */
|
|
279
284
|
&:checked:hover {
|
|
280
285
|
&::before {
|
|
281
|
-
background: var(--color-on-
|
|
286
|
+
background: var(--color-on-accent) !important;
|
|
282
287
|
}
|
|
283
288
|
}
|
|
284
289
|
}
|
|
@@ -303,18 +308,17 @@ input[type="range"] {
|
|
|
303
308
|
/* Crucial: removes text-input borders */
|
|
304
309
|
background-origin: border-box;
|
|
305
310
|
|
|
306
|
-
/*
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
311
|
+
/* Fixed 2026-07-14 — this gradient is real and wired up by
|
|
312
|
+
Slider.astro's JS (sets --slider-value); the flat color below it was
|
|
313
|
+
silently overriding it. Removed the override so the fill effect
|
|
314
|
+
actually renders. */
|
|
310
315
|
background: linear-gradient(
|
|
311
316
|
to right,
|
|
312
317
|
var(--color-background, var(--color-accent)) 0%,
|
|
313
|
-
var(--color-background, var(--color-accent)) var(--slider-value),
|
|
314
|
-
var(--color-red, var(--color-surface)) var(--slider-value),
|
|
318
|
+
var(--color-background, var(--color-accent)) var(--slider-value, 50%),
|
|
319
|
+
var(--color-red, var(--color-surface)) var(--slider-value, 50%),
|
|
315
320
|
var(--color-red, var(--color-surface)) 100%
|
|
316
321
|
);
|
|
317
|
-
background: var(--color-surface-lowest);
|
|
318
322
|
}
|
|
319
323
|
|
|
320
324
|
input[type="range"]::-webkit-slider-thumb {
|
package/_standard-12-code.scss
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
@use "standard-00-variables" as *;
|
|
2
2
|
/* Note: General color utilities (.text-muted, .text-subtle, .text-accent, .bg-surface, .border-*) */
|
|
3
|
-
/* moved to
|
|
3
|
+
/* moved to _standard-50-utilities.scss for better layer organization (comment said
|
|
4
|
+
"standard-98-utilities.scss" — that file doesn't exist, fixed the reference) */
|
|
4
5
|
|
|
5
6
|
/* PrismJS syntax highlighting - Language agnostic tokens */
|
|
6
7
|
|