@refrakt-md/lumina 0.32.0 → 0.34.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.
Files changed (142) hide show
  1. package/base.css +29 -29
  2. package/contracts/structures.json +58 -60
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js.map +1 -1
  5. package/dist/icons.d.ts.map +1 -1
  6. package/dist/icons.js +57 -57
  7. package/dist/icons.js.map +1 -1
  8. package/dist/presets/catppuccin.js.map +1 -1
  9. package/dist/presets/dracula.js.map +1 -1
  10. package/dist/presets/gruvbox.js.map +1 -1
  11. package/dist/presets/niwaki.js.map +1 -1
  12. package/dist/presets/nord.js.map +1 -1
  13. package/dist/presets/one-dark.js.map +1 -1
  14. package/dist/presets/solarized.js.map +1 -1
  15. package/dist/presets/tideline.d.ts.map +1 -1
  16. package/dist/presets/tideline.js +20 -4
  17. package/dist/presets/tideline.js.map +1 -1
  18. package/dist/presets/tokyo-night.js.map +1 -1
  19. package/dist/tokens.js.map +1 -1
  20. package/index.css +124 -124
  21. package/package.json +5 -5
  22. package/presets.json +61 -13
  23. package/styles/base/attributes.css +32 -13
  24. package/styles/dimensions/checklist.css +45 -46
  25. package/styles/dimensions/cover.css +71 -51
  26. package/styles/dimensions/density.css +69 -65
  27. package/styles/dimensions/frame.css +116 -57
  28. package/styles/dimensions/metadata.css +110 -103
  29. package/styles/dimensions/motion.css +42 -13
  30. package/styles/dimensions/reading.css +27 -27
  31. package/styles/dimensions/sections.css +44 -45
  32. package/styles/dimensions/sequence.css +56 -57
  33. package/styles/dimensions/state.css +8 -2
  34. package/styles/dimensions/substrate.css +82 -58
  35. package/styles/dimensions/surfaces.css +65 -62
  36. package/styles/elements/blockquote.css +24 -25
  37. package/styles/elements/code.css +72 -71
  38. package/styles/elements/table.css +36 -37
  39. package/styles/global.css +163 -121
  40. package/styles/layouts/blog.css +219 -218
  41. package/styles/layouts/default.css +168 -167
  42. package/styles/layouts/docs.css +121 -122
  43. package/styles/layouts/mobile.css +54 -55
  44. package/styles/layouts/on-this-page.css +46 -47
  45. package/styles/layouts/plan.css +248 -247
  46. package/styles/layouts/search.css +142 -140
  47. package/styles/layouts/split.css +45 -45
  48. package/styles/layouts/theme-toggle.css +33 -31
  49. package/styles/layouts/version-switcher.css +38 -37
  50. package/styles/runes/accordion.css +90 -81
  51. package/styles/runes/aggregate.css +50 -39
  52. package/styles/runes/annotate.css +46 -45
  53. package/styles/runes/api.css +22 -23
  54. package/styles/runes/audio.css +140 -141
  55. package/styles/runes/badge.css +12 -13
  56. package/styles/runes/bar.css +4 -5
  57. package/styles/runes/bento.css +73 -62
  58. package/styles/runes/bg.css +62 -47
  59. package/styles/runes/blog.css +89 -90
  60. package/styles/runes/bond.css +49 -50
  61. package/styles/runes/breadcrumb.css +34 -35
  62. package/styles/runes/budget.css +126 -127
  63. package/styles/runes/bug.css +28 -27
  64. package/styles/runes/card.css +63 -60
  65. package/styles/runes/carousel.css +15 -15
  66. package/styles/runes/cast.css +50 -51
  67. package/styles/runes/changelog.css +45 -46
  68. package/styles/runes/character.css +31 -32
  69. package/styles/runes/chart.css +194 -106
  70. package/styles/runes/codegroup.css +109 -100
  71. package/styles/runes/collection.css +87 -86
  72. package/styles/runes/compare.css +38 -39
  73. package/styles/runes/comparison.css +205 -179
  74. package/styles/runes/conversation.css +36 -33
  75. package/styles/runes/cta.css +135 -132
  76. package/styles/runes/datatable.css +84 -83
  77. package/styles/runes/decision.css +25 -26
  78. package/styles/runes/design-context.css +21 -23
  79. package/styles/runes/details.css +26 -27
  80. package/styles/runes/diagram.css +28 -29
  81. package/styles/runes/diff.css +75 -72
  82. package/styles/runes/drawer.css +276 -198
  83. package/styles/runes/embed.css +20 -21
  84. package/styles/runes/event.css +35 -36
  85. package/styles/runes/expand.css +43 -34
  86. package/styles/runes/faction.css +47 -48
  87. package/styles/runes/feature.css +119 -112
  88. package/styles/runes/figure.css +11 -12
  89. package/styles/runes/file-ref.css +11 -13
  90. package/styles/runes/form.css +155 -154
  91. package/styles/runes/gallery.css +59 -60
  92. package/styles/runes/grid.css +10 -7
  93. package/styles/runes/hero.css +189 -185
  94. package/styles/runes/hint.css +57 -58
  95. package/styles/runes/howto.css +62 -64
  96. package/styles/runes/itinerary.css +133 -134
  97. package/styles/runes/juxtapose.css +83 -82
  98. package/styles/runes/lore.css +32 -34
  99. package/styles/runes/map.css +106 -99
  100. package/styles/runes/mediatext.css +30 -27
  101. package/styles/runes/milestone.css +98 -97
  102. package/styles/runes/mockup.css +338 -335
  103. package/styles/runes/nav.css +465 -450
  104. package/styles/runes/organization.css +23 -20
  105. package/styles/runes/page-section.css +14 -15
  106. package/styles/runes/pagination.css +45 -44
  107. package/styles/runes/palette.css +78 -80
  108. package/styles/runes/placeholder.css +8 -9
  109. package/styles/runes/plan-history.css +160 -161
  110. package/styles/runes/plan-progress.css +15 -16
  111. package/styles/runes/plan-ref.css +32 -23
  112. package/styles/runes/playlist.css +106 -107
  113. package/styles/runes/plot.css +92 -91
  114. package/styles/runes/preview.css +152 -149
  115. package/styles/runes/pricing.css +133 -123
  116. package/styles/runes/progress.css +32 -27
  117. package/styles/runes/pullquote.css +89 -90
  118. package/styles/runes/realm.css +47 -48
  119. package/styles/runes/recipe.css +112 -114
  120. package/styles/runes/relationships.css +77 -76
  121. package/styles/runes/reveal.css +90 -79
  122. package/styles/runes/sandbox.css +59 -60
  123. package/styles/runes/section.css +57 -50
  124. package/styles/runes/showcase.css +35 -16
  125. package/styles/runes/sidenote.css +30 -27
  126. package/styles/runes/snippet.css +8 -9
  127. package/styles/runes/spacing.css +86 -88
  128. package/styles/runes/spec.css +24 -25
  129. package/styles/runes/steps.css +89 -80
  130. package/styles/runes/storyboard.css +46 -45
  131. package/styles/runes/swatch.css +22 -23
  132. package/styles/runes/symbol.css +117 -118
  133. package/styles/runes/tabs.css +88 -79
  134. package/styles/runes/testimonial.css +43 -44
  135. package/styles/runes/textblock.css +32 -28
  136. package/styles/runes/timeline.css +63 -64
  137. package/styles/runes/tint.css +214 -215
  138. package/styles/runes/toc.css +40 -41
  139. package/styles/runes/track.css +89 -90
  140. package/styles/runes/typography.css +89 -91
  141. package/styles/runes/work.css +47 -36
  142. package/styles/runes/xref.css +21 -22
