@mikenotthepope/substrateui 0.1.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.
@@ -0,0 +1,489 @@
1
+ /*
2
+ * Substrate UI — Design System Tokens & Base Stylesheet
3
+ *
4
+ * Import this once in your app root to get the full Substrate UI look and feel.
5
+ * This is the ONLY file consumers need to import for components to render correctly.
6
+ *
7
+ * Usage:
8
+ * import "substrateui/styles"
9
+ *
10
+ * Token Reference:
11
+ * Colors ......... --background, --foreground, --primary, --secondary, --success, etc.
12
+ * Color Scales ... --primary-50 through --primary-900 (+ destructive, success, warning, info, error)
13
+ * Spacing ........ --spacing-0 through --spacing-16 (4px base unit)
14
+ * Typography ..... --text-xs through --text-6xl, --leading-*, --tracking-*
15
+ * Fluid Type ..... --text-3xl-fluid through --text-6xl-fluid (clamp-based responsive)
16
+ * Shadows ........ --shadow-xs through --shadow-2xl (hard pixel offsets)
17
+ * Radii .......... --radius (0 default, var(--radius-md) with .with-radius)
18
+ * --radius-none, --radius-sm, --radius-md, --radius-lg, --radius-full
19
+ * Fonts .......... --font-head, --font-sans, --font-mono
20
+ * Weights ........ --weight-normal, --weight-medium, --weight-bold
21
+ * Motion ......... --duration-fast through --duration-slower, --ease-* (incl. --ease-spring)
22
+ * Z-index ........ --z-base, --z-dropdown, --z-sticky, --z-overlay, --z-modal, --z-popover, --z-toast
23
+ * Opacity ........ --opacity-disabled, --opacity-hover, --opacity-placeholder
24
+ */
25
+
26
+ @import "tailwindcss";
27
+ @import "tw-animate-css";
28
+
29
+ /* ═══════════════════════════════════════════════════════════════════════════
30
+ TAILWIND THEME MAPPING
31
+ Maps CSS custom properties to Tailwind utility classes.
32
+ This is what allows `bg-primary`, `text-muted-foreground`, `shadow-lg`, etc.
33
+ NOTE: @theme inline must remain outside @layer for Tailwind v4 to process it.
34
+ ═══════════════════════════════════════════════════════════════════════════ */
35
+
36
+ @keyframes marquee {
37
+ 0% {
38
+ transform: translateX(0%);
39
+ }
40
+ 100% {
41
+ transform: translateX(-100%);
42
+ }
43
+ }
44
+
45
+ @keyframes marquee2 {
46
+ 0% {
47
+ transform: translateX(100%);
48
+ }
49
+ 100% {
50
+ transform: translateX(0%);
51
+ }
52
+ }
53
+
54
+ @theme inline {
55
+ --animate-marquee: marquee 20s linear infinite;
56
+ --animate-marquee2: marquee2 20s linear infinite;
57
+ /* Fonts */
58
+ --font-head: var(--font-head);
59
+ --font-sans: var(--font-sans);
60
+ --font-mono: var(--font-mono);
61
+
62
+ /* Radii */
63
+ --radius: var(--radius);
64
+ --radius-none: 0;
65
+ --radius-sm: 0.25rem;
66
+ --radius-md: 0.5rem;
67
+ --radius-lg: 0.75rem;
68
+ --radius-full: 9999px;
69
+
70
+ /* Retro shadow scale — hard pixel offsets, no blur */
71
+ --shadow-xs: 1px 1px 0 0 var(--border);
72
+ --shadow-sm: 2px 2px 0 0 var(--border);
73
+ --shadow: 3px 3px 0 0 var(--border);
74
+ --shadow-md: 4px 4px 0 0 var(--border);
75
+ --shadow-lg: 6px 6px 0 0 var(--border);
76
+ --shadow-xl: 10px 10px 0 1px var(--border);
77
+ --shadow-2xl: 16px 16px 0 1px var(--border);
78
+
79
+ /* Colors */
80
+ --color-background: var(--background);
81
+ --color-foreground: var(--foreground);
82
+ --color-primary: var(--primary);
83
+ --color-primary-foreground: var(--primary-foreground);
84
+ --color-primary-hover: var(--primary-hover);
85
+ --color-secondary: var(--secondary);
86
+ --color-secondary-foreground: var(--secondary-foreground);
87
+ --color-card: var(--card);
88
+ --color-card-foreground: var(--card-foreground);
89
+ --color-muted: var(--muted);
90
+ --color-muted-foreground: var(--muted-foreground);
91
+ --color-accent: var(--accent);
92
+ --color-accent-foreground: var(--accent-foreground);
93
+ --color-destructive: var(--destructive);
94
+ --color-destructive-foreground: var(--destructive-foreground);
95
+ --color-success: var(--success);
96
+ --color-success-foreground: var(--success-foreground);
97
+ --color-warning: var(--warning);
98
+ --color-warning-foreground: var(--warning-foreground);
99
+ --color-info: var(--info);
100
+ --color-info-foreground: var(--info-foreground);
101
+ --color-error: var(--error);
102
+ --color-error-foreground: var(--error-foreground);
103
+ --color-overlay: var(--overlay);
104
+ --color-border: var(--border);
105
+ --color-page: var(--page);
106
+ --color-page-foreground: var(--page-foreground);
107
+ --color-ring: var(--ring);
108
+ --color-input: var(--input);
109
+
110
+ /* Color palette scales */
111
+ --color-primary-50: var(--primary-50);
112
+ --color-primary-100: var(--primary-100);
113
+ --color-primary-200: var(--primary-200);
114
+ --color-primary-300: var(--primary-300);
115
+ --color-primary-400: var(--primary-400);
116
+ --color-primary-500: var(--primary-500);
117
+ --color-primary-600: var(--primary-600);
118
+ --color-primary-700: var(--primary-700);
119
+ --color-primary-800: var(--primary-800);
120
+ --color-primary-900: var(--primary-900);
121
+
122
+ --color-destructive-50: var(--destructive-50);
123
+ --color-destructive-100: var(--destructive-100);
124
+ --color-destructive-200: var(--destructive-200);
125
+ --color-destructive-300: var(--destructive-300);
126
+ --color-destructive-400: var(--destructive-400);
127
+ --color-destructive-500: var(--destructive-500);
128
+ --color-destructive-600: var(--destructive-600);
129
+ --color-destructive-700: var(--destructive-700);
130
+ --color-destructive-800: var(--destructive-800);
131
+ --color-destructive-900: var(--destructive-900);
132
+
133
+ --color-success-50: var(--success-50);
134
+ --color-success-100: var(--success-100);
135
+ --color-success-200: var(--success-200);
136
+ --color-success-300: var(--success-300);
137
+ --color-success-400: var(--success-400);
138
+ --color-success-500: var(--success-500);
139
+ --color-success-600: var(--success-600);
140
+ --color-success-700: var(--success-700);
141
+ --color-success-800: var(--success-800);
142
+ --color-success-900: var(--success-900);
143
+
144
+ --color-warning-50: var(--warning-50);
145
+ --color-warning-100: var(--warning-100);
146
+ --color-warning-200: var(--warning-200);
147
+ --color-warning-300: var(--warning-300);
148
+ --color-warning-400: var(--warning-400);
149
+ --color-warning-500: var(--warning-500);
150
+ --color-warning-600: var(--warning-600);
151
+ --color-warning-700: var(--warning-700);
152
+ --color-warning-800: var(--warning-800);
153
+ --color-warning-900: var(--warning-900);
154
+
155
+ --color-info-50: var(--info-50);
156
+ --color-info-100: var(--info-100);
157
+ --color-info-200: var(--info-200);
158
+ --color-info-300: var(--info-300);
159
+ --color-info-400: var(--info-400);
160
+ --color-info-500: var(--info-500);
161
+ --color-info-600: var(--info-600);
162
+ --color-info-700: var(--info-700);
163
+ --color-info-800: var(--info-800);
164
+ --color-info-900: var(--info-900);
165
+
166
+ --color-error-50: var(--error-50);
167
+ --color-error-100: var(--error-100);
168
+ --color-error-200: var(--error-200);
169
+ --color-error-300: var(--error-300);
170
+ --color-error-400: var(--error-400);
171
+ --color-error-500: var(--error-500);
172
+ --color-error-600: var(--error-600);
173
+ --color-error-700: var(--error-700);
174
+ --color-error-800: var(--error-800);
175
+ --color-error-900: var(--error-900);
176
+
177
+ /* Motion tokens */
178
+ --duration-fast: 100ms;
179
+ --duration-normal: 200ms;
180
+ --duration-slow: 400ms;
181
+ --duration-slower: 600ms;
182
+ --ease-default: cubic-bezier(0.4, 0, 0.2, 1);
183
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
184
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
185
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
186
+ --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
187
+ --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
188
+
189
+ /* Z-index scale */
190
+ --z-base: 0;
191
+ --z-dropdown: 50;
192
+ --z-sticky: 100;
193
+ --z-overlay: 200;
194
+ --z-modal: 300;
195
+ --z-popover: 400;
196
+ --z-toast: 500;
197
+
198
+ /* Opacity tokens */
199
+ --opacity-disabled: 0.5;
200
+ --opacity-hover: 0.8;
201
+ --opacity-placeholder: 0.5;
202
+ }
203
+
204
+ /* ═══════════════════════════════════════════════════════════════════════════
205
+ DESIGN TOKENS & BASE STYLES
206
+ Wrapped in @layer substrate for specificity isolation.
207
+ ═══════════════════════════════════════════════════════════════════════════ */
208
+
209
+ @layer substrate {
210
+ /* ─── Spacing Scale (4px base) ─── */
211
+
212
+ :root {
213
+ --spacing-0: 0;
214
+ --spacing-0_5: 0.125rem; /* 2px */
215
+ --spacing-1: 0.25rem; /* 4px */
216
+ --spacing-1_5: 0.375rem; /* 6px */
217
+ --spacing-2: 0.5rem; /* 8px */
218
+ --spacing-3: 0.75rem; /* 12px */
219
+ --spacing-4: 1rem; /* 16px */
220
+ --spacing-6: 1.5rem; /* 24px */
221
+ --spacing-8: 2rem; /* 32px */
222
+ --spacing-10: 2.5rem; /* 40px */
223
+ --spacing-12: 3rem; /* 48px */
224
+ --spacing-16: 4rem; /* 64px */
225
+ --spacing-20: 5rem; /* 80px */
226
+ --spacing-24: 6rem; /* 96px */
227
+ --spacing-28: 7rem; /* 112px */
228
+ }
229
+
230
+ /* ─── Typography Scale ─── */
231
+
232
+ :root {
233
+ --text-xs: 0.75rem; /* 12px */
234
+ --text-sm: 0.875rem; /* 14px */
235
+ --text-base: 1rem; /* 16px */
236
+ --text-lg: 1.125rem; /* 18px */
237
+ --text-xl: 1.25rem; /* 20px */
238
+ --text-2xl: 1.5rem; /* 24px */
239
+ --text-3xl: 1.875rem; /* 30px */
240
+ --text-4xl: 2.25rem; /* 36px */
241
+ --text-5xl: 3rem; /* 48px */
242
+ --text-6xl: 3.75rem; /* 60px */
243
+
244
+ --leading-none: 1;
245
+ --leading-tight: 1.25;
246
+ --leading-normal: 1.5;
247
+ --leading-relaxed: 1.625;
248
+
249
+ --tracking-tight: -0.025em;
250
+ --tracking-normal: 0;
251
+
252
+ --weight-normal: 400;
253
+ --weight-medium: 500;
254
+ --weight-bold: 700;
255
+ }
256
+
257
+ /* ─── Fluid Typography (responsive, opt-in) ─── */
258
+
259
+ :root {
260
+ --text-3xl-fluid: clamp(1.5rem, 1.25rem + 1.25vw, 1.875rem); /* 24px → 30px */
261
+ --text-4xl-fluid: clamp(1.875rem, 1.5rem + 1.875vw, 2.25rem); /* 30px → 36px */
262
+ --text-5xl-fluid: clamp(2.25rem, 1.5rem + 3.75vw, 3rem); /* 36px → 48px */
263
+ --text-6xl-fluid: clamp(2.5rem, 1.5rem + 5vw, 3.75rem); /* 40px → 60px */
264
+ }
265
+
266
+ /* ─── Motion Tokens ─── */
267
+
268
+ :root {
269
+ --duration-fast: 100ms;
270
+ --duration-normal: 200ms;
271
+ --duration-slow: 400ms;
272
+ --duration-slower: 600ms;
273
+
274
+ --ease-default: cubic-bezier(0.4, 0, 0.2, 1);
275
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
276
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
277
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
278
+ --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
279
+ --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
280
+ }
281
+
282
+ /* ─── Z-index Scale ─── */
283
+
284
+ :root {
285
+ --z-base: 0;
286
+ --z-dropdown: 50;
287
+ --z-sticky: 100;
288
+ --z-overlay: 200;
289
+ --z-modal: 300;
290
+ --z-popover: 400;
291
+ --z-toast: 500;
292
+ }
293
+
294
+ /* ─── Opacity Tokens ─── */
295
+
296
+ :root {
297
+ --opacity-disabled: 0.5;
298
+ --opacity-hover: 0.8;
299
+ --opacity-placeholder: 0.5;
300
+ }
301
+
302
+ /* ─── Border Radius ─── */
303
+
304
+ :root {
305
+ --radius: 0;
306
+ --radius-none: 0;
307
+ --radius-sm: 0.25rem;
308
+ --radius-md: 0.5rem;
309
+ --radius-lg: 0.75rem;
310
+ --radius-full: 9999px;
311
+ }
312
+
313
+ /* ─── Color Tokens (Light Theme) ─── */
314
+
315
+ :root {
316
+ --page: #DCEBFE;
317
+ --page-foreground: #000;
318
+ --background: #fff;
319
+ --foreground: #000;
320
+ --card: #fff;
321
+ --card-foreground: #000;
322
+ --primary: #5294FF;
323
+ --primary-hover: #3D7FE6;
324
+ --primary-foreground: #000;
325
+ --secondary: #fff;
326
+ --secondary-foreground: #000;
327
+ --muted: #d5d5d5;
328
+ --muted-foreground: #555;
329
+ --accent: #5294FF;
330
+ --accent-foreground: #000;
331
+ --destructive: #e63946;
332
+ --destructive-foreground: #fff;
333
+ --success: #4ade80;
334
+ --success-foreground: #000;
335
+ --warning: #fbbf24;
336
+ --warning-foreground: #000;
337
+ --info: #60a5fa;
338
+ --info-foreground: #000;
339
+ --error: #f87171;
340
+ --error-foreground: #000;
341
+ --overlay: rgba(0, 0, 0, 0.85);
342
+ --border: #000;
343
+ --ring: #000;
344
+ --input: #fff;
345
+ --grid-line: rgba(255, 255, 255, 0.5);
346
+ }
347
+
348
+ /* ─── Color Palette Scales ─── */
349
+
350
+ :root {
351
+ --primary-50: #EBF2FF;
352
+ --primary-100: #D6E5FF;
353
+ --primary-200: #ADC9FF;
354
+ --primary-300: #85AEFF;
355
+ --primary-400: #5294FF;
356
+ --primary-500: #3D7FE6;
357
+ --primary-600: #2E66BF;
358
+ --primary-700: #1F4D99;
359
+ --primary-800: #133573;
360
+ --primary-900: #0A1F4D;
361
+
362
+ --destructive-50: #FDE8EA;
363
+ --destructive-100: #FAC5CA;
364
+ --destructive-200: #F38B95;
365
+ --destructive-300: #EC5160;
366
+ --destructive-400: #E63946;
367
+ --destructive-500: #CC2D3A;
368
+ --destructive-600: #A6242F;
369
+ --destructive-700: #801B24;
370
+ --destructive-800: #591319;
371
+ --destructive-900: #330B0E;
372
+
373
+ --success-50: #ECFDF2;
374
+ --success-100: #D1FAE0;
375
+ --success-200: #A3F4C1;
376
+ --success-300: #74EEA1;
377
+ --success-400: #4ADE80;
378
+ --success-500: #36C76A;
379
+ --success-600: #28A554;
380
+ --success-700: #1B833E;
381
+ --success-800: #0E6128;
382
+ --success-900: #053F14;
383
+
384
+ --warning-50: #FEF7E6;
385
+ --warning-100: #FDF0CC;
386
+ --warning-200: #FBE199;
387
+ --warning-300: #FBD266;
388
+ --warning-400: #FBBF24;
389
+ --warning-500: #E0A91A;
390
+ --warning-600: #B88A14;
391
+ --warning-700: #8F6B0E;
392
+ --warning-800: #674C08;
393
+ --warning-900: #3F2E03;
394
+
395
+ --info-50: #EFF5FF;
396
+ --info-100: #DBEAFE;
397
+ --info-200: #B7D5FD;
398
+ --info-300: #93BFFC;
399
+ --info-400: #60A5FA;
400
+ --info-500: #4B8FE0;
401
+ --info-600: #3A73BF;
402
+ --info-700: #2B579F;
403
+ --info-800: #1C3B7F;
404
+ --info-900: #0E205F;
405
+
406
+ --error-50: #FEF0F0;
407
+ --error-100: #FEE2E2;
408
+ --error-200: #FDB9B9;
409
+ --error-300: #FC9090;
410
+ --error-400: #F87171;
411
+ --error-500: #E05555;
412
+ --error-600: #BF3A3A;
413
+ --error-700: #9F2020;
414
+ --error-800: #7F1010;
415
+ --error-900: #5F0505;
416
+ }
417
+
418
+ /* ─── Color Tokens (Dark Theme) ─── */
419
+
420
+ .dark {
421
+ --page: #20294B;
422
+ --page-foreground: #E6E6E6;
423
+ --background: #1F1F1F;
424
+ --foreground: #E6E6E6;
425
+ --card: #20294B;
426
+ --card-foreground: #E6E6E6;
427
+ --primary: #5294FF;
428
+ --primary-hover: #3D7FE6;
429
+ --primary-foreground: #000;
430
+ --secondary: #1F1F1F;
431
+ --secondary-foreground: #E6E6E6;
432
+ --muted: #1F1F1F;
433
+ --muted-foreground: #999;
434
+ --accent: #5294FF;
435
+ --accent-foreground: #000;
436
+ --destructive: #e63946;
437
+ --destructive-foreground: #fff;
438
+ --success: #4ade80;
439
+ --success-foreground: #000;
440
+ --warning: #fbbf24;
441
+ --warning-foreground: #000;
442
+ --info: #60a5fa;
443
+ --info-foreground: #000;
444
+ --error: #f87171;
445
+ --error-foreground: #7f1d1d;
446
+ --overlay: rgba(0, 0, 0, 0.85);
447
+ --border: #000;
448
+ --ring: #fff;
449
+ --input: #1F1F1F;
450
+ --grid-line: rgba(255, 255, 255, 0.06);
451
+ }
452
+
453
+ /* ─── Optional: rounded corners ─── */
454
+
455
+ .with-radius {
456
+ --radius: var(--radius-md);
457
+ }
458
+
459
+ /* ─── Base body styles ─── */
460
+
461
+ body {
462
+ background-color: var(--page);
463
+ background-image:
464
+ linear-gradient(var(--grid-line) 1px, transparent 1px),
465
+ linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
466
+ background-size: 40px 40px;
467
+ color: var(--page-foreground);
468
+ font-family: var(--font-sans), 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
469
+ }
470
+
471
+ /* ─── Scrollbar (dark mode) ─── */
472
+
473
+ .dark {
474
+ scrollbar-color: #E6E6E6 #1F1F1F;
475
+ }
476
+
477
+ /* ─── Reduced motion ─── */
478
+
479
+ @media (prefers-reduced-motion: reduce) {
480
+ *,
481
+ *::before,
482
+ *::after {
483
+ animation-duration: 0.01ms !important;
484
+ animation-iteration-count: 1 !important;
485
+ transition-duration: 0.01ms !important;
486
+ scroll-behavior: auto !important;
487
+ }
488
+ }
489
+ }