import { readFileSync } from 'node:fs' import { join, relative } from 'node:path' import { fileURLToPath } from 'node:url' import { walkFiles } from './lib/fs-walk.mjs' // Every control-UI surface must round its corners with the radius token ladder // defined in src/assets/base.css: the primitives --radius-none/xs/sm/md/lg/xl/ // 2xl/full and the semantic aliases --radius-control/card/panel/modal/pill. A // raw length (6px, 0.375rem, 14px, …) inside a border-radius / border-*-radius // declaration is a violation — route it through a token so the "Instrument" // direction's corner tiers stay consistent and can be tuned in one place. // // Allowed raw values: 0, 0px, 50% (true circles — dots/avatars), inherit, and // the fully-round pill literals 999px / 9999px, plus calc(...) expressions built // from var(--radius-*). base.css is the token source, so its --radius-* token // definitions (custom-property lines) are exempt. Any genuinely geometric one-off // (hairline caret, progress/trace bar, scrollbar thumb) can opt out with a // trailing `/* radius-allow: why */`. const root = fileURLToPath(new URL('..', import.meta.url)) const srcDir = join(root, 'src') const customProp = /^\s*--[\w-]+\s*:/ // A border-radius / border--radius declaration, capturing just its VALUE // (up to the next ; or }). Scanning only the value avoids false positives from // other lengths on the same line (e.g. a `padding: 0.25rem` shorthand sitting // beside a tokenized `border-radius: var(--radius-sm)`). const radiusValue = /border(?:-[a-z]+)*-radius\s*:\s*([^;}]+)/gi // A raw CSS length: number + px/rem/em unit. const lengthLiteral = /\b\d*\.?\d+(?:px|rem|em)\b/g // Raw length literals that are explicitly allowed even inside a radius decl. const allowedLength = /^(?:0px|999px|9999px)$/ const files = walkFiles(srcDir, /\.(vue|css)$/) // In .vue files only