@refrakt-md/lumina 0.21.0 → 0.23.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 (131) hide show
  1. package/base.css +2 -1
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +7 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/tokens.d.ts +5 -3
  6. package/dist/tokens.d.ts.map +1 -1
  7. package/dist/tokens.js +44 -3
  8. package/dist/tokens.js.map +1 -1
  9. package/index.css +11 -1
  10. package/package.json +7 -5
  11. package/styles/base/attributes.css +6 -7
  12. package/styles/dimensions/checklist.css +7 -36
  13. package/styles/dimensions/cover.css +13 -95
  14. package/styles/dimensions/density.css +6 -3
  15. package/styles/dimensions/frame.css +7 -4
  16. package/styles/dimensions/media.css +14 -61
  17. package/styles/dimensions/metadata.css +30 -80
  18. package/styles/dimensions/sections.css +16 -30
  19. package/styles/dimensions/sequence.css +17 -82
  20. package/styles/dimensions/state.css +39 -56
  21. package/styles/dimensions/substrate.css +3 -0
  22. package/styles/dimensions/surfaces.css +73 -113
  23. package/styles/elements/blockquote.css +3 -2
  24. package/styles/elements/code.css +3 -0
  25. package/styles/elements/table.css +3 -0
  26. package/styles/global.css +24 -63
  27. package/styles/layouts/blog.css +34 -95
  28. package/styles/layouts/default.css +12 -86
  29. package/styles/layouts/docs.css +9 -159
  30. package/styles/layouts/mobile.css +3 -52
  31. package/styles/layouts/on-this-page.css +8 -7
  32. package/styles/layouts/plan.css +27 -158
  33. package/styles/layouts/search.css +17 -82
  34. package/styles/layouts/split.css +24 -169
  35. package/styles/layouts/theme-toggle.css +3 -29
  36. package/styles/layouts/version-switcher.css +9 -10
  37. package/styles/runes/accordion.css +25 -68
  38. package/styles/runes/aggregate.css +4 -13
  39. package/styles/runes/annotate.css +11 -40
  40. package/styles/runes/api.css +4 -1
  41. package/styles/runes/audio.css +12 -50
  42. package/styles/runes/badge.css +5 -2
  43. package/styles/runes/bar.css +3 -0
  44. package/styles/runes/bento.css +18 -161
  45. package/styles/runes/bg.css +3 -37
  46. package/styles/runes/blog.css +18 -20
  47. package/styles/runes/bond.css +6 -26
  48. package/styles/runes/breadcrumb.css +7 -15
  49. package/styles/runes/budget.css +23 -45
  50. package/styles/runes/bug.css +5 -2
  51. package/styles/runes/card.css +27 -95
  52. package/styles/runes/cast.css +10 -27
  53. package/styles/runes/changelog.css +13 -17
  54. package/styles/runes/character.css +6 -20
  55. package/styles/runes/chart.css +15 -57
  56. package/styles/runes/codegroup.css +18 -26
  57. package/styles/runes/collection.css +8 -85
  58. package/styles/runes/compare.css +8 -19
  59. package/styles/runes/comparison.css +29 -56
  60. package/styles/runes/conversation.css +9 -31
  61. package/styles/runes/cta.css +17 -40
  62. package/styles/runes/datatable.css +33 -48
  63. package/styles/runes/decision.css +5 -2
  64. package/styles/runes/design-context.css +5 -4
  65. package/styles/runes/details.css +9 -17
  66. package/styles/runes/diagram.css +8 -16
  67. package/styles/runes/diff.css +11 -94
  68. package/styles/runes/drawer.css +9 -113
  69. package/styles/runes/embed.css +5 -13
  70. package/styles/runes/event.css +5 -3
  71. package/styles/runes/expand.css +10 -45
  72. package/styles/runes/faction.css +6 -12
  73. package/styles/runes/feature.css +15 -43
  74. package/styles/runes/figure.css +7 -26
  75. package/styles/runes/file-ref.css +3 -18
  76. package/styles/runes/form.css +19 -48
  77. package/styles/runes/gallery.css +8 -140
  78. package/styles/runes/grid.css +4 -56
  79. package/styles/runes/hero.css +28 -140
  80. package/styles/runes/hint.css +23 -48
  81. package/styles/runes/howto.css +9 -31
  82. package/styles/runes/itinerary.css +15 -44
  83. package/styles/runes/juxtapose.css +17 -92
  84. package/styles/runes/lore.css +7 -14
  85. package/styles/runes/map.css +9 -42
  86. package/styles/runes/mediatext.css +4 -45
  87. package/styles/runes/milestone.css +15 -28
  88. package/styles/runes/mockup.css +10 -115
  89. package/styles/runes/nav.css +37 -212
  90. package/styles/runes/organization.css +6 -5
  91. package/styles/runes/page-section.css +3 -4
  92. package/styles/runes/pagination.css +10 -42
  93. package/styles/runes/palette.css +16 -35
  94. package/styles/runes/placeholder.css +16 -0
  95. package/styles/runes/plan-history.css +23 -43
  96. package/styles/runes/plan-progress.css +6 -7
  97. package/styles/runes/plan-ref.css +4 -1
  98. package/styles/runes/playlist.css +10 -44
  99. package/styles/runes/plot.css +9 -25
  100. package/styles/runes/preview.css +9 -34
  101. package/styles/runes/pricing.css +23 -41
  102. package/styles/runes/progress.css +8 -27
  103. package/styles/runes/pullquote.css +9 -31
  104. package/styles/runes/realm.css +6 -12
  105. package/styles/runes/recipe.css +12 -36
  106. package/styles/runes/relationships.css +5 -36
  107. package/styles/runes/reveal.css +17 -22
  108. package/styles/runes/sandbox.css +9 -39
  109. package/styles/runes/section.css +10 -24
  110. package/styles/runes/showcase.css +3 -20
  111. package/styles/runes/sidenote.css +5 -4
  112. package/styles/runes/snippet.css +3 -0
  113. package/styles/runes/spacing.css +14 -33
  114. package/styles/runes/spec.css +5 -2
  115. package/styles/runes/steps.css +14 -46
  116. package/styles/runes/storyboard.css +4 -19
  117. package/styles/runes/swatch.css +4 -7
  118. package/styles/runes/symbol.css +16 -14
  119. package/styles/runes/tabs.css +15 -18
  120. package/styles/runes/testimonial.css +12 -13
  121. package/styles/runes/textblock.css +6 -24
  122. package/styles/runes/timeline.css +10 -28
  123. package/styles/runes/tint.css +3 -0
  124. package/styles/runes/toc.css +9 -7
  125. package/styles/runes/track.css +12 -41
  126. package/styles/runes/typography.css +15 -27
  127. package/styles/runes/work.css +5 -2
  128. package/styles/runes/xref.css +3 -1
  129. package/tokens/base.css +56 -66
  130. package/tokens/dark.css +79 -80
  131. package/styles/dimensions/guest-posture.css +0 -27
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Drawer — addressable modal panel (SPEC-060).
2
3
  *
