@ryanhelsing/ry-ui 1.0.13 → 1.0.15

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 (34) hide show
  1. package/.claude/skills/ry-ui-builder/SKILL.md +4 -6
  2. package/README.md +21 -25
  3. package/dist/components/ry-dropdown.d.ts +1 -1
  4. package/dist/components/ry-heading.d.ts +15 -0
  5. package/dist/components/ry-heading.d.ts.map +1 -0
  6. package/dist/components/ry-logo-bar.d.ts +25 -0
  7. package/dist/components/ry-logo-bar.d.ts.map +1 -0
  8. package/dist/components/ry-modal.d.ts +1 -1
  9. package/dist/components/ry-pricing.d.ts +4 -4
  10. package/dist/components/ry-pricing.d.ts.map +1 -1
  11. package/dist/components/ry-search-list.d.ts +30 -0
  12. package/dist/components/ry-search-list.d.ts.map +1 -0
  13. package/dist/components/ry-stat.d.ts +1 -4
  14. package/dist/components/ry-stat.d.ts.map +1 -1
  15. package/dist/components/ry-testimonial.d.ts +2 -5
  16. package/dist/components/ry-testimonial.d.ts.map +1 -1
  17. package/dist/components/ry-theme-panel.d.ts +1 -1
  18. package/dist/components/ry-theme-panel.d.ts.map +1 -1
  19. package/dist/core/ry-transform.d.ts.map +1 -1
  20. package/dist/css/ry-structure.css +555 -30
  21. package/dist/css/ry-theme.css +252 -41
  22. package/dist/css/ry-tokens.css +165 -100
  23. package/dist/css/ry-ui.css +977 -176
  24. package/dist/pages/components.html +19 -82
  25. package/dist/pages/landing.html +13 -40
  26. package/dist/ry-ui.d.ts +3 -1
  27. package/dist/ry-ui.d.ts.map +1 -1
  28. package/dist/ry-ui.js +945 -656
  29. package/dist/ry-ui.js.map +1 -1
  30. package/dist/themes/ocean.css +22 -22
  31. package/docs/components/dropdown.md +2 -2
  32. package/docs/components/modal.md +2 -2
  33. package/package.json +3 -1
  34. package/docs/components/button-group.md +0 -36
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * ry-ui Design Tokens
3
3
  *
4
- * These CSS custom properties define the visual language.
5
- * color-scheme: light dark enables OS preference detection.
6
- * light-dark() embeds both values no separate dark.css needed.
7
- * Override in your theme file to customize.
4
+ * CORE KNOBS DERIVED TOKENS COMPONENTS
5
+ *
6
+ * Themes only need to set the ~18 core knobs at the top.
7
+ * Everything else derives automatically via color-mix() and calc().
8
+ * Override any derived token for fine-tuning.
8
9
  */
9
10
 
10
11
  /* ═══════════════════════════════════════════════════════════════
@@ -32,90 +33,119 @@
32
33
  color-scheme: light dark;
33
34
 
34
35
  /* ═══════════════════════════════════════════════════════════════
35
- COLORS
36
+ CORE KNOBS — set these to define a theme
36
37
  ═══════════════════════════════════════════════════════════════ */
37
38
 
38
- /* Primary */
39
+ /* Palette: 3 roles */
39
40
  --ry-color-primary: light-dark(oklch(0.623 0.188 259.8), oklch(0.714 0.143 254.6));
40
- --ry-color-primary-hover: light-dark(oklch(0.546 0.215 262.9), oklch(0.623 0.188 259.8));
41
- --ry-color-primary-active: light-dark(oklch(0.488 0.217 264.4), oklch(0.546 0.215 262.9));
42
-
43
- /* Secondary */
44
41
  --ry-color-secondary: light-dark(oklch(0.554 0.041 257.4), oklch(0.711 0.035 256.8));
45
- --ry-color-secondary-hover: light-dark(oklch(0.446 0.037 257.3), oklch(0.869 0.02 252.9));
46
- --ry-color-secondary-active: light-dark(oklch(0.372 0.039 257.3), oklch(0.929 0.013 255.6));
47
-
48
- /* Accent */
49
42
  --ry-color-accent: light-dark(oklch(0.627 0.213 303.9), oklch(0.714 0.183 303.9));
50
- --ry-color-accent-hover: light-dark(oklch(0.557 0.213 303.9), oklch(0.627 0.213 303.9));
51
- --ry-color-accent-active: light-dark(oklch(0.497 0.213 303.9), oklch(0.557 0.213 303.9));
52
43
 
53
- /* Semantic */
44
+ /* Surface */
45
+ --ry-color-bg: light-dark(oklch(1 0 0), oklch(0.208 0.04 265.8));
46
+ --ry-color-text: light-dark(oklch(0.279 0.037 260), oklch(0.968 0.007 248.1));
47
+
48
+ /* Semantic (overrideable, but defaults are universal) */
54
49
  --ry-color-success: oklch(0.723 0.192 149.6);
55
50
  --ry-color-warning: oklch(0.769 0.165 70.1);
56
51
  --ry-color-danger: oklch(0.637 0.208 25.3);
57
- --ry-color-danger-hover: oklch(0.577 0.215 27.3);
58
52
  --ry-color-info: oklch(0.715 0.126 215.2);
59
53
 
60
- /* Semantic backgrounds & text (for alerts, badges) */
61
- --ry-color-info-bg: light-dark(oklch(0.984 0.019 201.1), oklch(0.398 0.066 227.4));
62
- --ry-color-info-text: light-dark(oklch(0.52 0.094 223.1), oklch(0.917 0.077 205.1));
63
- --ry-color-success-bg: light-dark(oklch(0.982 0.018 156.1), oklch(0.393 0.09 152.6));
64
- --ry-color-success-text: light-dark(oklch(0.527 0.137 150.1), oklch(0.925 0.081 156.1));
65
- --ry-color-warning-bg: light-dark(oklch(0.987 0.021 95.3), oklch(0.414 0.105 45.9));
66
- --ry-color-warning-text: light-dark(oklch(0.555 0.145 49), oklch(0.962 0.058 95.6));
67
- --ry-color-danger-bg: light-dark(oklch(0.971 0.013 17), oklch(0.396 0.133 25.7));
68
- --ry-color-danger-text: light-dark(oklch(0.505 0.19 27.5), oklch(0.885 0.059 18.3));
69
-
70
- /* Text */
71
- --ry-color-text: light-dark(oklch(0.279 0.037 260), oklch(0.968 0.007 248.1));
72
- --ry-color-text-muted: light-dark(oklch(0.554 0.041 257.4), oklch(0.711 0.035 256.8));
73
- --ry-color-text-inverse: light-dark(oklch(1 0 0), oklch(0.208 0.04 265.8));
54
+ /* Type: 2 fonts */
55
+ --ry-font-primary: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
56
+ --ry-font-secondary: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
74
57
 
75
- /* Background */
76
- --ry-color-bg: light-dark(oklch(1 0 0), oklch(0.208 0.04 265.8));
77
- --ry-color-bg-subtle: light-dark(oklch(0.984 0.003 248.2), oklch(0.279 0.037 260));
78
- --ry-color-bg-muted: light-dark(oklch(0.968 0.007 248.1), oklch(0.372 0.039 257.3));
58
+ /* Shape */
59
+ --ry-radius-base: 0.375rem;
60
+ --ry-border-width: 1px;
61
+ --ry-outline-width: 0px;
62
+
63
+ /* Depth */
64
+ --ry-shadow-color: light-dark(oklch(0 0 0 / 0.1), oklch(0 0 0 / 0.4));
65
+ --ry-shadow-strength: 1;
66
+ --ry-shadow-spread: 1;
67
+
68
+ /* Surface treatment */
69
+ --ry-panel-opacity: 1;
70
+ --ry-panel-blur: 0px;
71
+
72
+ /* Motion */
73
+ --ry-animation-style: smooth; /* none | smooth | bouncy */
74
+ --ry-duration-scale: 1;
75
+
76
+ /* Density */
77
+ --ry-space-scale: 1;
78
+
79
+ /* ═══════════════════════════════════════════════════════════════
80
+ DERIVED: COLORS — auto-generated from core palette
81
+ ═══════════════════════════════════════════════════════════════ */
79
82
 