@@ -1,67 +1,66 @@
1
1
  @layer skin {
2
- /* ─── Section Anatomy Dimension — skin ──────────────────────────────────
2
+ /* ─── Section Anatomy Dimension — skin ──────────────────────────────────
3
3
  * Zone rhythm (margins, gaps, padding), typography, and borders for the 6
4
4
  * standard section roles. The flex zone *containers* (header / preamble /
5
5
  * footer) live in @refrakt-md/skeleton (dimensions/sections.css). Rhythm stays
6
6
  * here so rune zone overrides resolve against it by source order.
7
7
  * ────────────────────────────────────────────────────────────────────── */
8
8
 
9
- /* ─── Header: chrome metadata row (badges, status, icons) ────────── */
10
- [data-section="header"] {
11
- gap: 0.5rem;
12
- margin-bottom: 3rem;
13
- }
9
+ /* ─── Header: chrome metadata row (badges, status, icons) ────────── */
10
+ [data-section="header"] {
11
+ gap: 0.5rem;
12
+ margin-bottom: 3rem;
13
+ }
14
14
 
15
- /* ─── Preamble: intro section (eyebrow, headline, blurb) ─────────── */
16
- [data-section="preamble"] {
17
- gap: 0.25rem;
18
- }
15
+ /* ─── Preamble: intro section (eyebrow, headline, blurb) ─────────── */
16
+ [data-section="preamble"] {
17
+ gap: 0.25rem;
18
+ }
19
19
 
20
- /* ─── Title: primary heading ──────────────────────────────────────── */
21
- /* Two inputs, in priority order:
20
+ /* ─── Title: primary heading ──────────────────────────────────────── */
21
+ /* Two inputs, in priority order:
22
22
  * --rf-prominence-size an explicit author `prominence=` (surfaces.css)
23
23
  * --rf-title-size the resting size for this density (density.css)
24
24
  * They were one variable until v0.32.0, which meant a rune could not state its
25
25
  * own resting size without also clobbering the author's override — the reason
26
26
  * `prominence` was inert on eight runes (WORK-538). Splitting them lets a rune
27
27
  * pin its default while `prominence` still wins. */
28
- [data-section="title"] {
29
- font-family: var(--rf-font-sans);
30
- font-size: var(--rf-prominence-size, var(--rf-title-size, var(--rf-text-2xl)));
31
- font-weight: var(--rf-weight-bold);
32
- line-height: var(--rf-leading-tight);
33
- color: var(--rf-color-text);
34
- margin: 0;
35
- }
28
+ [data-section="title"] {
29
+ font-family: var(--rf-font-sans);
30
+ font-size: var(--rf-prominence-size, var(--rf-title-size, var(--rf-text-2xl)));
31
+ font-weight: var(--rf-weight-bold);
32
+ line-height: var(--rf-leading-tight);
33
+ color: var(--rf-color-text);
34
+ margin: 0;
35
+ }
36
36
 
37
- /* ─── Description: secondary text ─────────────────────────────────── */
38
- [data-section="description"] {
39
- font-size: var(--rf-text);
40
- line-height: var(--rf-leading-normal);
41
- color: var(--rf-color-muted);
42
- margin: var(--rf-spacing-xs) 0 var(--rf-spacing-md);
43
- }
37
+ /* ─── Description: secondary text ─────────────────────────────────── */
38
+ [data-section="description"] {
39
+ font-size: var(--rf-text);
40
+ line-height: var(--rf-leading-normal);
41
+ color: var(--rf-color-muted);
42
+ margin: var(--rf-spacing-xs) 0 var(--rf-spacing-md);
43
+ }
44
44
 
45
- /* ─── Body: main content ──────────────────────────────────────────── */
46
- [data-section="body"] {
47
- line-height: var(--rf-leading-relaxed);
48
- color: var(--rf-color-text);
49
- }
45
+ /* ─── Body: main content ──────────────────────────────────────────── */
46
+ [data-section="body"] {
47
+ line-height: var(--rf-leading-relaxed);
48
+ color: var(--rf-color-text);
49
+ }
50
50
 
51
- /* ─── Footer: actions and links ───────────────────────────────────── */
52
- [data-section="footer"] {
53
- gap: var(--rf-spacing-sm);
54
- margin-top: var(--rf-spacing-md);
55
- padding-top: var(--rf-spacing-sm);
56
- border-top: 1px solid var(--rf-color-border);
57
- }
51
+ /* ─── Footer: actions and links ───────────────────────────────────── */
52
+ [data-section="footer"] {
53
+ gap: var(--rf-spacing-sm);
54
+ margin-top: var(--rf-spacing-md);
55
+ padding-top: var(--rf-spacing-sm);
56
+ border-top: 1px solid var(--rf-color-border);
57
+ }
58
58
 
59
- /* ─── Media: visual content ───────────────────────────────────────── */
60
- [data-section="media"] {
61
- /* Media zones manage their own spacing via their layout (split gap, cell
59
+ /* ─── Media: visual content ───────────────────────────────────────── */
60
+ [data-section="media"] {
61
+ /* Media zones manage their own spacing via their layout (split gap, cell
62
62
  * padding, flow margins); a blanket block margin here misaligns media in
63
63
  * flex/beside layouts, so keep it neutral. */
64
- margin: 0;
65
- }
66
-
64
+ margin: 0;
65
+ }
67
66
  }
