@refrakt-md/lumina 0.22.0 → 0.24.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 (132) hide show
  1. package/base.css +7 -1
  2. package/contracts/structures.json +537 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +7 -0
  5. package/dist/config.js.map +1 -1
  6. package/dist/tokens.d.ts.map +1 -1
  7. package/dist/tokens.js +13 -0
  8. package/dist/tokens.js.map +1 -1
  9. package/index.css +11 -1
  10. package/package.json +5 -4
  11. package/styles/base/attributes.css +6 -7
  12. package/styles/dimensions/checklist.css +6 -35
  13. package/styles/dimensions/cover.css +13 -95
  14. package/styles/dimensions/density.css +3 -0
  15. package/styles/dimensions/frame.css +3 -0
  16. package/styles/dimensions/media.css +14 -61
  17. package/styles/dimensions/metadata.css +24 -74
  18. package/styles/dimensions/motion.css +102 -0
  19. package/styles/dimensions/sections.css +10 -24
  20. package/styles/dimensions/sequence.css +14 -79
  21. package/styles/dimensions/state.css +39 -56
  22. package/styles/dimensions/substrate.css +3 -0
  23. package/styles/dimensions/surfaces.css +73 -113
  24. package/styles/elements/blockquote.css +3 -2
  25. package/styles/elements/code.css +3 -0
  26. package/styles/elements/table.css +3 -0
  27. package/styles/global.css +9 -48
  28. package/styles/layouts/blog.css +3 -64
  29. package/styles/layouts/default.css +3 -77
  30. package/styles/layouts/docs.css +3 -153
  31. package/styles/layouts/mobile.css +1 -50
  32. package/styles/layouts/on-this-page.css +3 -2
  33. package/styles/layouts/plan.css +3 -134
  34. package/styles/layouts/search.css +3 -68
  35. package/styles/layouts/split.css +24 -169
  36. package/styles/layouts/theme-toggle.css +3 -29
  37. package/styles/layouts/version-switcher.css +3 -4
  38. package/styles/runes/accordion.css +15 -58
  39. package/styles/runes/aggregate.css +3 -12
  40. package/styles/runes/annotate.css +6 -35
  41. package/styles/runes/api.css +3 -0
  42. package/styles/runes/audio.css +3 -41
  43. package/styles/runes/badge.css +3 -0
  44. package/styles/runes/bar.css +3 -0
  45. package/styles/runes/bento.css +16 -159
  46. package/styles/runes/bg.css +3 -37
  47. package/styles/runes/blog.css +3 -5
  48. package/styles/runes/bond.css +3 -23
  49. package/styles/runes/breadcrumb.css +5 -13
  50. package/styles/runes/budget.css +3 -25
  51. package/styles/runes/bug.css +3 -0
  52. package/styles/runes/card.css +24 -92
  53. package/styles/runes/cast.css +5 -22
  54. package/styles/runes/changelog.css +5 -9
  55. package/styles/runes/character.css +3 -17
  56. package/styles/runes/chart.css +35 -53
  57. package/styles/runes/codegroup.css +15 -23
  58. package/styles/runes/collection.css +5 -82
  59. package/styles/runes/compare.css +3 -14
  60. package/styles/runes/comparison.css +7 -34
  61. package/styles/runes/conversation.css +5 -27
  62. package/styles/runes/cta.css +3 -26
  63. package/styles/runes/datatable.css +25 -40
  64. package/styles/runes/decision.css +3 -0
  65. package/styles/runes/design-context.css +3 -2
  66. package/styles/runes/details.css +5 -13
  67. package/styles/runes/diagram.css +5 -13
  68. package/styles/runes/diff.css +5 -88
  69. package/styles/runes/drawer.css +1 -105
  70. package/styles/runes/embed.css +4 -12
  71. package/styles/runes/event.css +3 -1
  72. package/styles/runes/expand.css +5 -40
  73. package/styles/runes/faction.css +3 -9
  74. package/styles/runes/feature.css +4 -32
  75. package/styles/runes/figure.css +5 -24
  76. package/styles/runes/file-ref.css +3 -18
  77. package/styles/runes/form.css +3 -32
  78. package/styles/runes/gallery.css +3 -135
  79. package/styles/runes/grid.css +4 -56
  80. package/styles/runes/hero.css +13 -126
  81. package/styles/runes/hint.css +16 -41
  82. package/styles/runes/howto.css +3 -25
  83. package/styles/runes/itinerary.css +3 -32
  84. package/styles/runes/juxtapose.css +12 -87
  85. package/styles/runes/lore.css +3 -10
  86. package/styles/runes/map.css +3 -36
  87. package/styles/runes/mediatext.css +3 -44
  88. package/styles/runes/milestone.css +3 -16
  89. package/styles/runes/mockup.css +15 -108
  90. package/styles/runes/nav.css +3 -178
  91. package/styles/runes/organization.css +3 -2
  92. package/styles/runes/page-section.css +3 -4
  93. package/styles/runes/pagination.css +5 -37
  94. package/styles/runes/palette.css +3 -22
  95. package/styles/runes/placeholder.css +3 -3
  96. package/styles/runes/plan-history.css +3 -23
  97. package/styles/runes/plan-progress.css +3 -4
  98. package/styles/runes/plan-ref.css +3 -0
  99. package/styles/runes/playlist.css +2 -36
  100. package/styles/runes/plot.css +3 -19
  101. package/styles/runes/preview.css +7 -25
  102. package/styles/runes/pricing.css +7 -25
  103. package/styles/runes/progress.css +6 -25
  104. package/styles/runes/pullquote.css +3 -26
  105. package/styles/runes/realm.css +3 -9
  106. package/styles/runes/recipe.css +3 -27
  107. package/styles/runes/relationships.css +3 -34
  108. package/styles/runes/reveal.css +7 -12
  109. package/styles/runes/sandbox.css +6 -36
  110. package/styles/runes/section.css +4 -18
  111. package/styles/runes/showcase.css +3 -20
  112. package/styles/runes/sidenote.css +3 -2
  113. package/styles/runes/snippet.css +3 -0
  114. package/styles/runes/spacing.css +3 -22
  115. package/styles/runes/spec.css +3 -0
  116. package/styles/runes/steps.css +4 -36
  117. package/styles/runes/storyboard.css +2 -17
  118. package/styles/runes/swatch.css +3 -6
  119. package/styles/runes/symbol.css +6 -4
  120. package/styles/runes/tabs.css +6 -9
  121. package/styles/runes/testimonial.css +5 -6
  122. package/styles/runes/textblock.css +2 -20
  123. package/styles/runes/timeline.css +3 -21
  124. package/styles/runes/tint.css +3 -0
  125. package/styles/runes/toc.css +5 -3
  126. package/styles/runes/track.css +2 -31
  127. package/styles/runes/typography.css +3 -15
  128. package/styles/runes/work.css +3 -0
  129. package/styles/runes/xref.css +3 -1
  130. package/tokens/base.css +19 -0
  131. package/tokens/dark.css +3 -0
  132. package/styles/dimensions/guest-posture.css +0 -27
