@refrakt-md/lumina 0.7.2 → 0.8.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.
package/dist/config.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- /** Lumina theme configuration — extends base with icon SVGs */
1
+ /** Lumina theme configuration — extends base with icon SVGs and tint presets */
2
2
  export declare const luminaConfig: import("@refrakt-md/transform").ThemeConfig;
3
3
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,+DAA+D;AAC/D,eAAO,MAAM,YAAY,6CAUvB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,gFAAgF;AAChF,eAAO,MAAM,YAAY,6CAoFvB,CAAC"}
package/dist/config.js CHANGED
@@ -1,8 +1,82 @@
1
1
  import { baseConfig } from '@refrakt-md/runes';
2
2
  import { mergeThemeConfig } from '@refrakt-md/transform';
3
3
  import { icons as lucideIcons } from './icons.js';
4
- /** Lumina theme configuration — extends base with icon SVGs */
4
+ /** Lumina theme configuration — extends base with icon SVGs and tint presets */
5
5
  export const luminaConfig = mergeThemeConfig(baseConfig, {
6
+ tints: {
7
+ base: {
8
+ light: {
9
+ background: '#ffffff',
10
+ surface: '#f8fafc',
11
+ primary: '#1a1a2e',
12
+ secondary: '#64748b',
13
+ accent: '#0ea5e9',
14
+ border: '#e2e8f0',
15
+ },
16
+ dark: {
17
+ background: '#0c1222',
18
+ surface: '#0f172a',
19
+ primary: '#e2e8f0',
20
+ secondary: '#94a3b8',
21
+ accent: '#38bdf8',
22
+ border: 'rgba(255, 255, 255, 0.1)',
23
+ },
24
+ },
25
+ subtle: {
26
+ light: {
27
+ background: '#f8f9fb',
28
+ surface: '#f8fafc',
29
+ primary: '#1a1a2e',
30
+ secondary: '#64748b',
31
+ accent: '#0ea5e9',
32
+ border: '#e2e8f0',
33
+ },
34
+ dark: {
35
+ background: '#111827',
36
+ surface: '#0f172a',
37
+ primary: '#e2e8f0',
38
+ secondary: '#94a3b8',
39
+ accent: '#38bdf8',
40
+ border: 'rgba(255, 255, 255, 0.1)',
41
+ },
42
+ },
43
+ warm: {
44
+ light: {
45
+ background: '#fdf6e3',
46
+ primary: '#5c4a32',
47
+ accent: '#c47d3b',
48
+ border: '#e0d5c0',
49
+ },
50
+ dark: {
51
+ background: '#2a2118',
52
+ primary: '#e8d5b7',
53
+ accent: '#e0a86e',
54
+ border: '#4a3f33',
55
+ },
56
+ },
57
+ cool: {
58
+ light: {
59
+ background: '#f0f4ff',
60
+ primary: '#1e3a5f',
61
+ accent: '#3b82f6',
62
+ border: '#c7d7f0',
63
+ },
64
+ dark: {
65
+ background: '#0f1a2e',
66
+ primary: '#c7d7f0',
67
+ accent: '#60a5fa',
68
+ border: '#1e3a5f',
69
+ },
70
+ },
71
+ dark: {
72
+ mode: 'dark',
73
+ dark: {
74
+ background: '#1a1a2e',
75
+ primary: '#e0e0e0',
76
+ accent: '#e94560',
77
+ },
78
+ },
79
+ },
6
80
  icons: {
7
81
  hint: {
8
82
  note: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>',
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AAElD,+DAA+D;AAC/D,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC,UAAU,EAAE;IACxD,KAAK,EAAE;QACN,IAAI,EAAE;YACL,IAAI,EAAE,4SAA4S;YAClT,OAAO,EAAE,iXAAiX;YAC1X,OAAO,EAAE,uSAAuS;YAChT,KAAK,EAAE,qRAAqR;SAC5R;QACD,MAAM,EAAE,WAAW;KACnB;CACD,CAAC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AAElD,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC,UAAU,EAAE;IACxD,KAAK,EAAE;QACN,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aACjB;YACD,IAAI,EAAE;gBACL,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,0BAA0B;aAClC;SACD;QACD,MAAM,EAAE;YACP,KAAK,EAAE;gBACN,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aACjB;YACD,IAAI,EAAE;gBACL,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,0BAA0B;aAClC;SACD;QACD,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aACjB;YACD,IAAI,EAAE;gBACL,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aACjB;SACD;QACD,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aACjB;YACD,IAAI,EAAE;gBACL,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aACjB;SACD;QACD,IAAI,EAAE;YACL,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE;gBACL,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,SAAS;aACjB;SACD;KACD;IACD,KAAK,EAAE;QACN,IAAI,EAAE;YACL,IAAI,EAAE,4SAA4S;YAClT,OAAO,EAAE,iXAAiX;YAC1X,OAAO,EAAE,uSAAuS;YAChT,KAAK,EAAE,qRAAqR;SAC5R;QACD,MAAM,EAAE,WAAW;KACnB;CACD,CAAC,CAAC"}
package/index.css CHANGED
@@ -20,10 +20,15 @@
20
20
  @import './styles/layouts/on-this-page.css';
21
21
  @import './styles/layouts/search.css';
22
22
  @import './styles/layouts/version-switcher.css';
23
+ @import './styles/layouts/split.css';
24
+
25
+ /* Universal Rune Attributes */
26
+ @import './styles/base/attributes.css';
23
27
 
24
28
  /* Runes */
25
29
  @import './styles/runes/accordion.css';
26
30
  @import './styles/runes/annotate.css';
31
+ @import './styles/runes/audio.css';
27
32
  @import './styles/runes/api.css';
28
33
  @import './styles/runes/bento.css';
29
34
  @import './styles/runes/bond.css';
@@ -47,6 +52,7 @@
47
52
  @import './styles/runes/faction.css';
48
53
  @import './styles/runes/feature.css';
49
54
  @import './styles/runes/figure.css';
55
+ @import './styles/runes/gallery.css';
50
56
  @import './styles/runes/form.css';
51
57
  @import './styles/runes/grid.css';
52
58
  @import './styles/runes/hero.css';
@@ -59,6 +65,7 @@
59
65
  @import './styles/runes/nav.css';
60
66
  @import './styles/runes/organization.css';
61
67
  @import './styles/runes/page-section.css';
68
+ @import './styles/runes/playlist.css';
62
69
  @import './styles/runes/plot.css';
63
70
  @import './styles/runes/preview.css';
64
71
  @import './styles/runes/pricing.css';
@@ -74,6 +81,7 @@
74
81
  @import './styles/runes/testimonial.css';
75
82
  @import './styles/runes/timeline.css';
76
83
  @import './styles/runes/toc.css';
84
+ @import './styles/runes/track.css';
77
85
  @import './styles/runes/swatch.css';
78
86
  @import './styles/runes/palette.css';
79
87
  @import './styles/runes/typography.css';
@@ -82,3 +90,6 @@
82
90
  @import './styles/runes/pullquote.css';
83
91
  @import './styles/runes/textblock.css';
84
92
  @import './styles/runes/mediatext.css';
93
+ @import './styles/runes/tint.css';
94
+ @import './styles/runes/showcase.css';
95
+ @import './styles/runes/bg.css';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@refrakt-md/lumina",
3
3
  "description": "Lumina theme for refrakt.md — design tokens, CSS, identity transform, and framework adapters",
4
- "version": "0.7.2",
4
+ "version": "0.8.0",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -46,10 +46,10 @@
46
46
  "build": "tsc"
47
47
  },
48
48
  "dependencies": {
49
- "@refrakt-md/runes": "0.7.2",
50
- "@refrakt-md/transform": "0.7.2",
51
- "@refrakt-md/types": "0.7.2",
52
- "@refrakt-md/svelte": "0.7.2"
49
+ "@refrakt-md/runes": "0.8.0",
50
+ "@refrakt-md/transform": "0.8.0",
51
+ "@refrakt-md/types": "0.8.0",
52
+ "@refrakt-md/svelte": "0.8.0"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "svelte": "^5.0.0",
@@ -0,0 +1,20 @@
1
+ /* Universal Rune Attributes — spacing & inset
2
+ *
3
+ * Compound attribute selectors [data-rune][data-*] give specificity (0,2,0):
4
+ * - Overrides rune defaults like .rf-itinerary { margin: 2rem 0 } at (0,1,0)
5
+ * - Overridden by layout-level rules in default.css at (0,2,1)
6
+ * - Per-rune overrides (e.g. showcase) win via source order (loaded after) */
7
+
8
+ /* ── Spacing — vertical rhythm ─────────────────────────────────────── */
9
+
10
+ [data-rune][data-spacing="flush"] { margin-top: 0; margin-bottom: 0; }
11
+ [data-rune][data-spacing="tight"] { margin-top: var(--rf-spacing-section-tight, 1.5rem); margin-bottom: var(--rf-spacing-section-tight, 1.5rem); }
12
+ [data-rune][data-spacing="loose"] { margin-top: var(--rf-spacing-section-loose, 8rem); margin-bottom: var(--rf-spacing-section-loose, 8rem); }
13
+ [data-rune][data-spacing="breathe"] { margin-top: var(--rf-spacing-section-breathe, 12rem); margin-bottom: var(--rf-spacing-section-breathe, 12rem); }
14
+
15
+ /* ── Inset — horizontal padding ────────────────────────────────────── */
16
+
17
+ [data-rune][data-inset="flush"] { padding-inline: 0; }
18
+ [data-rune][data-inset="tight"] { padding-inline: var(--rf-inset-tight, 1rem); }
19
+ [data-rune][data-inset="loose"] { padding-inline: var(--rf-inset-loose, 4rem); }
20
+ [data-rune][data-inset="breathe"] { padding-inline: var(--rf-inset-breathe, 8rem); }
package/styles/global.css CHANGED
@@ -27,8 +27,8 @@ h1, h2, h3, h4, h5, h6 {
27
27
  letter-spacing: -0.015em;
28
28
  }
29
29
 
30
- h1 { font-size: 2rem; font-weight: 700; letter-spacing: -0.025em; }
31
- h2 { font-size: 1.5rem; }
30
+ h1 { font-size: 2rem; font-weight: 400; letter-spacing: -0.025em; }
31
+ h2 { font-size: 2.5rem; font-weight: 400; }
32
32
  h3 { font-size: 1.25rem; }
33
33
  h4 { font-size: 1.1rem; }
34
34
 
@@ -1,5 +1,9 @@
1
1
  /* Default layout */
2
2
  .rf-header {
3
+ position: sticky;
4
+ top: 0;
5
+ z-index: 100;
6
+ background: var(--rf-color-bg);
3
7
  border-bottom: 1px solid var(--rf-color-border);
4
8
  }
5
9
  .rf-header__inner {
@@ -57,15 +61,137 @@
57
61
  vertical-align: -0.15em;
58
62
  }
59
63
  .rf-page-content {
64
+ --rf-content-max: 80rem;
65
+ --rf-content-gutter: 1.5rem;
66
+
60
67
  padding-top: 2.5rem;
61
68
  padding-bottom: 4rem;
62
- max-width: 64rem;
63
- margin: 0 auto;
64
- padding-left: 1.5rem;
65
- padding-right: 1.5rem;
66
- --rf-content-padding: 1.5rem;
67
69
  container-type: inline-size;
68
70
  }
71
+ /* Markdoc wraps content in <article>; make it the grid container.
72
+ 5-track named grid: full | wide | content | wide | full */
73
+ .rf-page-content > article {
74
+ display: grid;
75
+ grid-template-columns:
76
+ [full-start] 1fr
77
+ [wide-start] minmax(0, var(--rf-wide-inset, 8rem))
78
+ [content-start] min(var(--rf-content-max), 100% - var(--rf-content-gutter) * 2)
79
+ [content-end] minmax(0, var(--rf-wide-inset, 8rem))
80
+ [wide-end] 1fr
81
+ [full-end];
82
+ }
83
+ .rf-page-content > article > * {
84
+ grid-column: content;
85
+ }
86
+
87
+ /* Width constraint via data-width attribute — narrower than content */
88
+ .rf-page-content > article > [data-width="compact"] {
89
+ max-width: var(--rf-width-compact, 30rem);
90
+ margin-inline: auto;
91
+ }
92
+ .rf-page-content > article > [data-width="narrow"] {
93
+ max-width: var(--rf-width-narrow, 40rem);
94
+ margin-inline: auto;
95
+ }
96
+ /* Width breakout via data-width attribute — wider than content */
97
+ .rf-page-content > article > [data-width="wide"] {
98
+ grid-column: wide;
99
+ }
100
+ .rf-page-content > article > [data-width="full"] {
101
+ grid-column: full;
102
+ padding-inline: max(
103
+ var(--rf-content-gutter, 1.5rem),
104
+ calc((100% - var(--rf-content-max, 80rem)) / 2)
105
+ );
106
+ }
107
+ /* Tinted sections also break out to full width */
108
+ .rf-page-content > article > :is([data-tint], [data-color-scheme]):not([data-width]) {
109
+ grid-column: full;
110
+ padding-inline: max(
111
+ var(--rf-content-gutter, 1.5rem),
112
+ calc((100% - var(--rf-content-max, 80rem)) / 2)
113
+ );
114
+ }
115
+
116
+ /* Section spacing — vertical rhythm between block runes
117
+ * Symmetric margins collapse between plain sections (no visual change)
118
+ * but ensure correct gaps at plain→tinted boundaries (where tinted
119
+ * sections use padding instead of margin). */
120
+ .rf-page-content > article > * + * {
121
+ margin-top: var(--rf-spacing-section, 4rem);
122
+ margin-bottom: var(--rf-spacing-section, 4rem);
123
+ }
124
+ .rf-page-content > article > [data-spacing="flush"] {
125
+ margin-top: 0;
126
+ margin-bottom: 0;
127
+ }
128
+ .rf-page-content > article > [data-spacing="tight"] {
129
+ margin-top: var(--rf-spacing-section-tight, 1.5rem);
130
+ margin-bottom: var(--rf-spacing-section-tight, 1.5rem);
131
+ }
132
+ .rf-page-content > article > [data-spacing="loose"] {
133
+ margin-top: var(--rf-spacing-section-loose, 8rem);
134
+ margin-bottom: var(--rf-spacing-section-loose, 8rem);
135
+ }
136
+ .rf-page-content > article > [data-spacing="breathe"] {
137
+ margin-top: var(--rf-spacing-section-breathe, 12rem);
138
+ margin-bottom: var(--rf-spacing-section-breathe, 12rem);
139
+ }
140
+
141
+ /* Spacing on tinted/dark sections — use padding so space is inside the painted background */
142
+ .rf-page-content > article > :is([data-color-scheme], [data-tint])[data-spacing="flush"] {
143
+ margin-top: 0;
144
+ margin-bottom: 0;
145
+ padding-top: 0;
146
+ padding-bottom: 0;
147
+ }
148
+ .rf-page-content > article > :is([data-color-scheme], [data-tint])[data-spacing="tight"] {
149
+ margin-top: 0;
150
+ margin-bottom: 0;
151
+ padding-top: var(--rf-spacing-section-tight, 1.5rem);
152
+ padding-bottom: var(--rf-spacing-section-tight, 1.5rem);
153
+ }
154
+ .rf-page-content > article > :is([data-color-scheme], [data-tint])[data-spacing="default"],
155
+ .rf-page-content > article > :is([data-color-scheme], [data-tint]):not([data-spacing]) {
156
+ margin-top: 0;
157
+ margin-bottom: 0;
158
+ padding-top: var(--rf-spacing-section, 4rem);
159
+ padding-bottom: var(--rf-spacing-section, 4rem);
160
+ }
161
+ .rf-page-content > article > :is([data-color-scheme], [data-tint])[data-spacing="loose"] {
162
+ margin-top: 0;
163
+ margin-bottom: 0;
164
+ padding-top: var(--rf-spacing-section-loose, 8rem);
165
+ padding-bottom: var(--rf-spacing-section-loose, 8rem);
166
+ }
167
+ .rf-page-content > article > :is([data-color-scheme], [data-tint])[data-spacing="breathe"] {
168
+ margin-top: 0;
169
+ margin-bottom: 0;
170
+ padding-top: var(--rf-spacing-section-breathe, 12rem);
171
+ padding-bottom: var(--rf-spacing-section-breathe, 12rem);
172
+ }
173
+
174
+ /* Inset — horizontal padding within block runes */
175
+ .rf-page-content > article > [data-inset="flush"] {
176
+ padding-inline: 0;
177
+ }
178
+ .rf-page-content > article > [data-inset="tight"] {
179
+ padding-inline: var(--rf-inset-tight, 1rem);
180
+ }
181
+ .rf-page-content > article > [data-inset="loose"] {
182
+ padding-inline: var(--rf-inset-loose, 4rem);
183
+ }
184
+ .rf-page-content > article > [data-inset="breathe"] {
185
+ padding-inline: var(--rf-inset-breathe, 8rem);
186
+ }
187
+
188
+ /* Collapse top/bottom padding when a full-bleed section is first/last */
189
+ .rf-page-content:has(> article > :first-child:is([data-width="full"], [data-tint])) {
190
+ padding-top: 0;
191
+ }
192
+ .rf-page-content:has(> article > :last-child:is([data-width="full"], [data-tint])) {
193
+ padding-bottom: 0;
194
+ }
69
195
 
70
196
  @media (max-width: 768px) {
71
197
  .rf-header__inner p ~ p {
@@ -0,0 +1,34 @@
1
+ /* Shared split layout — used by Feature, Hero, Step, and any rune with data-layout */
2
+
3
+ [data-layout="split"],
4
+ [data-layout="split-reverse"] {
5
+ display: grid;
6
+ grid-template-columns: var(--split-ratio, 1fr 1fr);
7
+ align-items: var(--split-valign, start);
8
+ gap: var(--split-gap, var(--rf-spacing-lg));
9
+ }
10
+
11
+ [data-layout="split-reverse"] > [data-name="content"] { order: 2; }
12
+ [data-layout="split-reverse"] > [data-name="media"] { order: 1; }
13
+
14
+ /* Grid so children can use justify-self/align-self (default: stretch) */
15
+ [data-layout="split"] > [data-name="media"],
16
+ [data-layout="split-reverse"] > [data-name="media"] {
17
+ display: grid;
18
+ }
19
+
20
+ /* Collapse breakpoints */
21
+ @media (max-width: 640px) {
22
+ [data-layout^="split"][data-collapse="sm"] { grid-template-columns: 1fr; }
23
+ [data-layout^="split"][data-collapse="sm"] > * { order: unset; }
24
+ }
25
+
26
+ @media (max-width: 768px) {
27
+ [data-layout^="split"][data-collapse="md"] { grid-template-columns: 1fr; }
28
+ [data-layout^="split"][data-collapse="md"] > * { order: unset; }
29
+ }
30
+
31
+ @media (max-width: 1024px) {
32
+ [data-layout^="split"][data-collapse="lg"] { grid-template-columns: 1fr; }
33
+ [data-layout^="split"][data-collapse="lg"] > * { order: unset; }
34
+ }
@@ -73,8 +73,8 @@
73
73
  display: block;
74
74
  }
75
75
  .rf-annotate-note__body p:last-child { margin-bottom: 0; }
76
- .rf-annotate-note__body span[property],
77
- .rf-annotate-note__body meta { display: none; }
76
+ .rf-annotate-note__body > span[property],
77
+ .rf-annotate-note__body > meta { display: none; }
78
78
  @media (max-width: 768px) {
79
79
  .rf-annotate--margin .rf-annotate-note {
80
80
  float: none;
@@ -0,0 +1,199 @@
1
+ /* Audio */
2
+ .rf-audio {
3
+ margin: 1.5rem 0;
4
+ border: 1px solid var(--rf-color-border);
5
+ border-radius: var(--rf-radius-md);
6
+ overflow: hidden;
7
+ }
8
+ .rf-audio rf-audio {
9
+ display: block;
10
+ }
11
+ .rf-audio__description {
12
+ padding: 0.75rem 1rem;
13
+ font-size: 0.875rem;
14
+ color: var(--rf-color-muted);
15
+ border-top: 1px solid var(--rf-color-border);
16
+ line-height: 1.5;
17
+ }
18
+ .rf-audio__description p {
19
+ margin: 0;
20
+ }
21
+ .rf-audio__description p + p {
22
+ margin-top: 0.5rem;
23
+ }
24
+
25
+ /* ── Audio Player (web component internals) ── */
26
+
27
+ .rf-audio-player {
28
+ padding: 1rem 1.25rem;
29
+ display: flex;
30
+ flex-direction: column;
31
+ gap: 0.625rem;
32
+ }
33
+
34
+ /* Track info */
35
+ .rf-audio-player__info {
36
+ display: flex;
37
+ flex-direction: column;
38
+ gap: 0.125rem;
39
+ }
40
+ .rf-audio-player__name {
41
+ font-size: 0.9375rem;
42
+ font-weight: 600;
43
+ color: var(--rf-color-text);
44
+ overflow: hidden;
45
+ text-overflow: ellipsis;
46
+ white-space: nowrap;
47
+ }
48
+ .rf-audio-player__artist {
49
+ font-size: 0.8125rem;
50
+ color: var(--rf-color-muted);
51
+ }
52
+
53
+ /* Controls row */
54
+ .rf-audio-player__controls {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: 0.625rem;
58
+ }
59
+
60
+ /* Play / pause button */
61
+ .rf-audio-player__play {
62
+ flex-shrink: 0;
63
+ width: 2.25rem;
64
+ height: 2.25rem;
65
+ border-radius: var(--rf-radius-full, 9999px);
66
+ border: none;
67
+ background: var(--rf-color-primary);
68
+ color: #fff;
69
+ cursor: pointer;
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ transition: opacity 0.15s ease;
74
+ padding: 0;
75
+ }
76
+ .rf-audio-player__play:hover {
77
+ opacity: 0.85;
78
+ }
79
+ .rf-audio-player__play:focus-visible {
80
+ outline: 2px solid var(--rf-color-primary);
81
+ outline-offset: 2px;
82
+ }
83
+ .rf-audio-player__play:disabled {
84
+ opacity: 0.4;
85
+ cursor: not-allowed;
86
+ }
87
+ .rf-audio-player__play svg {
88
+ width: 1rem;
89
+ height: 1rem;
90
+ fill: currentColor;
91
+ }
92
+
93
+ /* Time displays */
94
+ .rf-audio-player__time {
95
+ font-size: 0.75rem;
96
+ font-variant-numeric: tabular-nums;
97
+ color: var(--rf-color-muted);
98
+ min-width: 2.5rem;
99
+ user-select: none;
100
+ }
101
+ .rf-audio-player__time--current {
102
+ text-align: right;
103
+ }
104
+ .rf-audio-player__time--duration {
105
+ text-align: left;
106
+ }
107
+
108
+ /* Progress bar */
109
+ .rf-audio-player__progress {
110
+ flex: 1;
111
+ height: 6px;
112
+ background: var(--rf-color-surface-active, #e5e7eb);
113
+ border-radius: var(--rf-radius-full, 9999px);
114
+ cursor: pointer;
115
+ position: relative;
116
+ overflow: hidden;
117
+ }
118
+ .rf-audio-player__progress:focus-visible {
119
+ outline: 2px solid var(--rf-color-primary);
120
+ outline-offset: 2px;
121
+ }
122
+ .rf-audio-player__progress-bar {
123
+ height: 100%;
124
+ background: var(--rf-color-primary);
125
+ border-radius: var(--rf-radius-full, 9999px);
126
+ width: 0%;
127
+ transition: width 0.1s linear;
128
+ pointer-events: none;
129
+ }
130
+
131
+ /* Waveform container */
132
+ .rf-audio-player__waveform {
133
+ width: 100%;
134
+ min-height: 48px;
135
+ border-radius: var(--rf-radius-sm, 4px);
136
+ overflow: hidden;
137
+ }
138
+
139
+ /* Hide standard progress bar when waveform is active */
140
+ .rf-audio[data-waveform="true"] .rf-audio-player__controls .rf-audio-player__progress {
141
+ display: none;
142
+ }
143
+
144
+ /* Chapter list */
145
+ .rf-audio-player__chapters {
146
+ list-style: none;
147
+ padding: 0;
148
+ margin: 0.5rem 0 0;
149
+ border-top: 1px solid var(--rf-color-border);
150
+ padding-top: 0.5rem;
151
+ }
152
+ .rf-audio-player__chapter {
153
+ display: flex;
154
+ width: 100%;
155
+ align-items: center;
156
+ gap: 0.75rem;
157
+ padding: 0.375rem 0.5rem;
158
+ border: none;
159
+ background: none;
160
+ cursor: pointer;
161
+ border-radius: var(--rf-radius-sm, 4px);
162
+ transition: background 0.15s ease;
163
+ text-align: left;
164
+ font-family: inherit;
165
+ }
166
+ .rf-audio-player__chapter:hover {
167
+ background: var(--rf-color-surface-hover, rgba(0, 0, 0, 0.04));
168
+ }
169
+ .rf-audio-player__chapter:focus-visible {
170
+ outline: 2px solid var(--rf-color-primary);
171
+ outline-offset: -2px;
172
+ }
173
+ .rf-audio-player__chapter--active {
174
+ background: color-mix(in srgb, var(--rf-color-primary) 8%, transparent);
175
+ }
176
+ .rf-audio-player__chapter--active .rf-audio-player__chapter-name {
177
+ color: var(--rf-color-primary);
178
+ }
179
+ .rf-audio-player__chapter-name {
180
+ flex: 1;
181
+ font-size: 0.8125rem;
182
+ font-weight: 500;
183
+ color: var(--rf-color-text);
184
+ }
185
+ .rf-audio-player__chapter-time {
186
+ font-size: 0.75rem;
187
+ font-variant-numeric: tabular-nums;
188
+ color: var(--rf-color-muted);
189
+ flex-shrink: 0;
190
+ }
191
+
192
+ /* Active track highlight when connected to audio player */
193
+ .rf-track--active {
194
+ background: color-mix(in srgb, var(--rf-color-primary) 6%, transparent);
195
+ border-radius: var(--rf-radius-sm, 4px);
196
+ }
197
+ .rf-track--active .rf-track__track-name {
198
+ color: var(--rf-color-primary);
199
+ }
@@ -50,6 +50,9 @@
50
50
  background: var(--rf-color-surface);
51
51
  overflow: hidden;
52
52
  }
53
+ .rf-bento-cell--full {
54
+ grid-column: 1 / -1;
55
+ }
53
56
  .rf-bento-cell--large {
54
57
  grid-column: span 2;
55
58
  grid-row: span 2;
@@ -60,13 +63,31 @@
60
63
  .rf-bento-cell--small {
61
64
  grid-column: span 1;
62
65
  }
66
+ /* Span mode: heading level determines column span via CSS variable */
67
+ .rf-bento-cell--span {
68
+ grid-column: span var(--cell-span, 1);
69
+ }
70
+ .rf-bento-cell__icon {
71
+ margin-bottom: 0.75rem;
72
+ line-height: 0;
73
+ }
74
+ .rf-bento-cell__icon svg {
75
+ width: 1.5rem;
76
+ height: 1.5rem;
77
+ color: var(--rf-color-accent);
78
+ }
79
+ .rf-bento-cell__icon .rf-icon {
80
+ width: 1.5rem;
81
+ height: 1.5rem;
82
+ color: var(--rf-color-accent);
83
+ }
63
84
  .rf-bento-cell__title {
64
- font-size: 1rem;
85
+ font-size: 1.125rem;
65
86
  font-weight: 600;
66
87
  margin: 0 0 0.5rem;
67
88
  }
68
- .rf-bento-cell__body span[property],
69
- .rf-bento-cell__body meta { display: none; }
89
+ .rf-bento-cell__body > span[property],
90
+ .rf-bento-cell__body > meta { display: none; }
70
91
  .rf-bento-cell__body p:last-child { margin-bottom: 0; }
71
92
  .rf-bento-cell img {
72
93
  width: 100%;
@@ -74,13 +95,33 @@
74
95
  border-radius: var(--rf-radius-sm);
75
96
  margin-bottom: 0.75rem;
76
97
  }
98
+ /* Remove padding on bleed edges when showcase bleeds inside a cell */
99
+ .rf-bento-cell:has(.rf-showcase[data-bleed="bottom"]),
100
+ .rf-bento-cell:has(.rf-showcase[data-bleed="both"]),
101
+ .rf-bento-cell:has(.rf-showcase[data-bleed="bottom-end"]) {
102
+ padding-bottom: 0;
103
+ }
104
+ .rf-bento-cell:has(.rf-showcase[data-bleed="end"]),
105
+ .rf-bento-cell:has(.rf-showcase[data-bleed="bottom-end"]),
106
+ .rf-bento-cell:has(.rf-showcase[data-bleed="top-end"]) {
107
+ padding-inline-end: 0;
108
+ }
109
+ .rf-bento-cell:has(.rf-showcase[data-bleed="top"]),
110
+ .rf-bento-cell:has(.rf-showcase[data-bleed="both"]),
111
+ .rf-bento-cell:has(.rf-showcase[data-bleed="top-end"]) {
112
+ padding-top: 0;
113
+ }
77
114
  @media (max-width: 768px) {
78
115
  .rf-bento__grid { grid-template-columns: repeat(2, 1fr) !important; }
116
+ .rf-bento-cell--full { grid-column: 1 / -1; }
79
117
  .rf-bento-cell--large { grid-column: span 2; grid-row: span 1; }
80
118
  .rf-bento-cell--medium { grid-column: span 2; }
119
+ .rf-bento-cell--span { grid-column: span min(var(--cell-span, 1), 2); }
81
120
  }
82
121
  @media (max-width: 480px) {
83
122
  .rf-bento__grid { grid-template-columns: 1fr !important; }
123
+ .rf-bento-cell--full,
84
124
  .rf-bento-cell--large,
85
- .rf-bento-cell--medium { grid-column: span 1; }
125
+ .rf-bento-cell--medium,
126
+ .rf-bento-cell--span { grid-column: span 1; }
86
127
  }