@@ -1,64 +1,63 @@
1
1
  @layer skin {
2
- /* === Sequential Items — skin ===
2
+ /* === Sequential Items — skin ===
3
3
  * The connector lines (borders), the marker chrome (fill, radius, shadow), the
4
4
  * counter type, and the layout gaps. The counter mechanism, list resets, item
5
5
  * geometry, and marker box placement live in @refrakt-md/skeleton
6
6
  * (dimensions/sequence.css). */
7
7
 
8
- /* Numbered — counter circle chrome + type. */
9
- [data-sequence="numbered"] > li::before {
10
- font-size: var(--rf-text-xs);
11
- font-weight: var(--rf-weight-bold);
12
- font-variant-numeric: tabular-nums;
13
- color: var(--rf-color-primary);
14
- background: var(--rf-color-surface-active);
15
- border-radius: 50%;
16
- }
17
-
18
- [data-sequence="numbered"] > li + li {
19
- border-top: 1px solid var(--rf-color-border);
20
- }
21
-
22
- /* Connected vertical — the line is a left border; the dot is the marker. */
23
- [data-sequence="connected"] > li {
24
- border-left: 2px solid var(--rf-color-border);
25
- }
26
-
27
- [data-sequence="connected"] > li:last-child {
28
- border-left-color: transparent;
29
- }
30
-
31
- [data-sequence="connected"] > li::before {
32
- border-radius: 50%;
33
- background: var(--rf-color-primary);
34
- border: 2px solid var(--rf-color-bg);
35
- box-shadow: 0 0 0 2px var(--rf-color-primary);
36
- }
37
-
38
- /* Connected horizontal — the line moves to the top border; gap spaces the items. */
39
- [data-sequence="connected"][data-sequence-direction="horizontal"] {
40
- gap: 2rem;
41
- }
42
-
43
- [data-sequence="connected"][data-sequence-direction="horizontal"] > li {
44
- border-left: none;
45
- border-top: 2px solid var(--rf-color-border);
46
- }
47
-
48
- [data-sequence="connected"][data-sequence-direction="horizontal"] > li:last-child {
49
- border-top-color: var(--rf-color-border);
50
- }
51
-
52
- /* === Density interaction === */
53
-
54
- /* Compact: smaller circle keeps the same type scale. */
55
- [data-density="compact"] [data-sequence="numbered"] > li::before {
56
- font-size: var(--rf-text-xs);
57
- }
58
-
59
- /* Minimal: drop the connector line on the collapsed list. */
60
- [data-density="minimal"] [data-sequence="connected"] > li {
61
- border-left: none;
62
- }
63
-
8
+ /* Numbered — counter circle chrome + type. */
9
+ [data-sequence="numbered"] > li::before {
10
+ font-size: var(--rf-text-xs);
11
+ font-weight: var(--rf-weight-bold);
12
+ font-variant-numeric: tabular-nums;
13
+ color: var(--rf-color-primary);
14
+ background: var(--rf-color-surface-active);
15
+ border-radius: 50%;
16
+ }
17
+
18
+ [data-sequence="numbered"] > li + li {
19
+ border-top: 1px solid var(--rf-color-border);
20
+ }
21
+
22
+ /* Connected vertical — the line is a left border; the dot is the marker. */
23
+ [data-sequence="connected"] > li {
24
+ border-left: 2px solid var(--rf-color-border);
25
+ }
26
+
27
+ [data-sequence="connected"] > li:last-child {
28
+ border-left-color: transparent;
29
+ }
30
+
31
+ [data-sequence="connected"] > li::before {
32
+ border-radius: 50%;
33
+ background: var(--rf-color-primary);
34
+ border: 2px solid var(--rf-color-bg);
35
+ box-shadow: 0 0 0 2px var(--rf-color-primary);
36
+ }
37
+
38
+ /* Connected horizontal — the line moves to the top border; gap spaces the items. */
39
+ [data-sequence="connected"][data-sequence-direction="horizontal"] {
40
+ gap: 2rem;
41
+ }
42
+
43
+ [data-sequence="connected"][data-sequence-direction="horizontal"] > li {
44
+ border-left: none;
45
+ border-top: 2px solid var(--rf-color-border);
46
+ }
47
+
48
+ [data-sequence="connected"][data-sequence-direction="horizontal"] > li:last-child {
49
+ border-top-color: var(--rf-color-border);
50
+ }
51
+
52
+ /* === Density interaction === */
53
+
54
+ /* Compact: smaller circle keeps the same type scale. */
55
+ [data-density="compact"] [data-sequence="numbered"] > li::before {
56
+ font-size: var(--rf-text-xs);
57
+ }
58
+
59
+ /* Minimal: drop the connector line on the collapsed list. */
60
+ [data-density="minimal"] [data-sequence="connected"] > li {
61
+ border-left: none;
62
+ }
64
63
  }