@@ -1,7 +1,4 @@
1
- /* Audio */
2
- .rf-audio rf-audio {
3
- display: block;
4
- }
1
+ @layer skin {
5
2
  .rf-audio__description {
6
3
  padding: 0.75rem 1rem;
7
4
  font-size: var(--rf-text-sm);
@@ -19,22 +16,17 @@
19
16
 
20
17
  .rf-audio-player {
21
18
  padding: 1rem 1.25rem;
22
- display: flex;
23
- flex-direction: column;
24
19
  gap: 0.625rem;
25
20
  }
26
21
 
27
22
  /* Track info */
28
23
  .rf-audio-player__info {
29
- display: flex;
30
- flex-direction: column;
31
24
  gap: 0.125rem;
32
25
  }
33
26
  .rf-audio-player__name {
34
27
  font-size: var(--rf-text);
35
28
  font-weight: var(--rf-weight-semibold);
36
29
  color: var(--rf-color-text);
37
- overflow: hidden;
38
30
  text-overflow: ellipsis;
39
31
  white-space: nowrap;
40
32
  }
@@ -45,24 +37,16 @@
45
37
 
46
38
  /* Controls row */
47
39
  .rf-audio-player__controls {
48
- display: flex;
49
- align-items: center;
50
40
  gap: 0.625rem;
51
41
  }
52
42
 
53
43
  /* Play / pause button */
54
44
  .rf-audio-player__play {
55
- flex-shrink: 0;
56
- width: 2.25rem;
57
- height: 2.25rem;
58
45
  border-radius: var(--rf-radius-full, 9999px);
59
46
  border: none;
60
47
  background: var(--rf-color-primary);
61
48
  color: var(--rf-color-on-primary);
62
49
  cursor: pointer;
63
- display: flex;
64
- align-items: center;
65
- justify-content: center;
66
50
  transition: opacity 0.15s ease;
67
51
  padding: 0;
68
52
  }
@@ -78,8 +62,6 @@
78
62
  cursor: not-allowed;
79
63
  }
80
64
  .rf-audio-player__play svg {
81
- width: 1rem;
82
- height: 1rem;
83
65
  fill: currentColor;
84
66
  }
85
67
 
@@ -88,7 +70,6 @@
88
70
  font-size: var(--rf-text-xs);
89
71
  font-variant-numeric: tabular-nums;
90
72
  color: var(--rf-color-muted);
91
- min-width: 2.5rem;
92
73
  user-select: none;
93
74
  }
