From bc3a5029a6614d920a8def0bad88059918afe6e6 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Wed, 30 Sep 2026 21:17:42 +0000 Subject: [PATCH] Tab-radius gate: find Collapse's rule inside a selector list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The home link joined Collapse's rule (.vtl-collapse, .vtl-home { … }) so the two share one box, and the gate only recognised a rule that named .vtl-collapse alone, so it found no reference and failed on development. It now reads the reference from any rule whose selector list names .vtl-collapse as a whole selector (not :hover, -tx or a descendant), and its self-test gains a poison that moves only that rule's radius. --- internal/check-tab-radius-token.mjs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/check-tab-radius-token.mjs b/internal/check-tab-radius-token.mjs index 7afc9c94f..31ea686a4 100644 --- a/internal/check-tab-radius-token.mjs +++ b/internal/check-tab-radius-token.mjs @@ -53,13 +53,21 @@ const fail = (m) => { console.error('TAB-RADIUS: FAIL — ' + m); process.exit(1 // catches 999px, 9999px and the occasional 50vh. const PILL_MIN = 100 +// Does this line open a rule whose selector list names `cls` as a WHOLE selector? `.vtl-collapse, .vtl-home {` +// counts (the home link joined Collapse's rule so the two share one box); `.vtl-collapse:hover`, +// `.vtl-collapse-tx` and `.vtl.rail-collapsed .vtl-collapse` do not. +function opensRuleFor(ln, cls) { + const m = ln.match(/^\s*([^{}]+)\{/) + return !!m && m[1].split(',').map((x) => x.trim()).includes(cls) +} + function auditLines(lines) { const problems = [] // ── the reference: .vtl-collapse's literal radius, read from the file, never assumed ────────── const collapse = [] lines.forEach((ln, i) => { - if (!/^\s*\.vtl-collapse\s*\{/.test(ln)) return + if (!opensRuleFor(ln, '.vtl-collapse')) return const m = ln.match(/border-radius:\s*([^;]+);/) if (m) collapse.push({ line: i + 1, value: m[1].trim() }) }) @@ -151,6 +159,9 @@ if (process.argv.includes('--self-test')) { 'cursor:pointer; border-radius:999px; font:inherit;')], ['literal-instead-of-token', (s) => s.replace('cursor:pointer; border-radius:var(--vtl-radius,8px); font:inherit;', 'cursor:pointer; border-radius:8px; font:inherit;')], + // the reference must be read from Collapse's rule even inside a selector list: change ONLY that rule's + // radius and the (unchanged) tabs no longer agree with it. + ['collapse-radius-moved', (s) => s.split('\n').map((l) => (opensRuleFor(l, '.vtl-collapse') ? l.replace(/border-radius:\s*8px;/, 'border-radius:12px;') : l)).join('\n')], ] let bad = 0 for (const [name, poison] of cases) { @@ -161,7 +172,7 @@ if (process.argv.includes('--self-test')) { if (!caught) bad++ } if (bad) { console.error(`TAB-RADIUS SELF-TEST: FAIL — ${bad} case(s) not caught.`); process.exit(1) } - console.log('TAB-RADIUS SELF-TEST: PASS — both regressions caught; tree untouched (poisoned in memory).') + console.log('TAB-RADIUS SELF-TEST: PASS — every regression caught; tree untouched (poisoned in memory).') process.exit(0) }