@refrakt-md/lumina 0.7.2 → 0.8.1
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/base.css +4 -0
- package/contracts/structures.json +405 -98
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +75 -1
- package/dist/config.js.map +1 -1
- package/html/index.ts +28 -0
- package/index.css +11 -0
- package/package.json +16 -7
- package/styles/base/attributes.css +20 -0
- package/styles/global.css +2 -2
- package/styles/layouts/default.css +131 -5
- package/styles/layouts/split.css +34 -0
- package/styles/runes/annotate.css +2 -2
- package/styles/runes/audio.css +199 -0
- package/styles/runes/bento.css +45 -4
- package/styles/runes/bg.css +53 -0
- package/styles/runes/budget.css +2 -2
- package/styles/runes/cast.css +1 -1
- package/styles/runes/codegroup.css +9 -0
- package/styles/runes/comparison.css +2 -2
- package/styles/runes/conversation.css +4 -4
- package/styles/runes/cta.css +10 -2
- package/styles/runes/feature.css +34 -26
- package/styles/runes/gallery.css +182 -0
- package/styles/runes/grid.css +39 -5
- package/styles/runes/hero.css +30 -12
- package/styles/runes/itinerary.css +2 -0
- package/styles/runes/mockup.css +52 -16
- package/styles/runes/page-section.css +1 -0
- package/styles/runes/playlist.css +88 -0
- package/styles/runes/preview.css +3 -4
- package/styles/runes/reveal.css +2 -2
- package/styles/runes/showcase.css +94 -0
- package/styles/runes/steps.css +2 -10
- package/styles/runes/storyboard.css +2 -2
- package/styles/runes/tabs.css +8 -10
- package/styles/runes/tint.css +203 -0
- package/styles/runes/track.css +118 -0
- package/tokens/base.css +21 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/* Tint Rune — Colour Token Bridge
|
|
2
|
+
*
|
|
3
|
+
* Maps --tint-* custom properties (set by the identity transform) to
|
|
4
|
+
* Lumina's internal --rf-color-* tokens.
|
|
5
|
+
*
|
|
6
|
+
* The six bridgeable tokens are registered with @property so that when a
|
|
7
|
+
* tint doesn't override a particular token, the property falls back to
|
|
8
|
+
* its inherited value instead of becoming guaranteed-invalid (which would
|
|
9
|
+
* happen with a self-referencing var() fallback — a CSS cycle). */
|
|
10
|
+
|
|
11
|
+
/* ── 0. Token registration ────────────────────────────────────────────────
|
|
12
|
+
* @property makes guaranteed-invalid fall back to the inherited value
|
|
13
|
+
* (inherits: true) rather than propagating as invalid through children.
|
|
14
|
+
* initial-value matches the light-mode defaults from tokens/base.css. */
|
|
15
|
+
|
|
16
|
+
@property --rf-color-bg {
|
|
17
|
+
syntax: '<color>';
|
|
18
|
+
inherits: true;
|
|
19
|
+
initial-value: #ffffff;
|
|
20
|
+
}
|
|
21
|
+
@property --rf-color-surface {
|
|
22
|
+
syntax: '<color>';
|
|
23
|
+
inherits: true;
|
|
24
|
+
initial-value: #f8fafc;
|
|
25
|
+
}
|
|
26
|
+
@property --rf-color-text {
|
|
27
|
+
syntax: '<color>';
|
|
28
|
+
inherits: true;
|
|
29
|
+
initial-value: #1a1a2e;
|
|
30
|
+
}
|
|
31
|
+
@property --rf-color-muted {
|
|
32
|
+
syntax: '<color>';
|
|
33
|
+
inherits: true;
|
|
34
|
+
initial-value: #64748b;
|
|
35
|
+
}
|
|
36
|
+
@property --rf-color-primary {
|
|
37
|
+
syntax: '<color>';
|
|
38
|
+
inherits: true;
|
|
39
|
+
initial-value: #0ea5e9;
|
|
40
|
+
}
|
|
41
|
+
@property --rf-color-border {
|
|
42
|
+
syntax: '<color>';
|
|
43
|
+
inherits: true;
|
|
44
|
+
initial-value: #e2e8f0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* ── 1. Colour scheme override ──────────────────────────────────────────────
|
|
48
|
+
* Forces dark or light mode tokens on a subtree. The six tint-bridgeable
|
|
49
|
+
* tokens are also exposed as --cs-* intermediaries so compound selectors
|
|
50
|
+
* in step 4 can fall back to them without a cycle. */
|
|
51
|
+
|
|
52
|
+
[data-color-scheme="dark"] {
|
|
53
|
+
color-scheme: dark;
|
|
54
|
+
color: var(--rf-color-text);
|
|
55
|
+
background-color: var(--rf-color-bg);
|
|
56
|
+
|
|
57
|
+
--cs-bg: #0c1222;
|
|
58
|
+
--cs-surface: #0f172a;
|
|
59
|
+
--cs-text: #e2e8f0;
|
|
60
|
+
--cs-muted: #94a3b8;
|
|
61
|
+
--cs-accent: #38bdf8;
|
|
62
|
+
--cs-border: rgba(255, 255, 255, 0.1);
|
|
63
|
+
|
|
64
|
+
--rf-color-bg: var(--cs-bg);
|
|
65
|
+
--rf-color-surface: var(--cs-surface);
|
|
66
|
+
--rf-color-text: var(--cs-text);
|
|
67
|
+
--rf-color-muted: var(--cs-muted);
|
|
68
|
+
--rf-color-primary: var(--cs-accent);
|
|
69
|
+
--rf-color-border: var(--cs-border);
|
|
70
|
+
|
|
71
|
+
--rf-color-primary-hover: #7dd3fc;
|
|
72
|
+
--rf-color-surface-hover: #1e293b;
|
|
73
|
+
--rf-color-surface-active: #334155;
|
|
74
|
+
--rf-color-surface-raised: #1e293b;
|
|
75
|
+
|
|
76
|
+
--rf-color-info: #60a5fa;
|
|
77
|
+
--rf-color-info-bg: rgba(59, 130, 246, 0.1);
|
|
78
|
+
--rf-color-info-border: rgba(59, 130, 246, 0.3);
|
|
79
|
+
--rf-color-warning: #fbbf24;
|
|
80
|
+
--rf-color-warning-bg: rgba(245, 158, 11, 0.1);
|
|
81
|
+
--rf-color-warning-border: rgba(245, 158, 11, 0.3);
|
|
82
|
+
--rf-color-danger: #f87171;
|
|
83
|
+
--rf-color-danger-bg: rgba(239, 68, 68, 0.1);
|
|
84
|
+
--rf-color-danger-border: rgba(239, 68, 68, 0.3);
|
|
85
|
+
--rf-color-success: #34d399;
|
|
86
|
+
--rf-color-success-bg: rgba(16, 185, 129, 0.1);
|
|
87
|
+
--rf-color-success-border: rgba(16, 185, 129, 0.3);
|
|
88
|
+
|
|
89
|
+
--rf-color-code-bg: #0f172a;
|
|
90
|
+
--rf-color-code-text: #e2e8f0;
|
|
91
|
+
--rf-color-inline-code-bg: rgba(255, 255, 255, 0.08);
|
|
92
|
+
|
|
93
|
+
--rf-shadow-xs: 0 1px 2px rgba(0,0,0,0.3);
|
|
94
|
+
--rf-shadow-sm: 0 1px 3px rgba(0,0,0,0.4), 0 1px 2px rgba(0,0,0,0.3);
|
|
95
|
+
--rf-shadow-md: 0 4px 12px rgba(0,0,0,0.4), 0 1px 3px rgba(0,0,0,0.3);
|
|
96
|
+
--rf-shadow-lg: 0 8px 24px rgba(0,0,0,0.5), 0 2px 6px rgba(0,0,0,0.3);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[data-color-scheme="light"] {
|
|
100
|
+
color-scheme: light;
|
|
101
|
+
color: var(--rf-color-text);
|
|
102
|
+
background-color: var(--rf-color-bg);
|
|
103
|
+
|
|
104
|
+
--cs-bg: #ffffff;
|
|
105
|
+
--cs-surface: #f8fafc;
|
|
106
|
+
--cs-text: #1a1a2e;
|
|
107
|
+
--cs-muted: #64748b;
|
|
108
|
+
--cs-accent: #0ea5e9;
|
|
109
|
+
--cs-border: #e2e8f0;
|
|
110
|
+
|
|
111
|
+
--rf-color-bg: var(--cs-bg);
|
|
112
|
+
--rf-color-surface: var(--cs-surface);
|
|
113
|
+
--rf-color-text: var(--cs-text);
|
|
114
|
+
--rf-color-muted: var(--cs-muted);
|
|
115
|
+
--rf-color-primary: var(--cs-accent);
|
|
116
|
+
--rf-color-border: var(--cs-border);
|
|
117
|
+
|
|
118
|
+
--rf-color-primary-hover: #0284c7;
|
|
119
|
+
--rf-color-surface-hover: #f1f5f9;
|
|
120
|
+
--rf-color-surface-active: #e2e8f0;
|
|
121
|
+
--rf-color-surface-raised: #ffffff;
|
|
122
|
+
|
|
123
|
+
--rf-color-info: #3b82f6;
|
|
124
|
+
--rf-color-info-bg: #eff6ff;
|
|
125
|
+
--rf-color-info-border: #bfdbfe;
|
|
126
|
+
--rf-color-warning: #f59e0b;
|
|
127
|
+
--rf-color-warning-bg: #fffbeb;
|
|
128
|
+
--rf-color-warning-border: #fde68a;
|
|
129
|
+
--rf-color-danger: #ef4444;
|
|
130
|
+
--rf-color-danger-bg: #fef2f2;
|
|
131
|
+
--rf-color-danger-border: #fecaca;
|
|
132
|
+
--rf-color-success: #10b981;
|
|
133
|
+
--rf-color-success-bg: #ecfdf5;
|
|
134
|
+
--rf-color-success-border: #a7f3d0;
|
|
135
|
+
|
|
136
|
+
--rf-color-inline-code-bg: #f1f5f9;
|
|
137
|
+
|
|
138
|
+
--rf-shadow-xs: 0 1px 2px rgba(0,0,0,0.04);
|
|
139
|
+
--rf-shadow-sm: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
|
|
140
|
+
--rf-shadow-md: 0 4px 12px rgba(0,0,0,0.07), 0 1px 3px rgba(0,0,0,0.04);
|
|
141
|
+
--rf-shadow-lg: 0 8px 24px rgba(0,0,0,0.08), 0 2px 6px rgba(0,0,0,0.04);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* ── 2. Tint bridge — light mode (default) ────────────────────────────────
|
|
145
|
+
* Maps --tint-* → --rf-color-*. No fallback needed — when --tint-* is
|
|
146
|
+
* unset, var() produces guaranteed-invalid, and @property makes the
|
|
147
|
+
* token inherit from the parent element.
|
|
148
|
+
*
|
|
149
|
+
* :where() background gives tinted elements a painted background at zero
|
|
150
|
+
* specificity — runes with their own background naturally override it. */
|
|
151
|
+
|
|
152
|
+
:where([data-tint]) {
|
|
153
|
+
background-color: var(--rf-color-bg);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
[data-tint] {
|
|
157
|
+
color: var(--rf-color-text);
|
|
158
|
+
--rf-color-bg: var(--tint-background);
|
|
159
|
+
--rf-color-surface: var(--tint-surface);
|
|
160
|
+
--rf-color-text: var(--tint-primary);
|
|
161
|
+
--rf-color-muted: var(--tint-secondary);
|
|
162
|
+
--rf-color-primary: var(--tint-accent);
|
|
163
|
+
--rf-color-border: var(--tint-border);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* ── 3. Tint bridge — dark ancestor ───────────────────────────────────────
|
|
167
|
+
* When a dark context is on an ancestor (data-theme on html, or
|
|
168
|
+
* data-color-scheme on a parent), prefer dark tint values.
|
|
169
|
+
* Uses descendant combinator — does NOT match same-element.
|
|
170
|
+
* Unset tokens → guaranteed-invalid → @property inherits from parent
|
|
171
|
+
* (which carries the dark theme value). */
|
|
172
|
+
|
|
173
|
+
:is([data-theme="dark"], [data-color-scheme="dark"]) [data-tint] {
|
|
174
|
+
--rf-color-bg: var(--tint-dark-background, var(--tint-background));
|
|
175
|
+
--rf-color-surface: var(--tint-dark-surface, var(--tint-surface));
|
|
176
|
+
--rf-color-text: var(--tint-dark-primary, var(--tint-primary));
|
|
177
|
+
--rf-color-muted: var(--tint-dark-secondary, var(--tint-secondary));
|
|
178
|
+
--rf-color-primary: var(--tint-dark-accent, var(--tint-accent));
|
|
179
|
+
--rf-color-border: var(--tint-dark-border, var(--tint-border));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* ── 4. Tint bridge — colour scheme + tint on SAME element ────────────────
|
|
183
|
+
* Compound selectors (no space) match when both attributes sit on the
|
|
184
|
+
* same element. Falls back to --cs-* intermediaries so that unlisted
|
|
185
|
+
* tint tokens use the colour-scheme value, not the page-level value. */
|
|
186
|
+
|
|
187
|
+
[data-color-scheme="dark"][data-tint] {
|
|
188
|
+
--rf-color-bg: var(--tint-dark-background, var(--tint-background, var(--cs-bg)));
|
|
189
|
+
--rf-color-surface: var(--tint-dark-surface, var(--tint-surface, var(--cs-surface)));
|
|
190
|
+
--rf-color-text: var(--tint-dark-primary, var(--tint-primary, var(--cs-text)));
|
|
191
|
+
--rf-color-muted: var(--tint-dark-secondary, var(--tint-secondary, var(--cs-muted)));
|
|
192
|
+
--rf-color-primary: var(--tint-dark-accent, var(--tint-accent, var(--cs-accent)));
|
|
193
|
+
--rf-color-border: var(--tint-dark-border, var(--tint-border, var(--cs-border)));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
[data-color-scheme="light"][data-tint] {
|
|
197
|
+
--rf-color-bg: var(--tint-background, var(--cs-bg));
|
|
198
|
+
--rf-color-surface: var(--tint-surface, var(--cs-surface));
|
|
199
|
+
--rf-color-text: var(--tint-primary, var(--cs-text));
|
|
200
|
+
--rf-color-muted: var(--tint-secondary, var(--cs-muted));
|
|
201
|
+
--rf-color-primary: var(--tint-accent, var(--cs-accent));
|
|
202
|
+
--rf-color-border: var(--tint-border, var(--cs-border));
|
|
203
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* Track */
|
|
2
|
+
.rf-track {
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
gap: 0.75rem;
|
|
6
|
+
padding: 0.625rem 1.5rem;
|
|
7
|
+
border-bottom: 1px solid color-mix(in srgb, var(--rf-color-border) 50%, transparent);
|
|
8
|
+
transition: background 0.15s ease;
|
|
9
|
+
counter-increment: track;
|
|
10
|
+
}
|
|
11
|
+
.rf-track:last-child {
|
|
12
|
+
border-bottom: none;
|
|
13
|
+
}
|
|
14
|
+
.rf-track:hover {
|
|
15
|
+
background: color-mix(in srgb, var(--rf-color-border) 15%, transparent);
|
|
16
|
+
}
|
|
17
|
+
.rf-track::before {
|
|
18
|
+
content: counter(track);
|
|
19
|
+
min-width: 1.5rem;
|
|
20
|
+
font-size: 0.8rem;
|
|
21
|
+
color: var(--rf-color-muted);
|
|
22
|
+
text-align: right;
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Track name — primary text, takes remaining space */
|
|
27
|
+
.rf-track__track-name {
|
|
28
|
+
flex: 1;
|
|
29
|
+
font-size: 0.9375rem;
|
|
30
|
+
font-weight: 500;
|
|
31
|
+
color: var(--rf-color-text);
|
|
32
|
+
min-width: 0;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
text-overflow: ellipsis;
|
|
35
|
+
white-space: nowrap;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Artist — secondary text */
|
|
39
|
+
.rf-track__track-artist {
|
|
40
|
+
font-size: 0.8125rem;
|
|
41
|
+
color: var(--rf-color-muted);
|
|
42
|
+
flex-shrink: 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Duration — right-aligned, tabular nums */
|
|
46
|
+
.rf-track__track-duration {
|
|
47
|
+
font-size: 0.8125rem;
|
|
48
|
+
color: var(--rf-color-muted);
|
|
49
|
+
font-variant-numeric: tabular-nums;
|
|
50
|
+
flex-shrink: 0;
|
|
51
|
+
min-width: 3rem;
|
|
52
|
+
text-align: right;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Meta (date etc.) */
|
|
56
|
+
.rf-track__track-meta {
|
|
57
|
+
font-size: 0.75rem;
|
|
58
|
+
color: var(--rf-color-muted);
|
|
59
|
+
flex-shrink: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Description — full width below the row */
|
|
63
|
+
.rf-track__track-description {
|
|
64
|
+
flex-basis: 100%;
|
|
65
|
+
font-size: 0.8125rem;
|
|
66
|
+
color: var(--rf-color-muted);
|
|
67
|
+
line-height: 1.5;
|
|
68
|
+
padding-top: 0.5rem;
|
|
69
|
+
}
|
|
70
|
+
.rf-track__track-description p {
|
|
71
|
+
margin: 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Wrap when description is present */
|
|
75
|
+
.rf-track:has(.rf-track__track-description) {
|
|
76
|
+
flex-wrap: wrap;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Cue points (lyrics / chapters) */
|
|
80
|
+
.rf-track [data-name="lyrics"],
|
|
81
|
+
.rf-track [data-name="chapters"] {
|
|
82
|
+
flex-basis: 100%;
|
|
83
|
+
list-style: none;
|
|
84
|
+
padding: 0.5rem 0 0;
|
|
85
|
+
margin: 0;
|
|
86
|
+
font-size: 0.8125rem;
|
|
87
|
+
}
|
|
88
|
+
.rf-track [data-name="lyrics"] li {
|
|
89
|
+
padding: 0.125rem 0;
|
|
90
|
+
color: var(--rf-color-muted);
|
|
91
|
+
}
|
|
92
|
+
.rf-track [data-name="lyric"] {
|
|
93
|
+
margin: 0;
|
|
94
|
+
}
|
|
95
|
+
.rf-track [data-name="chapters"] li {
|
|
96
|
+
display: flex;
|
|
97
|
+
gap: 0.75rem;
|
|
98
|
+
padding: 0.25rem 0;
|
|
99
|
+
}
|
|
100
|
+
.rf-track [data-name="chapter-name"] {
|
|
101
|
+
color: var(--rf-color-text);
|
|
102
|
+
font-weight: 500;
|
|
103
|
+
}
|
|
104
|
+
.rf-track [data-name="chapter-time"] {
|
|
105
|
+
color: var(--rf-color-muted);
|
|
106
|
+
font-variant-numeric: tabular-nums;
|
|
107
|
+
margin-left: auto;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* Hide secondary columns on narrow screens */
|
|
111
|
+
@media (max-width: 480px) {
|
|
112
|
+
.rf-track__track-artist {
|
|
113
|
+
display: none;
|
|
114
|
+
}
|
|
115
|
+
.rf-track__track-meta {
|
|
116
|
+
display: none;
|
|
117
|
+
}
|
|
118
|
+
}
|
package/tokens/base.css
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
4
|
/* Typography */
|
|
5
|
-
--rf-font-sans: '
|
|
5
|
+
--rf-font-sans: 'Outfit', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
6
6
|
--rf-font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
|
|
7
7
|
|
|
8
8
|
/* Primary scale (sky-blue) */
|
|
@@ -52,6 +52,26 @@
|
|
|
52
52
|
--rf-radius-lg: 16px;
|
|
53
53
|
--rf-radius-full: 9999px;
|
|
54
54
|
|
|
55
|
+
/* Spacing */
|
|
56
|
+
--rf-spacing-xs: 0.25rem;
|
|
57
|
+
--rf-spacing-sm: 0.5rem;
|
|
58
|
+
--rf-spacing-md: 1.5rem;
|
|
59
|
+
--rf-spacing-lg: 2rem;
|
|
60
|
+
--rf-spacing-xl: 3rem;
|
|
61
|
+
--rf-spacing-2xl: 4rem;
|
|
62
|
+
|
|
63
|
+
/* Section spacing */
|
|
64
|
+
--rf-spacing-section: 4rem;
|
|
65
|
+
--rf-spacing-section-tight: 1.5rem;
|
|
66
|
+
--rf-spacing-section-loose: 6rem;
|
|
67
|
+
--rf-spacing-section-breathe: 8rem;
|
|
68
|
+
|
|
69
|
+
/* Inset (horizontal padding) */
|
|
70
|
+
--rf-inset-flush: 0;
|
|
71
|
+
--rf-inset-tight: 1rem;
|
|
72
|
+
--rf-inset-loose: 4rem;
|
|
73
|
+
--rf-inset-breathe: 8rem;
|
|
74
|
+
|
|
55
75
|
/* Shadows */
|
|
56
76
|
--rf-shadow-xs: 0 1px 2px rgba(0,0,0,0.04);
|
|
57
77
|
--rf-shadow-sm: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
|