@redseed/redseed-ui-tailwindcss 7.70.0 → 7.73.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/components/dropdown_menu.css +12 -0
- package/components/dropdown_option.css +46 -1
- package/components/form_field_checkbox.css +23 -0
- package/components/form_field_radio_group.css +23 -4
- package/components/meta_info.css +30 -0
- package/components/page_header.css +40 -21
- package/components/section_header.css +18 -9
- package/components/table.css +18 -0
- package/components/toast.css +21 -11
- package/package.json +1 -1
|
@@ -50,3 +50,15 @@
|
|
|
50
50
|
@apply origin-center right-1/2 translate-x-1/2;
|
|
51
51
|
@apply sm:origin-top-right sm:right-0 sm:translate-x-0;
|
|
52
52
|
}
|
|
53
|
+
|
|
54
|
+
/* A rule between groups of options (#364).
|
|
55
|
+
*
|
|
56
|
+
* Sits in the container's `space-y-2`, so it needs no margin of its own — the 8px above
|
|
57
|
+
* and below comes from the same rule that spaces the options, and a divider that set its
|
|
58
|
+
* own margin would stack on top of it.
|
|
59
|
+
*
|
|
60
|
+
* border-t on a zero-height div rather than an <hr>: <hr> carries UA margins and a default
|
|
61
|
+
* border that would have to be reset first, and the reset is more code than the line. */
|
|
62
|
+
.rsui-dropdown-divider {
|
|
63
|
+
@apply border-t border-border-primary;
|
|
64
|
+
}
|
|
@@ -7,4 +7,49 @@
|
|
|
7
7
|
|
|
8
8
|
/* focus state */
|
|
9
9
|
@apply focus-visible:bg-background-primary-invert focus-visible:outline-hidden;
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
|
+
/* A destructive option, so Delete does not read like Copy link (#363).
|
|
12
|
+
*
|
|
13
|
+
* The base hover flips to `bg-background-primary-invert` (Grey 300), which pairs with the
|
|
14
|
+
* default ink and not with error red — hence its own pairing here rather than inheriting
|
|
15
|
+
* that one.
|
|
16
|
+
*
|
|
17
|
+
* Measured, because a pairing that looks obviously fine is exactly how #314 shipped a
|
|
18
|
+
* badge at 4.46:1:
|
|
19
|
+
*
|
|
20
|
+
* #b42318 on white (rest) 6.57:1 AA
|
|
21
|
+
* #b42318 on #fecdca (hover/focus) 4.63:1 AA
|
|
22
|
+
*
|
|
23
|
+
* `background-error-invert` rather than the lighter `background-error` (#fef3f2) for the
|
|
24
|
+
* hover ground: against the white menu, #fef3f2 is 1.09:1 and barely registers as a state
|
|
25
|
+
* change, while #fecdca is 1.42:1 — which is what the existing grey hover measures (1.43:1).
|
|
26
|
+
* So the danger option's hover is exactly as perceptible as every other option's, and red
|
|
27
|
+
* instead of grey.
|
|
28
|
+
*
|
|
29
|
+
* Colour is not the only signal (WCAG 1.4.1) — the option is paired with a trash icon and
|
|
30
|
+
* an explicit verb at the call site. Stated in the prop docs, since CSS cannot enforce it. */
|
|
31
|
+
.rsui-dropdown-option--danger {
|
|
32
|
+
@apply text-text-error;
|
|
33
|
+
@apply hover:bg-background-error-invert hover:text-text-error;
|
|
34
|
+
@apply focus-visible:bg-background-error-invert focus-visible:text-text-error;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* The icon takes the option's tone, which it does not do on its own.
|
|
38
|
+
*
|
|
39
|
+
* `<Icon>` falls back to `primary` when no colour is named, and `.rsui-icon--primary > *`
|
|
40
|
+
* PAINTS the svg directly — a declaration beats the red this option sets, however specific
|
|
41
|
+
* the ancestor. So `<DropdownOption danger><Icon sm><TrashIcon /></Icon>` rendered a red
|
|
42
|
+
* label beside a near-black trash can, and a consuming app could not correct it: no class
|
|
43
|
+
* attribute, no style attribute.
|
|
44
|
+
*
|
|
45
|
+
* The prop docs require pairing danger with an icon for WCAG 1.4.1, so leaving that icon's
|
|
46
|
+
* colour to the call site made the component depend on external code to finish its own
|
|
47
|
+
* tone. (0,2,0) here beats icon.css's (0,1,0). currentColor so hover and focus follow the
|
|
48
|
+
* option without repeating the token.
|
|
49
|
+
*
|
|
50
|
+
* Fourth place this trap has bitten — the Toast close glyph, the Toast action, the Toast
|
|
51
|
+
* icon slot, and now here. Any component that sets a tone and accepts an <Icon> must paint
|
|
52
|
+
* it. */
|
|
53
|
+
.rsui-dropdown-option--danger .rsui-icon > * {
|
|
54
|
+
color: currentColor;
|
|
55
|
+
}
|
|
@@ -46,6 +46,29 @@
|
|
|
46
46
|
@apply text-text-on-color;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
/* INDETERMINATE — some but not all. Fills the box exactly as checked does, because the
|
|
50
|
+
box is the thing being reported on and a hollow box reads as "none". The dash rather
|
|
51
|
+
than the tick is the whole distinction.
|
|
52
|
+
|
|
53
|
+
Driven by `:indeterminate`, which is a real CSS pseudo-class matching the DOM property
|
|
54
|
+
the component writes — so the glyph and what a screen reader announces ("mixed") come
|
|
55
|
+
from the same source and cannot disagree. */
|
|
56
|
+
.rsui-form-field-checkbox__check input[type="checkbox"]:indeterminate {
|
|
57
|
+
@apply bg-text-primary border-text-primary;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.rsui-form-field-checkbox__check:has(input:indeterminate:not(:disabled)) svg {
|
|
61
|
+
@apply text-text-on-color;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* No draw-on for the dash. The tick's animation strokes a path in; a two-point dash has
|
|
65
|
+
nothing to stroke, so the same keyframes just make it flicker. */
|
|
66
|
+
.rsui-form-field-checkbox__check input:indeterminate ~ svg,
|
|
67
|
+
.rsui-form-field-checkbox__check:has(input:indeterminate) svg {
|
|
68
|
+
animation: none;
|
|
69
|
+
stroke-dasharray: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
49
72
|
@keyframes rsui-checkbox-tick {
|
|
50
73
|
0% { stroke-dashoffset: 30; transform: scale(0.8); }
|
|
51
74
|
60% { transform: scale(1.06); }
|
|
@@ -33,11 +33,30 @@
|
|
|
33
33
|
@apply sr-only;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
/*
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
/* An anchor names the end of the scale, not any one radio, so it ranks under the question
|
|
37
|
+
rather than level with it.
|
|
38
|
+
|
|
39
|
+
Sized explicitly, because nothing in the radio-group chain set a size — not __items, not
|
|
40
|
+
the root, and __item-label has none either — so an anchor inherited the document's 16px.
|
|
41
|
+
Measured across the likert stories, before and after:
|
|
42
|
+
|
|
43
|
+
story question anchor before anchor after
|
|
44
|
+
Likert 16px / 600 16px (level) 14px ranks under
|
|
45
|
+
LikertFivePoint 16px / 600 16px (level) 14px ranks under
|
|
46
|
+
LikertNarrow 14px / 500 16px (LARGER) 14px level, see below
|
|
47
|
+
|
|
48
|
+
The `lg` cases are the ones the issue was raised about and they now read correctly.
|
|
49
|
+
|
|
50
|
+
LikertNarrow is the residual: it passes no `lg`, so its question is already 14px and the
|
|
51
|
+
anchor lands level with it, separated by weight alone (500 against 400). That is still a
|
|
52
|
+
clear improvement — the anchor was BIGGER than its question before — and it is as far as
|
|
53
|
+
size can take it, because 12px would put the anchor under the brand's 14px caption floor.
|
|
54
|
+
Fixing it properly means the question growing, not the anchor shrinking.
|
|
55
|
+
|
|
56
|
+
Deliberately does NOT follow __item-label any more, which the previous comment tied it
|
|
57
|
+
to. That pairing is invisible in likert mode anyway, where __item-label is sr-only. */
|
|
39
58
|
.rsui-form-field-radio-group__anchor {
|
|
40
|
-
@apply shrink-0 font-normal text-text-primary;
|
|
59
|
+
@apply shrink-0 font-normal text-sm text-text-primary;
|
|
41
60
|
}
|
|
42
61
|
|
|
43
62
|
.rsui-form-field-radio-group__item {
|
package/components/meta_info.css
CHANGED
|
@@ -164,3 +164,33 @@
|
|
|
164
164
|
.rsui-meta-info--inline {
|
|
165
165
|
@apply flex-row flex-wrap items-center gap-x-space-xs gap-y-space-xs;
|
|
166
166
|
}
|
|
167
|
+
|
|
168
|
+
/* A subordinate line under the value (#361). `#subtitle` is the library's convention —
|
|
169
|
+
* SectionHeader, CardHeader, SectionSlider, PageHeader, Table and CheckboxCard all have
|
|
170
|
+
* one, and MetaInfo was the only header-ish component without.
|
|
171
|
+
*
|
|
172
|
+
* It qualifies the value rather than competing with it, so it gives up the value's
|
|
173
|
+
* semibold and its near-black: normal weight, secondary tone. Same relationship the card
|
|
174
|
+
* and section subtitles have to their titles.
|
|
175
|
+
*
|
|
176
|
+
* No margin — the root is a flex column whose row gap already puts the same 4px here as it
|
|
177
|
+
* does between the label and the value. A margin would stack on top of it.
|
|
178
|
+
*
|
|
179
|
+
* Not supported with `inline`: that modifier makes the root a wrapping ROW, so a subtitle
|
|
180
|
+
* joins the row instead of sitting under the value. The two say opposite things about the
|
|
181
|
+
* shape of the field, so this is documented rather than fought with CSS. */
|
|
182
|
+
.rsui-meta-info__subtitle {
|
|
183
|
+
@apply font-normal text-text-secondary;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.rsui-meta-info--sm .rsui-meta-info__subtitle {
|
|
187
|
+
@apply text-xs;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.rsui-meta-info--md .rsui-meta-info__subtitle {
|
|
191
|
+
@apply text-sm;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.rsui-meta-info--lg .rsui-meta-info__subtitle {
|
|
195
|
+
@apply text-base;
|
|
196
|
+
}
|
|
@@ -22,9 +22,18 @@
|
|
|
22
22
|
@apply w-full flex flex-col justify-between gap-y-space-md;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/* lg:gap-y-space-md, not lg:gap-y-0 (#265). This row is flex-wrap at every width, so once
|
|
26
|
+
the title block is wide enough that the actions cannot sit beside it — roughly the
|
|
27
|
+
1024-1279 band, or any lg header with a long subtitle — the actions wrap to a second
|
|
28
|
+
line and used to land flush against the text above them.
|
|
29
|
+
|
|
30
|
+
row-gap only applies BETWEEN wrapped lines, so the ordinary single-row lg header is
|
|
31
|
+
pixel-unchanged; there is no second line for it to open up. That is why the fix is a
|
|
32
|
+
row gap rather than padding or a margin, and why lg:gap-y-0 could be dropped outright
|
|
33
|
+
instead of being made conditional. */
|
|
25
34
|
.rsui-page-header__top {
|
|
26
35
|
@apply w-full flex flex-col items-start gap-y-space-xs flex-wrap;
|
|
27
|
-
@apply lg:flex-row lg:gap-y-
|
|
36
|
+
@apply lg:flex-row lg:gap-y-space-md lg:items-center;
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
/* 16px avatar -> title, matching the card family's avatar gap, and set once as a gap
|
|
@@ -57,7 +66,7 @@
|
|
|
57
66
|
lg:mr-4 removed. __title-text-container already supplies a 24px gap between the title
|
|
58
67
|
and the status slot, so the margin added to it and the rendered gap was 40px — the
|
|
59
68
|
same accidental sum the avatar had. */
|
|
60
|
-
.rsui-page-header__title
|
|
69
|
+
.rsui-page-header__title .rsui-page-header__heading {
|
|
61
70
|
@apply text-[1.75rem] leading-[1.2] font-bold text-text-primary;
|
|
62
71
|
@apply lg:text-[2.5rem] lg:leading-[1.15] lg:tracking-[-0.01em] lg:font-black;
|
|
63
72
|
}
|
|
@@ -310,30 +319,40 @@
|
|
|
310
319
|
@apply grid w-fit max-w-full items-start;
|
|
311
320
|
@apply gap-x-space-lg gap-y-space-md;
|
|
312
321
|
|
|
313
|
-
/*
|
|
322
|
+
/* Sized to content, and a cluster rather than a band. Straight from the standard:
|
|
323
|
+
"A grid four columns wide, only as wide as its content, so meta reads as one
|
|
324
|
+
cluster beside the title rather than a band across the page."
|
|
314
325
|
|
|
315
|
-
|
|
316
|
-
toggle would sit in the row rather than wrap. That moved every fact
|
|
317
|
-
sideways when pressed — 13.7px with `1fr`, up to 40px with `max-content`,
|
|
318
|
-
because both make a column's width depend on something the toggle changes.
|
|
319
|
-
Holding the count fixed removes the question: the toggle occupies the
|
|
320
|
-
fifth cell while collapsed, and the fifth fact takes it once expanded.
|
|
326
|
+
That sentence rules out both things this rule has been at different times.
|
|
321
327
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
328
|
+
It was `repeat(5, 6rem)` — a flat track, chosen because it depends on neither the
|
|
329
|
+
column count nor the content, so pressing the toggle could not move anything. But a
|
|
330
|
+
track that ignores content also ignores the room available: at 96px a real date,
|
|
331
|
+
"26 Sept 2026, 15:30 · 30 minutes", wrapped onto three lines with most of the header
|
|
332
|
+
empty beside it. A phone-width decision applied at every width.
|
|
327
333
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
334
|
+
Then it was briefly `w-full` with `minmax(6rem, 16rem)`, which fixed the wrapping by
|
|
335
|
+
making the region span the page — precisely the band the standard rejects.
|
|
336
|
+
|
|
337
|
+
`max-content` with a 6rem floor is what the standard describes: each column as wide
|
|
338
|
+
as the fact in it, the whole cluster only as wide as it needs, and the floor keeping
|
|
339
|
+
short facts from collapsing to nothing.
|
|
340
|
+
|
|
341
|
+
The toggle-press resize comes back, and that is correct — the standard expects it
|
|
342
|
+
and gives the numbers: "Open it and the remaining five fill out the grid: 118px
|
|
343
|
+
becomes 188px, still a cluster beside the title." A grid sized to its content has to
|
|
344
|
+
change size when its content changes. Holding it still was solving a problem the
|
|
345
|
+
standard does not have.
|
|
346
|
+
|
|
347
|
+
Five tracks, not four: four for facts, and the fifth is where the toggle sits — "a
|
|
348
|
+
toggle sitting where the fifth would be, at every width". Two on a phone, because
|
|
349
|
+
four labels across 375px is a queue, not a grid. */
|
|
350
|
+
grid-template-columns: repeat(2, minmax(6rem, max-content));
|
|
332
351
|
}
|
|
333
352
|
|
|
334
353
|
@media (min-width: 40rem) {
|
|
335
354
|
.rsui-page-header__meta-region {
|
|
336
|
-
grid-template-columns: repeat(5, 6rem);
|
|
355
|
+
grid-template-columns: repeat(5, minmax(6rem, max-content));
|
|
337
356
|
}
|
|
338
357
|
}
|
|
339
358
|
|
|
@@ -539,7 +558,7 @@
|
|
|
539
558
|
|
|
540
559
|
/* Ink application is tone-agnostic: only the variable values differ, so the
|
|
541
560
|
light tone resolves these to dark ink through the same rules. */
|
|
542
|
-
.rsui-page-header--toned .rsui-page-header__title
|
|
561
|
+
.rsui-page-header--toned .rsui-page-header__title .rsui-page-header__heading {
|
|
543
562
|
color: var(--rsui-page-header-ink);
|
|
544
563
|
}
|
|
545
564
|
|
|
@@ -567,7 +586,7 @@
|
|
|
567
586
|
|
|
568
587
|
27px below lg, 36px from lg up — the twin's two sizes.
|
|
569
588
|
--------------------------------------------------------------------------- */
|
|
570
|
-
.rsui-page-header--tone-bloom .rsui-page-header__title
|
|
589
|
+
.rsui-page-header--tone-bloom .rsui-page-header__title .rsui-page-header__heading {
|
|
571
590
|
@apply font-redseed-heading text-[1.6875rem] font-semibold;
|
|
572
591
|
@apply leading-[1.1] tracking-[-0.01em];
|
|
573
592
|
@apply lg:text-[2.25rem] lg:leading-[1.1] lg:font-semibold;
|
|
@@ -1,17 +1,26 @@
|
|
|
1
|
+
/* min-w-0, not overflow-hidden, for the useResponsiveWidth feedback loop (mobile width
|
|
2
|
+
briefly misreported, widened content re-triggers the observer, locking the broken
|
|
3
|
+
layout in).
|
|
4
|
+
|
|
5
|
+
Both were added together in 64bcce98 for that one loop: `overflow-hidden` here and
|
|
6
|
+
`min-w-0` on __header below. Only the min-width half does the work. An overflow-hidden
|
|
7
|
+
box is a scroll container, so its automatic minimum size drops to zero — that is the
|
|
8
|
+
whole mechanism, and `min-w-0` states it directly instead of buying it as a side effect
|
|
9
|
+
of clipping. Measured in a 320px flex container: overflow-hidden 318px, nothing 344.84px
|
|
10
|
+
(the loop), min-width:0 318px. Identical protection.
|
|
11
|
+
|
|
12
|
+
The clipping was never wanted and has cost twice. It clipped an open dropdown menu in
|
|
13
|
+
the header (c3c2a994 added a :has() carve-out, deleted here along with the rule it was
|
|
14
|
+
carving out of), and it clips the actions themselves: a default-size button leaves the
|
|
15
|
+
header exactly 0px of headroom, so its 4px focus ring is cropped flat — measured, and
|
|
16
|
+
the reason #385 sees a button lose its bottom edge. A header must render what it was
|
|
17
|
+
handed, and a focus ring is not optional. */
|
|
1
18
|
.rsui-section-header {
|
|
2
|
-
@apply flex flex-col gap-x-space-md gap-y-space-md transition-all;
|
|
19
|
+
@apply flex flex-col gap-x-space-md gap-y-space-md transition-all min-w-0;
|
|
3
20
|
@apply md:flex-row md:justify-between md:items-center;
|
|
4
21
|
@apply border-b border-transparent;
|
|
5
22
|
}
|
|
6
23
|
|
|
7
|
-
/* overflow-hidden guards against a useResponsiveWidth feedback loop (mobile
|
|
8
|
-
width briefly misreported, widened content re-triggers the observer,
|
|
9
|
-
locking the broken layout in). Opt out while a dropdown menu is open in
|
|
10
|
-
the header — otherwise the menu gets clipped by this boundary. */
|
|
11
|
-
.rsui-section-header:not(:has(.rsui-dropdown-menu__container--open)) {
|
|
12
|
-
@apply overflow-hidden;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
24
|
/* The --divider class was being set by SectionHeader.vue with no rule behind it, so
|
|
16
25
|
showDivider did nothing. Implemented the way CardHeader does it — a transparent
|
|
17
26
|
bottom border on the base, coloured here — and the prop's default flips to false in
|
package/components/table.css
CHANGED
|
@@ -60,3 +60,21 @@
|
|
|
60
60
|
.rsui-table__footer {
|
|
61
61
|
@apply w-full border-t border-border-primary overflow-hidden py-space-sm px-space-lg;
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
/* The selection column. Content-width, because a checkbox does not need a share of the
|
|
65
|
+
table and a column that grows pushes the data it sits beside off the screen first.
|
|
66
|
+
Centred so the boxes form a straight line down the page rather than tracking the
|
|
67
|
+
varying width of whatever is in the cell. */
|
|
68
|
+
.rsui-table__select-cell {
|
|
69
|
+
@apply w-px whitespace-nowrap text-center align-middle;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* The checkbox brings its own field spacing, which is right in a form and wrong in a table
|
|
73
|
+
cell — it made the selection column taller than every other row. */
|
|
74
|
+
.rsui-table__select-cell .rsui-form-field-slot {
|
|
75
|
+
@apply gap-0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.rsui-table__select-cell .rsui-form-field-checkbox__checkbox {
|
|
79
|
+
@apply justify-center;
|
|
80
|
+
}
|
package/components/toast.css
CHANGED
|
@@ -32,24 +32,34 @@
|
|
|
32
32
|
@apply text-sm font-medium;
|
|
33
33
|
@apply bg-background-primary-contrast text-text-on-color border border-transparent;
|
|
34
34
|
|
|
35
|
-
/* BOTTOM-LEFT, and it must clear
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
/* BOTTOM-LEFT, and it must clear three things the toast cannot see. Both offsets
|
|
36
|
+
below go on :root, NOT on a wrapper: the toast is teleported to the body, so a
|
|
37
|
+
custom property declared anywhere in the consumer's component tree never reaches
|
|
38
|
+
it. Both default to 0, so an ordinary page sets neither.
|
|
39
|
+
|
|
40
|
+
--rsui-toast-offset moves it UP. Written for a sticky action bar — the standards
|
|
41
|
+
are explicit that a toast sits above one and never over it, because the bar owns
|
|
42
|
+
the bottom edge — but it serves any furniture parked in that corner. In the LMS
|
|
43
|
+
that is the Help Scout Beacon launcher.
|
|
44
|
+
|
|
45
|
+
--rsui-toast-offset-inline moves it IN, and exists for the same reason one corner
|
|
46
|
+
can hold two things: clearing a launcher vertically is not enough if the toast then
|
|
47
|
+
sits flush to the viewport edge while the launcher is indented, because the two
|
|
48
|
+
read as misaligned rather than stacked. The page knows its own left gutter; the
|
|
49
|
+
toast cannot. (Unsuffixed is the vertical axis, for backwards compatibility with
|
|
50
|
+
the name that shipped in 10.1.0.)
|
|
43
51
|
|
|
44
52
|
env(safe-area-inset-bottom) is the home indicator. A toast is the last thing above
|
|
45
53
|
the bottom edge on a phone, so the inset is a FLOOR under the spacing rather than
|
|
46
54
|
an addition to it — the same max() shape drawer.css and modal.css already use. */
|
|
47
|
-
left: 1rem;
|
|
55
|
+
left: calc(1rem + var(--rsui-toast-offset-inline, 0px));
|
|
48
56
|
bottom: calc(max(1rem, env(safe-area-inset-bottom)) + var(--rsui-toast-offset, 0px));
|
|
49
57
|
|
|
50
58
|
/* Brief, so it is never a paragraph. Wide enough for a sentence, capped so it does
|
|
51
|
-
not stretch across a desktop, and held off both edges on a narrow screen
|
|
52
|
-
|
|
59
|
+
not stretch across a desktop, and held off both edges on a narrow screen — the
|
|
60
|
+
inline offset is subtracted too, or pushing the toast right would run it off the
|
|
61
|
+
opposite edge on a phone. */
|
|
62
|
+
max-width: min(28rem, calc(100vw - 2rem - var(--rsui-toast-offset-inline, 0px)));
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
/* The message is the only part allowed to grow, so the action and the close button keep
|