@bsuite/theme 0.5.0 → 0.7.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/src/preset-v4.css CHANGED
@@ -1,134 +1,143 @@
1
1
  /*
2
- * @bsuite/theme — Tailwind v4 @theme block
3
- * Version 0.3.1
2
+ * @bsuite/theme — Tailwind v4 @theme bridge
3
+ * Version 0.7.0
4
4
  *
5
- * Tailwind v4 exposes design tokens to the engine via CSS @theme blocks.
6
- * Import this before any app-specific @theme overrides:
5
+ * Usage (every D2C app; braden imports braden-css instead of css):
7
6
  *
8
7
  * @import 'tailwindcss';
9
- * @import '@bsuite/theme/preset-v4.css';
8
+ * @import '@bsuite/theme/css'; ← defines --role-* (vars.css)
9
+ * @import '@bsuite/theme/preset-v4.css'; ← this file, maps them to utilities
10
10
  *
11
- * @theme {
12
- * --color-app-primary: oklch(0.45 0.18 142); -- app-specific override
13
- * }
11
+ * ─────────────────────────────────────────────────────────────────────────
12
+ * WHY `@theme inline` AND NOT `@theme`
13
+ *
14
+ * Until 0.7.0 this file used a plain `@theme` block containing hardcoded
15
+ * oklch literals — a full second copy of every value in vars.css. Two
16
+ * consequences, both real bugs:
17
+ *
18
+ * 1. DARK MODE DID NOT REACH THESE UTILITIES. Plain `@theme` emits
19
+ * `--color-card: <literal>` at :root and makes `bg-card` resolve to
20
+ * `var(--color-card)`. vars.css rebinds `--role-bg-panel` under
21
+ * `.dark`, but nothing rebound `--color-card`, so `bg-card` stayed on
22
+ * its light-mode literal in dark mode.
23
+ * 2. IT DRIFTED. The duplicate copy still said `--color-card: oklch(1 0
24
+ * 0.5)` (pure white) and `--color-destructive: <purple>` after the
25
+ * token source had moved on from both.
26
+ *
27
+ * `@theme inline` emits the `var()` reference into the utility itself, so
28
+ * `bg-card` resolves through `--role-bg-panel` and follows every `.dark`
29
+ * and BrandingProvider rebinding for free. vars.css is the ONLY source of
30
+ * truth for values; this file contains no colour literals at all.
31
+ *
32
+ * Adding a colour literal to this file re-creates both bugs. Don't.
33
+ * ─────────────────────────────────────────────────────────────────────────
14
34
  *
15
35
  * Token naming: `--color-{name}` → Tailwind generates `bg-{name}`,
16
36
  * `text-{name}`, `border-{name}` etc. automatically.
17
- *
18
- * Layer order matches vars.css:
19
- * 1. Palette — --color-neon-electric-*
20
- * 2. Surface — --color-{light|dark}-{bg|text}-*
21
- * 3. Role — --color-role-* ← bind to these in components
22
- * 4. Shadcn — --color-background, --color-foreground, etc.
23
- * 5. Text-on — --color-text-on-*
24
37
  */
25
38
 
