@webority/theme 0.7.9 → 0.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority/theme",
3
- "version": "0.7.9",
3
+ "version": "0.8.0",
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": {
@@ -58,3 +58,7 @@
58
58
  // an accident.
59
59
  @import "flags";
60
60
  @import "wui/shell";
61
+ @import "wui/dock";
62
+ @import "wui/toolbar";
63
+ // Last: restates the settled state of menus other partials style, so it must win.
64
+ @import "wui/menu-motion";
@@ -7,6 +7,23 @@
7
7
  // Part of the wui-components layer — see _wui-components.scss for the load
8
8
  // order. Order within the layer is LOAD-BEARING; never reorder the imports.
9
9
 
10
+ // Default (md) card inset — a uniform 20px on the header, body and footer, driven by one
11
+ // friendly token. A consumer class can retune the padding by setting --wui-card-pad (e.g.
12
+ // `.tight-card { --wui-card-pad: 12px }` with `className`/`class` on the card) without
13
+ // overriding a selector. The padding-scale classes (.card-compact, .card-pad-*) still win —
14
+ // they set `padding` directly on the header/body/footer.
15
+ .card {
16
+ --wui-card-pad: 20px;
17
+ --bs-card-spacer-y: var(--wui-card-pad);
18
+ --bs-card-spacer-x: var(--wui-card-pad);
19
+ --bs-card-cap-padding-y: var(--wui-card-pad);
20
+ --bs-card-cap-padding-x: var(--wui-card-pad);
21
+ // Default card is borderless — a flat surface. The border-STYLE stays solid (Bootstrap's
22
+ // `border: var(--bs-card-border-width) solid …`), so a variant or a consumer class can
23
+ // bring the edge back just by giving it a width (set --bs-card-border-width).
24
+ --bs-card-border-width: 0;
25
+ }
26
+
10
27
  // A card header that carries a title on the left and controls on the right — the
11
28
  // pattern nearly every panel header uses, so it belongs here rather than being
12
29
  // re-flexed with utilities on each one.
@@ -40,8 +57,10 @@
40
57
  // ── Variants ──────────────────────────────────────────────────────────────────
41
58
  // `default` is the flat surface above. The rest are opt-in visual treatments,
42
59
  // chosen by the `variant` prop (React) / attribute (Razor).
43
- // Flat elevation: no in-page drop shadow — stronger border is the edge cue.
60
+ // Flat elevation: no in-page drop shadow — stronger border is the edge cue. The default card
61
+ // is borderless, so re-assert a width here (this variant's whole cue is that border).
44
62
  .card-elevated {
63
+ --bs-card-border-width: 1px;
45
64
  border-color: var(--color-border-strong);
46
65
  }
47
66
  .card-outlined {
@@ -95,14 +95,29 @@
95
95
  .wui-check:hover:not(:disabled):not(:checked),
96
96
  .wui-radio:hover:not(:disabled):not(:checked) {
97
97
  border-color: var(--color-primary);
98
- box-shadow: 0 0 0 4px var(--color-primary-soft);
98
+ box-shadow: 0 0 0 2px var(--color-primary-soft);
99
99
  }
100
+ // Keyboard focus keeps a restrained brand ring — a keyboard user MUST see where focus is
101
+ // (a11y). :focus-visible matches keyboard/AT focus only, never a plain mouse click.
100
102
  .form-check-input:focus-visible,
101
103
  .wui-check:focus-visible,
102
104
  .wui-radio:focus-visible {
103
105
  outline: none;
104
106
  border-color: var(--color-primary);
105
- box-shadow: 0 0 0 3px var(--color-primary-soft);
107
+ box-shadow: 0 0 0 2px var(--color-primary-soft);
108
+ }
109
+ // A plain MOUSE click must leave NO lingering focus/active glow, ring, border tint or
110
+ // darkening — Bootstrap paints all of them on :focus/:active. Neutralise them for pointer
111
+ // focus + active while the keyboard ring above stays, so a mouse click just toggles cleanly.
112
+ .form-check-input:focus:not(:focus-visible),
113
+ .wui-check:focus:not(:focus-visible),
114
+ .wui-radio:focus:not(:focus-visible),
115
+ .form-check-input:active,
116
+ .wui-check:active,
117
+ .wui-radio:active {
118
+ outline: none;
119
+ box-shadow: none;
120
+ filter: none;
106
121
  }
107
122
  .form-check-input:checked,
108
123
  .wui-check:checked,
@@ -167,7 +182,7 @@
167
182
  }
