@vitreajs/vitrea 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/accessibility.ts","../src/backdrop-hint.ts","../src/capability.ts","../src/diagnostics.ts","../src/foreground.ts","../src/frame.ts","../src/material.ts","../src/planes.ts","../src/scene.ts","../src/scheduler.ts","../src/state.ts","../src/renderer-seam.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Accessibility policy (§Accessibility policy, plus the Reduced Motion\n * paragraph of §Motion).\n *\n * The spec puts this in `core` as *policy*: what an accessibility preference\n * means for the material and for motion. `platform-web` reads the media queries\n * and hands the answers in as plain booleans (X4 — core never touches a media\n * query, a `window`, or anything else browser-shaped), and `vitrea-react`'s\n * `GlassRoot` supplies the per-root prop overrides. The decision itself is one\n * pure fold, so the same inputs always yield the same policy and a test can\n * enumerate every input there is.\n *\n * §Accessibility states four consequences in prose. They are encoded here as a\n * **table**, one row per preference, each row a partial override of the nominal\n * policy — so the table can be diffed against the spec paragraph line by line\n * instead of being reverse-engineered out of branching code. The resolver folds\n * the active rows over `NOMINAL_ACCESSIBILITY_POLICY` in a fixed precedence\n * order; adding a preference means adding a row, not editing a resolver.\n *\n * Every consequence is a small closed union rather than a number. The numbers —\n * blur radii, tint strengths, spring constants, morph durations — are\n * calibration-delegated unknowns owned by `@vitrea/geometry` and\n * `@vitrea/motion` (§Calibration harness). Core's job is to say *which regime*\n * applies; it would be inventing fidelity it has not measured if it said by how\n * much.\n */\n\nimport type { Diagnostic, DiagnosticsChannel } from \"./diagnostics\";\n\n/**\n * What the platform detected. `platform-web` fills this from media queries;\n * core never reads one (X4).\n */\nexport interface SystemAccessibilityPreferences {\n readonly reducedTransparency: boolean;\n readonly reducedMotion: boolean;\n readonly increasedContrast: boolean;\n readonly forcedColors: boolean;\n /**\n * Whether `prefers-reduced-transparency` is even queryable here. It is not\n * Baseline, which is exactly why the explicit override is load-bearing rather\n * than a courtesy (§Accessibility policy). Where this is `false`,\n * `reducedTransparency` above is an absence of evidence, not evidence of\n * absence — and the resolver says so through the diagnostics channel.\n */\n readonly reducedTransparencySupported: boolean;\n}\n\n/** The preferences the policy reasons about, and the table's row keys. */\nexport const ACCESSIBILITY_FLAGS = [\n \"reducedTransparency\",\n \"reducedMotion\",\n \"increasedContrast\",\n \"forcedColors\",\n] as const;\n\nexport type AccessibilityFlag = (typeof ACCESSIBILITY_FLAGS)[number];\n\n/**\n * The three preferences a `GlassRoot` may overrule (§Accessibility policy names\n * exactly this prop set). `forcedColors` is absent by design: a forced-colors\n * mandate comes from an operating-system accessibility setting that exists to\n * override author styling, so it is not an app's to switch off. The type — not\n * a runtime guard — is what makes that impossible to express.\n */\nexport type OverridableAccessibilityFlag = Exclude<AccessibilityFlag, \"forcedColors\">;\n\nexport const OVERRIDABLE_ACCESSIBILITY_FLAGS = [\n \"reducedTransparency\",\n \"reducedMotion\",\n \"increasedContrast\",\n] as const satisfies readonly OverridableAccessibilityFlag[];\n\n/** `\"system\"` defers to the platform; a boolean states the answer outright. */\nexport type AccessibilityOverride = \"system\" | boolean;\n\n/** Per-`GlassRoot` overrides. An absent key means `\"system\"`. */\nexport type AccessibilityOverrides = {\n readonly [K in OverridableAccessibilityFlag]?: AccessibilityOverride;\n};\n\n/**\n * How the material is allowed to behave.\n *\n * The axes are named for what §Accessibility talks about, and each carries the\n * nominal regime, the regime its preference asks for, and — where forced-colors\n * removes the glass entirely — the degenerate regime that leaves.\n *\n * `refraction` here is an *accessibility* ceiling, not the capability-derived\n * `RefractionQuality` of X2 (state.ts). A group can be capped by either; the\n * renderer honours whichever is lower.\n */\nexport interface ResolvedMaterialPolicy {\n /** Whether a glass body is drawn at all, or a flat system-coloured surface replaces it. */\n readonly glass: \"material\" | \"none\";\n /** Where colour comes from: the adaptive material, or the platform's forced palette. */\n readonly colorSource: \"material\" | \"system\";\n /** Backdrop diffusion. Reduced transparency asks for *more* frosted, so `increased`. */\n readonly frost: \"nominal\" | \"increased\" | \"none\";\n /** Edge lensing. Reduced transparency asks for *less* refraction — reduced, not removed. */\n readonly refraction: \"nominal\" | \"reduced\" | \"none\";\n /**\n * How much of the backdrop the surface hides. Reduced transparency raises it;\n * forced-colors' flat system fill hides the backdrop completely, which is\n * `opaque` rather than `none` — no glass means maximal occlusion, not minimal.\n */\n readonly occlusion: \"nominal\" | \"increased\" | \"opaque\";\n /**\n * Nominal glass is bounded by a rim highlight; `strong` is a drawn border.\n * Increased contrast asks for stronger borders, and forced-colors needs a\n * border because a flattened palette leaves nothing else to define the shape.\n */\n readonly border: \"nominal\" | \"strong\";\n /** The material's colour cast picked up from the backdrop. */\n readonly ambientTint: \"nominal\" | \"reduced\" | \"none\";\n /**\n * `adaptive` is the sampled/hinted light-dark foreground of §Foreground\n * adaptation. `near-monochrome` is a flat high-contrast foreground — which is\n * also what forced-colors gets, since adapting to a glass body that no longer\n * exists is not available there; `colorSource` records that the flat colour\n * comes from the system palette.\n */\n readonly foreground: \"adaptive\" | \"near-monochrome\";\n}\n\n/**\n * How motion is allowed to behave (§Motion, Reduced Motion).\n *\n * Reduced Motion \"shortens morphs to non-elastic interpolation\": the shortening\n * is a property of the driver kind, so `morph: \"non-elastic\"` carries both\n * halves and `@vitrea/motion` owns the calibrated duration for each kind.\n */\nexport interface ResolvedMotionPolicy {\n /** Spring overshoot past the target. */\n readonly overshoot: \"elastic\" | \"none\";\n /** Press compression and lensing deformation of the surface. */\n readonly deformation: \"nominal\" | \"none\";\n /** Travelling specular shimmer across the rim. */\n readonly shimmer: \"travel\" | \"none\";\n /** Morph driver family: an elastic spring, or plain shortened interpolation. */\n readonly morph: \"elastic\" | \"non-elastic\";\n /**\n * Crossfading one *surface transition* into another. Nominal glass never\n * does it — a morph is one continuous material transition, not two surfaces\n * dissolving. Reduced Motion reserves it for large plane shifts. (The\n * foreground light/dark crossfade of §Motion's driver table is a different,\n * unconditional channel and is not governed here.)\n */\n readonly crossfade: \"never\" | \"large-plane-shifts\";\n /**\n * Reduced Motion \"keeps direct-manipulation positional continuity\": a surface\n * being dragged still tracks the pointer. That holds under every preference,\n * so it is an invariant of the model, typed as the literal `true` — there is\n * no combination of inputs that can turn it off.\n */\n readonly positionalContinuity: true;\n}\n\n/**\n * What renderers consume. The four resolved booleans travel with the\n * consequences so a consumer (or `useGlassCapabilities()`) can see *what* was\n * decided and *why*, in the same spirit as X2's `configuredSource` surviving a\n * demotion.\n */\nexport interface ResolvedAccessibilityPolicy {\n readonly reducedTransparency: boolean;\n readonly reducedMotion: boolean;\n readonly increasedContrast: boolean;\n readonly forcedColors: boolean;\n readonly material: ResolvedMaterialPolicy;\n readonly motion: ResolvedMotionPolicy;\n}\n\n/**\n * One table row: the axes a preference changes, and nothing else.\n *\n * `positionalContinuity` is excluded from the motion partial so no row can\n * reach the invariant, whatever a future editor intends.\n */\nexport interface AccessibilityConsequences {\n readonly material?: Partial<ResolvedMaterialPolicy>;\n readonly motion?: Partial<Omit<ResolvedMotionPolicy, \"positionalContinuity\">>;\n}\n\n/** Full-fidelity glass: no preference detected, nothing capped. */\nexport const NOMINAL_ACCESSIBILITY_POLICY: ResolvedAccessibilityPolicy = {\n reducedTransparency: false,\n reducedMotion: false,\n increasedContrast: false,\n forcedColors: false,\n material: {\n glass: \"material\",\n colorSource: \"material\",\n frost: \"nominal\",\n refraction: \"nominal\",\n occlusion: \"nominal\",\n border: \"nominal\",\n ambientTint: \"nominal\",\n foreground: \"adaptive\",\n },\n motion: {\n overshoot: \"elastic\",\n deformation: \"nominal\",\n shimmer: \"travel\",\n morph: \"elastic\",\n crossfade: \"never\",\n positionalContinuity: true,\n },\n};\n\n/**\n * §Accessibility, encoded. Each row is that paragraph's sentence for one\n * preference and carries only the axes the sentence names:\n *\n * - \"Reduced transparency → more frosted, less refraction, higher occlusion.\"\n * - \"Increased contrast → stronger borders, near-monochrome foregrounds,\n * reduced ambient tint.\"\n * - \"`forced-colors` → system colors, borders, no glass.\"\n * - \"Reduced Motion removes elastic overshoot, deformation, and shimmer travel;\n * keeps direct-manipulation positional continuity; shortens morphs to\n * non-elastic interpolation; reserves crossfade for large plane shifts.\"\n * (§Motion)\n *\n * Reduced Motion is the only motion row, and the other three are the only\n * material rows — the spec draws no line between a colour preference and a\n * motion one, so neither does the table.\n */\nexport const ACCESSIBILITY_BEHAVIOR_TABLE: {\n readonly [K in AccessibilityFlag]: AccessibilityConsequences;\n} = {\n reducedTransparency: {\n material: { frost: \"increased\", refraction: \"reduced\", occlusion: \"increased\" },\n },\n increasedContrast: {\n material: { border: \"strong\", foreground: \"near-monochrome\", ambientTint: \"reduced\" },\n },\n reducedMotion: {\n motion: {\n overshoot: \"none\",\n deformation: \"none\",\n shimmer: \"none\",\n morph: \"non-elastic\",\n crossfade: \"large-plane-shifts\",\n },\n },\n forcedColors: {\n // \"system colors, borders, no glass\" — and with the glass gone, every\n // optical axis follows it: nothing to frost, lens, or tint, and a flat\n // system fill that hides the backdrop entirely.\n material: {\n glass: \"none\",\n colorSource: \"system\",\n frost: \"none\",\n refraction: \"none\",\n occlusion: \"opaque\",\n border: \"strong\",\n ambientTint: \"none\",\n foreground: \"near-monochrome\",\n },\n },\n};\n\n/**\n * Fold order, weakest first.\n *\n * `reducedMotion` touches only motion axes, and `reducedTransparency` and\n * `increasedContrast` touch disjoint material axes — those three commute, so\n * two preferences at once compose instead of one silently erasing the other.\n * `forcedColors` is the one row that spans every material axis, and it is last\n * because a platform-level colour mandate outranks every softening an app or a\n * softer preference asked for.\n */\nexport const ACCESSIBILITY_PRECEDENCE = [\n \"reducedMotion\",\n \"reducedTransparency\",\n \"increasedContrast\",\n \"forcedColors\",\n] as const satisfies readonly AccessibilityFlag[];\n\n/** An explicit boolean answers for the platform; `\"system\"` and absence defer to it. */\nconst resolveFlag = (detected: boolean, override: AccessibilityOverride | undefined): boolean =>\n override === undefined || override === \"system\" ? detected : override;\n\n/**\n * No `subjects`: this is a root-level policy finding, not a finding about a\n * group, node, or source id. An empty subject list also makes the channel's\n * dedupe key the code alone, so one misconfigured root reports once.\n */\nconst REDUCED_TRANSPARENCY_UNDETECTABLE: Diagnostic = {\n code: \"reduced-transparency-undetectable\",\n severity: \"warning\",\n subjects: [],\n message:\n 'This platform cannot query `prefers-reduced-transparency`, so leaving `reducedTransparency` on \"system\" silently resolves it to false and the preference is lost. Set the GlassRoot `reducedTransparency` prop to an explicit boolean (§Accessibility policy).',\n};\n\n/**\n * Resolve one `GlassRoot`'s accessibility policy.\n *\n * Purely functional: no state, no I/O, no clock. `diagnostics` is a side\n * channel — passing one never changes the policy that comes back.\n */\nexport function resolveAccessibilityPolicy(\n system: SystemAccessibilityPreferences,\n overrides: AccessibilityOverrides = {},\n diagnostics?: DiagnosticsChannel,\n): ResolvedAccessibilityPolicy {\n const active = {\n reducedTransparency: resolveFlag(system.reducedTransparency, overrides.reducedTransparency),\n reducedMotion: resolveFlag(system.reducedMotion, overrides.reducedMotion),\n increasedContrast: resolveFlag(system.increasedContrast, overrides.increasedContrast),\n // Deliberately not overridable — see OverridableAccessibilityFlag.\n forcedColors: system.forcedColors,\n } satisfies Record<AccessibilityFlag, boolean>;\n\n // The finding is about the *configuration*, not the resolved value: on a\n // platform that cannot answer the query, \"system\" always resolves to false,\n // so the app has no way to honour the preference until it states one. An app\n // that supplied an explicit boolean has already done that.\n const leftToTheSystem =\n overrides.reducedTransparency === undefined || overrides.reducedTransparency === \"system\";\n if (leftToTheSystem && !system.reducedTransparencySupported) {\n diagnostics?.report(REDUCED_TRANSPARENCY_UNDETECTABLE);\n }\n\n let material: ResolvedMaterialPolicy = NOMINAL_ACCESSIBILITY_POLICY.material;\n let motion: ResolvedMotionPolicy = NOMINAL_ACCESSIBILITY_POLICY.motion;\n\n for (const flag of ACCESSIBILITY_PRECEDENCE) {\n if (!active[flag]) continue;\n const row = ACCESSIBILITY_BEHAVIOR_TABLE[flag];\n if (row.material !== undefined) material = { ...material, ...row.material };\n if (row.motion !== undefined) motion = { ...motion, ...row.motion };\n }\n\n return { ...active, material, motion };\n}\n","/**\n * X6 — the hint contract (§Backdrop & analysis contracts).\n *\n * A `dom` group has no pixels vitrea may read, so its adaptation data comes\n * from exactly one mechanism: an author-declared `backdrop` on the GlassGroup,\n * or an estimator provider that supplies the same shape. Three parallel hint\n * mechanisms were consolidated into this one on purpose (Decision Log #13).\n *\n * The word \"estimator\" is load-bearing. A built-in DOM estimator may read known\n * background colours and images where CORS permits, and it is documented as an\n * estimator everywhere it appears — never as pixel analysis, which vitrea does\n * not promise for arbitrary DOM and never will.\n */\n\nimport type { HintAvailability } from \"./capability\";\nimport type { DiagnosticsChannel } from \"./diagnostics\";\n\n/** Coarse light/dark/mixed classification. The one field a hint must carry. */\nexport type BackdropTone = \"light\" | \"dark\" | \"mixed\";\n\nexport interface BackdropHint {\n readonly tone: BackdropTone;\n /** Relative luminance of the backdrop under the group, 0..1. */\n readonly luminance?: number;\n /** Busyness of the backdrop, 0..1 — how hard the foreground has to fight. */\n readonly complexity?: number;\n}\n\n/**\n * The provider form of the same contract. `kind` is a literal so the shape is\n * self-describing wherever it surfaces in developer tooling.\n */\nexport interface BackdropEstimatorProvider {\n readonly kind: \"estimator\";\n /** Names the estimator in diagnostics and developer output. */\n readonly id: string;\n /** Called per group. Returning `undefined` means \"no opinion here\". */\n estimate(groupId: string): BackdropHint | undefined;\n}\n\nexport interface BackdropHintRequest {\n readonly groupId: string;\n readonly backdrop?: BackdropHint;\n readonly estimator?: BackdropEstimatorProvider;\n readonly diagnostics?: DiagnosticsChannel;\n}\n\nexport interface ResolvedBackdropHint {\n readonly availability: HintAvailability;\n /** Absent exactly when `availability` is `\"none\"`. */\n readonly hint?: BackdropHint;\n}\n\n/**\n * Clamp a 0..1 channel, dropping a non-finite value outright: clamping NaN\n * would invent a number the author never supplied.\n */\nfunction normalizeChannel(value: number | undefined): {\n readonly value?: number;\n readonly corrected: boolean;\n} {\n if (value === undefined) return { corrected: false };\n if (!Number.isFinite(value)) return { corrected: true };\n if (value < 0) return { value: 0, corrected: true };\n if (value > 1) return { value: 1, corrected: true };\n return { value, corrected: false };\n}\n\nfunction normalizeHint(\n hint: BackdropHint,\n groupId: string,\n diagnostics: DiagnosticsChannel | undefined,\n): BackdropHint {\n const luminance = normalizeChannel(hint.luminance);\n const complexity = normalizeChannel(hint.complexity);\n\n if (luminance.corrected || complexity.corrected) {\n diagnostics?.report({\n code: \"backdrop-hint-out-of-range\",\n severity: \"warning\",\n subjects: [groupId],\n message: `X6: the backdrop hint for group \"${groupId}\" carried a luminance or complexity outside 0..1. Both are normalised fractions; out-of-range values were clamped and non-finite ones dropped.`,\n });\n }\n\n return {\n tone: hint.tone,\n ...(luminance.value === undefined ? {} : { luminance: luminance.value }),\n ...(complexity.value === undefined ? {} : { complexity: complexity.value }),\n };\n}\n\n/**\n * Resolve a group's hint. An explicit `backdrop` beats an estimator: the author\n * stated a fact, the estimator guessed one. Configuring both is reported once,\n * because it usually means the author forgot they had a provider installed.\n */\nexport function resolveBackdropHint(request: BackdropHintRequest): ResolvedBackdropHint {\n const { groupId, backdrop, estimator, diagnostics } = request;\n\n if (backdrop !== undefined) {\n if (estimator !== undefined) {\n diagnostics?.report({\n code: \"backdrop-hint-redundant-estimator\",\n severity: \"warning\",\n subjects: [groupId],\n message: `X6: group \"${groupId}\" has both an explicit backdrop hint and the estimator \"${estimator.id}\". The explicit hint wins; remove one so the source of adaptation is unambiguous.`,\n });\n }\n return { availability: \"author-hint\", hint: normalizeHint(backdrop, groupId, diagnostics) };\n }\n\n const estimated = estimator?.estimate(groupId);\n if (estimated === undefined) return { availability: \"none\" };\n\n return { availability: \"estimator\", hint: normalizeHint(estimated, groupId, diagnostics) };\n}\n","/**\n * X2 — the capability state machine (§Backdrop & analysis contracts, the\n * honesty core).\n *\n * Capability is not a free tuple. The app *configures* a source; the runtime\n * *resolves* one of an enumerated set of states from probe results that arrive\n * as plain data. Nothing here touches a GPU, a browser or a clock: platform-web\n * probes, C6 renders, this file only decides.\n *\n * ## Resolution rules\n *\n * 0. **WebGPU not requested is not a fault, and neither is WebGPU not ready\n * yet.** A root configured for the CSS tier never had WebGPU in play;\n * `platform.webgpu: \"not-requested\"` forces `activeRenderer: \"css\"` the same\n * way a renderer fault would, but names no fault, so a group with nothing\n * else wrong resolves `health: \"ok\"` — labeling intent as a fault would\n * invert the honesty doctrine (X2's K1 amendment, Decision Log #21c).\n * `\"pending\"` resolves identically, for the same reason read forwards: a root\n * that asked for WebGPU and is still bringing it up has not failed at\n * anything, and answering `no-webgpu` — whose recovery is honestly `\"none\"` —\n * would be a terminal answer to a request still in flight.\n * 1. **Renderer faults** — no WebGPU, a lost device, or a governor tier switch —\n * drop `activeRenderer` to `\"css\"`. Nothing else can.\n * 2. **Sampling faults** demote the backdrop path without touching the\n * renderer. A tainted or incompatible texture leaves WebGPU drawing tint,\n * rim and glow with nothing to sample (`samplingBackend: \"none\"`); it does\n * *not* silently re-point the group at the DOM behind it, because the app\n * asked for a texture and swapping backdrops underneath it would be exactly\n * the pretence this model exists to prevent.\n * 3. **Refraction follows what is actually sampled.** `\"true\"` needs GPU-texture\n * sampling; `\"approximate\"` is the shader's rim-lensing over a CSS proxy;\n * the CSS tier gets `\"none\"` because `backdrop-filter` blurs, it does not\n * bend.\n * 4. **`exact` analysis needs a GPU texture.** Otherwise a declared hint or an\n * estimator provider yields `\"hint\"` (X6), and nothing yields `\"none\"`.\n * 5. **One reason is reported, by precedence** — see `REASON_PRECEDENCE`.\n * 6. **A texture source with no pixels behind it is a sampling fault.** The app\n * declared a texture and the runtime has nothing to read, so the group draws\n * tint, rim and glow over an unsampled backdrop and says so\n * (`no-texture-supplied`). Reporting `gpu-texture` / `true` / `exact` for a\n * source nobody supplied is the loudest possible version of the pretence this\n * file exists to prevent.\n */\n\nimport type { ConfiguredSource, DemotionReason, GlassGroupState } from \"./state\";\n\n/**\n * Whether WebGPU is in play for this root at all, distinct from whether it\n * *works* — a root configured for the CSS tier never asks, and that is a\n * choice, not a fault (X2's K1 amendment, Decision Log #21c).\n *\n * The question is three-state on the way up, not two: between \"asked for\" and\n * \"answered\" there is a startup window in which the answer is not known yet, and\n * a host that has to publish *something* during it has only honest options if\n * the union has a name for it. `\"pending\"` is that name.\n */\nexport const WEBGPU_AVAILABILITIES = [\n \"not-requested\",\n \"pending\",\n \"unavailable\",\n \"available\",\n] as const;\n\nexport type WebGPUAvailability = (typeof WEBGPU_AVAILABILITIES)[number];\n\n/** Platform-wide probe results. platform-web produces these; core only reads them. */\nexport interface PlatformProbe {\n /**\n * `\"available\"` — a WebGPU adapter and device were obtained *and* whatever\n * draws with them is ready to paint. `\"unavailable\"` — WebGPU was requested\n * but no adapter, device or renderer could be had. `\"pending\"` — requested,\n * and the answer has not arrived yet; resolves exactly as `\"not-requested\"`\n * does, so a group is on the CSS tier without being demoted while the GPU tier\n * starts. `\"not-requested\"` — this root never asked for WebGPU at all (its\n * renderer is CSS by choice), which resolves honestly rather than as a fault.\n *\n * The two CSS-without-a-fault values resolve alike and stay tellable apart on\n * purpose: a host reads them back to distinguish \"CSS by choice\" from \"CSS\n * while WebGPU starts\", which is the difference between a final answer and a\n * provisional one.\n */\n readonly webgpu: WebGPUAvailability;\n /** `backdrop-filter` is supported and actually filters. */\n readonly backdropFilter: boolean;\n /**\n * S1's startup conformance probe: does a portaled masked proxy sample the\n * same pixels as an in-place `backdrop-filter`? Filter Effects 2's Backdrop\n * Root lacks WG consensus, so this is probed, never assumed.\n */\n readonly backdropProxyConformance: \"pass\" | \"fail\";\n readonly deviceHealth: \"ok\" | \"lost\";\n}\n\n/** Per-source facts. Meaningful for `texture` sources only. */\nexport interface SourceProbe {\n /** CORS taint. A tainted source cannot be read into a GPU texture at all. */\n readonly taint: \"clean\" | \"tainted\";\n /** Whether an app-supplied view satisfies the declared usage/format/dimension requirements. */\n readonly textureCompatibility: \"compatible\" | \"incompatible\";\n /**\n * Whether pixels have actually been handed over for this source.\n *\n * `TextureBackdropSource` declares that a source *is* a texture and carries no\n * pixels — core may not know what an `HTMLCanvasElement` is (X4) — so the\n * declaration and the supply are two separate events, and a group can sit\n * between them for as long as the app takes. Only the platform layer knows\n * which side of that gap a source is on, so it folds the fact in here, exactly\n * as it folds a per-group proxy verdict into `backdropProxyConformance`\n * (Decision Log #21a).\n *\n * Optional, defaulting to `\"supplied\"`: core cannot see the pixels either way,\n * and a resolver that assumed absence would demote every source registered\n * through a host that does not report this at all.\n */\n readonly supply?: \"supplied\" | \"absent\";\n}\n\n/**\n * Quality-governor pressure (§Performance envelope). The governor degrades\n * *within* a tier before it switches tiers, so only `\"demote-tier\"` is a\n * demotion; `\"degrade-in-tier\"` changes render quality knobs C6 owns and leaves\n * the resolved state untouched.\n */\nexport const GOVERNOR_PRESSURES = [\"none\", \"degrade-in-tier\", \"demote-tier\"] as const;\n\nexport type GovernorPressure = (typeof GOVERNOR_PRESSURES)[number];\n\n/**\n * X6 — which of the one hint mechanism is in play. Both an author-declared\n * `backdrop` prop and an estimator provider produce `analysis: \"hint\"`; the\n * distinction is kept for developer-facing reporting, never smuggled into the\n * state, whose shape is frozen.\n */\nexport const HINT_AVAILABILITIES = [\"none\", \"author-hint\", \"estimator\"] as const;\n\nexport type HintAvailability = (typeof HINT_AVAILABILITIES)[number];\n\n/** Everything the resolver needs. A texture group must declare its source probe. */\nexport type CapabilityInputs =\n | {\n readonly configuredSource: \"texture\";\n readonly platform: PlatformProbe;\n readonly source: SourceProbe;\n readonly governor: GovernorPressure;\n readonly hint: HintAvailability;\n }\n | {\n readonly configuredSource: \"dom\";\n readonly platform: PlatformProbe;\n readonly source?: undefined;\n readonly governor: GovernorPressure;\n readonly hint: HintAvailability;\n };\n\n/**\n * Which reason is reported when several faults hold. Platform facts come first\n * because they explain the largest loss; the governor comes last so transient\n * pressure never masks a standing fault the app could fix.\n */\nconst REASON_PRECEDENCE: readonly DemotionReason[] = [\n \"no-webgpu\",\n \"device-lost\",\n \"no-texture-supplied\",\n \"tainted-source\",\n \"incompatible-texture\",\n \"no-backdrop-filter\",\n \"probe-failed\",\n \"governor\",\n];\n\n/** What clears a demotion. `\"none\"` is the honest answer for a platform fact. */\nexport type RecoveryTrigger =\n | \"device-restored\"\n | \"source-replaced\"\n | \"probe-repassed\"\n | \"pressure-released\"\n | \"none\";\n\nexport interface RecoveryContract {\n readonly trigger: RecoveryTrigger;\n readonly explanation: string;\n}\n\n/**\n * Every demotion names its recovery transition (§honesty core). This table is\n * the contract; the resolver is stateless, so recovery *is* re-resolution once\n * the named input changes.\n */\nexport const DEMOTION_RECOVERY: Readonly<Record<DemotionReason, RecoveryContract>> = {\n \"no-webgpu\": {\n trigger: \"none\",\n explanation:\n \"WebGPU is unavailable in this browser session. Nothing the app can do recovers it; a user enabling support means a new session.\",\n },\n \"no-backdrop-filter\": {\n trigger: \"probe-repassed\",\n explanation:\n \"The backdrop-filter probe failed. Re-running it after the page's filter context changes can pass.\",\n },\n \"tainted-source\": {\n trigger: \"source-replaced\",\n explanation:\n \"A CORS-tainted source cannot be read into a GPU texture. Register a same-origin or CORS-permitted source.\",\n },\n \"incompatible-texture\": {\n trigger: \"source-replaced\",\n explanation:\n \"The supplied texture view does not satisfy the declared usage, format or dimension requirements. Register a conforming source.\",\n },\n \"no-texture-supplied\": {\n trigger: \"source-replaced\",\n explanation:\n \"The source is declared as a texture and no pixels have been handed over for it yet, so there is nothing to sample. Supply the canvas, image or video behind it — the group keeps drawing tint, rim and glow until then.\",\n },\n \"device-lost\": {\n trigger: \"device-restored\",\n explanation:\n \"The GPUDevice was lost. vitrea-owned devices re-request automatically; an app-owned device needs the replacement-device callback and the resource re-registration handshake.\",\n },\n \"probe-failed\": {\n trigger: \"probe-repassed\",\n explanation:\n \"The backdrop-proxy conformance probe found this engine's proxy sampling non-equivalent. It clears if the probe passes on a later run.\",\n },\n governor: {\n trigger: \"pressure-released\",\n explanation:\n \"The quality governor switched tiers under sustained pressure. It restores after its hysteresis and cooldown elapse.\",\n },\n};\n\n/** Faults that hold for these inputs, independent of what was resolved from them. */\nfunction applicableFaults(inputs: CapabilityInputs): readonly DemotionReason[] {\n const { platform, governor, configuredSource } = inputs;\n const faults = new Set<DemotionReason>();\n\n if (platform.webgpu === \"unavailable\") faults.add(\"no-webgpu\");\n // A device can only be lost if there was one to lose.\n if (platform.webgpu === \"available\" && platform.deviceHealth === \"lost\") {\n faults.add(\"device-lost\");\n }\n\n if (configuredSource === \"texture\") {\n if (inputs.source.supply === \"absent\") {\n // Taint and compatibility are claims *about supplied pixels*. With none\n // handed over there is nothing for them to be true or false of, so raising\n // them here would name a fault about a thing that does not exist.\n faults.add(\"no-texture-supplied\");\n } else {\n if (inputs.source.taint === \"tainted\") faults.add(\"tainted-source\");\n if (inputs.source.textureCompatibility === \"incompatible\") faults.add(\"incompatible-texture\");\n }\n } else {\n if (!platform.backdropFilter) {\n faults.add(\"no-backdrop-filter\");\n } else if (platform.backdropProxyConformance === \"fail\") {\n // Only meaningful where there is a filter to apply. Raising both would\n // put the group on the CSS tier (probe-failed demotes the renderer) with\n // no CSS blur to draw with — the worst of both, and the opposite of what\n // `no-backdrop-filter` is supposed to preserve.\n faults.add(\"probe-failed\");\n }\n }\n\n if (governor === \"demote-tier\") faults.add(\"governor\");\n\n return REASON_PRECEDENCE.filter((reason) => faults.has(reason));\n}\n\n/**\n * Faults that drop the renderer to the CSS tier.\n *\n * `probe-failed` is here because the spec says so outright: when the proxy\n * topology proves non-equivalent, the group demotes *to the CSS tier*\n * (§rendering contract, and S1's \"its dom groups demote to the CSS tier\"). That\n * is also the sensible fallback — the CSS tier applies `backdrop-filter` in\n * place and uses no proxies at all, so the very thing that failed is not on its\n * path.\n */\nconst RENDERER_FAULTS: readonly DemotionReason[] = [\n \"no-webgpu\",\n \"device-lost\",\n \"probe-failed\",\n \"governor\",\n];\n\n/**\n * Faults that cost the group its backdrop while the renderer keeps drawing.\n *\n * `no-backdrop-filter` is deliberately *not* a renderer fault, unlike\n * `probe-failed`: if the engine has no CSS blur at all, the CSS tier cannot draw\n * glass either, so keeping WebGPU — which can still render tint, rim and glow\n * geometrically over an unsampled backdrop — is both the higher fidelity and the\n * honest answer.\n */\nconst SAMPLING_FAULTS: readonly DemotionReason[] = [\n \"tainted-source\",\n \"incompatible-texture\",\n \"no-texture-supplied\",\n \"no-backdrop-filter\",\n];\n\n/**\n * Resolve one group's state. Pure, total, and deterministic: the same inputs\n * always produce the same state, and `configuredSource` is copied through\n * untouched by every path.\n */\nexport function resolveGlassGroupState(inputs: CapabilityInputs): GlassGroupState {\n const faults = applicableFaults(inputs);\n const configuredSource: ConfiguredSource = inputs.configuredSource;\n\n const rendererDemoted = faults.some((fault) => RENDERER_FAULTS.includes(fault));\n const samplingDemoted = faults.some((fault) => SAMPLING_FAULTS.includes(fault));\n\n // A root that never requested WebGPU — or that is still bringing it up —\n // forces the same renderer a fault would, without being one: neither names\n // anything in `faults`, so a group with no other fault reports `health: \"ok\"`\n // (rule 0 above).\n const cssWithoutFault =\n inputs.platform.webgpu === \"not-requested\" || inputs.platform.webgpu === \"pending\";\n const activeRenderer = cssWithoutFault || rendererDemoted ? \"css\" : \"webgpu\";\n\n const sampling = ((): Pick<GlassGroupState, \"samplingBackend\" | \"refraction\"> => {\n if (activeRenderer === \"css\") {\n // No shader runs, so nothing bends; backdrop-filter still frosts if present.\n return {\n samplingBackend: inputs.platform.backdropFilter ? \"css-backdrop\" : \"none\",\n refraction: \"none\",\n };\n }\n if (samplingDemoted) {\n return { samplingBackend: \"none\", refraction: \"none\" };\n }\n return configuredSource === \"texture\"\n ? { samplingBackend: \"gpu-texture\", refraction: \"true\" }\n : { samplingBackend: \"css-backdrop\", refraction: \"approximate\" };\n })();\n\n const analysis =\n sampling.samplingBackend === \"gpu-texture\" ? \"exact\" : inputs.hint === \"none\" ? \"none\" : \"hint\";\n\n const reason = faults[0];\n\n return {\n configuredSource,\n activeRenderer,\n ...sampling,\n analysis,\n health: reason === undefined ? \"ok\" : \"demoted\",\n ...(reason === undefined ? {} : { demotionReason: reason }),\n };\n}\n\n/** How one group's state moved between two resolutions. */\nexport type StateChange =\n | { readonly kind: \"unchanged\" }\n /** The group's first resolution — there was no previous state to move from. */\n | { readonly kind: \"initial\"; readonly reason?: DemotionReason }\n | { readonly kind: \"demoted\"; readonly reason: DemotionReason }\n | { readonly kind: \"recovered\"; readonly from: DemotionReason }\n | { readonly kind: \"changed\"; readonly reason?: DemotionReason };\n\nconst STATE_KEYS = [\n \"configuredSource\",\n \"activeRenderer\",\n \"samplingBackend\",\n \"refraction\",\n \"analysis\",\n \"health\",\n \"demotionReason\",\n] as const;\n\nconst sameState = (a: GlassGroupState, b: GlassGroupState): boolean =>\n STATE_KEYS.every((key) => a[key] === b[key]);\n\n/**\n * Name a transition, so a host can log \"recovered from device-lost\" rather than\n * diff two records. Used by the scene when it re-resolves during a frame. A\n * missing `previous` is a group's first resolution, not a change.\n */\nexport function classifyStateChange(\n previous: GlassGroupState | undefined,\n next: GlassGroupState,\n): StateChange {\n if (previous === undefined) {\n return {\n kind: \"initial\",\n ...(next.demotionReason === undefined ? {} : { reason: next.demotionReason }),\n };\n }\n if (sameState(previous, next)) return { kind: \"unchanged\" };\n\n if (previous.health === \"ok\" && next.demotionReason !== undefined) {\n return { kind: \"demoted\", reason: next.demotionReason };\n }\n if (previous.demotionReason !== undefined && next.health === \"ok\") {\n return { kind: \"recovered\", from: previous.demotionReason };\n }\n return {\n kind: \"changed\",\n ...(next.demotionReason === undefined ? {} : { reason: next.demotionReason }),\n };\n}\n","/**\n * The diagnostics channel — how core reports authoring problems it detects but\n * must not silently fix.\n *\n * Core is passive and DOM-free (X4), so it neither writes to a console nor\n * decides what a host does with a finding: the host supplies a sink. Findings\n * are deduplicated by default, because several of them are produced by checks\n * that run every frame (same-plane overlap, variant mixing) and a firehose is\n * worse than silence.\n *\n * Structural mistakes — an unknown id, a duplicate id, a still-referenced\n * source — are *not* diagnostics. Those throw `GlassSceneError`, because\n * continuing past them would leave a half-built scene. Diagnostics carry the\n * recoverable, per-frame, policy-level findings instead.\n */\n\nexport type DiagnosticSeverity = \"warning\" | \"error\";\n\n/** Everything core can report. Owned here so a host can switch exhaustively. */\nexport const DIAGNOSTIC_CODES = [\n /** Two glass surfaces overlap inside one plane — the sandwich cannot express it (X1). */\n \"same-plane-overlap\",\n /** `regular` and `clear` nodes share one GlassGroup (§Material variants). */\n \"variant-mixing\",\n /** A group's `mergeDistance` is below its `samplingPadding`, so proxies can double-filter (X1). */\n \"merge-distance-below-padding\",\n /** Two groups' padded proxies cover the same pixels, so the filter applies twice (X1). */\n \"group-proxy-overlap\",\n /** A `clear` node has no dimming policy, so it resolved to `regular` instead. */\n \"clear-variant-needs-dimming\",\n /** A foreground mode the resolved state cannot support; the nearest legal mode was used. */\n \"foreground-mode-illegal\",\n /** A `sampled-async` rate or hysteresis outside the supported range was clamped. */\n \"foreground-rate-clamped\",\n /** A backdrop hint carried a luminance/complexity outside 0..1. */\n \"backdrop-hint-out-of-range\",\n /** Both an explicit hint and an estimator provider are configured; the explicit hint wins (X6). */\n \"backdrop-hint-redundant-estimator\",\n /** `reducedTransparency` is left on \"system\" where the platform cannot detect it. */\n \"reduced-transparency-undetectable\",\n /** A frame-phase operation was performed in the wrong phase. */\n \"frame-phase-violation\",\n] as const;\n\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[number];\n\nexport interface Diagnostic {\n readonly code: DiagnosticCode;\n readonly severity: DiagnosticSeverity;\n /**\n * The ids this finding is about — group, node, or source. Together with\n * `code` this is the dedupe key, so \"these two nodes overlap\" is one finding\n * however many frames it survives.\n */\n readonly subjects: readonly string[];\n readonly message: string;\n}\n\nexport type DiagnosticSink = (diagnostic: Diagnostic) => void;\n\nexport interface DiagnosticsChannel {\n report(diagnostic: Diagnostic): void;\n /** Findings retained since construction or the last `clear()`. */\n readonly reported: readonly Diagnostic[];\n /** Forget what was seen, so a condition that returns is reported again. */\n clear(): void;\n}\n\nexport interface DiagnosticsChannelOptions {\n /** Where findings go. Omitted in tests and in hosts that only read `reported`. */\n readonly sink?: DiagnosticSink;\n /** Collapse repeats of the same code+subjects. Default true. */\n readonly dedupe?: boolean;\n}\n\n/** Separator for the dedupe key — a unit separator, so no realistic id collides. */\nconst KEY_SEPARATOR = \"␟\";\n\nconst keyOf = (diagnostic: Diagnostic): string =>\n [diagnostic.code, ...diagnostic.subjects].join(KEY_SEPARATOR);\n\nexport function createDiagnosticsChannel(\n options: DiagnosticsChannelOptions = {},\n): DiagnosticsChannel {\n const { sink, dedupe = true } = options;\n const retained: Diagnostic[] = [];\n const seen = new Set<string>();\n\n return {\n report(diagnostic: Diagnostic): void {\n if (dedupe) {\n const key = keyOf(diagnostic);\n if (seen.has(key)) return;\n seen.add(key);\n }\n retained.push(diagnostic);\n sink?.(diagnostic);\n },\n get reported(): readonly Diagnostic[] {\n return retained;\n },\n clear(): void {\n retained.length = 0;\n seen.clear();\n },\n };\n}\n","/**\n * §Foreground adaptation — the GPU → DOM data path's policy half.\n *\n * `ForegroundAdaptation = fixed | author-hint | sampled-async { rateHz,\n * hysteresis }`. The interesting part is legality: `sampled-async` needs GPU\n * classification results, so it is available only where `analysis: \"exact\"` —\n * \"exactly\", per the honesty doctrine. An illegal combination is neither\n * honoured nor silently dropped: it resolves to the nearest legal mode and the\n * downgrade is both returned and reported.\n *\n * Nothing here reads a clock or schedules anything. `rateHz` is a declared\n * cadence platform-web drives; core only validates it.\n */\n\nimport type { AnalysisQuality, GlassGroupState } from \"./state\";\nimport type { DiagnosticsChannel } from \"./diagnostics\";\n\n/** The three modes, ordered most adaptive first — the order the fallback walks. */\nexport const FOREGROUND_MODES = [\"sampled-async\", \"author-hint\", \"fixed\"] as const;\n\nexport type ForegroundMode = (typeof FOREGROUND_MODES)[number];\n\nexport type ForegroundAdaptation =\n | { readonly mode: \"fixed\" }\n | { readonly mode: \"author-hint\" }\n | {\n readonly mode: \"sampled-async\";\n /** Readback cadence. Low-frequency by contract — never per-frame. */\n readonly rateHz: number;\n /** Threshold band, 0..1, that keeps scrolling from pumping the foreground. */\n readonly hysteresis: number;\n };\n\n/**\n * Advisory bounds. `maxHz` exists to keep \"low-frequency async readback\" true\n * rather than aspirational: a quarter of a 60Hz frame budget is already far\n * more often than a foreground tone needs to change. Calibration (C7) may\n * replace these numbers; the invariant that readback is not per-frame is not\n * negotiable.\n */\nexport const SAMPLED_ASYNC_RATE_LIMITS = {\n minHz: 1,\n maxHz: 15,\n minHysteresis: 0.02,\n maxHysteresis: 0.5,\n} as const;\n\n/** Advisory defaults, replaced by calibration profiles (§Calibration). */\nexport const SAMPLED_ASYNC_DEFAULTS = { rateHz: 4, hysteresis: 0.06 } as const;\n\n/** Which modes a state can honestly support, most adaptive first. */\nfunction legalModes(analysis: AnalysisQuality): readonly ForegroundMode[] {\n switch (analysis) {\n case \"exact\":\n return FOREGROUND_MODES;\n case \"hint\":\n return [\"author-hint\", \"fixed\"];\n case \"none\":\n return [\"fixed\"];\n }\n}\n\nexport interface ForegroundResolutionOptions {\n /**\n * What a finding is about — a group id, or a node id where a surface\n * overrides its group's mode. Also the dedupe subject, so a standing\n * downgrade is reported once rather than once per frame.\n */\n readonly subject?: string;\n readonly diagnostics?: DiagnosticsChannel;\n}\n\nexport interface ResolvedForegroundAdaptation {\n readonly adaptation: ForegroundAdaptation;\n /** Present only when the requested mode was not legal for this state. */\n readonly downgraded?: { readonly from: ForegroundMode; readonly to: ForegroundMode };\n}\n\nconst clamp = (value: number, min: number, max: number): number =>\n Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : min;\n\nfunction validateSampled(\n requested: Extract<ForegroundAdaptation, { mode: \"sampled-async\" }>,\n options: ForegroundResolutionOptions,\n): ForegroundAdaptation {\n const { minHz, maxHz, minHysteresis, maxHysteresis } = SAMPLED_ASYNC_RATE_LIMITS;\n const rateHz = clamp(requested.rateHz, minHz, maxHz);\n const hysteresis = clamp(requested.hysteresis, minHysteresis, maxHysteresis);\n\n if (rateHz !== requested.rateHz || hysteresis !== requested.hysteresis) {\n options.diagnostics?.report({\n code: \"foreground-rate-clamped\",\n severity: \"warning\",\n subjects: [options.subject ?? \"*\"],\n message: `Foreground sampled-async parameters were clamped to the supported range (rateHz ${minHz}..${maxHz}, hysteresis ${minHysteresis}..${maxHysteresis}). Readback is low-frequency by contract, never per-frame.`,\n });\n }\n\n return { mode: \"sampled-async\", rateHz, hysteresis };\n}\n\n/**\n * Resolve a requested mode against a resolved group state. Total: every\n * request produces a legal adaptation, because `fixed` is legal everywhere.\n */\nexport function resolveForegroundAdaptation(\n requested: ForegroundAdaptation,\n state: GlassGroupState,\n options: ForegroundResolutionOptions = {},\n): ResolvedForegroundAdaptation {\n const legal = legalModes(state.analysis);\n\n if (legal.includes(requested.mode)) {\n return {\n adaptation:\n requested.mode === \"sampled-async\" ? validateSampled(requested, options) : requested,\n };\n }\n\n // Walk down from the requested mode to the first legal one. `fixed` is always\n // legal, so this cannot fall off the end.\n const from = requested.mode;\n const to = FOREGROUND_MODES.slice(FOREGROUND_MODES.indexOf(from) + 1).find((mode) =>\n legal.includes(mode),\n );\n const target: ForegroundMode = to ?? \"fixed\";\n\n options.diagnostics?.report({\n code: \"foreground-mode-illegal\",\n severity: \"warning\",\n subjects: [options.subject ?? \"*\"],\n message: `Foreground mode \"${from}\" needs a state this group does not have — sampled-async requires analysis: exact, author-hint requires a backdrop hint or estimator (X6). Resolved analysis is \"${state.analysis}\", so \"${target}\" was used instead.`,\n });\n\n return {\n adaptation: target === \"sampled-async\" ? { ...SAMPLED_ASYNC_DEFAULTS, mode: target } : { mode: target },\n downgraded: { from, to: target },\n };\n}\n\n/**\n * The mode a group gets when the app states none: adapt wherever that is\n * honest, hint where the author supplied one, fixed tones for arbitrary DOM.\n */\nexport function defaultForegroundAdaptation(state: GlassGroupState): ForegroundAdaptation {\n switch (state.analysis) {\n case \"exact\":\n return { mode: \"sampled-async\", ...SAMPLED_ASYNC_DEFAULTS };\n case \"hint\":\n return { mode: \"author-hint\" };\n case \"none\":\n return { mode: \"fixed\" };\n }\n}\n","/**\n * The frame vocabulary, shared by the scene and the scheduler.\n *\n * It lives in its own module because both need it: the scheduler drives the\n * phases, and the scene uses the current phase to gate the operations that only\n * make sense in one of them.\n *\n * The five phases are the pipeline the spec describes: collect what changed,\n * read the DOM once in a batch, update the scene from those reads, write the GPU\n * resources, then render. Their point is ordering discipline — every layout read\n * in one place so the steady state performs none, and every scene mutation\n * finished before the renderer starts walking the graph.\n */\n\nexport const FRAME_PHASES = [\"collect\", \"read\", \"update\", \"write\", \"render\"] as const;\n\nexport type FramePhase = (typeof FRAME_PHASES)[number];\n\n/**\n * What a host knows about the frame it is driving. `timeMs` arrives as a number\n * because core reads no clock (X4) — it is the host's monotonic timestamp.\n */\nexport interface FrameInfo {\n /** Monotonically increasing. Also the scope for at-most-once-per-frame work. */\n readonly id: number;\n readonly timeMs: number;\n}\n","/**\n * §Material variants.\n *\n * `regular` is the adaptive default. `clear` is persistently more transparent\n * with constrained adaptation, and it *requires* a dimming policy — without one\n * there is nothing keeping foreground content legible over a busy backdrop.\n *\n * Two deliberate choices here:\n *\n * - A `clear` surface with no dimming policy resolves to `regular` and raises a\n * dev-mode **error**. Applying an invented policy silently would be the one\n * thing this codebase refuses: pretending to a capability the author never\n * configured. Falling back to `regular` cannot produce an illegible surface,\n * and `DEFAULT_CLEAR_DIMMING` makes satisfying the requirement a one-liner.\n * - Mixing variants inside one GlassGroup **warns** and changes nothing. Apple's\n * guidance is not to mix; coercing one of the two would silently discard an\n * author's intent, which is worse than a surface that looks wrong on purpose.\n */\n\nimport type { DiagnosticsChannel } from \"./diagnostics\";\n\nexport const MATERIAL_VARIANTS = [\"regular\", \"clear\"] as const;\n\nexport type MaterialVariant = (typeof MATERIAL_VARIANTS)[number];\n\n/** The scrim laid beneath clear glass so foreground content stays legible. */\nexport interface DimmingPolicy {\n /** Scrim opacity, 0..1. */\n readonly scrim: number;\n /** Which way the scrim pushes the backdrop — dark content over light, or the reverse. */\n readonly direction: \"darken\" | \"lighten\";\n}\n\n/**\n * Advisory default, named as a delegated unknown in §Calibration: the harness\n * fits the real value. Its purpose here is to make the requirement cheap to\n * satisfy, not to be correct.\n */\nexport const DEFAULT_CLEAR_DIMMING: DimmingPolicy = { scrim: 0.28, direction: \"darken\" };\n\n/** A group's material defaults. A node inherits `variant` when it declares none. */\nexport interface MaterialProfile {\n readonly variant: MaterialVariant;\n /** Required for any clear surface in the group. */\n readonly dimming?: DimmingPolicy;\n}\n\nexport interface ResolvedMaterial {\n readonly variant: MaterialVariant;\n /** Regular adapts to the backdrop; clear's response is deliberately constrained. */\n readonly adaptation: \"adaptive\" | \"constrained\";\n /** Present exactly when `variant` is `\"clear\"`. */\n readonly dimming?: DimmingPolicy;\n}\n\nexport interface MaterialRequest {\n readonly variant: MaterialVariant;\n readonly dimming?: DimmingPolicy;\n /** Named in diagnostics; also the dedupe subject. */\n readonly nodeId?: string;\n readonly diagnostics?: DiagnosticsChannel;\n}\n\nexport function resolveMaterial(request: MaterialRequest): ResolvedMaterial {\n const { variant, dimming, nodeId, diagnostics } = request;\n\n if (variant === \"regular\") return { variant: \"regular\", adaptation: \"adaptive\" };\n\n if (dimming === undefined) {\n diagnostics?.report({\n code: \"clear-variant-needs-dimming\",\n severity: \"error\",\n subjects: [nodeId ?? \"*\"],\n message: `The clear variant requires a dimming policy (§Material variants); without one its foreground is not guaranteed legible. This surface rendered as regular instead. Supply one on the group's material profile — DEFAULT_CLEAR_DIMMING is a usable starting point.`,\n });\n return { variant: \"regular\", adaptation: \"adaptive\" };\n }\n\n return { variant: \"clear\", adaptation: \"constrained\", dimming };\n}\n\nexport interface VariantMixingCheck {\n readonly groupId: string;\n readonly members: readonly { readonly nodeId: string; readonly variant: MaterialVariant }[];\n readonly diagnostics?: DiagnosticsChannel;\n}\n\n/**\n * Report a group whose members do not agree on a variant. Returns whether they\n * were mixed; changes nothing either way.\n */\nexport function checkVariantMixing(check: VariantMixingCheck): boolean {\n const { groupId, members, diagnostics } = check;\n\n const regular = members.filter((member) => member.variant === \"regular\");\n const clear = members.filter((member) => member.variant === \"clear\");\n if (regular.length === 0 || clear.length === 0) return false;\n\n const name = (list: typeof members) => list.map((member) => member.nodeId).join(\", \");\n diagnostics?.report({\n code: \"variant-mixing\",\n severity: \"warning\",\n subjects: [groupId],\n message: `Group \"${groupId}\" mixes material variants, which Apple's guidance advises against: regular on ${name(regular)}, clear on ${name(clear)}. Both render as authored — split them into separate groups if the mix was not deliberate.`,\n });\n\n return true;\n}\n","/**\n * The z-slot model (§Core model: `z-slot (plane + order)`) and the geometry\n * primitives core needs to reason about it.\n *\n * Plane identity lives here rather than in platform-web because it is part of\n * the scene model: a GlassNode's slot is (plane, order), and the same-plane\n * overlap check is a core invariant. platform-web owns the *DOM realisation* of\n * a plane — the canvas pair and the paint order inside it (X1) — and re-exports\n * these names so there is one vocabulary.\n *\n * `Rect` is plain data. The numbers arrive from platform-web's batched layout\n * read; core never measures anything (X4).\n */\n\n/** v1 ships exactly two managed stacking planes (X1). More overlays are out of scope. */\nexport const GLASS_PLANES = [\"base\", \"overlay\"] as const;\n\nexport type GlassPlane = (typeof GLASS_PLANES)[number];\n\n/**\n * Where a node sits. `plane` picks the canvas pair; `order` sequences nodes\n * within it. Nodes in one plane must not overlap (X1) — order breaks ties for\n * paint sequence, it does not license stacking.\n */\nexport interface ZSlot {\n readonly plane: GlassPlane;\n readonly order: number;\n}\n\n/** Viewport-space rectangle in CSS px, measured by platform-web and handed in as data. */\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\nconst planeIndex = (plane: GlassPlane): number => GLASS_PLANES.indexOf(plane);\n\n/** Back-to-front ordering: every base node before every overlay node, then by `order`. */\nexport function compareZSlot(a: ZSlot, b: ZSlot): number {\n const byPlane = planeIndex(a.plane) - planeIndex(b.plane);\n return byPlane !== 0 ? byPlane : a.order - b.order;\n}\n\n/** Smallest rect containing both. */\nexport function unionRect(a: Rect, b: Rect): Rect {\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n return {\n x,\n y,\n width: Math.max(a.x + a.width, b.x + b.width) - x,\n height: Math.max(a.y + a.height, b.y + b.height) - y,\n };\n}\n\n/** Grow a rect outwards on every side — how a group's proxy gets its padding. */\nexport function inflateRect(rect: Rect, by: number): Rect {\n return {\n x: rect.x - by,\n y: rect.y - by,\n width: rect.width + by * 2,\n height: rect.height + by * 2,\n };\n}\n\n/**\n * Positive-area intersection. Touching edges are not an overlap — adjacent\n * surfaces in a toolbar are the common case and are legal. A degenerate rect\n * (an unmeasured or collapsed host) overlaps nothing.\n */\nexport function rectsOverlap(a: Rect, b: Rect): boolean {\n if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0) return false;\n return (\n a.x < b.x + b.width && b.x < a.x + a.width && a.y < b.y + b.height && b.y < a.y + a.height\n );\n}\n","/**\n * The scene model (§Core model): the three registries and everything that\n * follows from their references.\n *\n * ```\n * BackdropSource GlassGroup GlassNode\n * ├─ kind: texture | dom ├─ backdropSourceId ├─ shape family params\n * ├─ raw texture/source ├─ morph namespace ├─ viewport bounds, clip\n * ├─ blur pyramid ├─ material profile ├─ z-slot (plane + order)\n * ├─ analysis maps ├─ adaptation policy ├─ variant\n * ├─ dirty epoch ├─ mergeDistance ├─ interaction state\n * └─ resolution policy └─ samplingPadding └─ foreground policy\n * ```\n *\n * Core owns the *bookkeeping* half of each row. The raw texture, the blur\n * pyramid and the analysis maps are GPU objects C6 owns; what lives here is the\n * fact that they belong to the **source** and not to the group, plus the\n * dirty-epoch accounting that makes the invariant enforceable: a dirty source\n * yields **at most one rebuild per frame**, serving every group that samples it.\n * That hand-out is provisional for as long as the frame is — a frame that throws\n * gives its claims back (`rollbackDirtyBackdropSources`), because a spent claim\n * with nothing built behind it would leave the source clean forever.\n *\n * Two failure modes are kept deliberately distinct:\n *\n * - **Structural** mistakes throw `GlassSceneError` — a duplicate id, a dangling\n * reference, removing something still in use. Continuing past one leaves a\n * scene whose references lie, so there is nothing to report and recover from.\n * - **Policy** findings go to the diagnostics channel — overlap, variant mixing,\n * an illegal foreground mode. Those are recoverable, often per-frame, and the\n * host decides what to do about them.\n *\n * Nothing here measures, schedules, or draws. Viewport rects arrive as data from\n * platform-web's batched read; frames are driven from outside (see\n * `scheduler.ts`).\n */\n\nimport type { ShapeChannels, ShapeFamily } from \"@vitrea/geometry\";\nimport type { InteractionState } from \"@vitrea/motion\";\n\nimport {\n resolveAccessibilityPolicy,\n type AccessibilityOverrides,\n type ResolvedAccessibilityPolicy,\n type SystemAccessibilityPreferences,\n} from \"./accessibility\";\nimport {\n resolveBackdropHint,\n type BackdropEstimatorProvider,\n type BackdropHint,\n type ResolvedBackdropHint,\n} from \"./backdrop-hint\";\nimport {\n classifyStateChange,\n resolveGlassGroupState,\n type CapabilityInputs,\n type GovernorPressure,\n type HintAvailability,\n type PlatformProbe,\n type SourceProbe,\n type StateChange,\n} from \"./capability\";\nimport { createDiagnosticsChannel, type DiagnosticsChannel } from \"./diagnostics\";\nimport type { FramePhase } from \"./frame\";\nimport {\n defaultForegroundAdaptation,\n resolveForegroundAdaptation,\n type ForegroundAdaptation,\n type ResolvedForegroundAdaptation,\n} from \"./foreground\";\nimport {\n checkVariantMixing,\n resolveMaterial,\n type MaterialProfile,\n type MaterialVariant,\n type ResolvedMaterial,\n} from \"./material\";\nimport {\n inflateRect,\n rectsOverlap,\n unionRect,\n type GlassPlane,\n type Rect,\n type ZSlot,\n} from \"./planes\";\nimport type { GlassGroupState } from \"./state\";\n\nexport type GlassSceneErrorCode = \"duplicate-id\" | \"unknown-id\" | \"in-use\" | \"wrong-source-kind\";\n\n/** A structural violation. Distinct from a diagnostic: the scene refuses the change. */\nexport class GlassSceneError extends Error {\n readonly code: GlassSceneErrorCode;\n\n constructor(code: GlassSceneErrorCode, message: string) {\n super(message);\n this.name = \"GlassSceneError\";\n this.code = code;\n }\n}\n\n/**\n * How large the derived pyramids for a texture source are. Effect-texture\n * resolution is decoupled from DOM DPR on purpose (§Performance envelope).\n */\nexport interface BackdropResolutionPolicy {\n /** Effect-texture scale relative to CSS px. */\n readonly scale: number;\n /** Cap on a pyramid level's longest side, in texture px. */\n readonly maxDimension: number;\n}\n\n/** Advisory default; the governor and calibration both move it. */\nexport const DEFAULT_BACKDROP_RESOLUTION: BackdropResolutionPolicy = {\n scale: 1,\n maxDimension: 2048,\n};\n\n/** How far a group samples beyond its member union, and how near members merge. */\nexport interface GroupSamplingGeometry {\n /** Padding on the proxy's border box, in CSS px. */\n readonly samplingPadding: number;\n /** Proximity-union threshold within the group, in CSS px. */\n readonly mergeDistance: number;\n}\n\n/**\n * Advisory defaults, chosen so X1's constraints hold out of the box rather than\n * being numbers worth trusting.\n *\n * S1 measured that `samplingPadding` must be at least 3σ of the group's blur:\n * Filter Effects 2 clips a filter's input to the filtered element's own border\n * box, so an unpadded box starves its own blur at the edges. 24 is 3σ at\n * σ = 8 CSS px, a plausible regular-material blur — calibration (C7) replaces\n * it, and the *actual* 3σ check cannot live here because core carries no blur\n * radius (see the note on `GlassGroupDescriptor.samplingPadding`).\n *\n * `mergeDistance` defaults to the same number because X1 requires\n * `mergeDistance ≥ samplingPadding`: any two members close enough for their\n * padded proxies to overlap must already have merged into one, or the filter\n * applies twice — measured at 1.5625× for `brightness(1.25)`, paint-order\n * dependent, drifting up to 17/255 even in legal 8px-gap geometry.\n */\nexport const DEFAULT_GROUP_SAMPLING: GroupSamplingGeometry = {\n samplingPadding: 24,\n mergeDistance: 24,\n};\n\nexport interface TextureBackdropSource {\n readonly id: string;\n readonly kind: \"texture\";\n /**\n * Probed *before* registration. Reporting `analysis: \"exact\"` for a frame and\n * then withdrawing it would be exactly the pretence X2 exists to prevent.\n */\n readonly probe: SourceProbe;\n readonly resolution?: BackdropResolutionPolicy;\n}\n\nexport interface DomBackdropSource {\n readonly id: string;\n readonly kind: \"dom\";\n}\n\nexport type BackdropSourceDescriptor = TextureBackdropSource | DomBackdropSource;\n\nexport interface BackdropSourceRecord {\n readonly descriptor: BackdropSourceDescriptor;\n /** Bumped whenever the source's content changes. */\n readonly dirtyEpoch: number;\n /** The epoch a rebuild was last handed out for. Dirty means `dirtyEpoch > builtEpoch`. */\n readonly builtEpoch: number;\n}\n\nexport interface GlassGroupDescriptor {\n readonly id: string;\n readonly backdropSourceId: string;\n /** Scope for matched-geometry ids, so two morph pairs cannot collide. */\n readonly morphNamespace?: string;\n readonly material?: MaterialProfile;\n /** Requested adaptation. Resolved against the group's state, never assumed legal. */\n readonly foreground?: ForegroundAdaptation;\n /**\n * Proximity-union threshold within the group, in CSS px (§Geometry). X1\n * requires it to be at least `samplingPadding`; core checks that, since both\n * numbers live here.\n */\n readonly mergeDistance?: number;\n /**\n * Padding on the group proxy's border box, in CSS px. X1 also requires it to\n * be at least 3σ of the group's blur — core cannot check *that* one, because\n * it carries no blur radius; platform-web owns it, where the material's blur\n * is known.\n */\n readonly samplingPadding?: number;\n /** X6: the author's declared hint. */\n readonly backdrop?: BackdropHint;\n /** X6: the provider form of the same contract. */\n readonly estimator?: BackdropEstimatorProvider;\n}\n\nexport interface GlassGroupRecord {\n readonly descriptor: GlassGroupDescriptor;\n /** Set once the group has been resolved at least once. */\n readonly state?: GlassGroupState;\n /** Per-group governor override; falls back to the scene-wide pressure. */\n readonly governor?: GovernorPressure;\n}\n\nexport interface GlassNodeDescriptor {\n readonly id: string;\n readonly groupId: string;\n readonly shapeFamily: ShapeFamily;\n readonly shape: ShapeChannels;\n readonly zSlot: ZSlot;\n /** Inherits the group's material profile when absent. */\n readonly variant?: MaterialVariant;\n readonly interaction?: InteractionState;\n /** Overrides the group's adaptation for this surface. */\n readonly foreground?: ForegroundAdaptation;\n}\n\nexport interface GlassNodeRecord {\n readonly descriptor: GlassNodeDescriptor;\n /** Measured by platform-web in the read phase; absent until then. */\n readonly bounds?: Rect;\n /** Ancestor clip chain, viewport space. */\n readonly clip?: readonly Rect[];\n}\n\n/** One pyramid rebuild. `groupIds` is why there is one request and not one per group. */\nexport interface BackdropRebuildRequest {\n readonly sourceId: string;\n /** The dirty epoch this rebuild satisfies. */\n readonly epoch: number;\n readonly resolution: BackdropResolutionPolicy;\n /** Every group the rebuild serves. */\n readonly groupIds: readonly string[];\n}\n\nexport interface ResolvedGroup {\n readonly groupId: string;\n readonly state: GlassGroupState;\n readonly hint: ResolvedBackdropHint;\n readonly foreground: ResolvedForegroundAdaptation;\n /** Defaults filled in, so a consumer reads one pair of numbers and not two optionals. */\n readonly sampling: GroupSamplingGeometry;\n}\n\nexport interface ResolvedNode {\n readonly nodeId: string;\n readonly groupId: string;\n readonly material: ResolvedMaterial;\n readonly foreground: ResolvedForegroundAdaptation;\n}\n\nexport interface GroupStateChange {\n readonly groupId: string;\n /** Absent on a group's first resolution. */\n readonly previous?: GlassGroupState;\n readonly next: GlassGroupState;\n readonly change: StateChange;\n}\n\nexport interface SceneResolution {\n readonly groups: readonly ResolvedGroup[];\n readonly nodes: readonly ResolvedNode[];\n /** Only the groups whose state moved, plus every group's first resolution. */\n readonly changes: readonly GroupStateChange[];\n /**\n * One policy for the whole root, carried here so a renderer has everything a\n * frame decided in one object rather than two.\n */\n readonly accessibility: ResolvedAccessibilityPolicy;\n}\n\n/** One overlapping pair of surfaces inside one plane (X1). */\nexport interface PlaneOverlap {\n readonly plane: GlassPlane;\n readonly nodeIds: readonly [string, string];\n}\n\n/** Two groups whose padded backdrop proxies would overlap in one plane (X1). */\nexport interface ProxyOverlap {\n readonly plane: GlassPlane;\n readonly groupIds: readonly [string, string];\n}\n\nexport interface GlassSceneOptions {\n readonly platform: PlatformProbe;\n readonly accessibility?: SystemAccessibilityPreferences;\n readonly accessibilityOverrides?: AccessibilityOverrides;\n readonly diagnostics?: DiagnosticsChannel;\n /**\n * Dev-only checks — same-plane overlap, variant mixing — run only here.\n * Default true: they are cheap at v1's surface counts, and what they catch is\n * invisible otherwise.\n */\n readonly devMode?: boolean;\n}\n\nexport interface GlassScene {\n readonly diagnostics: DiagnosticsChannel;\n\n /**\n * The phase of the frame in flight, or `undefined` outside one. The scheduler\n * sets it; the scene uses it to gate phase-scoped operations. Outside a frame\n * the scene has no opinion — a host may register and measure whenever it likes.\n */\n readonly framePhase: FramePhase | undefined;\n setFramePhase(phase: FramePhase | undefined): void;\n\n registerBackdropSource(descriptor: BackdropSourceDescriptor): void;\n /** Only the resolution policy is patchable: `kind` is identity, the probe has its own setter. */\n updateBackdropSource(id: string, patch: { readonly resolution: BackdropResolutionPolicy }): void;\n removeBackdropSource(id: string): void;\n backdropSource(id: string): BackdropSourceRecord | undefined;\n\n registerGlassGroup(descriptor: GlassGroupDescriptor): void;\n /** A key present with `undefined` clears that override; an absent key keeps it. */\n updateGlassGroup(id: string, patch: DescriptorPatch<Omit<GlassGroupDescriptor, \"id\">>): void;\n removeGlassGroup(id: string): void;\n glassGroup(id: string): GlassGroupRecord | undefined;\n groupsOfSource(sourceId: string): readonly GlassGroupRecord[];\n\n registerGlassNode(descriptor: GlassNodeDescriptor): void;\n /** A key present with `undefined` clears that override; an absent key keeps it. */\n updateGlassNode(id: string, patch: DescriptorPatch<Omit<GlassNodeDescriptor, \"id\">>): void;\n removeGlassNode(id: string): void;\n glassNode(id: string): GlassNodeRecord | undefined;\n nodesOfGroup(groupId: string): readonly GlassNodeRecord[];\n\n /** Measured viewport geometry, from the read phase. */\n setNodeBounds(id: string, bounds: Rect, clip?: readonly Rect[]): void;\n\n setPlatformProbe(probe: PlatformProbe): void;\n setSourceProbe(sourceId: string, probe: SourceProbe): void;\n /** Scene-wide by default; per group when `groupId` is given. */\n setGovernorPressure(pressure: GovernorPressure, groupId?: string): void;\n setSystemAccessibility(preferences: SystemAccessibilityPreferences): void;\n setAccessibilityOverrides(overrides: AccessibilityOverrides): void;\n accessibilityPolicy(): ResolvedAccessibilityPolicy;\n\n markBackdropSourceDirty(id: string): void;\n /** Peek without consuming. */\n dirtyBackdropSources(): readonly BackdropSourceRecord[];\n /**\n * Hand out the frame's rebuilds. The frame id *is* the scope: a second call\n * with the same id returns nothing, which is the §Core model invariant.\n */\n consumeDirtyBackdropSources(frameId: number): readonly BackdropRebuildRequest[];\n /**\n * Give back what `frameId` took, because the frame did not finish.\n *\n * Consuming commits `builtEpoch` at hand-out rather than at completion — core\n * has no view of the wire and cannot wait for one. That is right while the\n * frame runs to its end, and a lie the moment it does not: a claim spent on a\n * frame that threw leaves the source sitting clean at an epoch whose pixels\n * were never imported, and nothing ever marks it dirty again. Restoring the\n * pre-consume epochs makes the commit provisional for exactly as long as the\n * frame is.\n *\n * Returns the source ids restored. Idempotent, and a no-op for any frame id\n * other than the one that consumed.\n */\n rollbackDirtyBackdropSources(frameId: number): readonly string[];\n\n resolve(): SceneResolution;\n checkSamePlaneOverlap(): readonly PlaneOverlap[];\n /**\n * The cross-group half of X1's proxy geometry. `mergeDistance` only unions\n * members *within* a group, so two neighbouring groups can still put two\n * padded proxies over the same pixels — which S1 measured double-filtering.\n */\n checkGroupProxyOverlap(): readonly ProxyOverlap[];\n}\n\n/**\n * A descriptor patch. Unlike `Partial`, a key present with `undefined` is\n * meaningful: it *clears* the override and restores the inherited default.\n * Without that, a declarative binding could never take a prop back — React\n * re-rendering `<GlassGroup backdrop={undefined}>` would have no way to say\n * \"this group no longer declares a hint\" short of tearing the entry down.\n */\nexport type DescriptorPatch<D> = { readonly [K in keyof D]?: D[K] | undefined };\n\n/**\n * Apply a patch, deleting the keys it explicitly cleared. `id` is identity and\n * therefore not patchable, which is why the patch is typed over `Omit<D, \"id\">`\n * while the result is a whole descriptor.\n */\nfunction applyPatch<D extends object>(base: D, patch: DescriptorPatch<Omit<D, \"id\">>): D {\n const next = { ...base } as Record<string, unknown>;\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined) delete next[key];\n else next[key] = value;\n }\n return next as D;\n}\n\nconst unknown = (kind: string, id: string): GlassSceneError =>\n new GlassSceneError(\"unknown-id\", `Unknown ${kind} \"${id}\".`);\n\nconst duplicate = (kind: string, id: string): GlassSceneError =>\n new GlassSceneError(\"duplicate-id\", `Duplicate ${kind} id \"${id}\" — ids must be unique.`);\n\n/** A texture source with a pending pyramid rebuild. dom sources never qualify. */\ntype RebuildableSource = BackdropSourceRecord & { readonly descriptor: TextureBackdropSource };\n\nexport function createGlassScene(options: GlassSceneOptions): GlassScene {\n const diagnostics = options.diagnostics ?? createDiagnosticsChannel();\n const devMode = options.devMode ?? true;\n\n const sources = new Map<string, BackdropSourceRecord>();\n const groups = new Map<string, GlassGroupRecord>();\n const nodes = new Map<string, GlassNodeRecord>();\n\n let platform = options.platform;\n let governor: GovernorPressure = \"none\";\n /**\n * Until a host reports otherwise, nothing is detected and every query is\n * answerable — the nominal policy. `reducedTransparencySupported` defaults to\n * true on purpose: the undetectable-preference warning is about a platform\n * fact a host *reported*, not about a host that has not spoken yet. The field\n * is required on `SystemAccessibilityPreferences`, so platform-web cannot\n * report preferences without stating it.\n */\n let system: SystemAccessibilityPreferences = options.accessibility ?? {\n reducedTransparency: false,\n reducedMotion: false,\n increasedContrast: false,\n forcedColors: false,\n reducedTransparencySupported: true,\n };\n let overrides: AccessibilityOverrides = options.accessibilityOverrides ?? {};\n let consumedFrameId: number | undefined;\n /**\n * What `consumedFrameId`'s hand-out committed, and what it committed *over* —\n * the ledger `rollbackDirtyBackdropSources` unwinds. One frame's worth, because\n * a rollback only ever concerns the frame that is failing right now.\n */\n let consumedEpochs: readonly { readonly id: string; readonly builtEpoch: number }[] = [];\n let framePhase: FramePhase | undefined;\n\n /**\n * Descriptors are frozen from the `update` phase onward.\n *\n * `update` is where reads become resolved state — the scheduler resolves the\n * whole scene at the top of it — so any descriptor change after that leaves\n * the frame's resolution describing a scene that no longer exists, and write\n * and render act on the difference. That covers patches, not only\n * registration: a node's `variant` feeds its resolved material and its\n * `foreground` its resolved adaptation, so \"only the graph's shape is frozen\"\n * would be a line with nothing behind it. Reconcile in `collect`, which is\n * what that phase is for; outside a frame a host may mutate freely, and that\n * is where a React commit lands.\n */\n const FROZEN_PHASES: readonly FramePhase[] = [\"update\", \"write\", \"render\"];\n\n const guardFrozenScene = (subject: string): void => {\n if (framePhase === undefined || !FROZEN_PHASES.includes(framePhase)) return;\n diagnostics.report({\n code: \"frame-phase-violation\",\n severity: \"error\",\n subjects: [subject],\n message: `The scene was changed during the \"${framePhase}\" phase, after this frame resolved. Register, remove and patch in the \"collect\" phase or outside a frame — from \"update\" onward the resolution and the scene must agree.`,\n });\n };\n\n const requireSource = (id: string): BackdropSourceRecord => {\n const record = sources.get(id);\n if (record === undefined) throw unknown(\"backdrop source\", id);\n return record;\n };\n\n const requireGroup = (id: string): GlassGroupRecord => {\n const record = groups.get(id);\n if (record === undefined) throw unknown(\"glass group\", id);\n return record;\n };\n\n const requireNode = (id: string): GlassNodeRecord => {\n const record = nodes.get(id);\n if (record === undefined) throw unknown(\"glass node\", id);\n return record;\n };\n\n const groupsOfSource = (sourceId: string): readonly GlassGroupRecord[] =>\n [...groups.values()].filter((group) => group.descriptor.backdropSourceId === sourceId);\n\n const nodesOfGroup = (groupId: string): readonly GlassNodeRecord[] =>\n [...nodes.values()].filter((node) => node.descriptor.groupId === groupId);\n\n /**\n * dom sources are never rebuildable: the browser compositor does their blur,\n * so the GPU builds no pyramid for them at all (§Core model invariant).\n */\n const isRebuildable = (record: BackdropSourceRecord): record is RebuildableSource =>\n record.descriptor.kind === \"texture\" && record.dirtyEpoch > record.builtEpoch;\n\n function capabilityInputs(\n group: GlassGroupRecord,\n hint: HintAvailability,\n ): CapabilityInputs {\n const source = requireSource(group.descriptor.backdropSourceId);\n const pressure = group.governor ?? governor;\n\n return source.descriptor.kind === \"texture\"\n ? {\n configuredSource: \"texture\",\n platform,\n source: source.descriptor.probe,\n governor: pressure,\n hint,\n }\n : { configuredSource: \"dom\", platform, governor: pressure, hint };\n }\n\n /**\n * Fill in the group's sampling geometry and check X1's relationship between\n * the two numbers. Authored values are never coerced — a silently widened\n * merge distance would change which members fuse, which is a visual decision\n * that belongs to the author.\n */\n const paddingOf = (group: GlassGroupRecord): number =>\n group.descriptor.samplingPadding ?? DEFAULT_GROUP_SAMPLING.samplingPadding;\n\n function samplingOf(group: GlassGroupRecord): GroupSamplingGeometry {\n const samplingPadding = paddingOf(group);\n const mergeDistance = group.descriptor.mergeDistance ?? samplingPadding;\n\n if (devMode && mergeDistance < samplingPadding) {\n diagnostics.report({\n code: \"merge-distance-below-padding\",\n severity: \"warning\",\n subjects: [group.descriptor.id],\n message: `Group \"${group.descriptor.id}\" has mergeDistance ${mergeDistance} below samplingPadding ${samplingPadding}, which X1 forbids: two members can then sit close enough for their padded proxies to overlap without having merged, and the backdrop filter applies twice over the overlap — paint-order dependent, and measured drifting up to 17/255. Raise mergeDistance to at least the padding.`,\n });\n }\n\n return { samplingPadding, mergeDistance };\n }\n\n const hintOf = (group: GlassGroupRecord): ResolvedBackdropHint =>\n resolveBackdropHint({\n groupId: group.descriptor.id,\n ...(group.descriptor.backdrop === undefined ? {} : { backdrop: group.descriptor.backdrop }),\n ...(group.descriptor.estimator === undefined\n ? {}\n : { estimator: group.descriptor.estimator }),\n diagnostics,\n });\n\n return {\n diagnostics,\n\n get framePhase() {\n return framePhase;\n },\n\n setFramePhase(phase) {\n framePhase = phase;\n },\n\n registerBackdropSource(descriptor) {\n if (sources.has(descriptor.id)) throw duplicate(\"backdrop source\", descriptor.id);\n guardFrozenScene(descriptor.id);\n sources.set(descriptor.id, { descriptor, dirtyEpoch: 0, builtEpoch: 0 });\n },\n\n updateBackdropSource(id, patch) {\n const record = requireSource(id);\n guardFrozenScene(id);\n if (record.descriptor.kind !== \"texture\") {\n throw new GlassSceneError(\n \"wrong-source-kind\",\n `Backdrop source \"${id}\" is a dom source: the compositor owns its blur, so it has no resolution policy.`,\n );\n }\n sources.set(id, {\n ...record,\n descriptor: { ...record.descriptor, resolution: patch.resolution },\n });\n },\n\n removeBackdropSource(id) {\n requireSource(id);\n guardFrozenScene(id);\n const dependents = groupsOfSource(id);\n if (dependents.length > 0) {\n throw new GlassSceneError(\n \"in-use\",\n `Backdrop source \"${id}\" is in use by ${dependents.map((group) => `\"${group.descriptor.id}\"`).join(\", \")}. Remove those groups first.`,\n );\n }\n sources.delete(id);\n },\n\n backdropSource(id) {\n return sources.get(id);\n },\n\n registerGlassGroup(descriptor) {\n if (groups.has(descriptor.id)) throw duplicate(\"glass group\", descriptor.id);\n requireSource(descriptor.backdropSourceId);\n guardFrozenScene(descriptor.id);\n groups.set(descriptor.id, { descriptor });\n },\n\n updateGlassGroup(id, patch) {\n const record = requireGroup(id);\n const descriptor = applyPatch(record.descriptor, patch);\n requireSource(descriptor.backdropSourceId);\n guardFrozenScene(id);\n groups.set(id, { ...record, descriptor });\n },\n\n removeGlassGroup(id) {\n requireGroup(id);\n guardFrozenScene(id);\n const members = nodesOfGroup(id);\n if (members.length > 0) {\n throw new GlassSceneError(\n \"in-use\",\n `Glass group \"${id}\" still holds ${members.map((node) => `\"${node.descriptor.id}\"`).join(\", \")}. Remove those nodes first.`,\n );\n }\n groups.delete(id);\n },\n\n glassGroup(id) {\n return groups.get(id);\n },\n\n groupsOfSource,\n\n registerGlassNode(descriptor) {\n if (nodes.has(descriptor.id)) throw duplicate(\"glass node\", descriptor.id);\n requireGroup(descriptor.groupId);\n guardFrozenScene(descriptor.id);\n nodes.set(descriptor.id, { descriptor });\n },\n\n updateGlassNode(id, patch) {\n const record = requireNode(id);\n const descriptor = applyPatch(record.descriptor, patch);\n requireGroup(descriptor.groupId);\n guardFrozenScene(id);\n nodes.set(id, { ...record, descriptor });\n },\n\n removeGlassNode(id) {\n requireNode(id);\n guardFrozenScene(id);\n nodes.delete(id);\n },\n\n glassNode(id) {\n return nodes.get(id);\n },\n\n nodesOfGroup,\n\n setNodeBounds(id, bounds, clip) {\n const record = requireNode(id);\n // Measuring in any other phase is the interleaved read/write that costs a\n // forced synchronous layout — the bug the batched read phase exists to\n // prevent. The value is still accepted: refusing it would leave the frame\n // drawing stale geometry, which is worse than a warned-about one.\n if (framePhase !== undefined && framePhase !== \"read\") {\n diagnostics.report({\n code: \"frame-phase-violation\",\n severity: \"warning\",\n subjects: [id],\n message: `Bounds for \"${id}\" were set during the \"${framePhase}\" phase. Batch every layout read into the \"read\" phase so the steady state performs none.`,\n });\n }\n nodes.set(id, { ...record, bounds, ...(clip === undefined ? {} : { clip }) });\n },\n\n setPlatformProbe(probe) {\n platform = probe;\n },\n\n setSourceProbe(sourceId, probe) {\n const record = requireSource(sourceId);\n if (record.descriptor.kind !== \"texture\") {\n throw new GlassSceneError(\n \"wrong-source-kind\",\n `Backdrop source \"${sourceId}\" is a dom source; only texture sources carry a source probe.`,\n );\n }\n sources.set(sourceId, { ...record, descriptor: { ...record.descriptor, probe } });\n },\n\n setGovernorPressure(pressure, groupId) {\n if (groupId === undefined) {\n governor = pressure;\n return;\n }\n const record = requireGroup(groupId);\n groups.set(groupId, { ...record, governor: pressure });\n },\n\n setSystemAccessibility(preferences) {\n system = preferences;\n },\n\n setAccessibilityOverrides(next) {\n overrides = next;\n },\n\n accessibilityPolicy() {\n return resolveAccessibilityPolicy(system, overrides, diagnostics);\n },\n\n markBackdropSourceDirty(id) {\n const record = requireSource(id);\n sources.set(id, { ...record, dirtyEpoch: record.dirtyEpoch + 1 });\n },\n\n dirtyBackdropSources() {\n return [...sources.values()].filter(isRebuildable);\n },\n\n consumeDirtyBackdropSources(frameId) {\n // The whole invariant in one guard: a frame gets one pass over the dirty\n // set, so no source is rebuilt twice however often a renderer asks.\n if (consumedFrameId === frameId) return [];\n consumedFrameId = frameId;\n\n const requests: BackdropRebuildRequest[] = [];\n const built: RebuildableSource[] = [];\n\n for (const record of sources.values()) {\n if (!isRebuildable(record)) continue;\n\n const consumers = groupsOfSource(record.descriptor.id).map((group) => group.descriptor.id);\n // Nothing samples it, so nothing needs it rebuilt. It stays dirty for\n // whenever a group does arrive.\n if (consumers.length === 0) continue;\n\n requests.push({\n sourceId: record.descriptor.id,\n epoch: record.dirtyEpoch,\n resolution: record.descriptor.resolution ?? DEFAULT_BACKDROP_RESOLUTION,\n groupIds: consumers,\n });\n built.push(record);\n }\n\n consumedEpochs = built.map((record) => ({\n id: record.descriptor.id,\n builtEpoch: record.builtEpoch,\n }));\n for (const record of built) {\n sources.set(record.descriptor.id, { ...record, builtEpoch: record.dirtyEpoch });\n }\n return requests;\n },\n\n rollbackDirtyBackdropSources(frameId) {\n if (consumedFrameId !== frameId) return [];\n const restored: string[] = [];\n for (const { id, builtEpoch } of consumedEpochs) {\n const record = sources.get(id);\n // Gone since the hand-out. Nothing to restore, and nothing to say about\n // it: a removed source has no pyramid anyone is waiting for.\n if (record === undefined) continue;\n // `dirtyEpoch` is left exactly as it stands. Anything that marked the\n // source dirty after the hand-out is a real change this frame's failed\n // claim has no business erasing, and restoring the older `builtEpoch`\n // under it re-opens the gap either way.\n sources.set(id, { ...record, builtEpoch });\n restored.push(id);\n }\n consumedEpochs = [];\n return restored;\n },\n\n resolve() {\n const resolvedGroups: ResolvedGroup[] = [];\n const resolvedNodes: ResolvedNode[] = [];\n const changes: GroupStateChange[] = [];\n const settled: GlassGroupRecord[] = [];\n\n for (const group of groups.values()) {\n const groupId = group.descriptor.id;\n const hint = hintOf(group);\n const state = resolveGlassGroupState(capabilityInputs(group, hint.availability));\n\n const requested = group.descriptor.foreground ?? defaultForegroundAdaptation(state);\n const foreground = resolveForegroundAdaptation(requested, state, { subject: groupId, diagnostics });\n\n const previous = group.state;\n const change = classifyStateChange(previous, state);\n if (change.kind !== \"unchanged\") {\n changes.push({\n groupId,\n ...(previous === undefined ? {} : { previous }),\n next: state,\n change,\n });\n }\n settled.push({ ...group, state });\n resolvedGroups.push({ groupId, state, hint, foreground, sampling: samplingOf(group) });\n\n const profile: MaterialProfile = group.descriptor.material ?? { variant: \"regular\" };\n const members = nodesOfGroup(groupId);\n\n for (const node of members) {\n const nodeId = node.descriptor.id;\n const material = resolveMaterial({\n variant: node.descriptor.variant ?? profile.variant,\n ...(profile.dimming === undefined ? {} : { dimming: profile.dimming }),\n nodeId,\n diagnostics,\n });\n resolvedNodes.push({\n nodeId,\n groupId,\n material,\n foreground: resolveForegroundAdaptation(node.descriptor.foreground ?? requested, state, {\n subject: nodeId,\n diagnostics,\n }),\n });\n }\n\n if (devMode) {\n checkVariantMixing({\n groupId,\n members: members.map((node) => ({\n nodeId: node.descriptor.id,\n variant: node.descriptor.variant ?? profile.variant,\n })),\n diagnostics,\n });\n }\n }\n\n for (const group of settled) groups.set(group.descriptor.id, group);\n\n return {\n groups: resolvedGroups,\n nodes: resolvedNodes,\n changes,\n accessibility: resolveAccessibilityPolicy(system, overrides, diagnostics),\n };\n },\n\n checkSamePlaneOverlap() {\n if (!devMode) return [];\n\n const measured = [...nodes.values()].filter(\n (node): node is GlassNodeRecord & { readonly bounds: Rect } => node.bounds !== undefined,\n );\n\n const overlaps: PlaneOverlap[] = [];\n // Pairwise: v1's benchmark scene is eight surfaces, so a sweep line would\n // buy nothing but code. Revisit if a scene ever holds dozens.\n for (let i = 0; i < measured.length; i += 1) {\n for (let j = i + 1; j < measured.length; j += 1) {\n const a = measured[i];\n const b = measured[j];\n if (a === undefined || b === undefined) continue;\n\n const plane = a.descriptor.zSlot.plane;\n if (plane !== b.descriptor.zSlot.plane) continue;\n if (!rectsOverlap(a.bounds, b.bounds)) continue;\n\n const nodeIds: readonly [string, string] = [a.descriptor.id, b.descriptor.id];\n overlaps.push({ plane, nodeIds });\n diagnostics.report({\n code: \"same-plane-overlap\",\n severity: \"error\",\n subjects: [...nodeIds],\n message: `Glass surfaces \"${nodeIds[0]}\" and \"${nodeIds[1]}\" overlap inside the \"${plane}\" plane (X1). The paint sandwich cannot put one surface's body above the other's DOM label — put the upper one on the overlay plane instead.`,\n });\n }\n }\n return overlaps;\n },\n\n checkGroupProxyOverlap() {\n if (!devMode) return [];\n\n // One padded box per (group, plane): the region that group's proxy would\n // cover. A group with nothing measured yet contributes none.\n const boxes: { readonly groupId: string; readonly plane: GlassPlane; readonly box: Rect }[] =\n [];\n\n for (const group of groups.values()) {\n const groupId = group.descriptor.id;\n const padding = paddingOf(group);\n const byPlane = new Map<GlassPlane, Rect>();\n\n for (const node of nodesOfGroup(groupId)) {\n const { bounds } = node;\n if (bounds === undefined) continue;\n const plane = node.descriptor.zSlot.plane;\n const grown = byPlane.get(plane);\n byPlane.set(plane, grown === undefined ? bounds : unionRect(grown, bounds));\n }\n\n for (const [plane, union] of byPlane) {\n boxes.push({ groupId, plane, box: inflateRect(union, padding) });\n }\n }\n\n const overlaps: ProxyOverlap[] = [];\n for (let i = 0; i < boxes.length; i += 1) {\n for (let j = i + 1; j < boxes.length; j += 1) {\n const a = boxes[i];\n const b = boxes[j];\n if (a === undefined || b === undefined) continue;\n if (a.plane !== b.plane || a.groupId === b.groupId) continue;\n if (!rectsOverlap(a.box, b.box)) continue;\n\n const groupIds: readonly [string, string] = [a.groupId, b.groupId];\n overlaps.push({ plane: a.plane, groupIds });\n diagnostics.report({\n code: \"group-proxy-overlap\",\n severity: \"warning\",\n subjects: [...groupIds],\n message: `Groups \"${groupIds[0]}\" and \"${groupIds[1]}\" sit close enough in the \"${a.plane}\" plane that their padded backdrop proxies overlap, and X1 says the filter then applies twice over that region — paint-order dependent, measured drifting up to 17/255. mergeDistance cannot help: it only unions members inside one group. Either put these surfaces in one group so they share a proxy, or separate them by more than the sum of their samplingPadding.`,\n });\n }\n }\n return overlaps;\n },\n };\n}\n","/**\n * The frame-phase contract, and a reference implementation of it.\n *\n * Core is **passive**. There is no timer, no `requestAnimationFrame`, and no\n * clock read anywhere here — a host calls `runFrame` and supplies the frame's\n * time as a number. platform-web owns the rAF loop and drives this; the same\n * scheduler runs in a test with hand-written frame ids and no browser at all.\n *\n * The pipeline is fixed:\n *\n * ```\n * collect what changed since the last frame is marked dirty\n * read every layout measurement, batched, so the steady state performs none\n * update the scene resolves: capability state, policies, dev-mode checks\n * write GPU resources are brought up to date — where rebuilds are handed out\n * render drawing, with the graph frozen\n * ```\n *\n * `update` resolves the scene *before* the first update hook runs, and that\n * ordering is the contract rather than an implementation detail: every phase from\n * `update` onward reads a resolution describing the graph as it stood at the top\n * of that phase. So the graph is structurally frozen from `update` on — the scene\n * reports a register or a remove there as a `frame-phase-violation`, because a\n * hook that restructures the graph leaves the frame's resolution describing a\n * graph that no longer exists. Structural reconciliation belongs in `collect`;\n * `update` is where reads become resolved state.\n *\n * Phase discipline is enforced, not documented. Consuming the dirty set outside\n * `write`, measuring outside `read`, and restructuring the graph once it has\n * resolved each report a `frame-phase-violation`. None of them throws: a violated\n * frame still draws, and a diagnostic that costs a frame is one a host will\n * silence rather than fix.\n */\n\nimport { FRAME_PHASES, type FrameInfo, type FramePhase } from \"./frame\";\nimport type {\n BackdropRebuildRequest,\n GlassScene,\n PlaneOverlap,\n ProxyOverlap,\n SceneResolution,\n} from \"./scene\";\n\n/** What a hook is handed. Valid for the phase it was passed to, and no longer. */\nexport interface FrameContext {\n readonly frame: FrameInfo;\n readonly phase: FramePhase;\n readonly scene: GlassScene;\n /** The frame's resolution. Absent before the update phase has produced it. */\n readonly resolution?: SceneResolution;\n /**\n * The backdrop sources needing a pyramid rebuild this frame. Legal in the\n * `write` phase, and at most once per frame however many participants ask —\n * the §Core model invariant, enforced rather than asserted.\n */\n consumeDirtyBackdropSources(): readonly BackdropRebuildRequest[];\n}\n\n/**\n * A hook per phase; every one optional. platform-web registers one participant\n * for the DOM host layer and the renderer registers another, so neither has to\n * know the other exists.\n */\nexport interface FrameParticipant {\n readonly id: string;\n readonly collect?: (context: FrameContext) => void;\n readonly read?: (context: FrameContext) => void;\n readonly update?: (context: FrameContext) => void;\n readonly write?: (context: FrameContext) => void;\n readonly render?: (context: FrameContext) => void;\n}\n\nexport interface FrameReport {\n readonly frame: FrameInfo;\n readonly resolution: SceneResolution;\n /** Same-plane surface overlaps found after the read phase, in dev mode. */\n readonly overlaps: readonly PlaneOverlap[];\n /** Groups whose padded proxies would cover the same pixels — X1's other half. */\n readonly proxyOverlaps: readonly ProxyOverlap[];\n /**\n * The rebuilds a write participant actually claimed — nothing more. The\n * scheduler never consumes on the frame's own behalf, because consuming\n * advances the source's `builtEpoch`: a rebuild taken so the report could be\n * \"complete\" would leave the source looking clean with no renderer having built\n * anything, and the pyramid would never be rebuilt. A frame with nobody to do\n * the work — no renderer registered yet, or one sitting out a device-loss\n * recovery — must therefore hand out nothing at all.\n */\n readonly rebuilds: readonly BackdropRebuildRequest[];\n /**\n * The source ids still dirty when the frame ended: whatever no participant\n * claimed, plus sources no group samples yet. Read with the non-consuming peek,\n * so a frame is never charged a rebuild for being reported on. A rebuild\n * survives here until a renderer takes it, which is precisely what lets\n * device-loss recovery pick the work back up instead of losing it.\n */\n readonly pendingSources: readonly string[];\n}\n\nexport interface FrameScheduler {\n /** Registering an existing id replaces that participant. */\n addParticipant(participant: FrameParticipant): void;\n removeParticipant(id: string): void;\n readonly participants: readonly FrameParticipant[];\n runFrame(frame: FrameInfo): FrameReport;\n}\n\nexport interface FrameSchedulerOptions {\n readonly scene: GlassScene;\n}\n\nexport function createFrameScheduler(options: FrameSchedulerOptions): FrameScheduler {\n const { scene } = options;\n const participants = new Map<string, FrameParticipant>();\n\n return {\n addParticipant(participant) {\n participants.set(participant.id, participant);\n },\n\n removeParticipant(id) {\n participants.delete(id);\n },\n\n get participants() {\n return [...participants.values()];\n },\n\n runFrame(frame) {\n let resolution: SceneResolution | undefined;\n let overlaps: readonly PlaneOverlap[] = [];\n let proxyOverlaps: readonly ProxyOverlap[] = [];\n const rebuilds: BackdropRebuildRequest[] = [];\n\n const contextFor = (phase: FramePhase): FrameContext => ({\n frame,\n phase,\n scene,\n ...(resolution === undefined ? {} : { resolution }),\n consumeDirtyBackdropSources: () => {\n if (phase !== \"write\") {\n scene.diagnostics.report({\n code: \"frame-phase-violation\",\n severity: \"error\",\n subjects: [phase],\n message: `The dirty backdrop set was consumed during the \"${phase}\" phase. Pyramid rebuilds belong to the \"write\" phase, after the scene has resolved and before anything draws.`,\n });\n return [];\n }\n const handed = scene.consumeDirtyBackdropSources(frame.id);\n rebuilds.push(...handed);\n return handed;\n },\n });\n\n try {\n for (const phase of FRAME_PHASES) {\n scene.setFramePhase(phase);\n\n // Resolving before the first update hook is what freezes the graph for\n // the rest of the frame: everything after this reads a resolution of\n // the graph as it stands right here.\n if (phase === \"update\") resolution = scene.resolve();\n\n for (const participant of [...participants.values()]) {\n participant[phase]?.(contextFor(phase));\n }\n\n // Bounds are freshest here, and both checks must finish before the\n // renderer acts on a layout the sandwich cannot express.\n if (phase === \"read\") {\n overlaps = scene.checkSamePlaneOverlap();\n proxyOverlaps = scene.checkGroupProxyOverlap();\n }\n }\n } catch (error) {\n // The frame is over and nothing downstream of the throw ran, so whatever\n // rebuilds it claimed were spent on nothing. Consuming commits\n // `builtEpoch` at hand-out, so leaving them spent would leave those\n // sources looking clean at an epoch no renderer ever built — a one-shot\n // dirty mark destroyed by an exception somewhere else entirely. Giving\n // them back costs the frame nothing it still had.\n scene.rollbackDirtyBackdropSources(frame.id);\n throw error;\n } finally {\n // A hook that throws still ends the frame. Left at the failing phase, the\n // scene would report the host's own error recovery — tearing the failed\n // node down, remeasuring — as phase violations it never committed, and\n // every later frame would inherit the same lie.\n scene.setFramePhase(undefined);\n }\n\n return {\n frame,\n // `update` always runs, so this is always assigned by the time it is read.\n resolution: resolution ?? scene.resolve(),\n overlaps,\n proxyOverlaps,\n rebuilds,\n pendingSources: scene.dirtyBackdropSources().map((source) => source.descriptor.id),\n };\n },\n };\n}\n","/**\n * X2 — the resolved-state model (§Backdrop & analysis contracts).\n *\n * Configuration and resolution are separate: an app *configures* a source, the\n * runtime *resolves* one of an enumerated set of states. Only enumerated states\n * are legal, every demotion names its reason, and `configuredSource` survives\n * demotion so an app can always see what it asked for versus what it got.\n *\n * C1 ships the shape; C4 ships the resolver.\n */\n\nexport type ConfiguredSource = \"texture\" | \"dom\";\nexport type ActiveRenderer = \"webgpu\" | \"css\";\nexport type SamplingBackend = \"gpu-texture\" | \"css-backdrop\" | \"none\";\nexport type RefractionQuality = \"true\" | \"approximate\" | \"none\";\nexport type AnalysisQuality = \"exact\" | \"hint\" | \"none\";\nexport type GroupHealth = \"ok\" | \"demoted\";\n\nexport const DEMOTION_REASONS = [\n \"no-webgpu\",\n \"no-backdrop-filter\",\n \"tainted-source\",\n \"incompatible-texture\",\n \"no-texture-supplied\",\n \"device-lost\",\n \"probe-failed\",\n \"governor\",\n] as const;\n\nexport type DemotionReason = (typeof DEMOTION_REASONS)[number];\n\nexport interface GlassGroupState {\n /** What the app declared — never mutated by the runtime. */\n readonly configuredSource: ConfiguredSource;\n /** What is actually drawing. */\n readonly activeRenderer: ActiveRenderer;\n readonly samplingBackend: SamplingBackend;\n readonly refraction: RefractionQuality;\n readonly analysis: AnalysisQuality;\n readonly health: GroupHealth;\n readonly demotionReason?: DemotionReason;\n}\n\nexport function isHealthy(state: GlassGroupState): boolean {\n return state.health === \"ok\" && state.demotionReason === undefined;\n}\n","/**\n * X7 — the lazy renderer seam.\n *\n * The static import below is type-only, so it is erased at build time; the\n * dynamic import is the only edge from core to the WebGPU renderer. That keeps\n * every byte of WGSL out of core's entry chunk, so a CSS-tier consumer never\n * downloads a shader. `packages/core/test/bundle-shape.test.ts` asserts it on\n * the built artifact rather than trusting this comment.\n */\n\nimport type {\n BackdropProvider,\n CopyProviderOptions,\n GlassRenderer,\n VideoProviderOptions,\n} from \"@vitrea/renderer-webgpu\";\n\nexport type { BackdropProvider, CopyProviderOptions, GlassRenderer, VideoProviderOptions };\n\n/**\n * The renderer's constructors, as the seam's consumers need them.\n *\n * A host that attaches the renderer to real canvases also has to build the\n * backdrop providers that feed it, and both must come through the *same* dynamic\n * import — a second entry edge would emit a second chunk and split the renderer\n * in two. Declared as an interface rather than `typeof import(...)` so the seam\n * states exactly what it promises, and the real module is checked against it.\n */\nexport interface WebGPURendererModule {\n createWebGPURenderer(): GlassRenderer;\n createCopyProvider(options: CopyProviderOptions): BackdropProvider;\n createVideoProvider(options: VideoProviderOptions): BackdropProvider;\n}\n\n/** Resolve the renderer module. Call only after a capability probe says yes. */\nexport async function loadWebGPURendererModule(): Promise<WebGPURendererModule> {\n return import(\"@vitrea/renderer-webgpu\");\n}\n\n/** Resolve the WebGPU renderer. Call only after a capability probe says yes. */\nexport async function loadWebGPURenderer(): Promise<GlassRenderer> {\n const { createWebGPURenderer } = await loadWebGPURendererModule();\n return createWebGPURenderer();\n}\n","/**\n * vitrea — the platform-free heart of the runtime.\n *\n * One of the two published packages (X7). The internal @vitrea/* packages are\n * bundled into this artifact at build time, so this package's published\n * dependency list is empty.\n *\n * Pure and passive: no DOM, no Node built-ins (X4), no timers and no clocks.\n * Every probe result, media-query answer and layout rect arrives as plain data;\n * @vitrea/platform-web owns the browser and drives the frames.\n *\n * The modules, roughly in dependency order:\n *\n * - `state`, `capability` — X2's resolved-state model and the transition table\n * that produces it: what the app configured versus what it actually got.\n * - `diagnostics` — how core reports what it will not silently fix.\n * - `planes`, `frame` — the z-slot vocabulary and the frame-phase vocabulary.\n * - `backdrop-hint` (X6), `foreground`, `material`, `accessibility` — the four\n * policy resolvers.\n * - `scene` — the three registries, their references, and the dirty-epoch\n * bookkeeping behind the one-rebuild-per-dirty-source-per-frame invariant.\n * - `scheduler` — the frame-phase contract plus a reference implementation.\n * - `renderer-seam` — the lazy edge to the WebGPU renderer (X7).\n */\n\nimport { SHAPE_FAMILIES, type ShapeFamily } from \"@vitrea/geometry\";\nimport { INTERACTION_STATES, MOTION_DRIVER_BY_CHANNEL, type InteractionState } from \"@vitrea/motion\";\n\nexport * from \"./accessibility\";\nexport * from \"./backdrop-hint\";\nexport * from \"./capability\";\nexport * from \"./diagnostics\";\nexport * from \"./foreground\";\nexport * from \"./frame\";\nexport * from \"./material\";\nexport * from \"./planes\";\nexport * from \"./scene\";\nexport * from \"./scheduler\";\nexport * from \"./state\";\nexport {\n loadWebGPURenderer,\n loadWebGPURendererModule,\n type BackdropProvider,\n type CopyProviderOptions,\n type GlassRenderer,\n type VideoProviderOptions,\n type WebGPURendererModule,\n} from \"./renderer-seam\";\nexport type { ShapeChannels, ShapeFamily, CornerProfile, Vec2, CornerRadii } from \"@vitrea/geometry\";\nexport type { MotionChannel, MotionDriverKind, InteractionState } from \"@vitrea/motion\";\n\n/**\n * The contract sets core owns, re-exported so a consumer never installs an\n * internal package. Reading these values here is also what makes the internal\n * packages part of core's bundle — the property X7's bundle test checks.\n */\nexport const VITREA_CONTRACTS: {\n readonly shapeFamilies: readonly ShapeFamily[];\n readonly interactionStates: readonly InteractionState[];\n readonly motionDrivers: typeof MOTION_DRIVER_BY_CHANNEL;\n} = {\n shapeFamilies: SHAPE_FAMILIES,\n interactionStates: INTERACTION_STATES,\n motionDrivers: MOTION_DRIVER_BY_CHANNEL,\n};\n\n/** Renderer tiers in v1's ladder. WebGL2 is out of scope; SVG displacement is a reserved seam. */\nexport const RENDERER_TIERS = [\"webgpu\", \"css\"] as const;\n\nexport type RendererTier = (typeof RENDERER_TIERS)[number];\n"]}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@vitreajs/vitrea",
3
+ "version": "0.1.0",
4
+ "description": "Framework-agnostic Liquid Glass material runtime: scene model, capability resolution, material policy, accessibility policy.",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://github.com/SSFSKIM/designer",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/SSFSKIM/designer.git",
10
+ "directory": "packages/core"
11
+ },
12
+ "keywords": [
13
+ "liquid-glass",
14
+ "webgpu",
15
+ "material",
16
+ "glass",
17
+ "ui",
18
+ "backdrop-filter",
19
+ "apple"
20
+ ],
21
+ "type": "module",
22
+ "sideEffects": false,
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ }
28
+ },
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "files": [
32
+ "dist",
33
+ "LICENSE",
34
+ "NOTICE"
35
+ ],
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "26.2.0",
41
+ "@vitrea/geometry": "0.0.0",
42
+ "@vitrea/motion": "0.0.0",
43
+ "@vitrea/renderer-webgpu": "0.0.0",
44
+ "eslint": "10.9.0",
45
+ "tsup": "8.5.1",
46
+ "typescript": "6.0.3",
47
+ "vitest": "4.1.11"
48
+ },
49
+ "scripts": {
50
+ "build": "tsup",
51
+ "lint": "eslint . && tsc --noEmit",
52
+ "test": "vitest run"
53
+ }
54
+ }