@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,52 +1,51 @@
1
1
  @layer skin {
2
- /* === Checklist — skin ===
2
+ /* === Checklist — skin ===
3
3
  * The indicator chrome (fill, border, radius, box-shadow) and the item text
4
4
  * treatment per state. The indicator gutter + box placement/size live in
5
5
  * @refrakt-md/skeleton (dimensions/checklist.css). */
6
6
 
7
- /* Indicator base chrome. */
8
- [data-checked]::before {
9
- border-radius: var(--rf-radius-sm, 0.25rem);
10
- border: 2px solid var(--rf-color-border);
11
- background: transparent;
12
- }
13
-
14
- /* Checked — filled with checkmark */
15
- [data-checked="checked"]::before {
16
- background: var(--rf-color-primary);
17
- border-color: var(--rf-color-primary);
18
- }
19
-
20
- [data-checked="checked"] {
21
- color: var(--rf-color-muted);
22
- }
23
-
24
- /* Active — primary colour with emphasis */
25
- [data-checked="active"]::before {
26
- border-color: var(--rf-color-primary);
27
- background: var(--rf-color-primary);
28
- box-shadow: 0 0 0 3px color-mix(in oklch, var(--rf-color-primary) 20%, transparent);
29
- }
30
-
31
- [data-checked="active"] {
32
- color: var(--rf-color-primary);
33
- font-weight: var(--rf-weight-semibold);
34
- }
35
-
36
- /* Skipped — muted with strikethrough */
37
- [data-checked="skipped"]::before {
38
- background: var(--rf-color-muted);
39
- border-color: var(--rf-color-muted);
40
- }
41
-
42
- [data-checked="skipped"] {
43
- text-decoration: line-through;
44
- color: var(--rf-color-muted);
45
- }
46
-
47
- /* Unchecked — empty indicator (inherits base styling) */
48
- [data-checked="unchecked"]::before {
49
- background: transparent;
50
- }
51
-
7
+ /* Indicator base chrome. */
8
+ [data-checked]::before {
9
+ border-radius: var(--rf-radius-sm, 0.25rem);
10
+ border: 2px solid var(--rf-color-border);
11
+ background: transparent;
12
+ }
13
+
14
+ /* Checked — filled with checkmark */
15
+ [data-checked="checked"]::before {
16
+ background: var(--rf-color-primary);
17
+ border-color: var(--rf-color-primary);
18
+ }
19
+
20
+ [data-checked="checked"] {
21
+ color: var(--rf-color-muted);
22
+ }
23
+
24
+ /* Active — primary colour with emphasis */
25
+ [data-checked="active"]::before {
26
+ border-color: var(--rf-color-primary);
27
+ background: var(--rf-color-primary);
28
+ box-shadow: 0 0 0 3px color-mix(in oklch, var(--rf-color-primary) 20%, transparent);
29
+ }
30
+
31
+ [data-checked="active"] {
32
+ color: var(--rf-color-primary);
33
+ font-weight: var(--rf-weight-semibold);
34
+ }
35
+
36
+ /* Skipped — muted with strikethrough */
37
+ [data-checked="skipped"]::before {
38
+ background: var(--rf-color-muted);
39
+ border-color: var(--rf-color-muted);
40
+ }
41
+
42
+ [data-checked="skipped"] {
43
+ text-decoration: line-through;
44
+ color: var(--rf-color-muted);
45
+ }
46
+
47
+ /* Unchecked — empty indicator (inherits base styling) */
48
+ [data-checked="unchecked"]::before {
49
+ background: transparent;
50
+ }
52
51
  }
