@almadar/ui 5.123.0 → 5.125.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/{TraitProvider-YkK6tXDw.d.cts → TraitProvider-Ch79cUcb.d.cts} +6 -1
  2. package/dist/{TraitProvider-YkK6tXDw.d.ts → TraitProvider-Ch79cUcb.d.ts} +6 -1
  3. package/dist/{UserContext-bziZwgFL.d.cts → UserContext-BKckAUv7.d.cts} +5 -5
  4. package/dist/{UserContext-bziZwgFL.d.ts → UserContext-BKckAUv7.d.ts} +5 -5
  5. package/dist/avl/index.cjs +332 -275
  6. package/dist/avl/index.js +334 -277
  7. package/dist/components/index.cjs +284 -248
  8. package/dist/components/index.d.cts +4 -3
  9. package/dist/components/index.d.ts +4 -3
  10. package/dist/components/index.js +284 -248
  11. package/dist/context/index.cjs +25 -66
  12. package/dist/context/index.d.cts +1 -1
  13. package/dist/context/index.d.ts +1 -1
  14. package/dist/context/index.js +25 -66
  15. package/dist/{offline-executor-aRuNznZx.d.cts → offline-executor-Qz4b6GpF.d.cts} +19 -1
  16. package/dist/{offline-executor-aRuNznZx.d.ts → offline-executor-Qz4b6GpF.d.ts} +19 -1
  17. package/dist/providers/index.cjs +395 -275
  18. package/dist/providers/index.d.cts +6 -6
  19. package/dist/providers/index.d.ts +6 -6
  20. package/dist/providers/index.js +394 -276
  21. package/dist/renderer/index.cjs +8 -0
  22. package/dist/renderer/index.d.cts +2 -2
  23. package/dist/renderer/index.d.ts +2 -2
  24. package/dist/renderer/index.js +1 -1
  25. package/dist/runtime/index.cjs +325 -268
  26. package/dist/runtime/index.d.cts +4 -2
  27. package/dist/runtime/index.d.ts +4 -2
  28. package/dist/runtime/index.js +327 -270
  29. package/package.json +13 -11
  30. package/themes/_contract.md +2 -0
  31. package/themes/almadar-website.css +3 -3
  32. package/themes/almadar.css +4 -4
  33. package/themes/bloomberg-dense.css +2 -2
  34. package/themes/clay.css +417 -0
  35. package/themes/corporate.css +411 -0
  36. package/themes/game-adventure.css +3 -3
  37. package/themes/game-rpg.css +2 -2
  38. package/themes/game-sci-fi.css +1 -1
  39. package/themes/game-ui-pack.css +2 -2
  40. package/themes/gazette.css +2 -2
  41. package/themes/glass.css +428 -0
  42. package/themes/index.css +9 -13
  43. package/themes/kiosk.css +5 -5
  44. package/themes/linear-clean.css +1 -1
  45. package/themes/minimalist.css +2 -2
  46. package/themes/neon.css +3 -3
  47. package/themes/notion-editorial.css +1 -1
  48. package/themes/prism.css +3 -3
  49. package/themes/retro.css +410 -0
  50. package/themes/terminal.css +1 -1
  51. package/themes/trait-wars.css +8 -8
  52. package/themes/wireframe.css +2 -2
  53. package/themes/arctic.css +0 -235
  54. package/themes/copper.css +0 -235
  55. package/themes/ember.css +0 -238
  56. package/themes/forest.css +0 -238
  57. package/themes/lavender.css +0 -233
  58. package/themes/midnight.css +0 -234
  59. package/themes/ocean.css +0 -238
  60. package/themes/rose.css +0 -233
  61. package/themes/sand.css +0 -234
  62. package/themes/slate.css +0 -233
  63. package/themes/sunset.css +0 -238
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.123.0",
3
+ "version": "5.125.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -117,12 +117,12 @@
117
117
  "access": "public"
118
118
  },