94
75
  .rf-audio-player__time--current {
@@ -100,51 +81,32 @@
100
81
 
101
82
  /* Progress bar */
102
83
  .rf-audio-player__progress {
103
- flex: 1;
104
- height: 6px;
105
84
  background: var(--rf-color-surface-active, #e5e7eb);
106
85
  border-radius: var(--rf-radius-full, 9999px);
107
86
  cursor: pointer;
108
- position: relative;
109
- overflow: hidden;
110
87
  }
111
88
  .rf-audio-player__progress:focus-visible {
112
89
  outline: 2px solid var(--rf-color-primary);
113
90
  outline-offset: 2px;
114
91
  }
115
92
  .rf-audio-player__progress-bar {
116
- height: 100%;
117
93
  background: var(--rf-color-primary);
118
94
  border-radius: var(--rf-radius-full, 9999px);
119
- width: 0%;
120
95
  transition: width 0.1s linear;
121
- pointer-events: none;
122
96
  }
123
97
 
124
98
  /* Waveform container */
125
99
  .rf-audio-player__waveform {
126
- width: 100%;
127
- min-height: 48px;
128
100
  border-radius: var(--rf-radius-sm, 4px);
129
- overflow: hidden;
130
- }
131
-
132
- /* Hide standard progress bar when waveform is active */
133
- .rf-audio[data-waveform="true"] .rf-audio-player__controls .rf-audio-player__progress {
134
- display: none;
135
101
  }
136
102
 
137
103
  /* Chapter list */
138
104
  .rf-audio-player__chapters {
139
- list-style: none;
140
105
  padding: 0;
141
106
  margin: 0.75rem 0 0;
142
107
  padding-top: 0;
143
108
  }
144
109
  .rf-audio-player__chapter {
145
- display: flex;
146
- width: 100%;
147
- align-items: center;
148
110
  gap: 0.75rem;
149
111
  padding: 0.375rem 0.5rem;
150
112
  border: none;
@@ -169,7 +131,6 @@
169
131
  color: var(--rf-color-primary);
170
132
  }
171
133
  .rf-audio-player__chapter-name {
172
- flex: 1;
173
134
  font-size: var(--rf-text-sm);
174
135
  font-weight: var(--rf-weight-medium);
175
136
  color: var(--rf-color-text);
@@ -178,7 +139,6 @@
178
139
  font-size: var(--rf-text-xs);
179
140
  font-variant-numeric: tabular-nums;
180
141
  color: var(--rf-color-muted);
181
- flex-shrink: 0;
182
142
  }
183
143
 
184
144
  /* Active track highlight when connected to audio player */
@@ -189,3 +149,5 @@
189
149
  .rf-track--active .rf-track__track-name {
190
150
  color: var(--rf-color-primary);
191
151
  }
152
+
153
+ }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Badge rune — standalone inline chip.
2
3
  *
3
4
  * The universal chip primitive emitted by `{% badge %}` AND by every
@@ -21,3 +22,5 @@
21
22
  border-radius: var(--rf-radius-sm);
22
23
  white-space: nowrap;
23
24
  }
25
+
26
+ }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Bar rune — composable handle for the SPEC-080 `bar` layout.
2
3
  *
3
4
  * Geometry comes from `[data-zone-layout="bar"]` in
@@ -8,3 +9,5 @@
8
9
  .rf-bar {
9
10
  margin: 0.5rem 0;
10
11
  }
