@mcp-b/design-tokens 0.20.5 → 0.22.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-b/design-tokens",
3
- "version": "0.20.5",
3
+ "version": "0.22.0",
4
4
  "description": "Shared design tokens for MCP-B React applications.",
5
5
  "homepage": "https://mcp-b-design-system-storybook.alexmnahas.workers.dev",
6
6
  "bugs": {
@@ -24,6 +24,8 @@
24
24
  "./index.css": "./src/index.css",
25
25
  "./borders": "./src/borders.css",
26
26
  "./borders.css": "./src/borders.css",
27
+ "./elevation": "./src/elevation.css",
28
+ "./elevation.css": "./src/elevation.css",
27
29
  "./focus": "./src/focus.css",
28
30
  "./focus.css": "./src/focus.css",
29
31
  "./motion": "./src/motion.css",
package/src/borders.css CHANGED
@@ -1,15 +1,58 @@
1
1
  /*
2
2
  * Border Tokens
3
+ *
4
+ * Radii are a base scale multiplied by --sigvelo-radius-scale, so a product,
5
+ * a theme, or one subtree can go rounder or squarer by setting a single
6
+ * variable instead of overriding every radius. Set it on :root for a global
7
+ * change, or on any element to rescale that subtree.
8
+ *
9
+ * --sigvelo-radius-full and --sigvelo-radius-circle stay unscaled: a pill and
10
+ * a circle are shapes, not sizes.
3
11
  */
4
12
 
5
13
  :root {
6
14
  --sigvelo-border-style: solid;
7
15
  --sigvelo-border-width: 1px;
8
- --sigvelo-radius-xs: 0.1875rem; /* 3px */
9
- --sigvelo-radius-sm: 0.25rem; /* 4px */
10
- --sigvelo-radius-md: 0.5rem; /* 8px */
11
- --sigvelo-radius-lg: 0.75rem; /* 12px */
12
- --sigvelo-radius-xl: 1rem; /* 16px */
16
+
17
+ /* Hairline rules and rings. Sub-pixel on 1x, crisp on 2x. */
18
+ --sigvelo-border-width-hairline: 0.5px;
19
+
20
+ --sigvelo-radius-scale: 1;
21
+
22
+ --sigvelo-radius-xs-base: 0.1875rem; /* 3px */
23
+ --sigvelo-radius-sm-base: 0.25rem; /* 4px */
24
+ --sigvelo-radius-md-base: 0.5rem; /* 8px */
25
+ --sigvelo-radius-lg-base: 0.75rem; /* 12px */
26
+ --sigvelo-radius-xl-base: 1rem; /* 16px */
27
+ --sigvelo-radius-2xl-base: 1.25rem; /* 20px */
28
+ --sigvelo-radius-3xl-base: 1.5rem; /* 24px */
29
+
30
+ --sigvelo-radius-xs: calc(var(--sigvelo-radius-xs-base) * var(--sigvelo-radius-scale));
31
+ --sigvelo-radius-sm: calc(var(--sigvelo-radius-sm-base) * var(--sigvelo-radius-scale));
32
+ --sigvelo-radius-md: calc(var(--sigvelo-radius-md-base) * var(--sigvelo-radius-scale));
33
+ --sigvelo-radius-lg: calc(var(--sigvelo-radius-lg-base) * var(--sigvelo-radius-scale));
34
+ --sigvelo-radius-xl: calc(var(--sigvelo-radius-xl-base) * var(--sigvelo-radius-scale));
35
+ --sigvelo-radius-2xl: calc(var(--sigvelo-radius-2xl-base) * var(--sigvelo-radius-scale));
36
+ --sigvelo-radius-3xl: calc(var(--sigvelo-radius-3xl-base) * var(--sigvelo-radius-scale));
37
+
13
38
  --sigvelo-radius-full: 9999px;
14
39
  --sigvelo-radius-circle: 50%;
40
+
41
+ /* Applied by the shared surface, row, control, and button recipes. Only
42
+ rounded rectangles opt in — pills and circles keep a true arc. */
43
+ --sigvelo-corner-shape: round;
44
+ }
45
+
46
+ /*
47
+ * Squircle corners where the browser can draw them. A superellipse cuts less
48
+ * material out of the corner than a circular arc, so the same radius reads
49
+ * tighter; the scale opens up to compensate and the two changes ship together.
50
+ * Browsers without corner-shape keep round corners at the unscaled radii and
51
+ * look exactly as they did before.
52
+ */
53
+ @supports (corner-shape: superellipse(1.5)) {
54
+ :root {
55
+ --sigvelo-corner-shape: superellipse(1.5);
56
+ --sigvelo-radius-scale: 1.25;
57
+ }
15
58
  }
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Increased contrast.
3
+ *
4
+ * A request for more contrast is about the faint end of each ramp — quiet text
5
+ * and hairline edges — not about the whole palette. Brand hues, surfaces, and
6
+ * every on-color pairing stay exactly as authored, so no component opts in and
7
+ * no contrast pair that already passed gets re-tuned.
8
+ *
9
+ * Every declaration here reads a token this block does not itself reassign.
10
+ * Custom properties resolve to the winning value, so a chain of promotions
11
+ * inside one block (subtle -> muted -> base) would collapse all three onto the
12
+ * base and flatten the hierarchy instead of raising it. Borders deliberately do
13
+ * collapse — a divider that cannot be seen has no hierarchy to preserve — while
14
+ * text keeps three distinguishable steps, measured against the canvas.
15
+ *
16
+ * Remapping the resolved aliases rather than the -light/-dark inputs means one
17
+ * block covers system dark mode, both data-theme choices, and the light-dark()
18
+ * path together.
19
+ */
20
+ @media (prefers-contrast: more) {
21
+ :root {
22
+ /* Secondary text is the first thing to go. Muted reaches full foreground;
23
+ the two steps below it stay apart by mixing toward the canvas rather
24
+ than by referencing each other. */
25
+ --sigvelo-color-text-muted: var(--sigvelo-color-text);
26
+ --sigvelo-color-text-subtle: color-mix(
27
+ in oklab,
28
+ var(--sigvelo-color-text),
29
+ var(--sigvelo-color-canvas) 20%
30
+ );
31
+ --sigvelo-color-text-faint: color-mix(
32
+ in oklab,
33
+ var(--sigvelo-color-text),
34
+ var(--sigvelo-color-canvas) 35%
35
+ );
36
+
37
+ /* Hairlines at the subtle and muted steps round to nothing at this
38
+ contrast level, so both take the solid border for their hue. */
39
+ --sigvelo-color-neutral-border-subtle: var(--sigvelo-color-neutral-border);
40
+ --sigvelo-color-neutral-border-muted: var(--sigvelo-color-neutral-border);
41
+ --sigvelo-color-primary-border-subtle: var(--sigvelo-color-primary-border);
42
+ --sigvelo-color-primary-border-muted: var(--sigvelo-color-primary-border);
43
+ --sigvelo-color-success-border-subtle: var(--sigvelo-color-success-border);
44
+ --sigvelo-color-success-border-muted: var(--sigvelo-color-success-border);
45
+ --sigvelo-color-warning-border-subtle: var(--sigvelo-color-warning-border);
46
+ --sigvelo-color-warning-border-muted: var(--sigvelo-color-warning-border);
47
+ --sigvelo-color-danger-border-subtle: var(--sigvelo-color-danger-border);
48
+ --sigvelo-color-danger-border-muted: var(--sigvelo-color-danger-border);
49
+ }
50
+ }
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Elevation Materials
3
+ *
4
+ * The geometry half of elevation: the composed filters that turn a
5
+ * translucent surface into frosted chrome. The color half — the layered
6
+ * shadows themselves — is theme-specific and lives in semantic-colors.css as
7
+ * the --sigvelo-elevation-* family.
8
+ *
9
+ * Elevation here is a stack, not a single shadow: a hairline ring that reads
10
+ * as an edge at any zoom, then a tight contact shadow, then a wide ambient
11
+ * one. That layering is what keeps a raised surface legible on both a white
12
+ * canvas and a near-black one.
13
+ */
14
+
15
+ :root {
16
+ /*
17
+ * Frosted chrome over scrolling content.
18
+ *
19
+ * Held to a single 1px radius, which separates modal chrome without making
20
+ * the page behind it look frosted. A backdrop filter repaints the whole
21
+ * area behind the element every frame, so a wider radius or a second pass
22
+ * such as saturate() on a full-viewport scrim costs frames on every dialog
23
+ * open — measurably, not theoretically: at blur(24px) saturate(180%) the
24
+ * Storybook suite dropped roughly a third of its runs to timing failures in
25
+ * stories that had nothing to do with dialogs.
26
+ */
27
+ --sigvelo-glass-filter: blur(1px);
28
+ }
package/src/focus.css CHANGED
@@ -5,7 +5,6 @@
5
5
  :root {
6
6
  --sigvelo-focus-width: 3px;
7
7
  --sigvelo-focus-offset: 1px;
8
- --sigvelo-backdrop-filter: blur(6px);
9
8
  /* Focus ring used in forced-colors mode, where the box-shadow ring is dropped. */
10
9
  --sigvelo-focus-ring-forced: 2px solid Highlight;
11
10
  }
package/src/index.css CHANGED
@@ -5,5 +5,8 @@
5
5
  @import "./focus.css";
6
6
  @import "./spacing.css";
7
7
  @import "./motion.css";
8
+ @import "./layers.css";
9
+ @import "./elevation.css";
8
10
  @import "./semantic-colors.css";
9
11
  @import "./themes.css";
12
+ @import "./contrast.css";
package/src/layers.css ADDED
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Stacking layers.
3
+ *
4
+ * Only the bands that components have to agree on live here. Ordering *inside*
5
+ * a component — a gradient behind its own text, a badge over its own avatar —
6
+ * stays a plain 0/1/2 in that component's stylesheet, because naming a token
7
+ * for it would imply a cross-component contract that does not exist.
8
+ *
9
+ * The gaps between bands are deliberate. A component that needs to sit just
10
+ * above its band says so with calc() against the band it belongs to, which
11
+ * keeps the relationship legible instead of encoding it as a bare 23.
12
+ */
13
+
14
+ :root {
15
+ /* Sticky application chrome: app bars, pinned rows, and hover cards that
16
+ float within a scroll region but below anything modal. */
17
+ --sigvelo-z-chrome: 20;
18
+
19
+ /* Drag affordances — resize handles, splitters — which have to stay grabbable
20
+ above the chrome they resize. */
21
+ --sigvelo-z-panel: 25;
22
+
23
+ /* Base UI popups: dialog, alert dialog, popover, menu, tooltip, preview card.
24
+ One band for all of them, because the library already resolves their order
25
+ among themselves by mount order. */
26
+ --sigvelo-z-overlay: 50;
27
+
28
+ /* Toasts outrank overlays: a toast reporting the result of a dialog action
29
+ has to be readable while that dialog is still closing. */
30
+ --sigvelo-z-toast: 100;
31
+
32
+ /*
33
+ * Overlays drawn on top of a host page this design system does not control —
34
+ * a browser control surface injected into someone else's document. Max int is
35
+ * not a layer, it is a concession that we cannot see the other stylesheet.
36
+ * Nothing that renders inside our own tree may use it.
37
+ *
38
+ * Recorded here so the value has one documented home, but such a surface
39
+ * cannot actually reference it: it mounts in a closed shadow root where this
40
+ * sheet does not exist, so var() would resolve to nothing and z-index would
41
+ * silently fall back to auto. Those stylesheets inline the number instead.
42
+ */
43
+ --sigvelo-z-host-overlay: 2147483647;
44
+ }
package/src/motion.css CHANGED
@@ -7,6 +7,24 @@
7
7
  --sigvelo-ease-standard: cubic-bezier(0.2, 0, 0, 1);
8
8
  --sigvelo-ease-emphasized: cubic-bezier(0.16, 1, 0.3, 1);
9
9
  --sigvelo-ease-accelerate: cubic-bezier(0.4, 0, 1, 1);
10
+ /* Nearly all of the distance in the first third, then a long settle. Reads
11
+ as responsive on entrances that also move a long way. */
12
+ --sigvelo-ease-snappy: cubic-bezier(0.23, 1, 0.32, 1);
13
+ /* Press and release. A damped spring settling in three shrinking bounces —
14
+ a cubic-bezier can only overshoot once, which reads as a wobble rather
15
+ than a physical button. Keep it on transform; on color it just looks slow. */
16
+ --sigvelo-ease-press: linear(
17
+ 0,
18
+ 0.3505,
19
+ 0.7432,
20
+ 0.9336,
21
+ 0.9951,
22
+ 1.0062,
23
+ 1.0045,
24
+ 1.0019,
25
+ 1.0005,
26
+ 1
27
+ );
10
28
 
11
29
  /* Semantic motion roles keep component families on one quiet rhythm. */
12
30
  --sigvelo-motion-duration-interaction: var(--sigvelo-duration-fast);
@@ -16,11 +34,25 @@
16
34
  /* Looping "busy/streaming" text shimmer sweep. Not reduced with the
17
35
  interaction scale — reduced motion turns the shimmer off entirely. */
18
36
  --sigvelo-motion-duration-shimmer: 2400ms;
37
+ /* Breathing rate of a live-state indicator. Slower than a heartbeat on
38
+ purpose: fast enough to read as ongoing, slow enough to sit at the edge of
39
+ vision for minutes without demanding attention. Like the shimmer, reduced
40
+ motion switches it off rather than shortening it. */
41
+ --sigvelo-motion-duration-pulse: 1400ms;
42
+ /* One full turn of a spinner. A loop rate, not a transition duration: the
43
+ transition scale tops out at 360ms, which as a rotation period is a blur —
44
+ which is why every surface that wanted a spinner used to write its own
45
+ literal instead of the shared class. */
46
+ --sigvelo-motion-duration-spin: 900ms;
19
47
 
20
48
  --sigvelo-motion-ease-enter: var(--sigvelo-ease-emphasized);
21
49
  --sigvelo-motion-ease-exit: var(--sigvelo-ease-accelerate);
22
50
  --sigvelo-motion-ease-change: var(--sigvelo-ease-standard);
23
51
 
52
+ /* Delay between neighbours in a revealed list, so a group of rows arrives
53
+ as a sequence instead of a single block. Keep the total under ~200ms. */
54
+ --sigvelo-motion-stagger-step: 35ms;
55
+
24
56
  --sigvelo-motion-distance-xs: 1px;
25
57
  --sigvelo-motion-distance-sm: 4px;
26
58
  --sigvelo-motion-distance-md: 8px;
@@ -6,159 +6,142 @@
6
6
  */
7
7
 
8
8
  :root {
9
- --sigvelo-color-canvas-light: white;
10
- --sigvelo-color-canvas-dark: var(--sigvelo-color-neutral-950);
11
- --sigvelo-color-surface-light: white;
12
- --sigvelo-color-surface-dark: color-mix(in oklab, var(--sigvelo-color-neutral-950), white 2.5%);
13
- --sigvelo-color-text-light: var(--sigvelo-color-neutral-900);
14
- --sigvelo-color-text-dark: var(--sigvelo-color-neutral-200);
15
- --sigvelo-color-text-muted-light: var(--sigvelo-color-neutral-700);
16
- --sigvelo-color-text-muted-dark: var(--sigvelo-color-neutral-500);
9
+ --sigvelo-color-canvas-light: #fff;
10
+ --sigvelo-color-canvas-dark: #212121;
11
+ /* The quiet window stage visible around bounded application surfaces. It is
12
+ not a control fill: canvas remains the neutral base for embedded fields. */
13
+ --sigvelo-color-surface-under-light: #f9f9f9;
14
+ --sigvelo-color-surface-under-dark: #000;
15
+ --sigvelo-color-surface-light: #fff;
16
+ --sigvelo-color-surface-dark: #181818;
17
+ --sigvelo-color-text-light: #0d0d0d;
18
+ --sigvelo-color-text-dark: #ececec;
19
+ --sigvelo-color-text-muted-light: #5d5d5d;
20
+ --sigvelo-color-text-muted-dark: #b4b4b4;
21
+ /* Two quieter rungs below muted, measured against the owning surface rather
22
+ than picked off the legacy neutral ramp.
23
+ subtle: de-emphasized label text, still holds ~4.5:1 against its surface.
24
+ faint: icons and resting affordances only — it clears the 3:1 needed for
25
+ a graphic, not the 4.5:1 needed for body copy. */
26
+ --sigvelo-color-text-subtle-light: #737373;
27
+ --sigvelo-color-text-subtle-dark: #a6a6a6;
28
+ --sigvelo-color-text-faint-light: #8f8f8f;
29
+ --sigvelo-color-text-faint-dark: #8f8f8f;
30
+ /* Surfaces that sit above the page. In light mode a raised card is the
31
+ same white as the surface and is separated by shadow alone; in dark mode
32
+ shadow does almost nothing, so the card lifts by getting lighter. */
33
+ --sigvelo-color-surface-raised-light: #fff;
34
+ --sigvelo-color-surface-raised-dark: #282828;
35
+ --sigvelo-color-surface-sunken-light: #f9f9f9;
36
+ --sigvelo-color-surface-sunken-dark: #171717;
37
+ /* Translucent counterpart of surface-raised, for panels that blur what is
38
+ scrolling underneath. Pair with --sigvelo-glass-filter, and fall back to
39
+ surface-raised where backdrop-filter is unavailable. */
40
+ --sigvelo-color-surface-glass-light: color-mix(
41
+ in oklab,
42
+ var(--sigvelo-color-surface-raised-light),
43
+ transparent 20%
44
+ );
45
+ --sigvelo-color-surface-glass-dark: color-mix(
46
+ in oklab,
47
+ var(--sigvelo-color-surface-raised-dark),
48
+ transparent 20%
49
+ );
17
50
  --sigvelo-color-focus-light: var(--sigvelo-color-primary-bg-light);
18
51
  --sigvelo-color-focus-dark: var(--sigvelo-color-primary-bg-dark);
19
52
  --sigvelo-focus-ring-light: var(--sigvelo-border-style) var(--sigvelo-focus-width)
20
53
  var(--sigvelo-color-focus-light);
21
54
  --sigvelo-focus-ring-dark: var(--sigvelo-border-style) var(--sigvelo-focus-width)
22
55
  var(--sigvelo-color-focus-dark);
23
- --sigvelo-color-backdrop-light: rgb(0 0 0 / 0.5);
24
- --sigvelo-color-backdrop-dark: rgb(0 0 0 / 0.5);
56
+ /* Paired with --sigvelo-glass-filter on dialog scrims. A pale tint and 1px
57
+ blur recede the page without turning it into a dark or frosted sheet. */
58
+ --sigvelo-color-backdrop-light: rgb(238 238 238 / 50%);
59
+ --sigvelo-color-backdrop-dark: rgb(0 0 0 / 50%);
25
60
  --sigvelo-color-selection-bg-light: var(--sigvelo-color-primary-300);
26
61
  --sigvelo-color-selection-bg-dark: var(--sigvelo-color-primary-700);
27
62
  --sigvelo-color-selection-text-light: var(--sigvelo-color-text-light);
28
63
  --sigvelo-color-selection-text-dark: var(--sigvelo-color-text-dark);
29
- --sigvelo-color-shadow-light: black;
30
- --sigvelo-color-shadow-dark: black;
31
- --sigvelo-shadow-xs-light: 0 0.0625rem 0.0625rem
32
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-light) 4%);
33
- --sigvelo-shadow-xs-dark: 0 1px 2px
34
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-dark) 8%);
35
- --sigvelo-shadow-sm-light: 0 0.125rem 0.1875rem
36
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-light) 8%);
37
- --sigvelo-shadow-sm-dark: 0 2px 4px
38
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-dark) 12%);
39
- --sigvelo-shadow-md-light: 0 0.1875rem 0.375rem
40
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-light) 10%);
41
- --sigvelo-shadow-md-dark: 0 4px 8px
42
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-dark) 16%);
43
- --sigvelo-shadow-lg-light: 0 0.375rem 0.75rem
44
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-light) 12%);
45
- --sigvelo-shadow-lg-dark: 0 8px 16px
46
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-dark) 20%);
47
- --sigvelo-shadow-xl-light: 0 0.5rem 1rem
48
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-light) 14%);
49
- --sigvelo-shadow-xl-dark: 0 12px 20px
50
- color-mix(in oklab, transparent, var(--sigvelo-color-shadow-dark) 24%);
51
- --sigvelo-inset-shadow-xs-light: inset 0 0.125rem 0.125rem -0.125rem
52
- color-mix(in oklab, black, transparent 94%);
53
- --sigvelo-inset-shadow-xs-dark: var(--sigvelo-inset-shadow-xs-light);
54
- --sigvelo-inset-shadow-sm-light: inset 0 0.25rem 0.25rem -0.25rem
55
- color-mix(in oklab, black, transparent 90%);
56
- --sigvelo-inset-shadow-sm-dark: var(--sigvelo-inset-shadow-sm-light);
57
- --sigvelo-inset-shadow-md-light: inset 0 0.5rem 0.5rem -0.5rem
58
- color-mix(in oklab, black, transparent 88%);
59
- --sigvelo-inset-shadow-md-dark: var(--sigvelo-inset-shadow-md-light);
60
- --sigvelo-inset-shadow-lg-light: inset 0 1rem 1rem -1rem
61
- color-mix(in oklab, black, transparent 85%);
62
- --sigvelo-inset-shadow-lg-dark: var(--sigvelo-inset-shadow-lg-light);
63
- --sigvelo-inset-shadow-xl-light: inset 0 1.5rem 1.5rem -1.5rem
64
- color-mix(in oklab, black, transparent 82%);
65
- --sigvelo-inset-shadow-xl-dark: var(--sigvelo-inset-shadow-xl-light);
66
- --sigvelo-color-primary-bg-subtle-light: var(--sigvelo-color-primary-100);
67
- --sigvelo-color-primary-bg-subtle-dark: color-mix(
68
- in oklab,
69
- var(--sigvelo-color-primary-900),
70
- white 1%
71
- );
72
- --sigvelo-color-primary-bg-muted-light: var(--sigvelo-color-primary-200);
73
- --sigvelo-color-primary-bg-muted-dark: var(--sigvelo-color-primary-800);
74
- --sigvelo-color-primary-bg-light: color-mix(
75
- in oklab,
76
- var(--sigvelo-color-primary-600),
77
- black 2.5%
78
- );
79
- --sigvelo-color-primary-bg-dark: color-mix(
80
- in oklab,
81
- var(--sigvelo-color-primary-600),
82
- black 7.5%
83
- );
84
- --sigvelo-color-primary-bg-strong-light: var(--sigvelo-color-primary-800);
85
- --sigvelo-color-primary-bg-strong-dark: var(--sigvelo-color-primary-200);
86
- --sigvelo-color-primary-bg-stronger-light: var(--sigvelo-color-primary-900);
87
- --sigvelo-color-primary-bg-stronger-dark: var(--sigvelo-color-primary-100);
88
- --sigvelo-color-primary-text-on-subtle-light: var(--sigvelo-color-primary-900);
89
- --sigvelo-color-primary-text-on-subtle-dark: var(--sigvelo-color-primary-100);
90
- --sigvelo-color-primary-text-on-bg-light: white;
91
- --sigvelo-color-primary-text-on-bg-dark: white;
92
- --sigvelo-color-primary-text-on-strong-light: white;
93
- --sigvelo-color-primary-text-on-strong-dark: black;
94
- --sigvelo-color-primary-text-light: color-mix(
95
- in oklab,
96
- var(--sigvelo-color-primary-600),
97
- black 12.5%
98
- );
99
- --sigvelo-color-primary-text-dark: var(--sigvelo-color-primary-500);
100
- --sigvelo-color-primary-border-subtle-light: color-mix(
101
- in oklab,
102
- var(--sigvelo-color-primary-100),
103
- black 3%
104
- );
105
- --sigvelo-color-primary-border-subtle-dark: color-mix(
106
- in oklab,
107
- var(--sigvelo-color-primary-900),
108
- white 7.5%
109
- );
110
- --sigvelo-color-primary-border-muted-light: var(--sigvelo-color-primary-300);
111
- --sigvelo-color-primary-border-muted-dark: var(--sigvelo-color-primary-800);
112
- --sigvelo-color-primary-border-light: var(--sigvelo-color-primary-500);
113
- --sigvelo-color-primary-border-dark: var(--sigvelo-color-primary-600);
114
- --sigvelo-color-neutral-bg-subtle-light: var(--sigvelo-color-neutral-100);
115
- --sigvelo-color-neutral-bg-subtle-dark: color-mix(
116
- in oklab,
117
- var(--sigvelo-color-neutral-900),
118
- white 1%
119
- );
120
- --sigvelo-color-neutral-bg-muted-light: var(--sigvelo-color-neutral-200);
121
- --sigvelo-color-neutral-bg-muted-dark: var(--sigvelo-color-neutral-800);
122
- --sigvelo-color-neutral-bg-light: color-mix(
123
- in oklab,
124
- var(--sigvelo-color-neutral-600),
125
- black 2.5%
126
- );
127
- --sigvelo-color-neutral-bg-dark: color-mix(
128
- in oklab,
129
- var(--sigvelo-color-neutral-600),
130
- black 7.5%
131
- );
132
- --sigvelo-color-neutral-bg-strong-light: var(--sigvelo-color-neutral-800);
133
- --sigvelo-color-neutral-bg-strong-dark: var(--sigvelo-color-neutral-200);
134
- --sigvelo-color-neutral-bg-stronger-light: var(--sigvelo-color-neutral-900);
135
- --sigvelo-color-neutral-bg-stronger-dark: var(--sigvelo-color-neutral-100);
136
- --sigvelo-color-neutral-text-on-subtle-light: var(--sigvelo-color-neutral-900);
137
- --sigvelo-color-neutral-text-on-subtle-dark: var(--sigvelo-color-neutral-100);
138
- --sigvelo-color-neutral-text-on-bg-light: white;
139
- --sigvelo-color-neutral-text-on-bg-dark: white;
140
- --sigvelo-color-neutral-text-on-strong-light: white;
141
- --sigvelo-color-neutral-text-on-strong-dark: black;
142
- --sigvelo-color-neutral-text-light: color-mix(
143
- in oklab,
144
- var(--sigvelo-color-neutral-600),
145
- black 12.5%
146
- );
147
- --sigvelo-color-neutral-text-dark: var(--sigvelo-color-neutral-500);
148
- --sigvelo-color-neutral-border-subtle-light: color-mix(
149
- in oklab,
150
- var(--sigvelo-color-neutral-200),
151
- transparent 40%
152
- );
153
- --sigvelo-color-neutral-border-subtle-dark: color-mix(
154
- in oklab,
155
- var(--sigvelo-color-neutral-900),
156
- white 4%
157
- );
158
- --sigvelo-color-neutral-border-muted-light: var(--sigvelo-color-neutral-300);
159
- --sigvelo-color-neutral-border-muted-dark: var(--sigvelo-color-neutral-800);
160
- --sigvelo-color-neutral-border-light: var(--sigvelo-color-neutral-500);
161
- --sigvelo-color-neutral-border-dark: var(--sigvelo-color-neutral-600);
64
+ /* One color for both themes. What differs between light and dark is how much
65
+ of it each stack mixes in, and that lives in the stacks below. */
66
+ --sigvelo-color-shadow: black;
67
+
68
+ /* Elevation stacks. Each begins with the hairline ring below — a sub-pixel
69
+ edge that survives zoom and keeps a shadowed surface from dissolving into
70
+ the canvas when the shadow itself is nearly invisible. */
71
+ --sigvelo-elevation-hairline-light: 0 0 0 var(--sigvelo-border-width-hairline)
72
+ color-mix(in oklab, transparent, var(--sigvelo-color-shadow) 5%);
73
+ --sigvelo-elevation-hairline-dark: 0 0 0 var(--sigvelo-border-width-hairline)
74
+ color-mix(in oklab, transparent, white 10%);
75
+ /* raised: rows, cards, anything one step off the page. A broad, low-alpha
76
+ shadow separates the surface without drawing a dark line beneath it. */
77
+ --sigvelo-elevation-raised-light:
78
+ var(--sigvelo-elevation-hairline-light),
79
+ 0 0 15px color-mix(in oklab, transparent, var(--sigvelo-color-shadow) 3%);
80
+ --sigvelo-elevation-raised-dark:
81
+ var(--sigvelo-elevation-hairline-dark),
82
+ 0 0 15px color-mix(in oklab, transparent, var(--sigvelo-color-shadow) 3%);
83
+ /* floating: composers and toolbars that hover over scrolling content. The
84
+ wide spread-free ambient layer is what reads as "off the page" rather
85
+ than "outlined". */
86
+ --sigvelo-elevation-floating-light:
87
+ var(--sigvelo-elevation-hairline-light),
88
+ 0 3px 7.5px color-mix(in oklab, transparent, var(--sigvelo-color-shadow) 4%),
89
+ 0 0 20px color-mix(in oklab, transparent, var(--sigvelo-color-shadow) 5%);
90
+ --sigvelo-elevation-floating-dark:
91
+ var(--sigvelo-elevation-hairline-dark),
92
+ 0 3px 7.5px color-mix(in oklab, transparent, var(--sigvelo-color-shadow) 32%),
93
+ 0 0 20px color-mix(in oklab, transparent, var(--sigvelo-color-shadow) 28%);
94
+ /* overlay: popovers, menus, dialogs — detached from the page entirely. */
95
+ --sigvelo-elevation-overlay-light: 0 0 1px rgb(0 0 0 / 62%), 0 8px 12px rgb(0 0 0 / 8%);
96
+ --sigvelo-elevation-overlay-dark: 0 0 1px rgb(255 255 255 / 14%), 0 8px 16px rgb(0 0 0 / 35%);
97
+ --sigvelo-color-primary-bg-subtle-light: #f9f9f9;
98
+ --sigvelo-color-primary-bg-subtle-dark: #2f2f2f;
99
+ --sigvelo-color-primary-bg-muted-light: #ececec;
100
+ --sigvelo-color-primary-bg-muted-dark: #424242;
101
+ --sigvelo-color-primary-bg-light: #0d0d0d;
102
+ --sigvelo-color-primary-bg-dark: #fff;
103
+ --sigvelo-color-primary-bg-strong-light: #000;
104
+ --sigvelo-color-primary-bg-strong-dark: #fff;
105
+ --sigvelo-color-primary-bg-stronger-light: #000;
106
+ --sigvelo-color-primary-bg-stronger-dark: #fff;
107
+ --sigvelo-color-primary-text-on-subtle-light: #0d0d0d;
108
+ --sigvelo-color-primary-text-on-subtle-dark: #ececec;
109
+ --sigvelo-color-primary-text-on-bg-light: #fff;
110
+ --sigvelo-color-primary-text-on-bg-dark: #0d0d0d;
111
+ --sigvelo-color-primary-text-on-strong-light: #fff;
112
+ --sigvelo-color-primary-text-on-strong-dark: #0d0d0d;
113
+ --sigvelo-color-primary-text-light: #0d0d0d;
114
+ --sigvelo-color-primary-text-dark: #ececec;
115
+ --sigvelo-color-primary-border-subtle-light: rgb(0 0 0 / 5%);
116
+ --sigvelo-color-primary-border-subtle-dark: rgb(255 255 255 / 10%);
117
+ --sigvelo-color-primary-border-muted-light: rgb(0 0 0 / 10%);
118
+ --sigvelo-color-primary-border-muted-dark: rgb(255 255 255 / 15%);
119
+ --sigvelo-color-primary-border-light: #0d0d0d;
120
+ --sigvelo-color-primary-border-dark: #ececec;
121
+ --sigvelo-color-neutral-bg-subtle-light: rgb(0 0 0 / 5%);
122
+ --sigvelo-color-neutral-bg-subtle-dark: rgb(255 255 255 / 8%);
123
+ --sigvelo-color-neutral-bg-muted-light: #ececec;
124
+ --sigvelo-color-neutral-bg-muted-dark: #424242;
125
+ --sigvelo-color-neutral-bg-light: #5d5d5d;
126
+ --sigvelo-color-neutral-bg-dark: #b4b4b4;
127
+ --sigvelo-color-neutral-bg-strong-light: #333;
128
+ --sigvelo-color-neutral-bg-strong-dark: #ececec;
129
+ --sigvelo-color-neutral-bg-stronger-light: #0d0d0d;
130
+ --sigvelo-color-neutral-bg-stronger-dark: #fff;
131
+ --sigvelo-color-neutral-text-on-subtle-light: #0d0d0d;
132
+ --sigvelo-color-neutral-text-on-subtle-dark: #ececec;
133
+ --sigvelo-color-neutral-text-on-bg-light: #fff;
134
+ --sigvelo-color-neutral-text-on-bg-dark: #0d0d0d;
135
+ --sigvelo-color-neutral-text-on-strong-light: #fff;
136
+ --sigvelo-color-neutral-text-on-strong-dark: #0d0d0d;
137
+ --sigvelo-color-neutral-text-light: #5d5d5d;
138
+ --sigvelo-color-neutral-text-dark: #b4b4b4;
139
+ --sigvelo-color-neutral-border-subtle-light: rgb(0 0 0 / 5%);
140
+ --sigvelo-color-neutral-border-subtle-dark: rgb(255 255 255 / 10%);
141
+ --sigvelo-color-neutral-border-muted-light: rgb(0 0 0 / 10%);
142
+ --sigvelo-color-neutral-border-muted-dark: rgb(255 255 255 / 15%);
143
+ --sigvelo-color-neutral-border-light: #5d5d5d;
144
+ --sigvelo-color-neutral-border-dark: #b4b4b4;
162
145
  --sigvelo-color-success-bg-subtle-light: var(--sigvelo-color-success-100);