80
- /* Border */
81
- --ry-color-border: light-dark(oklch(0.929 0.013 255.6), oklch(0.372 0.039 257.3));
82
- --ry-color-border-strong: light-dark(oklch(0.869 0.02 252.9), oklch(0.446 0.037 257.3));
83
+ /* Hover/active states via color-mix */
84
+ --ry-color-primary-hover: color-mix(in oklch, var(--ry-color-primary) 80%, var(--ry-color-text));
85
+ --ry-color-primary-active: color-mix(in oklch, var(--ry-color-primary) 65%, var(--ry-color-text));
86
+ --ry-color-secondary-hover: color-mix(in oklch, var(--ry-color-secondary) 80%, var(--ry-color-text));
87
+ --ry-color-secondary-active: color-mix(in oklch, var(--ry-color-secondary) 65%, var(--ry-color-text));
88
+ --ry-color-accent-hover: color-mix(in oklch, var(--ry-color-accent) 80%, var(--ry-color-text));
89
+ --ry-color-accent-active: color-mix(in oklch, var(--ry-color-accent) 65%, var(--ry-color-text));
90
+ --ry-color-danger-hover: color-mix(in oklch, var(--ry-color-danger) 80%, var(--ry-color-text));
91
+
92
+ /* Text variants */
93
+ --ry-color-text-muted: color-mix(in oklch, var(--ry-color-text) 55%, var(--ry-color-bg));
94
+ --ry-color-text-inverse: var(--ry-color-bg);
95
+
96
+ /* Background variants */
97
+ --ry-color-bg-subtle: color-mix(in oklch, var(--ry-color-bg) 96%, var(--ry-color-text));
98
+ --ry-color-bg-muted: color-mix(in oklch, var(--ry-color-bg) 92%, var(--ry-color-text));
99
+
100
+ /* Border variants */
101
+ --ry-color-border: color-mix(in oklch, var(--ry-color-bg) 82%, var(--ry-color-text));
102
+ --ry-color-border-strong: color-mix(in oklch, var(--ry-color-bg) 70%, var(--ry-color-text));
83
103
 
84
104
  /* Overlay */
85
- --ry-color-overlay: light-dark(oklch(0 0 0 / 0.5), oklch(0 0 0 / 0.7));
105
+ --ry-color-overlay: color-mix(in oklch, var(--ry-color-text) 50%, transparent);
106
+ --ry-color-hover-overlay: color-mix(in oklch, var(--ry-color-text) 4%, transparent);
107
+
108
+ /* Semantic backgrounds & text — derived from base semantic colors */
109
+ --ry-color-info-bg: color-mix(in srgb, var(--ry-color-info) 12%, var(--ry-color-bg));
110
+ --ry-color-info-text: color-mix(in oklch, var(--ry-color-info) 70%, var(--ry-color-text));
111
+ --ry-color-success-bg: color-mix(in srgb, var(--ry-color-success) 12%, var(--ry-color-bg));
112
+ --ry-color-success-text: color-mix(in oklch, var(--ry-color-success) 70%, var(--ry-color-text));
113
+ --ry-color-warning-bg: color-mix(in srgb, var(--ry-color-warning) 12%, var(--ry-color-bg));
114
+ --ry-color-warning-text: color-mix(in oklch, var(--ry-color-warning) 70%, var(--ry-color-text));
115
+ --ry-color-danger-bg: color-mix(in srgb, var(--ry-color-danger) 12%, var(--ry-color-bg));
116
+ --ry-color-danger-text: color-mix(in oklch, var(--ry-color-danger) 70%, var(--ry-color-text));
86
117
 
87
118
  /* ═══════════════════════════════════════════════════════════════
88
- CODE SYNTAX
119
+ DERIVED: CODE SYNTAX — from palette, auto-adapts to any theme
89
120
  ═══════════════════════════════════════════════════════════════ */
90
121
 
91
- --ry-code-bg: light-dark(oklch(0.978 0.003 248.2), oklch(0.208 0.04 265.8));
92
- --ry-code-header-bg: light-dark(oklch(0.947 0.007 248.1), oklch(0.279 0.037 260));
93
- --ry-code-text-color: light-dark(oklch(0.279 0.013 253.1), oklch(0.968 0.007 248.1));
94
- --ry-code-title-color: light-dark(oklch(0.485 0.02 251.1), oklch(0.711 0.035 256.8));
95
- --ry-code-icon-color: light-dark(oklch(0.666 0.018 251), oklch(0.554 0.041 257.4));
96
- --ry-code-icon-hover-bg: light-dark(oklch(0.876 0.012 248.1), oklch(0.372 0.039 257.3));
97
- --ry-code-icon-hover-color: light-dark(oklch(0.279 0.013 253.1), oklch(0.968 0.007 248.1));
98
- --ry-code-line-number-color: light-dark(oklch(0.666 0.018 251 / 0.6), oklch(0.446 0.037 257.3 / 0.6));
99
- --ry-code-line-border-color: light-dark(oklch(0.876 0.012 248.1), oklch(0.372 0.039 257.3));
100
- --ry-code-color-preview-border: light-dark(oklch(0.279 0.013 253.1 / 0.3), oklch(0.968 0.007 248.1 / 0.3));
101
- --ry-code-keyword: light-dark(oklch(0.552 0.205 24.5), oklch(0.637 0.208 25.3));
102
- --ry-code-property: light-dark(oklch(0.451 0.164 258.2), oklch(0.714 0.143 254.6));
103
- --ry-code-value: light-dark(oklch(0.321 0.108 259.1), oklch(0.769 0.165 70.1));
104
- --ry-code-string: light-dark(oklch(0.321 0.108 259.1), oklch(0.723 0.192 149.6));
105
- --ry-code-number: light-dark(oklch(0.451 0.164 258.2), oklch(0.769 0.165 70.1));
106
- --ry-code-comment: light-dark(oklch(0.565 0.019 251), oklch(0.711 0.035 256.8));
107
- --ry-code-selector: light-dark(oklch(0.439 0.118 148.1), oklch(0.715 0.126 215.2));
108
- --ry-code-punctuation: light-dark(oklch(0.279 0.013 253.1), oklch(0.711 0.035 256.8));
109
- --ry-code-tag: light-dark(oklch(0.439 0.118 148.1), oklch(0.715 0.126 215.2));
110
- --ry-code-attribute: light-dark(oklch(0.451 0.164 258.2), oklch(0.714 0.143 254.6));
122
+ --ry-code-bg: var(--ry-color-bg-subtle);
123
+ --ry-code-header-bg: var(--ry-color-bg-muted);
124
+ --ry-code-text-color: var(--ry-color-text);
125
+ --ry-code-title-color: var(--ry-color-text-muted);
126
+ --ry-code-icon-color: var(--ry-color-text-muted);
127
+ --ry-code-icon-hover-bg: var(--ry-color-bg-muted);
128
+ --ry-code-icon-hover-color: var(--ry-color-text);
129
+ --ry-code-line-number-color: var(--ry-color-secondary);
130
+ --ry-code-line-border-color: var(--ry-color-border);
131
+ --ry-code-color-preview-border: var(--ry-color-border);
132
+ --ry-code-keyword: var(--ry-color-danger);
133
+ --ry-code-property: var(--ry-color-primary);
134
+ --ry-code-value: var(--ry-color-accent);
135
+ --ry-code-string: var(--ry-color-success);
136
+ --ry-code-number: var(--ry-color-warning);
137
+ --ry-code-comment: var(--ry-color-text-muted);
138
+ --ry-code-selector: var(--ry-color-info);
139
+ --ry-code-punctuation: var(--ry-color-text-muted);
140
+ --ry-code-tag: var(--ry-color-info);
141
+ --ry-code-attribute: var(--ry-color-primary);
111
142
 
112
143
  /* ═══════════════════════════════════════════════════════════════
113
- TYPOGRAPHY
144
+ DERIVED: TYPOGRAPHY — from core font knobs
114
145
  ═══════════════════════════════════════════════════════════════ */
115
146
 
116
- /* Font families */
117
- --ry-font-sans: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
118
- --ry-font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
147
+ --ry-font-sans: var(--ry-font-primary);
148
+ --ry-font-mono: var(--ry-font-secondary);
119
149
 
120
150
  /* Font sizes */
121
151
  --ry-text-xs: 0.75rem;
@@ -139,61 +169,96 @@
139
169
  --ry-leading-relaxed: 1.75;
140
170
 
141
171
  /* ═══════════════════════════════════════════════════════════════
142
- SPACING
172
+ DERIVED: SPACING — scaled from base
143
173
  ═══════════════════════════════════════════════════════════════ */
144
174
 
145
175
  --ry-space-0: 0;
146
- --ry-space-1: 0.25rem;
147
- --ry-space-2: 0.5rem;
148
- --ry-space-3: 0.75rem;
149
- --ry-space-4: 1rem;
150
- --ry-space-5: 1.25rem;
151
- --ry-space-6: 1.5rem;
152
- --ry-space-8: 2rem;
153
- --ry-space-10: 2.5rem;
154
- --ry-space-12: 3rem;
155
- --ry-space-16: 4rem;
156
- --ry-space-20: 5rem;
176
+ --ry-space-1: calc(0.25rem * var(--ry-space-scale));
177
+ --ry-space-2: calc(0.5rem * var(--ry-space-scale));
178
+ --ry-space-3: calc(0.75rem * var(--ry-space-scale));
179
+ --ry-space-4: calc(1rem * var(--ry-space-scale));
180
+ --ry-space-5: calc(1.25rem * var(--ry-space-scale));
181
+ --ry-space-6: calc(1.5rem * var(--ry-space-scale));
182
+ --ry-space-8: calc(2rem * var(--ry-space-scale));
183
+ --ry-space-10: calc(2.5rem * var(--ry-space-scale));
184
+ --ry-space-12: calc(3rem * var(--ry-space-scale));
185
+ --ry-space-16: calc(4rem * var(--ry-space-scale));
186
+ --ry-space-20: calc(5rem * var(--ry-space-scale));
157
187
 
158
188
  /* ═══════════════════════════════════════════════════════════════
159
- BORDERS & RADIUS
189
+ DERIVED: BORDERS & RADIUS — scaled from base
160
190
  ═══════════════════════════════════════════════════════════════ */
