import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import { cssDeclarations } from "./css-contract-test-support.ts"; const globalStyles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); function minHeightPx(selector: string) { const matches = [...cssDeclarations(selector, globalStyles).matchAll(/min-height:\s*(\d+)px/g)] .map((hit) => Number(hit[1])); assert.ok(matches.length > 0, `${selector} must declare min-height`); return Math.max(...matches); } function hasHitExpandPseudo(selector: string) { const after = cssDeclarations(`${selector}::after`, globalStyles); assert.match(after, /position:\s*absolute/); assert.match(after, /content:\s*""/); return after; } test("40px controls grow to a 44px box when that does not pack a scrolling list badly", () => { assert.ok(minHeightPx(".select-item") >= 44); assert.ok(minHeightPx(".birth-time-window-details .birth-time-skip-button") >= 44); assert.ok(minHeightPx(".report-center-section-heading button") >= 44); }); test("icon and chip controls keep their visual size and expand the hit with a pseudo-element", () => { const actions = cssDeclarations(".message-actions button", globalStyles); assert.match(actions, /width:\s*26px/); assert.match(actions, /height:\s*26px/); assert.match(cssDeclarations(".message-actions", globalStyles), /gap:\s*1px/); const actionHit = hasHitExpandPseudo(".message-actions button"); assert.match(actionHit, /width:\s*27px/); assert.match(actionHit, /height:\s*34px/); assert.equal(minHeightPx(".chart-nav-chip"), 32); assert.match(hasHitExpandPseudo(".chart-nav-chip"), /inset:\s*-4px/); const auth = cssDeclarations(".auth-links button", globalStyles); assert.match(auth, /min-height:\s*32px/); assert.match(hasHitExpandPseudo(".auth-links button"), /inset:\s*-4px/); });