Two of the five explorer brands pinned NEXT_PUBLIC_FONT_FAMILY to Geist off fonts.googleapis.com: every visitor to explore.lux.network and the SPC explorer was announced to Google on page load, and the two hosts rendered in a face the other three do not use. Dropping the pair leaves all five brands with the same env and the image's own faces. The branded matrix declared Basel Grotesk as the brand token for all four orgs, and the broker audit had already been switched to test for Zen while still calling the result hasGeist and printing it under a Geist label — a check whose name denied its own predicate. The README hero card asked for Inter.
Branded web3-surface regression
Proves every public web3 surface across all four orgs (Lux / Zoo / Hanzo / Pars)
is LIVE · FUNCTIONAL · correctly BRANDED at four breakpoints
(390 / 768 / 1280 / 1920), with zero cross-brand leakage — the
white-label invariant. Real Chrome/Blink (channel: 'chrome'), read-only against
LIVE production surfaces (no transactions, no wallet-connect, no auth — the
login/connect form is asserted, never submitted).
Run
npm run test:branded # full matrix (surfaces × 4 breakpoints)
npm run test:branded:1280 # just the 1280 column
npx playwright test -c playwright.branded.config.ts --project=390 --grep bridge
npm run test:branded:report # open the HTML report
Screenshots → ~/Desktop/lux-shots-e2e/<surface>-<bp>.png (one per cell).
Matrix artifacts → branded-report/{matrix.md,matrix.txt,matrix.json} (gitignored).
What each cell asserts (the owner's 6-point rubric → 8 concrete checks)
| # | check | asserts |
|---|---|---|
| 1 | http |
HTTP 200 (or a documented redirect that lands 200) |
| 2 | title / favicon / leak |
branded <title> + a real favicon + zero foreign brand in the <head> (title, meta, favicon/logo asset URLs) |
| 3 | overflow |
no horizontal overflow (scrollWidth ≤ innerWidth) |
| 4 | console |
no app-origin console errors / uncaught exceptions (3rd-party telemetry + benign resource-4xx allow-listed, with rationale) |
| 5 | key |
the key interactive control (Connect / Sign-in / chain selector …) is present and visible |
| 6 | font |
brand font present — a broken Times/serif fallback fails. Brand accent is captured as an observational note (computed-accent extraction is too noisy to gate) |
Body references to other chains (a bridge listing "Lux C-Chain" as a source, a
wallet listing "Avalanche" as a network) are legitimate product content and are
recorded as a note, never a leak — the leak gate is the <head> only.
Gate vs. flag (the durable-regression model)
The spec never hard-codes "known broken." It runs all 8 checks on every surface and
consults surfaces.ts:
posture: 'live'— a surface we own; every check gates (a new failure is a real regression → the run goes red ✗) unless that check is listed inflags.flags[check]— a KNOWN, documented defect: that one check is demoted GATE→FLAG ⚑ with areason+ aflipcondition (when to delete the flag). A flag may be scoped to specific breakpoints viabps(e.g. a mobile-only overflow), so the un-covered breakpoints still gate.posture: 'down' | 'foreign-domain'— documented-unreachable / serves a different company (owner domain-reclaim pending); nothing gates, the whole surface is a FLAG.- Stale flags — if a flagged check starts passing, the run reports it as STALE so the table self-cleans.
Legend: ✓ pass · ⚑ documented flag (expected, carries a flip) · ✗ regression (un-flagged failure — the only thing that fails CI) · · not run.
Adding / updating a surface
Edit surfaces.ts only — the spec + reporter are a pure function of
the table. To accept a newly-discovered defect, add a flag with a concrete flip
condition (and bps if breakpoint-specific); to prove a fix, delete the flag and
watch the cell go green.