/** * CSS Compiler -- `BoundaryDef` to `@container` query rules. * * Takes a boundary definition and state-specific CSS property maps, * generates `@container` query rules using boundary thresholds as * breakpoints. * * @module */ import type { Boundary, StateUnion } from '@czap/core'; import { Diagnostics } from '@czap/core'; import { inferSyntax } from './css-utils.js'; // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- /** * A single CSS rule — a selector plus a property map. * * Emitted inside a {@link CSSContainerRule} by {@link CSSCompiler.compile}. */ export interface CSSRule { /** CSS selector (e.g. `.card`, `[data-state="open"]`). */ readonly selector: string; /** Flat property map applied inside the selector block. */ readonly properties: Record; } /** * A nested `@supports` / `@media` group inside a state's container block. * Nested groups are preserved recursively (#110 — never silent-drop depth ≥ 2). */ export interface CSSAtRuleGroup { /** The at-rule prelude exactly as authored. */ readonly prelude: string; /** Declarations authored directly inside the at-rule. */ readonly bareProps?: Record; /** Nested selector rules inside the at-rule. */ readonly rules?: readonly CSSRule[]; /** Nested conditional at-rule groups. */ readonly atRuleGroups?: readonly CSSAtRuleGroup[]; } /** * A `@container` at-rule grouping rules that apply at a given container query. * * Produced per-state by {@link CSSCompiler.compile}; the container `name` * is derived from the boundary's `input` identifier. */ export interface CSSContainerRule { /** Container name (sanitized from the boundary input). */ readonly name: string; /** Condition text like `(width >= 768px)`. */ readonly query: string; /** Rules evaluated inside the container query. */ readonly rules: readonly CSSRule[]; /** Nested `@supports` / `@media` groups inside the container block. */ readonly atRuleGroups?: readonly CSSAtRuleGroup[]; } /** * Structured per-state input for {@link CSSCompiler.compile}: bare * properties that style the boundary selector itself, plus nested rules * that each carry their own selector (the `@quantize` nested-selector * authoring form). */ export interface CSSStateBody { /** Properties applied to the boundary selector (the `selector` param, default `.czap-boundary`). */ readonly bareProps?: Record; /** Per-selector rules emitted verbatim into the state's `@container` block. */ readonly rules?: readonly CSSRule[]; /** Nested `@supports` / `@media` groups inside the state (#110). */ readonly atRuleGroups?: readonly CSSAtRuleGroup[]; } /** * Per-state input accepted by {@link CSSCompiler.compile}: either a flat * property map (the documented bare-props form, back-compat) or a * {@link CSSStateBody} carrying nested selector rules. */ export type CSSStateInput = Record | CSSStateBody; /** * Output of {@link CSSCompiler.compile}. * * `raw` is the serialized form of `containerRules`, pre-joined so most * consumers can inject it directly into a `