12
+
13
+ }
@@ -1,81 +1,14 @@
1
- /* Bento — a grid of cells, each a card-in-a-grid-track (SPEC-085). */
2
-
3
- /* The grid responds to its OWN width, not the viewport, so it reduces columns and
4
- * stacks correctly inside any container a doc preview, a sidebar, a narrow page
5
- * track not just at viewport breakpoints. The progressive-reduction and collapse
6
- * rules below are `@container rf-bento` queries against this. */
7
- .rf-bento {
8
- container-type: inline-size;
9
- container-name: rf-bento;
10
- }
1
+ @layer skin {
2
+ /* Bento — skin. A grid of cells, each a card-in-a-grid-track (SPEC-085). The
3
+ * container-query grid system, cell flex layout, media placement, sizing knobs,
4
+ * collapse queries, and the stretched link live in @refrakt-md/skeleton
5
+ * (styles/runes/bento.css). What remains here is skin: the grid gap, the cell
6
+ * surface chrome + spacing vars, the media-well chrome, type, and bleed resets. */
11
7
 
12
8
  .rf-bento__grid {
13
- /* Effective column count: the author's `--bento-columns` (default 6),
14
- * progressively reduced at breakpoints below. A CSS variable (not the inline
15
- * `--bento-columns`) so the media queries can override it without !important. */
16
- --bento-cols-effective: var(--bento-columns, 6);
17
- display: grid;
18
- grid-template-columns: repeat(var(--bento-cols-effective), 1fr);
19
- /* Uniform fixed row tracks in grid mode — never tied to column width (which
20
- * would explode vertically on collapse). Makes row spans meaningful and bounds
21
- * tall guests instead of letting them balloon a row. When the grid collapses to
22
- * a single column it becomes a STACK, and `--bento-row-track` is flipped to
23
- * `auto` (below) so cells size to their content and text is never clipped.
24
- * `--bento-row-height` is the author's `row-height` preset (below); it falls
25
- * back to the theme default `--rf-bento-row-height`. */
26
- grid-auto-rows: var(--bento-row-track, var(--bento-row-height, var(--rf-bento-row-height, 24rem)));
27
9
  gap: var(--bento-gap, 1rem);
28
10
  }
29
11
 
30
- /* Author row-height presets — the uniform grid row track height (grid mode). */
31
- .rf-bento[data-row-height="sm"] { --bento-row-height: 16rem; }
32
- .rf-bento[data-row-height="md"] { --bento-row-height: 24rem; }
33
- .rf-bento[data-row-height="lg"] { --bento-row-height: 32rem; }
34
- .rf-bento[data-row-height="xl"] { --bento-row-height: 40rem; }
35
-
36
- /* content-height / media-ratio — perpendicular text-zone knobs, each settable as
37
- * a GRID default (on .rf-bento, inherited by every cell) or a per-CELL override
38
- * (on .rf-bento-cell, shadowing the inherited value). A cell is either a column
39
- * cell or a beside cell, so the two never collide:
40
- * • column cells (top/bottom/no-media): `content-height` pins the TEXT height;
41
- * the media zone (flex:1) absorbs the rest of the row track.
42
- * • beside cells (start/end): `media-ratio` pins the MEDIA width; the content
43
- * (flex:1) absorbs the rest of the cell width.
44
- * The cascade is pure CSS variable inheritance — grid sets the var on the
45
- * section, a cell redeclares it on itself. */
46
- .rf-bento[data-content-height="sm"], .rf-bento-cell[data-content-height="sm"] { --cell-content-height: 6rem; --cell-content-overflow: hidden; }
47
- .rf-bento[data-content-height="md"], .rf-bento-cell[data-content-height="md"] { --cell-content-height: 10rem; --cell-content-overflow: hidden; }
48
- .rf-bento[data-content-height="lg"], .rf-bento-cell[data-content-height="lg"] { --cell-content-height: 14rem; --cell-content-overflow: hidden; }
49
- .rf-bento[data-content-height="xl"], .rf-bento-cell[data-content-height="xl"] { --cell-content-height: 18rem; --cell-content-overflow: hidden; }
50
-
51
- .rf-bento[data-media-ratio="1/3"], .rf-bento-cell[data-media-ratio="1/3"] { --cell-media-ratio: 33.333%; }
52
- .rf-bento[data-media-ratio="2/5"], .rf-bento-cell[data-media-ratio="2/5"] { --cell-media-ratio: 40%; }
53
- .rf-bento[data-media-ratio="1/2"], .rf-bento-cell[data-media-ratio="1/2"] { --cell-media-ratio: 50%; }
54
- .rf-bento[data-media-ratio="3/5"], .rf-bento-cell[data-media-ratio="3/5"] { --cell-media-ratio: 60%; }
55
- .rf-bento[data-media-ratio="2/3"], .rf-bento-cell[data-media-ratio="2/3"] { --cell-media-ratio: 66.667%; }
56
-
57
- /* content-height pins the text area on COLUMN cells only (top/bottom — and
58
- * no-media cells, which default to `top`). Positive selectors keep this at the
59
- * same specificity as the mobile/collapse stack resets below, so those still win
60
- * and the text area returns to natural height when stacked. Both the basis and
61
- * the clip are gated on content-height being set (via the cascading vars): when
62
- * unset they fall back to `auto` / `visible`, so the content zone keeps its
63
- * default overflow and a bleeding showcase (negative margins) still reaches the
64
- * cell edge. The clip only engages when you actually pin the height. */
65
- .rf-bento-cell[data-media-position="top"] > .rf-bento-cell__content,
66
- .rf-bento-cell[data-media-position="bottom"] > .rf-bento-cell__content {
67
- flex-basis: var(--cell-content-height, auto);
68
- overflow: var(--cell-content-overflow, visible);
69
- }
70
-
71
- /* Cell footprint: resolved `cols`/`rows` spans, auto-capped to the effective
72
- * column count so a wide cell never overflows the (reduced) grid. */
73
- .rf-bento-cell {
74
- grid-column: span min(var(--cell-cols, 1), var(--bento-cols-effective, 6));
75
- grid-row: span var(--cell-rows, 1);
76
- min-width: 0;
77
- }
78
-
79
12
  /* The cell. `:where()` keeps the background at zero specificity so a per-cell
80
13
  * `{% tint %}` can repaint it (tint-deferrable). */
81
14
  :where(.rf-bento-cell) {
@@ -83,98 +16,52 @@
83
16
  }
84
17
  .rf-bento-cell {
85
18
  border-radius: var(--rf-radius-container);
86
- /* The cell hugs its media with only a thin edge margin; the content zone adds
87
- * the remaining inset back (below), so copy still sits at the full padding
88
- * while media — and a media banner — sits close to the cell border.
89
- * `--bento-media-gap` is the always-on space between media and content (in any
90
- * `data-media-position`), regardless of cell size; the flex gap handles both
91
- * column / column-reverse (top/bottom) and row / row-reverse (start/end). */
19
+ /* Thin-edge inset model: the cell hugs its media with a thin edge; the content
20
+ * zone adds the remaining inset back (below). */
92
21
  --container-padding: 1.25rem;
93
22
  --bento-cell-edge: 0.5rem;
94
23
  --bento-media-gap: var(--rf-spacing-md);
95
24
  padding: var(--bento-cell-edge);
96
25
  border: 1px solid var(--rf-color-border);
97
- overflow: hidden;
98
- position: relative; /* anchor for the stretched link */
99
- display: flex;
100
- flex-direction: column;
101
26
  gap: var(--bento-media-gap);
102
- min-height: 0;
103
27
  }
104
28
 
105
- /* Media placement (data-media-position): top stacks media above content (the
106
- * default flow order); bottom flips it; start/end place media beside the body. */
107
- .rf-bento-cell[data-media-position="bottom"] { flex-direction: column-reverse; }
108
- .rf-bento-cell[data-media-position="start"] { flex-direction: row; align-items: stretch; }
109
- .rf-bento-cell[data-media-position="end"] { flex-direction: row-reverse; align-items: stretch; }
29
+ /* Media slot shares the cell surface chrome (1px border + recessed well). */
30
+ :where(.rf-bento-cell) [data-section="media"] {
31
+ border: 1px solid var(--rf-color-border);
32
+ background: oklch(from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h);
33
+ }
34
+
110
35
  .rf-bento-cell[data-media-position="start"] > .rf-bento-cell__media,
111
36
  .rf-bento-cell[data-media-position="end"] > .rf-bento-cell__media {
112
- flex: 0 0 var(--cell-media-ratio, 42%);
113
37
  margin-bottom: 0;
114
- align-self: stretch;
115
38
  }
116
- .rf-bento-cell[data-media-position="start"] > .rf-bento-cell__content,
117
- .rf-bento-cell[data-media-position="end"] > .rf-bento-cell__content { flex: 1; min-width: 0; }
118
39
 
119
- /* Zones. The WORK-339 media-zone selector sizes/clips any guest — no per-guest
120
- * CSS here. */
121
40
  .rf-bento-cell__media { margin-bottom: 0; }
122
- /* Text-first: the body keeps its natural height and is never squeezed out by
123
- * media. In a fixed grid track the media zone (top/bottom) absorbs the leftover
124
- * height and crops (cover); once collapsed to a stack it becomes an aspect-ratio
125
- * banner (below). `--bento-media-aspect` is the knob SPEC-086's `frame-aspect`
126
- * will drive; `--bento-media-anchor` picks which slice shows when cropped (e.g.
127
- * `top` to peek the top of a tall guest like a phone mockup). */
41
+
128
42
  /* Add the remaining inset back on top of the cell's thin edge, so text sits at
129
- * the full `--container-padding`. The top inset doubles as the gap between media
130
- * and copy (media zone carries no margin of its own). */
43
+ * the full `--container-padding`. */
131
44
  .rf-bento-cell__content {
132
- display: flex;
133
- flex-direction: column;
134
- min-height: 0;
135
- flex: 0 0 auto;
136
45
  padding: calc(var(--container-padding) - var(--bento-cell-edge));
137
46
  }
138
- .rf-bento-cell[data-media-position="top"] > .rf-bento-cell__media,
139
- .rf-bento-cell[data-media-position="bottom"] > .rf-bento-cell__media {
140
- flex: 1 1 auto;
141
- min-height: 0;
142
- aspect-ratio: var(--bento-media-aspect, 16 / 9);
143
- }
144
- .rf-bento-cell__media > :is(img, video) { object-position: var(--bento-media-anchor, center); }
145
- /* SPEC-086 — reconcile `frame` facets with bento's existing media vars rather
146
- * than duplicating them: frame-aspect/anchor (landed on the media zone by the
147
- * engine) feed the knobs bento already consumes (incl. the collapse path). */
148
- .rf-bento-cell__media[style*="--frame-aspect"] { --bento-media-aspect: var(--frame-aspect); }
149
- .rf-bento-cell__media[style*="--frame-anchor"] { --bento-media-anchor: var(--frame-anchor); }
150
47
  .rf-bento-cell__title {
151
48
  font-size: var(--rf-text-lg);
152
49
  font-weight: var(--rf-weight-semibold);
153
50
  margin: 0 0 0.5rem;
154
51
  }
155
- .rf-bento-cell__body { min-height: 0; }
156
- .rf-bento-cell__body > span[property],
157
- .rf-bento-cell__body > meta { display: none; }
158
52
  .rf-bento-cell__body > :first-child { margin-top: 0; }
159
53
  .rf-bento-cell__body p:last-child { margin-bottom: 0; }
160
54
  .rf-bento-cell__footer {
161
- margin-top: auto;
162
55
  padding-top: 0.5rem;
163
56
  border-top: 1px solid var(--rf-color-border);
164
57
  font-size: 0.8125em;
165
58
  color: var(--rf-color-muted);
166
59
  }
167
60
  .rf-bento-cell__body img {
168
- width: 100%;
169
- height: auto;
170
61
  border-radius: var(--rf-radius-sm);
171
62
  margin-bottom: 0.75rem;
172
63
  }
173
64
 
174
- /* Whole-cell link — stretched overlay; nested links stay clickable. */
175
- .rf-bento-cell__link { position: absolute; inset: 0; z-index: 0; }
176
- .rf-bento-cell a:not(.rf-bento-cell__link) { position: relative; z-index: 1; }
177
-
178
65
  /* Drop padding on bleed edges when a showcase bleeds (clipped to a peek by
179
66
  * the media-zone + cell overflow). */
180
67
  .rf-bento-cell:has(.rf-showcase[data-bleed="bottom"]),
@@ -187,34 +74,4 @@
187
74
  .rf-bento-cell:has(.rf-showcase[data-bleed="both"]),
188
75
  .rf-bento-cell:has(.rf-showcase[data-bleed="top-end"]) { padding-top: 0; }
189
76
 
190
- /* ─── Binary collapse ─── Above the chosen breakpoint, the grid renders exactly
191
- * as authored: `columns` and per-cell `cols`/`rows` are honored (span auto-cap
192
- * above still keeps wide cells inside the grid). Below it, the grid drops to a
193
- * single stacked column with auto row tracks (cells size to content, never
194
- * clipped). Default = `sm` (640px), so phones stack but tablet-portrait and up
195
- * keep the grid. Authors who want graceful column reduction between desktop and
196
- * stack can opt in via `collapse="gradual"` (not yet implemented). */
197
- @container rf-bento (max-width: 640px) {
198
- /* `[data-collapse=""]` matches the unset (default) case — the engine emits
199
- * the attribute with an empty value when the author doesn't set it, so a bare
200
- * `:not([data-collapse])` wouldn't match. */
201
- :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento__grid { --bento-cols-effective: 1; --bento-row-track: auto; }
202
- :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position="start"],
203
- :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position="end"] { flex-direction: column; }
204
- :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position] > .rf-bento-cell__media { flex: 0 0 auto; aspect-ratio: var(--bento-media-aspect, 16 / 9); }
205
- :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position] > .rf-bento-cell__content { flex: 0 0 auto; }
206
- }
207
- @container rf-bento (max-width: 768px) {
208
- .rf-bento[data-collapse="md"] .rf-bento__grid { --bento-cols-effective: 1; --bento-row-track: auto; }
209
- .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position="start"],
210
- .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position="end"] { flex-direction: column; }
211
- .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position] > .rf-bento-cell__media { flex: 0 0 auto; aspect-ratio: var(--bento-media-aspect, 16 / 9); }
212
- .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position] > .rf-bento-cell__content { flex: 0 0 auto; }
213
- }
214
- @container rf-bento (max-width: 1024px) {
215
- .rf-bento[data-collapse="lg"] .rf-bento__grid { --bento-cols-effective: 1; --bento-row-track: auto; }
216
- .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position="start"],
217
- .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position="end"] { flex-direction: column; }
218
- .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position] > .rf-bento-cell__media { flex: 0 0 auto; aspect-ratio: var(--bento-media-aspect, 16 / 9); }
219
- .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position] > .rf-bento-cell__content { flex: 0 0 auto; }
220
77
  }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Background — Directive rune for background images, video, overlays, blur */