@@ -13,8 +13,14 @@
13
13
  }
14
14
 
15
15
  @keyframes rf-expand {
16
- from { opacity: 0; transform: translateY(-0.5rem); }
17
- to { opacity: 1; transform: translateY(0); }
16
+ from {
17
+ opacity: 0;
18
+ transform: translateY(-0.5rem);
19
+ }
20
+ to {
21
+ opacity: 1;
22
+ transform: translateY(0);
23
+ }
18
24
  }
19
25
 
20
26
  /* Active/inactive selection indicators */
@@ -1,5 +1,5 @@
1
1
  @layer skin {
2
- /* Substrate (SPEC-087) — generated surface pattern.
2
+ /* Substrate (SPEC-087) — generated surface pattern.
3
3
  *
4
4
  * The token-driven gradient recipes that realise each pattern ship here in the
5
5
  * always-included base layer (not a theme's swappable CSS), so "dots = dots on
@@ -21,42 +21,59 @@
21
21
  * and each pattern only feeds custom properties (which never collide with a
22
22
  * rune's background). The rune's `background-color` still shows through. */
23
23
 
24
- [data-substrate]:not([data-substrate="none"]) {
25
- --substrate-cell: 16px;
26
- --substrate-opacity: 0.5;
27
- /* `--substrate-boost` (per-pattern) and `--substrate-mode-boost` (light/dark)
24
+ [data-substrate]:not([data-substrate="none"]) {
25
+ --substrate-cell: 16px;
26
+ --substrate-opacity: 0.5;
27
+ /* `--substrate-boost` (per-pattern) and `--substrate-mode-boost` (light/dark)
28
28
  * are intentionally NOT set here — only referenced with a `1` fallback — so a
29
29
  * lower-specificity pattern rule or an inherited dark-mode rule can drive them
30
30
  * without losing to this (0,2,0) base. The product is clamped to 100% by
31
31
  * color-mix. */
32
- --substrate-ink: color-mix(in oklab, var(--rf-color-border) calc(var(--substrate-opacity) * var(--substrate-boost, 1) * var(--substrate-mode-boost, 1) * 100%), transparent);
33
- background-image: var(--substrate-image);
34
- background-size: var(--substrate-tile, var(--substrate-cell) var(--substrate-cell));
35
- background-position: var(--substrate-pos, 0 0);
36
- background-repeat: repeat;
37
- }
32
+ --substrate-ink: color-mix(
33
+ in oklab,
34
+ var(--rf-color-border)
35
+ calc(
36
+ var(--substrate-opacity) *
37
+ var(--substrate-boost, 1) *
38
+ var(--substrate-mode-boost, 1) *
39
+ 100%
40
+ ),
41
+ transparent
42
+ );
43
+ background-image: var(--substrate-image);
44
+ background-size: var(--substrate-tile, var(--substrate-cell) var(--substrate-cell));
45
+ background-position: var(--substrate-pos, 0 0);
46
+ background-repeat: repeat;
47
+ }
38
48
 
