@ryanhelsing/ry-ui 1.0.13 → 1.0.14

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/README.md CHANGED
@@ -174,6 +174,7 @@ Wrap markup in `<ry>` to use unprefixed tags:
174
174
  | `<ry-feature-grid>` | `cols="2\|3\|4"` | Responsive grid for feature cards |
175
175
  | `<ry-pricing>` | — | Container for pricing cards |
176
176
  | `<ry-pricing-card>` | `featured` | Pricing tier. `featured` scales up with bold border |
177
+ | `<ry-heading>` | `size="sm\|lg"`, `align="center\|right"`, `divider` | Section heading with optional `slot="sub"` subtitle |
177
178
 
178
179
  ---
179
180
 
@@ -0,0 +1,19 @@
1
+ /**
2
+ * <ry-heading>
3
+ *
4
+ * Section heading with optional subtitle.
5
+ *
6
+ * Usage:
7
+ * <ry-heading>Page Title</ry-heading>
8
+ * <ry-heading size="lg">Large Title</ry-heading>
9
+ * <ry-heading align="center">
10
+ * Centered Title
11
+ * <span slot="sub">A brief description</span>
12
+ * </ry-heading>
13
+ */
14
+ import { RyElement } from '../core/ry-element.js';
15
+ export declare class RyHeading extends RyElement {
16
+ #private;
17
+ setup(): void;
18
+ }
19
+ //# sourceMappingURL=ry-heading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ry-heading.d.ts","sourceRoot":"","sources":["../../src/ts/components/ry-heading.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,qBAAa,SAAU,SAAQ,SAAS;;IACtC,KAAK,IAAI,IAAI;CAmBd"}
@@ -7,7 +7,7 @@
7
7
  * Usage:
8
8
  * <ry-theme-panel></ry-theme-panel>
9
9
  *
10
- * Themes: "none" (bare structure), "default", "ocean"
10
+ * Themes: "none" (bare structure), "default", "ocean", "antigravity"
11
11
  * Modes: "auto" (OS preference), "light", "dark"
12
12
  *
13
13
  * Sets data-ry-theme and data-ry-mode on <html>.
