From 1ef2cab89e12990a59f11ab7232f121a13c9ca8e Mon Sep 17 00:00:00 2001 From: ctao Date: Sat, 25 Jul 2026 17:48:48 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20navigation=20blink=20root-caused=20?= =?UTF-8?q?=E2=80=94=20defer=20search-client.js=20(was=20parser-blocking?= =?UTF-8?q?=20mid-body),=20npm=20run=20demo=20serves=20the=20production=20?= =?UTF-8?q?build=20through=20the=20tunnel;=20DESIGN.md=20documents=20the?= =?UTF-8?q?=20VT=20removal=20+=20font-swap=20decision?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DESIGN.md | 31 ++++++++++++++++++++++++++++++- package.json | 1 + src/layouts/Base.astro | 9 +++++++-- src/pages/search.astro | 5 +++-- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 054bff1..9283e75 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -45,6 +45,16 @@ Type scale — the ONLY font sizes in the codebase (no ad-hoc rem values): Always end `font-family` with a generic (`sans-serif`) — lint requirement. +Font loading (decided after the navigation-blink incident): self-hosted latin +woff2, preloaded in `Base.astro`, `font-display: swap` + metric-matched Arial +fallbacks for BOTH families (`Inter Fallback`, `Space Grotesk Fallback` — +size-adjust/ascent/descent computed from the real font metrics, capsize +method). Never `optional`: its ~100ms window loses to per-navigation +revalidation (dev/preview serve `Cache-Control: no-cache`), which randomly +committed whole pageviews to Arial — the "fonts flash between navigations" +bug. With swap + matched metrics every page converges on brand fonts and the +swap is layout-neutral. + ## Spacing scale (fluid; mobile ≈ min, desktop ≈ max) | Token | Value | Use | @@ -122,6 +132,12 @@ Rules: - ALL `animation`/`transition` declarations live inside the single `@media (prefers-reduced-motion: no-preference)` block at the end of global.css; the `reduce` block additionally force-disables everything. +- NO cross-document view transitions (`@view-transition`). The root crossfade + snapshots the incoming page at its first render opportunity — on slow + networks that is a half-parsed page, so every navigation read as a + full-page blink (the diagnosed symptom); scrolled→top navigations crossfade + two unrelated frames even when it works. Navigation feel comes from static + HTML + Astro prefetch, not from animating the swap. - Animate `transform`/`opacity` only (compositor-only); never background-position/box-shadow in keyframes. No `will-change`. No `filter: blur` on large layers and no `background-attachment: fixed` @@ -276,6 +292,15 @@ inventing a section order. The navy band is reserved for `/` and `/login`. caps, aria-hidden; 26px Galaxy) ABOVE the label — never instead of it. Glyphs are wayfinding, not decoration. +## Serving the demo + +Phone/tunnel demos run the **production build**: `npm run demo` +(= `astro build && astro preview`, same port 4321 so the tunnel URL keeps +working). `astro dev` through the tunnel adds HMR + dev-toolbar module +traffic and serves everything `no-cache` — every navigation re-negotiates +assets over the tunnel, which reads as blinking/slow paints that do NOT +exist in the built site. Dev mode is for local editing only. + ## Do not - No new hues, tints, or grays — derive via `color-mix` from brand tokens only. @@ -283,7 +308,11 @@ inventing a section order. The navy band is reserved for `/` and `/login`. Typography); headline weight stays 500 (brand D.3.4). - No font sizes outside the type-scale tokens; no ad-hoc spacing/shadow/radius. - No animation/transition outside the `no-preference` block; no JS motion; - no transition durations/easings outside `--dur`/`--ease`. + no transition durations/easings outside `--dur`/`--ease`; no + `@view-transition` (see Motion policy). +- No parser-blocking ` - +