@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority/theme",
3
- "version": "0.76.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": {
@@ -27,12 +27,11 @@
27
27
  }
28
28
 
29
29
  .btn-primary {
30
- // Pin hover/active to the pressed-primary token so a rebrand tracks
31
- // automatically instead of Bootstrap auto-shading $primary off-spec.
32
- --bs-btn-hover-bg: var(--wui-primary-pressed);
33
- --bs-btn-hover-border-color: var(--wui-primary-pressed);
34
- --bs-btn-active-bg: var(--wui-primary-pressed);
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-bg-muted);
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);
@@ -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
- // Ink on a solid status fill (success, warning, danger, info): near-black in both modes, since
29
- // white fails AA on the bright fills.
30
- --color-on-status-fill: #0F0F0F;
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";
@@ -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
+ }
@@ -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
- --bs-card-border-width: 0;
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: var(--color-surface);
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
- top: 0;
95
- bottom: 0;
96
- left: 0;
97
- width: 4px;
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: var(--color-surface);
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-lg);
168
- border-top-right-radius: var(--radius-lg);
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
+ }
@@ -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 these two size to their content, so they stretch to the field instead.
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%;
@@ -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;
@@ -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 display face (a product's serif brand face when it
179
- // overrides --wui-font-display), and an optional caption reads under the number. For the
180
- // single showcase stat on a marketing/portal surface where the number is the hero.
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: 44px;
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
- // The editorial serif is this variant's signature (see the reference tile), so the value gets
210
- // a serif stack directly — not --wui-font-display, which defaults to the body sans and so would
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: -2px;
1323
+ bottom: 1px;
1316
1324
  height: 1px;
1317
1325
  background: currentColor;
1318
1326
  transform: scaleX(0);
@@ -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
+
@@ -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(--wui-primary-30);
57
- --bs-btn-hover-border-color: var(--wui-primary-30);
58
- --bs-btn-active-border-color: var(--wui-primary-30);
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 {