export type Rgb = [number, number, number]; export declare function oklchToSrgb(L: number, C: number, H: number): Rgb; export declare const luminance: ([r, g, b]: Rgb) => number; export declare function contrast(a: Rgb, b: Rgb): number; export declare const round2: (n: number) => number; /** * Source-over alpha compositing in sRGB — what the browser does for * `bg-primary/20`, which Tailwind v4 emits as a colour mixed toward * transparent and the compositor then lays over the backdrop. * * This is the step the estate has repeatedly skipped. A `-text` token measured * against `--role-bg-body` is measured against a surface it is rarely on; the * pill it actually ships in is a wash of its OWN hue, which pulls the backdrop * toward the text and costs roughly a point of ratio. */ export declare function over(fg: Rgb, bg: Rgb, alpha: number): Rgb; /** * THE SAME READER, POINTED AT ANOTHER STYLESHEET. * * This module used to be hardcoded to `css/vars.css`, so there was NO trusted way to * measure `css/braden.css` — the Corporate palette. On 2026-08-28 that gap cost three * separate hand-rolled readers in one session, each handling `var()` differently, each * returning a different verdict for the same file (4.16 / 3.33 / "all pass"), and one * of them reached a PR description before the live page contradicted it. * * A measurement tool that covers one of two stylesheets guarantees the second gets * measured by whatever the reader writes that day. So: same parser, same cascade rules, * same alias resolution, any file. */ export declare function sheet(absPath: string): { blocks: (selector: string) => string; resolve: (name: string, scope: string) => Rgb; root: string; }; /** * Every top-level block whose selector list contains `selector`, concatenated * in source order — NOT the first one. vars.css declares `:root` twice and * `.dark` twice, and the second pair is where the role aliases live. */ export declare function blocks(selector: string): string; export declare const ROOT: string; export declare const DARK: string; /** * Resolve `--name` inside a block, following `var()` aliases TO A FIXED POINT. * * IT USED TO FOLLOW EXACTLY ONE HOP, and that was enough for `css/vars.css`, where * `--role-primary` is a bare `oklch()`. It is not enough for `css/braden.css`, where * `--role-primary: var(--braden-red)` and `--role-accent-text: * var(--role-accent-text-base)`. On 2026-08-28 that cost a false measurement: callers * that swallowed the throw treated the unresolved fill as "no tint" and graded every * aliased role against plain surfaces only — dropping the /15 and /20 composites, * which are the cells that fail. Six Corporate roles read as PASS and the live page * said 3.01-3.95. * * So: loop, with a bounded depth so a cycle cannot hang, and THROW on anything that * does not land on a bare oklch triple. Throwing is the point — a resolver that * returns null hands its caller a value that is easy to mistake for "nothing to * check", and that is precisely how half a cross product went ungraded. */ export declare function resolve_(name: string, scope: string): Rgb; /** Does `--name` resolve in `scope`? Lets a gate enumerate without throwing. */ export declare function declared(name: string, scope: string): boolean; export declare const SURFACES: readonly ["role-bg-body", "role-bg-surface", "role-bg-panel", "role-bg-input", "role-bg-sunken"]; //# sourceMappingURL=contrast-instrument.d.ts.map