168
183
  .form-switch .form-check-input:hover:not(:disabled):not(:checked) {
169
184
  border-color: transparent;
170
- box-shadow: 0 0 0 4px var(--color-primary-soft);
185
+ box-shadow: 0 0 0 2px var(--color-primary-soft);
171
186
  }
172
187
  .form-switch .form-check-input:checked {
173
188
  border-color: transparent;
@@ -176,6 +191,12 @@
176
191
  // Re-assert the knob — the checkbox :checked tick has equal specificity.
177
192
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='7' fill='white'/%3E%3C/svg%3E");
178
193
  }
194
+ // On a mouse click the switch's track border reverts to its resting transparent — Bootstrap's
195
+ // :focus otherwise tints it brand-blue, leaving a coloured outline after the click. The shared
196
+ // :focus:not(:focus-visible) rule already dropped the glow; this drops the border tint too.
197
+ .form-switch .form-check-input:focus:not(:focus-visible) {
198
+ border-color: transparent;
199
+ }
179
200
 
180
201
  // Circular variant (shape="circle") — a compact round on/off button instead of a sliding
181
202
  // pill. The track is a square-sized circle; the knob dot stays CENTRED in both states (no
@@ -194,6 +215,15 @@
194
215
  .form-switch-circle .form-check-input:checked {
195
216
  background-position: center;
196
217
  }
