@stigmer/theme 3.1.3 → 3.1.5
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/README.md +35 -73
- package/package.json +1 -1
- package/presets/corporate.css +2 -2
- package/presets/fintech.css +4 -4
- package/presets/friendly.css +8 -8
- package/presets/monochrome.css +4 -4
- package/presets/startup.css +6 -6
- package/src/contract/__tests__/color.test.ts +59 -0
- package/src/contract/__tests__/contrast.test.ts +81 -0
- package/src/contract/__tests__/parse.test.ts +106 -0
- package/src/contract/__tests__/resolve.test.ts +85 -0
- package/src/contract/audit.ts +138 -0
- package/src/contract/color.ts +79 -0
- package/src/contract/pairs.ts +169 -0
- package/src/contract/parse.ts +131 -0
- package/src/contract/resolve.ts +92 -0
- package/src/presets/corporate.css +2 -2
- package/src/presets/fintech.css +4 -4
- package/src/presets/friendly.css +8 -8
- package/src/presets/monochrome.css +4 -4
- package/src/presets/startup.css +6 -6
- package/src/tokens.css +171 -28
- package/tokens.css +171 -28
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { ThemeFileTokens, TokenDeclaration } from "./parse.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cascade-faithful token resolution for a Stigmer theme scope.
|
|
5
|
+
*
|
|
6
|
+
* Models the element `StigmerProvider` renders:
|
|
7
|
+
* `<div class="stgm stgm-theme-<id>" data-stgm-color-mode="<mode>">` with
|
|
8
|
+
* `tokens.css` loaded before the preset CSS. On that element the cascade
|
|
9
|
+
* resolves each token in this priority order (highest first):
|
|
10
|
+
*
|
|
11
|
+
* 1. **preset dark** — `[data-stgm-color-mode="dark"] .stgm-theme-<id>`
|
|
12
|
+
* (specificity 0,2,0) beats everything else.
|
|
13
|
+
* 2. **preset light** — `.stgm-theme-<id>` (0,1,0) ties with the default
|
|
14
|
+
* dark block (0,1,0) and wins: preset CSS is loaded after `tokens.css`
|
|
15
|
+
* (source order within a layer) and, in app setups that import presets
|
|
16
|
+
* unlayered while `tokens.css` sits in `@layer stgm`, unlayered wins
|
|
17
|
+
* outright. Both routes give the preset-light value priority — which is
|
|
18
|
+
* why a preset that defines a token only in its light block leaks that
|
|
19
|
+
* light value into dark mode (a defect the audit detects; see
|
|
20
|
+
* `presetLightLeaksIntoDark`).
|
|
21
|
+
* 3. **default dark** — `[data-stgm-color-mode="dark"]` in `tokens.css`.
|
|
22
|
+
* 4. **default light** — `:root` in `tokens.css` (inherited).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** Which cascade layer supplied a resolved token value. */
|
|
26
|
+
export type TokenSource =
|
|
27
|
+
| "preset-dark"
|
|
28
|
+
| "preset-light"
|
|
29
|
+
| "default-dark"
|
|
30
|
+
| "default-light";
|
|
31
|
+
|
|
32
|
+
/** A token value after cascade resolution, with its winning layer. */
|
|
33
|
+
export interface ResolvedToken {
|
|
34
|
+
readonly name: string;
|
|
35
|
+
readonly value: string;
|
|
36
|
+
readonly source: TokenSource;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type ColorMode = "light" | "dark";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Resolve every token visible in the given scope.
|
|
43
|
+
*
|
|
44
|
+
* @param defaults Parsed `tokens.css`.
|
|
45
|
+
* @param preset Parsed preset CSS, or `undefined` for the built-in default
|
|
46
|
+
* preset (no theme class).
|
|
47
|
+
*/
|
|
48
|
+
export function resolveTokens(
|
|
49
|
+
defaults: ThemeFileTokens,
|
|
50
|
+
preset: ThemeFileTokens | undefined,
|
|
51
|
+
mode: ColorMode,
|
|
52
|
+
): ReadonlyMap<string, ResolvedToken> {
|
|
53
|
+
// Lowest priority first; later layers overwrite.
|
|
54
|
+
const layers: readonly { source: TokenSource; tokens: ReadonlyMap<string, TokenDeclaration> }[] = [
|
|
55
|
+
{ source: "default-light", tokens: defaults.light },
|
|
56
|
+
...(mode === "dark" ? [{ source: "default-dark" as const, tokens: defaults.dark }] : []),
|
|
57
|
+
...(preset ? [{ source: "preset-light" as const, tokens: preset.light }] : []),
|
|
58
|
+
...(preset && mode === "dark"
|
|
59
|
+
? [{ source: "preset-dark" as const, tokens: preset.dark }]
|
|
60
|
+
: []),
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
const resolved = new Map<string, ResolvedToken>();
|
|
64
|
+
for (const layer of layers) {
|
|
65
|
+
for (const [name, declaration] of layer.tokens) {
|
|
66
|
+
resolved.set(name, { name, value: declaration.value, source: layer.source });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return resolved;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Tokens whose dark-mode value is silently the preset's *light* value —
|
|
74
|
+
* the preset defines them in its light block but not its dark block, while
|
|
75
|
+
* the defaults do provide a dark value that can no longer take effect.
|
|
76
|
+
*
|
|
77
|
+
* Every such token is a latent defect: the preset author almost certainly
|
|
78
|
+
* intended the default dark value to show through, but the cascade gives
|
|
79
|
+
* the preset-light value priority (see module doc, rule 2).
|
|
80
|
+
*/
|
|
81
|
+
export function presetLightLeaksIntoDark(
|
|
82
|
+
defaults: ThemeFileTokens,
|
|
83
|
+
preset: ThemeFileTokens,
|
|
84
|
+
): readonly string[] {
|
|
85
|
+
const leaks: string[] = [];
|
|
86
|
+
for (const name of preset.light.keys()) {
|
|
87
|
+
if (!preset.dark.has(name) && defaults.dark.has(name)) {
|
|
88
|
+
leaks.push(name);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return leaks;
|
|
92
|
+
}
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
--stgm-muted-faint: oklch(0.96 0.01 250);
|
|
45
45
|
--stgm-primary-muted: oklch(0.58 0.10 250);
|
|
46
46
|
--stgm-destructive-muted: oklch(0.65 0.12 27);
|
|
47
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
47
|
+
--stgm-muted-foreground-faint: oklch(0.62 0.02 250);
|
|
48
48
|
--stgm-backdrop: oklch(0.97 0.01 250 / 80%);
|
|
49
49
|
--stgm-sidebar: oklch(0.20 0.06 250);
|
|
50
50
|
--stgm-sidebar-foreground: oklch(0.93 0 0);
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
--stgm-muted-faint: oklch(0.19 0.03 250);
|
|
99
99
|
--stgm-primary-muted: oklch(0.60 0.10 250);
|
|
100
100
|
--stgm-destructive-muted: oklch(0.60 0.10 22);
|
|
101
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
101
|
+
--stgm-muted-foreground-faint: oklch(0.5 0.03 250);
|
|
102
102
|
--stgm-backdrop: oklch(0.16 0.04 250 / 80%);
|
|
103
103
|
--stgm-sidebar: oklch(0.13 0.05 250);
|
|
104
104
|
--stgm-sidebar-foreground: oklch(0.93 0 0);
|
package/src/presets/fintech.css
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
--stgm-muted-faint: oklch(0.975 0.003 280);
|
|
46
46
|
--stgm-primary-muted: oklch(0.58 0.14 280);
|
|
47
47
|
--stgm-destructive-muted: oklch(0.65 0.12 27);
|
|
48
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
48
|
+
--stgm-muted-foreground-faint: oklch(0.62 0.02 280);
|
|
49
49
|
--stgm-backdrop: oklch(0.98 0.005 280 / 80%);
|
|
50
50
|
--stgm-sidebar: oklch(0.12 0.06 280);
|
|
51
51
|
--stgm-sidebar-foreground: oklch(0.90 0.01 280);
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
--stgm-secondary: oklch(0.23 0.05 280);
|
|
73
73
|
--stgm-secondary-foreground: oklch(0.92 0.01 280);
|
|
74
74
|
--stgm-muted: oklch(0.23 0.05 280);
|
|
75
|
-
--stgm-muted-foreground: oklch(0.
|
|
75
|
+
--stgm-muted-foreground: oklch(0.65 0.04 280);
|
|
76
76
|
--stgm-accent: oklch(0.28 0.06 280);
|
|
77
77
|
--stgm-accent-foreground: oklch(0.92 0.01 280);
|
|
78
78
|
--stgm-border: oklch(0.35 0.06 280);
|
|
@@ -99,14 +99,14 @@
|
|
|
99
99
|
--stgm-muted-faint: oklch(0.15 0.04 280);
|
|
100
100
|
--stgm-primary-muted: oklch(0.60 0.14 280);
|
|
101
101
|
--stgm-destructive-muted: oklch(0.60 0.10 22);
|
|
102
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
102
|
+
--stgm-muted-foreground-faint: oklch(0.5 0.03 280);
|
|
103
103
|
--stgm-backdrop: oklch(0.12 0.05 280 / 80%);
|
|
104
104
|
--stgm-sidebar: oklch(0.08 0.06 280);
|
|
105
105
|
--stgm-sidebar-foreground: oklch(0.88 0.01 280);
|
|
106
106
|
--stgm-sidebar-primary: oklch(0.70 0.22 280);
|
|
107
107
|
--stgm-sidebar-primary-foreground: oklch(0.10 0 0);
|
|
108
108
|
--stgm-sidebar-muted: oklch(0.14 0.06 280);
|
|
109
|
-
--stgm-sidebar-muted-foreground: oklch(0.
|
|
109
|
+
--stgm-sidebar-muted-foreground: oklch(0.58 0.04 280);
|
|
110
110
|
--stgm-sidebar-accent: oklch(0.16 0.07 280);
|
|
111
111
|
--stgm-sidebar-accent-foreground: oklch(0.88 0.01 280);
|
|
112
112
|
--stgm-sidebar-border: oklch(0.22 0.06 280);
|
package/src/presets/friendly.css
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
--stgm-card-foreground: oklch(0.22 0.03 50);
|
|
11
11
|
--stgm-popover: oklch(0.99 0.01 65);
|
|
12
12
|
--stgm-popover-foreground: oklch(0.22 0.03 50);
|
|
13
|
-
--stgm-primary: oklch(0.
|
|
13
|
+
--stgm-primary: oklch(0.55 0.20 40);
|
|
14
14
|
--stgm-primary-foreground: oklch(0.98 0 0);
|
|
15
15
|
--stgm-secondary: oklch(0.94 0.02 65);
|
|
16
16
|
--stgm-secondary-foreground: oklch(0.30 0.03 50);
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
--stgm-border: oklch(0.88 0.02 65);
|
|
22
22
|
--stgm-input: oklch(0.88 0.02 65);
|
|
23
23
|
--stgm-input-bg: oklch(0.99 0.01 65);
|
|
24
|
-
--stgm-ring: oklch(0.
|
|
24
|
+
--stgm-ring: oklch(0.55 0.15 40);
|
|
25
25
|
--stgm-chart-1: oklch(0.62 0.20 40);
|
|
26
26
|
--stgm-chart-2: oklch(0.58 0.16 150);
|
|
27
27
|
--stgm-chart-3: oklch(0.55 0.18 280);
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
--stgm-shadow-lg: 0 10px 20px -3px rgb(0 0 0 / 0.08), 0 4px 8px -4px rgb(0 0 0 / 0.06);
|
|
33
33
|
--stgm-transition-duration: 200ms;
|
|
34
34
|
--stgm-transition-timing: cubic-bezier(0.4, 0, 0.2, 1);
|
|
35
|
-
--stgm-primary-hover: oklch(0.
|
|
35
|
+
--stgm-primary-hover: oklch(0.50 0.18 40);
|
|
36
36
|
--stgm-primary-subtle: oklch(0.95 0.03 40);
|
|
37
37
|
--stgm-destructive-subtle: oklch(0.95 0.03 27);
|
|
38
38
|
--stgm-muted-subtle: oklch(0.95 0.02 65);
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
--stgm-muted-faint: oklch(0.96 0.015 65);
|
|
45
45
|
--stgm-primary-muted: oklch(0.68 0.12 40);
|
|
46
46
|
--stgm-destructive-muted: oklch(0.65 0.12 27);
|
|
47
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
47
|
+
--stgm-muted-foreground-faint: oklch(0.62 0.02 50);
|
|
48
48
|
--stgm-backdrop: oklch(0.97 0.015 65 / 80%);
|
|
49
49
|
--stgm-sidebar: oklch(0.95 0.02 65);
|
|
50
50
|
--stgm-sidebar-foreground: oklch(0.22 0.03 50);
|
|
51
|
-
--stgm-sidebar-primary: oklch(0.
|
|
51
|
+
--stgm-sidebar-primary: oklch(0.55 0.20 40);
|
|
52
52
|
--stgm-sidebar-primary-foreground: oklch(0.98 0 0);
|
|
53
53
|
--stgm-sidebar-muted: oklch(0.92 0.02 65);
|
|
54
54
|
--stgm-sidebar-muted-foreground: oklch(0.50 0.03 50);
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
--stgm-secondary: oklch(0.27 0.03 50);
|
|
72
72
|
--stgm-secondary-foreground: oklch(0.93 0.01 65);
|
|
73
73
|
--stgm-muted: oklch(0.27 0.03 50);
|
|
74
|
-
--stgm-muted-foreground: oklch(0.
|
|
74
|
+
--stgm-muted-foreground: oklch(0.67 0.03 50);
|
|
75
75
|
--stgm-accent: oklch(0.33 0.04 50);
|
|
76
76
|
--stgm-accent-foreground: oklch(0.93 0.01 65);
|
|
77
77
|
--stgm-border: oklch(0.38 0.04 50);
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
--stgm-primary-hover: oklch(0.66 0.16 40);
|
|
90
90
|
--stgm-primary-subtle: oklch(0.26 0.04 40);
|
|
91
91
|
--stgm-destructive-subtle: oklch(0.26 0.04 22);
|
|
92
|
-
--stgm-muted-subtle: oklch(0.
|
|
92
|
+
--stgm-muted-subtle: oklch(0.24 0.02 50);
|
|
93
93
|
--stgm-muted-foreground-subtle: oklch(0.52 0.03 50);
|
|
94
94
|
--stgm-accent-hover: oklch(0.26 0.03 50);
|
|
95
95
|
--stgm-destructive-hover: oklch(0.64 0.16 22);
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
--stgm-muted-faint: oklch(0.20 0.02 50);
|
|
99
99
|
--stgm-primary-muted: oklch(0.62 0.10 40);
|
|
100
100
|
--stgm-destructive-muted: oklch(0.60 0.10 22);
|
|
101
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
101
|
+
--stgm-muted-foreground-faint: oklch(0.52 0.02 50);
|
|
102
102
|
--stgm-backdrop: oklch(0.18 0.03 50 / 80%);
|
|
103
103
|
--stgm-sidebar: oklch(0.15 0.03 50);
|
|
104
104
|
--stgm-sidebar-foreground: oklch(0.90 0.01 65);
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
--stgm-muted-faint: oklch(0.98 0 0);
|
|
47
47
|
--stgm-primary-muted: oklch(0.40 0 0);
|
|
48
48
|
--stgm-destructive-muted: oklch(0.65 0.12 27.325);
|
|
49
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
49
|
+
--stgm-muted-foreground-faint: oklch(0.63 0 0);
|
|
50
50
|
--stgm-backdrop: oklch(0.99 0 0 / 80%);
|
|
51
51
|
--stgm-sidebar: oklch(0.97 0 0);
|
|
52
52
|
--stgm-sidebar-foreground: oklch(0.15 0 0);
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
--stgm-primary-hover: oklch(0.88 0 0);
|
|
92
92
|
--stgm-primary-subtle: oklch(0.21 0 0);
|
|
93
93
|
--stgm-destructive-subtle: oklch(0.21 0.03 25);
|
|
94
|
-
--stgm-muted-subtle: oklch(0.
|
|
94
|
+
--stgm-muted-subtle: oklch(0.20 0 0);
|
|
95
95
|
--stgm-muted-foreground-subtle: oklch(0.55 0 0);
|
|
96
96
|
--stgm-accent-hover: oklch(0.22 0 0);
|
|
97
97
|
--stgm-destructive-hover: oklch(0.64 0.17 22);
|
|
@@ -100,14 +100,14 @@
|
|
|
100
100
|
--stgm-muted-faint: oklch(0.17 0 0);
|
|
101
101
|
--stgm-primary-muted: oklch(0.80 0 0);
|
|
102
102
|
--stgm-destructive-muted: oklch(0.60 0.10 22);
|
|
103
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
103
|
+
--stgm-muted-foreground-faint: oklch(0.5 0 0);
|
|
104
104
|
--stgm-backdrop: oklch(0.145 0 0 / 80%);
|
|
105
105
|
--stgm-sidebar: oklch(0.11 0 0);
|
|
106
106
|
--stgm-sidebar-foreground: oklch(0.96 0 0);
|
|
107
107
|
--stgm-sidebar-primary: oklch(0.96 0 0);
|
|
108
108
|
--stgm-sidebar-primary-foreground: oklch(0.145 0 0);
|
|
109
109
|
--stgm-sidebar-muted: oklch(0.18 0 0);
|
|
110
|
-
--stgm-sidebar-muted-foreground: oklch(0.
|
|
110
|
+
--stgm-sidebar-muted-foreground: oklch(0.6 0 0);
|
|
111
111
|
--stgm-sidebar-accent: oklch(0.20 0 0);
|
|
112
112
|
--stgm-sidebar-accent-foreground: oklch(0.96 0 0);
|
|
113
113
|
--stgm-sidebar-border: oklch(0.24 0 0);
|
package/src/presets/startup.css
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
--stgm-muted-faint: oklch(0.98 0 0);
|
|
44
44
|
--stgm-primary-muted: oklch(0.58 0.14 285);
|
|
45
45
|
--stgm-destructive-muted: oklch(0.65 0.12 27);
|
|
46
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
46
|
+
--stgm-muted-foreground-faint: oklch(0.62 0 0);
|
|
47
47
|
--stgm-backdrop: oklch(0.99 0 0 / 80%);
|
|
48
48
|
--stgm-sidebar: oklch(0.97 0 0);
|
|
49
49
|
--stgm-sidebar-foreground: oklch(0.13 0 0);
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
--stgm-secondary: oklch(0.16 0 0);
|
|
71
71
|
--stgm-secondary-foreground: oklch(0.85 0 0);
|
|
72
72
|
--stgm-muted: oklch(0.16 0 0);
|
|
73
|
-
--stgm-muted-foreground: oklch(0.
|
|
73
|
+
--stgm-muted-foreground: oklch(0.62 0 0);
|
|
74
74
|
--stgm-accent: oklch(0.20 0 0);
|
|
75
75
|
--stgm-accent-foreground: oklch(0.90 0 0);
|
|
76
76
|
--stgm-border: oklch(0.22 0 0);
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
--stgm-primary-hover: oklch(0.66 0.18 285);
|
|
89
89
|
--stgm-primary-subtle: oklch(0.16 0.04 285);
|
|
90
90
|
--stgm-destructive-subtle: oklch(0.16 0.04 22);
|
|
91
|
-
--stgm-muted-subtle: oklch(0.
|
|
92
|
-
--stgm-muted-foreground-subtle: oklch(0.
|
|
91
|
+
--stgm-muted-subtle: oklch(0.15 0 0);
|
|
92
|
+
--stgm-muted-foreground-subtle: oklch(0.52 0 0);
|
|
93
93
|
--stgm-accent-hover: oklch(0.15 0 0);
|
|
94
94
|
--stgm-destructive-hover: oklch(0.64 0.17 22);
|
|
95
95
|
--stgm-foreground-hover: oklch(0.82 0 0);
|
|
@@ -97,14 +97,14 @@
|
|
|
97
97
|
--stgm-muted-faint: oklch(0.11 0 0);
|
|
98
98
|
--stgm-primary-muted: oklch(0.62 0.12 285);
|
|
99
99
|
--stgm-destructive-muted: oklch(0.60 0.10 22);
|
|
100
|
-
--stgm-muted-foreground-faint: oklch(0.
|
|
100
|
+
--stgm-muted-foreground-faint: oklch(0.48 0 0);
|
|
101
101
|
--stgm-backdrop: oklch(0.09 0 0 / 80%);
|
|
102
102
|
--stgm-sidebar: oklch(0.07 0 0);
|
|
103
103
|
--stgm-sidebar-foreground: oklch(0.85 0 0);
|
|
104
104
|
--stgm-sidebar-primary: oklch(0.72 0.20 285);
|
|
105
105
|
--stgm-sidebar-primary-foreground: oklch(0.10 0 0);
|
|
106
106
|
--stgm-sidebar-muted: oklch(0.13 0 0);
|
|
107
|
-
--stgm-sidebar-muted-foreground: oklch(0.
|
|
107
|
+
--stgm-sidebar-muted-foreground: oklch(0.58 0 0);
|
|
108
108
|
--stgm-sidebar-accent: oklch(0.14 0 0);
|
|
109
109
|
--stgm-sidebar-accent-foreground: oklch(0.85 0 0);
|
|
110
110
|
--stgm-sidebar-border: oklch(0.18 0 0);
|
package/src/tokens.css
CHANGED
|
@@ -1,116 +1,257 @@
|
|
|
1
|
+
/* The --stgm-* design token contract for all Stigmer UI components.
|
|
2
|
+
This file is the single source of truth: the token reference docs are
|
|
3
|
+
generated from it (group headers and per-token comments below are parsed
|
|
4
|
+
by site/scripts/generate-theme-docs), and the contrast contract in
|
|
5
|
+
src/contract/ gates every value against WCAG thresholds in CI.
|
|
6
|
+
|
|
7
|
+
Light values live on :root; dark values in the block below. Descriptions
|
|
8
|
+
are written once, on the light declarations — a dark declaration changes
|
|
9
|
+
the value, never the meaning. */
|
|
10
|
+
|
|
1
11
|
:root {
|
|
12
|
+
/* @group Typography */
|
|
13
|
+
/* UI text font stack. Hosts override by defining the fallback variable or the token itself. */
|
|
2
14
|
--stgm-font-sans: var(--font-geist-sans, system-ui, sans-serif);
|
|
15
|
+
/* Code and tabular-figure font stack. */
|
|
3
16
|
--stgm-font-mono: var(--font-geist-mono, ui-monospace, monospace);
|
|
17
|
+
|
|
18
|
+
/* @group Shape */
|
|
19
|
+
/* Base corner radius. The Tailwind radius scale (sm/md/lg/xl) is derived from this single token, so one override reshapes every component. */
|
|
4
20
|
--stgm-radius: 0.625rem;
|
|
21
|
+
|
|
22
|
+
/* @group Core surfaces & text */
|
|
23
|
+
/* Page background behind all Stigmer content. */
|
|
5
24
|
--stgm-background: oklch(0.98 0 0);
|
|
25
|
+
/* Primary body text on the page background. */
|
|
6
26
|
--stgm-foreground: oklch(0.145 0 0);
|
|
27
|
+
/* Card fill (approval cards, plan cards, panels). */
|
|
7
28
|
--stgm-card: oklch(1 0 0);
|
|
29
|
+
/* Text on card surfaces. */
|
|
8
30
|
--stgm-card-foreground: oklch(0.145 0 0);
|
|
31
|
+
/* Floating surface fill (dropdowns, dialogs, tooltips). */
|
|
9
32
|
--stgm-popover: oklch(1 0 0);
|
|
33
|
+
/* Text on floating surfaces. */
|
|
10
34
|
--stgm-popover-foreground: oklch(0.145 0 0);
|
|
11
|
-
|
|
35
|
+
/* Brand action color (primary buttons, active states, links). */
|
|
36
|
+
--stgm-primary: oklch(0.52 0.12 190);
|
|
37
|
+
/* Text on primary-filled elements. */
|
|
12
38
|
--stgm-primary-foreground: oklch(0.985 0 0);
|
|
39
|
+
/* Secondary button and low-emphasis control fill. */
|
|
13
40
|
--stgm-secondary: oklch(0.94 0 0);
|
|
41
|
+
/* Text on secondary-filled elements. */
|
|
14
42
|
--stgm-secondary-foreground: oklch(0.205 0 0);
|
|
43
|
+
/* Muted panel fill (code blocks, quiet notices). */
|
|
15
44
|
--stgm-muted: oklch(0.94 0 0);
|
|
16
|
-
|
|
45
|
+
/* Supporting text (captions, timestamps, the Thinking indicator). */
|
|
46
|
+
--stgm-muted-foreground: oklch(0.5 0 0);
|
|
47
|
+
/* Hover/selection fill for menu items and list rows. */
|
|
17
48
|
--stgm-accent: oklch(0.94 0 0);
|
|
49
|
+
/* Text on accent-filled elements. */
|
|
18
50
|
--stgm-accent-foreground: oklch(0.205 0 0);
|
|
19
|
-
|
|
51
|
+
|
|
52
|
+
/* @group Semantic colors */
|
|
53
|
+
/* Destructive action color (deny buttons, error text). */
|
|
54
|
+
--stgm-destructive: oklch(0.55 0.245 27.325);
|
|
55
|
+
/* Text on destructive-filled elements. */
|
|
20
56
|
--stgm-destructive-foreground: oklch(0.985 0 0);
|
|
21
|
-
|
|
57
|
+
/* Positive state color (success badges, confirmations). */
|
|
58
|
+
--stgm-success: oklch(0.5 0.15 150);
|
|
59
|
+
/* Text on success-filled elements. */
|
|
22
60
|
--stgm-success-foreground: oklch(0.985 0 0);
|
|
61
|
+
/* Quiet success surface (subtle badges, inline confirmations). */
|
|
23
62
|
--stgm-success-subtle: oklch(0.95 0.03 150);
|
|
63
|
+
/* Caution state color (warning badges). */
|
|
24
64
|
--stgm-warning: oklch(0.75 0.18 80);
|
|
65
|
+
/* Text on warning-filled elements. */
|
|
25
66
|
--stgm-warning-foreground: oklch(0.145 0 0);
|
|
67
|
+
/* Informational state color (info badges, hints). */
|
|
26
68
|
--stgm-info: oklch(0.55 0.15 250);
|
|
69
|
+
/* Text on info-filled elements. */
|
|
27
70
|
--stgm-info-foreground: oklch(0.985 0 0);
|
|
71
|
+
|
|
72
|
+
/* @group Forms & focus */
|
|
73
|
+
/* Default border for cards, dividers, and containers. */
|
|
28
74
|
--stgm-border: oklch(0.885 0 0);
|
|
75
|
+
/* Input control border. */
|
|
29
76
|
--stgm-input: oklch(0.87 0 0);
|
|
77
|
+
/* Input control fill. */
|
|
30
78
|
--stgm-input-bg: oklch(1 0 0);
|
|
79
|
+
/* Focus ring color. */
|
|
31
80
|
--stgm-ring: oklch(0.55 0.1 190);
|
|
81
|
+
|
|
82
|
+
/* @group Charts */
|
|
83
|
+
/* Categorical chart series 1. */
|
|
32
84
|
--stgm-chart-1: oklch(0.646 0.222 41.116);
|
|
85
|
+
/* Categorical chart series 2. */
|
|
33
86
|
--stgm-chart-2: oklch(0.6 0.118 184.704);
|
|
87
|
+
/* Categorical chart series 3. */
|
|
34
88
|
--stgm-chart-3: oklch(0.398 0.07 227.392);
|
|
89
|
+
/* Categorical chart series 4. */
|
|
35
90
|
--stgm-chart-4: oklch(0.828 0.189 84.429);
|
|
91
|
+
/* Categorical chart series 5. */
|
|
36
92
|
--stgm-chart-5: oklch(0.769 0.188 70.08);
|
|
93
|
+
/* Named chart color for cross-view consistency (e.g. token usage). */
|
|
37
94
|
--stgm-chart-purple: oklch(0.585 0.233 292);
|
|
95
|
+
/* Named chart color for cross-view consistency. */
|
|
38
96
|
--stgm-chart-blue: oklch(0.546 0.245 262);
|
|
97
|
+
/* Named chart color for cross-view consistency. */
|
|
39
98
|
--stgm-chart-green: oklch(0.577 0.174 149);
|
|
99
|
+
/* Named chart color for cross-view consistency. */
|
|
40
100
|
--stgm-chart-orange: oklch(0.702 0.209 41);
|
|
101
|
+
/* Named chart color for cross-view consistency. */
|
|
41
102
|
--stgm-chart-yellow: oklch(0.795 0.184 86);
|
|
103
|
+
|
|
104
|
+
/* @group Emphasis & elevation */
|
|
105
|
+
/* Stronger border for emphasized containers and separators. */
|
|
42
106
|
--stgm-border-prominent: oklch(0.75 0 0);
|
|
107
|
+
/* Small elevation shadow (inputs, buttons). */
|
|
43
108
|
--stgm-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
109
|
+
/* Medium elevation shadow (cards, panels). */
|
|
44
110
|
--stgm-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
111
|
+
/* Large elevation shadow (dialogs, popovers). */
|
|
45
112
|
--stgm-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
113
|
+
|
|
114
|
+
/* @group Motion & layering */
|
|
115
|
+
/* Base transition duration for interactive state changes. */
|
|
46
116
|
--stgm-transition-duration: 150ms;
|
|
117
|
+
/* Base transition easing curve. */
|
|
47
118
|
--stgm-transition-timing: cubic-bezier(0.4, 0, 0.2, 1);
|
|
119
|
+
/* Stacking order for portaled surfaces (dropdowns, dialogs). */
|
|
48
120
|
--stgm-z-popover: 50;
|
|
49
|
-
|
|
121
|
+
|
|
122
|
+
/* @group State shades */
|
|
123
|
+
/* Primary fill on hover. */
|
|
124
|
+
--stgm-primary-hover: oklch(0.47 0.11 190);
|
|
125
|
+
/* Quiet primary-tinted surface (selected rows, active nav). */
|
|
50
126
|
--stgm-primary-subtle: oklch(0.95 0.02 190);
|
|
127
|
+
/* Quiet destructive surface (error notices, danger zones). */
|
|
51
128
|
--stgm-destructive-subtle: oklch(0.95 0.03 27);
|
|
129
|
+
/* Subtlest distinct fill on the page background (user message bubble). Kept borderless-legible: the contrast contract enforces its separation from --stgm-background. */
|
|
52
130
|
--stgm-muted-subtle: oklch(0.96 0 0);
|
|
131
|
+
/* De-emphasized supporting text, one step quieter than muted-foreground. */
|
|
53
132
|
--stgm-muted-foreground-subtle: oklch(0.64 0 0);
|
|
133
|
+
/* Accent fill on hover. */
|
|
54
134
|
--stgm-accent-hover: oklch(0.96 0 0);
|
|
135
|
+
/* Destructive fill on hover. */
|
|
55
136
|
--stgm-destructive-hover: oklch(0.52 0.22 27.325);
|
|
137
|
+
/* Foreground-colored interactive text on hover. */
|
|
56
138
|
--stgm-foreground-hover: oklch(0.20 0 0);
|
|
139
|
+
/* Quieter border for nested or low-emphasis containers. */
|
|
57
140
|
--stgm-border-muted: oklch(0.92 0 0);
|
|
141
|
+
/* Faintest distinct fill (zebra stripes, ghost rows). */
|
|
58
142
|
--stgm-muted-faint: oklch(0.975 0 0);
|
|
143
|
+
/* Desaturated primary for secondary indicators. */
|
|
59
144
|
--stgm-primary-muted: oklch(0.62 0.08 190);
|
|
145
|
+
/* Desaturated destructive for secondary error indicators. */
|
|
60
146
|
--stgm-destructive-muted: oklch(0.65 0.12 27.325);
|
|
61
|
-
|
|
147
|
+
/* Faintest readable text (placeholder-level hints). Held to a 3:1 floor by the contrast contract. */
|
|
148
|
+
--stgm-muted-foreground-faint: oklch(0.64 0 0);
|
|
149
|
+
/* Modal backdrop overlay behind dialogs. */
|
|
62
150
|
--stgm-backdrop: oklch(0.98 0 0 / 80%);
|
|
151
|
+
|
|
152
|
+
/* @group Sidebar */
|
|
153
|
+
/* Sidebar background. Sidebar tokens form their own context: presets may give the sidebar a contrasting (e.g. dark-on-light) treatment. */
|
|
63
154
|
--stgm-sidebar: oklch(0.97 0 0);
|
|
155
|
+
/* Primary text in the sidebar. */
|
|
64
156
|
--stgm-sidebar-foreground: oklch(0.145 0 0);
|
|
65
|
-
|
|
157
|
+
/* Brand action color inside the sidebar. */
|
|
158
|
+
--stgm-sidebar-primary: oklch(0.52 0.12 190);
|
|
159
|
+
/* Text on sidebar-primary fills. */
|
|
66
160
|
--stgm-sidebar-primary-foreground: oklch(0.985 0 0);
|
|
161
|
+
/* Muted panel fill inside the sidebar. */
|
|
67
162
|
--stgm-sidebar-muted: oklch(0.94 0 0);
|
|
68
|
-
|
|
163
|
+
/* Supporting text in the sidebar (section headers). */
|
|
164
|
+
--stgm-sidebar-muted-foreground: oklch(0.5 0 0);
|
|
165
|
+
/* Hover/active item fill in the sidebar. */
|
|
69
166
|
--stgm-sidebar-accent: oklch(0.94 0 0);
|
|
167
|
+
/* Text on sidebar accent fills. */
|
|
70
168
|
--stgm-sidebar-accent-foreground: oklch(0.205 0 0);
|
|
169
|
+
/* Borders and dividers inside the sidebar. */
|
|
71
170
|
--stgm-sidebar-border: oklch(0.885 0 0);
|
|
171
|
+
/* Focus ring inside the sidebar. */
|
|
72
172
|
--stgm-sidebar-ring: oklch(0.55 0.1 190);
|
|
73
173
|
|
|
74
|
-
|
|
174
|
+
/* @group Status */
|
|
175
|
+
/* Ready/healthy status accent (pill text, solid fills, dots). */
|
|
176
|
+
--stgm-status-ready: oklch(0.5 0.15 150);
|
|
177
|
+
/* Text on a solid ready fill. */
|
|
75
178
|
--stgm-status-ready-foreground: oklch(0.985 0 0);
|
|
179
|
+
/* Quiet ready surface (status pill fill). */
|
|
76
180
|
--stgm-status-ready-subtle: oklch(0.95 0.03 150);
|
|
77
|
-
|
|
181
|
+
/* Running/in-progress status accent. */
|
|
182
|
+
--stgm-status-running: oklch(0.5 0.14 230);
|
|
183
|
+
/* Text on a solid running fill. */
|
|
78
184
|
--stgm-status-running-foreground: oklch(0.985 0 0);
|
|
185
|
+
/* Quiet running surface. */
|
|
79
186
|
--stgm-status-running-subtle: oklch(0.95 0.03 230);
|
|
80
|
-
|
|
187
|
+
/* Pending/queued status accent. */
|
|
188
|
+
--stgm-status-pending: oklch(0.5 0 0);
|
|
189
|
+
/* Text on a solid pending fill. */
|
|
81
190
|
--stgm-status-pending-foreground: oklch(0.985 0 0);
|
|
191
|
+
/* Quiet pending surface. */
|
|
82
192
|
--stgm-status-pending-subtle: oklch(0.95 0 0);
|
|
83
|
-
|
|
84
|
-
--stgm-status-degraded
|
|
193
|
+
/* Degraded/at-risk status accent. */
|
|
194
|
+
--stgm-status-degraded: oklch(0.52 0.17 80);
|
|
195
|
+
/* Text on a solid degraded fill. */
|
|
196
|
+
--stgm-status-degraded-foreground: oklch(0.985 0 0);
|
|
197
|
+
/* Quiet degraded surface. */
|
|
85
198
|
--stgm-status-degraded-subtle: oklch(0.95 0.03 80);
|
|
86
|
-
|
|
199
|
+
/* Failed/error status accent. */
|
|
200
|
+
--stgm-status-failed: oklch(0.55 0.245 27.325);
|
|
201
|
+
/* Text on a solid failed fill. */
|
|
87
202
|
--stgm-status-failed-foreground: oklch(0.985 0 0);
|
|
203
|
+
/* Quiet failed surface. */
|
|
88
204
|
--stgm-status-failed-subtle: oklch(0.95 0.03 27);
|
|
89
|
-
|
|
205
|
+
/* Disabled/inactive status accent. */
|
|
206
|
+
--stgm-status-disabled: oklch(0.5 0 0);
|
|
207
|
+
/* Text on a solid disabled fill. */
|
|
90
208
|
--stgm-status-disabled-foreground: oklch(0.985 0 0);
|
|
209
|
+
/* Quiet disabled surface. */
|
|
91
210
|
--stgm-status-disabled-subtle: oklch(0.94 0 0);
|
|
92
|
-
|
|
211
|
+
/* Draft/unpublished status accent. */
|
|
212
|
+
--stgm-status-draft: oklch(0.5 0 0);
|
|
213
|
+
/* Text on a solid draft fill. */
|
|
93
214
|
--stgm-status-draft-foreground: oklch(0.985 0 0);
|
|
215
|
+
/* Quiet draft surface. */
|
|
94
216
|
--stgm-status-draft-subtle: oklch(0.95 0 0);
|
|
95
217
|
|
|
218
|
+
/* @group Diff viewer */
|
|
219
|
+
/* Added-line background in diffs. */
|
|
96
220
|
--stgm-diff-added-bg: oklch(0.96 0.04 150);
|
|
221
|
+
/* Added-line text in diffs. */
|
|
97
222
|
--stgm-diff-added-fg: oklch(0.35 0.12 150);
|
|
223
|
+
/* Removed-line background in diffs. */
|
|
98
224
|
--stgm-diff-removed-bg: oklch(0.96 0.04 27);
|
|
225
|
+
/* Removed-line text in diffs. */
|
|
99
226
|
--stgm-diff-removed-fg: oklch(0.40 0.16 27);
|
|
227
|
+
/* Hunk header background in diffs. */
|
|
100
228
|
--stgm-diff-hunk-header-bg: oklch(0.96 0.02 250);
|
|
229
|
+
/* Hunk header text in diffs. */
|
|
101
230
|
--stgm-diff-hunk-header-fg: oklch(0.45 0.08 250);
|
|
102
231
|
|
|
232
|
+
/* @group Syntax highlighting */
|
|
233
|
+
/* Keywords in highlighted code. */
|
|
103
234
|
--stgm-syntax-keyword: oklch(0.45 0.15 280);
|
|
235
|
+
/* Properties, attributes, and titles in highlighted code. */
|
|
104
236
|
--stgm-syntax-property: oklch(0.40 0.14 250);
|
|
237
|
+
/* String literals in highlighted code. */
|
|
105
238
|
--stgm-syntax-string: oklch(0.42 0.12 150);
|
|
239
|
+
/* Numeric literals in highlighted code. */
|
|
106
240
|
--stgm-syntax-number: oklch(0.50 0.16 50);
|
|
241
|
+
/* Booleans and literals in highlighted code. */
|
|
107
242
|
--stgm-syntax-bool: oklch(0.45 0.15 280);
|
|
243
|
+
/* Comments in highlighted code. */
|
|
108
244
|
--stgm-syntax-comment: oklch(0.55 0 0);
|
|
245
|
+
/* Atoms and symbols in highlighted code. */
|
|
109
246
|
--stgm-syntax-atom: oklch(0.50 0.10 25);
|
|
247
|
+
/* Meta and preprocessor tokens in highlighted code. */
|
|
110
248
|
--stgm-syntax-meta: oklch(0.50 0.12 320);
|
|
249
|
+
/* Tags in highlighted markup. */
|
|
111
250
|
--stgm-syntax-tag: oklch(0.45 0.15 20);
|
|
112
251
|
}
|
|
113
252
|
|
|
253
|
+
/* Dark values for the same contract. Tokens omitted here inherit their
|
|
254
|
+
light value (fonts, radius, motion, z-index). */
|
|
114
255
|
[data-stgm-color-mode="dark"] {
|
|
115
256
|
--stgm-background: oklch(0.145 0 0);
|
|
116
257
|
--stgm-foreground: oklch(0.985 0 0);
|
|
@@ -123,18 +264,20 @@
|
|
|
123
264
|
--stgm-secondary: oklch(0.269 0 0);
|
|
124
265
|
--stgm-secondary-foreground: oklch(0.985 0 0);
|
|
125
266
|
--stgm-muted: oklch(0.269 0 0);
|
|
126
|
-
--stgm-muted-foreground: oklch(0.
|
|
267
|
+
--stgm-muted-foreground: oklch(0.75 0 0);
|
|
127
268
|
--stgm-accent: oklch(0.371 0 0);
|
|
128
269
|
--stgm-accent-foreground: oklch(0.985 0 0);
|
|
270
|
+
/* Dark fills are lightened, so their foregrounds flip to near-black
|
|
271
|
+
(matching --stgm-primary-foreground) to preserve AA contrast. */
|
|
129
272
|
--stgm-destructive: oklch(0.704 0.191 22.216);
|
|
130
|
-
--stgm-destructive-foreground: oklch(0.
|
|
273
|
+
--stgm-destructive-foreground: oklch(0.145 0 0);
|
|
131
274
|
--stgm-success: oklch(0.7 0.15 150);
|
|
132
|
-
--stgm-success-foreground: oklch(0.
|
|
275
|
+
--stgm-success-foreground: oklch(0.145 0 0);
|
|
133
276
|
--stgm-success-subtle: oklch(0.24 0.04 150);
|
|
134
277
|
--stgm-warning: oklch(0.78 0.16 80);
|
|
135
278
|
--stgm-warning-foreground: oklch(0.145 0 0);
|
|
136
279
|
--stgm-info: oklch(0.7 0.15 250);
|
|
137
|
-
--stgm-info-foreground: oklch(0.
|
|
280
|
+
--stgm-info-foreground: oklch(0.145 0 0);
|
|
138
281
|
--stgm-border: oklch(1 0 0 / 14%);
|
|
139
282
|
--stgm-input: oklch(1 0 0 / 20%);
|
|
140
283
|
--stgm-input-bg: oklch(0.205 0 0);
|
|
@@ -156,7 +299,7 @@
|
|
|
156
299
|
--stgm-primary-hover: oklch(0.66 0.11 190);
|
|
157
300
|
--stgm-primary-subtle: oklch(0.24 0.03 190);
|
|
158
301
|
--stgm-destructive-subtle: oklch(0.24 0.04 22);
|
|
159
|
-
--stgm-muted-subtle: oklch(0.
|
|
302
|
+
--stgm-muted-subtle: oklch(0.24 0 0);
|
|
160
303
|
--stgm-muted-foreground-subtle: oklch(0.60 0 0);
|
|
161
304
|
--stgm-accent-hover: oklch(0.30 0 0);
|
|
162
305
|
--stgm-destructive-hover: oklch(0.64 0.17 22.216);
|
|
@@ -179,25 +322,25 @@
|
|
|
179
322
|
--stgm-sidebar-ring: oklch(0.5 0.08 190);
|
|
180
323
|
|
|
181
324
|
--stgm-status-ready: oklch(0.7 0.15 150);
|
|
182
|
-
--stgm-status-ready-foreground: oklch(0.
|
|
325
|
+
--stgm-status-ready-foreground: oklch(0.145 0 0);
|
|
183
326
|
--stgm-status-ready-subtle: oklch(0.24 0.04 150);
|
|
184
327
|
--stgm-status-running: oklch(0.7 0.14 230);
|
|
185
|
-
--stgm-status-running-foreground: oklch(0.
|
|
328
|
+
--stgm-status-running-foreground: oklch(0.145 0 0);
|
|
186
329
|
--stgm-status-running-subtle: oklch(0.24 0.04 230);
|
|
187
330
|
--stgm-status-pending: oklch(0.708 0 0);
|
|
188
|
-
--stgm-status-pending-foreground: oklch(0.
|
|
331
|
+
--stgm-status-pending-foreground: oklch(0.145 0 0);
|
|
189
332
|
--stgm-status-pending-subtle: oklch(0.24 0 0);
|
|
190
333
|
--stgm-status-degraded: oklch(0.78 0.16 80);
|
|
191
334
|
--stgm-status-degraded-foreground: oklch(0.145 0 0);
|
|
192
335
|
--stgm-status-degraded-subtle: oklch(0.24 0.04 80);
|
|
193
336
|
--stgm-status-failed: oklch(0.704 0.191 22.216);
|
|
194
|
-
--stgm-status-failed-foreground: oklch(0.
|
|
337
|
+
--stgm-status-failed-foreground: oklch(0.145 0 0);
|
|
195
338
|
--stgm-status-failed-subtle: oklch(0.24 0.04 22);
|
|
196
|
-
--stgm-status-disabled: oklch(0.
|
|
197
|
-
--stgm-status-disabled-foreground: oklch(0.
|
|
339
|
+
--stgm-status-disabled: oklch(0.62 0 0);
|
|
340
|
+
--stgm-status-disabled-foreground: oklch(0.145 0 0);
|
|
198
341
|
--stgm-status-disabled-subtle: oklch(0.21 0 0);
|
|
199
342
|
--stgm-status-draft: oklch(0.708 0 0);
|
|
200
|
-
--stgm-status-draft-foreground: oklch(0.
|
|
343
|
+
--stgm-status-draft-foreground: oklch(0.145 0 0);
|
|
201
344
|
--stgm-status-draft-subtle: oklch(0.24 0 0);
|
|
202
345
|
|
|
203
346
|
--stgm-diff-added-bg: oklch(0.22 0.04 150);
|