39
- /* dots — one tiled radial-gradient. A small dot reads fainter than a 1px line,
49
+ /* dots — one tiled radial-gradient. A small dot reads fainter than a 1px line,
40
50
  * so dots get a per-pattern ink boost. */
41
- [data-substrate="dots"] {
42
- --substrate-image: radial-gradient(var(--substrate-ink) var(--substrate-dot, 1.5px), transparent 0);
43
- --substrate-boost: 1.4;
44
- }
51
+ [data-substrate="dots"] {
52
+ --substrate-image: radial-gradient(
53
+ var(--substrate-ink) var(--substrate-dot, 1.5px),
54
+ transparent 0
55
+ );
56
+ --substrate-boost: 1.4;
57
+ }
45
58
 
46
- /* grid — two tiled linear-gradients */
47
- [data-substrate="grid"] {
48
- --substrate-image:
49
- linear-gradient(var(--substrate-ink) 1px, transparent 1px),
50
- linear-gradient(90deg, var(--substrate-ink) 1px, transparent 1px);
51
- }
59
+ /* grid — two tiled linear-gradients */
60
+ [data-substrate="grid"] {
61
+ --substrate-image:
62
+ linear-gradient(var(--substrate-ink) 1px, transparent 1px),
63
+ linear-gradient(90deg, var(--substrate-ink) 1px, transparent 1px);
64
+ }
52
65
 
53
- /* lines — diagonal hatching (the repeating gradient owns its own spacing) */
54
- [data-substrate="lines"] {
55
- --substrate-image: repeating-linear-gradient(45deg, var(--substrate-ink) 0 1px, transparent 1px var(--substrate-cell));
56
- --substrate-tile: auto;
57
- }
66
+ /* lines — diagonal hatching (the repeating gradient owns its own spacing) */
67
+ [data-substrate="lines"] {
68
+ --substrate-image: repeating-linear-gradient(
69
+ 45deg,
70
+ var(--substrate-ink) 0 1px,
71
+ transparent 1px var(--substrate-cell)
72
+ );
73
+ --substrate-tile: auto;
74
+ }
58
75
 
59
- /* cross — plus marks at the centre of each cell, drawn as two perpendicular
76
+ /* cross — plus marks at the centre of each cell, drawn as two perpendicular
60
77
  * thin ellipses (no `mask` — an element-level `mask` would clip the rune's
61
78
  * own text content along with the pattern, which is what we don't want). A
62
79
  * small plus reads fainter than a 1px line at the same ink opacity, so the
@@ -67,45 +84,52 @@
67
84
  * transparent for a zero-length transition, beats the `ink 100%, transparent
68
85
  * 100%` form which some renderers collapse to nothing). Ellipse radii at
69
86
  * 1px (rather than sub-pixel 0.5px) so the stroke survives DPR rounding. */
