sid-ui 0.0.0-stage → 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.
Files changed (116) hide show
  1. package/README.md +54 -2
  2. package/package.json +51 -4
  3. package/src/brand/BrandFooter.tsx +45 -0
  4. package/src/brand/BrandHeading.tsx +24 -0
  5. package/src/brand/BrandLockup.tsx +47 -0
  6. package/src/brand/JoinedLogo.tsx +67 -0
  7. package/src/brand/JoinedMark.tsx +76 -0
  8. package/src/brand/geometry.ts +26 -0
  9. package/src/brand/index.ts +11 -0
  10. package/src/brand/name.ts +5 -0
  11. package/src/brand/paint.tsx +56 -0
  12. package/src/components/Action.tsx +44 -0
  13. package/src/components/AddressSelector.tsx +99 -0
  14. package/src/components/BarChart.tsx +132 -0
  15. package/src/components/Calendar.tsx +284 -0
  16. package/src/components/CalendarAgenda.tsx +87 -0
  17. package/src/components/CalendarMonth.tsx +223 -0
  18. package/src/components/CalendarSchedule.tsx +210 -0
  19. package/src/components/Card.tsx +80 -0
  20. package/src/components/Charts.tsx +64 -0
  21. package/src/components/Chat.tsx +35 -0
  22. package/src/components/CitySelector.tsx +81 -0
  23. package/src/components/Clock.tsx +196 -0
  24. package/src/components/CodeInput.tsx +183 -0
  25. package/src/components/Container.tsx +20 -0
  26. package/src/components/Content.tsx +50 -0
  27. package/src/components/Data.tsx +43 -0
  28. package/src/components/DataInput.tsx +107 -0
  29. package/src/components/DateField.tsx +162 -0
  30. package/src/components/DonutChart.tsx +123 -0
  31. package/src/components/Drawer.tsx +110 -0
  32. package/src/components/Feedback.tsx +37 -0
  33. package/src/components/FileUploader.tsx +377 -0
  34. package/src/components/FunnelChart.tsx +83 -0
  35. package/src/components/Glyph.tsx +330 -0
  36. package/src/components/GoogleSignIn.tsx +67 -0
  37. package/src/components/GridSystem.tsx +131 -0
  38. package/src/components/HeatmapCalendar.tsx +167 -0
  39. package/src/components/KanbanBoard.tsx +421 -0
  40. package/src/components/Kpi.tsx +61 -0
  41. package/src/components/LayoutPrimitives.tsx +86 -0
  42. package/src/components/Lists.tsx +19 -0
  43. package/src/components/LocationSelector.tsx +49 -0
  44. package/src/components/MessageList.tsx +80 -0
  45. package/src/components/Nav.tsx +69 -0
  46. package/src/components/Navigation.tsx +52 -0
  47. package/src/components/Notification.tsx +115 -0
  48. package/src/components/NotificationTrigger.tsx +248 -0
  49. package/src/components/Overlay.tsx +50 -0
  50. package/src/components/Page.tsx +143 -0
  51. package/src/components/PageTabs.tsx +28 -0
  52. package/src/components/PickerShell.tsx +138 -0
  53. package/src/components/PillNav.tsx +194 -0
  54. package/src/components/Primitives.tsx +30 -0
  55. package/src/components/Rating.tsx +78 -0
  56. package/src/components/Responsive.tsx +128 -0
  57. package/src/components/ResponsiveFrame.tsx +122 -0
  58. package/src/components/Segment.tsx +190 -0
  59. package/src/components/Sparkline.tsx +52 -0
  60. package/src/components/StateSelector.tsx +39 -0
  61. package/src/components/Sticky.tsx +95 -0
  62. package/src/components/Table.tsx +344 -0
  63. package/src/components/ThemeToggle.tsx +48 -0
  64. package/src/components/Tile.tsx +23 -0
  65. package/src/components/TimeColumns.tsx +155 -0
  66. package/src/components/TimeDial.tsx +260 -0
  67. package/src/components/TimeField.tsx +196 -0
  68. package/src/components/TimeInput.tsx +213 -0
  69. package/src/components/TimeSlots.tsx +83 -0
  70. package/src/components/Timeline.tsx +111 -0
  71. package/src/components/TokenDemo.tsx +378 -0
  72. package/src/components/Tree.tsx +283 -0
  73. package/src/components/TrendChart.tsx +211 -0
  74. package/src/components/breakpoints.ts +42 -0
  75. package/src/components/calendarTypes.ts +26 -0
  76. package/src/components/chartMath.ts +125 -0
  77. package/src/components/chartParts.tsx +116 -0
  78. package/src/components/codeInputRules.ts +58 -0
  79. package/src/components/date.ts +87 -0
  80. package/src/components/hooks.ts +53 -0
  81. package/src/components/index.ts +195 -0
  82. package/src/components/kanban.ts +78 -0
  83. package/src/components/motion.ts +78 -0
  84. package/src/components/places-search.tsx +73 -0
  85. package/src/components/places.ts +209 -0
  86. package/src/components/size.ts +3 -0
  87. package/src/components/time.ts +83 -0
  88. package/src/components/useFileDrop.ts +104 -0
  89. package/src/places/geoapify.ts +129 -0
  90. package/src/styles/astryx.css +5 -0
  91. package/src/styles/components/brand.css +98 -0
  92. package/src/styles/components/calendar.css +680 -0
  93. package/src/styles/components/charts.css +659 -0
  94. package/src/styles/components/code-input.css +233 -0
  95. package/src/styles/components/google.css +11 -0
  96. package/src/styles/components/message-list.css +153 -0
  97. package/src/styles/components/notification.css +350 -0
  98. package/src/styles/components/picker.css +114 -0
  99. package/src/styles/components/pill-nav.css +179 -0
  100. package/src/styles/components/responsive.css +419 -0
  101. package/src/styles/components/sticky.css +23 -0
  102. package/src/styles/components/table.css +267 -0
  103. package/src/styles/components/time.css +526 -0
  104. package/src/styles/components/timeline.css +426 -0
  105. package/src/styles/components/tree.css +269 -0
  106. package/src/styles/components.css +423 -0
  107. package/src/styles/joined.css +4 -0
  108. package/src/styles/theme.css +79 -0
  109. package/src/styles/tokens.css +338 -0
  110. package/src/theme/JoinedProvider.tsx +50 -0
  111. package/src/theme/index.ts +3 -0
  112. package/src/theme/joined.d.ts +11 -0
  113. package/src/theme/joined.js +569 -0
  114. package/src/theme/joined.theme.ts +74 -0
  115. package/src/theme/joined.variants.d.ts +16 -0
  116. package/src/theme/theme.css +786 -0