2
3
 
3
4
  /* Background layer — absolute positioned behind content. `border-radius:
@@ -6,10 +7,6 @@
6
7
  * without needing `overflow: hidden` (though hosts with thin-edge padding
7
8
  * still need it so the bg can't poke past the rounded outer edge). */
8
9
  [data-name="bg"] {
9
- position: absolute;
10
- inset: 0;
11
- z-index: 0;
12
- overflow: hidden;
13
10
  border-radius: inherit;
14
11
  background-image: var(--bg-image);
15
12
  background-size: var(--bg-fit, cover);
@@ -27,51 +24,18 @@
27
24
  [data-name="bg"][data-bg-fixed] {
28
25
  background-attachment: fixed;
29
26
  }
30
- /* Content above background — any sibling of the bg layer gets `z-index: 1`
31
- * so it stacks over the `data-name="bg"` layer (which sits at `z-index: 0`).
32
- * Keyed off the `data-bg` attribute the engine emits on the bg-owning rune
33
- * (`engine.ts` → `bgDataAttrs['data-bg'] = ''`), not the per-block BEM
34
- * modifier class `rf-<block>--has-bg` — the attribute is rune-agnostic so
35
- * one rule covers card, bento-cell, hero, feature, and anything else that
36
- * raises a bg layer. */
37
- [data-bg] > :not([data-name="bg"]) {
38
- position: relative;
39
- z-index: 1;
40
- }
41
- /* Video background */
42
- [data-name="bg-video"] {
43
- width: 100%;
44
- height: 100%;
45
- object-fit: cover;
46
- object-position: var(--bg-position, center);
47
- }
48
27
  [data-name="bg-video"][style*="--bg-blur"] {
49
28
  filter: blur(var(--bg-blur));
50
29
  }
51
30
  [data-name="bg-video"][style*="--bg-opacity"] {
52
31
  opacity: var(--bg-opacity);
53
32
  }
54
- /* Overlay */
55
- [data-name="bg-overlay"] {
56
- position: absolute;
57
- inset: 0;
58
- }
59
33
  [data-name="bg-overlay"][data-bg-overlay="dark"] {
60
34
  background: rgba(0, 0, 0, 0.5);
61
35
  }
62
36
  [data-name="bg-overlay"][data-bg-overlay="light"] {
63
37
  background: rgba(255, 255, 255, 0.6);
64
38
  }
65
-
66
- /* Scrim (SPEC-088) — a structured legibility treatment behind overlaid text.
67
- * gradient: a directional darken/lighten; frost: a backdrop blur + tint.
68
- * `tone` picks the colour, `dir` the heavy edge; strength/blur come inline. */
69
- [data-name="scrim"] {
70
- position: absolute;
71
- inset: 0;
72
- pointer-events: none;
73
- z-index: 1;
74
- }
75
39
  [data-name="scrim"][data-scrim-tone="dark"] { --scrim-color: 0 0 0; }
76
40
  [data-name="scrim"][data-scrim-tone="light"] { --scrim-color: 255 255 255; }
77
41
  [data-name="scrim"][data-scrim-dir="top"] { --scrim-grad-dir: to top; }
@@ -86,3 +50,5 @@
86
50
  backdrop-filter: blur(var(--scrim-blur, 8px));
87
51
  background: rgb(var(--scrim-color, 0 0 0) / 0.18);
88
52
  }