@@ -1,5 +1,5 @@
1
1
  @layer skin {
2
- /* Cover layout (SPEC-089) — skin.
2
+ /* Cover layout (SPEC-089) — skin.
3
3
  *
4
4
  * The grid-overlay *structure* (media well + content share one grid cell, the
5
5
  * well fills/crops its guest, the overlay positions via content-place) lives in
@@ -7,83 +7,103 @@
7
7
  * media radii, the overlay's surface padding, and the legibility scrim
8
8
  * (gradient / frost) painted over the media. */
9
9
 
10
- [data-cover-scope="header"] > [data-name="cover-band"] {
11
- border-radius: var(--rf-radius-media);
12
- }
10
+ [data-cover-scope="header"] > [data-name="cover-band"] {
11
+ border-radius: var(--rf-radius-media);
12
+ }
13
13
 
14
- [data-media-position="cover"] [data-section="media"] {
15
- border-radius: var(--rf-radius-media);
16
- }
14
+ [data-media-position="cover"] [data-section="media"] {
15
+ border-radius: var(--rf-radius-media);
16
+ }
17
17
 
18
- /* A backdrop sandbox sits flush in the well — the well's own radius/overflow
18
+ /* A backdrop sandbox sits flush in the well — the well's own radius/overflow
19
19
  * does the clipping. */
20
- [data-media-position="cover"] [data-section="media"] .rf-sandbox {
21
- border-radius: 0;
22
- }
20
+ [data-media-position="cover"] [data-section="media"] .rf-sandbox {
21
+ border-radius: 0;
22
+ }
23
23
 
24
- /* The overlaid box carries the surface padding (density-aware via --rune-padding). */
25
- [data-media-position="cover"]:not([data-cover-scope="header"]) > [data-name="content"],
26
- [data-cover-scope="header"] > [data-name="cover-band"] > [data-name="preamble"] {
27
- padding: var(--rune-padding, var(--rf-spacing-md));
28
- }
24
+ /* The overlaid box carries the surface padding (density-aware via --rune-padding). */
25
+ [data-media-position="cover"]:not([data-cover-scope="header"]) > [data-name="content"],
26
+ [data-cover-scope="header"] > [data-name="cover-band"] > [data-name="preamble"] {
27
+ padding: var(--rune-padding, var(--rf-spacing-md));
28
+ }
29
29
 
30
- /* ── default cover scrim (SPEC-088 scrim, on the media surface) ────────
30
+ /* ── default cover scrim (SPEC-088 scrim, on the media surface) ────────
31
31
  * Overlaying text on an arbitrary image without a scrim is a legibility footgun,
32
32
  * so cover applies a default gradient scrim weighted toward the content edge.
33
33
  * `scrim="none"` opts out. The overlaid foreground is set light by the engine
34
34
  * (data-color-scheme) so text reads against the darkened media. */
35
- [data-media-position="cover"]:not([data-scrim="none"]) [data-section="media"]::after {
36
- content: "";
37
- position: absolute;
38
- inset: 0;
39
- pointer-events: none;
40
- /* `inherit` matches the media zone's `--rf-radius-media`, so a frost scrim's
35
+ [data-media-position="cover"]:not([data-scrim="none"]) [data-section="media"]::after {
36
+ content: "";
37
+ position: absolute;
38
+ inset: 0;
39
+ pointer-events: none;
40
+ /* `inherit` matches the media zone's `--rf-radius-media`, so a frost scrim's
41
41
  * `backdrop-filter` region clips at the same rounded corners — `overflow:
42
42
  * hidden` on the media zone doesn't reliably clip backdrop-filter past the
43
43
  * rounded edge in WebKit, so the pseudo carries its own radius. (The
44
44
  * gradient variant doesn't strictly need this, but it's harmless and keeps
45
45
  * the two scrim variants visually congruent.) */
46
- border-radius: inherit;
47
- /* The scrim shape is `--cover-scrim-image` (custom property override) when
46
+ border-radius: inherit;
47
+ /* The scrim shape is `--cover-scrim-image` (custom property override) when
48
48
  * the engine emits one — for `content-place="center …"` it emits a radial
49
49
  * ellipse so the dark falls under the centred overlay. For the directional
50
50
  * cases (`start`/`end` block-axis) the engine sets `--cover-scrim-dir` and
51
51
  * the linear fallback resolves to the right edge. */
52
- background-image: var(--cover-scrim-image, linear-gradient(var(--cover-scrim-dir, to top), rgb(0 0 0 / 0.55), transparent 62%));
53
- }
52
+ background-image: var(
53
+ --cover-scrim-image,
54
+ linear-gradient(var(--cover-scrim-dir, to top), rgb(0 0 0 / 0.55), transparent 62%)
55
+ );
56
+ }
54
57
 