161
191
 
162
192
  --ry-radius-none: 0;
163
- --ry-radius-sm: 0.25rem;
164
- --ry-radius-md: 0.375rem;
165
- --ry-radius-lg: 0.5rem;
166
- --ry-radius-xl: 0.75rem;
167
- --ry-radius-2xl: 1rem;
193
+ --ry-radius-sm: calc(var(--ry-radius-base) * 0.66);
194
+ --ry-radius-md: var(--ry-radius-base);
195
+ --ry-radius-lg: calc(var(--ry-radius-base) * 1.33);
196
+ --ry-radius-xl: calc(var(--ry-radius-base) * 2);
197
+ --ry-radius-2xl: calc(var(--ry-radius-base) * 2.66);
168
198
  --ry-radius-full: 9999px;
169
199
 
170
- --ry-border-width: 1px;
171
-
172
200
  /* ═══════════════════════════════════════════════════════════════
173
- SHADOWS
201
+ DERIVED: SHADOWS — scaled from strength + spread knobs
174
202
  ═══════════════════════════════════════════════════════════════ */
175
203
 
176
- --ry-shadow-color: light-dark(oklch(0 0 0 / 0.1), oklch(0 0 0 / 0.4));
177
- --ry-shadow-color-sm: light-dark(oklch(0 0 0 / 0.05), oklch(0 0 0 / 0.3));
178
- --ry-shadow-sm: 0 1px 2px 0 var(--ry-shadow-color-sm);
179
- --ry-shadow-md: 0 4px 6px -1px var(--ry-shadow-color), 0 2px 4px -2px var(--ry-shadow-color);
180
- --ry-shadow-lg: 0 10px 15px -3px var(--ry-shadow-color), 0 4px 6px -4px var(--ry-shadow-color);
181
- --ry-shadow-xl: 0 20px 25px -5px var(--ry-shadow-color), 0 8px 10px -6px var(--ry-shadow-color);
204
+ --ry-shadow-color-sm: color-mix(in oklch, var(--ry-shadow-color) calc(50% * var(--ry-shadow-strength)), transparent);
205
+ --ry-shadow-sm:
206
+ 0
207
+ calc(1px * var(--ry-shadow-spread))
208
+ calc(2px * var(--ry-shadow-spread))
209
+ 0
210
+ var(--ry-shadow-color-sm);
211
+ --ry-shadow-md:
212
+ 0
213
+ calc(4px * var(--ry-shadow-spread))
214
+ calc(6px * var(--ry-shadow-spread))
215
+ calc(-1px * var(--ry-shadow-spread))
216
+ var(--ry-shadow-color),
217
+ 0
218
+ calc(2px * var(--ry-shadow-spread))
219
+ calc(4px * var(--ry-shadow-spread))
220
+ calc(-2px * var(--ry-shadow-spread))
221
+ var(--ry-shadow-color);
222
+ --ry-shadow-lg:
223
+ 0
224
+ calc(10px * var(--ry-shadow-spread))
225
+ calc(15px * var(--ry-shadow-spread))
226
+ calc(-3px * var(--ry-shadow-spread))
227
+ var(--ry-shadow-color),
228
+ 0
229
+ calc(4px * var(--ry-shadow-spread))
230
+ calc(6px * var(--ry-shadow-spread))
231
+ calc(-4px * var(--ry-shadow-spread))
232
+ var(--ry-shadow-color);
233
+ --ry-shadow-xl:
234
+ 0
235
+ calc(20px * var(--ry-shadow-spread))
236
+ calc(25px * var(--ry-shadow-spread))
237
+ calc(-5px * var(--ry-shadow-spread))
238
+ var(--ry-shadow-color),
239
+ 0
240
+ calc(8px * var(--ry-shadow-spread))
241
+ calc(10px * var(--ry-shadow-spread))
242
+ calc(-6px * var(--ry-shadow-spread))
243
+ var(--ry-shadow-color);
182
244
 
183
245
  /* ═══════════════════════════════════════════════════════════════
184
- TRANSITIONS
246
+ DERIVED: TRANSITIONS — scaled from duration-scale + animation style
185
247
  ═══════════════════════════════════════════════════════════════ */
186
248
 
187
- --ry-duration-fast: 100ms;
188
- --ry-duration-normal: 200ms;
189
- --ry-duration-slow: 300ms;
249
+ --ry-duration-fast: calc(100ms * var(--ry-duration-scale));
250
+ --ry-duration-normal: calc(200ms * var(--ry-duration-scale));
251
+ --ry-duration-slow: calc(300ms * var(--ry-duration-scale));
190
252
 
191
253
  --ry-ease: cubic-bezier(0.4, 0, 0.2, 1);
192
254
  --ry-ease-in: cubic-bezier(0.4, 0, 1, 1);
193
255
  --ry-ease-out: cubic-bezier(0, 0, 0.2, 1);
256
+ --ry-ease-out-back: cubic-bezier(0.34, 1.85, 0.64, 1);
257
+ --ry-ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
258
+ --ry-ease-in-out-expo: cubic-bezier(1, 0, 0, 1);
194
259
 
195
260
  /* ═══════════════════════════════════════════════════════════════
196
- Z-INDEX
261
+ Z-INDEX (not themeable — structural)
197
262
  ═══════════════════════════════════════════════════════════════ */
198
263
 
199
264
  --ry-z-dropdown: 1000;
@@ -206,13 +271,13 @@
206
271
  --ry-z-toast: 1080;
207
272
 
208
273
  /* ═══════════════════════════════════════════════════════════════
209
- FOCUS
274
+ DERIVED: FOCUS — from primary
210
275
  ═══════════════════════════════════════════════════════════════ */
211
276
 
212
- --ry-focus-ring: 0 0 0 3px light-dark(oklch(0.623 0.188 259.8 / 0.5), oklch(0.714 0.143 254.6 / 0.5));
277
+ --ry-focus-ring: 0 0 0 3px color-mix(in oklch, var(--ry-color-primary) 50%, transparent);
213
278
  }
214
279
 
215
- /* Force light or dark mode (legacy — theme used to conflate theme + mode) */
280
+ /* Force light or dark mode */
216
281
  [data-ry-theme="light"] { color-scheme: light; }
217
282
  [data-ry-theme="dark"] { color-scheme: dark; }
218
283
 
@@ -241,16 +306,146 @@
241
306
  SCROLL LOCK (for modals, drawers)
242
307
  ═══════════════════════════════════════════════════════════════ */
243
308
 
309
+ body {
310
+ margin: 0;
311
+ min-height: 100dvh;
312
+ line-height: 1.5;
313
+ -webkit-font-smoothing: antialiased;
314
+ text-rendering: optimizeLegibility;
315
+ }
316
+
244
317
  body[data-ry-scroll-lock] {
245
318
  overflow: hidden;
246
319
  padding-right: var(--ry-scrollbar-width, 0);
247
320
  }
248
321
 
322
+ /* ═══════════════════════════════════════════════════════════════
323
+ PREFLIGHT RESET (opt-in via data-ry-reset on body/html)
324
+ Faithful equivalent of Tailwind Preflight.
325
+ ═══════════════════════════════════════════════════════════════ */
326
+
327
+ /* Universal — :where() gives zero specificity so component styles always win */
328
+ :where([data-ry-reset]) *,
329
+ :where([data-ry-reset]) *::before,
330
+ :where([data-ry-reset]) *::after,
331
+ :where([data-ry-reset]) *::backdrop {
332
+ box-sizing: border-box;
333
+ margin: 0;
334
+ padding: 0;
335
+ border: 0 solid;
336
+ }
337
+
338
+ /* Root */
339
+ :where([data-ry-reset]) {
340
+ line-height: 1.5;
341
+ -webkit-text-size-adjust: 100%;
342
+ tab-size: 4;
343
+ -webkit-tap-highlight-color: transparent;
344
+ }
345
+
346
+ /* Typography */
347
+ :where([data-ry-reset]) :where(h1, h2, h3, h4, h5, h6) {
348
+ font-size: inherit;
349
+ font-weight: inherit;
350
+ }
351
+ :where([data-ry-reset]) :where(a) {
352
+ color: inherit;
353
+ text-decoration: inherit;
354
+ }
355
+ :where([data-ry-reset]) :where(b, strong) {
356
+ font-weight: bolder;
357
+ }
358
+ :where([data-ry-reset]) :where(code, kbd, samp, pre) {
359
+ font-size: 1em;
360
+ }
361
+ :where([data-ry-reset]) :where(small) {
362
+ font-size: 80%;
363
+ }
364
+ :where([data-ry-reset]) :where(sub, sup) {
365
+ font-size: 75%;
366
+ line-height: 0;
367
+ position: relative;
368
+ vertical-align: baseline;
369
+ }
370
+ :where([data-ry-reset]) :where(sub) { bottom: -0.25em; }
371
+ :where([data-ry-reset]) :where(sup) { top: -0.5em; }
372
+
373
+ /* Lists */
374
+ :where([data-ry-reset]) :where(ol, ul, menu) {
375
+ list-style: none;
376
+ }
377
+
378
+ /* Table */
379
+ :where([data-ry-reset]) :where(table) {
380
+ text-indent: 0;
381
+ border-color: inherit;
382
+ border-collapse: collapse;
383
+ }
384
+
385
+ /* HR */
386
+ :where([data-ry-reset]) :where(hr) {
387
+ height: 0;
388
+ color: inherit;
389
+ border-top-width: 1px;
390
+ }
391
+
392
+ /* Media */
393
+ :where([data-ry-reset]) :where(img, svg, video, canvas, audio, iframe, embed, object) {
394
+ display: block;
395
+ vertical-align: middle;
396
+ }
397
+ :where([data-ry-reset]) :where(img, video) {
398
+ max-width: 100%;
399
+ height: auto;
400
+ }
401
+
402
+ /* Form controls */
403
+ :where([data-ry-reset]) :where(button, input, select, optgroup, textarea) {
404
+ font: inherit;
405
+ font-feature-settings: inherit;
406
+ font-variation-settings: inherit;
407
+ letter-spacing: inherit;
408
+ color: inherit;
409
+ border-radius: 0;
410
+ background-color: transparent;
411
+ }
412
+ :where([data-ry-reset]) ::placeholder {
413
+ opacity: 1;
414
+ }
415
+ @supports (color: color-mix(in oklab, currentcolor 50%, transparent)) {
416
+ :where([data-ry-reset]) ::placeholder {
417
+ color: color-mix(in oklab, currentcolor 50%, transparent);
418
+ }
419
+ }
420
+ :where([data-ry-reset]) :where(textarea) {
421
+ resize: vertical;
422
+ }
423
+ :where([data-ry-reset]) :where(button, input:where([type='button'], [type='reset'], [type='submit'])) {
424
+ appearance: button;
425
+ }
426
+ :where([data-ry-reset]) ::-webkit-search-decoration {
427
+ -webkit-appearance: none;
428
+ }
429
+ :where([data-ry-reset]) ::-webkit-inner-spin-button,
430
+ :where([data-ry-reset]) ::-webkit-outer-spin-button {
431
+ height: auto;
432
+ }
433
+
434
+ /* Misc */
435
+ :where([data-ry-reset]) :where(summary) {
436
+ display: list-item;
437
+ }
438
+ :where([data-ry-reset]) :where([hidden]:not([hidden='until-found'])) {
439
+ display: none !important;
440
+ }
441
+
249
442
  /* ═══════════════════════════════════════════════════════════════
250
443
  TRANSFORM WRAPPER (FOUC prevention)
251
444
  ═══════════════════════════════════════════════════════════════ */