53
+
54
+ }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Blog — post listing with filtering and sorting */
2
3
  .rf-blog {
3
4
  padding: 2rem 0;
@@ -21,8 +22,6 @@
21
22
  max-width: 640px;
22
23
  }
23
24
  .rf-blog__posts {
24
- display: flex;
25
- flex-direction: column;
26
25
  gap: 1.5rem;
27
26
  }
28
27
  .rf-blog__post {
@@ -48,7 +47,6 @@
48
47
  color: var(--rf-color-primary);
49
48
  }
50
49
  .rf-blog__post time {
51
- display: inline-block;
52
50
  font-size: var(--rf-text-sm);
53
51
  color: var(--rf-color-muted);
54
52
  margin-bottom: 0.5rem;
@@ -62,8 +60,6 @@
62
60
 
63
61
  /* Grid layout */
64
62
  .rf-blog--grid .rf-blog__posts {
65
- display: grid;
66
- grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
67
63
  gap: 1.25rem;
68
64
  }
69
65
 
@@ -92,3 +88,5 @@
92
88
  font-size: var(--rf-text-xs);
93
89
  margin-bottom: 0.25rem;
94
90
  }
91
+
92
+ }
@@ -1,8 +1,6 @@
1
+ @layer skin {
1
2
  /* Bond */
2
3
  .rf-bond {
3
- display: flex;
4
- flex-wrap: wrap;
5
- align-items: center;
6
4
  gap: 0.75rem;
7
5
  }
8
6
  .rf-bond > span[property="from"],
@@ -12,38 +10,18 @@
12
10
  color: var(--rf-color-text);
13
11
  white-space: nowrap;
14
12
  }
