@sableui/react 0.1.1 → 0.3.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.
- package/AGENTS.md +3 -1
- package/CHANGELOG.md +120 -0
- package/CONTRIBUTING.md +8 -0
- package/README.md +1 -0
- package/bin/sable-lint.mjs +0 -0
- package/bin/sable.mjs +68 -26
- package/dist/{_contract-CYScOdf5.d.ts → _contract-o3tUc8Ig.d.ts} +1 -1
- package/dist/blocks/index.d.ts +396 -0
- package/dist/blocks/index.js +1997 -0
- package/dist/chunk-6LCIBMMG.js +4908 -0
- package/dist/{chunk-J23ELQQZ.js → chunk-CKNM7KSB.js} +1664 -4270
- package/dist/chunk-K6LII3OE.js +5093 -0
- package/dist/{chunk-RWP4XBSK.js → chunk-KFZ43RKU.js} +1 -1
- package/dist/{chunk-PAOZBZME.js → chunk-NGBDP3BM.js} +1 -1
- package/dist/{chunk-5Z5KLOAU.js → chunk-TH563WLW.js} +14 -1
- package/dist/{chunk-JI7WJP2L.js → chunk-X276MF2W.js} +5 -0
- package/dist/foundations/index.js +1 -1
- package/dist/icon/index.js +2 -2
- package/dist/icon-sets/reicon.js +1 -1
- package/dist/index.d.ts +624 -133
- package/dist/index.js +767 -4964
- package/dist/ios/index.d.ts +14 -2
- package/dist/ios/index.js +10 -9
- package/dist/ios/preview.d.ts +11 -1
- package/dist/ios/preview.js +14 -9
- package/dist/ios/styles.css +26 -6
- package/dist/{meta-6dUzgC6M.d.ts → meta-CcE_SeFu.d.ts} +37 -1
- package/dist/patterns/index.d.ts +1 -1
- package/dist/patterns/index.js +1684 -471
- package/dist/presets/index.d.ts +1 -1
- package/dist/presets/index.js +1 -1
- package/dist/styles.css +238 -40
- package/dist/{theme-provider-BWcizhAt.d.ts → theme-provider-BE-KqUG-.d.ts} +1 -1
- package/dist/themes/atelier/atelier.css +3 -0
- package/dist/themes/atelier/index.d.ts +1 -1
- package/dist/themes/base/base.css +34 -4
- package/dist/themes/base/index.d.ts +1 -1
- package/dist/themes/ember/ember.css +3 -0
- package/dist/themes/ember/index.d.ts +1 -1
- package/dist/themes/index.d.ts +2 -2
- package/dist/themes/index.js +2 -2
- package/dist/themes/meridian/index.d.ts +1 -1
- package/dist/themes/meridian/meridian.css +10 -5
- package/dist/themes/poppy/index.d.ts +1 -1
- package/dist/themes/poppy/poppy.css +16 -0
- package/dist/themes/prism/index.d.ts +1 -1
- package/dist/themes/prism/prism.css +4 -1
- package/dist/themes/verdant/index.d.ts +1 -1
- package/dist/themes/verdant/verdant.css +7 -2
- package/llms/blocks/api-keys-block.md +79 -0
- package/llms/blocks/chat-thread-block.md +51 -0
- package/llms/blocks/command-palette-block.md +48 -0
- package/llms/blocks/cta-band-block.md +62 -0
- package/llms/blocks/danger-zone-block.md +69 -0
- package/llms/blocks/device-comparison-block.md +91 -0
- package/llms/blocks/event-card-block.md +84 -0
- package/llms/blocks/faq-block.md +72 -0
- package/llms/blocks/feature-grid-block.md +75 -0
- package/llms/blocks/feedback-form-block.md +66 -0
- package/llms/blocks/goal-progress-block.md +54 -0
- package/llms/blocks/hero-block.md +65 -0
- package/llms/blocks/invite-team-block.md +61 -0
- package/llms/blocks/invoice-history-block.md +84 -0
- package/llms/blocks/kpi-sparkline-block.md +57 -0
- package/llms/blocks/media-player-block.md +100 -0
- package/llms/blocks/newsletter-block.md +64 -0
- package/llms/blocks/not-found-block.md +56 -0
- package/llms/blocks/notification-list-block.md +63 -0
- package/llms/blocks/notification-settings-block.md +54 -0
- package/llms/blocks/order-tracking-block.md +62 -0
- package/llms/blocks/pricing-card-block.md +82 -0
- package/llms/blocks/pricing-table-block.md +129 -0
- package/llms/blocks/product-card-block.md +69 -0
- package/llms/blocks/profile-card-block.md +103 -0
- package/llms/blocks/profile-form-block.md +114 -0
- package/llms/blocks/revenue-breakdown-block.md +70 -0
- package/llms/blocks/sign-in-block.md +64 -0
- package/llms/blocks/sign-up-block.md +78 -0
- package/llms/blocks/site-footer-block.md +96 -0
- package/llms/blocks/stat-row-block.md +59 -0
- package/llms/blocks/steps-block.md +73 -0
- package/llms/blocks/task-list-block.md +81 -0
- package/llms/blocks/team-members-block.md +91 -0
- package/llms/blocks/testimonial-block.md +78 -0
- package/llms/blocks/traffic-sources-block.md +63 -0
- package/llms/blocks/traffic-trend-block.md +95 -0
- package/llms/blocks/upload-list-block.md +66 -0
- package/llms/blocks/verify-code-block.md +59 -0
- package/llms/blocks/wallet-block.md +84 -0
- package/llms/components/area-chart.md +112 -0
- package/llms/components/bar-chart.md +131 -0
- package/llms/components/bubble.md +5 -5
- package/llms/components/button.md +1 -1
- package/llms/components/card.md +2 -2
- package/llms/components/checkbox-card.md +1 -1
- package/llms/components/context-card.md +2 -2
- package/llms/components/context-menu.md +1 -1
- package/llms/components/date-tile.md +79 -0
- package/llms/components/dialog.md +1 -1
- package/llms/components/empty-state.md +4 -4
- package/llms/components/entity.md +5 -3
- package/llms/components/fieldset.md +1 -1
- package/llms/components/kbd.md +18 -6
- package/llms/components/line-chart.md +101 -0
- package/llms/components/menu.md +1 -1
- package/llms/components/{dots-menu.md → overflow-menu.md} +9 -9
- package/llms/components/pie-chart.md +103 -0
- package/llms/components/pill.md +1 -1
- package/llms/components/radar-chart.md +106 -0
- package/llms/components/radial-chart.md +102 -0
- package/llms/components/segmented-bar.md +102 -0
- package/llms/components/settings-menu.md +2 -2
- package/llms/components/side-nav.md +1 -1
- package/llms/components/skeleton.md +1 -1
- package/llms/components/sparkline.md +80 -0
- package/llms/components/table.md +1 -1
- package/llms/components/theme-selector.md +1 -1
- package/llms/foundations/shape.md +1 -1
- package/llms/patterns/auth-page.md +132 -42
- package/llms/patterns/brand-landing-page.md +271 -175
- package/llms/patterns/chat-panel.md +120 -39
- package/llms/patterns/dashboard-page.md +276 -65
- package/llms/patterns/feed-page.md +245 -64
- package/llms/patterns/landing-page.md +473 -75
- package/llms/patterns/list-detail-page.md +377 -68
- package/llms/patterns/settings-page.md +268 -67
- package/llms/reference/token-intent.md +4 -2
- package/llms/reference/utilities.md +20 -5
- package/llms/tasks/building-an-ios-prototype.md +4 -1
- package/llms/tasks/choosing-a-component.md +2 -2
- package/llms-full.txt +6428 -892
- package/llms.txt +67 -16
- package/package.json +5 -1
- package/registry.json +3217 -552
- package/targets/ios.json +88 -18
- package/llms/components/description.md +0 -96
- package/dist/{chunk-L6Y46C62.js → chunk-MXJX3NZI.js} +1 -1
package/dist/presets/index.d.ts
CHANGED
package/dist/presets/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SEMANTIC_TOKENS, WORKSPACE_SURFACE_TOKENS, DERIVED_EDGE_TOKENS, RADIUS_TOKENS, MOTION_TOKENS, TYPE_SCALE_TOKENS, TYPE_REFINEMENT_TOKENS, TYPE_OVERLINE_TOKENS, DENSITY_TOKENS, LAYERING_TOKENS, TYPE_UI_TOKENS } from '../chunk-
|
|
1
|
+
import { SEMANTIC_TOKENS, WORKSPACE_SURFACE_TOKENS, DERIVED_EDGE_TOKENS, RADIUS_TOKENS, MOTION_TOKENS, TYPE_SCALE_TOKENS, TYPE_REFINEMENT_TOKENS, TYPE_OVERLINE_TOKENS, DENSITY_TOKENS, LAYERING_TOKENS, TYPE_UI_TOKENS } from '../chunk-X276MF2W.js';
|
|
2
2
|
|
|
3
3
|
// src/presets/index.ts
|
|
4
4
|
var PRESET_TOKEN_NAMES = [.../* @__PURE__ */ new Set([
|
package/dist/styles.css
CHANGED
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
|
|
53
53
|
/* Elevation — theme-provided so docs/app shells can express a different surface
|
|
54
54
|
feel without touching component code. */
|
|
55
|
-
--shadow-sm: var(--theme-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.
|
|
56
|
-
--shadow: var(--theme-shadow, 0 1px 2px 0 rgb(0 0 0 / 0.
|
|
55
|
+
--shadow-sm: var(--theme-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));
|
|
56
|
+
--shadow: var(--theme-shadow, 0 1px 2px 0 rgb(0 0 0 / 0.05), 0 3px 8px -2px rgb(0 0 0 / 0.08));
|
|
57
57
|
--shadow-md: var(--theme-shadow-md, 0 1px 2px 0 rgb(0 0 0 / 0.04), 0 4px 8px -2px rgb(0 0 0 / 0.06), 0 12px 24px -6px rgb(0 0 0 / 0.07));
|
|
58
58
|
--shadow-lg: var(--theme-shadow-lg, 0 2px 4px 0 rgb(0 0 0 / 0.04), 0 8px 16px -4px rgb(0 0 0 / 0.07), 0 24px 48px -12px rgb(0 0 0 / 0.11));
|
|
59
59
|
--shadow-xl: var(--theme-shadow-xl, 0 2px 4px 0 rgb(0 0 0 / 0.04), 0 12px 24px -6px rgb(0 0 0 / 0.08), 0 32px 64px -16px rgb(0 0 0 / 0.13));
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
--color-border-strong: var(--border-strong);
|
|
82
82
|
--color-border-floating: var(--border-floating);
|
|
83
83
|
--color-input: var(--input);
|
|
84
|
+
--color-control-border: var(--control-border);
|
|
84
85
|
--color-ring: var(--ring);
|
|
85
86
|
|
|
86
87
|
/* Sidebar set */
|
|
@@ -160,6 +161,27 @@
|
|
|
160
161
|
--z-skip-link: 100; /* the skip-to-content link — above all chrome */
|
|
161
162
|
}
|
|
162
163
|
|
|
164
|
+
/* ==========================================================================
|
|
165
|
+
Scrim strength — how much a modal's backdrop (`bg-overlay/(--scrim-alpha)`)
|
|
166
|
+
dims what is behind it, per mode.
|
|
167
|
+
|
|
168
|
+
`--overlay` is near-black in every theme and mode, which is right for a
|
|
169
|
+
scrim. But a dark page is near-black too: Base's dark `--background` IS its
|
|
170
|
+
`--overlay`, so a 50% scrim over it changed nothing, and with a dialog open
|
|
171
|
+
the page's text stayed at nearly full strength — while foundations/surfaces
|
|
172
|
+
calls the scrim "the primary depth cue" for a modal. Dark mode needs more of
|
|
173
|
+
the same scrim to dim the lighter things (cards, text, imagery) by as much.
|
|
174
|
+
A token rather than a `dark:` variant, like everything else mode-dependent.
|
|
175
|
+
========================================================================== */
|
|
176
|
+
|
|
177
|
+
:root,
|
|
178
|
+
.light {
|
|
179
|
+
--scrim-alpha: 50%;
|
|
180
|
+
}
|
|
181
|
+
.dark {
|
|
182
|
+
--scrim-alpha: 72%;
|
|
183
|
+
}
|
|
184
|
+
|
|
163
185
|
/* ==========================================================================
|
|
164
186
|
The page ground. Without it, `.dark` on <html> turned the ink light while the
|
|
165
187
|
page stayed the browser's white, so a fresh install in dark mode was
|
|
@@ -319,41 +341,50 @@
|
|
|
319
341
|
Typography — six tiers. Each utility bundles size + weight + line-height +
|
|
320
342
|
tracking. Compose with color/margin only; never override the four paired
|
|
321
343
|
properties individually. Mono uses the theme's --font-mono.
|
|
344
|
+
|
|
345
|
+
Leading is authored as a RATIO (the `--type-*-leading` hooks every theme
|
|
346
|
+
tunes) and rendered on the 0.25rem grid: `round(nearest, ratio × 1em,
|
|
347
|
+
0.25rem)`. Ratios alone landed almost nowhere on the grid DESIGN.md
|
|
348
|
+
promises (15px body at 1.55 = 23.25px, a 36px h1 at 1.15 = 41.4px), so
|
|
349
|
+
stacked text drifted off the vertical rhythm a fraction of a pixel per
|
|
350
|
+
line. Rounding keeps each tier's (and each theme's) intended proportion and
|
|
351
|
+
snaps the result — 24px and 40px there — at any root size, because the grid
|
|
352
|
+
step is in rem too. The `ui-*` tier is already whole px on the grid.
|
|
322
353
|
========================================================================== */
|
|
323
354
|
|
|
324
355
|
@utility text-display-4xl {
|
|
325
356
|
font-family: var(--font-display, var(--font-sans));
|
|
326
357
|
font-size: var(--type-display-4xl-size, clamp(4.5rem, 12vw, 12rem));
|
|
327
358
|
font-weight: var(--type-display-4xl-weight, 800);
|
|
328
|
-
line-height: var(--type-display-4xl-leading, 0.9);
|
|
359
|
+
line-height: round(nearest, calc(var(--type-display-4xl-leading, 0.9) * 1em), 0.25rem);
|
|
329
360
|
letter-spacing: var(--type-display-4xl-tracking, -0.05em);
|
|
330
361
|
}
|
|
331
362
|
@utility text-display-3xl {
|
|
332
363
|
font-family: var(--font-display, var(--font-sans));
|
|
333
364
|
font-size: var(--type-display-3xl-size, 6rem);
|
|
334
365
|
font-weight: var(--type-display-3xl-weight, 700);
|
|
335
|
-
line-height: var(--type-display-3xl-leading, 0.95);
|
|
366
|
+
line-height: round(nearest, calc(var(--type-display-3xl-leading, 0.95) * 1em), 0.25rem);
|
|
336
367
|
letter-spacing: var(--type-display-3xl-tracking, -0.045em);
|
|
337
368
|
}
|
|
338
369
|
@utility text-display-2xl {
|
|
339
370
|
font-family: var(--font-display, var(--font-sans));
|
|
340
371
|
font-size: var(--type-display-2xl-size, 4.5rem);
|
|
341
372
|
font-weight: var(--type-display-2xl-weight, 700);
|
|
342
|
-
line-height: var(--type-display-2xl-leading, 1);
|
|
373
|
+
line-height: round(nearest, calc(var(--type-display-2xl-leading, 1) * 1em), 0.25rem);
|
|
343
374
|
letter-spacing: var(--type-display-2xl-tracking, -0.04em);
|
|
344
375
|
}
|
|
345
376
|
@utility text-display-xl {
|
|
346
377
|
font-family: var(--font-display, var(--font-sans));
|
|
347
378
|
font-size: var(--type-display-xl-size, 3.75rem);
|
|
348
379
|
font-weight: var(--type-display-xl-weight, 700);
|
|
349
|
-
line-height: var(--type-display-xl-leading, 1.05);
|
|
380
|
+
line-height: round(nearest, calc(var(--type-display-xl-leading, 1.05) * 1em), 0.25rem);
|
|
350
381
|
letter-spacing: var(--type-display-xl-tracking, -0.035em);
|
|
351
382
|
}
|
|
352
383
|
@utility text-display-lg {
|
|
353
384
|
font-family: var(--font-display, var(--font-sans));
|
|
354
385
|
font-size: var(--type-display-lg-size, 3rem);
|
|
355
386
|
font-weight: var(--type-display-lg-weight, 700);
|
|
356
|
-
line-height: var(--type-display-lg-leading, 1.1);
|
|
387
|
+
line-height: round(nearest, calc(var(--type-display-lg-leading, 1.1) * 1em), 0.25rem);
|
|
357
388
|
letter-spacing: var(--type-display-lg-tracking, -0.03em);
|
|
358
389
|
}
|
|
359
390
|
|
|
@@ -361,28 +392,28 @@
|
|
|
361
392
|
font-family: var(--font-display, var(--font-sans));
|
|
362
393
|
font-size: var(--type-heading-1-size, 2.25rem);
|
|
363
394
|
font-weight: var(--type-heading-weight, 600);
|
|
364
|
-
line-height: var(--type-heading-1-leading, 1.15);
|
|
395
|
+
line-height: round(nearest, calc(var(--type-heading-1-leading, 1.15) * 1em), 0.25rem);
|
|
365
396
|
letter-spacing: var(--type-heading-1-tracking, -0.025em);
|
|
366
397
|
}
|
|
367
398
|
@utility text-heading-2 {
|
|
368
399
|
font-family: var(--font-display, var(--font-sans));
|
|
369
400
|
font-size: var(--type-heading-2-size, 1.75rem);
|
|
370
401
|
font-weight: var(--type-heading-weight, 600);
|
|
371
|
-
line-height: var(--type-heading-2-leading, 1.2);
|
|
402
|
+
line-height: round(nearest, calc(var(--type-heading-2-leading, 1.2) * 1em), 0.25rem);
|
|
372
403
|
letter-spacing: var(--type-heading-2-tracking, -0.02em);
|
|
373
404
|
}
|
|
374
405
|
@utility text-heading-3 {
|
|
375
406
|
font-family: var(--font-display, var(--font-sans));
|
|
376
407
|
font-size: var(--type-heading-3-size, 1.375rem);
|
|
377
408
|
font-weight: var(--type-heading-weight, 600);
|
|
378
|
-
line-height: var(--type-heading-3-leading, 1.25);
|
|
409
|
+
line-height: round(nearest, calc(var(--type-heading-3-leading, 1.25) * 1em), 0.25rem);
|
|
379
410
|
letter-spacing: var(--type-heading-3-tracking, -0.015em);
|
|
380
411
|
}
|
|
381
412
|
@utility text-heading-4 {
|
|
382
413
|
font-family: var(--font-display, var(--font-sans));
|
|
383
414
|
font-size: var(--type-heading-4-size, 1.125rem);
|
|
384
415
|
font-weight: var(--type-heading-weight, 600);
|
|
385
|
-
line-height: var(--type-heading-4-leading, 1.3);
|
|
416
|
+
line-height: round(nearest, calc(var(--type-heading-4-leading, 1.3) * 1em), 0.25rem);
|
|
386
417
|
letter-spacing: var(--type-heading-4-tracking, -0.01em);
|
|
387
418
|
}
|
|
388
419
|
|
|
@@ -397,13 +428,13 @@
|
|
|
397
428
|
@utility text-title-lg {
|
|
398
429
|
font-size: var(--type-title-lg-size, 1rem);
|
|
399
430
|
font-weight: var(--type-title-weight, 600);
|
|
400
|
-
line-height: var(--type-title-leading, 1.4);
|
|
431
|
+
line-height: round(nearest, calc(var(--type-title-leading, 1.4) * 1em), 0.25rem);
|
|
401
432
|
letter-spacing: var(--type-title-tracking, -0.01em);
|
|
402
433
|
}
|
|
403
434
|
@utility text-title-sm {
|
|
404
435
|
font-size: var(--type-title-sm-size, 0.875rem);
|
|
405
436
|
font-weight: var(--type-title-weight, 600);
|
|
406
|
-
line-height: var(--type-title-leading, 1.4);
|
|
437
|
+
line-height: round(nearest, calc(var(--type-title-leading, 1.4) * 1em), 0.25rem);
|
|
407
438
|
letter-spacing: var(--type-title-sm-tracking, -0.005em);
|
|
408
439
|
}
|
|
409
440
|
|
|
@@ -422,20 +453,20 @@
|
|
|
422
453
|
@utility text-body-lg {
|
|
423
454
|
font-size: var(--type-body-lg-size, 1.0625rem);
|
|
424
455
|
font-weight: var(--type-body-lg-weight, 400);
|
|
425
|
-
line-height: var(--type-body-lg-leading, 1.6);
|
|
456
|
+
line-height: round(nearest, calc(var(--type-body-lg-leading, 1.6) * 1em), 0.25rem);
|
|
426
457
|
letter-spacing: var(--type-body-lg-tracking, -0.005em);
|
|
427
458
|
text-wrap: pretty;
|
|
428
459
|
}
|
|
429
460
|
@utility text-body-md {
|
|
430
461
|
font-size: var(--type-body-md-size, 0.9375rem);
|
|
431
462
|
font-weight: var(--type-body-md-weight, 400);
|
|
432
|
-
line-height: var(--type-body-md-leading, 1.55);
|
|
463
|
+
line-height: round(nearest, calc(var(--type-body-md-leading, 1.55) * 1em), 0.25rem);
|
|
433
464
|
letter-spacing: var(--type-body-md-tracking, -0.005em);
|
|
434
465
|
}
|
|
435
466
|
@utility text-body-sm {
|
|
436
467
|
font-size: var(--type-body-sm-size, 0.8125rem);
|
|
437
468
|
font-weight: var(--type-body-sm-weight, 400);
|
|
438
|
-
line-height: var(--type-body-sm-leading, 1.5);
|
|
469
|
+
line-height: round(nearest, calc(var(--type-body-sm-leading, 1.5) * 1em), 0.25rem);
|
|
439
470
|
letter-spacing: var(--type-body-sm-tracking, 0);
|
|
440
471
|
}
|
|
441
472
|
/* The dense floor of the body ramp — running text in operator consoles,
|
|
@@ -444,26 +475,104 @@
|
|
|
444
475
|
@utility text-body-xs {
|
|
445
476
|
font-size: var(--type-body-xs-size, 0.75rem);
|
|
446
477
|
font-weight: var(--type-body-xs-weight, 400);
|
|
447
|
-
line-height: var(--type-body-xs-leading, 1.5);
|
|
478
|
+
line-height: round(nearest, calc(var(--type-body-xs-leading, 1.5) * 1em), 0.25rem);
|
|
448
479
|
letter-spacing: var(--type-body-xs-tracking, 0);
|
|
449
480
|
}
|
|
450
481
|
|
|
482
|
+
/* ==========================================================================
|
|
483
|
+
Lists — typography for semantic HTML lists, not components. A list is text
|
|
484
|
+
with structure, so it is styled where the rest of the type is: put the class
|
|
485
|
+
on the native <ul>, <ol> or <dl> and keep the elements' own semantics.
|
|
486
|
+
|
|
487
|
+
- sable-list / sable-list-numbered: body type, a hanging marker in the muted
|
|
488
|
+
ink (the marker is punctuation, not content), and the same rhythm between
|
|
489
|
+
items as between a stacked label and its control.
|
|
490
|
+
- sable-list-dl: label/value pairs on a two-column grid — muted label tier
|
|
491
|
+
for the <dt>, body tier for the <dd>, aligned on the baseline. A long
|
|
492
|
+
unbroken value (an address, a hash, a URL) wraps inside its column rather
|
|
493
|
+
than widening the grid. Colour a status value with a text-* utility on the
|
|
494
|
+
<dd> (text-success, text-destructive…).
|
|
495
|
+
- sable-list-dl-2: two pairs a row once the nearest @container ancestor is
|
|
496
|
+
at least 28rem wide — the room the list actually has, not the viewport, so
|
|
497
|
+
it does not overflow a narrow card on a wide screen.
|
|
498
|
+
Compact density retunes all of them with the rest of the type (see the
|
|
499
|
+
[data-density="compact"] block).
|
|
500
|
+
========================================================================== */
|
|
501
|
+
@utility sable-list {
|
|
502
|
+
list-style: disc;
|
|
503
|
+
padding-inline-start: 1.25em;
|
|
504
|
+
font-size: var(--type-body-md-size, 0.9375rem);
|
|
505
|
+
line-height: round(nearest, calc(var(--type-body-md-leading, 1.55) * 1em), 0.25rem);
|
|
506
|
+
color: var(--foreground);
|
|
507
|
+
& > li + li {
|
|
508
|
+
margin-block-start: --spacing(1.5);
|
|
509
|
+
}
|
|
510
|
+
& > li::marker {
|
|
511
|
+
color: var(--muted-foreground);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
@utility sable-list-numbered {
|
|
515
|
+
list-style: decimal;
|
|
516
|
+
padding-inline-start: 1.5em;
|
|
517
|
+
font-size: var(--type-body-md-size, 0.9375rem);
|
|
518
|
+
line-height: round(nearest, calc(var(--type-body-md-leading, 1.55) * 1em), 0.25rem);
|
|
519
|
+
color: var(--foreground);
|
|
520
|
+
& > li + li {
|
|
521
|
+
margin-block-start: --spacing(1.5);
|
|
522
|
+
}
|
|
523
|
+
& > li::marker {
|
|
524
|
+
color: var(--muted-foreground);
|
|
525
|
+
font-variant-numeric: tabular-nums;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
@utility sable-list-dl {
|
|
529
|
+
display: grid;
|
|
530
|
+
grid-template-columns: max-content minmax(0, 1fr);
|
|
531
|
+
align-items: baseline;
|
|
532
|
+
column-gap: --spacing(6);
|
|
533
|
+
row-gap: --spacing(3);
|
|
534
|
+
/* The values' type and ink live on the list and the <dd>s inherit them, so a
|
|
535
|
+
text-* utility on a <dd> (text-success, text-mono-md) simply wins. The term
|
|
536
|
+
and the wrapping rules sit in :where(), which adds no specificity. */
|
|
537
|
+
font-size: var(--type-body-md-size, 0.9375rem);
|
|
538
|
+
line-height: round(nearest, calc(var(--type-body-md-leading, 1.55) * 1em), 0.25rem);
|
|
539
|
+
letter-spacing: var(--type-body-md-tracking, -0.005em);
|
|
540
|
+
color: var(--foreground);
|
|
541
|
+
& > :where(dt) {
|
|
542
|
+
font-size: var(--type-label-md-size, 0.75rem);
|
|
543
|
+
font-weight: var(--type-label-md-weight, 600);
|
|
544
|
+
line-height: round(nearest, calc(var(--type-label-md-leading, 1.2) * 1em), 0.25rem);
|
|
545
|
+
letter-spacing: var(--type-label-md-tracking, 0);
|
|
546
|
+
color: var(--muted-foreground);
|
|
547
|
+
}
|
|
548
|
+
& > :where(dd) {
|
|
549
|
+
margin: 0;
|
|
550
|
+
min-width: 0;
|
|
551
|
+
overflow-wrap: break-word;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
@utility sable-list-dl-2 {
|
|
555
|
+
@container (min-width: 28rem) {
|
|
556
|
+
grid-template-columns: max-content minmax(0, 1fr) max-content minmax(0, 1fr);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
451
560
|
@utility text-label-lg {
|
|
452
561
|
font-size: var(--type-label-lg-size, 0.875rem);
|
|
453
562
|
font-weight: var(--type-label-lg-weight, 600);
|
|
454
|
-
line-height: var(--type-label-lg-leading, 1.25);
|
|
563
|
+
line-height: round(nearest, calc(var(--type-label-lg-leading, 1.25) * 1em), 0.25rem);
|
|
455
564
|
letter-spacing: var(--type-label-lg-tracking, -0.005em);
|
|
456
565
|
}
|
|
457
566
|
@utility text-label-md {
|
|
458
567
|
font-size: var(--type-label-md-size, 0.75rem);
|
|
459
568
|
font-weight: var(--type-label-md-weight, 600);
|
|
460
|
-
line-height: var(--type-label-md-leading, 1.2);
|
|
569
|
+
line-height: round(nearest, calc(var(--type-label-md-leading, 1.2) * 1em), 0.25rem);
|
|
461
570
|
letter-spacing: var(--type-label-md-tracking, 0);
|
|
462
571
|
}
|
|
463
572
|
@utility text-label-sm {
|
|
464
573
|
font-size: var(--type-label-sm-size, 0.6875rem);
|
|
465
574
|
font-weight: var(--type-label-sm-weight, 600);
|
|
466
|
-
line-height: var(--type-label-sm-leading, 1.2);
|
|
575
|
+
line-height: round(nearest, calc(var(--type-label-sm-leading, 1.2) * 1em), 0.25rem);
|
|
467
576
|
letter-spacing: var(--type-label-sm-tracking, 0);
|
|
468
577
|
}
|
|
469
578
|
/* Sentence case like every other label (UI text is sentence case). The
|
|
@@ -473,14 +582,14 @@
|
|
|
473
582
|
@utility text-label-xs {
|
|
474
583
|
font-size: var(--type-label-xs-size, 0.6875rem);
|
|
475
584
|
font-weight: var(--type-label-xs-weight, 600);
|
|
476
|
-
line-height: var(--type-label-xs-leading, 1.2);
|
|
585
|
+
line-height: round(nearest, calc(var(--type-label-xs-leading, 1.2) * 1em), 0.25rem);
|
|
477
586
|
letter-spacing: var(--type-label-xs-tracking, 0.01em);
|
|
478
587
|
text-transform: var(--type-label-xs-transform, none);
|
|
479
588
|
}
|
|
480
589
|
@utility text-caption {
|
|
481
590
|
font-size: var(--type-caption-size, 0.75rem);
|
|
482
591
|
font-weight: var(--type-caption-weight, 400);
|
|
483
|
-
line-height: var(--type-caption-leading, 1.4);
|
|
592
|
+
line-height: round(nearest, calc(var(--type-caption-leading, 1.4) * 1em), 0.25rem);
|
|
484
593
|
letter-spacing: var(--type-caption-tracking, 0);
|
|
485
594
|
}
|
|
486
595
|
|
|
@@ -491,7 +600,7 @@
|
|
|
491
600
|
@utility text-overline {
|
|
492
601
|
font-size: var(--type-overline-size, 0.75rem);
|
|
493
602
|
font-weight: var(--type-overline-weight, 600);
|
|
494
|
-
line-height: var(--type-overline-leading, 1.2);
|
|
603
|
+
line-height: round(nearest, calc(var(--type-overline-leading, 1.2) * 1em), 0.25rem);
|
|
495
604
|
letter-spacing: var(--type-overline-tracking, 0.08em);
|
|
496
605
|
text-transform: var(--type-overline-transform, uppercase);
|
|
497
606
|
}
|
|
@@ -503,7 +612,7 @@
|
|
|
503
612
|
font-family: var(--font-mono);
|
|
504
613
|
font-size: var(--type-mono-xl-size, 1.75rem);
|
|
505
614
|
font-weight: var(--type-mono-xl-weight, 500);
|
|
506
|
-
line-height: var(--type-mono-xl-leading, 1.15);
|
|
615
|
+
line-height: round(nearest, calc(var(--type-mono-xl-leading, 1.15) * 1em), 0.25rem);
|
|
507
616
|
letter-spacing: var(--type-mono-xl-tracking, -0.01em);
|
|
508
617
|
font-variant-numeric: tabular-nums;
|
|
509
618
|
}
|
|
@@ -511,7 +620,7 @@
|
|
|
511
620
|
font-family: var(--font-mono);
|
|
512
621
|
font-size: var(--type-mono-lg-size, 1.25rem);
|
|
513
622
|
font-weight: var(--type-mono-lg-weight, 500);
|
|
514
|
-
line-height: var(--type-mono-lg-leading, 1.25);
|
|
623
|
+
line-height: round(nearest, calc(var(--type-mono-lg-leading, 1.25) * 1em), 0.25rem);
|
|
515
624
|
letter-spacing: var(--type-mono-lg-tracking, 0);
|
|
516
625
|
font-variant-numeric: tabular-nums;
|
|
517
626
|
}
|
|
@@ -519,7 +628,7 @@
|
|
|
519
628
|
font-family: var(--font-mono);
|
|
520
629
|
font-size: var(--type-mono-md-size, 0.8125rem);
|
|
521
630
|
font-weight: var(--type-mono-md-weight, 400);
|
|
522
|
-
line-height: var(--type-mono-md-leading, 1.5);
|
|
631
|
+
line-height: round(nearest, calc(var(--type-mono-md-leading, 1.5) * 1em), 0.25rem);
|
|
523
632
|
letter-spacing: var(--type-mono-md-tracking, 0);
|
|
524
633
|
font-variant-numeric: tabular-nums;
|
|
525
634
|
}
|
|
@@ -530,7 +639,7 @@
|
|
|
530
639
|
font-family: var(--font-mono);
|
|
531
640
|
font-size: var(--type-mono-caption-size, 0.75rem);
|
|
532
641
|
font-weight: var(--type-mono-caption-weight, 400);
|
|
533
|
-
line-height: var(--type-mono-caption-leading, 1.4);
|
|
642
|
+
line-height: round(nearest, calc(var(--type-mono-caption-leading, 1.4) * 1em), 0.25rem);
|
|
534
643
|
letter-spacing: var(--type-mono-caption-tracking, 0);
|
|
535
644
|
font-variant-numeric: tabular-nums;
|
|
536
645
|
}
|
|
@@ -538,7 +647,7 @@
|
|
|
538
647
|
font-family: var(--font-mono);
|
|
539
648
|
font-size: var(--type-mono-sm-size, 0.6875rem);
|
|
540
649
|
font-weight: var(--type-mono-sm-weight, 500);
|
|
541
|
-
line-height: var(--type-mono-sm-leading, 1.2);
|
|
650
|
+
line-height: round(nearest, calc(var(--type-mono-sm-leading, 1.2) * 1em), 0.25rem);
|
|
542
651
|
letter-spacing: var(--type-mono-sm-tracking, 0.02em);
|
|
543
652
|
font-variant-numeric: tabular-nums;
|
|
544
653
|
}
|
|
@@ -736,13 +845,16 @@
|
|
|
736
845
|
concentrically at every corner setting (Menu, Select, Combobox, ContextMenu). The inset grows with the radius: a rounder popup needs more
|
|
737
846
|
room, or its rows' corners approach half their height and every row turns
|
|
738
847
|
into a pill. The row radius is what is left. At the default ladder (md 12px)
|
|
739
|
-
this is
|
|
740
|
-
|
|
848
|
+
this is a 4px inset and 7px rows: the popup's 1px border is part of the
|
|
849
|
+
distance from the outer curve, so it comes off the radius too (sable-frame
|
|
850
|
+
already subtracts it; this used to be the one formula that did not).
|
|
851
|
+
Utilities rather than :root tokens so the math runs on the element, inside
|
|
852
|
+
whatever preset it sits in. */
|
|
741
853
|
@utility popup-inset {
|
|
742
854
|
padding: max(--spacing(1), calc(var(--radius-md) / 3));
|
|
743
855
|
}
|
|
744
856
|
@utility rounded-popup-item {
|
|
745
|
-
border-radius: max(0px, calc(var(--radius-md) - max(--spacing(1), calc(var(--radius-md) / 3))));
|
|
857
|
+
border-radius: max(0px, calc(var(--radius-md) - max(--spacing(1), calc(var(--radius-md) / 3)) - 1px));
|
|
746
858
|
}
|
|
747
859
|
/* A rule (separator) that runs edge to edge through the popup padding. It
|
|
748
860
|
bleeds by exactly popup-inset, so it reaches both edges at every radius; a
|
|
@@ -771,11 +883,40 @@
|
|
|
771
883
|
border: var(--sable-frame-border-width) solid var(--sable-frame-edge);
|
|
772
884
|
border-radius: var(--sable-frame-radius);
|
|
773
885
|
}
|
|
886
|
+
/* The same geometry and elevation as the Menu / Select / Combobox popups, so a
|
|
887
|
+
list hosted in a frame floats beside a menu as its equal: popup-inset's
|
|
888
|
+
padding (it grows with the radius) and shadow-md, the floating-surface step
|
|
889
|
+
(shadow-lg is for surfaces with a scrim — foundations/surfaces). */
|
|
774
890
|
@utility sable-frame-popover {
|
|
775
891
|
--sable-frame-radius: var(--radius-md);
|
|
776
|
-
--sable-frame-padding: --spacing(1);
|
|
892
|
+
--sable-frame-padding: max(--spacing(1), calc(var(--radius-md) / 3));
|
|
777
893
|
--sable-frame-edge: var(--border-floating);
|
|
778
|
-
box-shadow: var(--shadow-
|
|
894
|
+
box-shadow: var(--shadow-md);
|
|
895
|
+
}
|
|
896
|
+
/* A frame around edge-to-edge tool chrome — panel sections, a tree, a status
|
|
897
|
+
bar — at the theme's own radius. It publishes the geometry its contents need
|
|
898
|
+
to stay concentric with it, the way Card does with --card-inner-radius and
|
|
899
|
+
popups with popup-inset:
|
|
900
|
+
- --panel-field-radius: a compact field's corner. It aims for the theme's small
|
|
901
|
+
radius but no more than a quarter of the field's height (a rounder preset
|
|
902
|
+
would otherwise turn 24px fields into pills), and is then whatever keeps it
|
|
903
|
+
parallel to the frame's curve.
|
|
904
|
+
- --panel-inset: the rows' side padding, frame radius less that field radius,
|
|
905
|
+
never under the 8px a tool row always has. A rounder preset gets more room
|
|
906
|
+
instead of crowding its first label and last field into the corners.
|
|
907
|
+
- --panel-edge: the extra the first and last section take top and bottom, so
|
|
908
|
+
the vertical edge breathes by the same amount.
|
|
909
|
+
Unframed — a square Workspace column — none of these are set, and panels fall
|
|
910
|
+
back to the 8px inset and the field shell's own radius. Custom properties only,
|
|
911
|
+
like every sable-frame-* modifier: a real property would sort this rule ahead of
|
|
912
|
+
.sable-frame and lose to it. Clip with overflow-hidden on the element. */
|
|
913
|
+
@utility sable-frame-tool {
|
|
914
|
+
--sable-frame-radius: var(--radius-lg);
|
|
915
|
+
--sable-frame-padding: 0px;
|
|
916
|
+
--panel-field-target: min(var(--radius-sm), calc(var(--control-xs) / 4));
|
|
917
|
+
--panel-inset: max(--spacing(2), calc(var(--sable-frame-radius) - var(--panel-field-target)));
|
|
918
|
+
--panel-field-radius: max(0px, calc(var(--sable-frame-radius) - var(--panel-inset)));
|
|
919
|
+
--panel-edge: calc(var(--panel-inset) - --spacing(2));
|
|
779
920
|
}
|
|
780
921
|
@utility sable-frame-borderless {
|
|
781
922
|
--sable-frame-border-width: 0px;
|
|
@@ -790,13 +931,17 @@
|
|
|
790
931
|
@utility sable-frame-inner {
|
|
791
932
|
border-radius: var(--sable-frame-inner-radius, var(--radius-sm));
|
|
792
933
|
}
|
|
934
|
+
/* Floored at radius-xs, not zero: an inset at or past the outer radius left a
|
|
935
|
+
1-2px sliver (the docs' composer measured 2px, Toast's close 1.5px) that is
|
|
936
|
+
neither square nor round and reads as a mistake. A square theme's xs is 0,
|
|
937
|
+
so it still goes square. */
|
|
793
938
|
@utility rounded-concentric-* {
|
|
794
939
|
border-radius: max(
|
|
795
|
-
|
|
940
|
+
var(--radius-xs),
|
|
796
941
|
calc(--value(--radius-*, [*]) - --modifier(--spacing-*, [*]))
|
|
797
942
|
);
|
|
798
943
|
border-radius: max(
|
|
799
|
-
|
|
944
|
+
var(--radius-xs),
|
|
800
945
|
calc(--value(--radius-*, [*]) - --spacing(--modifier(number)))
|
|
801
946
|
);
|
|
802
947
|
}
|
|
@@ -1154,6 +1299,17 @@
|
|
|
1154
1299
|
font-weight: var(--type-ui-md-weight, 500);
|
|
1155
1300
|
line-height: var(--type-ui-leading, 16px);
|
|
1156
1301
|
}
|
|
1302
|
+
/* The list utilities carry their own type, so they follow the same tiers:
|
|
1303
|
+
items and values as body-md, terms as label-md. */
|
|
1304
|
+
& :is(.sable-list, .sable-list-numbered, .sable-list-dl) {
|
|
1305
|
+
font-size: min(0.9375rem, var(--type-ui-md-size, 12px));
|
|
1306
|
+
line-height: var(--type-ui-leading, 16px);
|
|
1307
|
+
}
|
|
1308
|
+
& .sable-list-dl > :where(dt) {
|
|
1309
|
+
font-size: min(0.75rem, var(--type-ui-md-size, 12px));
|
|
1310
|
+
font-weight: var(--type-ui-md-weight, 500);
|
|
1311
|
+
line-height: var(--type-ui-leading, 16px);
|
|
1312
|
+
}
|
|
1157
1313
|
& .text-label-sm,
|
|
1158
1314
|
& .text-label-xs {
|
|
1159
1315
|
font-size: min(0.6875rem, var(--type-ui-micro-size, 10px));
|
|
@@ -1340,6 +1496,20 @@
|
|
|
1340
1496
|
background-position: -200% 0;
|
|
1341
1497
|
}
|
|
1342
1498
|
}
|
|
1499
|
+
/* The skeleton sweep. One pass eases in, glides and settles (no constant-speed
|
|
1500
|
+
conveyor), then the band waits off-screen for the last 30% before the next.
|
|
1501
|
+
The resting position — the from/to — is off-screen right, so a frozen
|
|
1502
|
+
animation (reduced motion) leaves a plain block, not a stuck highlight. */
|
|
1503
|
+
@keyframes sable-sweep {
|
|
1504
|
+
0% {
|
|
1505
|
+
background-position: 100% 0;
|
|
1506
|
+
animation-timing-function: cubic-bezier(0.55, 0, 0.2, 1);
|
|
1507
|
+
}
|
|
1508
|
+
70%,
|
|
1509
|
+
100% {
|
|
1510
|
+
background-position: 0% 0;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1343
1513
|
@keyframes sable-pulse-soft {
|
|
1344
1514
|
0%,
|
|
1345
1515
|
100% {
|
|
@@ -1681,16 +1851,44 @@
|
|
|
1681
1851
|
animation: sable-pulse-soft calc(1600ms * var(--motion-scale))
|
|
1682
1852
|
var(--motion-ease-standard) infinite;
|
|
1683
1853
|
}
|
|
1854
|
+
/*
|
|
1855
|
+
* The skeleton sweep: ONE band of light passing through a whole loading layout,
|
|
1856
|
+
* not a separate flash per block.
|
|
1857
|
+
*
|
|
1858
|
+
* - `background-attachment: fixed` lays the gradient against the viewport, so
|
|
1859
|
+
* every skeleton on screen is a window onto the same band. A text line, an
|
|
1860
|
+
* avatar and a card below it light up in sequence, a single wave, instead of
|
|
1861
|
+
* each box sweeping at its own speed (a 40px line and a 600px card used to
|
|
1862
|
+
* race each other). iOS Safari ignores fixed backgrounds and falls back to a
|
|
1863
|
+
* per-box sweep, which is the old behaviour, not a broken one.
|
|
1864
|
+
* - The image is two viewports plus 600px wide with the band at its centre, so
|
|
1865
|
+
* from 100% to 0% the band travels from 300px off the left edge to 300px off
|
|
1866
|
+
* the right, and its width (360px, feathered over five stops) holds at any
|
|
1867
|
+
* screen size rather than scaling with the box.
|
|
1868
|
+
* - The band is light catching the block, not a shadow crossing it: the skeleton's
|
|
1869
|
+
* own muted fill, a few lightness steps up, so it is a sheen in light AND dark
|
|
1870
|
+
* mode with no per-theme value (mixing in the foreground darkened it in light).
|
|
1871
|
+
* - The base position is the resting one, off-screen: under --motion-scale 0
|
|
1872
|
+
* the skeleton is a calm block.
|
|
1873
|
+
*
|
|
1874
|
+
* Background-position is painted, not composited, unlike most recipes here. It
|
|
1875
|
+
* buys the coherent wave, which a per-element transform cannot, and skeletons
|
|
1876
|
+
* are small and short-lived.
|
|
1877
|
+
*/
|
|
1684
1878
|
@utility motion-shimmer {
|
|
1685
1879
|
background-image: linear-gradient(
|
|
1686
1880
|
100deg,
|
|
1687
|
-
transparent
|
|
1688
|
-
|
|
1689
|
-
|
|
1881
|
+
transparent calc(50% - 180px),
|
|
1882
|
+
oklch(from var(--muted) calc(l + 0.02) c h / 0.6) calc(50% - 90px),
|
|
1883
|
+
oklch(from var(--muted) calc(l + 0.055) c h / 0.9) 50%,
|
|
1884
|
+
oklch(from var(--muted) calc(l + 0.02) c h / 0.6) calc(50% + 90px),
|
|
1885
|
+
transparent calc(50% + 180px)
|
|
1690
1886
|
);
|
|
1691
|
-
background-size: 200% 100%;
|
|
1887
|
+
background-size: calc(200% + 600px) 100%;
|
|
1692
1888
|
background-repeat: no-repeat;
|
|
1693
|
-
|
|
1889
|
+
background-attachment: fixed;
|
|
1890
|
+
background-position: 0% 0;
|
|
1891
|
+
animation: sable-sweep calc(2400ms * var(--motion-scale)) infinite;
|
|
1694
1892
|
}
|
|
1695
1893
|
/*
|
|
1696
1894
|
* The same sweep, but through the glyphs instead of behind them — for live
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { T as ThemeManifest } from './_contract-
|
|
3
|
+
import { T as ThemeManifest } from './_contract-o3tUc8Ig.js';
|
|
4
4
|
|
|
5
5
|
declare const SABLE_THEME_ATTRIBUTE: "data-sable-theme";
|
|
6
6
|
declare const DEFAULT_THEME_ID: string;
|
|
@@ -100,6 +100,8 @@
|
|
|
100
100
|
--border: oklch(92% 0 0);
|
|
101
101
|
--border-strong: oklch(85% 0 0);
|
|
102
102
|
--input: oklch(92% 0 0);
|
|
103
|
+
/* The resting edge of a control whose outline IS the control (checkbox, radio, an off switch track). Held to WCAG 1.4.11 3:1 on every surface, unlike the quieter --input field outline. */
|
|
104
|
+
--control-border: oklch(62.3% 0 0);
|
|
103
105
|
--ring: #000000;
|
|
104
106
|
--primary: #000000;
|
|
105
107
|
--primary-foreground: #ffffff;
|
|
@@ -177,6 +179,7 @@
|
|
|
177
179
|
--border: oklch(29% 0 0);
|
|
178
180
|
--border-strong: oklch(36% 0 0);
|
|
179
181
|
--input: oklch(29% 0 0);
|
|
182
|
+
--control-border: oklch(54.9% 0 0);
|
|
180
183
|
--ring: #ffffff;
|
|
181
184
|
--primary: #ffffff;
|
|
182
185
|
--primary-foreground: #000000;
|
|
@@ -15,6 +15,19 @@
|
|
|
15
15
|
|
|
16
16
|
:root,
|
|
17
17
|
[data-sable-theme="base"] {
|
|
18
|
+
/* Chart series colours — a categorical palette validated for colour-blind
|
|
19
|
+
separation (adjacent pairs), a normal-vision floor, a lightness band and a
|
|
20
|
+
chroma floor against this theme's surfaces. Charts take them in order
|
|
21
|
+
(series 1 → --chart-1). Global defaults: every theme inherits them, and a
|
|
22
|
+
theme or preset may override the set — re-validate it if it does. */
|
|
23
|
+
--chart-1: oklch(57.53% 0.1626 255.53); /* #2a78d6 */
|
|
24
|
+
--chart-2: oklch(67.08% 0.1750 40.64); /* #eb6834 */
|
|
25
|
+
--chart-3: oklch(66.90% 0.1408 162.11); /* #1baf7a */
|
|
26
|
+
--chart-4: oklch(76.44% 0.1612 75.12); /* #eda100 */
|
|
27
|
+
--chart-5: oklch(71.63% 0.1412 357.39); /* #e87ba4 */
|
|
28
|
+
--chart-6: oklch(52.85% 0.1798 142.50); /* #008300 */
|
|
29
|
+
--chart-7: oklch(52.71% 0.1968 283.44); /* #6250d6 */
|
|
30
|
+
--chart-8: oklch(62.26% 0.1909 24.91); /* #e34948 */
|
|
18
31
|
/* Font stacks (theme-internal; host app provides the actual font files) */
|
|
19
32
|
--font-sans: "Figtree", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
20
33
|
--font-mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Courier New", monospace;
|
|
@@ -31,8 +44,10 @@
|
|
|
31
44
|
/* Elevation, light. Layered: a tight contact shadow plus one or two soft drops
|
|
32
45
|
whose offsets roughly double per step. A single 5% blur read mushy and
|
|
33
46
|
barely separated a menu from the page (DESIGN.md → Elevation). */
|
|
34
|
-
--theme-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.
|
|
35
|
-
|
|
47
|
+
--theme-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
48
|
+
/* A visible step above sm: sm and this differed by one 5% layer, which no
|
|
49
|
+
one could tell apart. */
|
|
50
|
+
--theme-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05), 0 3px 8px -2px rgb(0 0 0 / 0.08);
|
|
36
51
|
--theme-shadow-md: 0 1px 2px 0 rgb(0 0 0 / 0.04), 0 4px 8px -2px rgb(0 0 0 / 0.06), 0 12px 24px -6px rgb(0 0 0 / 0.07);
|
|
37
52
|
--theme-shadow-lg: 0 2px 4px 0 rgb(0 0 0 / 0.04), 0 8px 16px -4px rgb(0 0 0 / 0.07), 0 24px 48px -12px rgb(0 0 0 / 0.11);
|
|
38
53
|
--theme-shadow-xl: 0 2px 4px 0 rgb(0 0 0 / 0.04), 0 12px 24px -6px rgb(0 0 0 / 0.08), 0 32px 64px -16px rgb(0 0 0 / 0.13);
|
|
@@ -239,6 +254,8 @@
|
|
|
239
254
|
step on the same neutral ramp as --border. */
|
|
240
255
|
--border-strong: var(--zinc-300);
|
|
241
256
|
--input: var(--zinc-200);
|
|
257
|
+
/* The resting edge of a control whose outline IS the control (checkbox, radio, an off switch track). Held to WCAG 1.4.11 3:1 on every surface, unlike the quieter --input field outline. */
|
|
258
|
+
--control-border: var(--zinc-500);
|
|
242
259
|
--ring: var(--zinc-500);
|
|
243
260
|
|
|
244
261
|
/* Tones — light (all clear WCAG AA on white) */
|
|
@@ -370,12 +387,22 @@
|
|
|
370
387
|
/* A preset-scoped subtree inside a dark page follows the page into dark mode;
|
|
371
388
|
add `.light` to that subtree to pin it light. */
|
|
372
389
|
.dark [data-sable-theme="base"]:not(.light) {
|
|
390
|
+
/* The same eight hues, stepped for the dark band (L 0.48–0.67, >= 3:1 on
|
|
391
|
+
the dark surfaces) and validated as a set — not a lightness flip. */
|
|
392
|
+
--chart-1: oklch(62.21% 0.1612 255.05); /* #3987e5 */
|
|
393
|
+
--chart-2: oklch(62.21% 0.1726 40.11); /* #d95926 */
|
|
394
|
+
--chart-3: oklch(62.12% 0.1283 163.11); /* #199e70 */
|
|
395
|
+
--chart-4: oklch(66.99% 0.1425 73.23); /* #c98500 */
|
|
396
|
+
--chart-5: oklch(62.24% 0.1712 0.84); /* #d55181 */
|
|
397
|
+
--chart-6: oklch(52.85% 0.1798 142.50); /* #008300 */
|
|
398
|
+
--chart-7: oklch(66.96% 0.1452 286.83); /* #9085e9 */
|
|
399
|
+
--chart-8: oklch(66.93% 0.1586 22.31); /* #e66767 */
|
|
373
400
|
/* Elevation, dark. A drop barely registers on near-black, so depth is the
|
|
374
401
|
surface step (popover above card) plus a faint top-edge highlight that
|
|
375
402
|
catches "light" on anything floating. Deeper drops than light mode, since
|
|
376
403
|
black on near-black needs more alpha to read at all. */
|
|
377
404
|
--theme-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
|
|
378
|
-
--theme-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.3), 0
|
|
405
|
+
--theme-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.3), 0 4px 10px -2px rgb(0 0 0 / 0.4);
|
|
379
406
|
--theme-shadow-md: inset 0 1px 0 0 rgb(255 255 255 / 0.04), 0 1px 2px 0 rgb(0 0 0 / 0.3), 0 8px 20px -6px rgb(0 0 0 / 0.45);
|
|
380
407
|
--theme-shadow-lg: inset 0 1px 0 0 rgb(255 255 255 / 0.05), 0 2px 4px 0 rgb(0 0 0 / 0.3), 0 20px 40px -12px rgb(0 0 0 / 0.55);
|
|
381
408
|
--theme-shadow-xl: inset 0 1px 0 0 rgb(255 255 255 / 0.05), 0 2px 4px 0 rgb(0 0 0 / 0.3), 0 28px 56px -16px rgb(0 0 0 / 0.6);
|
|
@@ -409,6 +436,7 @@
|
|
|
409
436
|
--border: oklch(from var(--zinc-700) l c h / 0.4);
|
|
410
437
|
--border-strong: oklch(from var(--zinc-500) l c h / 0.55);
|
|
411
438
|
--input: oklch(from var(--zinc-700) l c h / 0.4);
|
|
439
|
+
--control-border: var(--zinc-500);
|
|
412
440
|
--ring: var(--zinc-500);
|
|
413
441
|
|
|
414
442
|
/* Tones — dark-tuned (boosted chroma for vibrancy on the dark canvas) */
|
|
@@ -438,6 +466,8 @@
|
|
|
438
466
|
--sidebar-primary-foreground: var(--zinc-950);
|
|
439
467
|
--sidebar-accent: var(--zinc-800);
|
|
440
468
|
--sidebar-accent-foreground: var(--zinc-50);
|
|
441
|
-
|
|
469
|
+
/* zinc-800, not zinc-900: on the zinc-950 sidebar zinc-900 measured 1.16:1,
|
|
470
|
+
fainter than the page's own border. */
|
|
471
|
+
--sidebar-border: var(--zinc-800);
|
|
442
472
|
--sidebar-ring: var(--zinc-500);
|
|
443
473
|
}
|