252
445
 
253
- ry {
446
+ ry,
447
+ ry-search-item,
448
+ ry-search-group {
254
449
  display: none;
255
450
  }
256
451
 
@@ -262,13 +457,14 @@ ry {
262
457
  ry-page, ry-header, ry-main, ry-footer, ry-section, ry-aside,
263
458
  ry-grid, ry-stack, ry-cluster, ry-split, ry-center,
264
459
  ry-card, ry-accordion, ry-modal, ry-tabs, ry-dropdown,
265
- ry-button, ry-button-group, ry-badge, ry-alert, ry-field, ry-nav, ry-logo, ry-actions,
460
+ ry-button, ry-badge, ry-alert, ry-field, ry-nav, ry-logo, ry-actions,
266
461
  ry-accordion-item, ry-tab, ry-menu, ry-menu-item, ry-divider,
267
462
  ry-theme-toggle, ry-select, ry-switch, ry-tooltip, ry-drawer, ry-toast,
268
463
  ry-toggle-button, ry-knob, ry-slider, ry-number-select, ry-color-picker, ry-color-input,
269
464
  ry-gradient-picker, ry-tree, ry-tree-item,
270
465
  ry-tag, ry-tag-input, ry-hero, ry-stat, ry-feature, ry-feature-grid,
271
- ry-pricing, ry-pricing-card, ry-carousel, ry-combobox) {
466
+ ry-pricing, ry-pricing-card, ry-carousel, ry-combobox, ry-heading,
467
+ ry-logo-bar) {
272
468
  box-sizing: border-box;
273
469
  }
274
470
 
@@ -313,7 +509,8 @@ ry {
313
509
  :is(ry-modal [data-ry-target="header"] h3,
314
510
  ry-card h3,
315
511
  ry-hero h1,
316
- ry-pricing-card h3) {
512
+ ry-pricing-card h3,
513
+ ry-heading [data-ry-target="title"]) {
317
514
  text-wrap: balance;
318
515
  }
319
516
 
@@ -328,6 +525,7 @@ ry-page {
328
525
  min-height: 100dvh;
329
526
  container-type: inline-size;
330
527
  scrollbar-gutter: stable;
528
+ overflow-x: clip;
331
529
  }
332
530
 
333
531
  /* ═══════════════════════════════════════════════════════════════
@@ -371,6 +569,51 @@ ry-footer {
371
569
  text-align: center;
372
570
  }
373
571
 
572
+ /* Full footer with columns */
573
+ ry-footer[layout="columns"] {
574
+ text-align: start;
575
+ padding: var(--ry-space-12, 3rem) var(--ry-space-6, 1.5rem);
576
+ }
577
+
578
+ ry-footer[layout="columns"] > [data-ry-target="columns"],
579
+ ry-footer[layout="columns"] > .ry-footer__columns {
580
+ display: grid;
581
+ grid-template-columns: 1.5fr repeat(auto-fit, minmax(8rem, 1fr));
582
+ gap: var(--ry-space-8, 2rem);
583
+ padding-block-end: var(--ry-space-8, 2rem);
584
+ }
585
+
586
+ ry-footer[layout="columns"] > [data-ry-target="columns"] nav,
587
+ ry-footer[layout="columns"] > .ry-footer__columns nav {
588
+ display: flex;
589
+ flex-direction: column;
590
+ gap: var(--ry-space-2, 0.5rem);
591
+ }
592
+
593
+ ry-footer[layout="columns"] > [data-ry-target="columns"] nav strong,
594
+ ry-footer[layout="columns"] > .ry-footer__columns nav strong {
595
+ margin-block-end: var(--ry-space-2, 0.5rem);
596
+ }
597
+
598
+ ry-footer[layout="columns"] > [data-ry-target="bottom"],
599
+ ry-footer[layout="columns"] > .ry-footer__bottom {
600
+ display: flex;
601
+ justify-content: space-between;
602
+ align-items: center;
603
+ flex-wrap: wrap;
604
+ gap: var(--ry-space-4, 1rem);
605
+ padding-block-start: var(--ry-space-6, 1.5rem);
606
+ border-top: 1px solid currentColor;
607
+ opacity: 0.5;
608
+ }
609
+
610
+ @media (max-width: 768px) {
611
+ ry-footer[layout="columns"] > [data-ry-target="columns"],
612
+ ry-footer[layout="columns"] > .ry-footer__columns {
613
+ grid-template-columns: 1fr 1fr;
614
+ }
615
+ }
616
+
374
617
  /* ═══════════════════════════════════════════════════════════════
375
618
  SECTION
376
619
  ═══════════════════════════════════════════════════════════════ */
@@ -389,19 +632,114 @@ ry-section[narrow] {
389
632
  margin-inline: auto;
390
633
  }
391
634
 
392
- /* Logo bar pattern */
393
- .ry-logo-bar {
394
- text-align: center;
635
+ /* Full-width breakout bg goes edge-to-edge, content stays centered */
636
+ ry-section[full],
637
+ ry-section[inverted],
638
+ ry-footer,
639
+ ry-logo-bar {
640
+ width: 100vw;
641
+ margin-inline-start: calc(50% - 50vw);
642
+ padding-inline: max(var(--ry-space-6, 1.5rem), calc(50vw - 50%));
395
643
  }
396
644
 
397
- .ry-logo-bar p {
398
- margin: 0 0 var(--ry-space-4, 1rem);
645
+ ry-section[inverted] {
646
+ padding-block: var(--ry-space-12, 3rem);
399
647
  }
400
648
 
401
- .ry-logo-bar ry-cluster {
402
- justify-content: center;
403
- gap: var(--ry-space-10, 2.5rem);
649
+ ry-section[pad-bottom="lg"] {
650
+ padding-bottom: var(--ry-space-20, 5rem);
651
+ }
652
+
653
+ /* ═══════════════════════════════════════════════════════════════
654
+ LOGO BAR
655
+ ═══════════════════════════════════════════════════════════════ */
656
+
657
+ ry-logo-bar {
658
+ display: flex;
404
659
  flex-wrap: wrap;
660
+ justify-content: center;
661
+ align-items: center;
662
+ gap: var(--ry-space-8, 2rem);
663
+ padding-block: var(--ry-space-8, 2rem);
664
+ text-align: center;
665
+ }
666
+
667
+ ry-logo-bar > p {
668
+ width: 100%;
669
+ margin: 0;
670
+ }
671
+
672
+ ry-logo-bar > :not(p) {
673
+ display: inline-flex;
674
+ align-items: center;
675
+ }
676
+
677
+ /* Scroll layout — horizontal scroll, no wrap */
678
+ ry-logo-bar[layout="scroll"] {
679
+ flex-wrap: nowrap;
680
+ overflow-x: auto;
681
+ overflow-y: hidden;
682
+ scrollbar-width: none;
683
+ -webkit-overflow-scrolling: touch;
684
+ }
685
+
686
+ ry-logo-bar[layout="scroll"]::-webkit-scrollbar {
687
+ display: none;
688
+ }
689
+
690
+ ry-logo-bar[layout="scroll"] > :not(p) {
691
+ flex-shrink: 0;
692
+ }
693
+
694
+ /* Marquee layout — infinite auto-scroll */
695
+ ry-logo-bar[layout="marquee"] {
696
+ flex-wrap: nowrap;
697
+ overflow: hidden;
698
+ }
699
+
700
+ ry-logo-bar[layout="marquee"] [data-ry-target="track"] {
701
+ display: flex;
702
+ align-items: center;
703
+ gap: var(--ry-space-8, 2rem);
704
+ width: max-content;
705
+ animation: ry-marquee var(--ry-logo-bar-speed, 30s) linear infinite;
706
+ }
707
+
708
+ ry-logo-bar[layout="marquee"] [data-ry-target="track"] > * {
709
+ display: inline-flex;
710
+ align-items: center;
711
+ flex-shrink: 0;
712
+ }
713
+
714
+ ry-logo-bar[layout="marquee"]:hover [data-ry-target="track"] {
715
+ animation-play-state: paused;
716
+ }
717
+
718
+ @keyframes ry-marquee {
719
+ from { transform: translateX(0); }
720
+ to { transform: translateX(-25%); }
721
+ }
722
+
723
+ /* Size variants */
724
+ ry-logo-bar[size="sm"] {
725
+ padding: var(--ry-space-4, 1rem) var(--ry-space-4, 1rem);
726
+ gap: var(--ry-space-4, 1rem);
727
+ }
728
+
729
+ ry-logo-bar[size="lg"] {
730
+ padding: var(--ry-space-12, 3rem) var(--ry-space-6, 1.5rem);
731
+ gap: var(--ry-space-6, 1.5rem);
732
+ }
733
+
734
+ /* Logo items */
735
+ ry-logo-bar img {
736
+ height: var(--ry-logo-bar-height, 2rem);
737
+ width: auto;
738
+ object-fit: contain;
739
+ }
740
+
741
+ ry-logo-bar span {
742
+ white-space: nowrap;
405
743
  }
406
744
 
407
745
  /* ═══════════════════════════════════════════════════════════════
@@ -429,6 +767,13 @@ ry-grid[cols="auto-fill"] {
429
767
  grid-template-columns: repeat(auto-fill, minmax(var(--ry-grid-min, 280px), 1fr));
430
768
  }
431
769
 
770
+ ry-grid[overlap] {
771
+ position: relative;
772
+ z-index: 1;
773
+ margin-top: calc(-1 * var(--ry-space-12, 3rem));
774
+ padding-inline: var(--ry-space-6, 1.5rem);
775
+ }
776
+
432
777
  /* Default responsive behavior */
433
778
  @container (max-width: 640px) {
434
779
  :is(ry-grid[cols="2"], ry-grid[cols="3"], ry-grid[cols="4"],
@@ -584,11 +929,13 @@ ry-center {
584
929
  ry-nav {
585
930
  display: flex;
586
931
  align-items: center;
587
- gap: var(--ry-space-4, 1rem);
932
+ gap: var(--ry-space-1, 0.25rem);
588
933
  }
589
934
 
590
935
  ry-nav a {
591
936
  text-decoration: none;
937
+ padding: var(--ry-space-2, 0.5rem) var(--ry-space-3, 0.75rem);
938
+ white-space: nowrap;
592
939
  }
593
940
 
594
941
  /* ═══════════════════════════════════════════════════════════════
@@ -608,6 +955,7 @@ ry-actions {
608
955
  display: flex;
609
956
  align-items: center;
610
957
  gap: var(--ry-space-2, 0.5rem);
958
+ margin-inline-start: auto;
611
959
  }
612
960
 
613
961
  /* ═══════════════════════════════════════════════════════════════
@@ -667,19 +1015,13 @@ ry-button[icon][size="sm"]:empty {
667
1015
  padding: var(--ry-space-1, 0.25rem);
668
1016
  }
669
1017
 
670
- /* ═══════════════════════════════════════════════════════════════
671
- BUTTON GROUP
672
- ═══════════════════════════════════════════════════════════════ */
673
-
674
- ry-button-group {
675
- display: inline-flex;
676
- gap: 2px;
677
- padding: 2px;
678
- border-radius: var(--ry-radius-md, 0.375rem);
679
- }
680
-
681
- ry-button-group > :is(ry-button, ry-toggle-button) {
682
- border-radius: calc(var(--ry-radius-md, 0.375rem) - 2px);
1018
+ /* Link variant — inline text link style */
1019
+ ry-button[variant="link"] {
1020
+ background: none;
1021
+ border: none;
1022
+ padding: 0;
1023
+ display: inline;
1024
+ cursor: pointer;
683
1025
  }
684
1026
 
685
1027
  /* ═══════════════════════════════════════════════════════════════
@@ -1083,6 +1425,12 @@ ry-card p:last-child {
1083
1425
  margin-bottom: 0;
1084
1426
  }
1085
1427
 
1428
+ ry-card > img:first-child {
1429
+ display: block;
1430
+ width: 100%;
1431
+ margin-bottom: var(--ry-space-4, 1rem);
1432
+ }
1433
+
1086
1434
  /* ═══════════════════════════════════════════════════════════════
1087
1435
  BADGES
1088
1436
  ═══════════════════════════════════════════════════════════════ */
@@ -1104,7 +1452,7 @@ ry-alert {
1104
1452
  padding: var(--ry-space-4, 1rem);
1105
1453
  }
1106
1454
 
1107
- ry-alert [slot="title"] {
1455
+ .ry-alert__title {
1108
1456
  margin: 0 0 var(--ry-space-1, 0.25rem) 0;
1109
1457
  }
1110
1458
 
@@ -1816,7 +2164,11 @@ ry-select[multiple] [data-ry-target="trigger"] {
1816
2164
  }
1817
2165
 
1818
2166
  ry-select[multiple] [data-ry-target="tags"] {
1819
- display: contents;
2167
+ display: flex;
2168
+ flex-wrap: wrap;
2169
+ flex: 1 1 0%;
2170
+ gap: var(--ry-space-1, 0.25rem);
2171
+ align-items: center;
1820
2172
  }
1821
2173
 
1822
2174
  ry-select[multiple] [data-ry-target="clear"] {
@@ -2789,6 +3141,40 @@ ry-tag-input[disabled] [data-ry-target="container"] {
2789
3141
  cursor: not-allowed;
2790
3142
  }
2791
3143
 
3144
+ /* ═══════════════════════════════════════════════════════════════
3145
+ DEVICE FRAME (CSS-only phone mockup)
3146
+ ═══════════════════════════════════════════════════════════════ */
3147
+
3148
+ .ry-phone {
3149
+ position: relative;
3150
+ display: inline-block;
3151
+ padding: 0.75rem;
3152
+ border-radius: 2.5rem;
3153
+ border: 3px solid currentColor;
3154
+ overflow: hidden;
3155
+ max-width: 20rem;
3156
+ }
3157
+
3158
+ .ry-phone::before {
3159
+ content: '';
3160
+ position: absolute;
3161
+ top: 0.75rem;
3162
+ left: 50%;
3163
+ transform: translateX(-50%);
3164
+ width: 5rem;
3165
+ height: 1.5rem;
3166
+ border-radius: 0 0 1rem 1rem;
3167
+ background: currentColor;
3168
+ z-index: 1;
3169
+ }
3170
+
3171
+ .ry-phone img {
3172
+ display: block;
3173
+ width: 100%;
3174
+ height: auto;
3175
+ border-radius: 1.75rem;
3176
+ }
3177
+
2792
3178
  /* ═══════════════════════════════════════════════════════════════
2793
3179
  HERO
2794
3180
  ═══════════════════════════════════════════════════════════════ */
@@ -2827,12 +3213,97 @@ ry-hero[size="sm"] {
2827
3213
  padding: var(--ry-space-8, 2rem) var(--ry-space-6, 1.5rem);
2828
3214
  }
2829
3215
 
2830
- ry-hero[size="lg"] {
2831
- padding: var(--ry-space-20, 5rem) var(--ry-space-6, 1.5rem);
2832
- }
3216
+ ry-hero[size="lg"] {
3217
+ padding: var(--ry-space-20, 5rem) var(--ry-space-6, 1.5rem);
3218
+ }
3219
+
3220
+ ry-hero[size="full"] {
3221
+ min-height: 100vh;
3222
+ min-height: 100dvh;
3223
+ justify-content: center;
3224
+ }
3225
+
3226
+ ry-hero[full-bleed] {
3227
+ max-width: none;
3228
+ }
3229
+
3230
+ /* Split layout: text + media side by side */
3231
+ ry-hero[layout="split"] {
3232
+ display: grid;
3233
+ grid-template-columns: 1fr 1fr;
3234
+ align-items: center;
3235
+ text-align: start;
3236
+ gap: 0;
3237
+ max-width: none;
3238
+ padding: 0;
3239
+ overflow: hidden;
3240
+ }
3241
+
3242
+ ry-hero[layout="split"] > *:first-child {
3243
+ display: flex;
3244
+ flex-direction: column;
3245
+ align-items: flex-start;
3246
+ gap: var(--ry-space-4, 1rem);
3247
+ padding: var(--ry-space-12, 3rem) var(--ry-space-12, 3rem) var(--ry-space-12, 3rem) clamp(var(--ry-space-6, 1.5rem), 8vw, 10rem);
3248
+ }
3249
+
3250
+ ry-hero[layout="split"] > *:first-child > * + * {
3251
+ margin-block-start: 0;
3252
+ }
3253
+
3254
+ ry-hero[layout="split"] > *:last-child {
3255
+ align-self: stretch;
3256
+ position: relative;
3257
+ overflow: hidden;
3258
+ }
3259
+
3260
+ ry-hero[layout="split"] > *:last-child img {
3261
+ display: block;
3262
+ width: 100%;
3263
+ height: 100%;
3264
+ object-fit: cover;
3265
+ object-position: center;
3266
+ }
3267
+
3268
+ /* Full viewport height for split */
3269
+ ry-hero[layout="split"][size="full"] {
3270
+ min-height: 100vh;
3271
+ min-height: 100dvh;
3272
+ }
3273
+
3274
+ /* Flip: image left, text right */
3275
+ ry-hero[layout="split"][reverse] {
3276
+ direction: rtl;
3277
+ }
3278
+
3279
+ ry-hero[layout="split"][reverse] > * {
3280
+ direction: ltr;
3281
+ }
3282
+
3283
+ ry-hero[layout="split"][reverse] > *:first-child {
3284
+ padding-inline: var(--ry-space-12, 3rem) clamp(var(--ry-space-6, 1.5rem), 8vw, 10rem);
3285
+ }
3286
+
3287
+ @media (max-width: 768px) {
3288
+ ry-hero[layout="split"] {
3289
+ grid-template-columns: 1fr;
3290
+ }
3291
+
3292
+ ry-hero[layout="split"] > *:first-child {
3293
+ padding: var(--ry-space-8, 2rem) var(--ry-space-6, 1.5rem);
3294
+ }
3295
+
3296
+ ry-hero[layout="split"][reverse] > *:first-child {
3297
+ padding: var(--ry-space-8, 2rem) var(--ry-space-6, 1.5rem);
3298
+ }
2833
3299
 
2834
- ry-hero[full-bleed] {
2835
- max-width: none;
3300
+ ry-hero[layout="split"] > *:last-child {
3301
+ max-height: 20rem;
3302
+ }
3303
+
3304
+ ry-hero[layout="split"][size="full"] {
3305
+ min-height: auto;
3306
+ }
2836
3307
  }
2837
3308
 
2838
3309
  /* ═══════════════════════════════════════════════════════════════
@@ -2963,11 +3434,11 @@ ry-pricing-card h3 {
2963
3434
  margin: 0 0 var(--ry-space-2, 0.5rem) 0;
2964
3435
  }
2965
3436
 
2966
- ry-pricing-card [slot="price"] {
3437
+ .ry-pricing-card__price {
2967
3438
  margin-block-end: var(--ry-space-6, 1.5rem);
2968
3439
  }
2969
3440
 
2970
- ry-pricing-card [slot="price"] span {
3441
+ .ry-pricing-card__price span {
2971
3442
  display: inline;
2972
3443
  }
2973
3444
 
@@ -3275,6 +3746,125 @@ ry-theme-panel [data-ry-target="mode-btn"] {
3275
3746
  line-height: 1;
3276
3747
  }
3277
3748
 
3749
+ /* ═══════════════════════════════════════════════════════════════
3750
+ HEADING
3751
+ ═══════════════════════════════════════════════════════════════ */
3752
+
3753
+ ry-heading {
3754
+ display: flex;
3755
+ flex-direction: column;
3756
+ gap: var(--ry-space-2, 0.5rem);
3757
+ }
3758
+
3759
+ ry-heading[align="center"] {
3760
+ text-align: center;
3761
+ }
3762
+
3763
+ ry-heading[align="right"] {
3764
+ text-align: end;
3765
+ }
3766
+
3767
+ /* Balanced text wrapping for heading titles */
3768
+ ry-heading [data-ry-target="title"] {
3769
+ text-wrap: balance;
3770
+ margin: 0;
3771
+ }
3772
+
3773
+ ry-heading [data-ry-target="sub"] {
3774
+ margin: 0;
3775
+ }
3776
+
3777
+ /* Divider variant: adds a bottom border */
3778
+ ry-heading[divider] {
3779
+ padding-block-end: var(--ry-space-4, 1rem);
3780
+ }
3781
+
3782
+ /* ═══════════════════════════════════════════════════════════════
3783
+ SEARCH LIST
3784
+ ═══════════════════════════════════════════════════════════════ */
3785
+
3786
+ ry-search-list {
3787
+ display: flex;
3788
+ flex-direction: column;
3789
+ overflow: hidden;
3790
+ min-height: 0;
3791
+ }
3792
+
3793
+ ry-search-list [data-ry-target="search"] {
3794
+ flex-shrink: 0;
3795
+ padding: var(--ry-space-2) var(--ry-space-3);
3796
+ position: sticky;
3797
+ top: 0;
3798
+ z-index: 1;
3799
+ }
3800
+
3801
+ ry-search-list [data-ry-target="input"] {
3802
+ width: 100%;
3803
+ padding: var(--ry-space-2) var(--ry-space-3);
3804
+ border: none;
3805
+ background: transparent;
3806
+ font: inherit;
3807
+ outline: none;
3808
+ }
3809
+
3810
+ ry-search-list [data-ry-target="list"] {
3811
+ flex: 1;
3812
+ overflow-y: auto;
3813
+ min-height: 0;
3814
+ padding: var(--ry-space-1) var(--ry-space-2);
3815
+ }
3816
+
3817
+ ry-search-list [data-ry-target="item"] {
3818
+ display: flex;
3819
+ align-items: center;
3820
+ padding: var(--ry-space-1) var(--ry-space-3);
3821
+ cursor: pointer;
3822
+ user-select: none;
3823
+ }
3824
+
3825
+ ry-search-list [data-ry-target="item"][hidden] {
3826
+ display: none;
3827
+ }
3828
+
3829
+ ry-search-list [data-ry-target="group-header"] {
3830
+ padding: var(--ry-space-2) var(--ry-space-3);
3831
+ padding-top: var(--ry-space-4);
3832
+ font-size: 0.6875rem;
3833
+ text-transform: uppercase;
3834
+ letter-spacing: 0.05em;
3835
+ pointer-events: none;
3836
+ user-select: none;
3837
+ }
3838
+
3839
+ ry-search-list [data-ry-target="group"][hidden] {
3840
+ display: none;
3841
+ }
3842
+
3843
+ ry-search-list [data-ry-target="empty"] {
3844
+ padding: var(--ry-space-6) var(--ry-space-3);
3845
+ text-align: center;
3846
+ }
3847
+
3848
+ ry-search-list [data-ry-target="empty"][hidden] {
3849
+ display: none;
3850
+ }
3851
+
3852
+ /* ═══════════════════════════════════════════════════════════════
3853
+ UTILITIES
3854
+ ═══════════════════════════════════════════════════════════════ */
3855
+
3856
+ .ry-avatar {
3857
+ display: block;
3858
+ width: 4rem;
3859
+ height: 4rem;
3860
+ margin-bottom: var(--ry-space-4, 1rem);
3861
+ }
3862
+
3863
+ .ry-avatar[data-size="lg"] {
3864
+ width: 6rem;
3865
+ height: 6rem;
3866
+ }
3867
+
3278
3868
  } /* @layer ry-structure */
3279
3869
 
3280
3870
  /**
@@ -3295,6 +3885,46 @@ html {
3295
3885
  background-color: var(--ry-color-bg);
3296
3886
  }
3297
3887
 
3888
+ /* ═══════════════════════════════════════════════════════════════
3889
+ SECTION — INVERTED
3890
+ ═══════════════════════════════════════════════════════════════ */
3891
+
3892
+ ry-section[inverted] {
3893
+ background-color: var(--ry-color-text);
3894
+ color: var(--ry-color-bg);
3895
+ border-radius: var(--ry-radius-lg);
3896
+ }
3897
+
3898
+ ry-section[inverted] :is(h1, h2, h3, h4, p, span, a) {
3899
+ color: inherit;
3900
+ }
3901
+
3902
+ ry-section[inverted] p {
3903
+ opacity: 0.7;
3904
+ }
3905
+
3906
+ /* ═══════════════════════════════════════════════════════════════
3907
+ FOOTER — INVERTED
3908
+ ═══════════════════════════════════════════════════════════════ */
3909
+
3910
+ ry-footer[inverted] {
3911
+ background-color: var(--ry-color-text);
3912
+ color: var(--ry-color-bg);
3913
+ }
3914
+
3915
+ ry-footer[inverted] :is(a, strong, p, span, nav) {
3916
+ color: inherit;
3917
+ }
3918
+
3919
+ ry-footer[inverted] a {
3920
+ opacity: 0.7;
3921
+ transition: opacity var(--ry-duration-fast);
3922
+ }
3923
+
3924
+ ry-footer[inverted] a:hover {
3925
+ opacity: 1;
3926
+ }
3927
+
3298
3928
  /* ═══════════════════════════════════════════════════════════════
3299
3929
  FOCUS STYLES
3300
3930
  ═══════════════════════════════════════════════════════════════ */
@@ -3397,11 +4027,14 @@ ry-nav a {
3397
4027
  color: var(--ry-color-text-muted);
3398
4028
  font-size: var(--ry-text-sm);
3399
4029
  font-weight: var(--ry-font-medium);
3400
- transition: color var(--ry-duration-fast) var(--ry-ease);
4030
+ border-radius: var(--ry-radius-md);
4031
+ transition: color var(--ry-duration-fast) var(--ry-ease),
4032
+ background-color var(--ry-duration-fast) var(--ry-ease);
3401
4033
  }
3402
4034
 
3403
4035
  ry-nav a:hover {
3404
4036
  color: var(--ry-color-text);
4037
+ background-color: var(--ry-color-hover-overlay);
3405
4038
  }
3406
4039
 
3407
4040
  ry-nav a[aria-current="page"] {
@@ -3452,7 +4085,7 @@ ry-split [data-ry-target="handle"]:focus-visible::after {
3452
4085
  BUTTONS
3453
4086
  ═══════════════════════════════════════════════════════════════ */
3454
4087
 
3455
- :is(.ry-btn, ry-button) {
4088
+ :is(:where(.ry-btn), ry-button) {
3456
4089
  font-family: var(--ry-font-sans);
3457
4090
  font-size: var(--ry-text-sm);
3458
4091
  font-weight: var(--ry-font-medium);
@@ -3469,93 +4102,88 @@ ry-split [data-ry-target="handle"]:focus-visible::after {
3469
4102
  transition-timing-function: var(--ry-ease);
3470
4103
  }
3471
4104
 
3472
- :is(.ry-btn, ry-button):hover {
4105
+ :is(:where(.ry-btn), ry-button):hover {
3473
4106
  background-color: var(--ry-color-primary-hover);
3474
4107
  }
3475
4108
 
3476
- :is(.ry-btn, ry-button):active {
4109
+ :is(:where(.ry-btn), ry-button):active {
3477
4110
  background-color: var(--ry-color-primary-active);
3478
4111
  }
3479
4112
 
3480
- :is(.ry-btn:disabled, .ry-btn[aria-disabled="true"], ry-button[disabled]) {
4113
+ :is(:where(.ry-btn:disabled, .ry-btn[aria-disabled="true"]), ry-button[disabled]) {
3481
4114
  opacity: 0.5;
3482
4115
  }
3483
4116
 
3484
4117
  /* Button variants */
3485
- :is(.ry-btn--secondary, ry-button[variant="secondary"]) {
4118
+ :is(:where(.ry-btn--secondary), ry-button[variant="secondary"]) {
3486
4119
  background-color: var(--ry-color-secondary);
3487
4120
  }
3488
- :is(.ry-btn--secondary, ry-button[variant="secondary"]):hover {
4121
+ :is(:where(.ry-btn--secondary), ry-button[variant="secondary"]):hover {
3489
4122
  background-color: var(--ry-color-secondary-hover);
3490
4123
  }
3491
4124
 
3492
- :is(.ry-btn--outline, ry-button[variant="outline"]) {
4125
+ :is(:where(.ry-btn--outline), ry-button[variant="outline"]) {
3493
4126
  background-color: transparent;
3494
4127
  color: var(--ry-color-primary);
3495
4128
  border-color: var(--ry-color-primary);
3496
4129
  }
3497
- :is(.ry-btn--outline, ry-button[variant="outline"]):hover {
4130
+ :is(:where(.ry-btn--outline), ry-button[variant="outline"]):hover {
3498
4131
  background-color: var(--ry-color-primary);
3499
4132
  color: var(--ry-color-text-inverse);
3500
4133
  }
3501
4134
 
3502
- :is(.ry-btn--ghost, ry-button[variant="ghost"]) {
4135
+ :is(:where(.ry-btn--ghost), ry-button[variant="ghost"]) {
3503
4136
  background-color: transparent;
3504
4137
  color: var(--ry-color-text);
3505
4138
  }
3506
- :is(.ry-btn--ghost, ry-button[variant="ghost"]):hover {
4139
+ :is(:where(.ry-btn--ghost), ry-button[variant="ghost"]):hover {
3507
4140
  background-color: var(--ry-color-bg-muted);
3508
4141
  }
3509
4142
 
3510
- :is(.ry-btn--danger, ry-button[variant="danger"]) {
4143
+ :is(:where(.ry-btn--danger), ry-button[variant="danger"]) {
3511
4144
  background-color: var(--ry-color-danger);
3512
4145
  }
3513
- :is(.ry-btn--danger, ry-button[variant="danger"]):hover {
4146
+ :is(:where(.ry-btn--danger), ry-button[variant="danger"]):hover {
3514
4147
  background-color: var(--ry-color-danger-hover);
3515
4148
  }
3516
4149
 
3517
- :is(.ry-btn--accent, ry-button[variant="accent"]) {
4150
+ :is(:where(.ry-btn--accent), ry-button[variant="accent"]) {
3518
4151
  background-color: var(--ry-color-accent);
3519
4152
  }
3520
- :is(.ry-btn--accent, ry-button[variant="accent"]):hover {
4153
+ :is(:where(.ry-btn--accent), ry-button[variant="accent"]):hover {
3521
4154
  background-color: var(--ry-color-accent-hover);
3522
4155
  }
3523
4156
 
4157
+ /* Link variant — inline text link */
4158
+ :is(:where(.ry-btn--link), ry-button[variant="link"]) {
4159
+ background: none;
4160
+ color: var(--ry-color-primary);
4161
+ font-weight: var(--ry-font-semibold);
4162
+ text-decoration: none;
4163
+ border: none;
4164
+ }
4165
+ :is(:where(.ry-btn--link), ry-button[variant="link"]):hover {
4166
+ text-decoration: underline;
4167
+ }
4168
+
3524
4169
  /* Pressed/active toggle state */
3525
- :is(.ry-btn[aria-pressed="true"], ry-button[pressed]) {
4170
+ :is(:where(.ry-btn[aria-pressed="true"]), ry-button[pressed]) {
3526
4171
  background-color: var(--ry-color-primary);
3527
4172
  color: var(--ry-color-text-inverse);
3528
4173
  border-color: var(--ry-color-primary);
3529
4174
  }
3530
- :is(.ry-btn[aria-pressed="true"], ry-button[pressed]):hover {
4175
+ :is(:where(.ry-btn[aria-pressed="true"]), ry-button[pressed]):hover {
3531
4176
  background-color: var(--ry-color-primary-hover);
3532
4177
  border-color: var(--ry-color-primary-hover);
3533
4178
  }
3534
4179
 
3535
- /* ═══════════════════════════════════════════════════════════════
3536
- BUTTON GROUP
3537
- ═══════════════════════════════════════════════════════════════ */
3538
-
3539
- ry-button-group {
3540
- background-color: var(--ry-color-bg-muted);
3541
- }
3542
-
3543
- ry-button-group > :is(ry-button, ry-toggle-button) {
3544
- border-color: transparent;
3545
- background-color: transparent;
3546
- color: var(--ry-color-text-muted);
3547
- }
3548
-
3549
- ry-button-group > :is(ry-button, ry-toggle-button):hover:not([pressed]) {
3550
- color: var(--ry-color-text);
3551
- }
3552
4180
 
3553
4181
  /* Button sizes (typography only - padding is structural) */
3554
- :is(.ry-btn--sm, ry-button[size="sm"]) {
4182
+ :is(:where(.ry-btn--sm), ry-button[size="sm"]) {
3555
4183
  font-size: var(--ry-text-xs);
3556
4184
  }
3557
4185
 
3558
- :is(.ry-btn--lg, ry-button[size="lg"]) {
4186
+ :is(:where(.ry-btn--lg), ry-button[size="lg"]) {
3559
4187
  font-size: var(--ry-text-base);
3560
4188
  }
3561
4189
 
@@ -4004,6 +4632,10 @@ ry-card p {
4004
4632
  color: var(--ry-color-text-muted);
4005
4633
  }
4006
4634
 
4635
+ ry-card > img:first-child {
4636
+ border-radius: var(--ry-radius-md);
4637
+ }
4638
+
4007
4639
  /* ═══════════════════════════════════════════════════════════════
4008
4640
  BADGES
4009
4641
  ═══════════════════════════════════════════════════════════════ */
@@ -4081,7 +4713,7 @@ ry-badge[style*="--ry-badge-color"] {
4081
4713
  color: var(--ry-color-danger-text);
4082
4714
  }
4083
4715
 
4084
- :is(.ry-alert__title, ry-alert [slot="title"]) {
4716
+ .ry-alert__title {
4085
4717
  font-weight: var(--ry-font-semibold);
4086
4718
  }
4087
4719
 
@@ -5425,13 +6057,13 @@ ry-pricing-card h3 {
5425
6057
  color: var(--ry-color-text);
5426
6058
  }
5427
6059
 
5428
- ry-pricing-card [slot="price"] {
6060
+ .ry-pricing-card__price {
5429
6061
  font-size: var(--ry-text-4xl);
5430
6062
  font-weight: var(--ry-font-bold);
5431
6063
  color: var(--ry-color-text);
5432
6064
  }
5433
6065
 
5434
- ry-pricing-card [slot="price"] span {
6066
+ .ry-pricing-card__price span {
5435
6067
  font-size: var(--ry-text-base);
5436
6068
  font-weight: var(--ry-font-normal);
5437
6069
  color: var(--ry-color-text-muted);
@@ -5601,18 +6233,34 @@ ry-combobox[data-ry-state="open"] .ry-combobox__input-wrapper {
5601
6233
  LOGO BAR
5602
6234
  ═══════════════════════════════════════════════════════════════ */
5603
6235
 
5604
- .ry-logo-bar p {
6236
+ ry-logo-bar > p {
5605
6237
  color: var(--ry-color-text-muted);
5606
6238
  font-size: var(--ry-text-sm);
6239
+ font-family: var(--ry-font-sans);
5607
6240
  text-transform: uppercase;
5608
6241
  letter-spacing: 0.1em;
5609
6242
  }
5610
6243
 
5611
- .ry-logo-bar span {
6244
+ ry-logo-bar span {
5612
6245
  font-size: var(--ry-text-2xl);
5613
6246
  font-weight: var(--ry-font-bold);
6247
+ font-family: var(--ry-font-sans);
5614
6248
  color: var(--ry-color-text);
5615
6249
  opacity: 0.5;
6250
+ transition: opacity var(--ry-duration-fast) var(--ry-ease);
6251
+ }
6252
+
6253
+ ry-logo-bar span:hover {
6254
+ opacity: 0.8;
6255
+ }
6256
+
6257
+ ry-logo-bar img {
6258
+ opacity: 0.5;
6259
+ transition: opacity var(--ry-duration-fast) var(--ry-ease);
6260
+ }
6261
+
6262
+ ry-logo-bar img:hover {
6263
+ opacity: 0.8;
5616
6264
  }
5617
6265
 
5618
6266
  /* ═══════════════════════════════════════════════════════════════
@@ -5656,6 +6304,28 @@ ry-combobox[data-ry-state="open"] .ry-combobox__input-wrapper {
5656
6304
  ═══════════════════════════════════════════════════════════════ */
5657
6305
 
5658
6306
  [data-ry-theme="none"] {
6307
+ /* Strictly black and white */
6308
+ --ry-color-primary: light-dark(#000000, #ffffff);
6309
+ --ry-color-primary-hover: light-dark(#333333, #cccccc);
6310
+ --ry-color-primary-active: light-dark(#555555, #aaaaaa);
6311
+ --ry-color-secondary: light-dark(#000000, #ffffff);
6312
+ --ry-color-secondary-hover: light-dark(#333333, #cccccc);
6313
+ --ry-color-secondary-active: light-dark(#555555, #aaaaaa);
6314
+ --ry-color-accent: light-dark(#000000, #ffffff);
6315
+ --ry-color-accent-hover: light-dark(#333333, #cccccc);
6316
+ --ry-color-accent-active: light-dark(#555555, #aaaaaa);
6317
+ --ry-color-text: light-dark(#000000, #ffffff);
6318
+ --ry-color-text-muted: light-dark(#666666, #999999);
6319
+ --ry-color-text-inverse: light-dark(#ffffff, #000000);
6320
+ --ry-color-bg: light-dark(#ffffff, #000000);
6321
+ --ry-color-bg-subtle: light-dark(#f5f5f5, #0a0a0a);
6322
+ --ry-color-bg-muted: light-dark(#eeeeee, #111111);
6323
+ --ry-color-border: light-dark(#dddddd, #333333);
6324
+ --ry-color-border-strong: light-dark(#999999, #666666);
6325
+ --ry-color-overlay: light-dark(rgba(255,255,255,0.95), rgba(0,0,0,0.95));
6326
+ --ry-color-hover-overlay: light-dark(rgba(0,0,0,0.04), rgba(255,255,255,0.06));
6327
+ --ry-focus-ring: light-dark(0 0 0 3px rgba(0,0,0,0.3), 0 0 0 3px rgba(255,255,255,0.3));
6328
+ /* No radii, no shadows */
5659
6329
  --ry-radius-sm: 0;
5660
6330
  --ry-radius-md: 0;
5661
6331
  --ry-radius-lg: 0;
@@ -5701,4 +6371,135 @@ ry-combobox[data-ry-state="open"] .ry-combobox__input-wrapper {
5701
6371
  color: var(--ry-color-text-inverse);
5702
6372
  }
5703
6373
 
6374
+ /* ═══════════════════════════════════════════════════════════════
6375
+ HEADING
6376
+ ═══════════════════════════════════════════════════════════════ */
6377
+
6378
+ .ry-heading__title {
6379
+ font-size: var(--ry-text-2xl);
6380
+ font-weight: var(--ry-font-bold);
6381
+ line-height: var(--ry-leading-tight);
6382
+ color: var(--ry-color-text);
6383
+ }
6384
+
6385
+ .ry-heading__sub {
6386
+ font-size: var(--ry-text-base);
6387
+ line-height: var(--ry-leading-normal);
6388
+ color: var(--ry-color-text-muted);
6389
+ }
6390
+
6391
+ /* Size: sm */
6392
+ ry-heading[size="sm"] .ry-heading__title {
6393
+ font-size: var(--ry-text-lg);
6394
+ }
6395
+
6396
+ ry-heading[size="sm"] .ry-heading__sub {
6397
+ font-size: var(--ry-text-sm);
6398
+ }
6399
+
6400
+ /* Size: lg */
6401
+ ry-heading[size="lg"] .ry-heading__title {
6402
+ font-size: var(--ry-text-4xl);
6403
+ }
6404
+
6405
+ ry-heading[size="lg"] .ry-heading__sub {
6406
+ font-size: var(--ry-text-lg);
6407
+ }
6408
+
6409
+ /* Divider variant */
6410
+ ry-heading[divider] {
6411
+ border-bottom: var(--ry-border-width) solid var(--ry-color-border);
6412
+ }
6413
+
6414
+ /* ═══════════════════════════════════════════════════════════════
6415
+ SEARCH LIST
6416
+ ═══════════════════════════════════════════════════════════════ */
6417
+
6418
+ .ry-search-list__search {
6419
+ background-color: var(--ry-color-bg);
6420
+ border-bottom: var(--ry-border-width) solid var(--ry-color-border);
6421
+ }
6422
+
6423
+ .ry-search-list__input {
6424
+ font-family: var(--ry-font-sans);
6425
+ font-size: var(--ry-text-sm);
6426
+ color: var(--ry-color-text);
6427
+ }
6428
+
6429
+ .ry-search-list__input::placeholder {
6430
+ color: var(--ry-color-text-muted);
6431
+ }
6432
+
6433
+ .ry-search-list__item {
6434
+ font-size: var(--ry-text-sm);
6435
+ color: var(--ry-color-text);
6436
+ border-radius: var(--ry-radius-md);
6437
+ transition: background-color var(--ry-duration-fast) var(--ry-ease);
6438
+ }
6439
+
6440
+ .ry-search-list__item[data-highlighted] {
6441
+ background-color: var(--ry-color-bg-muted);
6442
+ }
6443
+
6444
+ .ry-search-list__item[aria-selected="true"] {
6445
+ background-color: var(--ry-color-primary);
6446
+ color: var(--ry-color-text-inverse);
6447
+ }
6448
+
6449
+ .ry-search-list__item[aria-selected="true"][data-highlighted] {
6450
+ background-color: var(--ry-color-primary-hover);
6451
+ }
6452
+
6453
+ .ry-search-list__group-header {
6454
+ font-family: var(--ry-font-sans);
6455
+ font-weight: 600;
6456
+ color: var(--ry-color-text-muted);
6457
+ }
6458
+
6459
+ .ry-search-list__empty {
6460
+ font-size: var(--ry-text-sm);
6461
+ color: var(--ry-color-text-muted);
6462
+ }
6463
+
6464
+ .ry-search-list__item mark {
6465
+ background-color: transparent;
6466
+ color: var(--ry-color-primary);
6467
+ font-weight: 600;
6468
+ }
6469
+
6470
+ .ry-search-list__item[aria-selected="true"] mark {
6471
+ color: inherit;
6472
+ text-decoration: underline;
6473
+ }
6474
+
6475
+ /* ═══════════════════════════════════════════════════════════════
6476
+ UTILITIES
6477
+ ═══════════════════════════════════════════════════════════════ */
6478
+
6479
+ .ry-eyebrow {
6480
+ text-transform: uppercase;
6481
+ letter-spacing: 0.1em;
6482
+ font-weight: var(--ry-font-semibold);
6483
+ font-size: var(--ry-text-sm);
6484
+ color: var(--ry-color-text-muted);
6485
+ }
6486
+
6487
+ .ry-avatar {
6488
+ border-radius: var(--ry-radius-full);
6489
+ object-fit: cover;
6490
+ }
6491
+
6492
+ .ry-bg-subtle {
6493
+ background-color: var(--ry-color-bg-subtle);
6494
+ }
6495
+
6496
+ .ry-bg-inverted {
6497
+ background-color: var(--ry-color-text);
6498
+ color: var(--ry-color-bg);
6499
+ }
6500
+
6501
+ .ry-bg-inverted p {
6502
+ opacity: 0.7;
6503
+ }
6504
+
5704
6505
  } /* @layer ry-theme */