@@ -0,0 +1,423 @@
1
+ /* Joined-shaped UI kit. Visual language matches https://astryx.atmeta.com/
2
+ (system fonts, pill buttons, no chrome borders on primary/ghost).
3
+ Color comes only from tokens.css. Control sizes are one step up from Astryx:
4
+ sm is the old md, md is the old lg, and lg is a larger step. */
5
+
6
+ @import "./components/picker.css";
7
+ @import "./components/tree.css";
8
+ @import "./components/timeline.css";
9
+ @import "./components/table.css";
10
+ @import "./components/time.css";
11
+ @import "./components/calendar.css";
12
+ @import "./components/responsive.css";
13
+ @import "./components/notification.css";
14
+ @import "./components/sticky.css";
15
+ @import "./components/charts.css";
16
+ @import "./components/message-list.css";
17
+ @import "./components/pill-nav.css";
18
+ @import "./components/code-input.css";
19
+ @import "./components/brand.css";
20
+ @import "./components/google.css";
21
+
22
+ /* Input / Field */
23
+ .os-field-group {
24
+ display: flex;
25
+ flex-direction: column;
26
+ gap: var(--spacing-1);
27
+ box-sizing: border-box;
28
+ }
29
+
30
+ .os-field-helper {
31
+ color: var(--color-text-secondary);
32
+ font-size: var(--font-size-sm);
33
+ }
34
+ .os-field-helper-error {
35
+ color: var(--color-error);
36
+ font-size: var(--font-size-sm);
37
+ }
38
+
39
+ /* Form controls */
40
+ .os-check {
41
+ display: inline-flex;
42
+ align-items: center;
43
+ gap: var(--space-2);
44
+ cursor: pointer;
45
+ color: var(--ink);
46
+ }
47
+ .os-check input {
48
+ accent-color: var(--color-accent, var(--primary));
49
+ width: 18px;
50
+ height: 18px;
51
+ margin: 0;
52
+ }
53
+
54
+ /* Preview / docs chrome */
55
+ .os-preview-grid {
56
+ display: grid;
57
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
58
+ gap: var(--spacing-4);
59
+ }
60
+ .os-preview {
61
+ background: transparent;
62
+ border-radius: var(--radius-container);
63
+ overflow: hidden;
64
+ border: none;
65
+ }
66
+ .os-preview-stage {
67
+ min-height: 220px;
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ padding: var(--spacing-8);
72
+ background: var(--color-background-muted);
73
+ box-sizing: border-box;
74
+ border-radius: var(--radius-container);
75
+ }
76
+ .os-preview-label {
77
+ margin: 8px 0 0;
78
+ padding: 0;
79
+ color: var(--color-text-secondary);
80
+ font-size: 14px;
81
+ }
82
+ .os-page-body {
83
+ max-width: 880px;
84
+ padding: 40px 48px 96px;
85
+ box-sizing: border-box;
86
+ }
87
+
88
+ /* Kanban surfaces need their own contrast layer. The default muted Card is
89
+ intentionally subtle, but that makes adjacent columns merge in dark mode. */
90
+ .os-kanban-row > .os-kanban-cell {
91
+ position: relative;
92
+ overflow: hidden;
93
+ background: var(--color-background-muted);
94
+ border: 1px solid var(--color-border-emphasized);
95
+ border-block-start: 4px solid var(--color-accent);
96
+ box-shadow: var(--shadow-sm);
97
+ }
98
+
99
+ .os-kanban-row > .os-kanban-cell:nth-child(2) {
100
+ border-block-start-color: var(--color-warning);
101
+ }
102
+
103
+ .os-kanban-row > .os-kanban-cell:nth-child(3) {
104
+ border-block-start-color: var(--color-success);
105
+ }
106
+
107
+ .os-kanban-row > .os-kanban-cell:nth-child(4) {
108
+ border-block-start-color: var(--color-error);
109
+ }
110
+
111
+ .os-kanban-cell [role="list"] {
112
+ min-height: inherit;
113
+ }
114
+
115
+ .os-kanban-cell [data-kanban-card] {
116
+ border-radius: var(--radius-inner);
117
+ transition:
118
+ transform 160ms ease,
119
+ filter 160ms ease;
120
+ }
121
+
122
+ .os-kanban-cell [data-kanban-card]:hover {
123
+ transform: translateY(-1px);
124
+ filter: brightness(1.04);
125
+ }
126
+
127
+ .os-kanban-cell [data-kanban-card]:focus-visible {
128
+ outline: 3px solid var(--color-accent);
129
+ outline-offset: 3px;
130
+ }
131
+ .os-page-hero {
132
+ max-width: 720px;
133
+ margin: 0 auto 48px;
134
+ text-align: center;
135
+ padding-top: 48px;
136
+ }
137
+
138
+ /* Field — quiet fill, label above, accent ring on focus */
139
+ .os-field-label {
140
+ font-size: var(--font-size-sm, 0.75rem);
141
+ font-weight: 500;
142
+ color: var(--color-text-secondary);
143
+ letter-spacing: 0.01em;
144
+ }
145
+ .os-field-description {
146
+ margin: 0;
147
+ font-size: var(--font-size-sm, 0.75rem);
148
+ color: var(--color-text-secondary);
149
+ }
150
+ .os-control {
151
+ display: flex;
152
+ align-items: center;
153
+ gap: var(--spacing-2);
154
+ min-height: 40px;
155
+ padding: 0 var(--spacing-3);
156
+ background: var(--color-background-surface);
157
+ border: 1px solid var(--color-border-emphasized);
158
+ border-radius: var(--radius-element);
159
+ transition: border-color var(--duration-fast) var(--ease-standard);
160
+ }
161
+ .os-control-sm {
162
+ min-height: 32px;
163
+ }
164
+ .os-control-md {
165
+ min-height: 40px;
166
+ }
167
+ .os-control-lg {
168
+ min-height: 48px;
169
+ }
170
+ .os-control:hover {
171
+ border-color: var(--color-text-disabled);
172
+ }
173
+ .os-control:focus-within {
174
+ outline: 2px solid var(--color-accent);
175
+ outline-offset: 1px;
176
+ border-color: var(--color-accent);
177
+ }
178
+ .os-control-error {
179
+ border-color: var(--color-error);
180
+ background: var(--color-background-surface);
181
+ }
182
+ .os-control-error:focus-within {
183
+ outline-color: var(--color-error);
184
+ border-color: var(--color-error);
185
+ }
186
+
187
+ .os-control-disabled {
188
+ opacity: 0.45;
189
+ }
190
+
191
+ /* Rating */
192
+ .os-rating {
193
+ display: inline-flex;
194
+ align-items: center;
195
+ gap: var(--spacing-2);
196
+ }
197
+ .os-rating-stars {
198
+ display: inline-flex;
199
+ gap: 2px;
200
+ }
201
+ .os-star {
202
+ border: 0;
203
+ background: transparent;
204
+ color: var(--color-border-emphasized, var(--color-border));
205
+ font-size: 20px;
206
+ line-height: 1;
207
+ padding: 0;
208
+ cursor: default;
209
+ }
210
+ button.os-star {
211
+ cursor: pointer;
212
+ }
213
+ .os-star-on {
214
+ color: var(--color-warning);
215
+ }
216
+ .os-rating-sm .os-star {
217
+ font-size: 14px;
218
+ }
219
+ .os-rating-lg .os-star {
220
+ font-size: 28px;
221
+ }
222
+ .os-rating-value {
223
+ font-size: var(--font-size-sm, 0.75rem);
224
+ color: var(--color-text-secondary);
225
+ font-variant-numeric: tabular-nums;
226
+ }
227
+
228
+ .os-rating-caption {
229
+ font-size: var(--font-size-sm, 0.75rem);
230
+ color: var(--color-text-primary);
231
+ }
232
+
233
+ /* One step up from the Astryx scale, on :root so portaled menus inherit it.
234
+ sm 32 (old md), md 36 (old lg), lg 48. */
235
+ :root {
236
+ --size-element-sm: 32px;
237
+ --size-element-md: 36px;
238
+ --size-element-lg: 48px;
239
+ --control-height-sm: var(--size-element-sm);
240
+ --control-height: var(--size-element-md);
241
+ --control-height-lg: var(--size-element-lg);
242
+ }
243
+
244
+ /* Pill buttons, same idea as the nav pills: a full radius, and enough inline
245
+ padding that the label sits clear of the curve. The radius is the private
246
+ Astryx variable, so a chat composer or thumbnail can still tighten the
247
+ buttons inside it. Icon-only controls stay circles. */
248
+ [data-astryx-theme] {
249
+ --_button-radius: var(--radius-full);
250
+ }
251
+
252
+ .astryx-button {
253
+ padding-inline: var(--spacing-5);
254
+ }
255
+
256
+ .astryx-button[data-size="sm"] {
257
+ padding-inline: var(--spacing-4);
258
+ }
259
+
260
+ .astryx-button[data-size="lg"] {
261
+ padding-inline: var(--spacing-8);
262
+ font-size: var(--font-size-lg);
263
+ }
264
+
265
+ /* Icon slot: sm keeps 16. md takes the old large mark. lg steps up again. */
266
+ .astryx-button[data-size="md"] > span > span:has(> svg),
267
+ .astryx-button[data-size="md"] > span > span:has(> svg) > svg {
268
+ width: 20px;
269
+ height: 20px;
270
+ font-size: 20px;
271
+ }
272
+
273
+ .astryx-button[data-size="lg"] > span > span:has(> svg),
274
+ .astryx-button[data-size="lg"] > span > span:has(> svg) > svg {
275
+ width: 24px;
276
+ height: 24px;
277
+ font-size: 24px;
278
+ }
279
+
280
+ /* Menu rows follow the same ladder. sm is the old md row, md is the old lg
281
+ row, lg is a full large control. */
282
+ .astryx-dropdown-menu-item[data-size="sm"] {
283
+ min-height: var(--size-element-sm);
284
+ padding-block: var(--spacing-1-5);
285
+ }
286
+
287
+ .astryx-dropdown-menu-item[data-size="md"] {
288
+ min-height: var(--size-element-md);
289
+ padding-block: var(--spacing-2);
290
+ }
291
+
292
+ .astryx-dropdown-menu-item[data-size="md"] .astryx-icon {
293
+ width: 1.25rem;
294
+ height: 1.25rem;
295
+ font-size: 1.25rem;
296
+ }
297
+
298
+ .astryx-dropdown-menu-item[data-size="lg"] {
299
+ min-height: var(--size-element-lg);
300
+ padding-block: var(--spacing-3);
301
+ padding-inline: var(--spacing-3);
302
+ font-size: var(--font-size-lg);
303
+ }
304
+
305
+ .astryx-dropdown-menu-item[data-size="lg"] .astryx-icon {
306
+ width: 1.5rem;
307
+ height: 1.5rem;
308
+ font-size: 1.5rem;
309
+ }
310
+
311
+ /* Segmented control is a pill track. Neutral shrinks each item by 8px, which
312
+ after the size step-up lands on the old small height, and the radius token
313
+ is the element radius. Items use the control size; the track is fully round. */
314
+ .astryx-segmented-control {
315
+ --_segmented-control-radius: var(--radius-full);
316
+ border-radius: var(--radius-full);
317
+ }
318
+
319
+ .astryx-segmented-control-item[data-size="sm"] {
320
+ height: var(--size-element-sm);
321
+ }
322
+
323
+ .astryx-segmented-control-item[data-size="md"] {
324
+ height: var(--size-element-md);
325
+ }
326
+
327
+ .astryx-segmented-control-item[data-size="lg"] {
328
+ height: var(--size-element-lg);
329
+ }
330
+
331
+ .astryx-button:has(> span > span:only-child svg) {
332
+ padding-inline: 0;
333
+ padding-block: 0;
334
+ }
335
+
336
+ /* Joined buttons share one capsule: outer ends are full, seams stay square.
337
+ The trailing test matches Astryx, so a menu layer after the last button
338
+ does not steal the end cap. */
339
+ .astryx-button-group[data-orientation="horizontal"] .astryx-button:first-child {
340
+ border-start-start-radius: var(--radius-full);
341
+ border-end-start-radius: var(--radius-full);
342
+ }
343
+
344
+ .astryx-button-group[data-orientation="horizontal"]
345
+ .astryx-button:not(:has(~ *:not([popover]):not(template))) {
346
+ border-start-end-radius: var(--radius-full);
347
+ border-end-end-radius: var(--radius-full);
348
+ }
349
+
350
+ .astryx-button-group[data-orientation="vertical"] .astryx-button:first-child {
351
+ border-start-start-radius: var(--radius-full);
352
+ border-start-end-radius: var(--radius-full);
353
+ }
354
+
355
+ .astryx-button-group[data-orientation="vertical"]
356
+ .astryx-button:not(:has(~ *:not([popover]):not(template))) {
357
+ border-end-start-radius: var(--radius-full);
358
+ border-end-end-radius: var(--radius-full);
359
+ }
360
+
361
+ .astryx-button-group[data-elevation="low"],
362
+ .astryx-button-group[data-elevation="med"],
363
+ .astryx-button-group[data-elevation="high"] {
364
+ border-radius: var(--radius-full);
365
+ }
366
+
367
+ /* Pressed toggles stay outlined. A weak accent wash sits behind the accent
368
+ icon and label, so on reads as color rather than a solid fill. */
369
+ .astryx-toggle-button[data-is-pressed="true"] {
370
+ background-color: var(--color-accent-muted);
371
+ color: var(--color-accent);
372
+ }
373
+ .astryx-toggle-button[data-is-pressed="true"] .os-glyph {
374
+ color: var(--color-accent);
375
+ fill: none;
376
+ }
377
+
378
+ @media (forced-colors: active) {
379
+ .astryx-toggle-button[data-is-pressed="true"] {
380
+ background-color: Highlight;
381
+ color: HighlightText;
382
+ }
383
+ }
384
+
385
+ .os-swatch-grid {
386
+ display: grid;
387
+ grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
388
+ gap: var(--space-2);
389
+ }
390
+ .os-swatch {
391
+ overflow: hidden;
392
+ border-radius: var(--radius-md);
393
+ border: var(--border-width-hairline) solid var(--border-subtle);
394
+ background: var(--surface-sunken);
395
+ }
396
+ .os-swatch-chip {
397
+ height: 40px;
398
+ border-bottom: var(--border-width-hairline) solid var(--border-subtle);
399
+ }
400
+ .os-swatch-body {
401
+ padding: var(--space-2);
402
+ }
403
+ .os-swatch-body .caption {
404
+ display: block;
405
+ white-space: nowrap;
406
+ overflow: hidden;
407
+ text-overflow: ellipsis;
408
+ }
409
+ .os-token-demo {
410
+ border: var(--border-width-hairline) solid var(--border-subtle);
411
+ border-radius: var(--radius-lg);
412
+ background: var(--surface);
413
+ padding: var(--space-4);
414
+ }
415
+ .os-token-demo-toolbar {
416
+ display: flex;
417
+ flex-wrap: wrap;
418
+ align-items: center;
419
+ gap: var(--space-3);
420
+ }
421
+ .os-token-group {
422
+ margin-bottom: var(--space-8);
423
+ }
@@ -0,0 +1,4 @@
1
+ /* The full Joined stylesheet — Astryx foundation, then Joined
2
+ composites. Apps import this one file. */
3
+ @import "./astryx.css";
4
+ @import "./components.css";
@@ -0,0 +1,79 @@
1
+ @import "./tokens.css";
2
+ @import "./components.css";
3
+
4
+ @source "../components/**/*.{ts,tsx}";
5
+
6
+ /* Point Tailwind's dark: variant at our [data-theme] attribute instead of
7
+ prefers-color-scheme, so dark: utilities and the Joined tokens read
8
+ from the same switch. */
9
+ @custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
10
+
11
+ /* Exposes the Joined tokens as Tailwind v4 utilities (bg-primary,
12
+ text-ink-muted, rounded-pill, duration-fast, …). "inline" keeps these
13
+ bound to the live custom property so the dark/light swap keeps working. */
14
+ @theme inline {
15
+ --color-canvas: var(--canvas);
16
+ --color-surface: var(--surface);
17
+ --color-surface-sunken: var(--surface-sunken);
18
+ --color-surface-hover: var(--surface-hover);
19
+ --color-surface-selected: var(--surface-selected);
20
+ --color-border-subtle: var(--border-subtle);
21
+ --color-border-default: var(--border-default);
22
+ --color-border-strong: var(--border-strong);
23
+ --color-border-focus: var(--border-focus);
24
+ --color-ink: var(--ink);
25
+ --color-ink-muted: var(--ink-muted);
26
+ --color-ink-faint: var(--ink-faint);
27
+ --color-on-primary: var(--on-primary);
28
+ --color-primary: var(--primary);
29
+ --color-primary-hover: var(--primary-hover);
30
+ --color-primary-active: var(--primary-active);
31
+ --color-primary-bg: var(--primary-bg);
32
+ --color-link: var(--link);
33
+ --color-link-hover: var(--link-hover);
34
+ --color-success: var(--success);
35
+ --color-success-bg: var(--success-bg);
36
+ --color-warning: var(--warning);
37
+ --color-warning-bg: var(--warning-bg);
38
+ --color-danger: var(--danger);
39
+ --color-danger-hover: var(--danger-hover);
40
+ --color-danger-bg: var(--danger-bg);
41
+ --color-meta-blue-50: var(--meta-blue-50);
42
+ --color-meta-blue-100: var(--meta-blue-100);
43
+ --color-meta-blue-200: var(--meta-blue-200);
44
+ --color-meta-blue-300: var(--meta-blue-300);
45
+ --color-meta-blue-400: var(--meta-blue-400);
46
+ --color-meta-blue-500: var(--meta-blue-500);
47
+ --color-meta-blue-600: var(--meta-blue-600);
48
+ --color-meta-blue-700: var(--meta-blue-700);
49
+ --color-meta-blue-800: var(--meta-blue-800);
50
+ --color-meta-blue-900: var(--meta-blue-900);
51
+ --color-meta-blue-950: var(--meta-blue-950);
52
+
53
+ --radius-pill: 999px;
54
+
55
+ --shadow-1: var(--elevation-1);
56
+ --shadow-2: var(--elevation-2);
57
+ --shadow-3: var(--elevation-3);
58
+
59
+ --duration-fast: 80ms;
60
+ --duration-normal: 120ms;
61
+ --duration-slow: 200ms;
62
+ --ease-standard: var(--ease-standard);
63
+ --ease-decelerate: var(--ease-decelerate);
64
+ --ease-accelerate: var(--ease-accelerate);
65
+
66
+ --font-sans: var(--font-sans);
67
+ --font-mono: var(--font-mono);
68
+ }
69
+
70
+ html,
71
+ body {
72
+ height: 100%;
73
+ }
74
+ body {
75
+ margin: 0;
76
+ background: var(--canvas);
77
+ color: var(--ink);
78
+ font-family: var(--font-sans);
79
+ }