55
- /* Frost treatment (`scrim-type="frost"`) — a frosted-glass blur over the media
58
+ /* Frost treatment (`scrim-type="frost"`) — a frosted-glass blur over the media
56
59
  * instead of a gradient. `scrim-blur` (named scale) sets the blur radius; the
57
60
  * tint follows the cover scheme (a dark scheme → a dark frost for light text).
58
61
  * The frost is masked to the content edge (following `--cover-scrim-dir`, default
59
62
  * bottom) so it reads as a band behind the text, not a blur over the whole
60
63
  * image. `--cover-scrim-mask` is the radial equivalent for centred content. */
61
- [data-media-position="cover"][data-scrim-blur="none"] { --cover-scrim-blur: 0px; }
62
- [data-media-position="cover"][data-scrim-blur="sm"] { --cover-scrim-blur: 4px; }
63
- [data-media-position="cover"][data-scrim-blur="md"] { --cover-scrim-blur: 8px; }
64
- [data-media-position="cover"][data-scrim-blur="lg"] { --cover-scrim-blur: 16px; }
65
- [data-media-position="cover"][data-scrim-type="frost"]:not([data-scrim="none"]) [data-section="media"]::after {
66
- background-image: none;
67
- background-color: rgb(0 0 0 / 0.18);
68
- -webkit-backdrop-filter: blur(var(--cover-scrim-blur, 8px));
69
- backdrop-filter: blur(var(--cover-scrim-blur, 8px));
70
- -webkit-mask-image: var(--cover-scrim-mask, linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%));
71
- mask-image: var(--cover-scrim-mask, linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%));
72
- }
73
- [data-media-position="cover"][data-scrim-type="frost"][data-color-scheme="light"]:not([data-scrim="none"]) [data-section="media"]::after {
74
- background-color: rgb(255 255 255 / 0.25);
75
- }
64
+ [data-media-position="cover"][data-scrim-blur="none"] {
65
+ --cover-scrim-blur: 0px;
66
+ }
67
+ [data-media-position="cover"][data-scrim-blur="sm"] {
68
+ --cover-scrim-blur: 4px;
69
+ }
70
+ [data-media-position="cover"][data-scrim-blur="md"] {
71
+ --cover-scrim-blur: 8px;
72
+ }
73
+ [data-media-position="cover"][data-scrim-blur="lg"] {
74
+ --cover-scrim-blur: 16px;
75
+ }
76
+ [data-media-position="cover"][data-scrim-type="frost"]:not([data-scrim="none"])
77
+ [data-section="media"]::after {
78
+ background-image: none;
79
+ background-color: rgb(0 0 0 / 0.18);
80
+ -webkit-backdrop-filter: blur(var(--cover-scrim-blur, 8px));
81
+ backdrop-filter: blur(var(--cover-scrim-blur, 8px));
82
+ -webkit-mask-image: var(
83
+ --cover-scrim-mask,
84
+ linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%)
85
+ );
86
+ mask-image: var(
87
+ --cover-scrim-mask,
88
+ linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%)
89
+ );
90
+ }
91
+ [data-media-position="cover"][data-scrim-type="frost"][data-color-scheme="light"]:not(
92
+ [data-scrim="none"]
93
+ )
94
+ [data-section="media"]::after {
95
+ background-color: rgb(255 255 255 / 0.25);
96
+ }
76
97
 
77
- /* The overlay carries the cover colour-scheme (set by the engine) so its text
98
+ /* The overlay carries the cover colour-scheme (set by the engine) so its text
78
99
  * reads against the darkened media. The standalone `[data-color-scheme]` rule
79
100
  * also paints a `background-color`; null it out here so the overlay stays
80
101
  * see-through over the media (the scrim, not a solid box, does the legibility). */
