From 11ba7b3180681f8a8532f8ebf3b4ec39c36df39d Mon Sep 17 00:00:00 2001 From: Logan Date: Fri, 21 Aug 2026 10:46:22 -0400 Subject: [PATCH] build(frontend): sweep every stylesheet, not index.css by name The hook fires on frontend/**/*.{ts,css} while the script read one hardcoded path, so a second stylesheet would have been silently unswept while the hook still went green over it. There is only index.css today, which is exactly when this is cheap to fix. Watched catching a planted nested rule in a second file. --- CLAUDE.md | 5 ++++- frontend/scripts/check-css-nesting.mjs | 24 +++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7a3c670..46cf9fc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3502,7 +3502,10 @@ would notice on 113 — the rule simply does not exist, there and nowhere else, which is how the bottom bar's `text-overflow: ellipsis` came to have never truncated on the device. `make css-check` (`frontend/scripts/check-css-nesting.mjs`, a pre-commit hook and a CI -step) fails on one, over `index.css` and the `css` literals alike, and +step) fails on one, over every `frontend/*.css` and the `css` literals +alike — a glob rather than `index.css` by name, because the hook fires +on `frontend/**/*.{ts,css}` and a sweep that names one file goes green +over a stylesheet it never opened — and says the fix is a leading `&` — valid in both syntaxes, so no nested rule here has a reason to omit it. Two things it has to get right, and both follow from asking whether a *style* rule is anywhere above rather diff --git a/frontend/scripts/check-css-nesting.mjs b/frontend/scripts/check-css-nesting.mjs index 45daa76..6338793 100644 --- a/frontend/scripts/check-css-nesting.mjs +++ b/frontend/scripts/check-css-nesting.mjs @@ -18,10 +18,24 @@ import { findBareNestedRules } from './css-nesting.mjs'; const problems = []; -for (const { line, selector } of findBareNestedRules( - readFileSync('index.css', 'utf8'), -)) { - problems.push({ file: 'index.css', line, selector }); +// Every stylesheet, not `index.css` by name: the hook that runs this +// fires on `frontend/**/*.{ts,css}`, so naming one file promises a +// coverage the sweep does not deliver -- a second stylesheet would be +// silently unswept while the hook still went green over it. There is +// only `index.css` today, which is exactly when this is free to fix. +const stylesheets = globSync('*.css', { cwd: process.cwd() }); + +if (stylesheets.length === 0) { + console.error('css-nesting-check: no stylesheet matched *.css'); + process.exit(1); +} + +for (const file of stylesheets) { + for (const { line, selector } of findBareNestedRules( + readFileSync(file, 'utf8'), + )) { + problems.push({ file, line, selector }); + } } const sources = globSync('src/**/*.ts', { cwd: process.cwd() }); @@ -61,5 +75,5 @@ if (problems.length > 0) { } console.log( - `css-nesting-check: index.css + ${sources.length} files, no bare nested rules`, + `css-nesting-check: ${stylesheets.length} stylesheet(s) + ${sources.length} files, no bare nested rules`, );