@webority/theme 0.7.4 → 0.7.6

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.
@@ -13,27 +13,32 @@
13
13
  // variables since Bootstrap only consumes the named theme colors.
14
14
  // `!default` so a product that sets these in its own _variables BEFORE importing this file
15
15
  // (the documented override path) wins — a plain assignment here would clobber the brand.
16
- $primary: #4F46E5 !default;
17
- $secondary: #4B5675 !default; // foreground-3 — quiet text + secondary buttons
18
- $success: #04B440 !default;
19
- $info: #056EE9 !default;
20
- $warning: #DFA000 !default;
21
- $danger: #E82646 !default;
22
- $light: #F9FBFC !default; // surface-mute
23
- $dark: #071437 !default; // text-heading
16
+ $primary: #4F46E5 !default;
17
+ // $secondary is intentional quiet grey (text-2 / foreground-3), NOT a second
18
+ // brand hue. `.btn-secondary`, `.text-secondary`, `.bg-secondary` mean "quiet /
19
+ // de-emphasised" across products (Metronic-like). Products that need a true
20
+ // second brand colour should use a custom utility or token — do not repurpose
21
+ // $secondary without a coordinated migration.
22
+ $secondary: #4B5675 !default;
23
+ $success: #04B440 !default;
24
+ $info: #056EE9 !default;
25
+ $warning: #DFA000 !default;
26
+ $danger: #E82646 !default;
27
+ $light: #F9FBFC !default; // surface-mute
28
+ $dark: #071437 !default; // text-heading
24
29
 
25
30
  // Override `$theme-colors` so Bootstrap's $theme-colors map includes
26
31
  // our brand. Anything we add here gets utility classes generated
27
32
  // automatically (e.g. adding "accent" gives you bg-accent, text-accent).
28
33
  $theme-colors: (
29
- "primary": $primary,
34
+ "primary": $primary,
30
35
  "secondary": $secondary,
31
- "success": $success,
32
- "info": $info,
33
- "warning": $warning,
34
- "danger": $danger,
35
- "light": $light,
36
- "dark": $dark,
36
+ "success": $success,
37
+ "info": $info,
38
+ "warning": $warning,
39
+ "danger": $danger,
40
+ "light": $light,
41
+ "dark": $dark,
37
42
  );
38
43
 
39
44
  // Brand helper — set a product's primary ONCE and have the theme-colour map