70
- [data-substrate="cross"] {
71
- --substrate-image:
72
- radial-gradient(ellipse 3px 1px at center, var(--substrate-ink) 100%, transparent 0),
73
- radial-gradient(ellipse 1px 3px at center, var(--substrate-ink) 100%, transparent 0);
74
- --substrate-pos: center;
75
- --substrate-boost: 1.6;
76
- }
87
+ [data-substrate="cross"] {
88
+ --substrate-image:
89
+ radial-gradient(ellipse 3px 1px at center, var(--substrate-ink) 100%, transparent 0),
90
+ radial-gradient(ellipse 1px 3px at center, var(--substrate-ink) 100%, transparent 0);
91
+ --substrate-pos: center;
92
+ --substrate-boost: 1.6;
93
+ }
77
94
 
78
- /* checker — alternating filled cells */
79
- [data-substrate="checker"] {
80
- --substrate-image:
81
- conic-gradient(var(--substrate-ink) 0 25%, transparent 0 50%, var(--substrate-ink) 0 75%, transparent 0);
82
- }
95
+ /* checker — alternating filled cells */
96
+ [data-substrate="checker"] {
97
+ --substrate-image: conic-gradient(
98
+ var(--substrate-ink) 0 25%,
99
+ transparent 0 50%,
100
+ var(--substrate-ink) 0 75%,
101
+ transparent 0
102
+ );
103
+ }
83
104
 
84
- [data-substrate="none"] { background-image: none; }
105
+ [data-substrate="none"] {
106
+ background-image: none;
107
+ }
85
108
 
86
- /* substrate-fill="inset" — paint the pattern over the recessed inset fill
109
+ /* substrate-fill="inset" — paint the pattern over the recessed inset fill
87
110
  * (SPEC-087 inset surface) instead of the inherited surface colour. */
88
- [data-substrate][data-substrate-fill="inset"] {
89
- background-color: oklch(from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h);
90
- }
111
+ [data-substrate][data-substrate-fill="inset"] {
112
+ background-color: oklch(
113
+ from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h
114
+ );
115
+ }
91
116
 
92
- /* Dark mode — the border ink sits close to the dark surface, so patterns need
117
+ /* Dark mode — the border ink sits close to the dark surface, so patterns need
93
118
  * more presence across the board (dots compound their per-pattern boost on top,
94
119
  * landing near full strength). Set the multiplier on the dark root so it
95
120
  * inherits into every substrate element; mirrors how dark.css triggers dark. */
96
- [data-theme="dark"],
97
- [data-color-scheme="dark"] {
98
- --substrate-mode-boost: 1.6;
99
- }
100
- @media (prefers-color-scheme: dark) {
101
- :root:not([data-theme="light"]) {
121
+ [data-theme="dark"],
122
+ [data-color-scheme="dark"] {
102
123
  --substrate-mode-boost: 1.6;
103
124
  }
104
- }
105
- /* A tint-locked light subtree resets to the light intensity (nearest ancestor
125
+ @media (prefers-color-scheme: dark) {
126
+ :root:not([data-theme="light"]) {
127
+ --substrate-mode-boost: 1.6;
128
+ }
129
+ }
130
+ /* A tint-locked light subtree resets to the light intensity (nearest ancestor
106
131
  * wins via inheritance), even when nested inside dark mode. */
107
- [data-color-scheme="light"] {
108
- --substrate-mode-boost: 1;
109
- }
110
-
132
+ [data-color-scheme="light"] {
133
+ --substrate-mode-boost: 1;
134
+ }
111
135
  }