119
119
  "dependencies": {
120
- "@almadar/core": "^10.32.0",
121
- "@almadar/evaluator": "^2.32.0",
122
- "@almadar/logger": "^1.9.0",
123
- "@almadar/runtime": "^6.35.0",
124
- "@almadar/std": "^16.142.0",
125
- "@almadar/syntax": "^1.11.0",
120
+ "@almadar/core": "^10.34.0",
121
+ "@almadar/evaluator": "^2.35.0",
122
+ "@almadar/logger": "^1.10.0",
123
+ "@almadar/runtime": "^6.37.0",
124
+ "@almadar/std": "^16.144.0",
125
+ "@almadar/syntax": "^1.12.0",
126
126
  "@dnd-kit/core": "^6.3.1",
127
127
  "@dnd-kit/sortable": "^10.0.0",
128
128
  "@dnd-kit/utilities": "^3.2.2",
@@ -171,7 +171,7 @@
171
171
  }
172
172
  },
173
173
  "devDependencies": {
174
- "@almadar/eslint-plugin": "^2.14.0",
174
+ "@almadar/eslint-plugin": "^2.15.0",
175
175
  "@react-three/drei": "^10.7.7",
176
176
  "@react-three/fiber": "^9.6.0",
177
177
  "@react-three/postprocessing": "3.0.4",
@@ -208,9 +208,10 @@
208
208
  "tsup": "^8.0.0",
209
209
  "tsx": "^4.7.0",
210
210
  "turbo": "^2.8.17",
211
- "typescript": "^5.4.0",
212
211
  "vite": "^5.2.0",
213
- "vitest": "^3.2.6"
212
+ "vitest": "^3.2.6",
213
+ "@typescript/native": "npm:typescript@^7.0.2",
214
+ "typescript": "npm:@typescript/typescript6@^6.0.2"
214
215
  },
215
216
  "repository": {
216
217
  "type": "git",
@@ -233,6 +234,7 @@
233
234
  "build": "NODE_OPTIONS=--max-old-space-size=8192 tsup",
234
235
  "build:watch": "tsup --watch",
235
236
  "typecheck": "tsc --noEmit",
236
- "lint": "eslint --no-warn-ignored --max-warnings 0 ."
237
+ "lint": "eslint --no-warn-ignored --max-warnings 0 .",
238
+ "verify:themes": "node scripts/theme-contrast-audit.mjs"
237
239
  }
238
240
  }
@@ -221,3 +221,5 @@ instantly regardless of theme.
221
221
  3. **No raw pixel literals in components**. All dimensional values flow through these tokens or through Tailwind utilities backed by them in `tailwind-preset.cjs`. Components that hardcode `text-[10px]` or `min-w-[44px]` are migration targets.
222
222
  4. **Icon family swap is runtime-resolved**. `--icon-family` is read by the icon resolver in `@almadar/ui`; setting the variable in a theme does not require component edits.
223
223
  5. **Wireframe and trait-wars exceptions**. Wireframe's `--easing-standard` is `linear` not the default cubic-bezier; trait-wars's iconography may remain `lucide` even if its visual personality diverges. Document any per-theme override at the top of the theme file.
