@webority/theme 0.7.4 → 0.7.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.
@@ -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,169 @@
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
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);
97
+ --color-scrim: color-mix(in srgb, var(--wui-text-heading) 62%, transparent);
98
+ --color-on-scrim: var(--wui-bg-light);
99
99
 
100
100
  // Elevation — in-page flat; only floating overlays lift (matches zeroed BS
101
- // $box-shadow* utilities and --wui-shadow-card* none — TASK-06080).
101
+ // $box-shadow* utilities and --wui-shadow-card* none).
102
102
  --shadow-sm: none;
103
103
  --shadow-md: none;
104
104
  --shadow-lg: none;
105
- --shadow-overlay: var(--wui-shadow-overlay);
105
+ --shadow-overlay: var(--wui-shadow-overlay);
106
106
  --shadow-overlay-lg: var(--wui-shadow-overlay-lg);
107
107
 
108
108
  // Corner radii
109
109
  --radius-sm: var(--wui-radius-sm);
110
- --radius: var(--wui-radius);
110
+ --radius: var(--wui-radius);
111
111
  --radius-lg: var(--wui-radius-lg);
112
112
  --radius-xl: var(--wui-radius-xl);
113
113
  }
114
114
 
115
115
  :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);
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);
120
120
 
121
- --color-border: var(--wui-dark-border);
121
+ --color-border: var(--wui-dark-border);
122
122
  --color-border-strong: var(--wui-dark-border-strong);
123
123
 
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);
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);
127
127
 
128
128
  // Re-bridge the Bootstrap colour vars onto the (now dark) app tokens so the
129
129
  // named-var text/body/border utilities — .text-body-secondary, .text-muted,
130
130
  // .text-body-emphasis, .border, backgrounds — flip with the theme. Declared
131
131
  // here (not only in :root) so the dark theming is explicit and cannot be lost
132
132
  // 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);
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);
141
141
  // Bootstrap's .bg-* / .text-secondary / .bg-body-tertiary utilities read the --bs-*-RGB
142
142
  // triplets (for -opacity support), NOT the plain vars above — without these overrides they
143
143
  // keep their compiled LIGHT triplet in dark mode (a white .bg-body on a dark portal). The
144
144
  // 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);
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);
155
155
  --color-primary-hover: var(--wui-dark-primary-hover);
156
- --color-primary-soft: color-mix(in srgb, var(--wui-primary) 20%, transparent);
156
+ --color-primary-soft: color-mix(in srgb, var(--wui-primary) 20%, transparent);
157
157
 
158
158
  // On a dark surface the FILL colours are already the readable ones — the darkened
159
159
  // `-text` values would sink into the background. So dark mode maps text back to the
160
160
  // 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);
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);
174
174
 
175
175
  color-scheme: dark;
176
176
  }
@@ -10,11 +10,11 @@
10
10
  // Bootstrap `.form-check` + `.form-check-input` are the public selection skin
11
11
  // (AppCheckbox / AppRadio / AppSwitch). `.wui-check` / `.wui-radio` are aliases
12
12
  // for the same glyph (AppDataTable select column + legacy `.wui-control`
13
- // markup) — never a second look (TASK-06077). One 20px brand glyph language.
13
+ // markup) — never a second look. One 20px brand glyph language.
14
14
  //
15
15
  // Layout wrappers:
16
- // .form-check / .form-check-label — App* path
17
- // .wui-control / .wui-control-label — optional compact label wrap (alias)
16
+ // .form-check / .form-check-label — App* path
17
+ // .wui-control / .wui-control-label — optional compact label wrap (alias)
18
18
 
19
19
  .form-check,
20
20
  .wui-control {
@@ -141,7 +141,7 @@
141
141
  }
142
142
 
143
143
  // Compact row-select — ONLY inside the select column (AppDataTable / Razor
144
- // data-table → `.wui-select-cell`). Scope is load-bearing (BUG-06678).
144
+ // data-table → `.wui-select-cell`). Scope is load-bearing.
145
145
  .wui-select-cell .wui-check,
146
146
  .wui-select-cell .form-check-input {
147
147
  width: 16px;
@@ -187,7 +187,7 @@
187
187
  // ── Field / Input ──
188
188
  // Bootstrap `.form-control` / `.form-select` are the field skin. `.input` /
189
189
  // `.select` / `.textarea` are aliases (and App* size/shell hooks) that MUST
190
- // share the same chrome — never a second look (TASK-06079). The only WUI
190
+ // share the same chrome — never a second look. The only WUI
191
191
  // deltas on top of Bootstrap's $input-* vars: shared control height, hover
192
192
  // fill, brand-border focus (no glow), soft invalid border.
193
193
  //
@@ -598,7 +598,7 @@ textarea.form-control.autosize {
598
598
  }
599
599
  @keyframes wui-clear-in {
600
600
  from { opacity: 0; transform: translateY(-50%) scale(0.72); }
601
- to { opacity: 1; transform: translateY(-50%) scale(1); }
601
+ to { opacity: 1; transform: translateY(-50%) scale(1); }
602
602
  }
603
603
 
604
604
  // Prefix / suffix addon — a bordered box before/after the input (₹, https://, .com). The
@@ -959,8 +959,8 @@ wui-select[compact] {
959
959
  //
960
960
  // Two other vocabularies existed and are accepted as DEPRECATED ALIASES so a
961
961
  // consumer can migrate without a flag day:
962
- // - colour-named .tone-green / -amber / -red / -blue / -grey (was the library's)
963
- // - short semantic .tone-ok / -warn / -bad (a short-semantic set)
962
+ // - colour-named .tone-green / -amber / -red / -blue / -grey (was the library's)
963
+ // - short semantic .tone-ok / -warn / -bad (a short-semantic set)
964
964
  // Author new markup with the semantic names; the aliases will be removed.
965
965
  .status-label.success,
966
966
  .status-label.tone-ok,
@@ -549,3 +549,30 @@
549
549
  cursor: not-allowed;
550
550
  opacity: 0.6;
551
551
  }
552
+
553
+ // Breadcrumbs — Bootstrap's .breadcrumb with brand tokens (AppBreadcrumbs / <app-breadcrumbs>).
554
+ // The divider is a CSS ::before glyph, so React (react-bootstrap Breadcrumb) and Razor share it.
555
+ .breadcrumb {
556
+ --bs-breadcrumb-divider: "›";
557
+ --bs-breadcrumb-divider-color: var(--color-text-subtle);
558
+ margin-bottom: 0;
559
+ font-size: 13px;
560
+ }
561
+ .breadcrumb-item a {
562
+ display: inline-flex;
563
+ align-items: center;
564
+ gap: 4px;
565
+ color: var(--color-text-muted);
566
+ text-decoration: none;
567
+ }
568
+ .breadcrumb-item a:hover {
569
+ color: var(--color-primary);
570
+ text-decoration: underline;
571
+ }
572
+ .breadcrumb-item.active {
573
+ display: inline-flex;
574
+ align-items: center;
575
+ gap: 4px;
576
+ color: var(--color-text);
577
+ font-weight: 500;
578
+ }