81
- [data-media-position="cover"] [data-name="content"][data-color-scheme],
82
- [data-cover-scope="header"] > [data-name="cover-band"][data-color-scheme] {
83
- background-color: transparent;
84
- /* Muted text (the blurb) is barely legible over a photo, so on the overlay it
102
+ [data-media-position="cover"] [data-name="content"][data-color-scheme],
103
+ [data-cover-scope="header"] > [data-name="cover-band"][data-color-scheme] {
104
+ background-color: transparent;
105
+ /* Muted text (the blurb) is barely legible over a photo, so on the overlay it
85
106
  * reads at full foreground strength — the same colour as the headline. */
86
- --rf-color-muted: var(--rf-color-text);
87
- }
88
-
107
+ --rf-color-muted: var(--rf-color-text);
108
+ }
89
109
  }
@@ -1,103 +1,107 @@
1
1
  @layer skin {
2
- /* ─── Density Dimension ─────────────────────────────────────────────────
2
+ /* ─── Density Dimension ─────────────────────────────────────────────────
3
3
  * Controls spacing, visibility, and detail level across all runes.
4
4
  * Three levels: full (dedicated page), compact (grid/card), minimal (list).
5
5
  *
6
6
  * Sets --rune-padding which surfaces consume for container padding.
7
7
  * ────────────────────────────────────────────────────────────────────── */
8
8
 
9
- /* ─── Full: all content visible, generous spacing ─────────────────── */
9
+ /* ─── Full: all content visible, generous spacing ─────────────────── */
10
10
 
11
- [data-density="full"] {
12
- --rune-padding: var(--rf-spacing-md);
13
- --rf-title-size: var(--rf-text-2xl);
14
- }
11
+ [data-density="full"] {
12
+ --rune-padding: var(--rf-spacing-md);
13
+ --rf-title-size: var(--rf-text-2xl);
14
+ }
15
15
 
16
- /* ─── Compact: truncated descriptions, tight spacing ──────────────── */
16
+ /* ─── Compact: truncated descriptions, tight spacing ──────────────── */
17
17
 
18
- [data-density="compact"] {
19
- --rune-padding: var(--rf-spacing-sm);
20
- --rf-title-size: var(--rf-text-xl);
21
- }
18
+ [data-density="compact"] {
19
+ --rune-padding: var(--rf-spacing-sm);
20
+ --rf-title-size: var(--rf-text-xl);
21
+ }
22
22
 
23
- [data-density="compact"] [data-section="description"] {
24
- display: -webkit-box;
25
- -webkit-line-clamp: 2;
26
- -webkit-box-orient: vertical;
27
- overflow: hidden;
28
- }
23
+ [data-density="compact"] [data-section="description"] {
24
+ display: -webkit-box;
25
+ -webkit-line-clamp: 2;
26
+ -webkit-box-orient: vertical;
27
+ overflow: hidden;
28
+ }
29
29
 
30
- [data-density="compact"] [data-meta-rank="secondary"] {
31
- display: none;
32
- }
30
+ [data-density="compact"] [data-meta-rank="secondary"] {
31
+ display: none;
32
+ }
33
33
 
34
- /* ─── Minimal: title and primary metadata only ────────────────────── */
34
+ /* ─── Minimal: title and primary metadata only ────────────────────── */
35
35
 
36
- [data-density="minimal"] {
37
- --rune-padding: var(--rf-spacing-xs);
38
- --rf-title-size: var(--rf-text);
39
- }
36
+ [data-density="minimal"] {
37
+ --rune-padding: var(--rf-spacing-xs);
38
+ --rf-title-size: var(--rf-text);
39
+ }
40
40
 
41
- /* Every rune root clears the prominence override so an ancestor's `prominence=`
41
+ /* Every rune root clears the prominence override so an ancestor's `prominence=`
42
42
  * cannot leak into a nested rune's title — the same protection the density
43
43
  * declarations above already give --rf-title-size. Declared here because this
44
44
  * file is imported before dimensions/surfaces.css, so a rune carrying both
45
45
  * `data-density` and `data-prominence` still keeps its own. */
46
- [data-density] {
47
- --rf-prominence-size: initial;
48
- }
46
+ [data-density] {
47
+ --rf-prominence-size: initial;
48
+ }
49
49
 
50
- [data-density="minimal"] [data-section="description"] {
51
- display: none;
52
- }
50
+ [data-density="minimal"] [data-section="description"] {
51
+ display: none;
52
+ }
53
53
 
54
- [data-density="minimal"] [data-section="body"] {
55
- display: none;
56
- }
54
+ [data-density="minimal"] [data-section="body"] {
55
+ display: none;
56
+ }
57
57
 
58
- /* Most runes put the title beside the body; card puts its leading heading
58
+ /* Most runes put the title beside the body; card puts its leading heading
59
59
  * *inside* the body slot. The blanket hide above would take the title with it
60
60
  * and leave an empty surface, so where a title is nested in the body, keep the
61
61
  * body box and hide only its other children — "title and primary metadata only"
62
62
  * then means what it says on those runes too. (SPEC-125 Phase 1: card only
63
63
  * gained a `body` role in v0.31.0, so this case could not arise before.) */
64
- [data-density="minimal"] [data-section="body"]:has(> [data-name="title"]) {
65
- display: revert;
66
- }
64
+ [data-density="minimal"] [data-section="body"]:has(> [data-name="title"]) {
65
+ display: revert;
66
+ }
67
67
 
68
- [data-density="minimal"] [data-section="body"]:has(> [data-name="title"]) > :not([data-name="title"]) {
69
- display: none;
70
- }
68
+ [data-density="minimal"]
69
+ [data-section="body"]:has(> [data-name="title"])
70
+ > :not([data-name="title"]) {
71
+ display: none;
72
+ }
71
73
 
72
- [data-density="minimal"] [data-section="footer"] {
73
- display: none;
74
- }
74
+ [data-density="minimal"] [data-section="footer"] {
75
+ display: none;
76
+ }
75
77
 
76
- [data-density="minimal"] [data-meta-rank="secondary"] {
77
- display: none;
78
- }
78
+ [data-density="minimal"] [data-meta-rank="secondary"] {
79
+ display: none;
80
+ }
79
81
 
80
- /* ─── Nested density scoping ─────────────────────────────────────── *
82
+ /* ─── Nested density scoping ─────────────────────────────────────── *
81
83
  * Density rules use descendant selectors that leak into nested runes
82
84
  * with their own density. These resets ensure each rune's density is
83
85
  * self-contained — e.g. a full-density recipe inside a compact-density
84
86
  * preview should not have its description truncated.
85
87
  * ──────────────────────────────────────────────────────────────────── */
86
88
 
87
- [data-density="compact"] [data-density="full"] [data-section="description"] {
88
- display: block;
89
- -webkit-line-clamp: unset;
90
- -webkit-box-orient: initial;
91
- overflow: visible;
92
- }
93
-
94
- [data-density="compact"] [data-density="full"] [data-meta-rank="secondary"],
95
- [data-density="minimal"] [data-density="full"] [data-section="description"],
96
- [data-density="minimal"] [data-density="full"] [data-section="body"],
97
- [data-density="minimal"] [data-density="full"] [data-section="footer"],
98
- [data-density="minimal"] [data-density="full"] [data-meta-rank="secondary"],
99
- [data-density="minimal"] [data-density="full"] [data-section="body"]:has(> [data-name="title"]) > :not([data-name="title"]) {
100
- display: revert;
101
- }
102
-
89
+ [data-density="compact"] [data-density="full"] [data-section="description"] {
90
+ display: block;
91
+ -webkit-line-clamp: unset;
92
+ -webkit-box-orient: initial;
93
+ overflow: visible;
94
+ }
95
+
96
+ [data-density="compact"] [data-density="full"] [data-meta-rank="secondary"],
97
+ [data-density="minimal"] [data-density="full"] [data-section="description"],
98
+ [data-density="minimal"] [data-density="full"] [data-section="body"],
99
+ [data-density="minimal"] [data-density="full"] [data-section="footer"],
100
+ [data-density="minimal"] [data-density="full"] [data-meta-rank="secondary"],
101
+ [data-density="minimal"]
102
+ [data-density="full"]
103
+ [data-section="body"]:has(> [data-name="title"])
104
+ > :not([data-name="title"]) {
105
+ display: revert;
106
+ }
103
107
  }