224
+ 6. **Contrast is gated.** Every theme's canonical foreground/fill pairs must pass WCAG AA 4.5:1 — enforced by `scripts/theme-contrast-audit.mjs` (`pnpm verify:themes`), which runs in CI and before every npm publish. A new or edited theme that fails the audit blocks the publish.
225
+ 7. **No hardcoded palette colors in components.** Components must consume these tokens only (no `text-white`, `bg-gray-800`, `border-indigo-300`, `text-[#hex]`). Enforced by the `almadar/no-hardcoded-colors` ESLint rule (`@almadar/eslint-plugin`, enabled in this package's `eslint.config.cjs`). The single sanctioned exception is media-overlay chrome (white text / dark scrims painted over images or video), which requires an inline `eslint-disable-next-line almadar/no-hardcoded-colors` comment stating the reason.
@@ -45,7 +45,7 @@
45
45
  --color-accent-foreground: #0f172a;
46
46
 
47
47
  --color-muted: #f1f5f9;
48
- --color-muted-foreground: #64748b;
48
+ --color-muted-foreground: #5c6b80;
49
49
 
50
50
  --color-background: #ffffff;
51
51
  --color-foreground: #0f172a;
@@ -61,11 +61,11 @@
61
61
  /* Semantic colors */
62
62
  --color-error: #dc2626;
63
63
  --color-error-foreground: #ffffff;
64
- --color-success: #22c55e;
64
+ --color-success: #15803d;
65
65
  --color-success-foreground: #ffffff;
66
66
  --color-warning: #f59e0b;
67
67
  --color-warning-foreground: #000000;
68
- --color-info: #3b82f6;
68
+ --color-info: #1d4ed8;
69
69
  --color-info-foreground: #ffffff;
70
70
 
71
71
  /* Icon styling */
@@ -43,11 +43,11 @@
43
43
  --color-secondary-hover: #e2e8f0;
44
44
  --color-secondary-foreground: #0f172a;
45
45
 
46
- --color-accent: #06b6d4;
46
+ --color-accent: #0e7490;
47
47
  --color-accent-foreground: #ffffff;
48
48
 
49
49
  --color-muted: #f1f5f9;
50
- --color-muted-foreground: #64748b;
50
+ --color-muted-foreground: #607080;
51
51
 
52
52
  --color-background: #f8fafc;
53
53
  --color-foreground: #0f172a;
@@ -61,11 +61,11 @@
61
61
  /* Semantic colors */
62
62
  --color-error: #dc2626;
63
63
  --color-error-foreground: #ffffff;
64
- --color-success: #16a34a;
64
+ --color-success: #15803d;
65
65
  --color-success-foreground: #ffffff;
66
66
  --color-warning: #ca8a04;
67
67
  --color-warning-foreground: #000000;
68
- --color-info: #0ea5e9;
68
+ --color-info: #0369a1;
69
69
  --color-info-foreground: #ffffff;
70
70
 
71
71
  /* Icon styling */
@@ -71,7 +71,7 @@
71
71
 
72
72
  --color-error: #dc2626;
73
73
  --color-error-foreground: #ffffff;
74
- --color-success: #16a34a;
74
+ --color-success: #15803d;
75
75
  --color-success-foreground: #ffffff;
76
76
  --color-warning: #f59e0b;
77
77
  --color-warning-foreground: #0a0e1a;
@@ -244,7 +244,7 @@
244
244
  --color-accent-foreground: #0a0e1a;
245
245
 
246
246
  --color-muted: #131826;
247
- --color-muted-foreground: #6b7a94;
247
+ --color-muted-foreground: #8a98b3;
248
248
 
249
249
  --color-background: #0a0e1a;
250
250
  --color-foreground: #c7d2e0;
@@ -0,0 +1,417 @@
1
+ /**
2
+ * Clay Theme — "Claymorphism / Soft UI"
3
+ *
4
+ * Puffy pastel 3D surfaces that look molded from soft clay. Large diffuse
5
+ * drop shadows paired with an inner top highlight make cards and buttons
6
+ * bulge gently off the background. Big soft radii, a lavender-pink / mint /
7
+ * cream pastel palette, chubby paddings, rounded Manrope type, and a quick
8
+ * spring bounce on every interaction give it a friendly consumer-SaaS feel.
9
+ */
10
+
11
+ /* ==========================================================================
12
+ * LIGHT MODE
13
+ * ========================================================================== */
14
+ [data-theme="clay-light"] {
15
+ /* Shadows - Soft diffuse drop + inner top highlight (the clay bulge) */
16
+ --shadow-main:
17
+ 0 12px 24px -6px rgba(93, 62, 110, 0.18), inset 0 2px 4px rgba(255, 255, 255, 0.7);
18
+ --shadow-sm:
19
+ 0 6px 12px -4px rgba(93, 62, 110, 0.12), inset 0 1px 2px rgba(255, 255, 255, 0.6);
20
+ --shadow-lg:
21
+ 0 20px 40px -8px rgba(93, 62, 110, 0.22), inset 0 2px 6px rgba(255, 255, 255, 0.7);
22
+ --shadow-inner:
23
+ inset 0 2px 4px rgba(255, 255, 255, 0.7), inset 0 -3px 6px rgba(93, 62, 110, 0.12);
24
+ --shadow-none: none;
25
+ --shadow-hover:
26
+ 0 16px 32px -6px rgba(93, 62, 110, 0.24), inset 0 2px 4px rgba(255, 255, 255, 0.8);
27
+ --shadow-active:
28
+ 0 4px 8px -2px rgba(93, 62, 110, 0.15), inset 0 3px 6px rgba(93, 62, 110, 0.12);
29
+
30
+ /* Border radius - Big, soft, puffy */
31
+ --radius-none: 0px;
32
+ --radius-sm: 12px;
33
+ --radius-md: 16px;
34
+ --radius-lg: 20px;
35
+ --radius-xl: 24px;
36
+ --radius-full: 9999px;
37
+
38
+ /* Border width - Barely-there, clay edges are soft */
39
+ --border-width: 1px;
40
+ --border-width-thin: 1px;
41
+ --border-width-thick: 2px;
42
+
43
+ /* Colors - Pastel lavender-pink on warm cream */
44
+ --color-primary: #b97fd8;
45
+ --color-primary-hover: #a569c7;
46
+ --color-primary-foreground: #251038;
47
+
48
+ --color-secondary: #c9ecdc;
49
+ --color-secondary-hover: #b2e3cd;
50
+ --color-secondary-foreground: #1f4a38;
51
+
52
+ --color-accent: #f2a172;
53
+ --color-accent-foreground: #4a2410;
54
+
55
+ --color-muted: #f2e9e4;
56
+ --color-muted-foreground: #6a5560;
57
+
58
+ --color-background: #faf5f0;
59
+ --color-foreground: #3d2c3a;
60
+ --color-card: #fffdf9;
61
+ --color-card-foreground: #3d2c3a;
62
+ --color-surface: #f2e8e2;
63
+ --color-border: rgba(93, 62, 110, 0.14);
64
+ --color-input: rgba(93, 62, 110, 0.2);
65
+ --color-ring: #b97fd8;
66
+
67
+ /* Semantic colors - Softened pastels, still readable */
68
+ --color-error: #c92847;
69
+ --color-error-foreground: #ffffff;
70
+ --color-success: #20835b;
71
+ --color-success-foreground: #ffffff;
72
+ --color-warning: #e3a63d;
73
+ --color-warning-foreground: #3d2a00;
74
+ --color-info: #3f6fd1;
75
+ --color-info-foreground: #ffffff;
76
+
77
+ /* Typography - Rounded, friendly, medium-plus */
78
+ --font-family:
79
+ "Manrope", "Plus Jakarta Sans", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
80
+ --font-weight-normal: 500;
81
+ --font-weight-medium: 600;
82
+ --font-weight-bold: 800;
83
+ --letter-spacing: 0.005em;
84
+ --line-height: 1.55;
85
+
86
+ /* Icon styling - Chubby strokes */
87
+ --icon-stroke-width: 2.25;
88
+ --icon-color: #b97fd8;
89
+
90
+ /* Transitions - Bouncy but quick */
91
+ --transition-fast: 120ms;
92
+ --transition-normal: 180ms;
93
+ --transition-slow: 280ms;
94
+ --transition-timing: cubic-bezier(0.34, 1.56, 0.64, 1);
95
+
96
+ /* Hover/Active transforms - Puffy press-and-bounce */
97
+ --hover-scale: 1.03;
98
+ --hover-translate-y: -1px;
99
+ --hover-translate-x: 0;
100
+ --active-scale: 0.97;
101
+ --active-translate-y: 1px;
102
+
103
+ /* Focus ring */
104
+ --focus-ring-width: 3px;
105
+ --focus-ring-offset: 2px;
106
+ --focus-ring-color: rgba(185, 127, 216, 0.5);
107
+
108
+ /* Layer 1 — backfill (preserves current visual output, see themes/_contract.md) */
109
+ /* Density axis — spacing scale */
110
+ --space-0: 0px;
111
+ --space-1: 4px;
112
+ --space-2: 8px;
113
+ --space-3: 12px;
114
+ --space-4: 16px;
115
+ --space-5: 20px;
116
+ --space-6: 24px;
117
+ --space-7: 28px;
118
+ --space-8: 32px;
119
+ --space-9: 36px;
120
+ --space-10: 40px;
121
+ --space-11: 44px;
122
+ --space-12: 48px;
123
+ /* Density axis — per-element heights (slightly taller, chubby) */
124
+ --button-height-sm: 32px;
125
+ --button-height-md: 40px;
126
+ --button-height-lg: 50px;
127
+ --input-height-sm: 32px;
128
+ --input-height-md: 40px;
129
+ --input-height-lg: 50px;
130
+ --row-height-compact: 36px;
131
+ --row-height-normal: 44px;
132
+ --row-height-spacious: 56px;
133
+ /* Density axis — per-element padding (generous, pillowy) */
134
+ --card-padding-sm: 16px;
135
+ --card-padding-md: 20px;
136
+ --card-padding-lg: 32px;
137
+ --dialog-padding: 32px;
138
+ --section-gap: 40px;
139
+ /* Type axis — family triplet (aliases existing --font-family for backward compat) */
140
+ --font-family-display: var(--font-family);
141
+ --font-family-body: var(--font-family);
142
+ --font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
143
+ /* Type axis — size scale */
144
+ --text-xs: 12px;
145
+ --leading-xs: 16px;
146
+ --text-sm: 14px;
147
+ --leading-sm: 20px;
148
+ --text-base: 16px;
149
+ --leading-base: 24px;
150
+ --text-lg: 18px;
151
+ --leading-lg: 28px;
152
+ --text-xl: 20px;
153
+ --leading-xl: 28px;
154
+ --text-2xl: 24px;
155
+ --leading-2xl: 32px;
156
+ --text-3xl: 30px;
157
+ --leading-3xl: 36px;
158
+ --text-4xl: 36px;
159
+ --leading-4xl: 40px;
160
+ --text-display-1: 48px;
161
+ --leading-display-1: 52px;
162
+ --text-display-2: 60px;
163
+ --leading-display-2: 64px;
164
+ /* Type axis — intent mapping */
165
+ --intent-heading-major-size: var(--text-2xl);
166
+ --intent-heading-major-weight: var(--font-weight-bold);
167
+ --intent-heading-major-leading: var(--leading-2xl);
168
+ --intent-heading-minor-size: var(--text-lg);
169
+ --intent-heading-minor-weight: var(--font-weight-bold);
170
+ --intent-heading-minor-leading: var(--leading-lg);
171
+ --intent-body-emphasis-size: var(--text-base);
172
+ --intent-body-emphasis-weight: var(--font-weight-medium);
173
+ --intent-body-emphasis-leading: var(--leading-base);
174
+ --intent-body-default-size: var(--text-sm);
175
+ --intent-body-default-weight: var(--font-weight-normal);
176
+ --intent-body-default-leading: var(--leading-sm);
177
+ --intent-body-quiet-size: var(--text-sm);
178
+ --intent-body-quiet-weight: var(--font-weight-normal);
179
+ --intent-body-quiet-leading: var(--leading-sm);
180
+ --intent-caption-size: var(--text-xs);
181
+ --intent-caption-weight: var(--font-weight-normal);
182
+ --intent-caption-leading: var(--leading-xs);
183
+ --intent-numeric-size: var(--text-sm);
184
+ --intent-numeric-weight: var(--font-weight-medium);
185
+ --intent-numeric-leading: var(--leading-sm);
186
+ /* Motion axis — duration palette */
187
+ --duration-instant: 0ms;
188
+ --duration-fast: var(--transition-fast);
189
+ --duration-normal: var(--transition-normal);
190
+ --duration-slow: var(--transition-slow);
191
+ --duration-dramatic: 700ms;
192
+ /* Motion axis — easing palette (spring IS the standard here) */
193
+ --easing-linear: linear;
194
+ --easing-standard: var(--transition-timing);
195
+ --easing-emphasized: cubic-bezier(0.2, 0, 0, 1);
196
+ --easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
197
+ /* Iconography axis */
198
+ --icon-family: lucide;
199
+ --icon-default-size: 18px;
200
+ /* Elevation axis — per-layer mapping */
201
+ --elevation-card: var(--shadow-sm);
202
+ --elevation-popover: var(--shadow-main);
203
+ --elevation-dialog: var(--shadow-lg);
204
+ --elevation-toast: var(--shadow-main);
205
+ /* Geometry axis — radius rhythm with intent */
206
+ --radius-container: var(--radius-lg);
207
+ --radius-interactive: var(--radius-md);
208
+ --radius-pill: var(--radius-full);
209
+ /* Geometry axis — border-width rhythm */
210
+ --border-hairline: 1px;
211
+ --border-standard: var(--border-width);
212
+ --border-heavy: var(--border-width-thick);
213
+ }
214
+
215
+ /* ==========================================================================
216
+ * DARK MODE
217
+ * ========================================================================== */
218
+ [data-theme="clay-dark"] {
219
+ /* Shadows - Deep diffuse drop + faint inner top light */
220
+ --shadow-main:
221
+ 0 14px 28px -6px rgba(0, 0, 0, 0.45), inset 0 1px 2px rgba(255, 255, 255, 0.08);
222
+ --shadow-sm:
223
+ 0 8px 16px -4px rgba(0, 0, 0, 0.35), inset 0 1px 2px rgba(255, 255, 255, 0.06);
224
+ --shadow-lg:
225
+ 0 24px 48px -8px rgba(0, 0, 0, 0.55), inset 0 2px 4px rgba(255, 255, 255, 0.1);
226
+ --shadow-inner:
227
+ inset 0 2px 4px rgba(255, 255, 255, 0.06), inset 0 -4px 8px rgba(0, 0, 0, 0.35);
228
+ --shadow-none: none;
229
+ --shadow-hover:
230
+ 0 18px 36px -6px rgba(0, 0, 0, 0.5), inset 0 2px 3px rgba(255, 255, 255, 0.1);
231
+ --shadow-active:
232
+ 0 4px 10px -2px rgba(0, 0, 0, 0.4), inset 0 3px 8px rgba(0, 0, 0, 0.4);
233
+
234
+ /* Border radius - Big, soft, puffy */
235
+ --radius-none: 0px;
236
+ --radius-sm: 12px;
237
+ --radius-md: 16px;
238
+ --radius-lg: 20px;
239
+ --radius-xl: 24px;
240
+ --radius-full: 9999px;
241
+
242
+ /* Border width - Barely-there, clay edges are soft */
243
+ --border-width: 1px;
244
+ --border-width-thin: 1px;
245
+ --border-width-thick: 2px;
246
+
247
+ /* Colors - Muted pastels on deep warm plum */
248
+ --color-primary: #cf9ce8;
249
+ --color-primary-hover: #bb84d8;
250
+ --color-primary-foreground: #2a1538;
251
+
252
+ --color-secondary: #35544a;
253
+ --color-secondary-hover: #406457;
254
+ --color-secondary-foreground: #c8ecdc;
255
+
256
+ --color-accent: #f0ab82;
257
+ --color-accent-foreground: #3a1c0a;
258
+
259
+ --color-muted: #3a2d42;
260
+ --color-muted-foreground: #bfa8c4;
261
+
262
+ --color-background: #241c2a;
263
+ --color-foreground: #f3e9f2;
264
+ --color-card: #2f2438;
265
+ --color-card-foreground: #f3e9f2;
266
+ --color-surface: #3a2d42;
267
+ --color-border: rgba(207, 156, 232, 0.16);
268
+ --color-input: rgba(207, 156, 232, 0.22);
269
+ --color-ring: #cf9ce8;
270
+
271
+ /* Semantic colors - Pastel-bright for dark mode, dark text on top */
272
+ --color-error: #f08a9a;
273
+ --color-error-foreground: #3d0f18;
274
+ --color-success: #8fd8b0;
275
+ --color-success-foreground: #0f2a1d;
276
+ --color-warning: #ecc56a;
277
+ --color-warning-foreground: #332400;
278
+ --color-info: #9ab8f0;
279
+ --color-info-foreground: #0f1f3d;
280
+
281
+ /* Typography - Rounded, friendly, medium-plus */
282
+ --font-family:
283
+ "Manrope", "Plus Jakarta Sans", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
284
+ --font-weight-normal: 500;
285
+ --font-weight-medium: 600;
286
+ --font-weight-bold: 800;
287
+ --letter-spacing: 0.005em;
288
+ --line-height: 1.55;
289
+
290
+ /* Icon styling - Chubby strokes */
291
+ --icon-stroke-width: 2.25;
292
+ --icon-color: #cf9ce8;
293
+
294
+ /* Transitions - Bouncy but quick */
295
+ --transition-fast: 120ms;
296
+ --transition-normal: 180ms;
297
+ --transition-slow: 280ms;
298
+ --transition-timing: cubic-bezier(0.34, 1.56, 0.64, 1);
299
+
300
+ /* Hover/Active transforms - Puffy press-and-bounce */
301
+ --hover-scale: 1.03;
302
+ --hover-translate-y: -1px;
303
+ --hover-translate-x: 0;
304
+ --active-scale: 0.97;
305
+ --active-translate-y: 1px;
306
+
307
+ /* Focus ring */
308
+ --focus-ring-width: 3px;
309
+ --focus-ring-offset: 2px;
310
+ --focus-ring-color: rgba(207, 156, 232, 0.5);
311
+
312
+ /* Layer 1 — backfill (preserves current visual output, see themes/_contract.md) */
313
+ /* Density axis — spacing scale */
314
+ --space-0: 0px;
315
+ --space-1: 4px;
316
+ --space-2: 8px;
317
+ --space-3: 12px;
318
+ --space-4: 16px;
319
+ --space-5: 20px;
320
+ --space-6: 24px;
321
+ --space-7: 28px;
322
+ --space-8: 32px;
323
+ --space-9: 36px;
324
+ --space-10: 40px;
325
+ --space-11: 44px;
326
+ --space-12: 48px;
327
+ /* Density axis — per-element heights (slightly taller, chubby) */
328
+ --button-height-sm: 32px;
329
+ --button-height-md: 40px;
330
+ --button-height-lg: 50px;
331
+ --input-height-sm: 32px;
332
+ --input-height-md: 40px;
333
+ --input-height-lg: 50px;
334
+ --row-height-compact: 36px;
335
+ --row-height-normal: 44px;
336
+ --row-height-spacious: 56px;
337
+ /* Density axis — per-element padding (generous, pillowy) */
338
+ --card-padding-sm: 16px;
339
+ --card-padding-md: 20px;
340
+ --card-padding-lg: 32px;
341
+ --dialog-padding: 32px;
342
+ --section-gap: 40px;
343
+ /* Type axis — family triplet (aliases existing --font-family for backward compat) */
344
+ --font-family-display: var(--font-family);
345
+ --font-family-body: var(--font-family);
346
+ --font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
347
+ /* Type axis — size scale */
348
+ --text-xs: 12px;
349
+ --leading-xs: 16px;
350
+ --text-sm: 14px;
351
+ --leading-sm: 20px;
352
+ --text-base: 16px;
353
+ --leading-base: 24px;
354
+ --text-lg: 18px;
355
+ --leading-lg: 28px;
356
+ --text-xl: 20px;
357
+ --leading-xl: 28px;
358
+ --text-2xl: 24px;
359
+ --leading-2xl: 32px;
360
+ --text-3xl: 30px;
361
+ --leading-3xl: 36px;
362
+ --text-4xl: 36px;
363
+ --leading-4xl: 40px;
364
+ --text-display-1: 48px;
365
+ --leading-display-1: 52px;
366
+ --text-display-2: 60px;
367
+ --leading-display-2: 64px;
368
+ /* Type axis — intent mapping */
369
+ --intent-heading-major-size: var(--text-2xl);
370
+ --intent-heading-major-weight: var(--font-weight-bold);
371
+ --intent-heading-major-leading: var(--leading-2xl);
372
+ --intent-heading-minor-size: var(--text-lg);
373
+ --intent-heading-minor-weight: var(--font-weight-bold);
374
+ --intent-heading-minor-leading: var(--leading-lg);
375
+ --intent-body-emphasis-size: var(--text-base);
376
+ --intent-body-emphasis-weight: var(--font-weight-medium);
377
+ --intent-body-emphasis-leading: var(--leading-base);
378
+ --intent-body-default-size: var(--text-sm);
379
+ --intent-body-default-weight: var(--font-weight-normal);
380
+ --intent-body-default-leading: var(--leading-sm);
381
+ --intent-body-quiet-size: var(--text-sm);
382
+ --intent-body-quiet-weight: var(--font-weight-normal);
383
+ --intent-body-quiet-leading: var(--leading-sm);
384
+ --intent-caption-size: var(--text-xs);
385
+ --intent-caption-weight: var(--font-weight-normal);
386
+ --intent-caption-leading: var(--leading-xs);
387
+ --intent-numeric-size: var(--text-sm);
388
+ --intent-numeric-weight: var(--font-weight-medium);
389
+ --intent-numeric-leading: var(--leading-sm);
390
+ /* Motion axis — duration palette */
391
+ --duration-instant: 0ms;
392
+ --duration-fast: var(--transition-fast);
393
+ --duration-normal: var(--transition-normal);
394
+ --duration-slow: var(--transition-slow);
395
+ --duration-dramatic: 700ms;
396
+ /* Motion axis — easing palette (spring IS the standard here) */
397
+ --easing-linear: linear;
398
+ --easing-standard: var(--transition-timing);
399
+ --easing-emphasized: cubic-bezier(0.2, 0, 0, 1);
400
+ --easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
401
+ /* Iconography axis */
402
+ --icon-family: lucide;
403
+ --icon-default-size: 18px;
404
+ /* Elevation axis — per-layer mapping */
405
+ --elevation-card: var(--shadow-sm);
406
+ --elevation-popover: var(--shadow-main);
407
+ --elevation-dialog: var(--shadow-lg);
408
+ --elevation-toast: var(--shadow-main);
409
+ /* Geometry axis — radius rhythm with intent */
410
+ --radius-container: var(--radius-lg);
411
+ --radius-interactive: var(--radius-md);
412
+ --radius-pill: var(--radius-full);
413
+ /* Geometry axis — border-width rhythm */
414
+ --border-hairline: 1px;
415
+ --border-standard: var(--border-width);
416
+ --border-heavy: var(--border-width-thick);
417
+ }