15
- .rf-bond__connector {
16
- display: flex;
17
- align-items: center;
18
- flex-shrink: 0;
19
- }
20
13
  .rf-bond__arrow {
21
- display: inline-block;
22
- width: 2rem;
23
- height: 2px;
24
14
  background: var(--rf-color-border);
25
- position: relative;
26
15
  }
27
16
  .rf-bond__arrow::after {
28
- content: '';
29
- position: absolute;
30
- right: -1px;
31
- top: 50%;
32
- transform: translateY(-50%);
33
17
  border: 4px solid transparent;
34
18
  border-left: 6px solid var(--rf-color-border);
35
19
  }
36
20
  .rf-bond[data-bidirectional="true"] .rf-bond__arrow::before {
37
- content: '';
38
- position: absolute;
39
- left: -1px;
40
- top: 50%;
41
- transform: translateY(-50%);
42
21
  border: 4px solid transparent;
43
22
  border-right: 6px solid var(--rf-color-border);
44
23
  }
45
24
  .rf-bond__body {
46
- width: 100%;
47
25
  font-size: var(--rf-text-sm);
48
26
  color: var(--rf-color-muted);
49
27
  }
@@ -72,3 +50,5 @@
72
50
  .rf-bond[data-status="broken"] {
73
51
  opacity: 0.6;
74
52
  }
