From c23246f2dd5274b3162d5850cba1a88e673649a1 Mon Sep 17 00:00:00 2001 From: Bitcoin Universe Date: Sat, 29 Aug 2026 19:31:00 +0000 Subject: [PATCH 01/11] Make the shell fit a phone rather than a picture of one The layout has had phone widths in its test matrix for some time and has looked right in all of them. Almost nothing that makes this product hard to use on an actual phone shows up in a screenshot, so almost none of it had been found. What was wrong, in the order it costs a visitor something: The search field computed at 13px below 576px, and the five preference selects in the footer at 14px. iOS Safari zooms the layout viewport in when a focused field is under 16px and does not zoom back out, so every search on an iPhone ended with the visitor panning a page twice as wide as their screen to read the answer. Both are 16px now. The placeholder truncates a little sooner as a result, which is the right way round: it is a hint, and the result list does the explaining. The viewport meta did not ask for viewport-fit=cover and nothing in the repository mentioned a safe area, so on every notched phone the header sat inside a letterbox and the bottom bar sat under the home indicator. The four insets are tokens now, used through max() so a phone without a cutout keeps its ordinary padding, and the header, the bar and the content column all read the same ones. Content ended underneath the bottom bar. The reservation was 68px, written on main, and the footer is a sibling of main: every settings control and the whole last row of links sat behind the bar on every phone. It is on their shared parent now and derived from what the bar occupies, including the home indicator. Nothing reserved room for the sticky layers when the browser scrolls. Tabbing to a control near the bottom of a page put it exactly behind the bar, which is a WCAG 2.2 focus-obscured failure. Each of the three header shapes now states its own scroll-padding: writing one number for the tallest of them caused the fault it was meant to prevent, because the reserve is taken out of the room the browser has to place the element in. The bottom bar scrolled sideways with its scrollbar hidden and no other sign, so destinations past the edge were present and unreachable, and arriving on one from a link left the bar scrolled away from it. It has scroll shadows now, painted with the two-layer background technique so the fade appears only on the side that has more and only when there is more, and the current destination is scrolled into view after every navigation. Controls were sized for a cursor. The chain and network pickers at 38px, the pagination arrows at 35, the documentation tabs at 42, the copy control beside every identifier at 21 by 17, and rows of identifier links nineteen pixels apart. The floors are the platform ones, 44 for anything in the shell or repeated, and WCAG's 24 with its spacing exception everywhere else, which is what lets a dense table stay dense. The block timeline scrolled sideways as an unnamed div. It is a region with a name now: it is the one place here that should scroll sideways, and saying so is what separates it from a row that merely got cut off. The transaction tracker drew 37px blocks at 320px because its height was a fifth of its width. It has a floor. Menus had no height cap, so a chain list on a short screen ran off the bottom with no way to reach the rest of it. The search results were pinned 42px below a field that is now 48 tall. 100vh is still 100vh where the intent is the large viewport, and says so. A new gate measures all of it. It is built the opposite way round from the visual matrix, few page loads and many assertions each, so it costs about a tenth of what the matrix does and can afford to grow. --- .../blockchain-blocks.component.scss | 9 + .../master-page/master-page.component.html | 2 +- .../master-page/master-page.component.scss | 130 ++- .../master-page/master-page.component.ts | 56 +- .../search-form/search-form.component.html | 6 + .../search-form/search-form.component.scss | 100 ++- .../search-form/search-form.component.ts | 27 + .../search-results.component.scss | 37 +- .../app/components/start/start.component.html | 17 + .../components/tracker/tracker.component.ts | 12 +- .../transactions-list.component.scss | 21 + .../app/dashboard/dashboard.component.scss | 17 + .../address-text/address-text.component.scss | 14 + .../global-footer.component.scss | 10 + frontend/src/app/shared/shared.module.ts | 3 +- .../asset-flow/asset-flow.component.scss | 16 + .../multichain-explorer.component.scss | 9 + .../protocol-strip.component.scss | 8 + .../app/universe/universe-viewport.service.ts | 96 +++ frontend/src/index.mempool.html | 12 +- frontend/src/styles.scss | 219 +++++ frontend/src/styles/_universe-tokens.scss | 43 + scripts/universe/visual-qa/capture.mjs | 12 +- scripts/universe/visual-qa/mobile-check.mjs | 757 ++++++++++++++++++ 24 files changed, 1605 insertions(+), 28 deletions(-) create mode 100644 frontend/src/app/universe/universe-viewport.service.ts create mode 100644 scripts/universe/visual-qa/mobile-check.mjs diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss index 529cae0fab2..91e48909dfa 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss @@ -139,6 +139,15 @@ padding: 0 var(--u-space-2); pointer-events: all; + // The height label sits directly above its block, so the two are close + // enough that a thumb aimed at one can land on the other. Room around the + // text rather than a taller box, so the label stays on the block it names + // and the timeline's spacing is unchanged. + @media (pointer: coarse), (max-width: 991.98px) { + margin-block: -6px; + padding-block: 6px; + } + &:hover, &:focus { color: var(--u-brand-hover); diff --git a/frontend/src/app/components/master-page/master-page.component.html b/frontend/src/app/components/master-page/master-page.component.html index c7653fc7f00..8051b04635e 100644 --- a/frontend/src/app/components/master-page/master-page.component.html +++ b/frontend/src/app/components/master-page/master-page.component.html @@ -78,7 +78,7 @@ whether it leads to blocks or to protocols, and below the breakpoint this becomes a thumb-reachable bar rather than a squeezed desktop navbar. -->