@webority/theme 0.30.0 → 0.31.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.30.0",
3
+ "version": "0.31.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": {
package/scss/_tokens.scss CHANGED
@@ -331,6 +331,7 @@
331
331
  --wui-z-shell-drawer: 1045; // mobile sidebar drawer
332
332
  --wui-z-modal-backdrop: 1500;
333
333
  --wui-z-modal: 1505;
334
+ --wui-z-tour: 1550; // product tour: above a modal, below menus and popovers
334
335
  --wui-z-menu: 1600; // portalled select/date/phone menus + infotip
335
336
  --wui-z-popover: 1600; // same rung as --wui-z-menu (above modal)
336
337
  --wui-z-tooltip: 1650;
@@ -236,6 +236,7 @@ $focus-ring-width: 3px; // BS 0.25rem (4px)
236
236
  //
237
237
  // SCSS variables are compile-time and can't reference the runtime custom
238
238
  // properties above — keep these numbers in sync with _tokens.scss by hand.
239
+ $zindex-tour: 1550;
239
240
  $zindex-popover: 1600;
240
241
  $zindex-tooltip: 1650;
241
242
  $zindex-toast: 1700;
@@ -64,8 +64,11 @@
64
64
  @import "wui/toolbar";
65
65
  @import "wui/theme-toggle";
66
66
  @import "wui/tree";
67
+ @import "wui/floating";
68
+ @import "wui/chat";
67
69
  // After `overlays`: anchors the shared modal shell to the top when it holds the palette card.
68
70
  @import "wui/command-palette";
69
71
  @import "wui/context-menu";
72
+ @import "wui/tour";
70
73
  // Last: restates the settled state of menus other partials style, so it must win.
71
74
  @import "wui/menu-motion";
@@ -1,315 +1,14 @@
1
- // Charts: AppLineChart and AppBarChart, and the <wui-chart> element behind AppChart.
1
+ // Charts: the <wui-chart> element behind AppChart.
2
2
  //
3
- // Part of the wui-components layer; see _wui-components.scss for the load order. The line and
4
- // bar charts use one accent (--color-primary), muted grid and labels, and direct labels instead of
5
- // a legend; the element draws series in the --wui-chart-* colours. Every colour is a token the
6
- // dark remap in _wui-aliases.scss flips with the rest of the portal.
7
-
8
- .wui-chart {
9
- margin: 0;
10
- min-width: 0;
11
- color: var(--color-text-muted);
12
- font-size: 12px;
13
- font-variant-numeric: tabular-nums;
14
- }
15
- .wui-chart-title {
16
- margin-bottom: 12px;
17
- font-size: 14px;
18
- font-weight: 600;
19
- color: var(--color-text);
20
- }
21
-
22
- // ============================================================================
23
- // Line chart
24
- // ============================================================================
25
- // The top tick label sits above the top gridline, so the plot leaves room for it.
26
- .wui-chart-plot {
27
- position: relative;
28
- margin-top: 8px;
29
- }
30
- // Strokes overhang the plot by half their width at the top and bottom gridlines.
31
- .wui-chart-svg {
32
- display: block;
33
- overflow: visible;
34
- }
35
- .wui-chart-grid {
36
- stroke: var(--color-border);
37
- stroke-width: 1;
38
- }
39
- .wui-chart-reference {
40
- stroke: var(--color-border-strong);
41
- stroke-width: 1;
42
- stroke-dasharray: 4 4;
43
- }
44
- .wui-chart-line {
45
- stroke: var(--color-primary);
46
- stroke-width: 2;
47
- stroke-linecap: round;
48
- }
49
- // Bands are a quiet wash behind the series; the tone tints, it does not shout.
50
- .wui-chart-band {
51
- fill: var(--color-bg-muted);
52
- opacity: 0.6;
53
- }
54
- .wui-chart-band-info {
55
- fill: var(--color-info-soft);
56
- }
57
- .wui-chart-band-success {
58
- fill: var(--color-success-soft);
59
- }
60
- .wui-chart-band-warning {
61
- fill: var(--color-warning-soft);
62
- }
63
- .wui-chart-band-danger {
64
- fill: var(--color-danger-soft);
65
- }
66
-
67
- // Y tick values sit just above their gridline at the left edge, inside the plot, so the chart
68
- // spends no width on a label gutter at 320px.
69
- .wui-chart-tick,
70
- .wui-chart-band-label,
71
- .wui-chart-reference-label {
72
- position: absolute;
73
- font-size: 11px;
74
- line-height: 1;
75
- white-space: nowrap;
76
- color: var(--color-text-muted);
77
- pointer-events: none;
78
- }
79
- .wui-chart-tick {
80
- left: 0;
81
- padding-bottom: 3px;
82
- transform: translateY(-100%);
83
- }
84
- .wui-chart-band-label {
85
- right: 0;
86
- padding-top: 3px;
87
- }
88
- .wui-chart-reference-label {
89
- right: 0;
90
- padding-bottom: 3px;
91
- transform: translateY(-100%);
92
- }
93
-
94
- // A 24px hit area per point (WCAG 2.2 target size), drawn as an 8px ring.
95
- .wui-chart-point {
96
- position: absolute;
97
- width: 24px;
98
- height: 24px;
99
- margin: -12px 0 0 -12px;
100
- padding: 0;
101
- display: grid;
102
- place-items: center;
103
- border: 0;
104
- border-radius: 50%;
105
- background: transparent;
106
- cursor: default;
107
- }
108
- .wui-chart-point:focus-visible {
109
- outline: 2px solid var(--color-primary);
110
- outline-offset: 0;
111
- }
112
- .wui-chart-dot {
113
- width: 8px;
114
- height: 8px;
115
- border-radius: 50%;
116
- border: 2px solid var(--color-primary);
117
- background: var(--color-surface);
118
- transition: transform 120ms var(--wui-ease-out-quart);
119
- }
120
- .wui-chart-point:hover .wui-chart-dot,
121
- .wui-chart-point:focus-visible .wui-chart-dot {
122
- transform: scale(1.35);
123
- background: var(--color-primary);
124
- }
125
-
126
- // CSS-only tooltip above the point; the first and last points anchor it to their own edge so
127
- // it never runs off a narrow chart.
128
- .wui-chart-tip {
129
- position: absolute;
130
- bottom: calc(100% + 4px);
131
- left: 50%;
132
- z-index: 1;
133
- display: flex;
134
- flex-direction: column;
135
- align-items: flex-start;
136
- gap: 2px;
137
- padding: 6px 10px;
138
- border: 1px solid var(--color-border-light);
139
- border-radius: var(--radius);
140
- background: var(--color-surface);
141
- box-shadow: var(--wui-shadow-overlay);
142
- white-space: nowrap;
143
- text-align: left;
144
- pointer-events: none;
145
- visibility: hidden;
146
- opacity: 0;
147
- transform: translateX(-50%);
148
- transition:
149
- opacity 120ms var(--wui-ease-out-quart),
150
- visibility 120ms;
151
- }
152
- .wui-chart-point-start .wui-chart-tip {
153
- left: 0;
154
- transform: none;
155
- }
156
- .wui-chart-point-end .wui-chart-tip {
157
- left: auto;
158
- right: 0;
159
- transform: none;
160
- }
161
- .wui-chart-point:hover .wui-chart-tip,
162
- .wui-chart-point:focus-visible .wui-chart-tip {
163
- visibility: visible;
164
- opacity: 1;
165
- }
166
- .wui-chart-tip-label {
167
- font-size: 11px;
168
- color: var(--color-text-muted);
169
- }
170
- .wui-chart-tip-value {
171
- font-size: 13px;
172
- font-weight: 600;
173
- color: var(--color-text);
174
- }
175
-
176
- .wui-chart-xaxis {
177
- position: relative;
178
- height: 16px;
179
- margin-top: 6px;
180
- }
181
- .wui-chart-xlabel {
182
- position: absolute;
183
- top: 0;
184
- font-size: 11px;
185
- line-height: 16px;
186
- white-space: nowrap;
187
- transform: translateX(-50%);
188
- }
189
- // Below md only every Nth label shows (the component marks the rest minor); a 12-month axis
190
- // would otherwise overlap on a phone.
191
- .wui-chart-xlabel-minor {
192
- display: none;
193
- }
194
- @media (min-width: 768px) {
195
- .wui-chart-xlabel-minor {
196
- display: block;
197
- }
198
- }
199
-
200
- // ============================================================================
201
- // Bar chart
202
- // ============================================================================
203
- .wui-bar-chart-list {
204
- margin: 0;
205
- padding: 0;
206
- list-style: none;
207
- }
208
- .wui-bar-chart-label {
209
- min-width: 0;
210
- color: var(--color-text-body);
211
- overflow-wrap: anywhere;
212
- }
213
- .wui-bar-chart-value {
214
- font-weight: 600;
215
- white-space: nowrap;
216
- color: var(--color-text);
217
- }
218
- .wui-bar-chart-track {
219
- position: relative;
220
- overflow: hidden;
221
- border-radius: 999px;
222
- background: var(--color-progress-track);
223
- }
224
- .wui-bar-chart-fill {
225
- border-radius: inherit;
226
- background: var(--color-primary);
227
- }
228
- // Each track is a focus stop; the ring sits outside the track's own clipped content.
229
- .wui-bar-chart-track:focus-visible {
230
- outline: 2px solid var(--color-primary);
231
- outline-offset: 2px;
232
- }
233
-
234
- // Horizontal: a label/value line over each bar, so a long label wraps instead of squeezing
235
- // the bar at 320px.
236
- .wui-bar-chart-horizontal .wui-bar-chart-list {
237
- display: flex;
238
- flex-direction: column;
239
- gap: 14px;
240
- }
241
- .wui-bar-chart-horizontal .wui-bar-chart-item {
242
- display: grid;
243
- grid-template-columns: minmax(0, 1fr) auto;
244
- grid-template-areas:
245
- "label value"
246
- "track track";
247
- column-gap: 12px;
248
- row-gap: 6px;
249
- align-items: baseline;
250
- }
251
- .wui-bar-chart-horizontal .wui-bar-chart-label {
252
- grid-area: label;
253
- }
254
- .wui-bar-chart-horizontal .wui-bar-chart-value {
255
- grid-area: value;
256
- }
257
- .wui-bar-chart-horizontal .wui-bar-chart-track {
258
- grid-area: track;
259
- height: 8px;
260
- }
261
- .wui-bar-chart-horizontal .wui-bar-chart-fill {
262
- height: 100%;
263
- transition: width 300ms var(--wui-ease-out-quart);
264
- }
265
-
266
- // Vertical: bars side by side, value above and label below each. The plot height is one var a
267
- // caller can set from its own class.
268
- .wui-bar-chart-vertical .wui-bar-chart-list {
269
- display: flex;
270
- gap: 8px;
271
- }
272
- .wui-bar-chart-vertical .wui-bar-chart-item {
273
- flex: 1 1 0;
274
- min-width: 0;
275
- display: grid;
276
- grid-template-areas:
277
- "value"
278
- "track"
279
- "label";
280
- justify-items: center;
281
- row-gap: 6px;
282
- text-align: center;
283
- }
284
- // Seven bars on a 320px phone leave about 40px a column, so "18 of 25" may wrap here.
285
- .wui-bar-chart-vertical .wui-bar-chart-value {
286
- grid-area: value;
287
- white-space: normal;
288
- }
289
- .wui-bar-chart-vertical .wui-bar-chart-track {
290
- grid-area: track;
291
- display: flex;
292
- align-items: flex-end;
293
- width: 100%;
294
- max-width: 32px;
295
- height: var(--wui-bar-chart-height, 180px);
296
- border-radius: var(--radius-sm);
297
- }
298
- .wui-bar-chart-vertical .wui-bar-chart-fill {
299
- width: 100%;
300
- transition: height 300ms var(--wui-ease-out-quart);
301
- }
302
- .wui-bar-chart-vertical .wui-bar-chart-label {
303
- grid-area: label;
304
- font-size: 11px;
305
- }
3
+ // Part of the wui-components layer; see _wui-components.scss for the load order. The element draws
4
+ // series in the --wui-chart-* colours. Every colour is a token the dark remap in _wui-aliases.scss
5
+ // flips with the rest of the portal.
306
6
 
307
7
  // ============================================================================
308
8
  // Chart element: <wui-chart> (AppChart, <app-chart>)
309
9
  // ============================================================================
310
10
  // The element builds the legend, the drawing surface, the state box and the data table; the
311
- // engine draws inside .wui-chart-canvas with colours the element reads from --wui-chart-*. The
312
- // names here stay clear of the line and bar chart classes above.
11
+ // engine draws inside .wui-chart-canvas with colours the element reads from --wui-chart-*.
313
12
  wui-chart {
314
13
  position: relative;
315
14
  display: block;
@@ -513,9 +212,6 @@ wui-chart[aria-busy="true"] .wui-chart-surface {
513
212
  }
514
213
 
515
214
  @media (prefers-reduced-motion: reduce) {
516
- .wui-chart-dot,
517
- .wui-chart-tip,
518
- .wui-bar-chart-fill,
519
215
  .wui-chart-legend-item,
520
216
  .wui-chart-legend-swatch,
521
217
  .wui-chart-surface {
@@ -0,0 +1,82 @@
1
+ // ── Assistant chat ──
2
+ // <wui-chat> / <app-chat>: a launcher pinned to a bottom corner and a side panel holding the
3
+ // conversation and the question box. The header, buttons, form field and alerts inside are the
4
+ // theme's own (.drawer-header, .btn, .form-control, .alert); only the placement and the two chat
5
+ // shapes live here. A compact launcher is the shared .wui-floating-btn circle (_floating.scss).
6
+ //
7
+ // Part of the wui-components layer — see _wui-components.scss for load order.
8
+
9
+ // The element is a plain host: its two parts are fixed to the viewport.
10
+ wui-chat {
11
+ display: contents;
12
+ }
13
+
14
+ .wui-chat-launcher {
15
+ position: fixed;
16
+ bottom: 0;
17
+ inset-inline-end: 0;
18
+ z-index: var(--wui-z-fixed);
19
+ margin: 1rem;
20
+ }
21
+ wui-chat[position="start"] .wui-chat-launcher {
22
+ inset-inline-end: auto;
23
+ inset-inline-start: 0;
24
+ }
25
+
26
+ // Above the shell chrome and below modals, like the drawer it stands in for.
27
+ .wui-chat-panel {
28
+ position: fixed;
29
+ top: 0;
30
+ bottom: 0;
31
+ inset-inline-end: 0;
32
+ z-index: var(--wui-z-shell-drawer);
33
+ display: flex;
34
+ flex-direction: column;
35
+ width: min(440px, 100%);
36
+ background: var(--color-surface);
37
+ border-inline-start: 1px solid var(--color-border);
38
+ box-shadow: var(--wui-shadow-overlay-lg);
39
+ }
40
+ wui-chat[position="start"] .wui-chat-panel {
41
+ inset-inline-end: auto;
42
+ inset-inline-start: 0;
43
+ border-inline-start: 0;
44
+ border-inline-end: 1px solid var(--color-border);
45
+ }
46
+ // `hidden` is how the element closes the panel; display: flex above would otherwise win over it.
47
+ .wui-chat-panel[hidden] {
48
+ display: none;
49
+ }
50
+
51
+ .wui-chat-body {
52
+ flex: 1 1 auto;
53
+ min-height: 0;
54
+ padding: 20px;
55
+ overflow-y: auto;
56
+ }
57
+ .wui-chat-empty {
58
+ padding-block: 2rem;
59
+ }
60
+ .wui-chat-foot {
61
+ flex: none;
62
+ padding: 16px 20px;
63
+ border-top: 1px solid var(--color-border);
64
+ }
65
+
66
+ // The person's question, on the right; the answer is plain text on the panel.
67
+ .wui-chat-question {
68
+ max-width: 85%;
69
+ }
70
+ .wui-chat-bubble {
71
+ padding: 10px 14px;
72
+ background: var(--color-bg-muted);
73
+ border-radius: var(--wui-radius-lg);
74
+ white-space: pre-wrap;
75
+ overflow-wrap: anywhere;
76
+ }
77
+
78
+ // The question box grows with its text, up to a few lines.
79
+ .wui-chat-foot .form-control {
80
+ max-height: 9rem;
81
+ resize: none;
82
+ }
@@ -0,0 +1,64 @@
1
+ // ── Floating stack ──
2
+ // The one fixed corner container the compact floating buttons (the chat launcher, the report-an-issue
3
+ // button) portal into, so they stack with a gap and never overlap or need a hand-set offset. React's
4
+ // useFloatingStack creates it; the items inside are not fixed themselves.
5
+ //
6
+ // Part of the wui-components layer — see _wui-components.scss for load order.
7
+
8
+ .wui-floating-stack {
9
+ position: fixed;
10
+ bottom: 0;
11
+ z-index: var(--wui-z-fixed);
12
+ display: flex;
13
+ // The primary item sits in the corner and the secondary one stacks above it.
14
+ flex-direction: column-reverse;
15
+ gap: 12px;
16
+ margin: 1rem;
17
+ // The container spans only its items, but a gap between them must not swallow clicks on the page.
18
+ pointer-events: none;
19
+ }
20
+ .wui-floating-stack[data-position="end"] {
21
+ inset-inline-end: 0;
22
+ align-items: flex-end;
23
+ }
24
+ .wui-floating-stack[data-position="start"] {
25
+ inset-inline-start: 0;
26
+ align-items: flex-start;
27
+ }
28
+ .wui-floating-stack-item {
29
+ display: inline-flex;
30
+ pointer-events: auto;
31
+ }
32
+ .wui-floating-stack-item--primary {
33
+ order: 0;
34
+ }
35
+ .wui-floating-stack-item--secondary {
36
+ order: 1;
37
+ }
38
+
39
+ // ── Compact floating button ──
40
+ // An icon-only circle. The label lives in the tooltip and the aria-label, never on the button.
41
+ .wui-floating-btn {
42
+ --wui-floating-size: 48px;
43
+
44
+ display: inline-flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ width: var(--wui-floating-size);
48
+ height: var(--wui-floating-size);
49
+ padding: 0;
50
+ border-radius: 50%;
51
+ box-shadow: var(--wui-shadow-overlay);
52
+ }
53
+ // Quieter than the primary circle: a light brand tint, the brand icon and a thin brand border.
54
+ .wui-floating-btn--secondary {
55
+ --wui-floating-size: 40px;
56
+ --bs-btn-border-color: var(--wui-primary-30);
57
+ --bs-btn-hover-border-color: var(--wui-primary-30);
58
+ --bs-btn-active-border-color: var(--wui-primary-30);
59
+ }
60
+ @media (prefers-reduced-motion: reduce) {
61
+ .wui-floating-btn {
62
+ transition: none;
63
+ }
64
+ }
@@ -867,6 +867,18 @@
867
867
  .file-preview[aria-busy="true"] {
868
868
  cursor: progress;
869
869
  }
870
+ // A disabled drop zone (AppDropZone `disabled`): dimmed, no pointer affordance, and no hover lift.
871
+ .file-input[aria-disabled="true"] {
872
+ opacity: 0.6;
873
+ cursor: not-allowed;
874
+ }
875
+ .file-input[aria-disabled="true"] > .file-input-zone-label {
876
+ cursor: not-allowed;
877
+ }
878
+ .file-input.file-input-tall[aria-disabled="true"]:hover:not(:focus-within):not(.dragging) {
879
+ background: var(--color-bg-muted);
880
+ border-color: var(--color-border);
881
+ }
870
882
  .wui-file-busy {
871
883
  position: absolute;
872
884
  inset: 0;
@@ -351,6 +351,12 @@
351
351
  padding-top: 12px;
352
352
  border-top: 1px solid var(--color-border);
353
353
  }
354
+ // A node the author places right after a group's links (`groups[].after` /
355
+ // `<app-nav-group-after>`). Like sidebarStart it has no place on the 88px rail.
356
+ .wui-nav-group-after {
357
+ flex: none;
358
+ margin-top: 4px;
359
+ }
354
360
  .app-nav-group-label {
355
361
  padding: 6px 14px;
356
362
  font-size: 12px;
@@ -439,6 +445,7 @@
439
445
  }
440
446
  .app-shell.collapsed .app-nav-badge,
441
447
  .app-shell.collapsed .app-nav-group-label,
448
+ .app-shell.collapsed .wui-nav-group-after,
442
449
  .app-shell.collapsed .app-sidebar-brand-text,
443
450
  .app-shell.collapsed .app-sidebar-start {
444
451
  display: none;
@@ -756,6 +763,7 @@
756
763
  .app-shell.app-shell.collapsed .app-nav-text,
757
764
  .app-shell.app-shell.collapsed .app-nav-badge,
758
765
  .app-shell.app-shell.collapsed .app-nav-group-label,
766
+ .app-shell.app-shell.collapsed .wui-nav-group-after,
759
767
  .app-shell.app-shell.collapsed .app-sidebar-start {
760
768
  display: revert;
761
769
  }
@@ -8,11 +8,12 @@
8
8
  // (`.tbl-empty-block`) reuse the client-side table rules in _data.scss unchanged.
9
9
 
10
10
  // While a page is in flight the current rows stay in place, dimmed, so the table does not jump;
11
- // they are not interactive until the new page lands.
11
+ // they are not interactive until the new page lands. A table with no rows shows placeholder rows
12
+ // instead, at full strength.
12
13
  .wui-table-server > .table-wrap[aria-busy="true"] {
13
14
  cursor: progress;
14
15
  }
15
- .wui-table-server > .table-wrap[aria-busy="true"] > .table > tbody {
16
+ .wui-table-server > .table-wrap[aria-busy="true"] > .table > tbody:not(:has(> tr[data-wui-skeleton])) {
16
17
  opacity: 0.55;
17
18
  pointer-events: none;
18
19
  transition: opacity 0.15s ease;
@@ -34,7 +35,7 @@
34
35
  }
35
36
 
36
37
  @media (prefers-reduced-motion: reduce) {
37
- .wui-table-server > .table-wrap[aria-busy="true"] > .table > tbody {
38
+ .wui-table-server > .table-wrap[aria-busy="true"] > .table > tbody:not(:has(> tr[data-wui-skeleton])) {
38
39
  transition: none;
39
40
  }
40
41
  }
@@ -0,0 +1,97 @@
1
+ // ── Product tour ──
2
+ // AppTour / <app-tour> / <wui-tour>: a dimmed page with one highlighted element and a card
3
+ // holding the step text and Back / Next / Skip. The element appends .wui-tour-layer to <body>
4
+ // and positions .wui-tour-spot (over the target) and .wui-tour-card (against the spot, through
5
+ // anchorOverlay, which sets position, top and left inline). Everything visual is here, every
6
+ // colour a theme token.
7
+ //
8
+ // Part of the wui-components layer, see _wui-components.scss for load order.
9
+
10
+ // The step data of a server-rendered tour is plain markup the element reads and the page never shows.
11
+ wui-tour,
12
+ wui-tour-step {
13
+ display: none;
14
+ }
15
+
16
+ .wui-tour-layer {
17
+ position: fixed;
18
+ inset: 0;
19
+ z-index: var(--wui-z-tour);
20
+ }
21
+
22
+ // The dim is the spot's own shadow, so the hole around the target needs no clip-path.
23
+ .wui-tour-spot {
24
+ position: fixed;
25
+ border-radius: var(--wui-radius-sm);
26
+ box-shadow:
27
+ 0 0 0 2px var(--color-primary),
28
+ 0 0 0 100vmax var(--color-scrim-strong);
29
+ pointer-events: none;
30
+ }
31
+ @media (prefers-reduced-motion: no-preference) {
32
+ .wui-tour-spot {
33
+ transition:
34
+ top 160ms ease,
35
+ left 160ms ease,
36
+ width 160ms ease,
37
+ height 160ms ease;
38
+ }
39
+ }
40
+
41
+ .wui-tour-card {
42
+ display: flex;
43
+ flex-direction: column;
44
+ gap: 8px;
45
+ width: min(360px, calc(100vw - 16px));
46
+ padding: 16px;
47
+ overflow-y: auto;
48
+ background: var(--color-surface);
49
+ color: var(--color-text);
50
+ border: 1px solid var(--color-border);
51
+ border-radius: var(--wui-radius-lg);
52
+ corner-shape: squircle;
53
+ box-shadow: var(--wui-shadow-overlay);
54
+ &:focus {
55
+ outline: none;
56
+ }
57
+ &:focus-visible {
58
+ outline: 2px solid var(--color-primary);
59
+ outline-offset: 2px;
60
+ }
61
+ }
62
+
63
+ .wui-tour-position {
64
+ margin: 0;
65
+ font-size: 12px;
66
+ color: var(--color-text-muted);
67
+ }
68
+ .wui-tour-title {
69
+ margin: 0;
70
+ font-size: 16px;
71
+ font-weight: 600;
72
+ }
73
+ .wui-tour-text {
74
+ margin: 0;
75
+ font-size: 14px;
76
+ color: var(--color-text-muted);
77
+ }
78
+ .wui-tour-actions {
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: space-between;
82
+ gap: 8px;
83
+ margin-top: 4px;
84
+ }
85
+ .wui-tour-nav {
86
+ display: flex;
87
+ gap: 8px;
88
+ }
89
+ // The buttons keep Bootstrap's look; the width stops the label change between Next and Done from
90
+ // moving the row, and Skip reads as the quiet action.
91
+ .wui-tour-skip {
92
+ color: var(--color-text-muted);
93
+ }
94
+ .wui-tour-back,
95
+ .wui-tour-next {
96
+ min-width: 64px;
97
+ }