@@ -1 +1 @@
1
- {"version":3,"file":"ry-theme-panel.d.ts","sourceRoot":"","sources":["../../src/ts/components/ry-theme-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AASlD,qBAAa,YAAa,SAAQ,SAAS;;IAIzC,KAAK,IAAI,IAAI;IA8Jb,IAAI,KAAK,IAAI,MAAM,CAAwB;IAC3C,IAAI,KAAK,CAAC,CAAC,EAAE,MAAM,EAKlB;IAED,IAAI,IAAI,IAAI,MAAM,CAAuB;IACzC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,EAKjB;CACF"}
1
+ {"version":3,"file":"ry-theme-panel.d.ts","sourceRoot":"","sources":["../../src/ts/components/ry-theme-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AASlD,qBAAa,YAAa,SAAQ,SAAS;;IAIzC,KAAK,IAAI,IAAI;IAiKb,IAAI,KAAK,IAAI,MAAM,CAAwB;IAC3C,IAAI,KAAK,CAAC,CAAC,EAAE,MAAM,EAKlB;IAED,IAAI,IAAI,IAAI,MAAM,CAAuB;IACzC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,EAKjB;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ry-transform.d.ts","sourceRoot":"","sources":["../../src/ts/core/ry-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAyDH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAgBxC"}
1
+ {"version":3,"file":"ry-transform.d.ts","sourceRoot":"","sources":["../../src/ts/core/ry-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AA0DH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAgBxC"}
@@ -48,7 +48,7 @@ ry {
48
48
  ry-toggle-button, ry-knob, ry-slider, ry-number-select, ry-color-picker, ry-color-input,
49
49
  ry-gradient-picker, ry-tree, ry-tree-item,
50
50
  ry-tag, ry-tag-input, ry-hero, ry-stat, ry-feature, ry-feature-grid,
51
- ry-pricing, ry-pricing-card, ry-carousel, ry-combobox) {
51
+ ry-pricing, ry-pricing-card, ry-carousel, ry-combobox, ry-heading) {
52
52
  box-sizing: border-box;
53
53
  }
54
54
 
@@ -93,7 +93,8 @@ ry {
93
93
  :is(ry-modal [data-ry-target="header"] h3,
94
94
  ry-card h3,
95
95
  ry-hero h1,
96
- ry-pricing-card h3) {
96
+ ry-pricing-card h3,
97
+ ry-heading [data-ry-target="title"]) {
97
98
  text-wrap: balance;
98
99
  }
99
100
 
@@ -364,11 +365,13 @@ ry-center {
364
365
  ry-nav {
365
366
  display: flex;
366
367
  align-items: center;
367
- gap: var(--ry-space-4, 1rem);
368
+ gap: var(--ry-space-1, 0.25rem);
368
369
  }
369
370
 
370
371
  ry-nav a {
371
372
  text-decoration: none;
373
+ padding: var(--ry-space-2, 0.5rem) var(--ry-space-3, 0.75rem);
374
+ white-space: nowrap;
372
375
  }
373
376
 
374
377
  /* ═══════════════════════════════════════════════════════════════
@@ -388,6 +391,7 @@ ry-actions {
388
391
  display: flex;
389
392
  align-items: center;
390
393
  gap: var(--ry-space-2, 0.5rem);
394
+ margin-inline-start: auto;
391
395
  }
392
396
 
393
397
  /* ═══════════════════════════════════════════════════════════════
@@ -3055,4 +3059,37 @@ ry-theme-panel [data-ry-target="mode-btn"] {
3055
3059
  line-height: 1;
3056
3060
  }
3057
3061
 
3062
+ /* ═══════════════════════════════════════════════════════════════
3063
+ HEADING
3064
+ ═══════════════════════════════════════════════════════════════ */
3065
+
3066
+ ry-heading {
3067
+ display: flex;
3068
+ flex-direction: column;
3069
+ gap: var(--ry-space-2, 0.5rem);
3070
+ }
3071
+
3072
+ ry-heading[align="center"] {
3073
+ text-align: center;
3074
+ }
3075
+
3076
+ ry-heading[align="right"] {
3077
+ text-align: end;
3078
+ }
3079
+
3080
+ /* Balanced text wrapping for heading titles */
3081
+ ry-heading [data-ry-target="title"] {
3082
+ text-wrap: balance;
3083
+ margin: 0;
3084
+ }
3085
+
3086
+ ry-heading [data-ry-target="sub"] {
3087
+ margin: 0;
3088
+ }
3089
+
3090
+ /* Divider variant: adds a bottom border */
3091
+ ry-heading[divider] {
3092
+ padding-block-end: var(--ry-space-4, 1rem);
3093
+ }
3094
+
3058
3095
  } /* @layer ry-structure */
@@ -118,11 +118,14 @@ ry-nav a {
118
118
  color: var(--ry-color-text-muted);
119
119
  font-size: var(--ry-text-sm);
120
120
  font-weight: var(--ry-font-medium);
121
- transition: color var(--ry-duration-fast) var(--ry-ease);
121
+ border-radius: var(--ry-radius-md);
122
+ transition: color var(--ry-duration-fast) var(--ry-ease),
123
+ background-color var(--ry-duration-fast) var(--ry-ease);
122
124
  }
123
125
 
124
126
  ry-nav a:hover {
125
127
  color: var(--ry-color-text);
128
+ background-color: var(--ry-color-hover-overlay);
126
129
  }
127
130
 
128
131
  ry-nav a[aria-current="page"] {
@@ -2377,6 +2380,28 @@ ry-combobox[data-ry-state="open"] .ry-combobox__input-wrapper {
2377
2380
  ═══════════════════════════════════════════════════════════════ */
2378
2381
 
2379
2382
  [data-ry-theme="none"] {
2383
+ /* Strictly black and white */
2384
+ --ry-color-primary: light-dark(#000000, #ffffff);
2385
+ --ry-color-primary-hover: light-dark(#333333, #cccccc);
2386
+ --ry-color-primary-active: light-dark(#555555, #aaaaaa);
2387
+ --ry-color-secondary: light-dark(#000000, #ffffff);
2388
+ --ry-color-secondary-hover: light-dark(#333333, #cccccc);
2389
+ --ry-color-secondary-active: light-dark(#555555, #aaaaaa);
2390
+ --ry-color-accent: light-dark(#000000, #ffffff);
2391
+ --ry-color-accent-hover: light-dark(#333333, #cccccc);
2392
+ --ry-color-accent-active: light-dark(#555555, #aaaaaa);
2393
+ --ry-color-text: light-dark(#000000, #ffffff);
2394
+ --ry-color-text-muted: light-dark(#666666, #999999);
2395
+ --ry-color-text-inverse: light-dark(#ffffff, #000000);
2396
+ --ry-color-bg: light-dark(#ffffff, #000000);
2397
+ --ry-color-bg-subtle: light-dark(#f5f5f5, #0a0a0a);
2398
+ --ry-color-bg-muted: light-dark(#eeeeee, #111111);
2399
+ --ry-color-border: light-dark(#dddddd, #333333);
2400
+ --ry-color-border-strong: light-dark(#999999, #666666);
2401
+ --ry-color-overlay: light-dark(rgba(255,255,255,0.95), rgba(0,0,0,0.95));
2402
+ --ry-color-hover-overlay: light-dark(rgba(0,0,0,0.04), rgba(255,255,255,0.06));
2403
+ --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));
2404
+ /* No radii, no shadows */
2380
2405
  --ry-radius-sm: 0;
2381
2406
  --ry-radius-md: 0;
2382
2407
  --ry-radius-lg: 0;
@@ -2422,4 +2447,44 @@ ry-combobox[data-ry-state="open"] .ry-combobox__input-wrapper {
2422
2447
  color: var(--ry-color-text-inverse);
2423
2448
  }
2424
2449
 
2450
+ /* ═══════════════════════════════════════════════════════════════
2451
+ HEADING
2452
+ ═══════════════════════════════════════════════════════════════ */
2453
+
2454
+ .ry-heading__title {
2455
+ font-size: var(--ry-text-2xl);
2456
+ font-weight: var(--ry-font-bold);
2457
+ line-height: var(--ry-leading-tight);
2458
+ color: var(--ry-color-text);
2459
+ }
2460
+
2461
+ .ry-heading__sub {
2462
+ font-size: var(--ry-text-base);
2463
+ line-height: var(--ry-leading-normal);
2464
+ color: var(--ry-color-text-muted);
2465
+ }
2466
+
2467
+ /* Size: sm */
2468
+ ry-heading[size="sm"] .ry-heading__title {
2469
+ font-size: var(--ry-text-lg);
2470
+ }
2471
+
2472
+ ry-heading[size="sm"] .ry-heading__sub {
2473
+ font-size: var(--ry-text-sm);
2474
+ }
2475
+
2476
+ /* Size: lg */
2477
+ ry-heading[size="lg"] .ry-heading__title {
2478
+ font-size: var(--ry-text-4xl);
2479
+ }
2480
+
2481
+ ry-heading[size="lg"] .ry-heading__sub {
2482
+ font-size: var(--ry-text-lg);
2483
+ }
2484
+
2485
+ /* Divider variant */
2486
+ ry-heading[divider] {
2487
+ border-bottom: var(--ry-border-width) solid var(--ry-color-border);
2488
+ }
2489
+
2425
2490
  } /* @layer ry-theme */
@@ -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;
79
71
 
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));
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
+ ═══════════════════════════════════════════════════════════════ */
82
+
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 oklch, 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 oklch, 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 oklch, 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 oklch, 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