@@ -41,8 +46,8 @@ $theme-colors: (
41
46
  // and $link-hover-color follow, instead of overriding each in turn. Call it in
42
47
  // the product's pre-bootstrap variables, BEFORE `bootstrap/scss/bootstrap`, e.g.:
43
48
  //
44
- // @include wui-brand-primary(#0EA5E9);
45
- // @import "bootstrap/scss/bootstrap";
49
+ // @include wui-brand-primary(#0EA5E9);
50
+ // @import "bootstrap/scss/bootstrap";
46
51
  //
47
52
  // It rewrites the globals in place, so the whole Bootstrap colour system derives
48
53
  // from the one value. Runtime CSS tokens (--wui-primary*) are still overridden
@@ -57,11 +62,11 @@ $theme-colors: (
57
62
 
58
63
  // ---- Body / text ----------------------------------------------------
59
64
  // $body-bg left at Bootstrap's $white — do not restate pure defaults here.
60
- $body-color: #252F4A; // text-1 from locked palette
65
+ $body-color: #252F4A; // text-1 from locked palette
61
66
  $body-secondary-color: #4B5675;
62
- $body-tertiary-color: #687088; // AA on white (matches --wui-text-3); #78829D was only 3.5:1
67
+ $body-tertiary-color: #687088; // AA on white (matches --wui-text-3); #78829D was only 3.5:1
63
68
  $body-secondary-bg: #F9FBFC;
64
- $body-tertiary-bg: #F5F6FA;
69
+ $body-tertiary-bg: #F5F6FA;
65
70
 
66
71
 
67
72
  // ---- Borders --------------------------------------------------------
@@ -73,11 +78,11 @@ $border-color-translucent: rgba(13, 24, 43, 0.08);
73
78
  // that is what let buttons drift to ~3x Bootstrap's.
74
79
  // Only rungs that DIFFER from Bootstrap 5.3 are set: BS is 0.375/0.25/0.5/1/2rem;
75
80
  // $border-radius-xl (1rem) and the font-weight ladder match BS and are left alone.
76
- $border-radius: 0.5rem; // 8px — buttons, inputs, dropdowns (BS 0.375)
77
- $border-radius-sm: 0.375rem; // 6px (BS 0.25)
78
- $border-radius-lg: 0.75rem; // 12px — cards, toasts (BS 0.5)
79
- $border-radius-2xl: 1.5rem; // 24px (BS 2rem via $border-radius-xxl)
80
- $border-radius-pill: 9999px; // same visual as BS 50rem; explicit for token clarity
81
+ $border-radius: 0.5rem; // 8px — buttons, inputs, dropdowns (BS 0.375)
82
+ $border-radius-sm: 0.375rem; // 6px (BS 0.25)
83
+ $border-radius-lg: 0.75rem; // 12px — cards, toasts (BS 0.5)
84
+ $border-radius-2xl: 1.5rem; // 24px (BS 2rem via $border-radius-xxl)
85
+ $border-radius-pill: 9999px; // same visual as BS 50rem; explicit for token clarity
81
86
 
82
87
 
83
88
  // ---- Typography -----------------------------------------------------
@@ -85,20 +90,20 @@ $border-radius-pill: 9999px; // same visual as BS 50rem; explicit for token
85
90
  // h1/h2/h6 match Bootstrap's $font-size-base multipliers at 1rem — not restated;
86
91
  // only h3–h5 are tighter than Bootstrap's scale.
87
92
  $font-family-sans-serif: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
88
- $font-family-monospace: 'JetBrains Mono', SFMono-Regular, Menlo, Monaco, Consolas, monospace;
93
+ $font-family-monospace: 'JetBrains Mono', SFMono-Regular, Menlo, Monaco, Consolas, monospace;
89
94
 
90
- $line-height-base: 1.55; // BS 1.5
95
+ $line-height-base: 1.55; // BS 1.5
91
96
 
92
- $headings-font-weight: 600; // BS 500
97
+ $headings-font-weight: 600; // BS 500
93
98
  $headings-letter-spacing: -0.02em;
94
- $headings-color: #071437;
99
+ $headings-color: #071437;
95
100
 
96
- $display-font-weight: 500;
97
- $display-line-height: 1.05;
101
+ $display-font-weight: 500;
102
+ $display-line-height: 1.05;
98
103
 
99
- $h3-font-size: 1.5rem; // 24px (BS 1.75rem)
100
- $h4-font-size: 1.25rem; // 20px (BS 1.5rem)
101
- $h5-font-size: 1.125rem; // 18px (BS 1.25rem)
104
+ $h3-font-size: 1.5rem; // 24px (BS 1.75rem)
105
+ $h4-font-size: 1.25rem; // 20px (BS 1.5rem)
106
+ $h5-font-size: 1.125rem; // 18px (BS 1.25rem)
102
107
 
103
108
 
104
109
  // ---- Spacing --------------------------------------------------------
@@ -106,17 +111,17 @@ $h5-font-size: 1.125rem; // 18px (BS 1.25rem)
106
111
  // with the same 0–5 rungs plus 6/7/8/10/12 for hero / section padding so
107
112
  // utilities like `py-8` exist. No need to restate $spacer itself.
108
113
  $spacers: (
109
- 0: 0,
110
- 1: 0.25rem, // 4px
111
- 2: 0.5rem, // 8px
112
- 3: 1rem, // 16px
113
- 4: 1.5rem, // 24px
114
- 5: 3rem, // 48px
115
- 6: 4.5rem, // 72px
116
- 7: 5rem, // 80px
117
- 8: 6rem, // 96px
118
- 10: 8rem, // 128px
119
- 12: 10rem, // 160px
114
+ 0: 0,
115
+ 1: 0.25rem, // 4px
116
+ 2: 0.5rem, // 8px
117
+ 3: 1rem, // 16px
118
+ 4: 1.5rem, // 24px
119
+ 5: 3rem, // 48px
120
+ 6: 4.5rem, // 72px
121
+ 7: 5rem, // 80px
122
+ 8: 6rem, // 96px
123
+ 10: 8rem, // 128px
124
+ 12: 10rem, // 160px
120
125
  );
121
126
 
122
127
  // $container-max-widths is intentionally NOT overridden — Bootstrap's
@@ -126,76 +131,76 @@ $spacers: (
126
131
 
127
132
 
128
133
  // ---- Shadows --------------------------------------------------------
129
- // Elevation rule (TASK-06080): in-page surfaces are FLAT (borders only).
134
+ // Elevation rule: in-page surfaces are FLAT (borders only).
130
135
  // Bootstrap utility ladder (.shadow / .shadow-sm / .shadow-lg) is zeroed so
131
136
  // products cannot reintroduce random depth. Floating UI (dropdown / modal /
132
137
  // toast) uses the overlay rungs — same values as --wui-shadow-overlay* in tokens.
133
- $wui-shadow-overlay: 0 8px 28px -6px rgba(7, 20, 55, 0.14);
138
+ $wui-shadow-overlay: 0 8px 28px -6px rgba(7, 20, 55, 0.14);
134
139
  $wui-shadow-overlay-lg: 0 24px 60px -16px rgba(7, 20, 55, 0.28);
135
140
 
136
- $box-shadow-sm: none;
137
- $box-shadow: none;
138
- $box-shadow-lg: none;
141
+ $box-shadow-sm: none;
142
+ $box-shadow: none;
143
+ $box-shadow-lg: none;
139
144
 
140
145
 
141
146
  // ---- Buttons --------------------------------------------------------
142
- $btn-font-weight: 500;
147
+ $btn-font-weight: 500;
143
148
  // Height comes from --wui-control-height (see _components.scss) so buttons line
144
149
  // up with inputs; the padding just needs to sit inside that.
145
- $btn-padding-y: 0.5rem;
146
- $btn-padding-x: 1.25rem;
147
- $btn-padding-y-lg: 0.875rem;
148
- $btn-padding-x-lg: 1.75rem;
149
- $btn-border-radius: $border-radius; // 8px
150
- $btn-border-radius-sm: $border-radius-sm; // 6px
151
- $btn-border-radius-lg: $border-radius-lg; // 12px
152
- $btn-transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
150
+ $btn-padding-y: 0.5rem;
151
+ $btn-padding-x: 1.25rem;
152
+ $btn-padding-y-lg: 0.875rem;
153
+ $btn-padding-x-lg: 1.75rem;
154
+ $btn-border-radius: $border-radius; // 8px
155
+ $btn-border-radius-sm: $border-radius-sm; // 6px
156
+ $btn-border-radius-lg: $border-radius-lg; // 12px
157
+ $btn-transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
153
158
 
154
159
 
155
160
  // ---- Forms ----------------------------------------------------------
156
161
  // Bootstrap `.form-control` is the field skin; post-CSS in wui/_controls.scss
157
162
  // layers shared height / hover / focus / invalid on `.form-control` and the
158
- // `.input` alias together (TASK-06079). Here only $input-* BS vars.
159
- $input-bg: #FFFFFF;
160
- $input-disabled-bg: #F5F6FA; // --wui-bg-muted
161
- $input-border-color: $border-color;
163
+ // `.input` alias together. Here only $input-* BS vars.
164
+ $input-bg: #FFFFFF;
165
+ $input-disabled-bg: #F5F6FA; // --wui-bg-muted
166
+ $input-border-color: $border-color;
162
167
  // $input-focus-border-color is intentionally NOT overridden. Setting it to $primary here
163
168
  // captures the LIBRARY's $primary (this file compiles before a product's brand override),
164
169
  // leaking indigo into every product. Bootstrap's !default derives it from brand $primary;
165
170
  // post-CSS focus uses var(--color-primary) so runtime rebrand tracks.
166
- $input-focus-box-shadow: none; // border IS the focus cue
167
- $input-focus-color: $body-color;
168
- $input-padding-y: 0.5rem; // filler inside --wui-control-height (44px)
169
- $input-padding-x: 0.875rem; // 14px
170
- $input-border-radius: $border-radius;
171
- $input-placeholder-color: #99A1B7; // --wui-text-4
171
+ $input-focus-box-shadow: none; // border IS the focus cue
172
+ $input-focus-color: $body-color;
173
+ $input-padding-y: 0.5rem; // filler inside --wui-control-height (44px)
174
+ $input-padding-x: 0.875rem; // 14px
175
+ $input-border-radius: $border-radius;
176
+ $input-placeholder-color: #99A1B7; // --wui-text-4
172
177
 
173
178
 
174
179
  // ---- Cards ----------------------------------------------------------
175
- $card-border-color: $border-color;
176
- $card-border-radius: $border-radius-lg;
180
+ $card-border-color: $border-color;
181
+ $card-border-radius: $border-radius-lg;
177
182
  // Flat surfaces — no drop shadow on default .card. Depth is border + tint.
178
183
  // `.card-lifted` is a 1px hover translate only (not a shadow).
179
- $card-box-shadow: none;
180
- $card-spacer-y: 1.5rem;
181
- $card-spacer-x: 1.5rem;
184
+ $card-box-shadow: none;
185
+ $card-spacer-y: 1.5rem;
186
+ $card-spacer-x: 1.5rem;
182
187
 
183
188
 
184
189
  // ---- Nav / dropdown --------------------------------------------------
185
- $nav-link-font-weight: 500;
186
- $dropdown-border-color: $border-color;
190
+ $nav-link-font-weight: 500;
191
+ $dropdown-border-color: $border-color;
187
192
  $dropdown-border-radius: $border-radius;
188
- $dropdown-box-shadow: $wui-shadow-overlay;
193
+ $dropdown-box-shadow: $wui-shadow-overlay;
189
194
 
190
195
 
191
196
  // ---- Modals + toasts ------------------------------------------------
192
- $modal-content-border-color: $border-color;
193
- $modal-content-border-radius: 1rem; // BS $border-radius-xl (1rem) — literal because we do not restate that rung
197
+ $modal-content-border-color: $border-color;
198
+ $modal-content-border-radius: 1rem; // BS $border-radius-xl (1rem) — literal because we do not restate that rung
194
199
  $modal-content-box-shadow-xs: $wui-shadow-overlay-lg;
195
200
 
196
- $toast-border-color: $border-color;
197
- $toast-border-radius: $border-radius-lg;
198
- $toast-box-shadow: $wui-shadow-overlay-lg;
201
+ $toast-border-color: $border-color;
202
+ $toast-border-radius: $border-radius-lg;
203
+ $toast-box-shadow: $wui-shadow-overlay-lg;
199
204
 
200
205
 
201
206
  // ---- Links ----------------------------------------------------------
@@ -203,8 +208,8 @@ $toast-box-shadow: $wui-shadow-overlay-lg;
203
208
  // Hover is a darkened mix of $primary — never a hard-coded indigo — so a product
204
209
  // that sets $primary (or calls wui-brand-primary) gets a matching hover. Approximate
205
210
  // of Bootstrap's shift-color($link-color, 20%) without importing BS functions here.
206
- $link-hover-color: mix(black, $primary, 12%);
207
- $link-decoration: none; // BS default is underline
211
+ $link-hover-color: mix(black, $primary, 12%);
212
+ $link-decoration: none; // BS default is underline
208
213
  $link-hover-decoration: underline;
209
214
 
210
215
 
@@ -214,7 +219,7 @@ $link-hover-decoration: underline;
214
219
  // leaked indigo into every product. Bootstrap's !default `rgba($primary, $focus-ring-opacity)`
215
220
  // is evaluated after the brand override, so it tracks the brand correctly.
216
221
  // $focus-ring-blur matches BS (0) — not restated.
217
- $focus-ring-width: 3px; // BS 0.25rem (4px)
222
+ $focus-ring-width: 3px; // BS 0.25rem (4px)
218
223
 
219
224
 
220
225
  // ---- Table ----------------------------------------------------------
@@ -230,5 +235,5 @@ $focus-ring-width: 3px; // BS 0.25rem (4px)
230
235
  // Bootstrap. Variants that set their own padding are unaffected — theirs still wins.
231
236
  // (Cell colour and header background take the same approach one level down, through
232
237
  // `--bs-table-color` / `--bs-table-bg`; see the base `.table` rules.)
233
- $table-cell-padding-y: 0.75rem; // 12px
234
- $table-cell-padding-x: 0.75rem; // 12px
238
+ $table-cell-padding-y: 0.75rem; // 12px
239
+ $table-cell-padding-x: 0.75rem; // 12px
@@ -8,169 +8,177 @@
8
8
 
9
9
  :root {
10
10
  // Surfaces
11
- --color-bg: var(--wui-bg-page);
12
- --color-bg-subtle: var(--wui-bg-elevated);
13
- --color-bg-muted: var(--wui-bg-muted);
14
- --color-surface: var(--wui-bg-light);
11
+ --color-bg: var(--wui-bg-page);
12
+ --color-bg-subtle: var(--wui-bg-elevated);
13
+ --color-bg-muted: var(--wui-bg-muted);
14
+ --color-surface: var(--wui-bg-light);
15
15
 
16
16
  // Borders
17
- --color-border: var(--wui-border-light);
18
- --color-border-light: var(--wui-border-soft);
17
+ --color-border: var(--wui-border-light);
18
+ --color-border-light: var(--wui-border-soft);
19
19
  --color-border-strong: var(--wui-text-5);
20
20
 
21
21
  // Text ramp
22
- --color-text: var(--wui-text-heading);
23
- --color-text-muted: var(--wui-text-2);
24
- --color-text-subtle: var(--wui-text-3);
22
+ --color-text: var(--wui-text-heading);
23
+ --color-text-muted: var(--wui-text-2);
24
+ --color-text-subtle: var(--wui-text-3);
25
25
 
26
26
  // Bootstrap colour vars bridged onto app tokens so un-tokenised BS text
27
27
  // flips with data-theme.
28
- --bs-body-color: var(--color-text);
29
- --bs-emphasis-color: var(--color-text);
30
- --bs-secondary-color: var(--color-text-muted);
31
- --bs-tertiary-color: var(--color-text-subtle);
32
- --bs-body-bg: var(--color-bg);
33
- --bs-border-color: var(--color-border);
28
+ --bs-body-color: var(--color-text);
29
+ --bs-emphasis-color: var(--color-text);
30
+ --bs-secondary-color: var(--color-text-muted);
31
+ --bs-tertiary-color: var(--color-text-subtle);
32
+ --bs-body-bg: var(--color-bg);
33
+ --bs-border-color: var(--color-border);
34
34
 
35
35
  // Brand
36
- --color-primary: var(--wui-primary);
36
+ --color-primary: var(--wui-primary);
37
37
  --color-primary-hover: var(--wui-primary-pressed);
38
- --color-primary-soft: var(--wui-primary-10);
38
+ --color-primary-soft: var(--wui-primary-10);
39
39
  // Text/icon colour for content sitting ON a solid --color-primary fill — see
40
40
  // --wui-primary-text for why this is a different axis from the -text tokens below.
41
- --color-primary-text: var(--wui-primary-text);
41
+ --color-primary-text: var(--wui-primary-text);
42
42
 
43
43
  // Semantic status ramps
44
- --color-info-active: var(--wui-info-active);
45
- --color-info: var(--wui-info);
46
- --color-info-50: var(--wui-info-50);
47
- --color-info-30: var(--wui-info-30);
48
- --color-info-20: var(--wui-info-20);
49
- --color-info-10: var(--wui-info-10);
50
- --color-info-5: var(--wui-info-5);
51
- --color-info-strong: var(--color-info-active);
52
- --color-info-soft: var(--color-info-10);
44
+ --color-info-active: var(--wui-info-active);
45
+ --color-info: var(--wui-info);
46
+ --color-info-50: var(--wui-info-50);
47
+ --color-info-30: var(--wui-info-30);
48
+ --color-info-20: var(--wui-info-20);
49
+ --color-info-10: var(--wui-info-10);
50
+ --color-info-5: var(--wui-info-5);
51
+ --color-info-strong: var(--color-info-active);
52
+ --color-info-soft: var(--color-info-10);
53
53
  // Use this — never --color-info — when the colour IS the text.
54
- --color-info-text: var(--wui-info-text);
54
+ --color-info-text: var(--wui-info-text);
55
55
 
56
56
  --color-success-active: var(--wui-success-active);
57
- --color-success: var(--wui-success);
58
- --color-success-50: var(--wui-success-50);
59
- --color-success-30: var(--wui-success-30);
60
- --color-success-20: var(--wui-success-20);
61
- --color-success-10: var(--wui-success-10);
62
- --color-success-5: var(--wui-success-5);
57
+ --color-success: var(--wui-success);
58
+ --color-success-50: var(--wui-success-50);
59
+ --color-success-30: var(--wui-success-30);
60
+ --color-success-20: var(--wui-success-20);
61
+ --color-success-10: var(--wui-success-10);
62
+ --color-success-5: var(--wui-success-5);
63
63
  --color-success-strong: var(--color-success-active);
64
- --color-success-soft: var(--color-success-10);
64
+ --color-success-soft: var(--color-success-10);
65
65
  // Use this — never --color-success — when the colour IS the text.
66
- --color-success-text: var(--wui-success-text);
66
+ --color-success-text: var(--wui-success-text);
67
67
 
68
68
  --color-warning-active: var(--wui-warning-active);
69
- --color-warning: var(--wui-warning);
70
- --color-warning-50: var(--wui-warning-50);
71
- --color-warning-30: var(--wui-warning-30);
72
- --color-warning-20: var(--wui-warning-20);
73
- --color-warning-10: var(--wui-warning-10);
74
- --color-warning-5: var(--wui-warning-5);
69
+ --color-warning: var(--wui-warning);
70
+ --color-warning-50: var(--wui-warning-50);
71
+ --color-warning-30: var(--wui-warning-30);
72
+ --color-warning-20: var(--wui-warning-20);
73
+ --color-warning-10: var(--wui-warning-10);
74
+ --color-warning-5: var(--wui-warning-5);
75
75
  --color-warning-strong: var(--color-warning-active);
76
- --color-warning-soft: var(--color-warning-10);
76
+ --color-warning-soft: var(--color-warning-10);
77
77
  // Use this — never --color-warning — when the colour IS the text.
78
- --color-warning-text: var(--wui-warning-text);
79
-
80
- --color-danger-active: var(--wui-danger-active);
81
- --color-danger: var(--wui-danger);
82
- --color-danger-50: var(--wui-danger-50);
83
- --color-danger-30: var(--wui-danger-30);
84
- --color-danger-20: var(--wui-danger-20);
85
- --color-danger-10: var(--wui-danger-10);
86
- --color-danger-5: var(--wui-danger-5);
87
- --color-danger-strong: var(--color-danger-active);
88
- --color-danger-soft: var(--color-danger-10);
78
+ --color-warning-text: var(--wui-warning-text);
79
+
80
+ --color-danger-active: var(--wui-danger-active);
81
+ --color-danger: var(--wui-danger);
82
+ --color-danger-50: var(--wui-danger-50);
83
+ --color-danger-30: var(--wui-danger-30);
84
+ --color-danger-20: var(--wui-danger-20);
85
+ --color-danger-10: var(--wui-danger-10);
86
+ --color-danger-5: var(--wui-danger-5);
87
+ --color-danger-strong: var(--color-danger-active);
88
+ --color-danger-soft: var(--color-danger-10);
89
89
  // Use this — never --color-danger — when the colour IS the text.
90
- --color-danger-text: var(--wui-danger-text);
90
+ --color-danger-text: var(--wui-danger-text);
91
91
 
92
92
  // Accent → warning ramp
93
- --color-accent: var(--color-warning);
94
- --color-accent-soft: var(--color-warning-soft);
93
+ --color-accent: var(--color-warning);
94
+ --color-accent-soft: var(--color-warning-soft);
95
95
 
96
- // Scrim — media hover overlays (logo uploader)
97
- --color-scrim: color-mix(in srgb, var(--wui-text-heading) 62%, transparent);
98
- --color-on-scrim: var(--wui-bg-light);
96
+ // Scrim — one dim ink, two strengths: scrim for page-level backdrops
97
+ // (drawer, modal, shell), scrim-strong for media overlays carrying white
98
+ // ink (logo uploader, file previews).
99
+ --color-scrim: color-mix(in srgb, var(--wui-text-heading) 45%, transparent);
100
+ --color-scrim-strong: color-mix(in srgb, var(--wui-text-heading) 62%, transparent);
101
+ --color-on-scrim: var(--wui-bg-light);
99
102
 
100
103
  // Elevation — in-page flat; only floating overlays lift (matches zeroed BS
101
- // $box-shadow* utilities and --wui-shadow-card* none — TASK-06080).
104
+ // $box-shadow* utilities and --wui-shadow-card* none).
102
105
  --shadow-sm: none;
103
106
  --shadow-md: none;
104
107
  --shadow-lg: none;
105
- --shadow-overlay: var(--wui-shadow-overlay);
108
+ --shadow-overlay: var(--wui-shadow-overlay);
106
109
  --shadow-overlay-lg: var(--wui-shadow-overlay-lg);
107
110
 
108
111
  // Corner radii
109
112
  --radius-sm: var(--wui-radius-sm);
110
- --radius: var(--wui-radius);
113
+ --radius: var(--wui-radius);
111
114
  --radius-lg: var(--wui-radius-lg);
112
115
  --radius-xl: var(--wui-radius-xl);
113
116
  }
114
117
 
115
118
  :root[data-theme="dark"] {
116
- --color-bg: var(--wui-dark-bg-page);
117
- --color-bg-subtle: var(--wui-dark-bg-elevated);
118
- --color-bg-muted: var(--wui-dark-bg-muted);
119
- --color-surface: var(--wui-dark-bg-surface);
119
+ --color-bg: var(--wui-dark-bg-page);
120
+ --color-bg-subtle: var(--wui-dark-bg-elevated);
121
+ --color-bg-muted: var(--wui-dark-bg-muted);
122
+ --color-surface: var(--wui-dark-bg-surface);
120
123
 
121
- --color-border: var(--wui-dark-border);
124
+ --color-border: var(--wui-dark-border);
125
+ --color-border-light: color-mix(in srgb, var(--wui-dark-border) 50%, transparent);
122
126
  --color-border-strong: var(--wui-dark-border-strong);
123
127
 
124
- --color-text: var(--wui-dark-text);
125
- --color-text-muted: var(--wui-dark-text-muted);
126
- --color-text-subtle: var(--wui-dark-text-subtle);
128
+ --color-text: var(--wui-dark-text);
129
+ --color-text-muted: var(--wui-dark-text-muted);
130
+ --color-text-subtle: var(--wui-dark-text-subtle);
127
131
 
128
132
  // Re-bridge the Bootstrap colour vars onto the (now dark) app tokens so the
129
133
  // named-var text/body/border utilities — .text-body-secondary, .text-muted,
130
134
  // .text-body-emphasis, .border, backgrounds — flip with the theme. Declared
131
135
  // here (not only in :root) so the dark theming is explicit and cannot be lost
132
136
  // to a later-loading consumer rule that scopes --bs-* under [data-theme].
133
- --bs-body-color: var(--color-text);
134
- --bs-emphasis-color: var(--color-text);
135
- --bs-secondary-color: var(--color-text-muted);
136
- --bs-tertiary-color: var(--color-text-subtle);
137
- --bs-body-bg: var(--color-bg);
138
- --bs-border-color: var(--color-border);
139
- --bs-secondary-bg: var(--wui-dark-bg-surface);
140
- --bs-tertiary-bg: var(--wui-dark-bg-muted);
137
+ --bs-body-color: var(--color-text);
138
+ --bs-emphasis-color: var(--color-text);
139
+ --bs-secondary-color: var(--color-text-muted);
140
+ --bs-tertiary-color: var(--color-text-subtle);
141
+ --bs-body-bg: var(--color-bg);
142
+ --bs-border-color: var(--color-border);
143
+ --bs-secondary-bg: var(--wui-dark-bg-surface);
144
+ --bs-tertiary-bg: var(--wui-dark-bg-muted);
141
145
  // Bootstrap's .bg-* / .text-secondary / .bg-body-tertiary utilities read the --bs-*-RGB
142
146
  // triplets (for -opacity support), NOT the plain vars above — without these overrides they
143
147
  // keep their compiled LIGHT triplet in dark mode (a white .bg-body on a dark portal). The
144
148
  // triplets mirror the dark hexes in _tokens.scss (Bootstrap's own --bs-x + --bs-x-rgb pattern).
145
- --bs-body-bg-rgb: 15, 17, 23; // --wui-dark-bg-page #0f1117
146
- --bs-body-color-rgb: 230, 232, 238; // --wui-dark-text #e6e8ee
147
- --bs-emphasis-color-rgb: 230, 232, 238; // --wui-dark-text #e6e8ee
148
- --bs-secondary-color-rgb: 180, 185, 198; // --wui-dark-text-muted #b4b9c6
149
- --bs-tertiary-color-rgb: 138, 144, 160; // --wui-dark-text-subtle #8a90a0
150
- --bs-secondary-bg-rgb: 24, 27, 35; // --wui-dark-bg-surface #181b23
151
- --bs-tertiary-bg-rgb: 35, 39, 51; // --wui-dark-bg-muted #232733
152
- --bs-border-color-rgb: 42, 47, 58; // --wui-dark-border #2a2f3a
153
-
154
- --color-primary: var(--wui-dark-primary);
149
+ --bs-body-bg-rgb: 15, 17, 23; // --wui-dark-bg-page #0f1117
150
+ --bs-body-color-rgb: 230, 232, 238; // --wui-dark-text #e6e8ee
151
+ --bs-emphasis-color-rgb: 230, 232, 238; // --wui-dark-text #e6e8ee
152
+ --bs-secondary-color-rgb: 180, 185, 198; // --wui-dark-text-muted #b4b9c6
153
+ --bs-tertiary-color-rgb: 138, 144, 160; // --wui-dark-text-subtle #8a90a0
154
+ --bs-secondary-bg-rgb: 24, 27, 35; // --wui-dark-bg-surface #181b23
155
+ --bs-tertiary-bg-rgb: 35, 39, 51; // --wui-dark-bg-muted #232733
156
+ --bs-border-color-rgb: 42, 47, 58; // --wui-dark-border #2a2f3a
157
+
158
+ --color-primary: var(--wui-dark-primary);
155
159
  --color-primary-hover: var(--wui-dark-primary-hover);
156
- --color-primary-soft: color-mix(in srgb, var(--wui-primary) 20%, transparent);
160
+ --color-primary-soft: color-mix(in srgb, var(--wui-primary) 20%, transparent);
161
+ // Dark mode primary text: #fff on #6B83EC measures 3.5:1, below WCAG AA (4.5:1).
162
+ // Map to a near-black for safe contrast (7.5:1+) when text sits on primary fill.
163
+ --color-primary-text: #0F0F0F;
157
164
 
158
165
  // On a dark surface the FILL colours are already the readable ones — the darkened
159
166
  // `-text` values would sink into the background. So dark mode maps text back to the
160
167
  // bright tokens rather than inheriting light mode's.
161
- --color-success-text: var(--wui-success);
162
- --color-danger-text: var(--wui-danger);
163
- --color-warning-text: var(--wui-warning);
164
- --color-info-text: var(--wui-info);
165
-
166
- --color-success-soft: color-mix(in srgb, var(--wui-success) 18%, transparent);
167
- --color-warning-soft: color-mix(in srgb, var(--wui-warning) 18%, transparent);
168
- --color-danger-soft: color-mix(in srgb, var(--wui-danger) 18%, transparent);
169
- --color-info-soft: color-mix(in srgb, var(--wui-info) 18%, transparent);
170
- --color-accent-soft: var(--color-warning-soft);
171
-
172
- --color-scrim: color-mix(in srgb, black 62%, transparent);
173
- --color-on-scrim: var(--wui-bg-light);
168
+ --color-success-text: var(--wui-success);
169
+ --color-danger-text: var(--wui-danger);
170
+ --color-warning-text: var(--wui-warning);
171
+ --color-info-text: var(--wui-info);
172
+
173
+ --color-success-soft: color-mix(in srgb, var(--wui-success) 18%, transparent);
174
+ --color-warning-soft: color-mix(in srgb, var(--wui-warning) 18%, transparent);
175
+ --color-danger-soft: color-mix(in srgb, var(--wui-danger) 18%, transparent);
176
+ --color-info-soft: color-mix(in srgb, var(--wui-info) 18%, transparent);
177
+ --color-accent-soft: var(--color-warning-soft);
178
+
179
+ --color-scrim: color-mix(in srgb, black 45%, transparent);
180
+ --color-scrim-strong: color-mix(in srgb, black 62%, transparent);
181
+ --color-on-scrim: var(--wui-bg-light);
174
182
 
175
183
  color-scheme: dark;
176
184
  }