@webority/theme 0.76.0 → 0.77.1
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/README.md +20 -0
- package/dist/purge-safelist.json +18 -1
- package/dist/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/_components.scss +8 -8
- package/scss/_wui-aliases.scss +4 -3
- package/scss/_wui-core.scss +88 -0
- package/scss/wui/_calendar.scss +27 -0
- package/scss/wui/_card.scss +30 -11
- package/scss/wui/_command-palette.scss +9 -0
- package/scss/wui/_controls.scss +1 -2
- package/scss/wui/_data.scss +44 -0
- package/scss/wui/_display.scss +18 -10
- package/scss/wui/_dock.scss +5 -0
- package/scss/wui/_file-viewer.scss +5 -0
- package/scss/wui/_floating.scss +7 -3
- package/scss/wui/_flow.scss +210 -1
- package/scss/wui/_image-crop.scss +5 -0
- package/scss/wui/_interaction.scss +28 -38
- package/scss/wui/_kanban.scss +5 -0
- package/scss/wui/_media.scss +6 -5
- package/scss/wui/_rich-text.scss +21 -0
- package/scss/wui/_shell.scss +6 -1
- package/scss/wui/_table-server.scss +5 -0
- package/scss/wui/_tree.scss +5 -0
- package/scss/wui/_utilities.scss +1 -0
- package/scss/wui/_workspace.scss +22 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.77.1",
|
|
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/_components.scss
CHANGED
|
@@ -27,12 +27,11 @@
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
.btn-primary {
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
--bs-btn-hover-
|
|
33
|
-
--bs-btn-
|
|
34
|
-
--bs-btn-active-
|
|
35
|
-
--bs-btn-active-border-color: var(--wui-primary-pressed);
|
|
30
|
+
// Hover and press read --color-primary-hover: the pressed primary in light and the lifted dark primary in dark (_wui-aliases.scss), so a rebrand and dark mode both track it.
|
|
31
|
+
--bs-btn-hover-bg: var(--color-primary-hover);
|
|
32
|
+
--bs-btn-hover-border-color: var(--color-primary-hover);
|
|
33
|
+
--bs-btn-active-bg: var(--color-primary-hover);
|
|
34
|
+
--bs-btn-active-border-color: var(--color-primary-hover);
|
|
36
35
|
// Bootstrap computes this label colour at SCSS compile time from the library's
|
|
37
36
|
// default $primary, so it can never react to a product overriding --wui-primary as a
|
|
38
37
|
// runtime CSS var. Routing it through the token makes a light-primary brand's
|
|
@@ -858,9 +857,10 @@
|
|
|
858
857
|
.card-header-actions + .card-close {
|
|
859
858
|
margin-left: 0.25rem;
|
|
860
859
|
}
|
|
860
|
+
// Hover tints the button danger, the same as the modal and drawer close buttons.
|
|
861
861
|
.card-close:hover {
|
|
862
|
-
background: var(--color-
|
|
863
|
-
color: var(--color-text);
|
|
862
|
+
background: var(--color-danger-soft);
|
|
863
|
+
color: var(--color-danger-text);
|
|
864
864
|
}
|
|
865
865
|
.card-close:focus-visible {
|
|
866
866
|
outline: var(--wui-focus-ring-width) solid var(--color-focus-ring);
|
package/scss/_wui-aliases.scss
CHANGED
|
@@ -25,9 +25,10 @@
|
|
|
25
25
|
--color-progress-track: var(--wui-progress-track);
|
|
26
26
|
// Label text inside a progress bar fill.
|
|
27
27
|
--color-progress-label: var(--wui-bg-light);
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
|
|
28
|
+
// Icon ink on a solid status fill (the filled timeline dots): white in both modes, by design
|
|
29
|
+
// choice. White on the bright success and warning fills sits under the 3:1 icon floor, so the
|
|
30
|
+
// contrast gate does not measure this pair.
|
|
31
|
+
--color-on-status-fill: #FFFFFF;
|
|
31
32
|
// Ink on a DEEP status fill (the -text tokens, used as a fill the way primary is): white in
|
|
32
33
|
// light mode, where those shades measure 5.5 to 6.2:1; near-black in dark mode, where -text is
|
|
33
34
|
// the bright fill.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// _wui-core.scss
|
|
3
|
+
// ----------------------------------------------------------------------------
|
|
4
|
+
// The core widget layer: every partial of _wui-components.scss except the
|
|
5
|
+
// on-demand set, in the same order. A portal imports this globally, and each
|
|
6
|
+
// on-demand partial (wui/<name>) from the lazy route that renders it.
|
|
7
|
+
//
|
|
8
|
+
// scripts/check-theme-split.mjs keeps this file in step with _wui-components.scss.
|
|
9
|
+
// The split guards two things: a widget rule left in core defeats the split,
|
|
10
|
+
// and a core rule that styles an on-demand class silently changes when that
|
|
11
|
+
// layer is absent.
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
// Shared tone-pill mixin — used by .badge, .status-label, and .chip.
|
|
15
|
+
// Must be imported before components that use it.
|
|
16
|
+
@import "wui/tone-pill";
|
|
17
|
+
|
|
18
|
+
// The order below is LOAD-BEARING. A later partial may deliberately override an
|
|
19
|
+
// earlier one, so reordering these imports silently changes the cascade — and
|
|
20
|
+
// nothing in the build will complain. `pnpm check:theme` measures the rules that
|
|
21
|
+
// have to win against Bootstrap; the rest is guarded by review.
|
|
22
|
+
@import "wui/controls";
|
|
23
|
+
@import "wui/choice";
|
|
24
|
+
@import "wui/media";
|
|
25
|
+
@import "wui/avatar-picker";
|
|
26
|
+
@import "wui/navigation";
|
|
27
|
+
@import "wui/card";
|
|
28
|
+
@import "wui/data";
|
|
29
|
+
@import "wui/illustration";
|
|
30
|
+
@import "wui/table-server";
|
|
31
|
+
@import "wui/inline-edit";
|
|
32
|
+
@import "wui/mention-input";
|
|
33
|
+
@import "wui/comment-thread";
|
|
34
|
+
@import "wui/overlays";
|
|
35
|
+
@import "wui/drawer";
|
|
36
|
+
@import "wui/modal-remote";
|
|
37
|
+
@import "wui/utilities";
|
|
38
|
+
@import "wui/typography";
|
|
39
|
+
@import "wui/disclosure";
|
|
40
|
+
@import "wui/display";
|
|
41
|
+
@import "wui/flow";
|
|
42
|
+
// After `flow`: the pricing section extends its `.plan-grid` rules.
|
|
43
|
+
@import "wui/sections";
|
|
44
|
+
@import "wui/chart";
|
|
45
|
+
@import "wui/chart-card";
|
|
46
|
+
@import "wui/scrollbar";
|
|
47
|
+
@import "wui/sortable";
|
|
48
|
+
// Before `split-view`, which places the legend sheet inside the list column.
|
|
49
|
+
@import "wui/record-pager";
|
|
50
|
+
@import "wui/shortcuts";
|
|
51
|
+
@import "wui/split-view";
|
|
52
|
+
@import "wui/groups";
|
|
53
|
+
@import "wui/carousel";
|
|
54
|
+
@import "wui/onboarding-checklist";
|
|
55
|
+
@import "wui/rating";
|
|
56
|
+
@import "wui/score-scale";
|
|
57
|
+
@import "wui/relative-time";
|
|
58
|
+
@import "wui/resizable";
|
|
59
|
+
@import "wui/rolling-number";
|
|
60
|
+
@import "wui/show-more";
|
|
61
|
+
@import "wui/truncate";
|
|
62
|
+
@import "wui/page-header-bar";
|
|
63
|
+
@import "wui/filter-popover";
|
|
64
|
+
@import "wui/metric-strip";
|
|
65
|
+
@import "wui/due-date";
|
|
66
|
+
|
|
67
|
+
// Country flags are NOT part of this layer. The 245 `.wui-flag-*` rules are about 187KB raw
|
|
68
|
+
// (38KB Brotli) of inlined SVG, and most sites never render a phone field or country picker.
|
|
69
|
+
// A site that does imports `@webority/theme/scss/flags` once, after this file; without it
|
|
70
|
+
// <wui-phone> and <wui-country-select> show an empty grey box where the flag should be.
|
|
71
|
+
@import "wui/shell";
|
|
72
|
+
@import "wui/shell-parts";
|
|
73
|
+
@import "wui/consent-banner";
|
|
74
|
+
@import "wui/lightbox";
|
|
75
|
+
@import "wui/toolbar";
|
|
76
|
+
@import "wui/theme-toggle";
|
|
77
|
+
@import "wui/floating";
|
|
78
|
+
@import "wui/code-block";
|
|
79
|
+
@import "wui/context-menu";
|
|
80
|
+
@import "wui/menubar";
|
|
81
|
+
@import "wui/navigation-menu";
|
|
82
|
+
@import "wui/hover-card";
|
|
83
|
+
@import "wui/notification-center";
|
|
84
|
+
@import "wui/whats-new";
|
|
85
|
+
// After every component partial: the shared focus ring and pressed wash settle ties with their hover rules.
|
|
86
|
+
@import "wui/interaction";
|
|
87
|
+
// Last: restates the settled state of menus other partials style, so it must win.
|
|
88
|
+
@import "wui/menu-motion";
|
package/scss/wui/_calendar.scss
CHANGED
|
@@ -240,6 +240,28 @@ wui-calendar[data-view="week"] .wui-calendar-surface > * {
|
|
|
240
240
|
--fc-event-text-color: var(--color-info-text-on-soft);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
+
// A month chip keeps the time on its first line and the title under it on up to two lines, so a
|
|
244
|
+
// title reads in a narrow cell; the full text is the chip tooltip and the day's "+N more" list.
|
|
245
|
+
wui-calendar[data-view="month"] .wui-calendar-chip {
|
|
246
|
+
flex-wrap: wrap;
|
|
247
|
+
align-items: center;
|
|
248
|
+
white-space: normal;
|
|
249
|
+
}
|
|
250
|
+
wui-calendar[data-view="month"] .wui-calendar-chip-time {
|
|
251
|
+
flex: none;
|
|
252
|
+
}
|
|
253
|
+
wui-calendar[data-view="month"] .wui-calendar-chip-title {
|
|
254
|
+
flex: 1 1 100%;
|
|
255
|
+
min-width: 0;
|
|
256
|
+
display: -webkit-box;
|
|
257
|
+
-webkit-box-orient: vertical;
|
|
258
|
+
-webkit-line-clamp: 2;
|
|
259
|
+
line-clamp: 2;
|
|
260
|
+
overflow: hidden;
|
|
261
|
+
overflow-wrap: anywhere;
|
|
262
|
+
white-space: normal;
|
|
263
|
+
}
|
|
264
|
+
|
|
243
265
|
// What a page with no script shows until the element's script replaces it.
|
|
244
266
|
.wui-calendar-fallback {
|
|
245
267
|
margin: 0;
|
|
@@ -254,3 +276,8 @@ wui-calendar[data-view="week"] .wui-calendar-surface > * {
|
|
|
254
276
|
transition: none;
|
|
255
277
|
}
|
|
256
278
|
}
|
|
279
|
+
|
|
280
|
+
// The shared pressed wash of wui/interaction, restated here so it ships with this on-demand layer.
|
|
281
|
+
:is(.wui-calendar-nav-btn, .wui-calendar-today-btn, .wui-calendar-view-btn):active:not(:disabled, [aria-disabled="true"]) {
|
|
282
|
+
background-image: linear-gradient(var(--color-pressed-overlay), var(--color-pressed-overlay)) !important;
|
|
283
|
+
}
|
package/scss/wui/_card.scss
CHANGED
|
@@ -21,14 +21,24 @@
|
|
|
21
21
|
// Default card is borderless — a flat surface. The border-STYLE stays solid (Bootstrap's
|
|
22
22
|
// `border: var(--bs-card-border-width) solid …`), so a variant or a consumer class can
|
|
23
23
|
// bring the edge back just by giving it a width (set --bs-card-border-width).
|
|
24
|
-
|
|
24
|
+
// With a unit: the inner radius below subtracts it, and calc() drops a bare 0.
|
|
25
|
+
--bs-card-border-width: 0px;
|
|
26
|
+
// Bootstrap compiles the inner radius from $card-border-radius, which is smaller than the
|
|
27
|
+
// token radius the card actually draws. The header, footer and media round their corners
|
|
28
|
+
// with it, so their fill poked out over a bordered card's corners and the border looked cut.
|
|
29
|
+
// Derive it from the live radius and border width instead.
|
|
30
|
+
--bs-card-inner-border-radius: calc(var(--bs-card-border-radius) - var(--bs-card-border-width));
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
// A card header that carries a title on the left and controls on the right — the
|
|
28
34
|
// pattern nearly every panel header uses, so it belongs here rather than being
|
|
29
35
|
// re-flexed with utilities on each one.
|
|
36
|
+
// The header and footer share the card's own fill (a muted card stays muted to its top edge),
|
|
37
|
+
// and the header carries no rule of its own: Bootstrap's divider followed the card's border
|
|
38
|
+
// width, so only the elevated variant drew one.
|
|
30
39
|
.card-header {
|
|
31
|
-
--bs-card-cap-bg:
|
|
40
|
+
--bs-card-cap-bg: transparent;
|
|
41
|
+
border-bottom: 0;
|
|
32
42
|
display: flex;
|
|
33
43
|
align-items: center;
|
|
34
44
|
justify-content: space-between;
|
|
@@ -63,8 +73,9 @@
|
|
|
63
73
|
--bs-card-border-width: 1px;
|
|
64
74
|
border-color: var(--color-border-strong);
|
|
65
75
|
}
|
|
76
|
+
// Through the variable, so the inner radius and the border agree.
|
|
66
77
|
.card-outlined {
|
|
67
|
-
border-width: 2px;
|
|
78
|
+
--bs-card-border-width: 2px;
|
|
68
79
|
border-color: var(--color-border-strong);
|
|
69
80
|
}
|
|
70
81
|
.card-muted {
|
|
@@ -88,14 +99,16 @@
|
|
|
88
99
|
.card-accent.tone-info {
|
|
89
100
|
--card-accent: var(--color-info);
|
|
90
101
|
}
|
|
102
|
+
// The stripe is a left-only border on a layer with the card's own corners. CSS corner shaping
|
|
103
|
+
// curves its inner edge with the radius minus each side's width, so the stripe thins smoothly
|
|
104
|
+
// to nothing round both left corners. A straight bar clipped by the corners showed sliced ends.
|
|
91
105
|
.card-accent::before {
|
|
92
106
|
content: "";
|
|
93
107
|
position: absolute;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
background: var(--card-accent);
|
|
108
|
+
inset: 0;
|
|
109
|
+
border-left: 4px solid var(--card-accent);
|
|
110
|
+
border-radius: inherit;
|
|
111
|
+
pointer-events: none;
|
|
99
112
|
}
|
|
100
113
|
|
|
101
114
|
// ── Padding scale ── (header + body + footer). `md` is the Bootstrap default.
|
|
@@ -114,6 +127,12 @@
|
|
|
114
127
|
.card-pad-lg > .card-footer {
|
|
115
128
|
padding: 28px 32px;
|
|
116
129
|
}
|
|
130
|
+
// With no rule under the header, its bottom padding alone separates the title from the body;
|
|
131
|
+
// the body's own top padding on top of it left a double gap. After the scale, so every
|
|
132
|
+
// padding step keeps the single gap.
|
|
133
|
+
.card > .card-header + .card-body {
|
|
134
|
+
padding-top: 0;
|
|
135
|
+
}
|
|
117
136
|
|
|
118
137
|
// ── Constrained width ── (`maxWidth`): caps + centres a standalone card. Cards
|
|
119
138
|
// are fluid (fill their column) unless this is set.
|
|
@@ -124,7 +143,7 @@
|
|
|
124
143
|
|
|
125
144
|
// ── Footer ── (React `footer` / Razor <app-card-footer>): mirrors the header row.
|
|
126
145
|
.card-footer {
|
|
127
|
-
--bs-card-cap-bg:
|
|
146
|
+
--bs-card-cap-bg: transparent;
|
|
128
147
|
display: flex;
|
|
129
148
|
align-items: center;
|
|
130
149
|
gap: 12px;
|
|
@@ -164,8 +183,8 @@
|
|
|
164
183
|
}
|
|
165
184
|
// Media flush at the top follows the card's rounded corners.
|
|
166
185
|
.card > .card-media:first-child {
|
|
167
|
-
border-top-left-radius: var(--radius
|
|
168
|
-
border-top-right-radius: var(--radius
|
|
186
|
+
border-top-left-radius: var(--bs-card-inner-border-radius);
|
|
187
|
+
border-top-right-radius: var(--bs-card-inner-border-radius);
|
|
169
188
|
}
|
|
170
189
|
|
|
171
190
|
// ── Clickable card ── (`href` / `onClick`): the whole surface is one control.
|
|
@@ -180,9 +180,13 @@ button.wui-cmd-crumb:focus-visible {
|
|
|
180
180
|
// Keeps a little of the next row visible when the keyboard scrolls the active one in.
|
|
181
181
|
scroll-margin: 6px;
|
|
182
182
|
}
|
|
183
|
+
// Focus stays in the input, and the hover tint alone marks the keyboard's row at about 1.2:1, so
|
|
184
|
+
// an inset ring makes it plain; inset, because the list scrolls and would clip an outer ring.
|
|
183
185
|
.wui-cmd-item[aria-selected="true"] {
|
|
184
186
|
background: var(--color-primary-soft);
|
|
185
187
|
color: var(--color-primary-ink);
|
|
188
|
+
outline: var(--wui-focus-ring-width) solid var(--color-focus-ring);
|
|
189
|
+
outline-offset: var(--wui-focus-ring-inset);
|
|
186
190
|
}
|
|
187
191
|
.wui-cmd-item[aria-disabled="true"] {
|
|
188
192
|
color: var(--color-text-muted);
|
|
@@ -296,3 +300,8 @@ button.wui-cmd-crumb:focus-visible {
|
|
|
296
300
|
color 0.12s ease;
|
|
297
301
|
}
|
|
298
302
|
}
|
|
303
|
+
|
|
304
|
+
// The shared pressed wash of wui/interaction, restated here so it ships with this on-demand layer.
|
|
305
|
+
:is(.wui-cmd-back, button.wui-cmd-crumb):active:not(:disabled, [aria-disabled="true"]) {
|
|
306
|
+
background-image: linear-gradient(var(--color-pressed-overlay), var(--color-pressed-overlay)) !important;
|
|
307
|
+
}
|
package/scss/wui/_controls.scss
CHANGED
|
@@ -1145,8 +1145,7 @@ $wui-field-error-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/
|
|
|
1145
1145
|
gap: 4px;
|
|
1146
1146
|
min-width: 0;
|
|
1147
1147
|
}
|
|
1148
|
-
// Inside the flex column
|
|
1149
|
-
.field > wui-rich-text,
|
|
1148
|
+
// Inside the flex column it sizes to its content, so it stretches to the field instead.
|
|
1150
1149
|
.field > wui-mention-input {
|
|
1151
1150
|
align-self: stretch;
|
|
1152
1151
|
width: 100%;
|
package/scss/wui/_data.scss
CHANGED
|
@@ -198,6 +198,7 @@
|
|
|
198
198
|
font-size: 12px;
|
|
199
199
|
font-weight: 500;
|
|
200
200
|
letter-spacing: 0.04em;
|
|
201
|
+
text-transform: uppercase;
|
|
201
202
|
white-space: nowrap;
|
|
202
203
|
vertical-align: middle;
|
|
203
204
|
transition:
|
|
@@ -484,6 +485,13 @@
|
|
|
484
485
|
overflow-x: auto;
|
|
485
486
|
scrollbar-width: none;
|
|
486
487
|
}
|
|
488
|
+
// A non-visible overflow-x makes overflow-y compute to auto, which clips the Filters panel to the bar.
|
|
489
|
+
// The phone sheet is position: fixed and escapes the clip, so the phone keeps overflow-x.
|
|
490
|
+
@media (min-width: 576px) {
|
|
491
|
+
.wui-table-toolbar-filters {
|
|
492
|
+
overflow: visible;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
487
495
|
// The search box is full-width on its own; in a toolbar it is one control among several.
|
|
488
496
|
.wui-table-toolbar .search-wrap {
|
|
489
497
|
width: min(320px, 100%);
|
|
@@ -545,6 +553,18 @@
|
|
|
545
553
|
.wui-filter-form > .wui-filter-bar {
|
|
546
554
|
display: contents !important;
|
|
547
555
|
}
|
|
556
|
+
.wui-table-toolbar-filters > .wui-filter-bar,
|
|
557
|
+
.wui-table-toolbar-filters > .wui-filter-form {
|
|
558
|
+
flex: 1 1 auto;
|
|
559
|
+
min-width: 0;
|
|
560
|
+
}
|
|
561
|
+
// An inline facet's control already shows its value, so its chip repeats it. On a phone the inline
|
|
562
|
+
// facets fold into the sheet and the chips are then the only visible values, so the hide is desktop only.
|
|
563
|
+
@media (min-width: 576px) {
|
|
564
|
+
.wui-filter-bar .wui-filter-chip-inline {
|
|
565
|
+
display: none;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
548
568
|
// On a phone each facet takes its own line; segments and buttons keep their width.
|
|
549
569
|
@media (max-width: 575.98px) {
|
|
550
570
|
.wui-filter-bar > .field,
|
|
@@ -562,6 +582,10 @@
|
|
|
562
582
|
white-space: nowrap;
|
|
563
583
|
flex: none;
|
|
564
584
|
}
|
|
585
|
+
// 3px padding and a 1px border on each side, so the strip reaches the small control height beside the other filter controls.
|
|
586
|
+
.wui-filter-bar .segmented-sm {
|
|
587
|
+
--segmented-option-h: calc(var(--wui-control-height-sm) - 8px);
|
|
588
|
+
}
|
|
565
589
|
// Facets folded behind the Filters button stack in one panel, each at the panel's width. Both surfaces
|
|
566
590
|
// draw it as the same <details>; in the Razor bar it sits inside the form, so the controls still submit.
|
|
567
591
|
.wui-filter-more-panel {
|
|
@@ -773,6 +797,24 @@
|
|
|
773
797
|
font-size: 13px;
|
|
774
798
|
user-select: none;
|
|
775
799
|
}
|
|
800
|
+
// A finger needs a 44px target: the pager's controls grow to the control height on a phone.
|
|
801
|
+
@media (max-width: 575.98px) {
|
|
802
|
+
.select.tpg-select {
|
|
803
|
+
height: var(--wui-control-height);
|
|
804
|
+
min-height: var(--wui-control-height);
|
|
805
|
+
}
|
|
806
|
+
.tpg-arrow {
|
|
807
|
+
width: var(--wui-control-height);
|
|
808
|
+
height: var(--wui-control-height);
|
|
809
|
+
}
|
|
810
|
+
.tpg-page {
|
|
811
|
+
min-width: var(--wui-control-height);
|
|
812
|
+
height: var(--wui-control-height);
|
|
813
|
+
}
|
|
814
|
+
.tpg-ellipsis {
|
|
815
|
+
height: var(--wui-control-height);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
776
818
|
|
|
777
819
|
// ── Standalone pagination (AppPagination) ──
|
|
778
820
|
// Bootstrap's .pagination is already styled; these rules refine it for the common case
|
|
@@ -1082,7 +1124,9 @@
|
|
|
1082
1124
|
align-items: flex-end;
|
|
1083
1125
|
}
|
|
1084
1126
|
// The leading cell is the card's title line: full width, no label.
|
|
1127
|
+
// Block, not the flex row of the other cells, so a name with a sub-line stacks instead of sitting beside it.
|
|
1085
1128
|
.table-ledger.wui-table-stack > * > tr > td:not(.wui-select-cell, .wui-expand-cell):is(:first-child, .wui-select-cell + td, .wui-expand-cell + td) {
|
|
1129
|
+
display: block;
|
|
1086
1130
|
justify-content: flex-start;
|
|
1087
1131
|
padding: 0 32px 6px 0;
|
|
1088
1132
|
text-align: left;
|
package/scss/wui/_display.scss
CHANGED
|
@@ -175,21 +175,27 @@
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
// Spotlight — an editorial feature tile: the label sits top-left with the icon chip pinned
|
|
178
|
-
// top-right, the value is set in the
|
|
179
|
-
//
|
|
180
|
-
//
|
|
178
|
+
// top-right, the value is set large in the product's own font, and an optional caption reads
|
|
179
|
+
// under the number. For the single showcase stat on a marketing/portal surface where the
|
|
180
|
+
// number is the hero.
|
|
181
181
|
.kpi.kpi-spotlight {
|
|
182
182
|
display: grid;
|
|
183
183
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
184
|
+
// Rows pack at the top: a tile stretched to a taller neighbour's height puts the spare
|
|
185
|
+
// space below the caption, so the label and icon row stays level across tiles.
|
|
186
|
+
align-content: start;
|
|
184
187
|
column-gap: 16px;
|
|
185
188
|
padding: 22px 24px;
|
|
186
|
-
--wui-kpi-value-size:
|
|
189
|
+
--wui-kpi-value-size: 36px;
|
|
187
190
|
}
|
|
188
191
|
.kpi.kpi-spotlight .kpi-icon {
|
|
189
192
|
grid-column: 2;
|
|
190
193
|
grid-row: 1;
|
|
191
194
|
align-self: start;
|
|
192
195
|
justify-self: end;
|
|
196
|
+
// A larger chip than the plain tile's 40px, to match the hero-sized value; the glyph keeps its size.
|
|
197
|
+
width: 48px;
|
|
198
|
+
height: 48px;
|
|
193
199
|
margin-bottom: 0;
|
|
194
200
|
}
|
|
195
201
|
.kpi.kpi-spotlight .kpi-label,
|
|
@@ -206,12 +212,9 @@
|
|
|
206
212
|
}
|
|
207
213
|
.kpi.kpi-spotlight .kpi-value {
|
|
208
214
|
margin-top: 14px;
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
// never read as serif. A product that wants its own face overrides this one selector.
|
|
212
|
-
// Size comes from --wui-kpi-value-size (44px default, set on the spotlight root above), so a
|
|
215
|
+
// No font-family: the value inherits the product's own font like every other tile.
|
|
216
|
+
// Size comes from --wui-kpi-value-size (36px default, set on the spotlight root above), so a
|
|
213
217
|
// custom `valueSize` (px) can tame a too-large headline.
|
|
214
|
-
font-family: var(--wui-font-display);
|
|
215
218
|
line-height: 1;
|
|
216
219
|
font-weight: 600;
|
|
217
220
|
}
|
|
@@ -357,6 +360,11 @@ a.info-row:hover .info-value {
|
|
|
357
360
|
border-bottom: 1px solid var(--color-border);
|
|
358
361
|
grid-column: span var(--descs-span, 1);
|
|
359
362
|
}
|
|
363
|
+
@for $n from 1 through 12 {
|
|
364
|
+
.wui-descs-span-#{$n} {
|
|
365
|
+
--descs-span: #{$n};
|
|
366
|
+
}
|
|
367
|
+
}
|
|
360
368
|
.descs-label {
|
|
361
369
|
font-size: 12px;
|
|
362
370
|
font-weight: 600;
|
|
@@ -1312,7 +1320,7 @@ a.info-row:hover .info-value {
|
|
|
1312
1320
|
position: absolute;
|
|
1313
1321
|
left: 0;
|
|
1314
1322
|
right: 0;
|
|
1315
|
-
bottom:
|
|
1323
|
+
bottom: 1px;
|
|
1316
1324
|
height: 1px;
|
|
1317
1325
|
background: currentColor;
|
|
1318
1326
|
transform: scaleX(0);
|
package/scss/wui/_dock.scss
CHANGED
|
@@ -100,3 +100,8 @@ wui-dock {
|
|
|
100
100
|
transition: none;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
// The shared pressed wash of wui/interaction, restated here so it ships with this on-demand layer.
|
|
105
|
+
.dock-item:active:not(:disabled, [aria-disabled="true"]) {
|
|
106
|
+
background-image: linear-gradient(var(--color-pressed-overlay), var(--color-pressed-overlay)) !important;
|
|
107
|
+
}
|
|
@@ -500,3 +500,8 @@ wui-file-viewer:fullscreen {
|
|
|
500
500
|
min-width: 48px;
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
+
// The shared pressed wash of wui/interaction, restated here so it ships with this on-demand layer.
|
|
504
|
+
.wui-file-viewer-zoom:active:not(:disabled, [aria-disabled="true"]) {
|
|
505
|
+
background-image: linear-gradient(var(--color-pressed-overlay), var(--color-pressed-overlay)) !important;
|
|
506
|
+
}
|
|
507
|
+
|
package/scss/wui/_floating.scss
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
flex-direction: column-reverse;
|
|
15
15
|
gap: 12px;
|
|
16
16
|
margin: 1rem;
|
|
17
|
+
// Clear the home indicator and the notch on a phone.
|
|
18
|
+
margin-bottom: max(1rem, env(safe-area-inset-bottom));
|
|
19
|
+
margin-left: max(1rem, env(safe-area-inset-left));
|
|
20
|
+
margin-right: max(1rem, env(safe-area-inset-right));
|
|
17
21
|
// The container spans only its items, but a gap between them must not swallow clicks on the page.
|
|
18
22
|
pointer-events: none;
|
|
19
23
|
}
|
|
@@ -53,9 +57,9 @@
|
|
|
53
57
|
// Quieter than the primary circle: a light brand tint, the brand icon and a thin brand border.
|
|
54
58
|
.wui-floating-btn--secondary {
|
|
55
59
|
--wui-floating-size: 40px;
|
|
56
|
-
--bs-btn-border-color: var(--
|
|
57
|
-
--bs-btn-hover-border-color: var(--
|
|
58
|
-
--bs-btn-active-border-color: var(--
|
|
60
|
+
--bs-btn-border-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
61
|
+
--bs-btn-hover-border-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
62
|
+
--bs-btn-active-border-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
59
63
|
}
|
|
60
64
|
@media (prefers-reduced-motion: reduce) {
|
|
61
65
|
.wui-floating-btn {
|