218
+
219
+ // Rounded-pill variant (shape="round") — the same sliding pill, but with truly circular
220
+ // ends. The switch is a type=checkbox, so it inherits the checkbox's default
221
+ // `corner-shape: squircle`, which superellipses the pill's ends; reset it to `round` for
222
+ // the fully semicircular track in the reference. Only the corner shape changes — size,
223
+ // knob and slide are the base pill's.
224
+ .form-switch-round .form-check-input {
225
+ corner-shape: round;
226
+ }
197
227
  @media (prefers-reduced-motion: reduce) {
198
228
  .form-check-input,
199
229
  .wui-check,
@@ -249,7 +249,10 @@
249
249
  // floating 42px header band, airy rows on a hairline rule, and an inset from
250
250
  // the card edge. Column geometry is NOT set here.
251
251
  .table-wrap:has(> .table-ledger) {
252
- padding: 20px 20px 0;
252
+ // One token drives the whole inset so a consumer can retune the table's padding with a
253
+ // class (set --wui-table-pad) without overriding this selector. Bottom padding is now
254
+ // included (was 0) so the last row isn't flush against the card edge.
255
+ padding: var(--wui-table-pad, 20px);
253
256
  }
254
257
  .table-ledger {
255
258
  border-spacing: 0;
@@ -0,0 +1,102 @@
1
+ // ── Floating dock ──
2
+ // AppFloatingDock / <app-floating-dock> / <wui-dock> — a macOS-style pill of icon
3
+ // links. The element writes --wui-dock-mag (1 → max-scale) per item on pointermove;
4
+ // everything visual lives here. With no JS (or coarse pointer / reduced motion /
5
+ // `static`) the var stays 1 and the dock is a plain icon row.
6
+ //
7
+ // Part of the wui-components layer — see _wui-components.scss for load order.
8
+
9
+ wui-dock {
10
+ --dock-size: 44px;
11
+
12
+ display: inline-flex;
13
+ align-items: flex-end;
14
+ gap: 10px;
15
+ padding: 10px 14px;
16
+ background: var(--color-surface);
17
+ border: 1px solid var(--color-border);
18
+ border-radius: var(--wui-radius-xl);
19
+ corner-shape: squircle;
20
+ box-shadow: var(--wui-shadow-overlay);
21
+ // Item boxes grow on hover; anchoring the row height to the rest size keeps the
22
+ // pill from pushing surrounding layout while items magnify upward out of it.
23
+ height: calc(var(--dock-size) + 20px);
24
+ }
25
+
26
+ .dock-item {
27
+ position: relative;
28
+ display: grid;
29
+ place-items: center;
30
+ width: calc(var(--dock-size) * var(--wui-dock-mag, 1));
31
+ height: calc(var(--dock-size) * var(--wui-dock-mag, 1));
32
+ border: none;
33
+ border-radius: 50%;
34
+ background: var(--color-bg-muted);
35
+ color: var(--color-text-muted);
36
+ text-decoration: none;
37
+ cursor: pointer;
38
+ // Smooths the snap-back when the pointer leaves; during tracking the element
39
+ // updates per frame, so the short transition just softens the steps.
40
+ transition:
41
+ width 120ms var(--wui-ease-ui),
42
+ height 120ms var(--wui-ease-ui),
43
+ background-color 160ms var(--wui-ease-ui),
44
+ color 160ms var(--wui-ease-ui);
45
+ }
46
+ .dock-item:hover,
47
+ .dock-item:focus-visible {
48
+ background: var(--color-primary-soft);
49
+ color: var(--color-primary);
50
+ }
51
+ .dock-item:focus-visible {
52
+ outline: 2px solid var(--color-primary);
53
+ outline-offset: 2px;
54
+ // Keyboard users get no pointer tracking — grow the focused item itself.
55
+ --wui-dock-mag: 1.25;
56
+ }
57
+
58
+ .dock-item-icon {
59
+ display: grid;
60
+ place-items: center;
61
+ font-size: calc(18px * var(--wui-dock-mag, 1));
62
+ line-height: 1;
63
+ }
64
+ // Node icons (SVGs) don't inherit font-size — scale the box instead.
65
+ .dock-item-icon > svg {
66
+ transform: scale(var(--wui-dock-mag, 1));
67
+ }
68
+
69
+ .dock-item-tip {
70
+ position: absolute;
71
+ bottom: calc(100% + 10px);
72
+ left: 50%;
73
+ translate: -50% 4px;
74
+ padding: 4px 10px;
75
+ background: var(--color-surface);
76
+ border: 1px solid var(--color-border);
77
+ border-radius: var(--wui-radius-sm);
78
+ box-shadow: var(--wui-shadow-thumb);
79
+ color: var(--color-text);
80
+ font-size: 12px;
81
+ font-weight: 500;
82
+ line-height: 1.35;
83
+ white-space: nowrap;
84
+ pointer-events: none;
85
+ opacity: 0;
86
+ transition:
87
+ opacity 140ms var(--wui-ease-ui),
88
+ translate 140ms var(--wui-ease-ui);
89
+ z-index: var(--wui-z-tooltip);
90
+ }
91
+ .dock-item:hover .dock-item-tip,
92
+ .dock-item:focus-visible .dock-item-tip {
93
+ opacity: 1;
94
+ translate: -50% 0;
95
+ }
96
+
97
+ @media (prefers-reduced-motion: reduce) {
98
+ .dock-item,
99
+ .dock-item-tip {
100
+ transition: none;
101
+ }
102
+ }
@@ -22,7 +22,8 @@
22
22
  // --wui-step-connector the incomplete-rail colour
23
23
  // --wui-step-size compact/vertical badge diameter (default 28px)
24
24
  // --wui-step-badge-size icons-variant badge diameter (default 56px)
25
- // The icons variant defaults its accent to success (green); the others to primary.
25
+ // Every variant defaults to the brand primary — active, done and rail share one accent
26
+ // (no multi-colour). Colour variety is opt-in: a `.wui-step-tone-*` class or a var override.
26
27
  // ============================================================================
27
28
  .stepper {
28
29
  // Full width so the flex:1 steps spread evenly across the container. Without it,
@@ -34,6 +35,18 @@
34
35
  gap: 0;
35
36
  padding: 0 8px;
36
37
  }
38
+ // A STANDALONE AppStepper gets the brand (primary) accent as a DECLARED default, so a tone
39
+ // class placed on the stepper element itself overrides it. The wizard is excluded because
40
+ // its tone class rides on the wizard HOST (an ancestor of the generated header): declaring
41
+ // the vars on the header would block that inherited override, so the wizard leans on the
42
+ // var fallbacks instead — which now also default to primary. :where() keeps this at ZERO
43
+ // specificity, so a .wui-step-tone-* class or an inline --wui-step-* override still wins.
44
+ :where(.stepper:not(.wizard-stepper)) {
45
+ --wui-step-accent: var(--color-primary);
46
+ --wui-step-accent-fg: var(--color-on-scrim);
47
+ --wui-step-soft: var(--color-primary-soft);
48
+ --wui-step-soft-fg: var(--color-primary);
49
+ }
37
50
  .step {
38
51
  position: relative;
39
52
  flex: 1;
@@ -188,8 +201,8 @@ button.step:focus-visible .step-circle {
188
201
  transform 0.2s ease;
189
202
  }
190
203
  .stepper-journey .step.done .step-circle {
191
- background: var(--wui-step-soft, var(--color-success-soft));
192
- color: var(--wui-step-soft-fg, var(--color-success-text));
204
+ background: var(--wui-step-soft, var(--color-primary-soft));
205
+ color: var(--wui-step-soft-fg, var(--color-primary));
193
206
  }
194
207
  .stepper-journey .step.active .step-circle {
195
208
  background: var(--wui-step-accent, var(--color-primary));
@@ -214,7 +227,7 @@ button.step:focus-visible .step-circle {
214
227
  color: var(--color-text-subtle);
215
228
  }
216
229
  .stepper-journey .step.done .step-index {
217
- color: var(--wui-step-soft-fg, var(--color-success-text));
230
+ color: var(--wui-step-soft-fg, var(--color-primary));
218
231
  }
219
232
  .stepper-journey .step.active .step-index {
220
233
  color: var(--wui-step-accent, var(--color-primary));
@@ -255,7 +268,7 @@ button.step:focus-visible .step-circle {
255
268
  background: var(--color-border-strong);
256
269
  }
257
270
  .stepper-journey .step-line.done {
258
- background: var(--wui-step-accent, var(--color-success));
271
+ background: var(--wui-step-accent, var(--color-primary));
259
272
  }
260
273
  // Below xl the four label+title pairs no longer fit side by side, so the bar
261
274
  // becomes a vertical list and the connectors go away.
@@ -348,9 +361,9 @@ button.step:focus-visible .step-circle {
348
361
  }
349
362
 
350
363
  // .stepper-icons — large icon badges joined by a rail, with a "STEP n" eyebrow above
351
- // each title. Done tints green with a filled connector; active is a solid primary
352
- // badge; pending is a muted badge. Built for icon-per-step flows — each step sets `icon`
353
- // (a step with no icon falls back to its number).
364
+ // each title. Done gets a soft-accent tint + filled connector; active is a solid-accent
365
+ // badge; pending is a muted badge — all one accent (brand primary by default). Built for
366
+ // icon-per-step flows — each step sets `icon` (a step with no icon falls back to its number).
354
367
  // ----------------------------------------------------------------------------
355
368
  .stepper-icons {
356
369
  align-items: flex-start;
@@ -371,11 +384,11 @@ button.step:focus-visible .step-circle {
371
384
  color 0.2s ease,
372
385
  transform 0.2s ease;
373
386
  }
374
- // The icons variant defaults its accent to success (green), so an untoned icons wizard
375
- // reads green — solid-green active badge, soft-green done badge, green rail. Every colour
376
- // still routes through the shared --wui-step-* vars, so a tone class or an override recolours it.
387
+ // Like every variant, the icons stepper defaults to the brand primary — a solid-primary
388
+ // active badge, a soft-primary done badge, a primary rail. Every colour routes through the
389
+ // shared --wui-step-* vars, so a `.wui-step-tone-*` class or an override recolours it.
377
390
  .stepper-icons .step.active .step-circle {
378
- background: var(--wui-step-accent, var(--color-success));
391
+ background: var(--wui-step-accent, var(--color-primary));
379
392
  color: var(--wui-step-accent-fg, var(--color-on-scrim));
380
393
  // The compact variant rings the active circle; here the solid fill carries it, so
381
394
  // drop the ring to match the flat badge look.
@@ -383,8 +396,8 @@ button.step:focus-visible .step-circle {
383
396
  }
384
397
  .stepper-icons .step.done .step-circle {
385
398
  border: none;
386
- background: var(--wui-step-soft, var(--color-success-soft));
387
- color: var(--wui-step-soft-fg, var(--color-success-text));
399
+ background: var(--wui-step-soft, var(--color-primary-soft));
400
+ color: var(--wui-step-soft-fg, var(--color-primary));
388
401
  }
389
402
  .stepper-icons .step.error .step-circle {
390
403
  background: var(--color-danger-soft);
@@ -406,10 +419,10 @@ button.step:focus-visible .step-circle {
406
419
  color: var(--color-text-subtle);
407
420
  }
408
421
  .stepper-icons .step.active .step-index {
409
- color: var(--wui-step-accent, var(--color-success));
422
+ color: var(--wui-step-accent, var(--color-primary));
410
423
  }
411
424
  .stepper-icons .step.done .step-index {
412
- color: var(--wui-step-soft-fg, var(--color-success-text));
425
+ color: var(--wui-step-soft-fg, var(--color-primary));
413
426
  }
414
427
  .stepper-icons .step.error .step-index {
415
428
  color: var(--color-danger-text);
@@ -435,7 +448,7 @@ button.step:focus-visible .step-circle {
435
448
  background: var(--wui-step-connector, var(--color-border));
436
449
  }
437
450
  .stepper-icons .step.done + .step::before {
438
- background: var(--wui-step-accent, var(--color-success));
451
+ background: var(--wui-step-accent, var(--color-primary));
439
452
  }
440
453
  // The compact hover ring is calibrated to the 28px badge; the 56px icon badge just
441
454
  // lifts on hover instead.
@@ -793,6 +806,7 @@ button.step:focus-visible .step-circle {
793
806
  // ============================================================================
794
807
  wui-wizard {
795
808
  display: block;
809
+ width: 100%;
796
810
  }
797
811
  // Custom elements don't inherit the UA `[hidden] { display: none }` once we give the
798
812
  // tag its own `display`, so the inactive panels need it stated explicitly.
@@ -819,13 +833,12 @@ wui-wizard-step[hidden] {
819
833
  }
820
834
  .wizard-footer {
821
835
  // The sticky Back/Skip/Next/Finish bar — pinned to the bottom of a scrolling flow
822
- // so the actions (and the Skip on an optional step) are always in reach.
836
+ // so the actions (and the Skip on an optional step) are always in reach. Runs flush on
837
+ // the flow (no divider or fill) — the buttons alone read as the footer.
823
838
  position: sticky;
824
839
  bottom: 0;
825
840
  margin-top: 24px;
826
841
  padding: 16px 0;
827
- border-top: 1px solid var(--color-border);
828
- background: var(--color-surface);
829
842
  z-index: 1;
830
843
  }
831
844
  .wizard-footer-actions {
@@ -0,0 +1,153 @@
1
+ // ── Menu open motion ──
2
+ // One entrance for every menu-like overlay: Bootstrap dropdown menus (AppDropdown,
3
+ // AppWorkspaceSwitcher), popovers (AppPopover), and every portalled wui-* panel
4
+ // (select / autocomplete / multiselect / phone / date / date-range / time).
5
+ //
6
+ // The motion is a PRODUCT-LEVEL choice, not a per-component prop — menus are opened by
7
+ // Bootstrap/react-bootstrap internals, and mixing motions inside one product reads as a
8
+ // bug. A product picks once, on the root element:
9
+ //
10
+ // <html data-wui-menu-motion="drop"> zoom + fade + a 6px drop out of the trigger (default)
11
+ // <html data-wui-menu-motion="zoom"> zoom + fade only (the quietest)
12
+ // <html data-wui-menu-motion="spring"> elastic overshoot (playful; marketing surfaces)
13
+ // <html data-wui-menu-motion="unfold"> scales open vertically, like a sheet
14
+ // <html data-wui-menu-motion="none"> no entrance
15
+ //
16
+ // Two load-bearing choices:
17
+ // - The keyframes animate the STANDALONE `scale` / `translate` properties, never
18
+ // `transform` — Popper and anchorOverlay position these panels via transform/fixed
19
+ // coordinates, and the standalone properties compose with that instead of clobbering.
20
+ // - Panels shown by removing `hidden` (the wui-* set) replay the animation on every
21
+ // reveal for free; Bootstrap surfaces key off `.show`. Close stays instant: the wui
22
+ // elements hide with `hidden` in the same tick, and delaying that for an exit
23
+ // animation would change observable close timing everywhere.
24
+ //
25
+ // Part of the wui-components layer — see _wui-components.scss for load order.
26
+
27
+ :root {
28
+ --wui-menu-anim: wui-menu-drop;
29
+ --wui-menu-anim-duration: 200ms;
30
+ --wui-menu-anim-ease: var(--wui-ease-out-quart);
31
+ }
32
+ :root[data-wui-menu-motion="zoom"] {
33
+ --wui-menu-anim: wui-menu-zoom;
34
+ --wui-menu-anim-duration: 160ms;
35
+ }
36
+ :root[data-wui-menu-motion="spring"] {
37
+ --wui-menu-anim: wui-menu-spring;
38
+ --wui-menu-anim-duration: 320ms;
39
+ --wui-menu-anim-ease: var(--wui-ease-elastic);
40
+ }
41
+ :root[data-wui-menu-motion="unfold"] {
42
+ --wui-menu-anim: wui-menu-unfold;
43
+ --wui-menu-anim-duration: 220ms;
44
+ }
45
+ :root[data-wui-menu-motion="none"] {
46
+ --wui-menu-anim: none;
47
+ }
48
+
49
+ @keyframes wui-menu-drop {
50
+ from {
51
+ opacity: 0;
52
+ scale: 0.95;
53
+ translate: 0 var(--wui-menu-drop, -6px);
54
+ }
55
+ to {
56
+ opacity: 1;
57
+ scale: 1;
58
+ translate: 0 0;
59
+ }
60
+ }
61
+ @keyframes wui-menu-zoom {
62
+ from {
63
+ opacity: 0;
64
+ scale: 0.95;
65
+ }
66
+ to {
67
+ opacity: 1;
68
+ scale: 1;
69
+ }
70
+ }
71
+ @keyframes wui-menu-spring {
72
+ from {
73
+ opacity: 0;
74
+ scale: 0.9;
75
+ translate: 0 var(--wui-menu-drop, -4px);
76
+ }
77
+ to {
78
+ opacity: 1;
79
+ scale: 1;
80
+ translate: 0 0;
81
+ }
82
+ }
83
+ @keyframes wui-menu-unfold {
84
+ from {
85
+ opacity: 0;
86
+ scale: 0.97 0.82;
87
+ }
88
+ to {
89
+ opacity: 1;
90
+ scale: 1 1;
91
+ }
92
+ }
93
+
94
+ .dropdown-menu.show,
95
+ .popover.show,
96
+ .search-select-menu:not([hidden]),
97
+ .country-dropdown-menu:not([hidden]),
98
+ .datepicker-pop:not([hidden]),
99
+ .daterange-pop:not([hidden]),
100
+ .timepicker-pop:not([hidden]) {
101
+ animation: var(--wui-menu-anim) var(--wui-menu-anim-duration) var(--wui-menu-anim-ease);
102
+ transform-origin: top;
103
+ }
104
+
105
+ // End-aligned dropdowns zoom from the corner they attach to.
106
+ .dropdown-menu-end.show {
107
+ transform-origin: top right;
108
+ }
109
+
110
+ // Opening upward: origin flips to the bottom edge and the drop comes from below.
111
+ .search-select-menu.drop-up,
112
+ .country-dropdown-menu.drop-up,
113
+ .datepicker-pop.drop-up,
114
+ .daterange-pop.drop-up,
115
+ .timepicker-pop.drop-up,
116
+ .dropdown-menu.show[data-popper-placement^="top"],
117
+ .dropup .dropdown-menu.show {
118
+ --wui-menu-drop: 6px;
119
+
120
+ transform-origin: bottom;
121
+ }
122
+
123
+ // Popover follows its Popper side; the drop always comes from the trigger's direction.
124
+ .popover.show[data-popper-placement^="top"] {
125
+ --wui-menu-drop: 6px;
126
+
127
+ transform-origin: bottom center;
128
+ }
129
+ .popover.show[data-popper-placement^="right"] {
130
+ --wui-menu-drop: 0px;
131
+
132
+ transform-origin: left center;
133
+ }
134
+ .popover.show[data-popper-placement^="left"] {
135
+ --wui-menu-drop: 0px;
136
+
137
+ transform-origin: right center;
138
+ }
139
+ .popover.show[data-popper-placement^="bottom"] {
140
+ transform-origin: top center;
141
+ }
142
+
143
+ @media (prefers-reduced-motion: reduce) {
144
+ .dropdown-menu.show,
145
+ .popover.show,
146
+ .search-select-menu:not([hidden]),
147
+ .country-dropdown-menu:not([hidden]),
148
+ .datepicker-pop:not([hidden]),
149
+ .daterange-pop:not([hidden]),
150
+ .timepicker-pop:not([hidden]) {
151
+ animation: none;
152
+ }
153
+ }