Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit c0d301e4d4d8a2ce3693f2ad342ce1cf63a3b2c1
parent 1ffa2f839d2d523c352ce573c473cd61c955bb76
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sun, 27 Sep 2026 00:19:11 -0400

search: "Press Enter or click Search to apply" wears the site's accent

The hint was `text-warning`, the same yellow on every site; an unapplied edit
is the next step, not a fault. It is now `text-brand`, which follows the site's
accent and the reader's pick and base, and clears 4.5:1 on each base's page
ground by construction (lib/brand.ts MIN_ACCENT_CONTRAST). The label is
unchanged; the specs find it by text.

theme-accent.spec: the hint is text-brand, its colour is the fixture site's
fitted custom colour, then Brass on light, sepia and dark, each >= 4.5:1 on
the body ground.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mcommon/components/SearchBar.tsx | 5++++-
Mexport/e2e/theme-accent.spec.ts | 52+++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/common/components/SearchBar.tsx b/common/components/SearchBar.tsx @@ -222,8 +222,11 @@ export default function SearchBar({ nav }: { nav?: ReactNode }) { more than the input row plus the chips. */} {(queryDirty || filtersDirty || hasSubs) && ( <p className="flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs"> + {/* The site's accent, not the warning hue: an unapplied edit is + the next step, not a fault. `--brand` clears 4.5:1 on every + base's page ground (lib/brand.ts MIN_ACCENT_CONTRAST). */} {(queryDirty || filtersDirty) && ( - <span className="text-warning"> + <span className="text-brand"> Press Enter or click Search to apply </span> )} diff --git a/export/e2e/theme-accent.spec.ts b/export/e2e/theme-accent.spec.ts @@ -1,6 +1,7 @@ import { test, expect, type Page } from "@playwright/test"; -import { ACCENTS } from "../../common/lib/brand"; +import { ACCENTS, MIN_ACCENT_CONTRAST, contrastRatio } from "../../common/lib/brand"; import { resolveAccent } from "../../common/lib/accent"; +import { installRoutes } from "./helpers"; // The ThemeMenu's two radio groups. A site opens in its OWN accent (the // fixture's site.json sets the custom hex #cc3366, so the layout renders @@ -139,3 +140,52 @@ test("picking the site's own colour again removes the stored accent", async ({ await pick(page, "Dark"); await expect.poll(() => state(page)).toMatchObject({ base: "dark", brand: FIXTURE.dark }); }); + +// The search bar's "Press Enter or click Search to apply" wears the site's +// accent (release 10). It was `text-warning`, the same yellow on every site. +// It follows the reader's accent and base like any `text-brand`, and stays +// readable on the page ground it sits on. +test("the unapplied-search hint wears the accent, readable on each base", async ({ + page, +}) => { + await installRoutes(page); + await page.emulateMedia({ colorScheme: "light" }); + await page.goto("/"); + const hint = page.getByText("Press Enter or click Search to apply"); + // Typing is an unapplied edit (the input mounts after hydration). + await page.locator('input[data-testid^="leaf-query-"]').first().fill("alpha"); + await expect(hint).toBeVisible(); + await expect(hint).toHaveClass(/(^|\s)text-brand(\s|$)/); + await expect(hint).not.toHaveClass(/text-warning/); + + // The hint's colour and the ground under it, as "#rrggbb". + const paint = () => + hint.evaluate((el) => { + const hex = (rgb: string) => + "#" + + (rgb.match(/\d+/g) ?? []) + .slice(0, 3) + .map((n) => Number(n).toString(16).padStart(2, "0")) + .join(""); + return { + color: hex(getComputedStyle(el).color), + ground: hex(getComputedStyle(document.body).backgroundColor), + }; + }); + const expectAccent = async (value: string) => { + await expect.poll(async () => (await paint()).color).toBe(value); + const { color, ground } = await paint(); + expect(contrastRatio(color, ground)).toBeGreaterThanOrEqual(MIN_ACCENT_CONTRAST); + }; + + // The fixture site's own (custom) colour, fitted to the light ground… + await expectAccent(FIXTURE.light); + // …a reader's pick… + await pick(page, "Brass"); + await expectAccent(ACCENTS.brass.onLight); + // …and each base's own value of it. + await pick(page, "Sepia"); + await expectAccent(ACCENTS.brass.onSepia); + await pick(page, "Dark"); + await expectAccent(ACCENTS.brass.onDark); +});