26
- @theme {
27
- /* ============================================================
28
- LAYER 1 — Neon Electric palette (11 colours, FROZEN)
29
- ============================================================ */
30
- --color-neon-electric-blue: oklch(0.546 0.215 262.9);
31
- --color-neon-electric-cyan: oklch(0.769 0.132 191.7);
32
- --color-neon-electric-indigo: oklch(0.511 0.23 277);
33
- --color-neon-electric-purple: oklch(0.568 0.202 283.1);
34
- --color-neon-electric-magenta: oklch(0.742 0.167 359.5);
35
- --color-neon-electric-pink: oklch(0.656 0.212 354.3);
36
- --color-neon-electric-coral: oklch(0.669 0.219 20.9);
37
- --color-neon-electric-orange: oklch(0.728 0.168 22.5);
38
- --color-neon-electric-yellow: oklch(0.868 0.125 81.4);
39
- --color-neon-electric-green: oklch(0.723 0.192 149.6);
40
- --color-neon-electric-lavender: oklch(0.736 0.141 285.6);
41
-
39
+ @theme inline {
42
40
  /* ============================================================
43
- LAYER 2Surface tokens (light)
41
+ LAYER 1Palette. Exposed for decorative use only.
42
+ Bind components to the role tokens below, never to these:
43
+ white-labelling mutates roles, so a palette-bound component
44
+ silently ignores tenant branding.
44
45
  ============================================================ */
45
- --color-light-bg-primary: oklch(0.961 0 0.5);
46
- --color-light-bg-secondary: oklch(0.982 0.002 248);
47
- --color-light-bg-tertiary: oklch(0.963 0.003 228.9);
48
- --color-light-bg-accent: oklch(1 0 0.5);
49
-
50
- /* Eye-strain-safe light text scale (L capped at 0.22, hue 260) */
51
- --color-light-text-primary: oklch(0.22 0.015 260); /* 13.2:1 AAA */
52
- --color-light-text-secondary: oklch(0.38 0.018 260); /* 8.1:1 AAA */
53
- --color-light-text-muted: oklch(0.52 0.018 260); /* 4.9:1 AA */
54
- --color-light-text-subtle: oklch(0.60 0.012 260); /* 3.8:1 AA large */
55
- --color-light-text-disabled: oklch(0.72 0.010 260);
46
+ --color-neon-electric-blue: var(--neon-electric-blue);
47
+ --color-neon-electric-cyan: var(--neon-electric-cyan);
48
+ --color-neon-electric-indigo: var(--neon-electric-indigo);
49
+ --color-neon-electric-purple: var(--neon-electric-purple);
50
+ --color-neon-electric-magenta: var(--neon-electric-magenta);
51
+ --color-neon-electric-pink: var(--neon-electric-pink);
52
+ --color-neon-electric-coral: var(--neon-electric-coral);
53
+ --color-neon-electric-orange: var(--neon-electric-orange);
54
+ --color-neon-electric-yellow: var(--neon-electric-yellow);
55
+ --color-neon-electric-green: var(--neon-electric-green);
56
+ --color-neon-electric-lavender: var(--neon-electric-lavender);
57
+ --color-neon-electric-red: var(--neon-electric-red);
58
+ --color-neon-electric-amber: var(--neon-electric-amber);
59
+ --color-neon-electric-teal: var(--neon-electric-teal);
60
+ --color-neon-electric-deep: var(--neon-electric-deep);
56
61
 
57
62
  /* ============================================================
58
- LAYER 2 — Surface tokens (dark)
63
+ LAYER 2 — Surfaces. Role-bound, so they flip with .dark.
59
64
  ============================================================ */
60
- --color-dark-bg-primary: oklch(0.166 0.026 269.4);
61
- --color-dark-bg-secondary: oklch(0.242 0.03 269.9);
62
- --color-dark-bg-tertiary: oklch(0.326 0.036 266.7);
63
- --color-dark-bg-quaternary: oklch(0.39 0.035 265);
64
- --color-dark-bg-accent: oklch(0.292 0.034 270);
65
-
66
- /* Eye-strain-safe dark text scale (L capped at 0.94, hue 260) */
67
- --color-dark-text-primary: oklch(0.94 0.012 260); /* 13.9:1 AAA */
68
- --color-dark-text-secondary: oklch(0.82 0.015 260); /* 9.8:1 AAA */
69
- --color-dark-text-muted: oklch(0.68 0.018 260); /* 5.6:1 AA */
70
- --color-dark-text-subtle: oklch(0.56 0.015 260); /* 3.6:1 AA large */
71
- --color-dark-text-disabled: oklch(0.44 0.010 260);
65
+ --color-bg-body: var(--role-bg-body);
66
+ --color-bg-surface: var(--role-bg-surface);
67
+ --color-bg-panel: var(--role-bg-panel);
68
+ --color-bg-input: var(--role-bg-input);
69
+ --color-bg-sunken: var(--role-bg-sunken);
70
+ --color-border-strong: var(--role-border-strong);
72
71
 
73
72
  /* ============================================================
74
- LAYER 3 — Role aliases
75
- Consumers should only reference these — never palette names.
73
+ LAYER 3 — Text scale
76
74
  ============================================================ */
77
- --color-role-primary: oklch(0.546 0.215 262.9); /* electric blue */
78
- --color-role-secondary: oklch(0.511 0.23 277); /* electric indigo */
79
- --color-role-accent: oklch(0.769 0.132 191.7); /* electric cyan */
80
-
81
- /* Colourblind-safe: error = purple, never red/coral */
82
- --color-role-error: oklch(0.568 0.202 283.1); /* electric purple */
83
- --color-role-destructive: oklch(0.568 0.202 283.1); /* synonym */
84
- --color-role-warning: oklch(0.728 0.168 22.5); /* electric orange */
85
- --color-role-success: oklch(0.723 0.192 149.6); /* electric green */
86
- --color-role-info: oklch(0.769 0.132 191.7); /* electric cyan */
87
-
88
- /* Semantic status aliases (deprecated: prefer role-*) */
89
- --color-status-success: oklch(0.723 0.192 149.6);
90
- --color-status-warning: oklch(0.728 0.168 22.5);
91
- --color-status-error: oklch(0.568 0.202 283.1); /* purple — colourblind policy */
92
- --color-status-info: oklch(0.769 0.132 191.7);
75
+ --color-text-heading: var(--role-text-heading);
76
+ --color-text-body: var(--role-text-body);
77
+ --color-text-secondary: var(--role-text-secondary);
78
+ --color-text-muted: var(--role-text-muted);
79
+ --color-text-subtle: var(--role-text-subtle);
80
+ --color-text-disabled: var(--role-text-disabled);
93
81
 
94
82
  /* ============================================================
95
- LAYER 4Shadcn/ui bridge
96
- Tailwind generates bg-background, text-foreground, etc.
83
+ LAYER 3Semantic roles.
84
+ Error is RED because D2C's primary is blue and error must be
85
+ maximally separated from primary under dichromacy — see the
86
+ separation policy in vars.css. Not a fixed-hue rule.
97
87
  ============================================================ */
98
- --color-background: oklch(0.961 0 0.5);
99
- --color-foreground: oklch(0.22 0.015 260);
100
- --color-card: oklch(1 0 0.5);
101
- --color-card-foreground: oklch(0.22 0.015 260);
102
- --color-popover: oklch(1 0 0.5);
103
- --color-popover-foreground: oklch(0.22 0.015 260);
104
- --color-primary: oklch(0.546 0.215 262.9);
105
- --color-primary-foreground: oklch(0.99 0 0);
106
- --color-secondary: oklch(0.511 0.23 277);
107
- --color-secondary-foreground: oklch(0.99 0 0);
108
- --color-muted: oklch(0.963 0.003 228.9);
109
- --color-muted-foreground: oklch(0.52 0.018 260);
110
- --color-accent: oklch(0.769 0.132 191.7);
111
- --color-accent-foreground: oklch(0.17 0.02 260);
112
- --color-destructive: oklch(0.568 0.202 283.1); /* purple — colourblind policy */
113
- --color-destructive-foreground: oklch(0.99 0 0);
114
- --color-border: oklch(0.942 0.005 247.9);
115
- --color-input: oklch(0.942 0.005 247.9);
116
- --color-ring: oklch(0.546 0.215 262.9);
88
+ --color-role-primary: var(--role-primary);
89
+ --color-role-secondary: var(--role-secondary);
90
+ --color-role-accent: var(--role-accent);
91
+ --color-role-error: var(--role-error);
92
+ --color-role-destructive: var(--role-destructive);
93
+ --color-role-warning: var(--role-warning);
94
+ --color-role-success: var(--role-success);
95
+ --color-role-info: var(--role-info);
96
+
97
+ /* AA-safe text variants — the only correct token for coloured type.
98
+ A saturated fill colour is not a legible text colour. */
99
+ --color-primary-text: var(--role-primary-text);
100
+ --color-accent-text: var(--role-accent-text);
101
+ --color-error-text: var(--role-error-text);
102
+ --color-warning-text: var(--role-warning-text);
103
+ --color-success-text: var(--role-success-text);
104
+
105
+ /* Per-app accent (Layer 5). Resolves through [data-app] on <body>,
106
+ falling back to the shared accent when no app is declared. */
107
+ --color-app-accent: var(--app-accent, var(--role-accent));
108
+ --color-app-accent-text: var(--app-accent-text, var(--role-accent-text));
117
109
 
118
110
  /* ============================================================
119
- LAYER 5Inverse text (for coloured fill surfaces)
111
+ LAYER 4shadcn/ui bridge
120
112
  ============================================================ */
121
- --color-text-on-primary: oklch(0.99 0 0);
122
- --color-text-on-accent: oklch(0.17 0.02 260);
123
- --color-text-on-error: oklch(0.99 0 0);
124
- --color-text-on-success: oklch(0.17 0.02 260);
125
- --color-text-on-warning: oklch(0.17 0.02 260);
113
+ --color-background: var(--role-bg-body);
114
+ --color-foreground: var(--role-text-body);
115
+ --color-card: var(--role-bg-panel);
116
+ --color-card-foreground: var(--role-text-body);
117
+ --color-popover: var(--role-bg-panel);
118
+ --color-popover-foreground: var(--role-text-body);
119
+ --color-primary: var(--role-primary);
120
+ --color-primary-foreground: var(--text-on-primary);
121
+ --color-secondary: var(--role-secondary);
122
+ --color-secondary-foreground: var(--text-on-primary);
123
+ --color-muted: var(--role-bg-input);
124
+ --color-muted-foreground: var(--role-text-muted);
125
+ --color-accent: var(--role-accent);
126
+ --color-accent-foreground: var(--text-on-accent);
127
+ --color-destructive: var(--role-destructive);
128
+ --color-destructive-foreground: var(--text-on-error);
129
+ --color-border: var(--role-border);
130
+ --color-input: var(--role-border);
131
+ --color-ring: var(--role-primary);
126
132
 
127
133
  /* ============================================================
128
- WCAG AA text pairs for raw neons on light backgrounds
134
+ LAYER 5 Inverse text on coloured fills
129
135
  ============================================================ */
130
- --color-accent-text: oklch(0.486 0.084 191.5);
131
- --color-primary-text: oklch(0.485 0.243 263.6);
136
+ --color-text-on-primary: var(--text-on-primary);
137
+ --color-text-on-accent: var(--text-on-accent);
138
+ --color-text-on-error: var(--text-on-error);
139
+ --color-text-on-success: var(--text-on-success);
140
+ --color-text-on-warning: var(--text-on-warning);
132
141
 
133
142
  /* ============================================================
134
143
  ANIMATIONS
@@ -143,27 +152,28 @@
143
152
  }
144
153
 
145
154
  /* ============================================================
146
- KEYFRAMES — outside @theme (v4 doesn't expose them there)
147
- oklch used throughout no rgba/hsl leakage
155
+ KEYFRAMES — outside @theme (v4 doesn't expose them there).
156
+ Colour-bearing frames derive from --role-accent, so they follow
157
+ per-app accent and tenant branding instead of pinning cyan.
148
158
  ============================================================ */
149
159
  @keyframes pulse-soft {
150
160
  0%, 100% { opacity: 1; }
151
- 50% { opacity: 0.7; }
161
+ 50% { opacity: 0.7; }
152
162
  }
153
163
 
154
164
  @keyframes glow {
155
- 0% { box-shadow: 0 0 5px oklch(0.769 0.132 191.7 / 0.2); }
156
- 100% { box-shadow: 0 0 20px oklch(0.769 0.132 191.7 / 0.6); }
165
+ 0% { box-shadow: 0 0 5px oklch(from var(--role-accent) l c h / 0.2); }
166
+ 100% { box-shadow: 0 0 20px oklch(from var(--role-accent) l c h / 0.6); }
157
167
  }
158
168
 
159
169
  @keyframes neon-pulse {
160
- 0%, 100% { text-shadow: 0 0 10px oklch(0.769 0.132 191.7 / 0.3); }
161
- 50% { text-shadow: 0 0 20px oklch(0.769 0.132 191.7 / 0.8); }
170
+ 0%, 100% { text-shadow: 0 0 10px oklch(from var(--role-accent) l c h / 0.3); }
171
+ 50% { text-shadow: 0 0 20px oklch(from var(--role-accent) l c h / 0.8); }
162
172
  }
163
173
 
164
174
  @keyframes float {
165
175
  0%, 100% { transform: translateY(0px); }
166
- 50% { transform: translateY(-10px); }
176
+ 50% { transform: translateY(-10px); }
167
177
  }
168
178
 
169
179
  @keyframes shimmer {
@@ -173,7 +183,7 @@
173
183
 
174
184
  @keyframes typing {
175
185
  0%, 60% { opacity: 1; }
176
- 30% { opacity: 0.4; }
186
+ 30% { opacity: 0.4; }
177
187
  }
178
188
 
179
189
  @keyframes shine {
@@ -1,22 +0,0 @@
1
- /*
2
- * runtime-branding.css — populated at runtime by <BrandingProvider>
3
- *
4
- * DO NOT add static values here. BrandingProvider reads the tenant's
5
- * branding JSON from Supabase and calls
6
- * document.documentElement.style.setProperty('--primary', value)
7
- * for each key. This file is a documentation placeholder only.
8
- *
9
- * Keys populated at runtime (if tenant has branding configured):
10
- * --primary (oklch string)
11
- * --accent (oklch string)
12
- * --accent-primary (oklch string)
13
- * --app-primary (oklch string)
14
- * --app-accent (oklch string)
15
- * Logo URLs are injected via JS into CSS vars:
16
- * --logo-url (url() string)
17
- * --mark-url (url() string)
18
- */
19
-
20
- :root[data-branding-loaded="true"] {
21
- /* intentionally empty — BrandingProvider injects vars directly via JS */
22
- }
@@ -1,43 +0,0 @@
1
- /*
2
- * @bsuite/theme — tokens-brand-corporate-braden.css
3
- *
4
- * Braden corporate brand deviation.
5
- * Applied via .theme-braden or data-brand="braden" — NEVER auto-applied.
6
- *
7
- * ⚠️ This file is EXEMPT from the D2C oklch-only rule (BRADEN-EXEMPT).
8
- * Do NOT import this file from index.css or any D2C app entry point.
9
- * Braden's own stylesheet opts in explicitly.
10
- *
11
- * Source of truth: TOKEN-MAPPING.md §4 + §6
12
- */
13
-
14
- .theme-braden,
15
- [data-brand="braden"] {
16
-
17
- /* ===== Braden brand primitives ===== */
18
- --app-primary: oklch(0.488 0.170 17.6); /* Braden Red */
19
- --app-accent: oklch(0.769 0.096 90.9); /* Braden Gold */
20
- --app-primary-dark: oklch(0.400 0.137 16.8); /* Braden Red — pressed/hover state */
21
-
22
- /* ===== Background ===== */
23
- --bg-body: oklch(1 0 0);
24
- --bg-panel: oklch(1 0 0);
25
- --bg-surface: oklch(0.975 0 0);
26
-
27
- /* ===== Text ===== */
28
- --text-primary: oklch(0.156 0 0);
29
-
30
- /* ===== Border ===== */
31
- --border-color: oklch(0.916 0 0);
32
-
33
- /* ===== Accent / brand ===== */
34
- --accent-primary: oklch(0.488 0.170 17.6); /* Braden Red */
35
- --accent-secondary: oklch(0.769 0.096 90.9); /* Braden Gold */
36
-
37
- /* ===== shadcn/ui bridge tokens ===== */
38
- --primary: oklch(0.488 0.170 17.6); /* Braden Red */
39
- --primary-foreground: oklch(1 0 0);
40
- --accent: oklch(0.769 0.096 90.9); /* Braden Gold */
41
- --accent-foreground: oklch(0.156 0 0);
42
- --ring: oklch(0.488 0.170 17.6); /* Braden Red ring */
43
- }
@@ -1,101 +0,0 @@
1
- /*
2
- * @bsuite/theme — tokens-dark.css
3
- *
4
- * Full semantic token set for the dark theme.
5
- * Applied to .dark.
6
- *
7
- * All values are in OKLCH — no hex, no hsl() wrappers.
8
- * Source of truth: TOKEN-MAPPING.md v0.2.0 + vars.css
9
- */
10
-
11
- .dark {
12
-
13
- /* ===== Text ===== */
14
- --text-primary: oklch(0.94 0.012 260);
15
- --text-secondary: oklch(0.82 0.015 260);
16
- --text-muted: oklch(0.68 0.018 260);
17
- --text-subtle: oklch(0.56 0.015 260);
18
- --text-disabled: oklch(0.44 0.010 260);
19
- --text-on-primary: oklch(0.99 0 0);
20
- --text-on-surface: oklch(0.94 0.012 260);
21
- --color-primary-text: oklch(0.623 0.188 259.8); /* WCAG AA blue text on dark bg */
22
- --color-accent-text: oklch(0.769 0.132 191.7); /* WCAG AA cyan text on dark bg */
23
-
24
- /* ===== Background ===== */
25
- --bg-body: oklch(0.166 0.026 269.4); /* deep navy */
26
- --bg-surface: oklch(0.19 0.02 260);
27
- --bg-panel: oklch(0.242 0.03 269.9);
28
- --bg-tertiary: oklch(0.326 0.036 266.7);
29
- --bg-elevated: oklch(0.292 0.034 270);
30
- --bg-input: oklch(0.242 0.03 269.9 / 0.6);
31
- --bg-hover: oklch(0.39 0.035 265);
32
- --bg-selected: oklch(0.546 0.215 262.9 / 0.15);
33
-
34
- /* ===== Border ===== */
35
- --border-color: oklch(0.769 0.132 191.7 / 0.15);
36
- --border-color-strong: oklch(0.769 0.132 191.7 / 0.3);
37
- --border-shell: oklch(0.769 0.132 191.7 / 0.18);
38
-
39
- /* ===== Accent / brand ===== */
40
- --accent-primary: oklch(0.546 0.215 262.9); /* Electric Blue */
41
- --accent-secondary: oklch(0.769 0.132 191.7); /* Electric Cyan */
42
-
43
- /* ===== Status (same values in both themes) ===== */
44
- --color-success: oklch(0.697 0.135 172.1);
45
- --color-warning: oklch(0.868 0.125 81.4);
46
- --color-error: oklch(0.568 0.202 283.1);
47
- --color-info: oklch(0.769 0.132 191.7);
48
-
49
- /* ===== shadcn/ui bridge tokens ===== */
50
- --background: oklch(0.166 0.026 269.4);
51
- --foreground: var(--text-primary);
52
- --card: oklch(0.242 0.03 269.9);
53
- --card-foreground: var(--text-primary);
54
- --popover: oklch(0.292 0.034 270);
55
- --popover-foreground: var(--text-primary);
56
- --primary: oklch(0.769 0.132 191.7); /* Cyan as primary in dark */
57
- --primary-foreground: oklch(0.166 0.026 269.4);
58
- --secondary: oklch(0.242 0.03 269.9);
59
- --secondary-foreground: var(--text-primary);
60
- --muted: oklch(0.242 0.03 269.9);
61
- --muted-foreground: var(--text-muted);
62
- --accent: oklch(0.546 0.215 262.9); /* Blue as accent in dark */
63
- --accent-foreground: var(--text-primary);
64
- --destructive: var(--color-error);
65
- --destructive-foreground: oklch(0.99 0 0);
66
- --border: oklch(0.769 0.132 191.7 / 0.15);
67
- --input: oklch(0.769 0.132 191.7 / 0.15);
68
- --ring: oklch(0.769 0.132 191.7); /* Cyan ring in dark */
69
-
70
- /* ===== Box shadows — deep blacks + neon cyan glow ===== */
71
- --shadow-elev-0: none;
72
- --shadow-elev-1: 0 1px 3px oklch(0 0 0 / 0.3);
73
- --shadow-elev-2: 0 4px 8px oklch(0 0 0 / 0.4), 0 1px 3px oklch(0 0 0 / 0.3);
74
- --shadow-elev-3: 0 8px 16px oklch(0 0 0 / 0.5), 0 4px 8px oklch(0 0 0 / 0.3);
75
- --shadow-elev-4: 0 16px 32px oklch(0 0 0 / 0.6), 0 8px 16px oklch(0 0 0 / 0.4);
76
-
77
- /* ===== Neon glow helpers ===== */
78
- --glow-button: 0 0 20px oklch(0.769 0.132 191.7 / 0.3);
79
- --glow-button-hover: 0 0 30px oklch(0.769 0.132 191.7 / 0.5);
80
-
81
- /*
82
- * Card glow — subtle neon separation for card surfaces, dark mode only.
83
- * Derived from the app's accent colour (--app-accent, falling back to
84
- * the shared --role-accent default, matching the live vars.css) so
85
- * per-tenant
86
- * BrandingProvider overrides and per-app brand accents (Conduit green,
87
- * R80.3 amber, etc.) automatically re-colour the glow. Two layers:
88
- * a 1px accent ring (edge definition, replaces a hard border) plus a
89
- * soft negative-spread halo (ambient separation). Kept subtle by
90
- * design — this is surface separation, not a decorative outline.
91
- */
92
- --card-glow-source: var(--app-accent, var(--role-accent));
93
- --glow-card: 0 0 0 1px color-mix(in oklch, var(--card-glow-source) 30%, transparent),
94
- 0 0 14px -4px color-mix(in oklch, var(--card-glow-source) 35%, transparent);
95
- --glow-card-hover: 0 0 0 1px color-mix(in oklch, var(--card-glow-source) 42%, transparent),
96
- 0 0 20px -4px color-mix(in oklch, var(--card-glow-source) 48%, transparent);
97
-
98
- /* ===== Button shadow ===== */
99
- --button-shadow: 0 0 20px oklch(0.769 0.132 191.7 / 0.3);
100
- --button-hover-shadow: 0 0 30px oklch(0.769 0.132 191.7 / 0.5);
101
- }
@@ -1,34 +0,0 @@
1
- /*
2
- * @bsuite/theme — tokens-high-contrast.css
3
- *
4
- * AAA accessibility overrides for users who have opted into
5
- * "More Contrast" in their OS/browser settings.
6
- *
7
- * Kept intentionally minimal — only tokens that fail AAA at default
8
- * values are overridden. All other tokens inherit from tokens-light.css
9
- * or tokens-dark.css.
10
- *
11
- * Source of truth: TOKEN-MAPPING.md v0.2.0
12
- */
13
-
14
- @media (prefers-contrast: more) {
15
-
16
- /* ----- Light mode overrides (default / :root) ----- */
17
- :root,
18
- .light {
19
- --text-primary: oklch(0 0 0); /* pure black */
20
- --text-secondary: oklch(0.1 0 0);
21
- --text-muted: oklch(0.2 0 0);
22
- --border-color: oklch(0 0 0);
23
- --border-color-strong: oklch(0 0 0);
24
- }
25
-
26
- /* ----- Dark mode overrides ----- */
27
- .dark {
28
- --text-primary: oklch(1 0 0); /* pure white */
29
- --text-secondary: oklch(0.9 0 0);
30
- --text-muted: oklch(0.8 0 0);
31
- --border-color: oklch(1 0 0);
32
- --border-color-strong: oklch(1 0 0);
33
- }
34
- }
@@ -1,89 +0,0 @@
1
- /*
2
- * @bsuite/theme — tokens-light.css
3
- *
4
- * Full semantic token set for the light theme.
5
- * Applied to :root and .light.
6
- *
7
- * All values are in OKLCH — no hex, no hsl() wrappers.
8
- * Source of truth: TOKEN-MAPPING.md v0.2.0
9
- */
10
-
11
- :root,
12
- .light {
13
-
14
- /* ===== Text ===== */
15
- --text-primary: oklch(0.22 0.015 260);
16
- --text-secondary: oklch(0.38 0.018 260);
17
- --text-muted: oklch(0.52 0.018 260);
18
- --text-subtle: oklch(0.60 0.012 260);
19
- --text-disabled: oklch(0.72 0.010 260);
20
- --text-on-primary: oklch(0.99 0 0);
21
- --text-on-surface: oklch(0.22 0.015 260);
22
- --color-primary-text: oklch(0.485 0.243 263.6); /* WCAG AA blue text on light bg */
23
- --color-accent-text: oklch(0.486 0.084 191.5); /* WCAG AA cyan text on light bg */
24
-
25
- /* ===== Background ===== */
26
- --bg-body: oklch(0.961 0 0.5);
27
- --bg-surface: oklch(0.982 0.002 248);
28
- --bg-panel: oklch(1 0 0);
29
- --bg-tertiary: oklch(0.963 0.003 228.9);
30
- --bg-elevated: oklch(1 0 0);
31
- --bg-input: oklch(0.982 0.002 248);
32
- --bg-hover: oklch(0.963 0.003 228.9);
33
- --bg-selected: oklch(0.546 0.215 262.9 / 0.08);
34
-
35
- /* ===== Border ===== */
36
- --border-color: oklch(0.916 0.006 248);
37
- --border-color-strong: oklch(0.741 0.022 250 / 0.5);
38
- --border-shell: oklch(0.741 0.022 250 / 0.2);
39
-
40
- /* ===== Accent / brand ===== */
41
- --accent-primary: oklch(0.546 0.215 262.9); /* Electric Blue */
42
- --accent-secondary: oklch(0.769 0.132 191.7); /* Electric Cyan */
43
-
44
- /* ===== Status ===== */
45
- --color-success: oklch(0.697 0.135 172.1);
46
- --color-warning: oklch(0.868 0.125 81.4);
47
- --color-error: oklch(0.568 0.202 283.1);
48
- --color-info: oklch(0.769 0.132 191.7);
49
-
50
- /* ===== shadcn/ui bridge tokens ===== */
51
- --background: oklch(0.961 0 0.5);
52
- --foreground: var(--text-primary);
53
- --card: oklch(1 0 0);
54
- --card-foreground: var(--text-primary);
55
- --popover: oklch(1 0 0);
56
- --popover-foreground: var(--text-primary);
57
- --primary: oklch(0.546 0.215 262.9); /* Electric Blue */
58
- --primary-foreground: var(--text-on-primary);
59
- --secondary: oklch(0.961 0 0.5);
60
- --secondary-foreground: var(--text-primary);
61
- --muted: oklch(0.961 0 0.5);
62
- --muted-foreground: var(--text-muted);
63
- --accent: oklch(0.769 0.132 191.7); /* Electric Cyan */
64
- --accent-foreground: oklch(0.17 0.02 260);
65
- --destructive: var(--color-error);
66
- --destructive-foreground: oklch(0.99 0 0);
67
- --border: oklch(0.916 0.006 248); /* from hsl(214.3 31.8% 91.4%) */
68
- --input: oklch(0.916 0.006 248);
69
- --ring: oklch(0.546 0.215 262.9); /* Electric Blue */
70
-
71
- /* ===== Border-radius ===== */
72
- --radius: 0.5rem;
73
-
74
- /* ===== Box shadows — soft neutral, no neon glow in light mode ===== */
75
- --shadow-elev-0: none;
76
- --shadow-elev-1: 0 1px 2px oklch(0 0 0 / 0.05);
77
- --shadow-elev-2: 0 4px 6px oklch(0 0 0 / 0.07), 0 2px 4px oklch(0 0 0 / 0.06);
78
- --shadow-elev-3: 0 10px 15px oklch(0 0 0 / 0.1), 0 4px 6px oklch(0 0 0 / 0.05);
79
- --shadow-elev-4: 0 20px 25px oklch(0 0 0 / 0.1), 0 10px 10px oklch(0 0 0 / 0.04);
80
-
81
- /* ===== Glow helpers — disabled in light mode ===== */
82
- --glow-button: none;
83
- --glow-button-hover: none;
84
- --glow-card: none;
85
- --glow-card-hover: none;
86
-
87
- /* ===== Button shadow — transparent/none in light mode ===== */
88
- --button-shadow: none;
89
- }