@webority/theme 0.8.7 → 0.8.9
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/dist/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/wui/_choice.scss +17 -1
- package/scss/wui/_controls.scss +7 -2
- package/scss/wui/_media.scss +4 -1
- package/scss/wui/_navigation.scss +29 -11
- package/scss/wui/_overlays.scss +16 -8
- package/scss/wui/_shell.scss +8 -4
- package/scss/wui/_typography.scss +81 -0
- package/scss/wui/_workspace.scss +94 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/theme",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.9",
|
|
4
4
|
"description": "Webority shared design system — Bootstrap 5.3 SCSS overrides, --wui-* tokens, and shared component CSS. The single source of brand chrome for React portals and Razor sites.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"publishConfig": {
|
package/scss/wui/_choice.scss
CHANGED
|
@@ -920,10 +920,26 @@ button.datepicker-month:hover {
|
|
|
920
920
|
cursor: not-allowed;
|
|
921
921
|
}
|
|
922
922
|
.app-phone-number-input .phone-input-wrap:has(.input.error),
|
|
923
|
-
.app-phone-number-input .phone-input-wrap:has(.input.is-invalid)
|
|
923
|
+
.app-phone-number-input .phone-input-wrap:has(.input.is-invalid),
|
|
924
|
+
// An explicit `error` prop sets aria-invalid on the host <wui-phone> (React + Razor); redden the
|
|
925
|
+
// shell for it too, not just the internal live-validation state above.
|
|
926
|
+
.app-phone-number-input wui-phone[aria-invalid="true"] .phone-input-wrap {
|
|
924
927
|
// Match AppInput's soft invalid border exactly (danger at 30%, mirroring primary-30 focus).
|
|
925
928
|
border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
|
|
926
929
|
}
|
|
930
|
+
// Popover-field controls (date / date-range / time) carry aria-invalid on the HOST element —
|
|
931
|
+
// React/Razor set it from the `error` prop — while the visible border lives on the inner trigger
|
|
932
|
+
// button. Redden that trigger, and keep it red while the popover is open (mirroring AppInput,
|
|
933
|
+
// whose invalid border persists through focus), so an errored/required field reads red like the
|
|
934
|
+
// plain field and the phone control.
|
|
935
|
+
wui-datepicker[aria-invalid="true"] .datepicker-trigger,
|
|
936
|
+
wui-datepicker[aria-invalid="true"] .datepicker.open .datepicker-trigger,
|
|
937
|
+
wui-date-range[aria-invalid="true"] .daterange-trigger,
|
|
938
|
+
wui-date-range[aria-invalid="true"] .daterange.open .daterange-trigger,
|
|
939
|
+
wui-timepicker[aria-invalid="true"] .timepicker-trigger,
|
|
940
|
+
wui-timepicker[aria-invalid="true"] .timepicker.open .timepicker-trigger {
|
|
941
|
+
border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
|
|
942
|
+
}
|
|
927
943
|
// The inner control drops its own chrome — the shell carries it.
|
|
928
944
|
.app-phone-number-input .phone-input-wrap > .input,
|
|
929
945
|
.app-phone-number-input .phone-input-wrap > .input:hover,
|
package/scss/wui/_controls.scss
CHANGED
|
@@ -1060,8 +1060,13 @@ wui-select[compact] {
|
|
|
1060
1060
|
background: var(--color-surface);
|
|
1061
1061
|
border-color: var(--wui-primary-30);
|
|
1062
1062
|
}
|
|
1063
|
-
.num-wrap:has(.num-input.error)
|
|
1064
|
-
|
|
1063
|
+
.num-wrap:has(.num-input.error),
|
|
1064
|
+
.num-wrap:has(.num-input.is-invalid),
|
|
1065
|
+
.num-wrap:has(.num-input[aria-invalid="true"]) {
|
|
1066
|
+
// Soft invalid border — match AppInput / AppPhoneNumberInput exactly (danger at 30%,
|
|
1067
|
+
// mirroring the primary-30 focus border), not the solid full-strength danger this used to
|
|
1068
|
+
// carry, so every field's error border reads the same light red.
|
|
1069
|
+
border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
|
|
1065
1070
|
}
|
|
1066
1071
|
|
|
1067
1072
|
// Numeric input inside the stepper — plain text field, no native spinner.
|
package/scss/wui/_media.scss
CHANGED
|
@@ -512,7 +512,10 @@
|
|
|
512
512
|
}
|
|
513
513
|
.attach-item-remove:hover {
|
|
514
514
|
border-color: var(--color-danger);
|
|
515
|
-
|
|
515
|
+
// The glyph is graphical (icon-only button, 3:1) so the brand hue would technically pass
|
|
516
|
+
// at 3.36:1 — but "tint background ⇒ -text foreground" is worth keeping exceptionless, so
|
|
517
|
+
// check-contrast can enforce it by inspection instead of case-by-case judgement.
|
|
518
|
+
color: var(--color-danger-text);
|
|
516
519
|
background: var(--color-danger-soft);
|
|
517
520
|
}
|
|
518
521
|
|
|
@@ -208,16 +208,30 @@
|
|
|
208
208
|
}
|
|
209
209
|
.app-tab.active {
|
|
210
210
|
color: var(--color-primary);
|
|
211
|
-
// Static fallback underline (no-JS / first paint); the ink bar takes over once wired.
|
|
212
|
-
border-bottom-color: var(--color-primary);
|
|
213
211
|
// The active tab carries weight as well as colour — colour alone is a weak
|
|
214
212
|
// signal for anyone who reads the strip at a glance or cannot distinguish it.
|
|
215
213
|
font-weight: 600;
|
|
216
214
|
}
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
|
|
215
|
+
// Static fallback underline (no-JS / first paint); the sliding ink bar takes over once
|
|
216
|
+
// wired. Inset 10px (tab padding is 14px) so the bar runs the label width + 4px each side
|
|
217
|
+
// — reads as belonging to the label yet never touches a rounded container edge. Matches
|
|
218
|
+
// the wired ink bar's inset below.
|
|
219
|
+
.app-tab.active::after {
|
|
220
|
+
content: "";
|
|
221
|
+
position: absolute;
|
|
222
|
+
left: var(--wui-tab-underline-inset, 10px);
|
|
223
|
+
right: var(--wui-tab-underline-inset, 10px);
|
|
224
|
+
bottom: -1px;
|
|
225
|
+
height: 2px;
|
|
226
|
+
border-radius: 2px;
|
|
227
|
+
background: var(--color-primary);
|
|
228
|
+
}
|
|
229
|
+
// Once JS wires the ink bar it owns the underline; pills fill and vertical use a side
|
|
230
|
+
// rail — none of them want the bottom fallback. Drop it so nothing doubles up.
|
|
231
|
+
.app-tabs[data-wui-tabs] .app-tab.active::after,
|
|
232
|
+
.app-tabs-pills .app-tab.active::after,
|
|
233
|
+
.app-tabs-vertical .app-tab.active::after {
|
|
234
|
+
display: none;
|
|
221
235
|
}
|
|
222
236
|
.app-tab:disabled {
|
|
223
237
|
color: var(--color-text-subtle);
|
|
@@ -237,10 +251,9 @@
|
|
|
237
251
|
}
|
|
238
252
|
.app-tab.danger.active {
|
|
239
253
|
color: var(--color-danger-text);
|
|
240
|
-
border-bottom-color: var(--color-danger);
|
|
241
254
|
}
|
|
242
|
-
.app-
|
|
243
|
-
|
|
255
|
+
.app-tab.danger.active::after {
|
|
256
|
+
background: var(--color-danger);
|
|
244
257
|
}
|
|
245
258
|
.app-tab.danger .app-tab-count {
|
|
246
259
|
background: var(--color-danger-soft);
|
|
@@ -255,10 +268,13 @@
|
|
|
255
268
|
left: 0;
|
|
256
269
|
bottom: -1px;
|
|
257
270
|
height: 2px;
|
|
258
|
-
|
|
271
|
+
// Inset 10px each side (tab padding is 14px) so the bar runs the label width + 4px per
|
|
272
|
+
// side — clear of a rounded container edge; falls to 0 rather than going negative on a
|
|
273
|
+
// tab narrower than the inset. Pills reset the inset to 0 (the pill fills the tab).
|
|
274
|
+
width: max(0px, calc(var(--wui-tab-w, 0) - var(--wui-tab-underline-inset, 10px) * 2));
|
|
259
275
|
background: var(--color-primary);
|
|
260
276
|
border-radius: 2px;
|
|
261
|
-
transform: translateX(var(--wui-tab-x, 0));
|
|
277
|
+
transform: translateX(calc(var(--wui-tab-x, 0) + var(--wui-tab-underline-inset, 10px)));
|
|
262
278
|
opacity: 0;
|
|
263
279
|
pointer-events: none;
|
|
264
280
|
transition:
|
|
@@ -365,6 +381,8 @@
|
|
|
365
381
|
bottom: 0;
|
|
366
382
|
height: auto;
|
|
367
383
|
z-index: 0;
|
|
384
|
+
// The pill fills the whole tab — no underline inset.
|
|
385
|
+
--wui-tab-underline-inset: 0px;
|
|
368
386
|
background: var(--color-primary-soft);
|
|
369
387
|
border-radius: var(--radius);
|
|
370
388
|
}
|
package/scss/wui/_overlays.scss
CHANGED
|
@@ -15,15 +15,23 @@
|
|
|
15
15
|
// Do NOT put layout on backdropClassName — that targets a sibling, not
|
|
16
16
|
// .modal.
|
|
17
17
|
.modal-backdrop.wui-modal-dim {
|
|
18
|
-
// Frost the page behind the dialog — the blur is the star, so the dim is kept
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
18
|
+
// Frost the page behind the dialog — the blur is the star, so the dim is kept SOFT (a heavy
|
|
19
|
+
// scrim would flatten the blur into a muddy grey). A moderate dim over a STRONG blur reads as
|
|
20
|
+
// clean frosted glass; the modal is still clearly the one live surface. The dialog sits in
|
|
21
|
+
// `.modal` (a higher z-index sibling), so it is never blurred.
|
|
22
|
+
//
|
|
23
|
+
// Full strength is load-bearing: Bootstrap composites the whole backdrop element at
|
|
24
|
+
// `--bs-backdrop-opacity` (0.5 by default), which HALVES both the blur and the dim into a
|
|
25
|
+
// weak, patchy wash — the bug this fixes. Pin the opacity to 1 and carry the dim entirely in
|
|
26
|
+
// `background`, so the frost renders at its true strength. (The fade-in still animates 0 → 1.)
|
|
27
|
+
--bs-backdrop-opacity: 1;
|
|
28
|
+
opacity: 1;
|
|
29
|
+
background: color-mix(in srgb, var(--color-scrim) 85%, transparent);
|
|
24
30
|
z-index: var(--wui-z-modal-backdrop);
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
// A little saturation boost is what makes the frost read as glass rather than fog — the
|
|
32
|
+
// colours behind bloom softly through the blur instead of greying out.
|
|
33
|
+
backdrop-filter: blur(12px) saturate(1.4);
|
|
34
|
+
-webkit-backdrop-filter: blur(12px) saturate(1.4);
|
|
27
35
|
}
|
|
28
36
|
.modal.wui-modal-shell {
|
|
29
37
|
--bs-modal-bg: transparent;
|
package/scss/wui/_shell.scss
CHANGED
|
@@ -421,18 +421,22 @@
|
|
|
421
421
|
}
|
|
422
422
|
|
|
423
423
|
// ── Badge tones ──────────────────────────────────────────────────────────────
|
|
424
|
-
// A nav badge can carry a status tone so an alert count reads red, not neutral.
|
|
424
|
+
// A nav badge can carry a status tone so an alert count reads red, not neutral. The COUNT is
|
|
425
|
+
// text on a tint, so it takes the -text token, not the brand fill hue: the base hues are sized
|
|
426
|
+
// for fills and icons (3:1) and every one of them missed the 4.5:1 text floor against its own
|
|
427
|
+
// tint — danger 3.36:1, info 3.23:1, success 2.09:1, warning 1.77:1 (amber on cream, all but
|
|
428
|
+
// illegible). The a11y sweep never saw these because the catalogue renders no toned nav badge.
|
|
425
429
|
.app-nav-badge.tone-danger {
|
|
426
430
|
background: var(--color-danger-soft);
|
|
427
|
-
color: var(--color-danger);
|
|
431
|
+
color: var(--color-danger-text);
|
|
428
432
|
}
|
|
429
433
|
.app-nav-badge.tone-success {
|
|
430
434
|
background: var(--color-success-soft);
|
|
431
|
-
color: var(--color-success);
|
|
435
|
+
color: var(--color-success-text);
|
|
432
436
|
}
|
|
433
437
|
.app-nav-badge.tone-warning {
|
|
434
438
|
background: var(--color-warning-soft);
|
|
435
|
-
color: var(--color-warning);
|
|
439
|
+
color: var(--color-warning-text);
|
|
436
440
|
}
|
|
437
441
|
// The existing `.app-nav-item.active .app-nav-badge` inverts a tinted badge on an
|
|
438
442
|
// active row (higher specificity), so an active row's badge stays legible.
|
|
@@ -165,6 +165,87 @@
|
|
|
165
165
|
color: currentColor;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
// ── Variants ──────────────────────────────────────────────────────────────
|
|
169
|
+
// The base `.chip` above is the SOFT variant (tinted surface, on-tint text, no
|
|
170
|
+
// visible border) — the default, unchanged. `.chip-outline` and
|
|
171
|
+
// `.chip-solid` layer on top and MUST stay after the tone block so a
|
|
172
|
+
// `.chip-solid.primary` (0,2,0) wins over `.chip.primary` (0,2,0) on source
|
|
173
|
+
// order. The disabled block below still wins because it comes after both.
|
|
174
|
+
|
|
175
|
+
// Outline — the soft tint kept, but the transparent border swapped for the
|
|
176
|
+
// tone's own colour (a crisper, bounded chip). Only the border changes for a
|
|
177
|
+
// toned chip; neutral drops the muted fill for a clean outlined pill.
|
|
178
|
+
.chip-outline {
|
|
179
|
+
background: transparent;
|
|
180
|
+
border-color: var(--color-border-strong);
|
|
181
|
+
}
|
|
182
|
+
.chip-outline.primary {
|
|
183
|
+
border-color: var(--color-primary);
|
|
184
|
+
}
|
|
185
|
+
.chip-outline.success {
|
|
186
|
+
border-color: var(--color-success);
|
|
187
|
+
}
|
|
188
|
+
.chip-outline.warning {
|
|
189
|
+
border-color: var(--color-warning);
|
|
190
|
+
}
|
|
191
|
+
.chip-outline.danger {
|
|
192
|
+
border-color: var(--color-danger);
|
|
193
|
+
}
|
|
194
|
+
.chip-outline.info {
|
|
195
|
+
border-color: var(--color-info);
|
|
196
|
+
}
|
|
197
|
+
.chip-outline.chip-clickable:hover {
|
|
198
|
+
border-color: var(--color-border-strong);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Solid — a filled pill carrying white text (near-black on the light-primary in
|
|
202
|
+
// dark mode, via --color-primary-text). The fills are the deep, white-safe
|
|
203
|
+
// tokens: --wui-*-strong / --color-primary are AA with white; info & warning
|
|
204
|
+
// have no ready deep token, so they are mixed toward black until white clears
|
|
205
|
+
// AA (warning-with-white only passes on a dark gold — the vibrant --wui-warning
|
|
206
|
+
// cannot). These raw --wui-* deep values are mode-independent, so no dark block
|
|
207
|
+
// is needed; neutral flips automatically because text↔surface swap by theme.
|
|
208
|
+
.chip-solid {
|
|
209
|
+
background: var(--color-text);
|
|
210
|
+
color: var(--color-surface);
|
|
211
|
+
border-color: transparent;
|
|
212
|
+
}
|
|
213
|
+
.chip-solid.primary {
|
|
214
|
+
background: var(--color-primary);
|
|
215
|
+
color: var(--color-primary-text);
|
|
216
|
+
border-color: transparent;
|
|
217
|
+
}
|
|
218
|
+
.chip-solid.success {
|
|
219
|
+
background: var(--wui-success-strong);
|
|
220
|
+
color: var(--color-on-scrim);
|
|
221
|
+
border-color: transparent;
|
|
222
|
+
}
|
|
223
|
+
.chip-solid.danger {
|
|
224
|
+
background: var(--wui-danger-strong);
|
|
225
|
+
color: var(--color-on-scrim);
|
|
226
|
+
border-color: transparent;
|
|
227
|
+
}
|
|
228
|
+
.chip-solid.info {
|
|
229
|
+
background: color-mix(in srgb, var(--wui-info) 78%, #000);
|
|
230
|
+
color: var(--color-on-scrim);
|
|
231
|
+
border-color: transparent;
|
|
232
|
+
}
|
|
233
|
+
.chip-solid.warning {
|
|
234
|
+
background: color-mix(in srgb, var(--wui-warning) 54%, #000);
|
|
235
|
+
color: var(--color-on-scrim);
|
|
236
|
+
border-color: transparent;
|
|
237
|
+
}
|
|
238
|
+
// The leading glyph and dismiss ✕ ride the label colour on a solid fill so they
|
|
239
|
+
// stay legible (the default --color-text-subtle would sink into a dark fill).
|
|
240
|
+
.chip-solid .chip-ic,
|
|
241
|
+
.chip-solid .chip-remove {
|
|
242
|
+
color: currentColor;
|
|
243
|
+
}
|
|
244
|
+
.chip-solid .chip-remove:hover {
|
|
245
|
+
background: color-mix(in srgb, currentColor 22%, transparent);
|
|
246
|
+
color: currentColor;
|
|
247
|
+
}
|
|
248
|
+
|
|
168
249
|
// Disabled — deliberately NOT opacity, and deliberately after the tones.
|
|
169
250
|
//
|
|
170
251
|
// `opacity: .55` fades the whole chip, which scales the LABEL's contrast down with it:
|
package/scss/wui/_workspace.scss
CHANGED
|
@@ -95,9 +95,9 @@
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
// ── Size tiers ──
|
|
98
|
-
// md is the base above. sm/lg scale the TRIGGER
|
|
99
|
-
//
|
|
100
|
-
//
|
|
98
|
+
// md is the base above. sm/lg scale the TRIGGER (the card / compact square, its mark, its name)
|
|
99
|
+
// AND the dropdown menu (width, row padding, avatar, the "+" chip and the footer), so the whole
|
|
100
|
+
// switcher — trigger and panel — reads at one size.
|
|
101
101
|
.workspace-switcher-sm .workspace-switcher-trigger {
|
|
102
102
|
min-height: 40px;
|
|
103
103
|
padding: 4px 8px;
|
|
@@ -139,9 +139,9 @@
|
|
|
139
139
|
|
|
140
140
|
// ── Menu ──
|
|
141
141
|
.workspace-switcher .workspace-switcher-menu {
|
|
142
|
-
width:
|
|
143
|
-
max-width:
|
|
144
|
-
padding:
|
|
142
|
+
width: 300px;
|
|
143
|
+
max-width: 300px;
|
|
144
|
+
padding: 5px;
|
|
145
145
|
background: var(--color-surface);
|
|
146
146
|
border: 1px solid var(--color-border-light);
|
|
147
147
|
border-radius: var(--radius-lg);
|
|
@@ -193,23 +193,25 @@
|
|
|
193
193
|
.workspace-switcher .workspace-switcher-create {
|
|
194
194
|
display: flex;
|
|
195
195
|
align-items: center;
|
|
196
|
-
gap:
|
|
196
|
+
gap: 10px;
|
|
197
197
|
width: 100%;
|
|
198
|
-
padding:
|
|
198
|
+
padding: 6px 10px;
|
|
199
199
|
border: none;
|
|
200
200
|
border-radius: var(--radius-lg);
|
|
201
201
|
corner-shape: squircle;
|
|
202
202
|
background: transparent;
|
|
203
203
|
color: var(--color-text);
|
|
204
|
-
font-size:
|
|
204
|
+
font-size: 13px;
|
|
205
|
+
font-weight: 500;
|
|
205
206
|
text-align: left;
|
|
206
207
|
text-decoration: none;
|
|
207
208
|
cursor: pointer;
|
|
208
209
|
}
|
|
209
|
-
//
|
|
210
|
+
// Compact menu avatars — small identity chips, close to the trigger mark.
|
|
210
211
|
.workspace-switcher .workspace-switcher-option .workspace-switcher-mark {
|
|
211
|
-
width:
|
|
212
|
-
height:
|
|
212
|
+
width: 28px;
|
|
213
|
+
height: 28px;
|
|
214
|
+
font-size: 11px;
|
|
213
215
|
}
|
|
214
216
|
.workspace-switcher .workspace-switcher-option:hover,
|
|
215
217
|
.workspace-switcher .workspace-switcher-create:hover {
|
|
@@ -244,9 +246,10 @@
|
|
|
244
246
|
font-size: 11px;
|
|
245
247
|
font-weight: 600;
|
|
246
248
|
}
|
|
249
|
+
// Active state reads from the tint + accent name (per the design); the check tick is dropped
|
|
250
|
+
// so the row stays a clean avatar + name, not a text line with a trailing glyph.
|
|
247
251
|
.workspace-switcher-tick {
|
|
248
|
-
|
|
249
|
-
color: var(--color-primary);
|
|
252
|
+
display: none;
|
|
250
253
|
}
|
|
251
254
|
.workspace-switcher-empty {
|
|
252
255
|
padding: 14px 10px;
|
|
@@ -255,17 +258,29 @@
|
|
|
255
258
|
color: var(--color-text-muted);
|
|
256
259
|
}
|
|
257
260
|
.workspace-switcher .workspace-switcher-create {
|
|
261
|
+
position: relative;
|
|
258
262
|
justify-content: center;
|
|
263
|
+
margin-top: 10px;
|
|
259
264
|
color: var(--color-primary);
|
|
260
265
|
font-weight: 600;
|
|
261
266
|
}
|
|
267
|
+
// Dashed divider above the create row — the list and the "Add …" action read as two zones,
|
|
268
|
+
// matching the design. A ::before (not a border) keeps the row's hover pill radius intact.
|
|
269
|
+
.workspace-switcher .workspace-switcher-create::before {
|
|
270
|
+
content: "";
|
|
271
|
+
position: absolute;
|
|
272
|
+
top: -5px;
|
|
273
|
+
left: 4px;
|
|
274
|
+
right: 4px;
|
|
275
|
+
border-top: 1px dashed var(--color-border);
|
|
276
|
+
}
|
|
262
277
|
// The create / add rows lead with a round soft-tint "+" chip and centre their accent label,
|
|
263
278
|
// matching the design's "Add Business" action.
|
|
264
279
|
.workspace-switcher .workspace-switcher-create .wui-icon,
|
|
265
280
|
.workspace-switcher .workspace-switcher-footer-action .wui-icon {
|
|
266
281
|
box-sizing: border-box;
|
|
267
|
-
width:
|
|
268
|
-
height:
|
|
282
|
+
width: 26px;
|
|
283
|
+
height: 26px;
|
|
269
284
|
padding: 6px;
|
|
270
285
|
border-radius: 50%;
|
|
271
286
|
background: var(--color-primary-soft);
|
|
@@ -276,8 +291,8 @@
|
|
|
276
291
|
// A single workspace still gets a menu: current row + this footer. The divider is what makes
|
|
277
292
|
// that read as a complete panel rather than a truncated list.
|
|
278
293
|
.workspace-switcher-footer {
|
|
279
|
-
margin-top:
|
|
280
|
-
padding-top:
|
|
294
|
+
margin-top: 8px;
|
|
295
|
+
padding-top: 10px;
|
|
281
296
|
border-top: 1px dashed var(--color-border);
|
|
282
297
|
}
|
|
283
298
|
.workspace-switcher .workspace-switcher-footer-action {
|
|
@@ -286,13 +301,13 @@
|
|
|
286
301
|
justify-content: center;
|
|
287
302
|
gap: 10px;
|
|
288
303
|
width: 100%;
|
|
289
|
-
padding:
|
|
304
|
+
padding: 6px 10px;
|
|
290
305
|
border: none;
|
|
291
306
|
border-radius: var(--radius-lg);
|
|
292
307
|
corner-shape: squircle;
|
|
293
308
|
background: transparent;
|
|
294
309
|
color: var(--color-primary);
|
|
295
|
-
font-size:
|
|
310
|
+
font-size: 13px;
|
|
296
311
|
font-weight: 600;
|
|
297
312
|
text-align: left;
|
|
298
313
|
text-decoration: none;
|
|
@@ -303,6 +318,65 @@
|
|
|
303
318
|
color: var(--color-primary);
|
|
304
319
|
}
|
|
305
320
|
|
|
321
|
+
// ── Menu size tiers ── the panel scales with the trigger's `size`. Placed AFTER the base Menu
|
|
322
|
+
// rules above so they win on source order (equal specificity). sm tightens the width, rows,
|
|
323
|
+
// avatar, "+" chip and footer; lg opens them up. The dropdown is a descendant of the size-classed
|
|
324
|
+
// root, so `.workspace-switcher-sm/-lg <menu-part>` reaches every row.
|
|
325
|
+
.workspace-switcher-sm .workspace-switcher-menu {
|
|
326
|
+
width: 240px;
|
|
327
|
+
max-width: 240px;
|
|
328
|
+
padding: 5px;
|
|
329
|
+
}
|
|
330
|
+
.workspace-switcher-sm .workspace-switcher-option,
|
|
331
|
+
.workspace-switcher-sm .workspace-switcher-create {
|
|
332
|
+
gap: 9px;
|
|
333
|
+
padding: 5px 9px;
|
|
334
|
+
font-size: 12px;
|
|
335
|
+
}
|
|
336
|
+
.workspace-switcher-sm .workspace-switcher-option .workspace-switcher-mark {
|
|
337
|
+
width: 24px;
|
|
338
|
+
height: 24px;
|
|
339
|
+
font-size: 10px;
|
|
340
|
+
}
|
|
341
|
+
.workspace-switcher-sm .workspace-switcher-create .wui-icon,
|
|
342
|
+
.workspace-switcher-sm .workspace-switcher-footer-action .wui-icon {
|
|
343
|
+
width: 22px;
|
|
344
|
+
height: 22px;
|
|
345
|
+
padding: 5px;
|
|
346
|
+
}
|
|
347
|
+
.workspace-switcher-sm .workspace-switcher-footer-action {
|
|
348
|
+
gap: 9px;
|
|
349
|
+
padding: 5px 10px;
|
|
350
|
+
font-size: 12px;
|
|
351
|
+
}
|
|
352
|
+
.workspace-switcher-lg .workspace-switcher-menu {
|
|
353
|
+
width: 300px;
|
|
354
|
+
max-width: 300px;
|
|
355
|
+
padding: 4px;
|
|
356
|
+
}
|
|
357
|
+
.workspace-switcher-lg .workspace-switcher-option,
|
|
358
|
+
.workspace-switcher-lg .workspace-switcher-create {
|
|
359
|
+
gap: 12px;
|
|
360
|
+
padding: 8px 12px;
|
|
361
|
+
font-size: 14px;
|
|
362
|
+
}
|
|
363
|
+
.workspace-switcher-lg .workspace-switcher-option .workspace-switcher-mark {
|
|
364
|
+
width: 34px;
|
|
365
|
+
height: 34px;
|
|
366
|
+
font-size: 13px;
|
|
367
|
+
}
|
|
368
|
+
.workspace-switcher-lg .workspace-switcher-create .wui-icon,
|
|
369
|
+
.workspace-switcher-lg .workspace-switcher-footer-action .wui-icon {
|
|
370
|
+
width: 30px;
|
|
371
|
+
height: 30px;
|
|
372
|
+
padding: 7px;
|
|
373
|
+
}
|
|
374
|
+
.workspace-switcher-lg .workspace-switcher-footer-action {
|
|
375
|
+
gap: 12px;
|
|
376
|
+
padding: 8px 12px;
|
|
377
|
+
font-size: 14px;
|
|
378
|
+
}
|
|
379
|
+
|
|
306
380
|
@media (prefers-reduced-motion: reduce) {
|
|
307
381
|
.workspace-switcher-trigger {
|
|
308
382
|
transition: none;
|