@@ -1,5 +1,5 @@
1
1
  @layer skin {
2
- /* ─── Surface Assignments (SPEC-107) ───────────────────────────────────
2
+ /* ─── Surface Assignments (SPEC-107) ───────────────────────────────────
3
3
  * Surface chrome is selected by the `data-elevation` depth-ladder axis, not by
4
4
  * rune name. Each rung maps to a chrome bundle (fill / border / radius /
5
5
  * padding / resting shadow); `data-prominence` maps the page-section-header
@@ -8,33 +8,37 @@
8
8
  * preserved while a theme can re-point any rune to a different rung.
9
9
  * ────────────────────────────────────────────────────────────────────── */
10
10
 
11
- /* Semantic surface/media aliases over the raw token scale (these reference
11
+ /* Semantic surface/media aliases over the raw token scale (these reference
12
12
  * tokens rather than holding raw values, so they live in the styles layer, not
13
13
  * the generated token contract). Outer surfaces round at --rf-radius-container;
14
14
  * media guests nested inside them round at the smaller --rf-radius-media so they
15
15
  * never read as more rounded than their container. SPEC-086's `frame` will
16
16
  * override these per-instance. */
17
- :root {
18
- --rf-radius-container: var(--rf-radius-lg);
19
- --rf-radius-media: var(--rf-radius-md);
20
- }
17
+ :root {
18
+ --rf-radius-container: var(--rf-radius-lg);
19
+ --rf-radius-media: var(--rf-radius-md);
20
+ }
21
21
 
22
- /* ─── Rune Spacing ────────────────────────────────────────────────── */
23
- /* Only top-level runes get vertical margin; child runes (nav items,
22
+ /* ─── Rune Spacing ────────────────────────────────────────────────── */
23
+ /* Only top-level runes get vertical margin; child runes (nav items,
24
24
  accordion items, grid cells, etc.) inherit spacing from their parent.
25
25
  Layout-chrome navs (menubar in header, columns in footer) are excluded
26
26
  so they sit flush with the surrounding header/footer container. */
27
27
 
28
- /* `:where(...)` zeros the selector specificity so per-rune CSS, the
28
+ /* `:where(...)` zeros the selector specificity so per-rune CSS, the
29
29
  * `[data-rune][data-spacing="..."]` attribute rules, and per-instance overrides
30
30
  * all win cleanly. Without `:where()` the `:not([data-rune] [data-rune])` clause
31
31
  * inflates this default to (0,3,0) — beating the (0,2,0) spacing attribute and
32
32
  * masking `spacing="flush"` on top-level runes like hero. */
33
- :where([data-rune]:not([data-rune] [data-rune]):not([data-layout="menubar"]):not([data-layout="columns"])) {
34
- margin: var(--rf-spacing-md) 0;
35
- }
33
+ :where(
34
+ [data-rune]:not([data-rune] [data-rune]):not([data-layout="menubar"]):not(
35
+ [data-layout="columns"]
36
+ )
37
+ ) {
38
+ margin: var(--rf-spacing-md) 0;
39
+ }
36
40
 
37
- /* ─── Elevation: depth-ladder chrome ──────────────────────────────────
41
+ /* ─── Elevation: depth-ladder chrome ──────────────────────────────────
38
42
  * `flat` and the shadow rungs (`raised` / `floating` / `overlay`) carry a
39
43
  * surface: fill, border, radius, and container padding. `sunken` adds the same
40
44
  * chrome but recesses its fill below the page. `flush` has no surface boundary
@@ -42,47 +46,47 @@
42
46
  * box-shadow on top of the flat chrome (kept distinct from `frame-shadow`'s
43
47
  * per-guest drop-shadow, SPEC-107 §1). */
44
48
 
45
- [data-elevation="flat"],
46
- [data-elevation="sunken"],
47
- [data-elevation="raised"],
48
- [data-elevation="floating"],
49
- [data-elevation="overlay"] {
50
- background: var(--rf-color-surface);
51
- border: 1px solid var(--rf-color-border);
52
- border-radius: var(--rf-radius-container);
53
- padding: var(--rune-padding, var(--rf-spacing-md));
54
- }
49
+ [data-elevation="flat"],
50
+ [data-elevation="sunken"],
51
+ [data-elevation="raised"],
52
+ [data-elevation="floating"],
53
+ [data-elevation="overlay"] {
54
+ background: var(--rf-color-surface);
55
+ border: 1px solid var(--rf-color-border);
56
+ border-radius: var(--rf-radius-container);
57
+ padding: var(--rune-padding, var(--rf-spacing-md));
58
+ }
55
59
 
56
- /* Sunken — the recessed "darker surface" (e.g. chart / diagram). Derived at
60
+ /* Sunken — the recessed "darker surface" (e.g. chart / diagram). Derived at
57
61
  * use-site via relative-color (lower L, keep C+H) so it recomputes from a
58
62
  * tinted `--rf-color-surface` automatically (a static inset-colour token would
59
63
  * freeze to the untinted :root). Writes `background` only — never re-bases
60
64
  * `--rf-color-surface` — so insets don't compound under nesting; depth is
61
65
  * conveyed by border + the darker fill. `--rf-surface-inset-shift: 0` flushes
62
66
  * it back to the surface colour. */
63
- [data-elevation="sunken"] {
64
- background: oklch(from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h);
65
- }
67
+ [data-elevation="sunken"] {
68
+ background: oklch(from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h);
69
+ }
66
70
 
67
- /* Resting-shadow rungs — depth above the flat surface. */
68
- [data-elevation="raised"] {
69
- box-shadow: var(--rf-shadow-sm);
70
- }
71
- [data-elevation="floating"] {
72
- box-shadow: var(--rf-shadow-md);
73
- }
74
- [data-elevation="overlay"] {
75
- box-shadow: var(--rf-shadow-lg);
76
- }
71
+ /* Resting-shadow rungs — depth above the flat surface. */
72
+ [data-elevation="raised"] {
73
+ box-shadow: var(--rf-shadow-sm);
74
+ }
75
+ [data-elevation="floating"] {
76
+ box-shadow: var(--rf-shadow-md);
77
+ }
78
+ [data-elevation="overlay"] {
79
+ box-shadow: var(--rf-shadow-lg);
80
+ }
77
81
 
78
- /* Flush — no surface boundary; only vertical rhythm (density-aware via
82
+ /* Flush — no surface boundary; only vertical rhythm (density-aware via
79
83
  * --rune-padding). Replaces the old inline/banner padding buckets; banner runes
80
84
  * that want a more generous band declare their own `padding-block`. */
81
- [data-elevation="flush"] {
82
- padding-block: var(--rune-padding, var(--rf-spacing-sm));
83
- }
85
+ [data-elevation="flush"] {
86
+ padding-block: var(--rune-padding, var(--rf-spacing-sm));
87
+ }
84
88
 
85
- /* ─── Prominence: page-section-header type register ───────────────────
89
+ /* ─── Prominence: page-section-header type register ───────────────────
86
90
  * `data-prominence` re-points the section title size for page-section-header
87
91
  * family runes (the engine only emits it where a header role exists). `normal`
88
92
  * is the rune's resting size; the other steps ramp away from it, cascading down
@@ -103,17 +107,17 @@
103
107
  * override. density.css clears the variable at every rune root, before these
104
108
  * rules, so an ancestor's prominence cannot leak into a nested rune's title
105
109
  * while a rune carrying both still keeps its own. */
106
- [data-prominence="quiet"] {
107
- --rf-prominence-size: calc(var(--rf-title-size, var(--rf-text-2xl)) * 5 / 6);
108
- }
109
- [data-prominence="prominent"] {
110
- --rf-prominence-size: calc(var(--rf-title-size, var(--rf-text-2xl)) * 5 / 4);
111
- }
112
- [data-prominence="display"] {
113
- --rf-prominence-size: calc(var(--rf-title-size, var(--rf-text-2xl)) * 5 / 3);
114
- }
110
+ [data-prominence="quiet"] {
111
+ --rf-prominence-size: calc(var(--rf-title-size, var(--rf-text-2xl)) * 5 / 6);
112
+ }
113
+ [data-prominence="prominent"] {
114
+ --rf-prominence-size: calc(var(--rf-title-size, var(--rf-text-2xl)) * 5 / 4);
115
+ }
116
+ [data-prominence="display"] {
117
+ --rf-prominence-size: calc(var(--rf-title-size, var(--rf-text-2xl)) * 5 / 3);
118
+ }
115
119
 
116
- /* ─── Media slot shares the surface chrome ───────────────────────────
120
+ /* ─── Media slot shares the surface chrome ───────────────────────────
117
121
  * When a `flat` surface wraps a cover `[data-section="media"]` slot, the slot
118
122
  * shares the surface's 1px border and a recessed well fill so the framed media
119
123
  * reads as part of the same surface. Scoped via `:where()` for zero specificity
@@ -121,17 +125,16 @@
121
125
  * e.g. character / testimonial) opt out — they manage their own circular chrome.
122
126
  * The hand-rolled `card` / `bento-cell` surfaces (which sit outside the
123
127
  * elevation axis) carry the same media chrome from their own CSS files. */
124
- :where([data-elevation="flat"]) [data-section="media"]:not([data-media="portrait"]) {
125
- border: 1px solid var(--rf-color-border);
126
- background: oklch(from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h);
127
- }
128
+ :where([data-elevation="flat"]) [data-section="media"]:not([data-media="portrait"]) {
129
+ border: 1px solid var(--rf-color-border);
130
+ background: oklch(from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h);
131
+ }
128
132
 
129
- /* …but a sunken surface used as a media-zone guest already sits inside the
133
+ /* …but a sunken surface used as a media-zone guest already sits inside the
130
134
  * slot's recessed well, so its own chrome would just double up. Drop it; keep
131
135
  * padding so axis labels / SVG keep breathing room. */
132
- [data-section="media"] > [data-elevation="sunken"] {
133
- background: transparent;
134
- border: 0;
135
- }
136
-
136
+ [data-section="media"] > [data-elevation="sunken"] {
137
+ background: transparent;
138
+ border: 0;
139
+ }
137
140
  }