3
4
  * Two visual modes ride on the same `.rf-drawer` element:
@@ -19,9 +20,6 @@
19
20
  */
20
21
 
21
22
  .rf-drawer {
22
- --rf-drawer-size-sm: 22rem;
23
- --rf-drawer-size-md: 36rem;
24
- --rf-drawer-size-lg: 52rem;
25
23
  --rf-drawer-bg: var(--rf-color-surface);
26
24
  --rf-drawer-fg: var(--rf-color-text);
27
25
  --rf-drawer-border: var(--rf-color-border);
@@ -32,13 +30,6 @@
32
30
  --rf-drawer-anim-ease: cubic-bezier(0.32, 0.72, 0, 1);
33
31
  }
34
32
 
35
- /* ─── Body-scroll lock while any drawer is open ────────────────── */
36
-
37
- html.rf-drawer-open,
38
- html.rf-drawer-open body {
39
- overflow: hidden;
40
- }
41
-
42
33
  /* ─── No-JS / in-flow mode ─────────────────────────────────────── */
43
34
 
44
35
  section.rf-drawer {
@@ -52,19 +43,16 @@ section.rf-drawer {
52
43
  }
53
44
 
54
45
  section.rf-drawer .rf-drawer__header {
55
- display: flex;
56
- align-items: baseline;
57
- justify-content: space-between;
58
46
  gap: var(--rf-spacing-sm);
59
47
  margin-bottom: var(--rf-spacing-sm);
60
48
  }
61
49
 
62
50
  section.rf-drawer .rf-drawer__title {
63
51
  margin: 0;
64
- font-size: 1.05rem;
65
- font-weight: 600;
52
+ font-size: var(--rf-text);
53
+ font-weight: var(--rf-weight-semibold);
66
54
  color: var(--rf-color-primary);
67
- letter-spacing: 0.01em;
55
+ letter-spacing: var(--rf-tracking-normal);
68
56
  }
69
57
 
70
58
  section.rf-drawer .rf-drawer__body > :first-child { margin-top: 0; }
@@ -73,11 +61,10 @@ section.rf-drawer .rf-drawer__body > :last-child { margin-bottom: 0; }
73
61
  /* In-flow footer — small text, top divider, mirrors the dialog-mode look so
74
62
  * authors get the same chrome whether JS is enhancing or not. */
75
63
  section.rf-drawer .rf-drawer__footer {
76
- display: block;
77
64
  margin-top: var(--rf-spacing-md);
78
65
  padding-top: var(--rf-spacing-sm);
79
66
  border-top: 1px solid var(--rf-drawer-border);
80
- font-size: 0.875rem;
67
+ font-size: var(--rf-text-sm);
81
68
  color: var(--rf-color-muted);
82
69
  }
83
70
  section.rf-drawer .rf-drawer__footer > :first-child { margin-top: 0; }
@@ -91,7 +78,6 @@ section.rf-drawer .rf-drawer__footer > :last-child { margin-bottom: 0; }
91
78
  * closed dialogs, so the closed dialog renders visibly as an empty box
92
79
  * positioned by the side `inset` rules. */
93
80
  dialog.rf-drawer {
94
- box-sizing: border-box;
95
81
  background: var(--rf-drawer-bg);
96
82
  color: var(--rf-drawer-fg);
97
83
  border: 1px solid var(--rf-drawer-border);
@@ -99,18 +85,6 @@ dialog.rf-drawer {
99
85
  box-shadow: var(--rf-drawer-shadow);
100
86
  padding: 0;
101
87
  margin: 0;
102
- overflow: hidden;
103
- max-width: calc(100vw - 2 * var(--rf-drawer-gutter));
104
- max-height: calc(100vh - 2 * var(--rf-drawer-gutter));
105
- }
106
-
107
- /* Flex column layout only when the dialog is actually open. The header
108
- * and footer pin via `flex: 0 0 auto`; the body scrolls via `flex: 1 1
109
- * auto; overflow-y: auto`. The dialog's `max-height` cap on the dialog
110
- * provides the scroll context. */
111
- dialog.rf-drawer[open] {
112
- display: flex;
113
- flex-direction: column;
114
88
  }
115
89
 
116
90
  dialog.rf-drawer::backdrop {
@@ -119,10 +93,6 @@ dialog.rf-drawer::backdrop {
119
93
  }
120
94
 
121
95
  dialog.rf-drawer .rf-drawer__header {
122
- flex: 0 0 auto;
123
- display: flex;
124
- align-items: center;
125
- justify-content: space-between;
126
96
  gap: var(--rf-spacing-md);
127
97
  /* Reset the generous `[data-section="header"]` bottom margin (3rem) — the
128
98
  * dialog chrome spaces the header from the body via the body's own
@@ -134,8 +104,8 @@ dialog.rf-drawer .rf-drawer__header {
134
104
  }
135
105
  dialog.rf-drawer .rf-drawer__title {
136
106
  margin: 0;
137
- font-size: 1.05rem;
138
- font-weight: 600;
107
+ font-size: var(--rf-text);
108
+ font-weight: var(--rf-weight-semibold);
139
109
  }
140
110
 
141
111
  dialog.rf-drawer .rf-drawer__close {
@@ -145,10 +115,9 @@ dialog.rf-drawer .rf-drawer__close {
145
115
  cursor: pointer;
146
116
  color: var(--rf-color-muted);
147
117
  padding: var(--rf-spacing-xs) var(--rf-spacing-sm);
148
- font-size: 1.25rem;
118
+ font-size: var(--rf-text-xl);
149
119
  line-height: 1;
150
120
  border-radius: var(--rf-radius-sm);
151
- flex-shrink: 0;
152
121
  }
153
122
  dialog.rf-drawer .rf-drawer__close:hover {
154
123
  color: var(--rf-color-text);
@@ -156,21 +125,17 @@ dialog.rf-drawer .rf-drawer__close:hover {
156
125
  }
157
126
 
158
127
  dialog.rf-drawer .rf-drawer__body {
159
- flex: 1 1 auto;
160
- overflow-y: auto;
161
128
  padding: var(--rf-spacing-md) var(--rf-spacing-lg);
162
- min-height: 0;
163
129
  }
164
130
 
165
131
  /* Dialog footer — small text, top divider, pinned at bottom via flex.
166
132
  * Stays visible regardless of body scroll depth so links like "View
167
133
  * source on GitHub →" (the SPEC-078 use case) are always one tap away. */
168
134
  dialog.rf-drawer .rf-drawer__footer {
169
- flex: 0 0 auto;
170
135
  padding: var(--rf-spacing-sm) var(--rf-spacing-lg);
171
136
  border-top: 1px solid var(--rf-drawer-border);
172
137
  background: var(--rf-drawer-bg);
173
- font-size: 0.875rem;
138
+ font-size: var(--rf-text-sm);
174
139
  color: var(--rf-color-muted);
175
140
  }
176
141
  dialog.rf-drawer .rf-drawer__footer > :first-child { margin-top: 0; }
@@ -191,67 +156,24 @@ dialog.rf-drawer .rf-drawer__body > :last-child,
191
156
  dialog.rf-drawer .rf-drawer__body > :last-child > :last-child {
192
157
  margin-bottom: 0;
193
158
  }
194
-
195
- /* ─── Side modifiers ───────────────────────────────────────────────
196
- *
197
- * Each side anchors the dialog with `inset`. The slide-in animation is
198
- * a keyframes animation triggered by `[open]` — picked over
199
- * `@starting-style` because keyframes have broader browser support
200
- * (everywhere `<dialog>` works) and a clearer source-of-truth: the
201
- * starting/ending frames are spelled out, no cascade-interaction
202
- * footguns. The matching backdrop fade is a separate animation.
203
- */
204
-
205
- dialog.rf-drawer[data-side="right"] {
206
- inset:
207
- var(--rf-drawer-gutter)
208
- var(--rf-drawer-gutter)
209
- var(--rf-drawer-gutter)
210
- auto;
211
- height: auto;
212
- }
213
159
  dialog.rf-drawer[data-side="right"][open]:not([data-state="closing"]) {
214
160
  animation: rf-drawer-slide-in-right var(--rf-drawer-anim-duration) var(--rf-drawer-anim-ease);
215
161
  }
216
162
  dialog.rf-drawer[data-side="right"][data-state="closing"] {
217
163
  animation: rf-drawer-slide-out-right var(--rf-drawer-anim-duration) var(--rf-drawer-anim-ease) forwards;
218
164
  }
219
- dialog.rf-drawer[data-side="left"] {
220
- inset:
221
- var(--rf-drawer-gutter)
222
- auto
223
- var(--rf-drawer-gutter)
224
- var(--rf-drawer-gutter);
225
- height: auto;
226
- }
227
165
  dialog.rf-drawer[data-side="left"][open]:not([data-state="closing"]) {
228
166
  animation: rf-drawer-slide-in-left var(--rf-drawer-anim-duration) var(--rf-drawer-anim-ease);
229
167
  }
230
168
  dialog.rf-drawer[data-side="left"][data-state="closing"] {
231
169
  animation: rf-drawer-slide-out-left var(--rf-drawer-anim-duration) var(--rf-drawer-anim-ease) forwards;
232
170
  }
233
- dialog.rf-drawer[data-side="top"] {
234
- inset:
235
- var(--rf-drawer-gutter)
236
- var(--rf-drawer-gutter)
237
- auto
238
- var(--rf-drawer-gutter);
239
- width: auto;
240
- }
241
171
  dialog.rf-drawer[data-side="top"][open]:not([data-state="closing"]) {
242
172
  animation: rf-drawer-slide-in-top var(--rf-drawer-anim-duration) var(--rf-drawer-anim-ease);
243
173
  }
244
174
  dialog.rf-drawer[data-side="top"][data-state="closing"] {
245
175
  animation: rf-drawer-slide-out-top var(--rf-drawer-anim-duration) var(--rf-drawer-anim-ease) forwards;
246
176
  }
247
- dialog.rf-drawer[data-side="bottom"] {
248
- inset:
249
- auto
250
- var(--rf-drawer-gutter)
251
- var(--rf-drawer-gutter)
252
- var(--rf-drawer-gutter);
253
- width: auto;
254
- }
255
177
  dialog.rf-drawer[data-side="bottom"][open]:not([data-state="closing"]) {
256
178
  animation: rf-drawer-slide-in-bottom var(--rf-drawer-anim-duration) var(--rf-drawer-anim-ease);
257
179
  }
@@ -336,30 +258,4 @@ dialog.rf-drawer[data-state="closing"]::backdrop {
336
258
  }
337
259
  }
338
260
 
339
- /* ─── Size modifiers (only meaningful in dialog mode) ─────────── */
340
-
341
- dialog.rf-drawer[data-side="right"][data-size="sm"],
342
- dialog.rf-drawer[data-side="left"][data-size="sm"] {
343
- width: var(--rf-drawer-size-sm);
344
- }
345
- dialog.rf-drawer[data-side="right"][data-size="md"],
346
- dialog.rf-drawer[data-side="left"][data-size="md"] {
347
- width: var(--rf-drawer-size-md);
348
- }
349
- dialog.rf-drawer[data-side="right"][data-size="lg"],
350
- dialog.rf-drawer[data-side="left"][data-size="lg"] {
351
- width: var(--rf-drawer-size-lg);
352
- }
353
-
354
- dialog.rf-drawer[data-side="top"][data-size="sm"],
355
- dialog.rf-drawer[data-side="bottom"][data-size="sm"] {
356
- height: var(--rf-drawer-size-sm);
357
- }
358
- dialog.rf-drawer[data-side="top"][data-size="md"],
359
- dialog.rf-drawer[data-side="bottom"][data-size="md"] {
360
- height: var(--rf-drawer-size-md);
361
- }
362
- dialog.rf-drawer[data-side="top"][data-size="lg"],
363
- dialog.rf-drawer[data-side="bottom"][data-size="lg"] {
364
- height: var(--rf-drawer-size-lg);
365
261
  }
@@ -1,32 +1,24 @@
1
- /* Embed */
1
+ @layer skin {
2
+ /* Embed — skin. The responsive iframe wrapper + empty-fallback hide live in
3
+ * @refrakt-md/skeleton (styles/runes/embed.css). */
2
4
  .rf-embed {
3
5
  margin: 0;
4
6
  padding: 0;
5
7
  }
6
8
  .rf-embed__wrapper {
7
- position: relative;
8
- width: 100%;
9
- height: 0;
10
- overflow: hidden;
11
9
  border-radius: var(--rf-radius-md);
12
10
  background: var(--rf-color-surface);
13
11
  }
14
12
  .rf-embed__wrapper iframe {
15
- position: absolute;
16
- top: 0;
17
- left: 0;
18
- width: 100%;
19
- height: 100%;
20
13
  border: none;
21
14
  }
22
15
  .rf-embed__fallback {
23
- font-size: 0.85rem;
16
+ font-size: var(--rf-text-sm);
24
17
  color: var(--rf-color-muted);
25
18
  margin-top: 0.5rem;
26
19
  }
27
20
  .rf-embed__fallback p:last-child {
28
21
  margin-bottom: 0;
29
22
  }
30
- .rf-embed__fallback:empty {
31
- display: none;
23
+
32
24
  }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Event */
2
3
 
3
4
  /* When/where def-list — geometry from the shared `[data-zone-layout=
@@ -11,13 +12,12 @@
11
12
  margin-top: 1.5rem;
12
13
  }
13
14
  .rf-event__register a {
14
- display: inline-block;
15
15
  padding: 0.5rem 1rem;
16
16
  background: var(--rf-color-primary);
17
17
  color: var(--rf-color-on-primary);
18
18
  border-radius: var(--rf-radius-md);
19
- font-weight: 500;
20
- font-size: 0.875rem;
19
+ font-weight: var(--rf-weight-medium);
20
+ font-size: var(--rf-text-sm);
21
21
  text-decoration: none;
22
22
  }
23
23
  .rf-event__register a:hover {
@@ -37,3 +37,5 @@
37
37
  .rf-event__body a:hover {
38
38
  color: var(--rf-color-primary-hover);
39
39
  }
40
+
41
+ }
@@ -1,72 +1,37 @@
1
- /* Expand — inline-substitution of a registered entity (SPEC-066).
2
- *
3
- * The wrapper is intentionally minimal — the embedded rune (plan rune,
4
- * character rune, etc.) renders itself standalone-style; expand just
5
- * provides the wrapper + canonical-link affordance. Themes that want
6
- * the embedded content visually distinguished from inline-authored
7
- * content target `.rf-expand .rf-spec`, `.rf-expand h1`, etc.
8
- *
9
- * Two visual treatments:
10
- *
11
- * 1. **Default (`level=` unset, peer-document mode)** — the embed reads
12
- * like a quoted document. A subtle border + indent treatment marks
13
- * it as set-aside material. Heading scale is dialed down slightly
14
- * so an H1 inside the embed doesn't compete with the host's H1.
15
- * 2. **Sub-section mode (`level=` set)** — the embed merges into the
16
- * host outline. The wrapper sheds the quoted treatment so it reads
17
- * as authored sub-content. Authors opt into this by setting
18
- * `level=`; CSS targets `.rf-expand:not([data-outline-scope])` to
19
- * pick the right treatment automatically.
20
- */
21
-
1
+ @layer skin {
2
+ /* Expand — skin. The inline-block canonical-link box lives in @refrakt-md/skeleton
3
+ * (styles/runes/expand.css). */
22
4
  .rf-expand {
23
5
  margin: var(--rf-spacing-md) 0;
24
6
  }
25
-
26
- /* Peer-document mode — no background, no rounded corners, no rules.
27
- * Reads as "set-aside material" through spacing alone, without competing
28
- * visually with the host content. Authors who want a stronger treatment
29
- * (rules, background, etc.) can override `.rf-expand[data-outline-scope]`
30
- * in their theme. */
31
7
  .rf-expand[data-outline-scope] {
32
8
  padding: var(--rf-spacing-md) 0;
33
9
  }
34
-
35
- /* Tone down embedded headings so the host outline keeps visual primacy.
36
- * The semantic levels are preserved (H1 stays H1 etc.); only the visual
37
- * scale is adjusted in the peer-document treatment. Authors using
38
- * `level=` for sub-section mode get the normal heading scale. */
39
10
  .rf-expand[data-outline-scope] :is(h1, h2, h3, h4, h5, h6):first-child {
40
11
  margin-top: 0;
41
12
  }
42
- .rf-expand[data-outline-scope] h1 { font-size: 1.5rem; }
43
- .rf-expand[data-outline-scope] h2 { font-size: 1.25rem; }
44
- .rf-expand[data-outline-scope] h3 { font-size: 1.1rem; }
45
-
13
+ .rf-expand[data-outline-scope] h1 { font-size: var(--rf-text-2xl); }
14
+ .rf-expand[data-outline-scope] h2 { font-size: var(--rf-text-xl); }
15
+ .rf-expand[data-outline-scope] h3 { font-size: var(--rf-text-lg); }
46
16
  .rf-expand > :first-child { margin-top: 0; }
47
17
  .rf-expand > :last-child { margin-bottom: 0; }
48
-
49
18
  .rf-expand__canonical-link {
50
- display: inline-block;
51
19
  margin-top: var(--rf-spacing-sm);
52
- font-size: 0.875rem;
20
+ font-size: var(--rf-text-sm);
53
21
  color: var(--rf-color-primary);
54
22
  text-decoration: none;
55
23
  }
56
24
  .rf-expand__canonical-link:hover {
57
25
  text-decoration: underline;
58
26
  }
59
-
60
- /* Error-state placeholder rendered when resolution fails. The build
61
- * also surfaces the error through `ctx.error`; this is the user-facing
62
- * affordance so the failure isn't silent. Keyed off `[data-expand-error]`
63
- * which the resolver sets on the error wrapper. */
64
27
  .rf-expand[data-expand-error] {
65
28
  padding: var(--rf-spacing-sm) var(--rf-spacing-md);
66
29
  border-left: 3px solid var(--rf-color-danger);
67
30
  background: var(--rf-color-danger-bg);
68
31
  color: var(--rf-color-danger);
69
32
  font-family: var(--rf-font-mono);
70
- font-size: 0.875rem;
33
+ font-size: var(--rf-text-sm);
71
34
  border-radius: 0 var(--rf-radius-sm) var(--rf-radius-sm) 0;
72
35
  }
36
+
37
+ }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Faction — split/stacked geometry, the title, and the metadata def-list all
2
3
  * come from the shared layers: layouts/split.css ([data-layout] +
3
4
  * [data-section="media"]), dimensions/sections.css ([data-section="title"] /
@@ -28,12 +29,6 @@
28
29
  row-gap: var(--rf-faction-media-gap);
29
30
  }
30
31
 
31
- /* Stacked layouts — beside layouts handled by shared split.css */
32
- .rf-faction[data-media-position="top"] {
33
- display: flex;
34
- flex-direction: column;
35
- }
36
-
37
32
  .rf-faction[data-media-position="top"] > .rf-faction__scene {
38
33
  margin-bottom: var(--rf-faction-media-gap);
39
34
  }
@@ -43,8 +38,6 @@
43
38
 
44
39
  /* Content */
45
40
  .rf-faction__sections {
46
- display: flex;
47
- flex-direction: column;
48
41
  gap: 1rem;
49
42
  }
50
43
  .rf-faction__content ul,
@@ -58,10 +51,9 @@
58
51
  border-top: 1px solid var(--rf-color-border);
59
52
  }
60
53
  .rf-faction-section__name {
61
- display: block;
62
- font-size: 1.25rem;
63
- font-weight: 700;
64
- line-height: 1.3;
54
+ font-size: var(--rf-text-xl);
55
+ font-weight: var(--rf-weight-bold);
56
+ line-height: var(--rf-leading-snug);
65
57
  margin-bottom: 0.5rem;
66
58
  color: var(--rf-color-text);
67
59
  }
@@ -69,3 +61,5 @@
69
61
  .rf-faction-section__body ol {
70
62
  padding-left: 1.5rem;
71
63
  }
64
+
65
+ }
@@ -1,36 +1,34 @@
1
- /* Feature */
1
+ @layer skin {
2
+ /* Feature — skin. The preamble/eyebrow/content/definitions-grid/icon layout and
3
+ * the media-position flip live in @refrakt-md/skeleton (styles/runes/feature.css). */
2
4
  .rf-feature {
3
5
  padding: 2.5rem 0 2rem;
4
6
  }
5
7
  .rf-feature__preamble {
6
- flex-direction: column;
7
- align-items: flex-start;
8
8
  gap: 0.25rem;
9
9
  margin-bottom: 1.5rem;
10
10
  }
11
11
  .rf-feature__eyebrow {
12
- font-size: 0.8125rem;
13
- font-weight: 600;
14
- letter-spacing: 0.05em;
12
+ font-size: var(--rf-text-sm);
13
+ font-weight: var(--rf-weight-semibold);
14
+ letter-spacing: var(--rf-tracking-wider);
15
15
  text-transform: uppercase;
16
16
  color: var(--rf-color-primary);
17
17
  margin: 0 0 0.5rem;
18
18
  }
19
19
  .rf-feature__eyebrow:has(a) {
20
- display: inline-block;
21
- position: relative;
22
20
  padding: 0.25rem 0.875rem;
23
21
  border: 1px solid var(--rf-color-border);
24
22
  border-radius: var(--rf-radius-full);
25
23
  color: var(--rf-color-text);
26
- font-weight: 400;
24
+ font-weight: var(--rf-weight-normal);
27
25
  text-transform: none;
28
- letter-spacing: 0;
26
+ letter-spacing: var(--rf-tracking-normal);
29
27
  transition: border-color 150ms ease;
30
28
  }
31
29
  .rf-feature__eyebrow:has(a):hover { border-color: var(--rf-color-muted); }
32
- .rf-feature__eyebrow:has(a) a { color: var(--rf-color-primary); font-weight: 600; text-decoration: none; }
33
- .rf-feature__eyebrow:has(a) a::before { content: ''; position: absolute; inset: 0; border-radius: inherit; }
30
+ .rf-feature__eyebrow:has(a) a { color: var(--rf-color-primary); font-weight: var(--rf-weight-semibold); text-decoration: none; }
31
+ .rf-feature__eyebrow:has(a) a::before { border-radius: inherit; }
34
32
  .rf-feature__headline {
35
33
  margin-top: 0;
36
34
  }
@@ -42,9 +40,6 @@
42
40
  .rf-feature__image {
43
41
  margin-bottom: 1rem;
44
42
  }
45
- .rf-feature__content {
46
- display: contents;
47
- }
48
43
  .rf-feature h2 {
49
44
  margin-bottom: 2rem;
50
45
  }
@@ -63,20 +58,13 @@
63
58
  /* Definitions stack in a single column by default; the `--definitions-grid`
64
59
  * modifier (SPEC-091 media-position variant: top/bottom) tiles them as a grid. */
65
60
  .rf-feature__definitions {
66
- display: block;
67
61
  margin: 0;
68
62
  }
69
63
  .rf-feature--definitions-grid .rf-feature__definitions {
70
- display: grid;
71
- grid-template-columns: repeat(auto-fit, minmax(max(240px, calc((100% - 3rem) / 3)), 1fr));
72
64
  gap: 1.5rem;
73
65
  }
74
66
  /* Beside layouts (media on start/end): definitions stay stacked (no grid
75
67
  * modifier) inside the content track. */
76
- .rf-feature[data-media-position="start"] .rf-feature__content,
77
- .rf-feature[data-media-position="end"] .rf-feature__content {
78
- display: block;
79
- }
80
68
  .rf-feature[data-media-position="start"] .rf-feature__preamble,
81
69
  .rf-feature[data-media-position="end"] .rf-feature__preamble,
82
70
  .rf-feature[data-media-position="start"] h2,
@@ -97,27 +85,21 @@
97
85
  background: var(--rf-color-surface);
98
86
  }
99
87
  .rf-feature__feature-item dt {
100
- font-weight: 650;
101
- font-size: 1.125rem;
88
+ font-weight: var(--rf-weight-semibold);
89
+ font-size: var(--rf-text-lg);
102
90
  margin-bottom: 0.75rem;
103
- letter-spacing: -0.01em;
91
+ letter-spacing: var(--rf-tracking-tight);
104
92
  color: var(--rf-color-text);
105
93
  }
106
- .rf-feature__feature-item dt:has(> .rf-icon) {
107
- display: flex;
108
- flex-direction: column;
109
- }
110
94
  .rf-feature__feature-item dt > .rf-icon {
111
- width: 1.5rem;
112
- height: 1.5rem;
113
95
  margin-bottom: 0.5rem;
114
96
  color: var(--rf-color-primary);
115
97
  }
116
98
  .rf-feature__feature-item dd {
117
99
  margin: 0;
118
100
  color: var(--rf-color-muted);
119
- font-size: 0.9rem;
120
- line-height: 1.65;
101
+ font-size: var(--rf-text-sm);
102
+ line-height: var(--rf-leading-relaxed);
121
103
  }
122
104
 
123
105
  /* Context-aware: feature inside a hero — no top padding, tighter spacing */
@@ -133,14 +115,4 @@
133
115
  padding: 0;
134
116
  }
135
117
 
136
- /* BUG-001 — content-first DOM inverts the shared media-first stacked contract
137
- * (layouts/split.css): counter it so the labels are truthful. `bottom` (the
138
- * default) is plain block flow — media after the content, the historical
139
- * look; an explicit `top` flips the visual order without touching the DOM. */
140
- .rf-feature[data-media-position="bottom"] {
141
- display: block;
142
- }
143
- .rf-feature[data-media-position="top"] {
144
- display: flex;
145
- flex-direction: column-reverse;
146
118
  }
@@ -1,34 +1,15 @@
1
- /* Figure */
2
- .rf-figure img {
3
- display: block;
4
- max-width: 100%;
5
- height: auto;
6
- margin-inline: auto;
1
+ @layer skin {
2
+ /* Figure — skin. The image box, frame-aspect fill, size max-widths, and alignment
3
+ * auto-margins live in @refrakt-md/skeleton (styles/runes/figure.css). */
4
+ .rf-figure :is(img, .rf-placeholder) {
7
5
  border-radius: var(--rf-radius-media);
8
6
  }
9
-
10
- /* When `frame-aspect` sets an explicit surface shape, the image fills the
11
- * shape rather than sitting at its natural size with whitespace on the
12
- * inline-end. `object-fit: cover` crops only if the natural aspect doesn't
13
- * match — and `frame-anchor` already picks the focal point of that crop
14
- * (the same contract as a card's media slot). */
15
- .rf-figure[style*="--frame-aspect"] img {
16
- width: 100%;
17
- height: 100%;
18
- object-fit: cover;
19
- margin: 0;
20
- }
21
7
  .rf-figure figcaption {
22
8
  margin-top: 0.625rem;
23
- font-size: 0.825rem;
9
+ font-size: var(--rf-text-sm);
24
10
  color: var(--rf-color-muted);
25
11
  text-align: center;
26
12
  font-style: italic;
27
13
  }
28
- .rf-figure--small { max-width: 320px; }
29
- .rf-figure--medium { max-width: 640px; }
30
- .rf-figure--large { max-width: 960px; }
31
- .rf-figure--full { max-width: 100%; }
32
- .rf-figure--left { margin-right: auto; }
33
- .rf-figure--center { margin-left: auto; margin-right: auto; }
34
- .rf-figure--right { margin-left: auto; }
14
+
15
+ }
@@ -1,21 +1,4 @@
1
- /* file-ref — path-based inline reference to a project file (SPEC-078).
2
- *
3
- * Renders as `<span class="rf-file-ref"><a>label</a></span>` in prose
4
- * (plus an invisible hoist sentinel `<meta>` when preview="drawer").
5
- * The span carries the data-rune class; the inner `<a>` is the click
6
- * target with its own visual treatment.
7
- *
8
- * Without preview, the link points at the canonical GitHub URL — give
9
- * it a small external-link affordance so readers know they're about to
10
- * leave the page. With preview, it points at the hoisted drawer's
11
- * fragment id; visually the same inline-link affordance — what makes
12
- * it a "preview link" rather than a "navigate-away link" is the drawer
13
- * that opens on click, not extra inline chrome.
14
- */
15
-
16
- .rf-file-ref {
17
- display: inline;
18
- }
1
+ @layer skin {
19
2
 
20
3
  .rf-file-ref > a {
21
4
  color: var(--rf-color-primary);
@@ -29,3 +12,5 @@
29
12
  .rf-file-ref > a:hover {
30
13
  text-decoration-thickness: 2px;
31
14
  }
15
+
16
+ }