@apliteni/apliteni-ui 0.100.0 → 0.104.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 +1 -1
- package/react/README.md +11 -1
- package/react/dist/index.css +7 -8
- package/react/dist/index.d.ts +8 -2
- package/react/dist/index.js +6 -3
- package/src/components/shell.js +11 -3
- package/src/styles/layout.css +41 -1
- package/src/styles/segmented.css +1 -0
- package/src/styles/tap-zone.css +25 -1
- package/src/styles/topbar.css +23 -4
package/package.json
CHANGED
package/react/README.md
CHANGED
|
@@ -32,7 +32,17 @@ import { DataTable, Modal, Button } from '@apliteni/apliteni-ui/react';
|
|
|
32
32
|
Both stylesheets. The React one adds what React's own components need — it carries no tokens, no
|
|
33
33
|
reset and none of the kit's control CSS, so it cannot stand in for the first import.
|
|
34
34
|
|
|
35
|
-
Components: `Success`, `SuccessPanel`, `SuccessCheck`, `Checkbox`, `Switch`, `SearchField`, `EmptyState`, `DataTable`, `Pagination`, `StatBand`, `Modal`, `Confirm`, `Drawer`, `CommandPalette`, `Dropdown`, `BackLink`, `Tooltip`, `Snippet`, `Tabs`, `Button`, `Badge`, `Pill`, `StatusDot`, `Card`, `Callout`, `Icon`.
|
|
35
|
+
Components: `Success`, `SuccessPanel`, `SuccessCheck`, `Checkbox`, `Switch`, `SearchField`, `EmptyState`, `DataTable`, `Pagination`, `StatBand`, `Modal`, `Confirm`, `Drawer`, `CommandPalette`, `Dropdown`, `BackLink`, `Tooltip`, `Snippet`, `Segmented`, `Tabs`, `Button`, `Badge`, `Pill`, `StatusDot`, `Card`, `Callout`, `Icon`.
|
|
36
|
+
|
|
37
|
+
`Segmented` is a controlled choice toolbar: pass `options`, `value`, `onChange`,
|
|
38
|
+
and a `label` for its accessible name. `size="sm"` compacts it, `block` makes it
|
|
39
|
+
fill its container, and `appearance="underline"` draws the underline strip instead
|
|
40
|
+
of the pill track; omit all three for the standard pill. Options support
|
|
41
|
+
`ariaLabel` and `disabled`; `disabled` on the toolbar disables every choice. What
|
|
42
|
+
each presentation guarantees is in
|
|
43
|
+
docs/components.md#the-rest-of-the-react-surface.
|
|
44
|
+
Reach for it when a choice filters or switches a view in place; use `Tabs` when the
|
|
45
|
+
choice owns a panel, and links when it changes the page.
|
|
36
46
|
|
|
37
47
|
`Pill` renders metadata with the existing pill spacing. Omit `variant` for neutral
|
|
38
48
|
metadata or use `live` or `soon`. Its children accept React content.
|
package/react/dist/index.css
CHANGED
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
--tap-clear-y: 0px;
|
|
37
37
|
}
|
|
38
38
|
@media (max-width: 560px) and (pointer: coarse) {
|
|
39
|
-
:where(.ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social, .ui-datepicker__opt) {
|
|
39
|
+
:where(.ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social, .ui-app__search, .toggle, .ui-datepicker__opt) {
|
|
40
40
|
position: relative;
|
|
41
41
|
}
|
|
42
|
-
:where(.ui-btn, .ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social, .ui-switch, .ui-datepicker__opt)::after {
|
|
42
|
+
:where(.ui-btn, .ui-seg button, .ui-tabs__tab, .ui-dropdown__trigger, .ui-toast__action, .ui-drawer__close, .ui-snippet__copy, .ui-footer__social, .ui-switch, .ui-datepicker__opt, .ui-app__search, .toggle)::after {
|
|
43
43
|
content: "";
|
|
44
44
|
position: absolute;
|
|
45
45
|
left: 50%;
|
|
@@ -133,6 +133,11 @@
|
|
|
133
133
|
--tap-clear-x: var(--tap-gap);
|
|
134
134
|
--tap-clear-y: var(--tap-gap);
|
|
135
135
|
}
|
|
136
|
+
.ui-app__bar,
|
|
137
|
+
.topbar__in {
|
|
138
|
+
--tap-clear-x: var(--space-3, 12px);
|
|
139
|
+
--tap-clear-y: var(--space-3, 12px);
|
|
140
|
+
}
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
/* ../src/styles/tooltip.css */
|
|
@@ -872,12 +877,6 @@
|
|
|
872
877
|
.ui-react-app .ui-app__bar {
|
|
873
878
|
padding-inline: var(--space-4);
|
|
874
879
|
}
|
|
875
|
-
.ui-react-app .ui-app__search {
|
|
876
|
-
min-width: 0;
|
|
877
|
-
}
|
|
878
|
-
.ui-react-app .ui-app__search kbd {
|
|
879
|
-
display: none;
|
|
880
|
-
}
|
|
881
880
|
.ui-react-app .ui-app__bar > .ui-app__brand {
|
|
882
881
|
display: none;
|
|
883
882
|
}
|
package/react/dist/index.d.ts
CHANGED
|
@@ -545,9 +545,11 @@ type SegmentedProps = {
|
|
|
545
545
|
onChange: (value: string) => void;
|
|
546
546
|
label: string;
|
|
547
547
|
appearance?: 'pill' | 'underline';
|
|
548
|
+
size?: 'sm';
|
|
549
|
+
block?: boolean;
|
|
548
550
|
disabled?: boolean;
|
|
549
551
|
};
|
|
550
|
-
declare function Segmented({ options, value, onChange, label, appearance, disabled }: SegmentedProps): react.JSX.Element;
|
|
552
|
+
declare function Segmented({ options, value, onChange, label, appearance, size, block, disabled }: SegmentedProps): react.JSX.Element;
|
|
551
553
|
|
|
552
554
|
type Filter = {
|
|
553
555
|
id: string;
|
|
@@ -776,6 +778,10 @@ type AppShellProps = {
|
|
|
776
778
|
lede?: string;
|
|
777
779
|
actions?: ReactNode;
|
|
778
780
|
bandControl?: ReactNode;
|
|
781
|
+
/** The band trigger's words. Below 560px the shell draws `searchShortLabel` instead;
|
|
782
|
+
* both stay the button's name, which does not change with the viewport. */
|
|
783
|
+
searchLabel?: string;
|
|
784
|
+
searchShortLabel?: string;
|
|
779
785
|
account: {
|
|
780
786
|
name: string;
|
|
781
787
|
email: string;
|
|
@@ -787,7 +793,7 @@ type AppShellProps = {
|
|
|
787
793
|
/** Spread linkProps onto the router link, including children and onClick. */
|
|
788
794
|
renderLink?: (section: AppShellSection, linkProps: ComponentPropsWithoutRef<'a'>) => ReactNode;
|
|
789
795
|
};
|
|
790
|
-
declare function AppShell({ sections, pathname, title, children, word, brand, brandHref, width, back, lede, actions, bandControl, account, onSignOut, defaultCollapsed, palette, renderLink }: AppShellProps): react.JSX.Element;
|
|
796
|
+
declare function AppShell({ sections, pathname, title, children, word, brand, brandHref, width, back, lede, actions, bandControl, account, onSignOut, searchLabel, searchShortLabel, defaultCollapsed, palette, renderLink }: AppShellProps): react.JSX.Element;
|
|
791
797
|
|
|
792
798
|
type EmptyStateVariant = 'first-run' | 'no-matches' | 'not-found' | 'not-yet-built';
|
|
793
799
|
type EmptyStateProps = {
|
package/react/dist/index.js
CHANGED
|
@@ -2519,10 +2519,10 @@ function RowIdentity({ symbol, name, logo, href }) {
|
|
|
2519
2519
|
// src/Segmented.tsx
|
|
2520
2520
|
import { segmentedNextIndex } from "@apliteni/apliteni-ui";
|
|
2521
2521
|
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2522
|
-
function Segmented({ options, value, onChange, label, appearance = "pill", disabled = false }) {
|
|
2522
|
+
function Segmented({ options, value, onChange, label, appearance = "pill", size, block = false, disabled = false }) {
|
|
2523
2523
|
const enabled = options.filter((o) => !o.disabled);
|
|
2524
2524
|
const tabValue = enabled.some((o) => o.value === value) ? value : enabled[0]?.value;
|
|
2525
|
-
return /* @__PURE__ */ jsx23("div", { className: `ui-seg${appearance === "underline" ? " ui-seg--underline" : ""}`, role: "toolbar", "aria-label": label, children: options.map((option) => /* @__PURE__ */ jsx23(
|
|
2525
|
+
return /* @__PURE__ */ jsx23("div", { className: `ui-seg${size === "sm" ? " ui-seg--sm" : ""}${block ? " ui-seg--block" : ""}${appearance === "underline" ? " ui-seg--underline" : ""}`, role: "toolbar", "aria-label": label, children: options.map((option) => /* @__PURE__ */ jsx23(
|
|
2526
2526
|
"button",
|
|
2527
2527
|
{
|
|
2528
2528
|
type: "button",
|
|
@@ -3407,6 +3407,8 @@ function AppShell({
|
|
|
3407
3407
|
bandControl,
|
|
3408
3408
|
account,
|
|
3409
3409
|
onSignOut,
|
|
3410
|
+
searchLabel = "Search or run a command\u2026",
|
|
3411
|
+
searchShortLabel = "Search",
|
|
3410
3412
|
defaultCollapsed = false,
|
|
3411
3413
|
palette,
|
|
3412
3414
|
renderLink
|
|
@@ -3514,7 +3516,8 @@ function AppShell({
|
|
|
3514
3516
|
!navigable && lockup,
|
|
3515
3517
|
/* @__PURE__ */ jsxs29("button", { type: "button", className: "ui-app__search", "aria-haspopup": "dialog", onClick: () => setSearch(true), children: [
|
|
3516
3518
|
/* @__PURE__ */ jsx34("span", { className: "ui-app__search-ic", children: /* @__PURE__ */ jsx34(Icon, { name: "search" }) }),
|
|
3517
|
-
/* @__PURE__ */ jsx34("span", { className: "ui-app__search-txt", children:
|
|
3519
|
+
/* @__PURE__ */ jsx34("span", { className: "ui-app__search-txt", children: searchLabel }),
|
|
3520
|
+
/* @__PURE__ */ jsx34("span", { className: "ui-app__search-short", "aria-hidden": "true", children: searchShortLabel }),
|
|
3518
3521
|
/* @__PURE__ */ jsx34("kbd", { className: "ui-cmdk__key", children: paletteHotkey() })
|
|
3519
3522
|
] }),
|
|
3520
3523
|
/* @__PURE__ */ jsx34("span", { className: "ui-app__bar-gap" }),
|
package/src/components/shell.js
CHANGED
|
@@ -91,12 +91,17 @@ const toWidth = (v) => (v === 'wide' ? 'wide' : 'centered');
|
|
|
91
91
|
|
|
92
92
|
// `search: 'palette-id'`, or the same id in `{ palette }` with a placeholder beside
|
|
93
93
|
// it. No palette to open, no field — the argument `signOutHref` takes.
|
|
94
|
-
//
|
|
94
|
+
// `shortLabel` is the word the band draws below 560px, where the sentence used to
|
|
95
|
+
// truncate mid-word. why: docs/components.md#the-page-shell
|
|
95
96
|
const toSearch = (v) => {
|
|
96
97
|
const given = typeof v === 'string' ? { palette: v } : (isRecord(v) && !Array.isArray(v) ? v : null);
|
|
97
98
|
const palette = given && typeof given.palette === 'string' ? given.palette.trim() : '';
|
|
98
99
|
if (!palette) return null;
|
|
99
|
-
return {
|
|
100
|
+
return {
|
|
101
|
+
palette,
|
|
102
|
+
placeholder: str(given.placeholder) || 'Search or run a command…',
|
|
103
|
+
shortLabel: str(given.shortLabel) || 'Search',
|
|
104
|
+
};
|
|
100
105
|
};
|
|
101
106
|
|
|
102
107
|
// `maxWidth` lands inside a style attribute, so a length is all this accepts — a number
|
|
@@ -236,10 +241,13 @@ function readerBlock({ name, email }, signOutHref, { band = false } = {}) {
|
|
|
236
241
|
// A field to look at, a button to press. `data-cmdk-open` and the cap's class are the
|
|
237
242
|
// palette's own, and the cap is NOT aria-hidden: it is half the button's name.
|
|
238
243
|
// why: docs/components.md#the-page-shell
|
|
239
|
-
|
|
244
|
+
// The short word repeats the sentence, so it is `aria-hidden`: the sentence and the
|
|
245
|
+
// cap are the name at every width, and layout.css clips rather than drops them.
|
|
246
|
+
const searchField = ({ palette, placeholder, shortLabel }) =>
|
|
240
247
|
`<button type="button" class="ui-app__search" data-cmdk-open="${esc(palette)}" aria-haspopup="dialog">`
|
|
241
248
|
+ `<span class="ui-app__search-ic" aria-hidden="true">${icon('search')}</span>`
|
|
242
249
|
+ `<span class="ui-app__search-txt">${esc(placeholder)}</span>`
|
|
250
|
+
+ `<span class="ui-app__search-short" aria-hidden="true">${esc(shortLabel)}</span>`
|
|
243
251
|
+ `<kbd class="ui-cmdk__key" data-palette-hotkey>${esc(paletteHotkey())}</kbd>`
|
|
244
252
|
+ `</button>`;
|
|
245
253
|
|
package/src/styles/layout.css
CHANGED
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
resting step. */
|
|
120
120
|
/* Re-tuned at #295, which took the light rail down a step with the page. Below 720px
|
|
121
121
|
the glyph is the whole row, so it is held at text grade rather than at 1.4.11's bar —
|
|
122
|
-
stories/apps/shell-states.test.js:
|
|
122
|
+
stories/apps/shell-states.test.js:1704 `a resting glyph is dimmer but still legible`. */
|
|
123
123
|
.ui-app__rail .ui-nav__ic svg { opacity: 0.66; }
|
|
124
124
|
|
|
125
125
|
/* A destructive row of the rail is a navigation row and rests like one; the danger
|
|
@@ -404,11 +404,26 @@
|
|
|
404
404
|
.ui-app__search-txt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
405
405
|
/* The other half of the name, so it never gives way. */
|
|
406
406
|
.ui-app__search kbd { flex: none; }
|
|
407
|
+
/* The one word the phone band draws instead of the sentence. Above 560px the
|
|
408
|
+
sentence fits and this is a second copy of it, so it is not drawn.
|
|
409
|
+
why: docs/components.md#the-page-shell */
|
|
410
|
+
.ui-app__search-short { display: none; }
|
|
407
411
|
|
|
408
412
|
/* The mark alone — no room for two lines on a 52px row. No rule over it, since the
|
|
409
413
|
band's hairline is under the whole of it, and no column, since this is not the rail.
|
|
410
414
|
why: docs/components.md#the-page-shell */
|
|
411
415
|
.ui-app__user--bar { flex: none; padding-top: 0; border-top: 0; }
|
|
416
|
+
/* The switch is a 34px square and stays one: the trigger above is the thing on this
|
|
417
|
+
band that gives way, and a flex item with the default shrink does not wait its
|
|
418
|
+
turn. Measured at 390 with a control beside the trigger, the React band's switch
|
|
419
|
+
drew 19x34 and the strategy topbar's drew 28.47x34 — a square glyph plate squashed,
|
|
420
|
+
and a tap zone the sheet could only clamp to 29 or 39.
|
|
421
|
+
Pinning the strategy topbar's half of this rule does not make its row narrower: it
|
|
422
|
+
moves a 5.53px shortfall onto the account block's trailing gutter instead, because
|
|
423
|
+
nothing before it in that row has width to spare. topbar.css's --space-2 comment
|
|
424
|
+
names that choice and the gutter it leaves.
|
|
425
|
+
why: docs/components.md#the-page-shell */
|
|
426
|
+
.ui-app__bar .toggle, .topbar__in .toggle { flex: none; }
|
|
412
427
|
.ui-app__user--bar .ui-app__av { margin-inline-start: 0; }
|
|
413
428
|
/* Crumb, then the title block. At --space-2 the crumb sat 8px off the h1 and
|
|
414
429
|
the h1 8px off its subtitle, so all three ranks read as one. */
|
|
@@ -518,6 +533,31 @@
|
|
|
518
533
|
.ui-app__main .ui-card__row { flex-wrap: wrap; gap: var(--space-3); }
|
|
519
534
|
}
|
|
520
535
|
|
|
536
|
+
/* -- The band's search at one column --------------------------------------- */
|
|
537
|
+
/* The band holds the trigger, the reader's mark and whatever the page puts between
|
|
538
|
+
them, so the sentence broke mid-word — "Search or run a co…". The short word takes
|
|
539
|
+
its place. Neither the sentence nor the cap is `display: none`: both are inside
|
|
540
|
+
the button's accessible name — the cap by Artur's call on #308 — so they are
|
|
541
|
+
clipped the way `.ui-sr` in loading.css clips, and the name holds at every width.
|
|
542
|
+
why: docs/components.md#the-page-shell */
|
|
543
|
+
@media (max-width: 560px) {
|
|
544
|
+
.ui-app__search-txt,
|
|
545
|
+
.ui-app__search kbd {
|
|
546
|
+
position: absolute;
|
|
547
|
+
width: 1px;
|
|
548
|
+
height: 1px;
|
|
549
|
+
margin: -1px;
|
|
550
|
+
padding: 0;
|
|
551
|
+
overflow: hidden;
|
|
552
|
+
clip-path: inset(50%);
|
|
553
|
+
white-space: nowrap;
|
|
554
|
+
border: 0;
|
|
555
|
+
}
|
|
556
|
+
/* It gives way before the band does: at a large font scale the word ellipsises
|
|
557
|
+
rather than pushing the reader's mark off the row. */
|
|
558
|
+
.ui-app__search-short { display: block; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
559
|
+
}
|
|
560
|
+
|
|
521
561
|
/* -- Auth card (sign-in / consent) — centered, glowing --------------------- */
|
|
522
562
|
.ui-auth {
|
|
523
563
|
min-height: 100vh;
|
package/src/styles/segmented.css
CHANGED
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
box. #527
|
|
115
115
|
why: guidelines/layout-and-density.md, the spacing scale */
|
|
116
116
|
.ui-seg--underline button { position: relative; border-radius: var(--radius-sm); padding: var(--space-3); min-height: var(--tap-min, 44px); white-space: normal; overflow-wrap: anywhere; font-weight: var(--weight-medium); }
|
|
117
|
+
.ui-seg--underline.ui-seg--sm button { padding: var(--space-3); min-height: var(--tap-min, 44px); }
|
|
117
118
|
/* The chosen tab is its label and one bar under it: no plate, no hairline, no
|
|
118
119
|
upright rail — those read as a list-row grip. #527 r31. The `outline: 0` that
|
|
119
120
|
stood here cancelled the accent outline the pill rule gave every chosen button;
|
package/src/styles/tap-zone.css
CHANGED
|
@@ -56,6 +56,8 @@
|
|
|
56
56
|
.ui-drawer__close,
|
|
57
57
|
.ui-snippet__copy,
|
|
58
58
|
.ui-footer__social,
|
|
59
|
+
.ui-app__search,
|
|
60
|
+
.toggle,
|
|
59
61
|
/* Already relative in react/src/DatePicker.css — restated because this
|
|
60
62
|
gate reads the kit's own sheets and cannot see that one, and a carrier
|
|
61
63
|
whose containing block it cannot find is a layer that measures against
|
|
@@ -75,7 +77,9 @@
|
|
|
75
77
|
.ui-snippet__copy,
|
|
76
78
|
.ui-footer__social,
|
|
77
79
|
.ui-switch,
|
|
78
|
-
.ui-datepicker__opt
|
|
80
|
+
.ui-datepicker__opt,
|
|
81
|
+
.ui-app__search,
|
|
82
|
+
.toggle
|
|
79
83
|
)::after {
|
|
80
84
|
content: "";
|
|
81
85
|
position: absolute;
|
|
@@ -215,4 +219,24 @@
|
|
|
215
219
|
--tap-clear-x: var(--tap-gap);
|
|
216
220
|
--tap-clear-y: var(--tap-gap);
|
|
217
221
|
}
|
|
222
|
+
|
|
223
|
+
/* Two 52px rows, each holding a control the kit draws under the floor: the
|
|
224
|
+
shell band's palette trigger, 37.05 tall once the phone band swaps its
|
|
225
|
+
sentence for the short word, and the theme switch at 34 square on both.
|
|
226
|
+
Neither row opens anything — the room is already in it, which is why these
|
|
227
|
+
two declare a clearance and no gap. Across, 6px a side against the band's
|
|
228
|
+
own 12px gap and the topbar's 8 below 560px, where this layer exists — not
|
|
229
|
+
the topbar's 14 above that step, where it does not. 6px a side crosses the
|
|
230
|
+
topbar's 4px midline by 1px, which does not mis-tap: neither neighbour on
|
|
231
|
+
that row carries a layer of its own. Down, the row's leftover height is 7.4px
|
|
232
|
+
above and below the trigger and 9 around the switch, where a 44px layer
|
|
233
|
+
needs 3.5 and 5. The rows keep their height, their gaps and their paint.
|
|
234
|
+
#486
|
|
235
|
+
|
|
236
|
+
--space-3 rather than --tap-gap, which is what every row above declares:
|
|
237
|
+
20 claims 10px a side and the trigger has 7.4. The clamp would still stop
|
|
238
|
+
at 44 today and be a number that is not true, which is what the browser
|
|
239
|
+
half fails a container for. */
|
|
240
|
+
.ui-app__bar,
|
|
241
|
+
.topbar__in { --tap-clear-x: var(--space-3, 12px); --tap-clear-y: var(--space-3, 12px); }
|
|
218
242
|
}
|
package/src/styles/topbar.css
CHANGED
|
@@ -246,12 +246,31 @@
|
|
|
246
246
|
/* One column, and the band is at its tightest. The row is already full at 390,
|
|
247
247
|
and at the gap above this one the account avatar stood from 365 to 397 and was
|
|
248
248
|
cut at the screen edge — the one control on this screen that opens the account
|
|
249
|
-
area. Packed to --space-2
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
area. Packed to --space-2 and a flat 14px trailing gutter the band needs 367.53
|
|
250
|
+
of the 362px it has there, a 5.53px shortfall, because layout.css now pins the
|
|
251
|
+
theme switch to a full 34px square so it keeps the tap floor it was given.
|
|
252
|
+
The wordmark, the Deck/Text switch and the version label are each already at
|
|
253
|
+
the width their own text needs, and the switch must not shrink again, so the
|
|
254
|
+
account block's trailing gutter is what gives — but a FLAT 14px gutter has no
|
|
255
|
+
fallback below the width it was sized for: at 375 it has already given every
|
|
256
|
+
one of its 14px and the row is still 6.53px short, so the avatar was cut and
|
|
257
|
+
the page gained 7px of horizontal scroll (#486 review round 2), worse again
|
|
258
|
+
at 320.
|
|
259
|
+
Both carry a share now, continuously, rather than the gutter alone holding a
|
|
260
|
+
fixed budget: the gutter still narrows first, from 14px at 390 down to 0 by
|
|
261
|
+
381.53px of available row width, and once it is spent the inter-control gap
|
|
262
|
+
takes the rest, from --space-2 down to its own floor of --space-1. 381.53px is
|
|
263
|
+
this row's own fixed width minus its gutter's full 14px — not a general
|
|
264
|
+
formula, a number that belongs to this composition's own wordmark, switch and
|
|
265
|
+
version label. The avatar is whole and the page carries no horizontal scroll
|
|
266
|
+
down to 375px. 320 still falls 41.53px short with both all the way down,
|
|
267
|
+
which stays #558; it is 5px better than main's own 46.53px there, not solved.
|
|
252
268
|
why: docs/foundations.md#breakpoints */
|
|
253
269
|
@media (max-width: 560px) {
|
|
254
|
-
.topbar__in {
|
|
270
|
+
.topbar__in {
|
|
271
|
+
gap: clamp(var(--space-1), calc(var(--space-2) - (381.53px - 100vw) / 5), var(--space-2));
|
|
272
|
+
padding-right: clamp(0px, calc(100vw - 381.53px), 14px);
|
|
273
|
+
}
|
|
255
274
|
}
|
|
256
275
|
|
|
257
276
|
/* Account — avatar + dropdown. Gated: hidden until the app confirms a session
|