53
+
54
+ }
@@ -1,26 +1,16 @@
1
- /* Breadcrumb */
1
+ @layer skin {
2
+ /* Breadcrumb — skin. The contents passthroughs + the flex trail live in
3
+ * @refrakt-md/skeleton (styles/runes/breadcrumb.css). */
2
4
  .rf-breadcrumb {
3
5
  font-size: var(--rf-text-sm);
4
6
  margin: 0 0 1.5rem;
5
7
  }
6
- .rf-breadcrumb__items {
7
- display: contents;
8
- }
9
- .rf-breadcrumb-item {
10
- display: contents;
11
- }
12
8
  .rf-breadcrumb ol {
13
- display: flex;
14
- align-items: center;
15
- flex-wrap: wrap;
16
9
  gap: 0.25rem;
17
- list-style: none;
18
10
  padding: 0;
19
11
  margin: 0;
20
12
  }
21
13
  .rf-breadcrumb li {
22
- display: flex;
23
- align-items: center;
24
14
  gap: 0.25rem;
25
15
  padding: 0;
26
16
  margin: 0;
@@ -44,3 +34,5 @@
44
34
  color: var(--rf-color-text);
45
35
  font-weight: var(--rf-weight-medium);
46
36
  }
37
+
38
+ }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Budget */
2
3
 
3
4
  /* Duration + currency meta row — flex/gap from the shared
@@ -28,8 +29,6 @@
28
29
 
29
30
  /* Categories */
30
31
  .rf-budget__categories {
31
- display: flex;
32
- flex-direction: column;
33
32
  gap: 1.5rem;
34
33
  }
35
34
 
@@ -42,9 +41,6 @@
42
41
  padding-left: 1rem;
43
42
  }
44
43
  .rf-budget-category__header {
45
- display: flex;
46
- justify-content: space-between;
47
- align-items: center;
48
44
  margin-bottom: 0.5rem;
49
45
  }
50
46
  .rf-budget-category--estimate .rf-budget-category__subtotal::before {
@@ -72,16 +68,12 @@
72
68
  white-space: nowrap;
73
69
  }
74
70
  .rf-budget-category__line-items {
75
- list-style: none;
76
71
  padding: 0;
77
72
  margin: 0;
78
73
  }
79
74
 
80
75
  /* Budget Line Item */
81
76
  .rf-budget-line-item {
82
- display: flex;
83
- justify-content: space-between;
84
- align-items: baseline;
85
77
  padding: 0.3125rem 0;
86
78
  gap: 1rem;
87
79
  }
@@ -91,8 +83,6 @@
91
83
  .rf-budget-line-item__description {
92
84
  font-size: var(--rf-text-sm);
93
85
  color: var(--rf-color-muted);
94
- flex: 1;
95
- min-width: 0;
96
86
  }
97
87
  .rf-budget-line-item__amount {
98
88
  font-size: var(--rf-text-sm);
@@ -107,14 +97,9 @@
107
97
  margin-top: 1.5rem;
108
98
  padding-top: 1rem;
109
99
  border-top: 2px solid var(--rf-color-text);
110
- display: flex;
111
- flex-direction: column;
112
100
  gap: 0.5rem;
113
101
  }
114
102
  .rf-budget__total {
115
- display: flex;
116
- justify-content: space-between;
117
- align-items: baseline;
118
103
  gap: 1rem;
119
104
  }
120
105
  .rf-budget__total-label {
@@ -130,15 +115,11 @@
130
115
  font-variant-numeric: tabular-nums;
131
116
  }
132
117
  .rf-budget__per-day {
133
- display: flex;
134
- justify-content: space-between;
135
- align-items: baseline;
136
118
  gap: 1rem;
137
119
  }
138
120
  .rf-budget__per-day-label {
139
121
  font-size: var(--rf-text-sm);
140
122
  color: var(--rf-color-muted);
141
- min-width: 0;
142
123
  }
143
124
  .rf-budget__per-day-amount {
144
125
  font-size: var(--rf-text);
@@ -147,11 +128,8 @@
147
128
  white-space: nowrap;
148
129
  font-variant-numeric: tabular-nums;
149
130
  }
150
-
151
- /* Summary style — hide line items, show only category headers */
152
- [data-variant="summary"] .rf-budget-category__line-items {
153
- display: none;
154
- }
155
131
  [data-variant="summary"] .rf-budget-category__header {
156
132
  margin-bottom: 0;
157
133
  }
134
+
135
+ }