mirror of
https://github.com/civitai/civitai.git
synced 2026-09-20 22:08:18 +08:00
233d0aa8be
The row is content-width and never collapses — `useResolvedNav` derives the bar/More split from the user's saved config, not the viewport — so it measures a fixed ~1334px signed in at every width from 1024 to 1400. `@md:overflow-visible` overrode both overflow axes above the `md` container breakpoint (1024px), removing the row's only escape: above 1024 it could not scroll, and an ancestor `overflow-hidden` clipped whatever exceeded the viewport. Measured at 1136px signed in, on `/`, `/models` and `/leaderboard/overall`: row right edge 1334, scrollable overflow 0, and neither Shop nor More hit-testable. `document.scrollWidth` equalled the viewport at every width, which is why a page-level overflow check finds nothing here. Dropping the override restores the scroll the row already relies on below 1024. `overflow-y` cannot be `visible` beside `overflow-x: auto` — it computes to `auto` — so the row clips on both axes, and an outline contributes no scrollable overflow. The row pays the focus ring's 4px of ink on the axis that scrolls, sized from the ink and carrying `var(--mantine-scale)` as Mantine's own rule does, rather than from a rem scale that only matches at a 16px root. The padding is horizontal ONLY, and that is a trade rather than an oversight. Padding all four sides also unclipped the ring top and bottom, including below 1024 where it is clipped today, but it made the bar taller on every page at every width. Justin saw the rendered result and declined it. Not "unchanged behaviour", though: the 36px More button used to set the row's height and leave a 32px pill 2px of slack, so half the ring showed. Shrinking More to pill height took that. The mechanism is unchanged; the amount is not. Second problem, same bar: on feed routes the filters and the settings gear wrapped to a second line, doubling the bar's height from 44px to 88px. `SubNav2` wraps, and a wrapping container places items at their flex BASIS before shrinking any of them, so at `basis: auto` the row's content width does not fit and the siblings wrap. `flex-1` gives it `basis: 0`: both share the line, and the row absorbs the shortfall by scrolling. `shrink-0` on the More button is the other half, because that shrink then lands on the children and More is the one that collapses, to an empty 28px circle. `min-w-0` is deliberately absent: `overflow-x: auto` already zeroes a flex item's automatic minimum size, and removing it changed nothing at any of eight widths. So is `lg:flex-nowrap`, measured the same way. Measured on /images, sub nav height, against a control built by reverting only these classes on the same dev server: 88px to 44px at 1440/1280/1184/1136/1024/900, and byte-identical child geometry at 768/640/390. The band is route-dependent and those figures are one route: 40px on /models where every control is `h-8`, 44px on /images where one filter control is 36px, and 36px on /comics, where `FilterButton`'s `compact-sm` takes the `h-9` branch. The rest is one size for the whole row, all of it measured rather than eyeballed: `SubNav2` top-aligns its children, because on platforms that draw classic scrollbars the scroller is taller than its pills and centring put the filters half a scrollbar low; the More button is 32px at 14px/600, matching the pills, where it was 36px at 16px/500; and the settings gear is 32px, circular, with a 16px icon in `--mantine-color-bright`. The gear's icon was never smaller than its neighbours — every icon in the bar is 16x16 with a 2px stroke — it was rgb(222,226,230) against their rgb(254,254,254), and at a matched box that reads as smaller rather than dimmer. `bright` is the same #222/#fefefe pair the pills use, so the gear matches the pills in both schemes; against the globe specifically it is exact in dark and slightly darker in light, where the globe is `text-gray-8`. The scrollbar is deliberately left visible: it is the only thing telling anyone the row scrolls, and "it doesn't look like it scrolls" was the original report. Guarded at two tiers, and every guard was mutated: Shell's provider deleted RED expected false to be true scale-95 planted (whitelist) RED to deeply equal [...7 items] relative on the row RED expected false to be true flex-1 removed RED expected 32 to be +0 shrink-0 removed from More RED expected 28 to be close to 81.796875 padding to px-0 RED expected -4 to be >= 0 @md:overflow-visible back RED expected 'visible' to be 'auto' The hit-test is the one that needed building twice. The trap it guards — a `position: sticky` or `relative` ancestor becoming the unportalled dropdown's containing block — produces a dropdown whose rect is IDENTICAL to a working one while its items stop being hit-testable, so a rect assertion and a `textContent` assertion both pass against the broken state. The first version of that test still passed with `relative` planted, because the geometry harness mounts a bare `MantineProvider` and never receives `ThemeProvider`'s `Popover.withinPortal: false`: the menu portalled in the test while rendering inline in the app. It now nests a provider carrying that default. The source gate strips comments before matching, so deleting the live row and leaving a commented-out copy fails loudly instead of passing silently, and it rejects positioning tokens on the row so the prohibition above is checked rather than merely written down. `.moreButton`'s height moved from an explicit `32px` to `h-8`, beside the pills' own. Measured either side on the same route and browser rather than argued from the cascade, because that cascade misled two reviewers on this file today: 32px / 16px / 10px / 14px / 600 in both states, identical on every axis. A second tidy-up — dropping `variant="subtle"`, which `LegacyActionIcon` and `ThemeProvider` each already set — is deliberately NOT here. The gear does not render for the probe session, so it could not be measured, and an unverifiable change whose only benefit is tidiness is not worth carrying. `.moreButton` no longer states a font either: measured with the declarations removed, the button still renders 14px/600, because that is what a Mantine `size="sm"` Button already produces. Two lines of framework default, deleted. The More button's height is now pinned in the geometry tier against a PILL's rather than a literal — deleting `h-8` reddens with `expected 36 to be 32`, where before it passed both tiers green while growing the bar 4px site-wide. The More button's height and typography are pinned in the geometry tier against a PILL's and against the literal 32, because parity alone passes when both move: `h-8` to `h-9` on both controls leaves them equal at Mantine's 36px and grows the bar 4px on every page. Mutants: 36-vs-32 either side, and 20px-vs-14px on the font. The pill's `text-base font-medium` does NOT render. `globals.css`'s unlayered `.mantine-Button-label *` sets both to `inherit` and sits after `@tailwind utilities`, so the span takes Mantine's `size="sm"` 14px/600. Three reviewers read those classes as 16px/500 in one day, so it is written beside them. The `geometry` project is `continue-on-error` on pull requests, so everything it measures informs rather than gates. The height claim is therefore asserted in the `unit` tier too — a 0.3s check that the More button's `clsx` still carries `h-8`. Paired control: removing it gives `expected [ 'shrink-0' ] to include 'h-8'`, reordering the class list stays green. The font and geometry claims stay advisory and the PR body says so. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>