163
146
  --sigvelo-color-success-bg-subtle-dark: color-mix(
164
147
  in oklab,
package/src/spacing.css CHANGED
@@ -1,65 +1,94 @@
1
1
  /*
2
2
  * Spacing & Form Control Tokens
3
+ *
4
+ * One 4px grid, named by quarter-rem step: --sigvelo-spacing-3 is 3 × 0.25rem
5
+ * = 12px. The scale is dense through the range components actually lay out in
6
+ * and thins out above 48px, where sizing becomes layout rather than spacing.
7
+ *
8
+ * Every control height and gap in this file resolves to a step on that grid.
9
+ * If a value you need is not on the scale, that is the signal to reconsider the
10
+ * value rather than to write the number: audit:css-recipes rejects off-grid
11
+ * lengths in component spacing.
3
12
  */
4
13
 
5
14
  :root {
6
15
  /* Spacing scale */
7
- --sigvelo-spacing-0-5: 0.125rem;
8
- --sigvelo-spacing-1: 0.25rem;
9
- --sigvelo-spacing-1-5: 0.375rem;
10
- --sigvelo-spacing-2: 0.5rem;
11
- --sigvelo-spacing-2-5: 0.625rem;
12
- --sigvelo-spacing-3: 0.75rem;
13
- --sigvelo-spacing-4: 1rem;
14
- --sigvelo-spacing-5: 1.25rem;
15
- --sigvelo-spacing-6: 1.5rem;
16
- --sigvelo-spacing-8: 2rem;
17
- --sigvelo-spacing-12: 3rem;
16
+ --sigvelo-spacing-0-5: 0.125rem; /* 2px */
17
+ --sigvelo-spacing-1: 0.25rem; /* 4px */
18
+ --sigvelo-spacing-1-5: 0.375rem; /* 6px */
19
+ --sigvelo-spacing-2: 0.5rem; /* 8px */
20
+ --sigvelo-spacing-2-5: 0.625rem; /* 10px */
21
+ --sigvelo-spacing-3: 0.75rem; /* 12px */
22
+ --sigvelo-spacing-3-5: 0.875rem; /* 14px */
23
+ --sigvelo-spacing-4: 1rem; /* 16px */
24
+ --sigvelo-spacing-5: 1.25rem; /* 20px */
25
+ --sigvelo-spacing-6: 1.5rem; /* 24px */
26
+ --sigvelo-spacing-7: 1.75rem; /* 28px */
27
+ --sigvelo-spacing-8: 2rem; /* 32px */
28
+ --sigvelo-spacing-9: 2.25rem; /* 36px */
29
+ --sigvelo-spacing-10: 2.5rem; /* 40px */
30
+ --sigvelo-spacing-11: 2.75rem; /* 44px */
31
+ --sigvelo-spacing-12: 3rem; /* 48px */
32
+ --sigvelo-spacing-14: 3.5rem; /* 56px */
33
+ --sigvelo-spacing-16: 4rem; /* 64px */
34
+ --sigvelo-spacing-20: 5rem; /* 80px */
35
+ --sigvelo-spacing-24: 6rem; /* 96px */
18
36
 
19
- --sigvelo-spacing-content: 1.75rem;
20
-
21
- /* Form control heights per size */
22
- --sigvelo-control-height-xs: 1.75rem;
23
- --sigvelo-control-height-sm: 2rem;
24
- --sigvelo-control-height-md: 2.25rem;
25
- --sigvelo-control-height-lg: 2.5rem;
26
- --sigvelo-control-height-xl: 2.75rem;
37
+ /* Form control heights per size. Expressed on the spacing scale so a panel,
38
+ a gap, or a reserved gutter can line up with a control by name. */
39
+ --sigvelo-control-height-xs: var(--sigvelo-spacing-7); /* 28px */
40
+ --sigvelo-control-height-sm: var(--sigvelo-spacing-8); /* 32px */
41
+ --sigvelo-control-height-md: var(--sigvelo-spacing-9); /* 36px */
42
+ --sigvelo-control-height-lg: var(--sigvelo-spacing-10); /* 40px */
43
+ --sigvelo-control-height-xl: var(--sigvelo-spacing-11); /* 44px */
27
44
 
28
45
  /* Form control font sizes per size */
29
46
  --sigvelo-control-text-xs: 0.75rem;
30
47
  --sigvelo-control-text-sm: 0.8125rem;
31
48
  --sigvelo-control-text-md: 0.875rem;
32
- --sigvelo-control-text-lg: 1rem;
33
- --sigvelo-control-text-xl: 1.125rem;
49
+ --sigvelo-control-text-lg: 0.875rem;
50
+ --sigvelo-control-text-xl: 0.875rem;
51
+
52
+ /* The leading that belongs to each of those sizes, from the type ramp's
53
+ whole-pixel partners. A ratio applied to a size that is itself a variable
54
+ lands on fractions — 13px at 1.25 is 16.25px — and a stack of rows then
55
+ drifts off the 4px grid a quarter pixel at a time. Every one of these fits
56
+ inside the matching control height with room to spare, so a control keeps
57
+ its box and gains a predictable baseline. */
58
+ --sigvelo-control-line-height-xs: var(--sigvelo-text-xs-leading); /* 16px */
59
+ --sigvelo-control-line-height-sm: var(--sigvelo-text-compact-leading); /* 18px */
60
+ --sigvelo-control-line-height-md: var(--sigvelo-text-sm-leading); /* 20px */
61
+ --sigvelo-control-line-height-lg: var(--sigvelo-text-sm-leading); /* 20px */
62
+ --sigvelo-control-line-height-xl: var(--sigvelo-text-sm-leading); /* 20px */
34
63
 
35
64
  /* Canonical control geometry derived from the public size scale. */
36
65
  --sigvelo-control-padding-inline-xs: var(--sigvelo-spacing-2);
37
66
  --sigvelo-control-padding-inline-sm: var(--sigvelo-spacing-2-5);
38
67
  --sigvelo-control-padding-inline-md: var(--sigvelo-spacing-3);
39
68
  --sigvelo-control-padding-inline-lg: var(--sigvelo-spacing-4);
40
- --sigvelo-control-padding-inline-xl: var(--sigvelo-spacing-5);
41
- --sigvelo-control-icon-size-xs: 0.75rem;
42
- --sigvelo-control-icon-size-sm: 0.875rem;
43
- --sigvelo-control-icon-size-md: 1rem;
44
- --sigvelo-control-icon-size-lg: 1.125rem;
45
- --sigvelo-control-icon-size-xl: 1.25rem;
69
+ --sigvelo-control-padding-inline-xl: var(--sigvelo-spacing-4);
70
+
71
+ /* Icons ride the type ramp rather than a scale of their own: a glyph beside
72
+ a label should be the size of the label, not a nearby round number. */
73
+ --sigvelo-control-icon-size-xs: var(--sigvelo-text-xs); /* 12px */
74
+ --sigvelo-control-icon-size-sm: var(--sigvelo-text-sm); /* 14px */
75
+ --sigvelo-control-icon-size-md: var(--sigvelo-text-base); /* 16px */
76
+ --sigvelo-control-icon-size-lg: var(--sigvelo-text-lg); /* 18px */
77
+ --sigvelo-control-icon-size-xl: var(--sigvelo-text-xl); /* 20px */
46
78
 
47
79
  /* Compact application density. Product chrome and shared recipes resolve
48
80
  through these aliases so density can be tuned in one place. */
49
81
  --sigvelo-density-compact-control-height: var(--sigvelo-control-height-sm);
50
82
  --sigvelo-density-compact-control-padding-inline: var(--sigvelo-control-padding-inline-sm);
51
83
  --sigvelo-density-compact-control-font-size: var(--sigvelo-control-text-sm);
84
+ --sigvelo-density-compact-control-line-height: var(--sigvelo-control-line-height-sm);
52
85
  --sigvelo-density-compact-control-icon-size: var(--sigvelo-control-icon-size-sm);
53
86
  --sigvelo-density-compact-control-gap: var(--sigvelo-spacing-1-5);
54
87
 
55
88
  /* Form control misc */
56
- --sigvelo-control-required-content: "*";
57
89
  --sigvelo-control-placeholder-color: color-mix(
58
90
  in oklab,
59
91
  var(--sigvelo-color-text-muted),
60
92
  transparent 25%
61
93
  );
62
-
63
- /* Button */
64
- --sigvelo-button-active-offset: 1.5px;
65
94
  }
package/src/themes.css CHANGED
@@ -8,25 +8,24 @@
8
8
  :root {
9
9
  color-scheme: light dark;
10
10
  --sigvelo-color-canvas: var(--sigvelo-color-canvas-light);
11
+ --sigvelo-color-surface-under: var(--sigvelo-color-surface-under-light);
11
12
  --sigvelo-color-surface: var(--sigvelo-color-surface-light);
13
+ --sigvelo-color-surface-raised: var(--sigvelo-color-surface-raised-light);
14
+ --sigvelo-color-surface-sunken: var(--sigvelo-color-surface-sunken-light);
15
+ --sigvelo-color-surface-glass: var(--sigvelo-color-surface-glass-light);
12
16
  --sigvelo-color-text: var(--sigvelo-color-text-light);
13
17
  --sigvelo-color-text-muted: var(--sigvelo-color-text-muted-light);
18
+ --sigvelo-color-text-subtle: var(--sigvelo-color-text-subtle-light);
19
+ --sigvelo-color-text-faint: var(--sigvelo-color-text-faint-light);
14
20
  --sigvelo-color-focus: var(--sigvelo-color-focus-light);
15
21
  --sigvelo-focus-ring: var(--sigvelo-focus-ring-light);
16
22
  --sigvelo-color-backdrop: var(--sigvelo-color-backdrop-light);
17
23
  --sigvelo-color-selection-bg: var(--sigvelo-color-selection-bg-light);
18
24
  --sigvelo-color-selection-text: var(--sigvelo-color-selection-text-light);
19
- --sigvelo-color-shadow: var(--sigvelo-color-shadow-light);
20
- --sigvelo-shadow-xs: var(--sigvelo-shadow-xs-light);
21
- --sigvelo-shadow-sm: var(--sigvelo-shadow-sm-light);
22
- --sigvelo-shadow-md: var(--sigvelo-shadow-md-light);
23
- --sigvelo-shadow-lg: var(--sigvelo-shadow-lg-light);
24
- --sigvelo-shadow-xl: var(--sigvelo-shadow-xl-light);
25
- --sigvelo-inset-shadow-xs: var(--sigvelo-inset-shadow-xs-light);
26
- --sigvelo-inset-shadow-sm: var(--sigvelo-inset-shadow-sm-light);
27
- --sigvelo-inset-shadow-md: var(--sigvelo-inset-shadow-md-light);
28
- --sigvelo-inset-shadow-lg: var(--sigvelo-inset-shadow-lg-light);
29
- --sigvelo-inset-shadow-xl: var(--sigvelo-inset-shadow-xl-light);
25
+ --sigvelo-elevation-hairline: var(--sigvelo-elevation-hairline-light);
26
+ --sigvelo-elevation-raised: var(--sigvelo-elevation-raised-light);
27
+ --sigvelo-elevation-floating: var(--sigvelo-elevation-floating-light);
28
+ --sigvelo-elevation-overlay: var(--sigvelo-elevation-overlay-light);
30
29
  --sigvelo-color-primary-bg-subtle: var(--sigvelo-color-primary-bg-subtle-light);
31
30
  --sigvelo-color-primary-bg-muted: var(--sigvelo-color-primary-bg-muted-light);
32
31
  --sigvelo-color-primary-bg: var(--sigvelo-color-primary-bg-light);
@@ -94,25 +93,24 @@
94
93
  @media (prefers-color-scheme: dark) {
95
94
  :root {
96
95
  --sigvelo-color-canvas: var(--sigvelo-color-canvas-dark);
96
+ --sigvelo-color-surface-under: var(--sigvelo-color-surface-under-dark);
97
97
  --sigvelo-color-surface: var(--sigvelo-color-surface-dark);
98
+ --sigvelo-color-surface-raised: var(--sigvelo-color-surface-raised-dark);
99
+ --sigvelo-color-surface-sunken: var(--sigvelo-color-surface-sunken-dark);
100
+ --sigvelo-color-surface-glass: var(--sigvelo-color-surface-glass-dark);
98
101
  --sigvelo-color-text: var(--sigvelo-color-text-dark);
99
102
  --sigvelo-color-text-muted: var(--sigvelo-color-text-muted-dark);
103
+ --sigvelo-color-text-subtle: var(--sigvelo-color-text-subtle-dark);
104
+ --sigvelo-color-text-faint: var(--sigvelo-color-text-faint-dark);
100
105
  --sigvelo-color-focus: var(--sigvelo-color-focus-dark);
101
106
  --sigvelo-focus-ring: var(--sigvelo-focus-ring-dark);
102
107
  --sigvelo-color-backdrop: var(--sigvelo-color-backdrop-dark);
103
108
  --sigvelo-color-selection-bg: var(--sigvelo-color-selection-bg-dark);
104
109
  --sigvelo-color-selection-text: var(--sigvelo-color-selection-text-dark);
105
- --sigvelo-color-shadow: var(--sigvelo-color-shadow-dark);
106
- --sigvelo-shadow-xs: var(--sigvelo-shadow-xs-dark);
107
- --sigvelo-shadow-sm: var(--sigvelo-shadow-sm-dark);
108
- --sigvelo-shadow-md: var(--sigvelo-shadow-md-dark);
109
- --sigvelo-shadow-lg: var(--sigvelo-shadow-lg-dark);
110
- --sigvelo-shadow-xl: var(--sigvelo-shadow-xl-dark);
111
- --sigvelo-inset-shadow-xs: var(--sigvelo-inset-shadow-xs-dark);
112
- --sigvelo-inset-shadow-sm: var(--sigvelo-inset-shadow-sm-dark);
113
- --sigvelo-inset-shadow-md: var(--sigvelo-inset-shadow-md-dark);
114
- --sigvelo-inset-shadow-lg: var(--sigvelo-inset-shadow-lg-dark);
115
- --sigvelo-inset-shadow-xl: var(--sigvelo-inset-shadow-xl-dark);
110
+ --sigvelo-elevation-hairline: var(--sigvelo-elevation-hairline-dark);
111
+ --sigvelo-elevation-raised: var(--sigvelo-elevation-raised-dark);
112
+ --sigvelo-elevation-floating: var(--sigvelo-elevation-floating-dark);
113
+ --sigvelo-elevation-overlay: var(--sigvelo-elevation-overlay-dark);
116
114
  --sigvelo-color-primary-bg-subtle: var(--sigvelo-color-primary-bg-subtle-dark);
117
115
  --sigvelo-color-primary-bg-muted: var(--sigvelo-color-primary-bg-muted-dark);
118
116
  --sigvelo-color-primary-bg: var(--sigvelo-color-primary-bg-dark);
@@ -179,25 +177,24 @@
179
177
  [data-theme="light"] {
180
178
  color-scheme: light;
181
179
  --sigvelo-color-canvas: var(--sigvelo-color-canvas-light);
180
+ --sigvelo-color-surface-under: var(--sigvelo-color-surface-under-light);
182
181
  --sigvelo-color-surface: var(--sigvelo-color-surface-light);
182
+ --sigvelo-color-surface-raised: var(--sigvelo-color-surface-raised-light);
183
+ --sigvelo-color-surface-sunken: var(--sigvelo-color-surface-sunken-light);
184
+ --sigvelo-color-surface-glass: var(--sigvelo-color-surface-glass-light);
183
185
  --sigvelo-color-text: var(--sigvelo-color-text-light);
184
186
  --sigvelo-color-text-muted: var(--sigvelo-color-text-muted-light);
187
+ --sigvelo-color-text-subtle: var(--sigvelo-color-text-subtle-light);
188
+ --sigvelo-color-text-faint: var(--sigvelo-color-text-faint-light);
185
189
  --sigvelo-color-focus: var(--sigvelo-color-focus-light);
186
190
  --sigvelo-focus-ring: var(--sigvelo-focus-ring-light);
187
191
  --sigvelo-color-backdrop: var(--sigvelo-color-backdrop-light);
188
192
  --sigvelo-color-selection-bg: var(--sigvelo-color-selection-bg-light);
189
193
  --sigvelo-color-selection-text: var(--sigvelo-color-selection-text-light);
190
- --sigvelo-color-shadow: var(--sigvelo-color-shadow-light);
191
- --sigvelo-shadow-xs: var(--sigvelo-shadow-xs-light);
192
- --sigvelo-shadow-sm: var(--sigvelo-shadow-sm-light);
193
- --sigvelo-shadow-md: var(--sigvelo-shadow-md-light);
194
- --sigvelo-shadow-lg: var(--sigvelo-shadow-lg-light);
195
- --sigvelo-shadow-xl: var(--sigvelo-shadow-xl-light);
196
- --sigvelo-inset-shadow-xs: var(--sigvelo-inset-shadow-xs-light);
197
- --sigvelo-inset-shadow-sm: var(--sigvelo-inset-shadow-sm-light);
198
- --sigvelo-inset-shadow-md: var(--sigvelo-inset-shadow-md-light);
199
- --sigvelo-inset-shadow-lg: var(--sigvelo-inset-shadow-lg-light);
200
- --sigvelo-inset-shadow-xl: var(--sigvelo-inset-shadow-xl-light);
194
+ --sigvelo-elevation-hairline: var(--sigvelo-elevation-hairline-light);
195
+ --sigvelo-elevation-raised: var(--sigvelo-elevation-raised-light);
196
+ --sigvelo-elevation-floating: var(--sigvelo-elevation-floating-light);
197
+ --sigvelo-elevation-overlay: var(--sigvelo-elevation-overlay-light);
201
198
  --sigvelo-color-primary-bg-subtle: var(--sigvelo-color-primary-bg-subtle-light);
202
199
  --sigvelo-color-primary-bg-muted: var(--sigvelo-color-primary-bg-muted-light);
203
200
  --sigvelo-color-primary-bg: var(--sigvelo-color-primary-bg-light);
@@ -264,25 +261,24 @@
264
261
  [data-theme="dark"] {
265
262
  color-scheme: dark;
266
263
  --sigvelo-color-canvas: var(--sigvelo-color-canvas-dark);
264
+ --sigvelo-color-surface-under: var(--sigvelo-color-surface-under-dark);
267
265
  --sigvelo-color-surface: var(--sigvelo-color-surface-dark);
266
+ --sigvelo-color-surface-raised: var(--sigvelo-color-surface-raised-dark);
267
+ --sigvelo-color-surface-sunken: var(--sigvelo-color-surface-sunken-dark);
268
+ --sigvelo-color-surface-glass: var(--sigvelo-color-surface-glass-dark);
268
269
  --sigvelo-color-text: var(--sigvelo-color-text-dark);
269
270
  --sigvelo-color-text-muted: var(--sigvelo-color-text-muted-dark);
271
+ --sigvelo-color-text-subtle: var(--sigvelo-color-text-subtle-dark);
272
+ --sigvelo-color-text-faint: var(--sigvelo-color-text-faint-dark);
270
273
  --sigvelo-color-focus: var(--sigvelo-color-focus-dark);
271
274
  --sigvelo-focus-ring: var(--sigvelo-focus-ring-dark);
272
275
  --sigvelo-color-backdrop: var(--sigvelo-color-backdrop-dark);
273
276
  --sigvelo-color-selection-bg: var(--sigvelo-color-selection-bg-dark);
274
277
  --sigvelo-color-selection-text: var(--sigvelo-color-selection-text-dark);
275
- --sigvelo-color-shadow: var(--sigvelo-color-shadow-dark);
276
- --sigvelo-shadow-xs: var(--sigvelo-shadow-xs-dark);
277
- --sigvelo-shadow-sm: var(--sigvelo-shadow-sm-dark);
278
- --sigvelo-shadow-md: var(--sigvelo-shadow-md-dark);
279
- --sigvelo-shadow-lg: var(--sigvelo-shadow-lg-dark);
280
- --sigvelo-shadow-xl: var(--sigvelo-shadow-xl-dark);
281
- --sigvelo-inset-shadow-xs: var(--sigvelo-inset-shadow-xs-dark);
282
- --sigvelo-inset-shadow-sm: var(--sigvelo-inset-shadow-sm-dark);
283
- --sigvelo-inset-shadow-md: var(--sigvelo-inset-shadow-md-dark);
284
- --sigvelo-inset-shadow-lg: var(--sigvelo-inset-shadow-lg-dark);
285
- --sigvelo-inset-shadow-xl: var(--sigvelo-inset-shadow-xl-dark);
278
+ --sigvelo-elevation-hairline: var(--sigvelo-elevation-hairline-dark);
279
+ --sigvelo-elevation-raised: var(--sigvelo-elevation-raised-dark);
280
+ --sigvelo-elevation-floating: var(--sigvelo-elevation-floating-dark);
281
+ --sigvelo-elevation-overlay: var(--sigvelo-elevation-overlay-dark);
286
282
  --sigvelo-color-primary-bg-subtle: var(--sigvelo-color-primary-bg-subtle-dark);
287
283
  --sigvelo-color-primary-bg-muted: var(--sigvelo-color-primary-bg-muted-dark);
288
284
  --sigvelo-color-primary-bg: var(--sigvelo-color-primary-bg-dark);
@@ -355,10 +351,26 @@
355
351
  var(--sigvelo-color-canvas-light),
356
352
  var(--sigvelo-color-canvas-dark)
357
353
  );
354
+ --sigvelo-color-surface-under: light-dark(
355
+ var(--sigvelo-color-surface-under-light),
356
+ var(--sigvelo-color-surface-under-dark)
357
+ );
358
358
  --sigvelo-color-surface: light-dark(
359
359
  var(--sigvelo-color-surface-light),
360
360
  var(--sigvelo-color-surface-dark)
361
361
  );
362
+ --sigvelo-color-surface-raised: light-dark(
363
+ var(--sigvelo-color-surface-raised-light),
364
+ var(--sigvelo-color-surface-raised-dark)
365
+ );
366
+ --sigvelo-color-surface-sunken: light-dark(
367
+ var(--sigvelo-color-surface-sunken-light),
368
+ var(--sigvelo-color-surface-sunken-dark)
369
+ );
370
+ --sigvelo-color-surface-glass: light-dark(
371
+ var(--sigvelo-color-surface-glass-light),
372
+ var(--sigvelo-color-surface-glass-dark)
373
+ );
362
374
  --sigvelo-color-text: light-dark(
363
375
  var(--sigvelo-color-text-light),
364
376
  var(--sigvelo-color-text-dark)
@@ -367,6 +379,14 @@
367
379
  var(--sigvelo-color-text-muted-light),
368
380
  var(--sigvelo-color-text-muted-dark)
369
381
  );
382
+ --sigvelo-color-text-subtle: light-dark(
383
+ var(--sigvelo-color-text-subtle-light),
384
+ var(--sigvelo-color-text-subtle-dark)
385
+ );
386
+ --sigvelo-color-text-faint: light-dark(
387
+ var(--sigvelo-color-text-faint-light),
388
+ var(--sigvelo-color-text-faint-dark)
389
+ );
370
390
  --sigvelo-color-focus: light-dark(
371
391
  var(--sigvelo-color-focus-light),
372
392
  var(--sigvelo-color-focus-dark)
@@ -383,10 +403,6 @@
383
403
  var(--sigvelo-color-selection-text-light),
384
404
  var(--sigvelo-color-selection-text-dark)
385
405
  );
386
- --sigvelo-color-shadow: light-dark(
387
- var(--sigvelo-color-shadow-light),
388
- var(--sigvelo-color-shadow-dark)
389
- );
390
406
  --sigvelo-color-primary-bg-subtle: light-dark(
391
407
  var(--sigvelo-color-primary-bg-subtle-light),
392
408
  var(--sigvelo-color-primary-bg-subtle-dark)
@@ -3,12 +3,30 @@
3
3
  */
4
4
 
5
5
  :root {
6
- --sigvelo-font-sans: system-ui, sans-serif;
6
+ --sigvelo-font-sans:
7
+ -apple-system-body, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica,
8
+ Arial, sans-serif;
7
9
  --sigvelo-font-heading: var(--sigvelo-font-sans);
8
10
  --sigvelo-font-mono:
9
11
  SFMono-Regular, Consolas, Menlo, Monaco, "liberation mono", "Courier New", monospace;
10
12
  --sigvelo-text-root: 16px;
11
13
 
14
+ /*
15
+ * Reading roles. Interface chrome, the assistant's prose, and the user's own
16
+ * words are three different reading tasks, and products routinely want them
17
+ * set differently — a serif response against a sans UI is the common one.
18
+ * All three resolve to the sans face until a consumer says otherwise, so
19
+ * nothing changes by default.
20
+ */
21
+ --sigvelo-font-ui: var(--sigvelo-font-sans);
22
+ --sigvelo-font-response: var(--sigvelo-font-sans);
23
+ --sigvelo-font-user-message: var(--sigvelo-font-sans);
24
+
25
+ /* Named so [data-font="dyslexic"] has something to point at. The face is not
26
+ bundled; a consumer that wants it self-hosts OpenDyslexic and the stack
27
+ falls through to a wide-spaced serif everywhere else. */
28
+ --sigvelo-font-dyslexic: "OpenDyslexic", "Comic Sans MS", Georgia, serif;
29
+
12
30
  /* Type scale */
13
31
  --sigvelo-text-3xs: 0.625rem;
14
32
  --sigvelo-text-2xs: 0.6875rem;
@@ -19,7 +37,7 @@
19
37
  --sigvelo-text-lg: 1.125rem;
20
38
  --sigvelo-text-xl: 1.25rem;
21
39
  --sigvelo-text-2xl: 1.5rem;
22
- --sigvelo-text-3xl: 1.875rem;
40
+ --sigvelo-text-3xl: 1.75rem;
23
41
  --sigvelo-text-4xl: 2.25rem;
24
42
  --sigvelo-text-5xl: 3rem;
25
43
 
@@ -35,8 +53,15 @@
35
53
  --sigvelo-font-weight-semibold: 500;
36
54
  --sigvelo-font-weight-bold: 700;
37
55
 
38
- /* Line heights */
39
- --sigvelo-leading-body: 1.6;
56
+ /*
57
+ * Line heights.
58
+ *
59
+ * The ratio scale below is for prose, where leading should grow with the
60
+ * reader's font size. For interface text, prefer the paired absolutes
61
+ * further down: they are quantized to whole pixels, so a stack of labels,
62
+ * rows, and icons lands on the same rhythm the spacing scale uses instead of
63
+ * accumulating fractional drift.
64
+ */
40
65
  --sigvelo-leading-none: 1;
41
66
  --sigvelo-leading-tight: 1.2;
42
67
  --sigvelo-leading-compact: 1.25;
@@ -45,8 +70,62 @@
45
70
  --sigvelo-leading-relaxed: 1.625;
46
71
  --sigvelo-leading-loose: 2;
47
72
 
48
- /* Letter spacing */
73
+ /*
74
+ * One leading per type step. Setting a size and its partner keeps every
75
+ * label of that size on the same baseline rhythm without anyone choosing a
76
+ * ratio by eye. Small text takes a proportionally tighter measure and large
77
+ * text a looser one, which is why these are not one multiplier.
78
+ */
79
+ --sigvelo-text-3xs-leading: 0.875rem; /* 14px */
80
+ --sigvelo-text-2xs-leading: 1rem; /* 16px */
81
+ --sigvelo-text-xs-leading: 1rem; /* 16px */
82
+ --sigvelo-text-compact-leading: 1.125rem; /* 18px */
83
+ --sigvelo-text-sm-leading: 1.25rem; /* 20px */
84
+ --sigvelo-text-base-leading: 1.5rem; /* 24px */
85
+ --sigvelo-text-lg-leading: 1.75rem; /* 28px */
86
+ --sigvelo-text-xl-leading: 1.75rem; /* 28px */
87
+ --sigvelo-text-2xl-leading: 2rem; /* 32px */
88
+ --sigvelo-text-3xl-leading: 2.25rem; /* 36px */
89
+ --sigvelo-text-4xl-leading: 2.5rem; /* 40px */
90
+ --sigvelo-text-5xl-leading: 3rem; /* 48px */
91
+
92
+ /* Letter spacing. Large type set at the default tracking looks loose, so
93
+ display headings tighten as they grow. */
94
+ --sigvelo-tracking-tighter: -0.03em;
95
+ --sigvelo-tracking-tight: -0.015em;
49
96
  --sigvelo-tracking-normal: 0;
50
97
  --sigvelo-tracking-wide: 0.025em;
51
98
  --sigvelo-tracking-wider: 0.05em;
99
+
100
+ /*
101
+ * Measure. Line length is the readability control with the most evidence
102
+ * behind it and the one nothing in the system could express, so long-form
103
+ * agent output ran the full width of whatever panel it landed in. Character
104
+ * units, not rem: the comfortable measure is a count of characters, and it
105
+ * should follow the reader's font size rather than fight it.
106
+ */
107
+ --sigvelo-measure-prose: 68ch;
108
+ /* Code, tables, and diagrams read worse when wrapped than when wide. */
109
+ --sigvelo-measure-wide-block: 100ch;
110
+
111
+ /*
112
+ * Reader text scale. Applied by .sigvelo-reader-text to prose only, never to
113
+ * chrome: a reader who wants larger message text is not asking for taller
114
+ * toolbars, and scaling both is how a side panel runs out of room. Controls
115
+ * keep resolving through the rem type ramp.
116
+ */
117
+ --sigvelo-chat-font-scale: 1;
118
+ }
119
+
120
+ /*
121
+ * Opt-in dyslexia-friendly face. Set on :root for the whole document or on any
122
+ * subtree. Only the reading roles change — mono stays mono, because a
123
+ * proportional face makes code worse for everyone.
124
+ */
125
+ :root[data-font="dyslexic"],
126
+ [data-font="dyslexic"] {
127
+ --sigvelo-font-ui: var(--sigvelo-font-dyslexic);
128
+ --sigvelo-font-response: var(--sigvelo-font-dyslexic);
129
+ --sigvelo-font-user-message: var(--sigvelo-font-dyslexic);
130
+ --sigvelo-font-heading: var(--sigvelo-font-dyslexic);
52
131
  }