@idle-screens/schema 3.6.1 → 3.7.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/steer.ts","../src/validate.ts","../src/shapes.ts","../src/simulate.ts","../src/compile.ts","../src/sequence.ts","../src/advise.ts","../src/luma.ts","../src/cohesion.ts","../src/describe.ts","../src/perceive.ts","../src/examples/aquarium.ts","../src/examples/aurora.ts","../src/examples/comets.ts","../src/examples/constellation.ts","../src/examples/dev-dashboard.ts","../src/examples/facets.ts","../src/examples/haiku.ts","../src/examples/lanterns.ts","../src/examples/matrix-rain.ts","../src/examples/nostalghia-candle.ts","../src/examples/polygons.ts","../src/examples/orrery.ts","../src/examples/pings.ts","../src/examples/procession.ts","../src/examples/rain.ts","../src/examples/relay-board.ts","../src/examples/sakura.ts","../src/examples/snowfall.ts","../src/examples/warp-tunnel.ts","../src/examples/index.ts"],"sourcesContent":["/**\n * Declarative, agent-authorable saver format. A `SaverSpec` describes a saver as DATA\n * (no code), which `compileSaver` turns into a seeded, deterministic, flash-safe\n * SaverPlugin. It models the \"drifting sprite field\" family that covers most classic\n * savers (fish, toasters, DVD, rain, messages): a static background plus one or more\n * layers of entities that move.\n *\n * SAFETY INVARIANT: there is deliberately NO full-field strobe/flash primitive — the\n * background is static and entities are bounded sprites — so a compiled spec cannot\n * produce photosensitive flashing by construction (proven by sampling a compiled spec\n * through @idle-screens/validator).\n */\nexport const SCHEMA_VERSION = 1 as const;\n\nexport interface SaverSpec {\n schemaVersion: 1;\n id: string;\n label: string;\n /** Deterministic seed; falls back to the host's SaverContext.seed. */\n seed?: number;\n background?: BackgroundSpec;\n layers: LayerSpec[];\n motionIntensity?: 'calm' | 'moderate' | 'energetic';\n /**\n * Declared density intent. `sparse` says the emptiness is the point (one\n * mark on a dark ground, long silences): `adviseSpec` withholds\n * `sparse-scene`, and scorers that gate on coverage should read this before\n * calling a faithful scene broken. `dense` withholds `dense-scene` the same\n * way. Either declaration is checked against the measured coverage and a\n * `density-mismatch` advisory fires when the scene contradicts it. Omitted\n * means `normal`. A hint only — it changes no pixel.\n */\n density?: 'sparse' | 'normal' | 'dense';\n /**\n * Frame persistence (0..1, capped at LIMITS.maxGhosting). Instead of fully clearing,\n * each frame the background is painted at reduced alpha so moving entities leave\n * decaying after-images (Mystify smears, long-exposure light). Inherently\n * flash-safe: ghosting can only smooth luminance changes, never sharpen them.\n * `renderFrame(t)` stays deterministic for seeks via a fixed-step warm-up replay.\n */\n ghosting?: number;\n /** Dimensional unit system. 'viewport' (default) = all sizes/speeds/distances are fractions of min(w,h). */\n units?: 'viewport' | 'px';\n /**\n * Resolution at which this spec was designed. Density scaling kicks in above this\n * threshold: entity counts scale by min(w,h) / referenceViewport. Default: 1080.\n * Set to your design resolution so a spec authored at 4K doesn't over-densify.\n */\n referenceViewport?: number;\n}\n\nexport type BackgroundSpec =\n | { type: 'solid'; color: string }\n | { type: 'gradient'; stops: GradientStop[]; band?: BandSpec; drift?: BackgroundDrift };\n\n/** A vertical gradient stop (`at` 0 = top, 1 = bottom). */\nexport interface GradientStop {\n at: number;\n color: string;\n}\n\n/** An optional solid band at the bottom (e.g. an aquarium seafloor). */\nexport interface BandSpec {\n color: string;\n /** Band height — px or a viewport fraction, per the spec's `units`. */\n height: number;\n}\n\n/** Slow oscillation of gradient stop positions — makes the background feel alive. */\nexport interface BackgroundDrift {\n /** Full cycle period in ms. Floor: LIMITS.minDriftPeriod (10 s). */\n period: number;\n /** How far stops shift (fraction of the 0..1 range). Default 0.15, max 0.3. */\n amount?: number;\n}\n\nexport interface LayerSpec {\n count: number;\n sprite: SpriteSpec;\n /** Sprite size range in px (font size for emoji/text; ignored for circle). */\n size?: [number, number];\n motion: MotionSpec;\n /** Wrap around the opposite edge when leaving the viewport. Default true. */\n wrap?: boolean;\n /** Flip the sprite horizontally to face its heading. Default false. */\n flip?: boolean;\n /** Per-entity opacity range, both 0..1. Default [1,1]. */\n alpha?: [number, number];\n /**\n * Compositing for this layer. 'lighter' = additive (glow stacking); 'screen' =\n * gentler additive for pale backgrounds; 'multiply' = darkening (shadows,\n * silhouettes). Default source-over. None of these can strobe.\n */\n blend?: 'lighter' | 'screen' | 'multiply';\n /**\n * Fractional spawn window (0 = left/top, 1 = right/bottom). Constrains where\n * entities are PLACED, not where they may travel. Default full viewport.\n */\n region?: { x?: [number, number]; y?: [number, number] };\n /**\n * Sinusoidal opacity breathing. SAFETY: amp is capped (LIMITS.maxPulseAmp),\n * period has a floor (LIMITS.minPulsePeriod — max 2 Hz), and every entity gets\n * its own seeded phase, so a layer can never strobe in unison. Effective alpha\n * is clamped to 0..1.\n *\n * `wave` derives each entity's phase from its spawn position instead of a seeded\n * draw, turning independent breathing into a traveling wave across the field\n * (ripples, wind through grass). `wavelength` is dimensional (px or viewport\n * units); `angle` is the propagation direction in degrees (0 = rightward,\n * default 0). Still flash-safe: neighbors are out of phase by construction.\n */\n pulse?: { amp: number; period: number; wave?: { wavelength: number; angle?: number } };\n /**\n * Per-entity rotation speed in degrees/sec (positive = clockwise).\n * Each entity gets a seeded starting angle. Composes with any motion type.\n * A scalar applies one speed to every entity; a `[min, max]` range gives each\n * entity a seeded speed within the range (like `speed`/`alpha`) — confetti,\n * tumbling debris, foliage. Existing scalar specs are unaffected (the range\n * form draws one extra seeded value, only when present).\n */\n spin?: number | [number, number];\n /**\n * Sinusoidal size breathing, parallel to `pulse` for opacity. `amp` is a\n * fraction of base size (0.3 = ±30 %). `period` in ms with the same\n * flash-safety floor as pulse. Per-entity seeded phase.\n */\n grow?: { amp: number; period: number };\n /**\n * Addressable name for this layer. Enables `setParam` to use `key.field` paths\n * instead of `layers.N.field` indices. Also makes specs self-documenting.\n */\n key?: string;\n /**\n * Exact fractional position {x, y} for a single entity (0 = left/top, 1 = right/bottom).\n * Only valid when `count` is 1 — or, with a `list` / `table` layout, as the\n * top-left anchor of the whole block. Overrides `region` scatter placement.\n */\n position?: { x: number; y: number };\n /**\n * Inter-entity links. `mode` picks the wiring:\n * - 'nearest' (default): each entity's k nearest neighbors within maxDist.\n * - 'chain': entities connected in order (0-1-2-…) — Mystify polygons, string\n * art. Ignores k/maxDist; `closed` joins the last entity back to the first.\n * - 'random': a fixed golden-ratio-stride wiring (k partners per entity,\n * deterministic, no RNG draws) — breaks the crystalline k-nearest look.\n * `falloff` fades link alpha with distance/maxDist, killing pop-in at the cutoff.\n * Capped at LIMITS.maxLinksK. Layer count must be <= LIMITS.maxLinkLayerCount when set.\n */\n links?: {\n k: number;\n maxDist: number;\n color?: string;\n alpha?: number;\n width?: number;\n mode?: 'nearest' | 'chain' | 'random';\n falloff?: boolean;\n closed?: boolean;\n };\n /**\n * Afterglow trail behind moving entities. Samples past positions analytically\n * (no state, fully deterministic). `length` in ms, `fade` 0..1 (default 1 = full fade).\n */\n trail?: { length: number; fade?: number };\n /**\n * Grid placement instead of random scatter: entities fill cells row-major within\n * `region`. `columns` defaults to an aspect-fit square-ish grid; `jitter` (0..1,\n * scalar or per-axis) offsets each entity within its cell by a seeded fraction of\n * the cell size — `{ y: 1 }` keeps columns crisp while scattering vertically\n * (Matrix rain). Unlocks column effects, LED walls, mosaics, uniform dot fields.\n */\n layout?:\n | { type: 'grid'; columns?: number; jitter?: number | { x?: number; y?: number } }\n /**\n * Data layouts — entities in READING ORDER, no scatter. `list` stacks them\n * in one column `gap` apart (viewport units of min(w,h), default 0.06);\n * `table` fills `columns` row-major with `gap` `{x, y}` (one number = both).\n * Text and emoji sprites take `strings[i]` / `glyphs[i]` in order instead of\n * a seeded pick, and palette `colors[i]` likewise, so N labels or N bars are\n * ONE layer. `position` (with any count) is the block's top-left anchor;\n * without it the block is centred in `region`.\n */\n | { type: 'list'; gap?: number }\n | { type: 'table'; columns: number; gap?: number | { x?: number; y?: number } };\n /**\n * Layer lifecycle for act structure — a pure function of t, no state. Alpha is 0\n * before `enter` (ms), ramps up over `fade` ms (default 1000), holds at 1, then\n * ramps down starting at `exit`. Entities are skipped entirely while at alpha 0.\n */\n life?: { enter?: number; exit?: number; fade?: number };\n /**\n * Sparse events — marks that appear, expand and fade in place, one at a time,\n * with long silences between (the \"one ping\" primitive). Each entity is dark\n * except for a window of `life` ms that recurs every `every` ms at a\n * per-entity offset: `jitter` 1 (default) scatters the offsets (a fixed\n * low-discrepancy sequence — not seeded, so declaring `emit` disturbs no\n * other draw and the same spec times its events identically under every\n * seed), 0 spreads the entities evenly across the period — a metronome, one\n * event at a time as long as `life ≤ every / count`.\n * Inside a window the entity fades in over the first quarter and out over\n * the rest; `grow` scales its size from `grow[0]` to `grow[1]` across the\n * window — expansion rather than travel. A pure function of t. Flash safety:\n * `every` ≥ 1000 ms and `life` ≥ 500 ms, so no entity fires more than once a\n * second and never as a hard cut. Composes with `pulse`, `life`, `trail` and\n * every motion; with `motion.ease` the eased travel restarts on every event.\n */\n emit?: { every: number; life: number; jitter?: number; grow?: [number, number] };\n /**\n * Phase-lock. Replaces the seeded per-entity phases of `pulse`, `grow` and\n * `cycle` with one shared phase (`phase` in turns, 0..1, default 0) and runs\n * those three at `rate` × scene time (default 1). Two layers declaring the\n * same clock breathe in step; different phases give a fixed offset (call and\n * response). `pulse.wave` still adds its position-derived phase on top, so a\n * clocked wave stays a wave. Because a clocked layer moves in unison, its\n * `pulse`/`grow` periods must satisfy `period / rate ≥ 1000 ms` (1 Hz).\n */\n clock?: { phase?: number; rate?: number };\n}\n\n/**\n * Closed-form velocity easing for `drift`, `rise` and `wander`. `settle`\n * starts at the entity's speed and decelerates to rest with time constant\n * `tau` ms — it travels `speed × tau` and stops, a mark flung and coming to\n * rest. `buoyant` starts at rest and approaches the speed over `tau` — a\n * bubble reaching terminal velocity. Position stays an analytic function of\n * t (no integration state). With `emit`, the eased travel restarts from the\n * spawn point on every event. For `wander` only the base velocity eases —\n * the harmonic meander keeps breathing, so a settled wanderer hovers rather\n * than freezes.\n */\nexport interface MotionEase {\n type: 'settle' | 'buoyant';\n tau: number;\n}\n\nexport type SpriteSpec =\n | { kind: 'emoji'; glyphs: string[]; cycle?: CycleSpec }\n | {\n kind: 'text';\n strings: string[];\n color?: string;\n font?: string;\n align?: 'left' | 'center' | 'right';\n baseline?: 'top' | 'middle' | 'bottom';\n maxWidth?: number;\n cycle?: CycleSpec;\n }\n /** `soft` renders a radial falloff (glow orb) instead of a hard disc.\n * `colorWeights` (same length as `colors`) biases the seeded per-entity pick —\n * \"mostly cool tones, occasional ember\" without duplicating entries. */\n | { kind: 'circle'; radius: [number, number]; color: string; soft?: boolean; colors?: string[]; colorWeights?: number[] }\n /** Unfilled circle (bubbles, portals, sonar pings). `width` = stroke width. */\n | { kind: 'ring'; radius: [number, number]; color: string; width?: number; colors?: string[]; colorWeights?: number[] }\n /**\n * A line segment oriented along the entity's instantaneous heading (derived\n * analytically from its motion) with a faded tail — rain that reads as rain,\n * shooting stars, warp stars. `length` is the segment length range; `width` the\n * stroke width.\n */\n | { kind: 'streak'; length: [number, number]; color: string; width?: number; colors?: string[]; colorWeights?: number[] }\n /**\n * Axis-aligned rectangle (rotates with `spin`). `width` is the horizontal size\n * range; `aspect` the height/width ratio range (default [1,1] = squares).\n * `feather` (0..1) softens the edges: that fraction of the half-size fades\n * out toward the border — Rothko's soft-edged block at 0.5–0.8.\n * Mondrian blocks, confetti, city lights.\n */\n | { kind: 'rect'; width: [number, number]; aspect?: [number, number]; color: string; feather?: number; colors?: string[]; colorWeights?: number[] }\n /**\n * A data bar. Entity i draws a bar `length × values[i] / max` long (viewport\n * units of min(w,h)), `thickness` thick, growing from its position toward\n * `direction` (default 'right'). `values` are PAINT — steer\n * `layers.N.sprite.values` and the bars glide; `max` defaults to the largest\n * value. Pair with a `list` layout: a chart is one layer, labels another.\n */\n | {\n kind: 'bar';\n values: number[];\n length: number;\n thickness: number;\n color: string;\n max?: number;\n direction?: 'right' | 'left' | 'up' | 'down';\n colors?: string[];\n colorWeights?: number[];\n }\n /**\n * Regular or custom polygon. `sides` (3..12, default 6) draws a regular\n * n-gon of the seeded `radius` (circumradius), point up; `points` (3..24\n * unit coordinates in −1..1, scaled by the radius) draws any facet — a\n * Picasso shard, a Kandinsky triangle, a Mondrian plane. `soft` feathers\n * the fill from the centre like a soft circle. Rotates with `spin`.\n */\n | { kind: 'polygon'; radius: [number, number]; color: string; sides?: number; points?: Array<[number, number]>; soft?: boolean; colors?: string[]; colorWeights?: number[] }\n /**\n * A freehand mark: a path through `points` (2..24 unit coordinates in\n * −1..1, scaled by the seeded `length`) stroked `width` wide with round\n * joins. `curve: 'smooth'` (default) runs a Catmull-Rom spline through the\n * points, `'linear'` a polyline. `taper` thins the mark to almost nothing at\n * both ends — a brush stroke rather than a line. `orient` turns the path's\n * +x along the entity's heading (like `streak`). Rotates with `spin`. Van\n * Gogh's stroke, Hokusai's contour, O'Keeffe's petal, Basquiat's scrawl.\n */\n | {\n kind: 'stroke';\n length: [number, number];\n points: Array<[number, number]>;\n color: string;\n width?: number;\n curve?: 'smooth' | 'linear';\n taper?: boolean;\n orient?: boolean;\n colors?: string[];\n colorWeights?: number[];\n }\n /**\n * Multi-line text block with deterministic line-breaking. Unlike `text` (one\n * string drawn as a single fillText call), `textBlock` wraps `text` within\n * `maxWidth` using a fixed metrics table so line breaks are identical across\n * platforms (same seed → same frames). All dimensions are viewport-fraction\n * (of `min(w,h)`), not px — addresses the absolute-font-size inconsistency.\n * Use with `count: 1`, `motion: { type: 'static' }`, and `position`.\n */\n | {\n kind: 'textBlock';\n text: string;\n maxWidth: number;\n fontSize: number;\n lineHeight?: number;\n align?: 'left' | 'center' | 'right';\n color?: string;\n reveal?: TextRevealSpec;\n };\n\n/**\n * Animated typing/deleting for `textBlock`. Layout always runs on the FULL\n * text — reveal only masks which glyphs are painted, so lines never reflow\n * and the block's box never changes size. `progress` is a numeric paint\n * param (excluded from the structural signature), so steering it with\n * `dur`/`ease` animates typing client-side in one call; gliding it back to 0\n * deletes. With center/right `align`, the revealing line stays anchored to\n * its alignment as it types (only left-aligned text reads as a classic\n * typewriter).\n */\nexport interface TextRevealSpec {\n /**\n * 0..1 fraction of the text revealed (default 1 = fully shown). Quantized\n * by `mode`. Steerable paint — glide it to animate typing or deleting.\n */\n progress?: number;\n /**\n * Reveal granularity: per-grapheme (default), per-word, per-line, or\n * `glyphFade` — each glyph fades in over a staggered alpha ramp instead of\n * appearing whole (the caption look). Still a pure function of `progress`.\n */\n mode?: 'typewriter' | 'word' | 'line' | 'glyphFade';\n /**\n * Self-typing rate in graphemes/second from scene start (media time). The\n * effective progress is `min(progress, speed·t/total)` — so a steered\n * `progress` can hold or delete even while `speed` is set. 0 = off.\n */\n speed?: number;\n /**\n * Caret at the reveal frontier. `true` for defaults, or configure blink\n * rate (Hz, full cycles/sec, capped at 3 for flash safety) and color.\n * Blink is a square wave of `t` — deterministic like everything else.\n */\n caret?: boolean | { blink?: number; color?: string };\n /**\n * `glyphFade` only: each glyph's fade window as a fraction of progress\n * (0 exclusive to 1, default 0.15). Small = soft typewriter; large = a\n * wave of overlapping fades. Ignored by the other modes.\n */\n fade?: number;\n}\n\n/** Rotate through sprite variants over time. Each entity offsets by its seeded phase. */\nexport interface CycleSpec {\n period: number;\n}\n\nexport type MotionSpec =\n /**\n * Drift at a per-entity speed picked from `speed` (px/sec) along `angle` degrees\n * (0 = right, 90 = down; default 0). `bidirectional` randomly flips horizontal\n * direction per entity (e.g. fish swimming both ways); `bob` adds a small vertical\n * wobble amplitude (px). Covers horizontal fields, diagonals (toasters) and rain\n * (angle 90).\n */\n | { type: 'drift'; speed: [number, number]; angle?: number; bidirectional?: boolean; bob?: number; ease?: MotionEase }\n /** Rise upward (px/sec) with an optional horizontal sway amplitude (px) — bubbles. */\n | { type: 'rise'; speed: [number, number]; sway?: number; ease?: MotionEase }\n /** Bounce diagonally at a per-entity speed, reflecting off the edges (px/sec). */\n | { type: 'bounce'; speed: [number, number] }\n /** Entity stays exactly where placed. No movement. Use with `position` for pinned elements. */\n | { type: 'static' }\n /**\n * Orbit around a center point. Each entity gets a seeded radius from `radius`\n * and a seeded phase. `speed` is angular velocity in degrees/sec. `center` is\n * fractional {x, y} (default {0.5, 0.5} = viewport center) — or\n * `{ layer: key }` to orbit a single-entity parent layer (moons around a\n * wandering planet). Strictly one level deep: the parent may not itself\n * orbit a layer, and must have `count: 1`.\n */\n | { type: 'orbit'; speed: [number, number]; radius: [number, number]; center?: { x: number; y: number } | { layer: string } }\n /**\n * Organic harmonic drift — the analytic flow field. Each entity moves at a base\n * velocity from `speed` plus 3 seeded sine octaves per axis, producing flowing\n * curved paths (Flurry streams, aurora, jellyfish) with zero simulation state.\n * `angle` fixes the base heading in degrees (omit for a seeded heading per\n * entity); `meander` scales the harmonic amplitude (dimensional, default 0.05\n * viewport units); `coherence` (0..1) blends every entity's harmonics toward a\n * shared layer-level set — at 1 the field undulates in unison (fake flocking).\n */\n | { type: 'wander'; speed: [number, number]; angle?: number; meander?: number; coherence?: number; ease?: MotionEase }\n /**\n * Perspective starfield: entities live on a depth axis and stream toward the\n * viewer, projected as `screen = center + offset / z`. Size and alpha scale\n * with 1/z (small and faint at the far plane, large and fast up close), and z\n * wraps — the honest warp tunnel. `speed` is in depth-units/sec\n * (1 = full near-to-far span per second, capped at LIMITS.maxWarpSpeed).\n */\n | { type: 'warp'; speed: [number, number]; center?: { x: number; y: number } }\n /**\n * Choreographed spline motion: entities traverse `points` (fractional {x,y})\n * over `duration` ms. `curve: 'smooth'` (default) uses Catmull-Rom through the\n * points; 'linear' uses straight segments. `closed` (default true) loops the\n * path; open paths ping-pong. Each entity gets a seeded phase offset along the\n * path, and `scatter` (dimensional) adds a seeded per-entity offset so shared\n * paths don't stack. Figure-eights, sweeping arcs, patrol routes.\n */\n | {\n type: 'path';\n points: Array<{ x: number; y: number }>;\n duration: number;\n curve?: 'linear' | 'smooth';\n closed?: boolean;\n scatter?: number;\n };\n\n/** A validation problem, pointing at a JSON path within the spec. */\nexport interface SpecError {\n path: string;\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: SpecError[];\n /** Non-blocking warnings about unknown/misplaced properties or likely authoring mistakes. */\n warnings?: SpecWarning[];\n}\n\n/** An advisory warning (non-blocking). Returned by `adviseSpec`. */\nexport interface SpecWarning {\n path: string;\n code: string;\n message: string;\n}\n\n/** Perf/safety caps enforced by `validateSpec`. */\nexport const LIMITS = {\n maxPerLayer: 400,\n maxTotal: 800,\n maxLayers: 36,\n maxSpeed: 4000, // px/sec — bounds motion so nothing teleports\n maxPulseAmp: 0.5, // opacity breathing amplitude cap\n minPulsePeriod: 500, // ms — caps pulse at 2 Hz (WCAG flash threshold is 3 Hz)\n maxSpin: 360, // degrees/sec — one full revolution per second\n maxGrowAmp: 0.8, // size breathing amplitude cap (fraction of base size)\n maxOrbitSpeed: 180, // degrees/sec — half a revolution per second\n maxLinksK: 8,\n maxLinkLayerCount: 200,\n minCyclePeriod: 500, // ms — same flash-safety floor as pulse\n referenceViewport: 1080, // for validating viewport-unit dimensional caps\n maxTrailLength: 5000, // ms — cap trail duration\n maxTrailSamples: 24, // dots per trail\n minDriftPeriod: 10000, // ms — background drift floor (10 s)\n maxDriftAmount: 0.3, // fraction of gradient stop shift\n maxGhosting: 0.95, // frame persistence cap — bounds the seek warm-up replay\n maxGhostReplayFrames: 120, // fixed-step frames replayed on a non-contiguous seek\n maxMeander: 500, // px — wander harmonic amplitude cap (viewport cap: /referenceViewport)\n maxWarpSpeed: 1.5, // depth-units/sec — full near-to-far span in ~0.7 s at max\n minPathPoints: 2,\n maxPathPoints: 24,\n minPathDuration: 2000, // ms — a path lap can't be faster than this\n maxGridColumns: 100,\n maxTextBlockLength: 2000,\n minTextBlockFontSize: 0.01,\n maxTextBlockFontSize: 0.2,\n maxTextBlockMaxWidth: 1.0,\n maxRevealSpeed: 120, // graphemes/sec — faster than any readable typing\n maxCaretBlinkHz: 3, // full blink cycles/sec — WCAG 2.3.1 flash-safety cap\n maxSegments: 24,\n minSegmentDuration: 1000, // ms — flash-safety floor: segment cuts are luminance transitions\n maxTransitionDur: 5000,\n minTransitionDur: 200,\n minEmitEvery: 1000, // ms — at most one event per second per entity (flash safety)\n maxEmitEvery: 600000, // ms — ten minutes; longer silences than that are `life.enter`\n minEmitLife: 500, // ms — an event is a smooth envelope, never a cut\n maxEmitGrow: 8, // × base size across an event window\n minClockedPeriod: 1000, // ms — a `clock`ed layer breathes in unison, so 1 Hz not 2\n minClockRate: 0.1,\n maxClockRate: 4,\n defaultListGap: 0.06, // viewport units between list/table cells (40 px in px specs)\n defaultListGapPx: 40,\n minPolygonSides: 3,\n maxPolygonSides: 12,\n maxShapePoints: 24, // polygon.points / stroke.points\n minEaseTau: 100, // ms\n maxEaseTau: 120000, // ms\n} as const;\n\n// ---------------------------------------------------------------------------\n// Sequence envelope — multi-segment timeline over unmodified SaverSpecs\n// ---------------------------------------------------------------------------\n\nexport type SequenceTransition =\n | { type: 'cut' }\n | { type: 'morph'; dur: number };\n\nexport interface SequenceSegment {\n key: string;\n scene: SaverSpec;\n /** Segment duration in ms. Only the final segment may omit this (holds until input). */\n duration?: number;\n /** How the segment advances: 'auto' (timer), 'input' (external event), 'either'. */\n advance?: 'auto' | 'input' | 'either';\n transition?: SequenceTransition;\n}\n\nexport interface IdleSequence {\n format: 'idle-sequence';\n schemaVersion: 1;\n id: string;\n label: string;\n seed?: number;\n loop: boolean;\n segments: SequenceSegment[];\n}\n","/**\n * Pure helpers for LIVE steering of compiled specs (setParam / applyTrack).\n * A track's deltas address spec fields by dot-path (\"layers.0.count\",\n * \"background.stops.1.color\") or layer key (\"fireflies.count\"). Steering\n * changes existing values only — unknown paths are ignored (the server\n * validates and rejects them; the runtime stays lenient).\n */\nimport type { SaverSpec } from './types';\n\ninterface PathTarget {\n parent: Record<string, unknown> | unknown[];\n key: string | number;\n}\n\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\nconst STEERABLE_ROOT_KEYS = new Set(['ghosting', 'referenceViewport']);\n\n/** Resolve a dot-path (key-aware) to its parent + final key; null if absent. */\nexport function resolveSpecPath(spec: unknown, path: string): PathTarget | null {\n if (!spec || typeof spec !== 'object' || !path) return null;\n const parts = path.split('.');\n if (parts.some((p) => UNSAFE_KEYS.has(p))) return null;\n const s = spec as { layers?: Array<Record<string, unknown>> };\n if (parts[0] !== 'layers' && parts[0] !== 'background' && !STEERABLE_ROOT_KEYS.has(parts[0]!) && Array.isArray(s.layers)) {\n const idx = s.layers.findIndex((l) => l && l.key === parts[0]);\n if (idx === -1) return null;\n parts.splice(0, 1, 'layers', String(idx));\n }\n let node: unknown = spec;\n for (let i = 0; i < parts.length - 1; i++) {\n if (node === null || typeof node !== 'object') return null;\n node = (node as Record<string, unknown>)[parts[i]!];\n }\n if (node === null || typeof node !== 'object') return null;\n const last = parts[parts.length - 1]!;\n const key: string | number = Array.isArray(node) ? Number(last) : last;\n const exists = Array.isArray(node)\n ? Number.isInteger(key as number) && (key as number) >= 0 && (key as number) < node.length\n : last in (node as Record<string, unknown>);\n return exists ? { parent: node as PathTarget['parent'], key } : null;\n}\n\n/** A steering delta as carried on a channel control-track. */\nexport interface SteerDelta {\n t: number;\n path: string;\n value: unknown;\n ease?: string;\n dur?: number;\n}\n\n/** Apply deltas to a deep copy of the spec (last-wins, target values). */\nexport function applyDeltasToSpec(spec: SaverSpec, deltas: SteerDelta[]): SaverSpec {\n const copy = JSON.parse(JSON.stringify(spec)) as SaverSpec;\n for (const d of deltas) {\n const loc = resolveSpecPath(copy, d.path);\n if (loc) (loc.parent as Record<string | number, unknown>)[loc.key] = d.value;\n }\n return copy;\n}\n\nconst HEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\nfunction lerpHex(a: string, b: string, k: number): string {\n const ca = hexToRgb(a);\n const cb = hexToRgb(b);\n const mix = ca.map((v, i) => Math.round(v + (cb[i]! - v) * k));\n return `#${mix.map((v) => v.toString(16).padStart(2, '0')).join('')}`;\n}\n\n/**\n * Interpolate between two structurally-similar specs at progress k (0..1).\n * Numbers lerp, hex colours lerp per channel, everything else steps to the\n * target immediately (k > 0). Layer counts round to integers.\n */\nexport function lerpSpec(from: SaverSpec, to: SaverSpec, k: number): SaverSpec {\n const kk = Math.max(0, Math.min(1, k));\n const walk = (a: unknown, b: unknown, key?: string | number): unknown => {\n if (typeof a === 'number' && typeof b === 'number') {\n const v = a + (b - a) * kk;\n return key === 'count' ? Math.max(1, Math.round(v)) : v;\n }\n if (typeof a === 'string' && typeof b === 'string' && HEX.test(a) && HEX.test(b)) {\n return lerpHex(a, b, kk);\n }\n if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {\n return b.map((bv, i) => walk(a[i], bv, i));\n }\n if (a && b && typeof a === 'object' && typeof b === 'object' && !Array.isArray(a) && !Array.isArray(b)) {\n const out: Record<string, unknown> = {};\n for (const kName of Object.keys(b as Record<string, unknown>)) {\n out[kName] = walk((a as Record<string, unknown>)[kName], (b as Record<string, unknown>)[kName], kName);\n }\n return out;\n }\n return kk > 0 ? b : a; // non-interpolable → step to target\n };\n return walk(from, to) as SaverSpec;\n}\n\n/**\n * Enumerate all steerable leaf paths in a (resolved) spec. Returns dot-paths\n * like \"layers.0.count\", \"background.stops.1.color\", etc. Metadata fields\n * (id, label, schemaVersion, seed, units, kind, type, key) are excluded —\n * they describe structure, not tuneable values.\n *\n * Layer keys are NOT substituted: paths always use numeric indices.\n * Consumers can map to key-based paths via resolveSpecPath if needed.\n */\nexport function steerablePaths(spec: unknown): string[] {\n if (!spec || typeof spec !== 'object') return [];\n const SKIP = new Set(['kind', 'type', 'key', 'schemaVersion', 'id', 'label', 'seed', 'units', 'motionIntensity', 'mode', 'curve', 'layer']);\n const INDEXED = new Set(['layers', 'stops']);\n const out: string[] = [];\n const walk = (node: unknown, prefix: string, key: string): void => {\n if (Array.isArray(node) && INDEXED.has(key)) {\n node.forEach((child, i) => walk(child, `${prefix}.${i}`, ''));\n return;\n }\n if (Array.isArray(node)) {\n if (prefix) out.push(prefix);\n return;\n }\n if (node && typeof node === 'object') {\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (SKIP.has(k)) continue;\n walk(v, prefix ? `${prefix}.${k}` : k, k);\n }\n return;\n }\n if (prefix) out.push(prefix);\n };\n walk(spec, '', '');\n return out;\n}\n\n/** Smooth (ease-in-out) progress curve used for glides. */\nexport function easeSmooth(k: number): number {\n const c = Math.max(0, Math.min(1, k));\n return c * c * (3 - 2 * c);\n}\n\n/**\n * Fields that require re-seeding entities when they change (placement/motion\n * are baked at build time). Colour/alpha/pulse-only changes redraw in place.\n */\nexport function structuralSignature(spec: SaverSpec): string {\n return JSON.stringify([\n spec.units,\n spec.referenceViewport,\n spec.layers.map((l) => {\n const s = l.sprite as Record<string, unknown>;\n return [\n l.count,\n l.size,\n l.region,\n l.position,\n l.motion,\n l.wrap,\n l.flip,\n l.alpha,\n l.pulse,\n l.spin,\n l.grow,\n l.layout,\n l.emit,\n l.clock,\n l.sprite.kind,\n // Dimensional draws baked into entities: radius (circle/ring), length\n // (streak), width+aspect (rect), palette pick (all shaped sprites).\n s.radius,\n s.length,\n l.sprite.kind === 'rect' ? [s.width, s.aspect] : l.sprite.kind === 'bar' ? [s.length, s.thickness] : undefined,\n Array.isArray(s.colors) ? s.colors.length : undefined,\n s.colorWeights,\n l.sprite.kind === 'emoji'\n ? [l.sprite.glyphs.length, l.sprite.cycle?.period]\n : l.sprite.kind === 'text'\n ? [l.sprite.strings.length, l.sprite.cycle?.period]\n : l.sprite.kind === 'textBlock'\n ? [l.sprite.fontSize]\n : undefined,\n ];\n }),\n ]);\n}\n","import { LIMITS, SCHEMA_VERSION, type IdleSequence, type SaverSpec, type SpecError, type SpecWarning, type ValidationResult } from './types';\nimport { structuralSignature } from './steer';\n\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst isObj = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst isStr = (v: unknown): v is string => typeof v === 'string';\nconst isNum = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nconst isRange = (v: unknown): v is [number, number] =>\n Array.isArray(v) && v.length === 2 && isNum(v[0]) && isNum(v[1]) && v[0] <= v[1];\n\n// Known properties at each level — used to detect unknown/misplaced fields\nconst KNOWN_TOP = new Set(['schemaVersion', 'id', 'label', 'seed', 'motionIntensity', 'density', 'units', 'referenceViewport', 'background', 'layers', 'ghosting']);\nconst KNOWN_LAYER = new Set([\n 'count', 'sprite', 'motion', 'size', 'wrap', 'flip', 'alpha', 'blend',\n 'region', 'pulse', 'spin', 'grow', 'key', 'position', 'trail', 'links',\n 'layout', 'life', 'emit', 'clock',\n]);\nconst KNOWN_CIRCLE = new Set(['kind', 'radius', 'color', 'soft', 'colors', 'colorWeights']);\nconst KNOWN_RING = new Set(['kind', 'radius', 'color', 'width', 'colors', 'colorWeights']);\nconst KNOWN_STREAK = new Set(['kind', 'length', 'color', 'width', 'colors', 'colorWeights']);\nconst KNOWN_RECT = new Set(['kind', 'width', 'aspect', 'color', 'feather', 'colors', 'colorWeights']);\nconst KNOWN_BAR = new Set(['kind', 'values', 'length', 'thickness', 'color', 'max', 'direction', 'colors', 'colorWeights']);\nconst KNOWN_POLYGON = new Set(['kind', 'radius', 'color', 'sides', 'points', 'soft', 'colors', 'colorWeights']);\nconst KNOWN_STROKE = new Set(['kind', 'length', 'points', 'color', 'width', 'curve', 'taper', 'orient', 'colors', 'colorWeights']);\nconst KNOWN_EMOJI = new Set(['kind', 'glyphs', 'cycle']);\nconst KNOWN_TEXT = new Set(['kind', 'strings', 'color', 'font', 'align', 'baseline', 'maxWidth', 'cycle']);\nconst KNOWN_TEXT_BLOCK = new Set(['kind', 'text', 'maxWidth', 'fontSize', 'lineHeight', 'align', 'color', 'reveal']);\nconst KNOWN_REVEAL = new Set(['progress', 'mode', 'speed', 'caret', 'fade']);\nconst KNOWN_REVEAL_CARET = new Set(['blink', 'color']);\nconst KNOWN_DRIFT = new Set(['type', 'speed', 'angle', 'bidirectional', 'bob', 'ease']);\nconst KNOWN_RISE = new Set(['type', 'speed', 'sway', 'ease']);\nconst KNOWN_BOUNCE = new Set(['type', 'speed']);\nconst KNOWN_STATIC = new Set(['type']);\nconst KNOWN_ORBIT = new Set(['type', 'speed', 'radius', 'center']);\nconst KNOWN_WANDER = new Set(['type', 'speed', 'angle', 'meander', 'coherence', 'ease']);\nconst KNOWN_WARP = new Set(['type', 'speed', 'center']);\nconst KNOWN_PATH = new Set(['type', 'points', 'duration', 'curve', 'closed', 'scatter']);\nconst KNOWN_BG_SOLID = new Set(['type', 'color']);\nconst KNOWN_BG_GRADIENT = new Set(['type', 'stops', 'band', 'drift']);\n\n// Layer-level properties that models commonly misplace inside sprite\nconst LAYER_PROPS_ON_SPRITE = new Set(['blend', 'trail', 'alpha', 'pulse', 'spin', 'grow', 'region', 'links', 'flip', 'wrap', 'key', 'emit', 'clock', 'life', 'layout']);\n\nfunction unknownKeys(obj: Record<string, unknown>, known: Set<string>): string[] {\n return Object.keys(obj).filter((k) => !known.has(k));\n}\n\n/**\n * Validate an untrusted (agent- or JSON-authored) spec structurally + semantically.\n * Returns typed errors and warnings; never throws. `compileSaver` refuses to run an invalid spec.\n *\n * Warnings are non-blocking advisories about unknown/misplaced properties and\n * near-zero speeds. They don't prevent compilation but indicate likely authoring mistakes.\n */\n/**\n * Normalize: if a sprite has `colors[]` but no `color`, default `color` to\n * `colors[0]`. Author intent is unambiguous (pick from the palette), and\n * requiring both is a known footgun (F3). Mutates the spec in place — the\n * added field is always correct.\n */\nfunction normalizeColors(spec: unknown): void {\n if (!isObj(spec) || !Array.isArray(spec.layers)) return;\n for (const layer of spec.layers) {\n if (!isObj(layer)) continue;\n const sprite = (layer as Record<string, unknown>).sprite;\n if (!isObj(sprite)) continue;\n const sp = sprite as Record<string, unknown>;\n if (Array.isArray(sp.colors) && sp.colors.length > 0 && sp.color === undefined) {\n sp.color = sp.colors[0];\n }\n }\n}\n\nexport function validateSpec(spec: unknown): ValidationResult {\n normalizeColors(spec);\n const errors: SpecError[] = [];\n const warnings: SpecWarning[] = [];\n const err = (path: string, message: string): void => void errors.push({ path, message });\n const warn = (path: string, code: string, message: string): void => void warnings.push({ path, code, message });\n\n if (!isObj(spec)) return { valid: false, errors: [{ path: '', message: 'spec must be an object' }], warnings: [] };\n\n if (spec.schemaVersion !== SCHEMA_VERSION) err('schemaVersion', `must be ${SCHEMA_VERSION}`);\n if (!isStr(spec.id) || spec.id.trim() === '') err('id', 'must be a non-empty string');\n if (!isStr(spec.label) || spec.label.trim() === '') err('label', 'must be a non-empty string');\n if (spec.seed !== undefined && !isNum(spec.seed)) err('seed', 'must be a number');\n if (spec.motionIntensity !== undefined && !['calm', 'moderate', 'energetic'].includes(spec.motionIntensity as string)) {\n err('motionIntensity', 'must be calm | moderate | energetic');\n }\n if (spec.density !== undefined && !['sparse', 'normal', 'dense'].includes(spec.density as string)) {\n err('density', 'must be sparse | normal | dense');\n }\n if (spec.units !== undefined && spec.units !== 'px' && spec.units !== 'viewport') {\n err('units', \"must be 'px' | 'viewport'\");\n }\n if (spec.units === 'px' && Array.isArray(spec.layers)) {\n for (const l of spec.layers) {\n if (isObj(l) && isObj((l as Record<string, unknown>).sprite) && ((l as Record<string, unknown>).sprite as Record<string, unknown>).kind === 'textBlock') {\n err('units', \"textBlock dimensions are viewport fractions — units: 'px' is not supported with textBlock sprites\");\n break;\n }\n }\n }\n if (spec.referenceViewport !== undefined) {\n if (!isNum(spec.referenceViewport) || spec.referenceViewport < 100 || spec.referenceViewport > 8640) {\n err('referenceViewport', 'must be a number between 100 and 8640');\n }\n }\n if (spec.ghosting !== undefined && (!isNum(spec.ghosting) || spec.ghosting < 0 || spec.ghosting > LIMITS.maxGhosting)) {\n err('ghosting', `must be a number 0..${LIMITS.maxGhosting}`);\n }\n\n for (const k of unknownKeys(spec, KNOWN_TOP)) {\n warn(k, 'unknown-property', `unknown top-level property '${k}' — will be ignored`);\n }\n\n if (spec.background !== undefined) validateBackground(spec.background, err, warn);\n\n if (!Array.isArray(spec.layers) || spec.layers.length === 0) {\n err('layers', 'must be a non-empty array');\n } else {\n if (spec.layers.length > LIMITS.maxLayers) err('layers', `at most ${LIMITS.maxLayers} layers`);\n let total = 0;\n spec.layers.forEach((layer, i) => {\n total += isObj(layer) && isNum(layer.count) ? layer.count : 0;\n validateLayer(layer, `layers[${i}]`, err, warn, spec);\n });\n if (total > LIMITS.maxTotal) err('layers', `total entities ${total} exceeds cap ${LIMITS.maxTotal}`);\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\nfunction color(v: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isStr(v) || !HEX.test(v)) err(path, 'must be a hex colour like #0a3a52');\n}\n\ntype WarnFn = (path: string, code: string, message: string) => void;\n\nfunction validateBackground(bg: unknown, err: (p: string, m: string) => void, warn: WarnFn): void {\n if (!isObj(bg)) return err('background', 'must be an object');\n if (bg.type === 'solid') {\n color(bg.color, 'background.color', err);\n for (const k of unknownKeys(bg, KNOWN_BG_SOLID)) {\n warn(`background.${k}`, 'unknown-property', `unknown background property '${k}' — will be ignored`);\n }\n } else if (bg.type === 'gradient') {\n if (!Array.isArray(bg.stops) || bg.stops.length < 2) {\n err('background.stops', 'gradient needs at least 2 stops');\n } else {\n bg.stops.forEach((s, i) => {\n if (!isObj(s) || !isNum(s.at) || s.at < 0 || s.at > 1) err(`background.stops[${i}].at`, 'must be 0..1');\n color(isObj(s) ? s.color : undefined, `background.stops[${i}].color`, err);\n });\n }\n if (bg.drift !== undefined) {\n if (!isObj(bg.drift)) err('background.drift', 'must be an object');\n else {\n if (!isNum(bg.drift.period) || bg.drift.period < LIMITS.minDriftPeriod) {\n err('background.drift.period', `must be >= ${LIMITS.minDriftPeriod} ms`);\n }\n if (bg.drift.amount !== undefined && (!isNum(bg.drift.amount) || bg.drift.amount <= 0 || bg.drift.amount > LIMITS.maxDriftAmount)) {\n err('background.drift.amount', `must be > 0 and <= ${LIMITS.maxDriftAmount}`);\n }\n }\n }\n if (bg.band !== undefined) {\n if (!isObj(bg.band)) err('background.band', 'must be an object');\n else {\n color(bg.band.color, 'background.band.color', err);\n if (!isNum(bg.band.height) || bg.band.height <= 0) err('background.band.height', 'must be > 0');\n }\n }\n for (const k of unknownKeys(bg, KNOWN_BG_GRADIENT)) {\n warn(`background.${k}`, 'unknown-property', `unknown background property '${k}' — will be ignored`);\n }\n } else {\n err('background.type', 'must be solid | gradient');\n }\n}\n\nfunction validateLayer(layer: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn, spec?: unknown): void {\n if (!isObj(layer)) return err(path, 'must be an object');\n\n for (const k of unknownKeys(layer, KNOWN_LAYER)) {\n if (k === 'id') {\n warn(`${path}.id`, 'misplaced-property', `'id' is not a layer property — did you mean 'key'? Use 'key' to name a layer`);\n } else if (k === 'depth') {\n warn(`${path}.depth`, 'unknown-property', `'depth' is not a layer property — use motion type 'warp' for true perspective depth, or fake parallax with size/speed/alpha across layers`);\n } else {\n warn(`${path}.${k}`, 'unknown-property', `unknown layer property '${k}' — will be ignored`);\n }\n }\n if (!isNum(layer.count) || !Number.isInteger(layer.count) || layer.count < 1) {\n err(`${path}.count`, 'must be a positive integer');\n } else if (layer.count > LIMITS.maxPerLayer) {\n err(`${path}.count`, `at most ${LIMITS.maxPerLayer} per layer`);\n }\n if (layer.size !== undefined && (!isRange(layer.size) || layer.size[0] <= 0)) {\n err(`${path}.size`, 'must be a [min,max] range of positive px');\n }\n if (layer.wrap !== undefined && typeof layer.wrap !== 'boolean') err(`${path}.wrap`, 'must be a boolean');\n if (layer.flip !== undefined && typeof layer.flip !== 'boolean') err(`${path}.flip`, 'must be a boolean');\n\n if (layer.alpha !== undefined && (!isRange(layer.alpha) || layer.alpha[0] < 0 || layer.alpha[1] > 1)) {\n err(`${path}.alpha`, 'must be a [min,max] range within 0..1');\n }\n if (layer.blend !== undefined && !['lighter', 'screen', 'multiply'].includes(layer.blend as string)) {\n err(`${path}.blend`, \"must be 'lighter' | 'screen' | 'multiply' when set\");\n }\n if (layer.key !== undefined && (!isStr(layer.key) || layer.key.trim() === '')) {\n err(`${path}.key`, 'must be a non-empty string');\n }\n if (layer.position !== undefined) {\n if (!isObj(layer.position) || !isNum(layer.position.x) || !isNum(layer.position.y)) {\n err(`${path}.position`, 'must be {x, y} with numbers 0..1');\n } else {\n if (layer.position.x < 0 || layer.position.x > 1) err(`${path}.position.x`, 'must be 0..1');\n if (layer.position.y < 0 || layer.position.y > 1) err(`${path}.position.y`, 'must be 0..1');\n const dataLayout = isObj(layer.layout) && (layer.layout.type === 'list' || layer.layout.type === 'table');\n if (isNum(layer.count) && layer.count !== 1 && !dataLayout) {\n err(`${path}.position`, \"position requires count: 1 — or a layout of type 'list' / 'table', where it anchors the whole block\");\n }\n }\n }\n if (layer.region !== undefined) {\n if (!isObj(layer.region)) err(`${path}.region`, 'must be an object');\n else {\n for (const axis of ['x', 'y'] as const) {\n const r = layer.region[axis];\n if (r !== undefined && (!isRange(r) || r[0] < 0 || r[1] > 1)) {\n err(`${path}.region.${axis}`, 'must be a [min,max] range within 0..1');\n }\n }\n }\n }\n if (layer.pulse !== undefined) {\n if (!isObj(layer.pulse)) err(`${path}.pulse`, 'must be an object');\n else {\n if (!isNum(layer.pulse.amp) || layer.pulse.amp <= 0 || layer.pulse.amp > LIMITS.maxPulseAmp) {\n err(`${path}.pulse.amp`, `must be within 0..${LIMITS.maxPulseAmp}`);\n }\n if (!isNum(layer.pulse.period) || layer.pulse.period < LIMITS.minPulsePeriod) {\n err(`${path}.pulse.period`, `must be >= ${LIMITS.minPulsePeriod} ms (flash-safety floor)`);\n }\n if (layer.pulse.wave !== undefined) {\n if (!isObj(layer.pulse.wave)) err(`${path}.pulse.wave`, 'must be an object');\n else {\n if (!isNum(layer.pulse.wave.wavelength) || layer.pulse.wave.wavelength <= 0) {\n err(`${path}.pulse.wave.wavelength`, 'must be > 0 (px or viewport-units)');\n }\n if (layer.pulse.wave.angle !== undefined && !isNum(layer.pulse.wave.angle)) {\n err(`${path}.pulse.wave.angle`, 'must be a number (degrees)');\n }\n }\n }\n }\n }\n if (layer.spin !== undefined) {\n if (isRange(layer.spin)) {\n if (Math.abs(layer.spin[0]) > LIMITS.maxSpin || Math.abs(layer.spin[1]) > LIMITS.maxSpin) {\n err(`${path}.spin`, `each end of the range must be within ±${LIMITS.maxSpin} deg/sec`);\n }\n } else if (!isNum(layer.spin)) {\n err(`${path}.spin`, 'must be a number or a [min,max] range (degrees/sec)');\n } else if (Math.abs(layer.spin) > LIMITS.maxSpin) {\n err(`${path}.spin`, `must be within ±${LIMITS.maxSpin} deg/sec`);\n }\n }\n if (layer.grow !== undefined) {\n if (!isObj(layer.grow)) err(`${path}.grow`, 'must be an object');\n else {\n if (!isNum(layer.grow.amp) || layer.grow.amp <= 0 || layer.grow.amp > LIMITS.maxGrowAmp) {\n err(`${path}.grow.amp`, `must be within 0..${LIMITS.maxGrowAmp}`);\n }\n if (!isNum(layer.grow.period) || layer.grow.period < LIMITS.minPulsePeriod) {\n err(`${path}.grow.period`, `must be >= ${LIMITS.minPulsePeriod} ms (flash-safety floor)`);\n }\n }\n }\n\n if (layer.links !== undefined) {\n if (!isObj(layer.links)) err(`${path}.links`, 'must be an object');\n else {\n if (!isNum(layer.links.k) || !Number.isInteger(layer.links.k) || layer.links.k < 1 || layer.links.k > LIMITS.maxLinksK) {\n err(`${path}.links.k`, `must be an integer 1..${LIMITS.maxLinksK}`);\n }\n if (!isNum(layer.links.maxDist) || layer.links.maxDist <= 0) {\n err(`${path}.links.maxDist`, 'must be > 0');\n }\n if (layer.links.color !== undefined) color(layer.links.color, `${path}.links.color`, err);\n if (layer.links.alpha !== undefined && (!isNum(layer.links.alpha) || layer.links.alpha < 0 || layer.links.alpha > 1)) {\n err(`${path}.links.alpha`, 'must be 0..1');\n }\n if (layer.links.width !== undefined && (!isNum(layer.links.width) || layer.links.width <= 0)) {\n err(`${path}.links.width`, 'must be > 0');\n }\n if (layer.links.mode !== undefined && !['nearest', 'chain', 'random'].includes(layer.links.mode as string)) {\n err(`${path}.links.mode`, \"must be 'nearest' | 'chain' | 'random'\");\n }\n if (layer.links.falloff !== undefined && typeof layer.links.falloff !== 'boolean') {\n err(`${path}.links.falloff`, 'must be a boolean');\n }\n if (layer.links.closed !== undefined && typeof layer.links.closed !== 'boolean') {\n err(`${path}.links.closed`, 'must be a boolean');\n }\n if (isNum(layer.count) && layer.count > LIMITS.maxLinkLayerCount) {\n err(`${path}.links`, `layer count must be <= ${LIMITS.maxLinkLayerCount} when links is set`);\n }\n }\n }\n\n if (layer.layout !== undefined) {\n if (isObj(layer.layout) && (layer.layout.type === 'list' || layer.layout.type === 'table')) {\n const lay = layer.layout;\n if (lay.type === 'table' && (!isNum(lay.columns) || !Number.isInteger(lay.columns) || lay.columns < 1 || lay.columns > LIMITS.maxGridColumns)) {\n err(`${path}.layout.columns`, `must be an integer 1..${LIMITS.maxGridColumns}`);\n }\n const gapOk = (v: unknown): boolean => isNum(v) && v > 0;\n if (lay.gap !== undefined) {\n if (isNum(lay.gap)) {\n if (!gapOk(lay.gap)) err(`${path}.layout.gap`, 'must be > 0 (viewport units of min(w,h), or px)');\n } else if (lay.type === 'table' && isObj(lay.gap)) {\n if (lay.gap.x !== undefined && !gapOk(lay.gap.x)) err(`${path}.layout.gap.x`, 'must be > 0');\n if (lay.gap.y !== undefined && !gapOk(lay.gap.y)) err(`${path}.layout.gap.y`, 'must be > 0');\n for (const k of unknownKeys(lay.gap, new Set(['x', 'y']))) {\n warn(`${path}.layout.gap.${k}`, 'unknown-property', `unknown gap property '${k}' — will be ignored`);\n }\n } else {\n err(`${path}.layout.gap`, lay.type === 'table' ? 'must be a number > 0 or { x?, y? }' : 'must be a number > 0');\n }\n }\n for (const k of unknownKeys(lay, new Set(lay.type === 'list' ? ['type', 'gap'] : ['type', 'columns', 'gap']))) {\n warn(`${path}.layout.${k}`, 'unknown-property', `unknown layout property '${k}' — will be ignored`);\n }\n // A data layout reads variants in order: N labels want N strings.\n const sp = layer.sprite;\n if (isObj(sp) && isNum(layer.count)) {\n const variants = sp.kind === 'text' && Array.isArray(sp.strings) ? sp.strings.length\n : sp.kind === 'emoji' && Array.isArray(sp.glyphs) ? sp.glyphs.length\n : sp.kind === 'bar' && Array.isArray(sp.values) ? sp.values.length : null;\n if (variants !== null && variants !== layer.count) {\n warn(`${path}.count`, 'list-length-mismatch', `count is ${layer.count} but the sprite carries ${variants} ${sp.kind === 'bar' ? 'values' : 'variants'} — a ${lay.type} layout reads them in order, so they cycle or go unused`);\n }\n }\n } else if (!isObj(layer.layout) || layer.layout.type !== 'grid') {\n err(`${path}.layout`, \"must be an object with type: 'grid' | 'list' | 'table'\");\n } else {\n if (layer.layout.columns !== undefined && (!isNum(layer.layout.columns) || !Number.isInteger(layer.layout.columns) || layer.layout.columns < 1 || layer.layout.columns > LIMITS.maxGridColumns)) {\n err(`${path}.layout.columns`, `must be an integer 1..${LIMITS.maxGridColumns}`);\n }\n const jit = layer.layout.jitter;\n if (jit !== undefined) {\n const jitterOk = (v: unknown): boolean => isNum(v) && v >= 0 && v <= 1;\n if (isNum(jit)) {\n if (!jitterOk(jit)) err(`${path}.layout.jitter`, 'must be 0..1');\n } else if (isObj(jit)) {\n if (jit.x !== undefined && !jitterOk(jit.x)) err(`${path}.layout.jitter.x`, 'must be 0..1');\n if (jit.y !== undefined && !jitterOk(jit.y)) err(`${path}.layout.jitter.y`, 'must be 0..1');\n } else {\n err(`${path}.layout.jitter`, 'must be a number 0..1 or { x?, y? }');\n }\n }\n if (layer.position !== undefined) {\n warn(`${path}.layout`, 'layout-with-position', 'position overrides layout for the single entity — layout has no effect');\n }\n }\n }\n\n if (layer.life !== undefined) {\n if (!isObj(layer.life)) err(`${path}.life`, 'must be an object');\n else {\n if (layer.life.enter !== undefined && (!isNum(layer.life.enter) || layer.life.enter < 0)) {\n err(`${path}.life.enter`, 'must be >= 0 (ms)');\n }\n if (layer.life.exit !== undefined && (!isNum(layer.life.exit) || layer.life.exit < 0)) {\n err(`${path}.life.exit`, 'must be >= 0 (ms)');\n }\n if (isNum(layer.life.enter) && isNum(layer.life.exit) && layer.life.exit <= layer.life.enter) {\n err(`${path}.life.exit`, 'must be greater than life.enter');\n }\n if (layer.life.fade !== undefined && (!isNum(layer.life.fade) || layer.life.fade < 0)) {\n err(`${path}.life.fade`, 'must be >= 0 (ms)');\n }\n }\n }\n\n if (layer.trail !== undefined) {\n if (!isObj(layer.trail)) err(`${path}.trail`, 'must be an object');\n else {\n if (!isNum(layer.trail.length) || layer.trail.length <= 0 || layer.trail.length > LIMITS.maxTrailLength) {\n err(`${path}.trail.length`, `must be > 0 and <= ${LIMITS.maxTrailLength} ms`);\n }\n if (layer.trail.fade !== undefined && (!isNum(layer.trail.fade) || layer.trail.fade < 0 || layer.trail.fade > 1)) {\n err(`${path}.trail.fade`, 'must be 0..1');\n }\n }\n }\n\n if (layer.emit !== undefined) {\n if (!isObj(layer.emit)) err(`${path}.emit`, 'must be an object { every, life, jitter?, grow? }');\n else {\n const em = layer.emit;\n if (!isNum(em.every) || em.every < LIMITS.minEmitEvery || em.every > LIMITS.maxEmitEvery) {\n err(`${path}.emit.every`, `must be ${LIMITS.minEmitEvery}..${LIMITS.maxEmitEvery} ms (at most one event per second per entity)`);\n }\n if (!isNum(em.life) || em.life < LIMITS.minEmitLife) {\n err(`${path}.emit.life`, `must be >= ${LIMITS.minEmitLife} ms (an event is a smooth envelope, never a cut)`);\n } else if (isNum(em.every) && em.life > em.every) {\n err(`${path}.emit.life`, 'must be <= emit.every (the visible window cannot outlast its period)');\n }\n if (em.jitter !== undefined && (!isNum(em.jitter) || em.jitter < 0 || em.jitter > 1)) {\n err(`${path}.emit.jitter`, 'must be 0..1 (0 = evenly staggered, 1 = scattered by a fixed sequence)');\n }\n if (em.grow !== undefined) {\n if (!Array.isArray(em.grow) || em.grow.length !== 2 || !isNum(em.grow[0]) || !isNum(em.grow[1])) {\n err(`${path}.emit.grow`, 'must be [from, to] size multipliers');\n } else if (em.grow[0] < 0 || em.grow[1] < 0 || em.grow[0] > LIMITS.maxEmitGrow || em.grow[1] > LIMITS.maxEmitGrow) {\n err(`${path}.emit.grow`, `each multiplier must be 0..${LIMITS.maxEmitGrow}`);\n }\n }\n // jitter 0 promises one event at a time; that only holds while a window\n // is shorter than the stagger between entities.\n if (em.jitter === 0 && isNum(em.every) && isNum(em.life) && isNum(layer.count) && layer.count > 1 && em.life > em.every / layer.count) {\n warn(`${path}.emit.life`, 'emit-overlap', `jitter 0 staggers ${layer.count} entities ${(em.every / layer.count).toFixed(0)} ms apart but each stays lit ${em.life} ms — windows overlap, so more than one event is visible at a time. Shorten life or lengthen every`);\n }\n for (const k of unknownKeys(em, new Set(['every', 'life', 'jitter', 'grow']))) {\n warn(`${path}.emit.${k}`, 'unknown-property', `unknown emit property '${k}' — will be ignored`);\n }\n }\n }\n if (layer.clock !== undefined) {\n if (!isObj(layer.clock)) err(`${path}.clock`, 'must be an object { phase?, rate? }');\n else {\n const ck = layer.clock;\n if (ck.phase !== undefined && (!isNum(ck.phase) || ck.phase < 0 || ck.phase > 1)) {\n err(`${path}.clock.phase`, 'must be 0..1 (turns)');\n }\n const rate = ck.rate === undefined ? 1 : ck.rate;\n if (!isNum(rate) || rate < LIMITS.minClockRate || rate > LIMITS.maxClockRate) {\n err(`${path}.clock.rate`, `must be ${LIMITS.minClockRate}..${LIMITS.maxClockRate}`);\n } else {\n // A clocked layer pulses in unison — every entity at once — so the\n // per-entity-phase defence is gone and the period floor doubles.\n const floor = LIMITS.minClockedPeriod * rate;\n if (isObj(layer.pulse) && isNum(layer.pulse.period) && layer.pulse.period < floor) {\n err(`${path}.pulse.period`, `must be >= ${floor} ms when the layer has a clock (period / rate >= ${LIMITS.minClockedPeriod} — the whole layer breathes in unison)`);\n }\n if (isObj(layer.grow) && isNum(layer.grow.period) && layer.grow.period < floor) {\n err(`${path}.grow.period`, `must be >= ${floor} ms when the layer has a clock (period / rate >= ${LIMITS.minClockedPeriod})`);\n }\n const sp = layer.sprite;\n if (isObj(sp) && isObj(sp.cycle) && isNum(sp.cycle.period) && sp.cycle.period < floor) {\n err(`${path}.sprite.cycle.period`, `must be >= ${floor} ms when the layer has a clock (period / rate >= ${LIMITS.minClockedPeriod})`);\n }\n }\n for (const k of unknownKeys(ck, new Set(['phase', 'rate']))) {\n warn(`${path}.clock.${k}`, 'unknown-property', `unknown clock property '${k}' — will be ignored`);\n }\n }\n }\n validateSprite(layer.sprite, `${path}.sprite`, err, warn);\n validateMotion(layer.motion, `${path}.motion`, err, warn, spec);\n}\n\nfunction validateSprite(sprite: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn): void {\n if (!isObj(sprite)) return err(path, 'must be an object');\n\n let knownSet: Set<string>;\n if (sprite.kind === 'emoji') {\n knownSet = KNOWN_EMOJI;\n if (!Array.isArray(sprite.glyphs) || sprite.glyphs.length === 0 || !sprite.glyphs.every(isStr)) {\n err(`${path}.glyphs`, 'must be a non-empty array of strings');\n }\n validateCycle(sprite, path, err);\n } else if (sprite.kind === 'text') {\n knownSet = KNOWN_TEXT;\n if (!Array.isArray(sprite.strings) || sprite.strings.length === 0 || !sprite.strings.every(isStr)) {\n err(`${path}.strings`, 'must be a non-empty array of strings');\n }\n if (sprite.color !== undefined) color(sprite.color, `${path}.color`, err);\n if (sprite.font !== undefined && !isStr(sprite.font)) {\n err(`${path}.font`, 'must be a string');\n }\n if (sprite.align !== undefined && !['left', 'center', 'right'].includes(sprite.align as string)) {\n err(`${path}.align`, 'must be left | center | right');\n }\n if (sprite.baseline !== undefined && !['top', 'middle', 'bottom'].includes(sprite.baseline as string)) {\n err(`${path}.baseline`, 'must be top | middle | bottom');\n }\n if (sprite.maxWidth !== undefined && (!isNum(sprite.maxWidth) || sprite.maxWidth <= 0)) {\n err(`${path}.maxWidth`, 'must be a positive number');\n }\n validateCycle(sprite, path, err);\n } else if (sprite.kind === 'circle') {\n knownSet = KNOWN_CIRCLE;\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n if (sprite.soft !== undefined && typeof sprite.soft !== 'boolean') err(`${path}.soft`, 'must be a boolean');\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'ring') {\n knownSet = KNOWN_RING;\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n if (sprite.width !== undefined && (!isNum(sprite.width) || sprite.width <= 0)) err(`${path}.width`, 'must be > 0');\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'streak') {\n knownSet = KNOWN_STREAK;\n if (!isRange(sprite.length) || sprite.length[0] <= 0) err(`${path}.length`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n if (sprite.width !== undefined && (!isNum(sprite.width) || sprite.width <= 0)) err(`${path}.width`, 'must be > 0');\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'rect') {\n knownSet = KNOWN_RECT;\n if (!isRange(sprite.width) || sprite.width[0] <= 0) err(`${path}.width`, 'must be a [min,max] range of positive px');\n if (sprite.aspect !== undefined && (!isRange(sprite.aspect) || sprite.aspect[0] <= 0)) {\n err(`${path}.aspect`, 'must be a [min,max] range of positive height/width ratios');\n }\n if (sprite.feather !== undefined && (!isNum(sprite.feather) || sprite.feather < 0 || sprite.feather > 1)) {\n err(`${path}.feather`, 'must be 0..1 (fraction of the half-size that fades out)');\n }\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'bar') {\n knownSet = KNOWN_BAR;\n if (!Array.isArray(sprite.values) || sprite.values.length === 0 || sprite.values.length > LIMITS.maxPerLayer || !sprite.values.every((v) => isNum(v) && v >= 0)) {\n err(`${path}.values`, `must be 1..${LIMITS.maxPerLayer} numbers >= 0`);\n }\n if (!isNum(sprite.length) || sprite.length <= 0) err(`${path}.length`, 'must be > 0 (full-scale bar length)');\n if (!isNum(sprite.thickness) || sprite.thickness <= 0) err(`${path}.thickness`, 'must be > 0');\n if (sprite.max !== undefined && (!isNum(sprite.max) || sprite.max <= 0)) err(`${path}.max`, 'must be > 0');\n if (sprite.direction !== undefined && !['right', 'left', 'up', 'down'].includes(sprite.direction as string)) {\n err(`${path}.direction`, \"must be 'right' | 'left' | 'up' | 'down'\");\n }\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'polygon') {\n knownSet = KNOWN_POLYGON;\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px (circumradius)');\n if (sprite.sides !== undefined && sprite.points !== undefined) {\n err(`${path}.sides`, 'use sides (a regular polygon) or points (a custom one), not both');\n }\n if (sprite.sides !== undefined && (!isNum(sprite.sides) || !Number.isInteger(sprite.sides) || sprite.sides < LIMITS.minPolygonSides || sprite.sides > LIMITS.maxPolygonSides)) {\n err(`${path}.sides`, `must be an integer ${LIMITS.minPolygonSides}..${LIMITS.maxPolygonSides}`);\n }\n if (sprite.points !== undefined) validateShapePoints(sprite.points, `${path}.points`, 3, err);\n if (sprite.soft !== undefined && typeof sprite.soft !== 'boolean') err(`${path}.soft`, 'must be a boolean');\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'stroke') {\n knownSet = KNOWN_STROKE;\n if (!isRange(sprite.length) || sprite.length[0] <= 0) err(`${path}.length`, 'must be a [min,max] range of positive px (the mark\\'s bounding size)');\n validateShapePoints(sprite.points, `${path}.points`, 2, err);\n if (sprite.width !== undefined && (!isNum(sprite.width) || sprite.width <= 0)) err(`${path}.width`, 'must be > 0');\n if (sprite.curve !== undefined && sprite.curve !== 'smooth' && sprite.curve !== 'linear') err(`${path}.curve`, \"must be 'smooth' | 'linear'\");\n if (sprite.taper !== undefined && typeof sprite.taper !== 'boolean') err(`${path}.taper`, 'must be a boolean');\n if (sprite.orient !== undefined && typeof sprite.orient !== 'boolean') err(`${path}.orient`, 'must be a boolean');\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'textBlock') {\n knownSet = KNOWN_TEXT_BLOCK;\n if (typeof sprite.text !== 'string' || sprite.text.length === 0) {\n err(`${path}.text`, 'must be a non-empty string');\n } else if (sprite.text.length > LIMITS.maxTextBlockLength) {\n err(`${path}.text`, `must be at most ${LIMITS.maxTextBlockLength} characters`);\n }\n if (!isNum(sprite.maxWidth) || sprite.maxWidth <= 0 || sprite.maxWidth > LIMITS.maxTextBlockMaxWidth) {\n err(`${path}.maxWidth`, `must be a positive number up to ${LIMITS.maxTextBlockMaxWidth} (viewport fraction)`);\n }\n if (!isNum(sprite.fontSize) || sprite.fontSize < LIMITS.minTextBlockFontSize || sprite.fontSize > LIMITS.maxTextBlockFontSize) {\n err(`${path}.fontSize`, `must be between ${LIMITS.minTextBlockFontSize} and ${LIMITS.maxTextBlockFontSize} (viewport fraction)`);\n }\n if (sprite.lineHeight !== undefined && (!isNum(sprite.lineHeight) || sprite.lineHeight < 0.5 || sprite.lineHeight > 4)) {\n err(`${path}.lineHeight`, 'must be between 0.5 and 4 (multiplier)');\n }\n if (sprite.align !== undefined && !['left', 'center', 'right'].includes(sprite.align as string)) {\n err(`${path}.align`, \"must be 'left' | 'center' | 'right'\");\n }\n if (sprite.color !== undefined) color(sprite.color, `${path}.color`, err);\n if (sprite.reveal !== undefined) {\n const rv = sprite.reveal as Record<string, unknown>;\n if (typeof rv !== 'object' || rv === null || Array.isArray(rv)) {\n err(`${path}.reveal`, 'must be an object');\n } else {\n for (const k of Object.keys(rv)) {\n if (!KNOWN_REVEAL.has(k)) err(`${path}.reveal.${k}`, 'unknown reveal field');\n }\n if (rv.progress !== undefined && (!isNum(rv.progress) || rv.progress < 0 || rv.progress > 1)) {\n err(`${path}.reveal.progress`, 'must be a number between 0 and 1');\n }\n if (rv.mode !== undefined && !['typewriter', 'word', 'line', 'glyphFade'].includes(rv.mode as string)) {\n err(`${path}.reveal.mode`, \"must be 'typewriter' | 'word' | 'line' | 'glyphFade'\");\n }\n if (rv.fade !== undefined && (!isNum(rv.fade) || rv.fade <= 0 || rv.fade > 1)) {\n err(`${path}.reveal.fade`, 'must be between 0 (exclusive) and 1 (fraction of progress)');\n }\n if (rv.speed !== undefined && (!isNum(rv.speed) || rv.speed < 0 || rv.speed > LIMITS.maxRevealSpeed)) {\n err(`${path}.reveal.speed`, `must be between 0 and ${LIMITS.maxRevealSpeed} (graphemes/sec)`);\n }\n if (rv.caret !== undefined && typeof rv.caret !== 'boolean') {\n const caret = rv.caret as Record<string, unknown>;\n if (typeof caret !== 'object' || caret === null || Array.isArray(caret)) {\n err(`${path}.reveal.caret`, 'must be a boolean or an object');\n } else {\n for (const k of Object.keys(caret)) {\n if (!KNOWN_REVEAL_CARET.has(k)) err(`${path}.reveal.caret.${k}`, 'unknown caret field');\n }\n if (caret.blink !== undefined && (!isNum(caret.blink) || caret.blink <= 0 || caret.blink > LIMITS.maxCaretBlinkHz)) {\n err(`${path}.reveal.caret.blink`, `must be between 0 (exclusive) and ${LIMITS.maxCaretBlinkHz} Hz (flash safety)`);\n }\n if (caret.color !== undefined) color(caret.color, `${path}.reveal.caret.color`, err);\n }\n }\n }\n }\n } else {\n err(`${path}.kind`, 'must be emoji | text | circle | ring | streak | rect | bar | polygon | stroke | textBlock');\n return;\n }\n\n for (const k of unknownKeys(sprite, knownSet)) {\n if (LAYER_PROPS_ON_SPRITE.has(k)) {\n warn(`${path}.${k}`, 'misplaced-property', `'${k}' belongs on the layer, not inside sprite — move it up one level`);\n } else {\n warn(`${path}.${k}`, 'unknown-property', `unknown sprite property '${k}' — will be ignored`);\n }\n }\n}\n\n/** Shared colors[] + colorWeights[] validation for circle/ring/streak/rect sprites. */\nfunction validatePalette(sprite: Record<string, unknown>, path: string, err: (p: string, m: string) => void): void {\n if (sprite.colors !== undefined) {\n if (!Array.isArray(sprite.colors) || sprite.colors.length === 0) {\n err(`${path}.colors`, 'must be a non-empty array of hex colours');\n } else {\n sprite.colors.forEach((c: unknown, ci: number) => color(c, `${path}.colors[${ci}]`, err));\n }\n }\n if (sprite.colorWeights !== undefined) {\n if (!Array.isArray(sprite.colors)) {\n err(`${path}.colorWeights`, 'requires colors to be set');\n } else if (!Array.isArray(sprite.colorWeights) || sprite.colorWeights.length !== sprite.colors.length) {\n err(`${path}.colorWeights`, 'must be an array the same length as colors');\n } else if (!sprite.colorWeights.every((v: unknown) => isNum(v) && v >= 0) || !sprite.colorWeights.some((v: unknown) => isNum(v) && v > 0)) {\n err(`${path}.colorWeights`, 'weights must be >= 0 with at least one > 0');\n }\n }\n}\n\nfunction validateCycle(sprite: Record<string, unknown>, path: string, err: (p: string, m: string) => void): void {\n if (sprite.cycle === undefined) return;\n if (!isObj(sprite.cycle)) return err(`${path}.cycle`, 'must be an object');\n if (!isNum(sprite.cycle.period) || sprite.cycle.period < LIMITS.minCyclePeriod) {\n err(`${path}.cycle.period`, `must be >= ${LIMITS.minCyclePeriod} ms (flash-safety floor)`);\n }\n}\n\nfunction validateMotion(motion: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn, spec?: unknown): void {\n if (!isObj(motion)) return err(path, 'must be an object');\n const isViewport = !isObj(spec) || (spec as Record<string, unknown>).units !== 'px';\n const refVp = isObj(spec) && isNum((spec as Record<string, unknown>).referenceViewport) ? (spec as Record<string, unknown>).referenceViewport as number : LIMITS.referenceViewport;\n const speedCap = isViewport ? LIMITS.maxSpeed / refVp : LIMITS.maxSpeed;\n const speedOk = (v: unknown, p: string): void => {\n if (!isRange(v)) err(p, 'must be a [min,max] range');\n else if (v[0] < 0) err(p, 'speed lower bound must be >= 0');\n else if (v[1] > speedCap) err(p, `speed exceeds cap ${isViewport ? speedCap.toFixed(2) + ' viewport-units/sec' : LIMITS.maxSpeed + ' px/sec'}`);\n };\n\n let knownSet: Set<string>;\n if (motion.type === 'drift') {\n knownSet = KNOWN_DRIFT;\n speedOk(motion.speed, `${path}.speed`);\n if (motion.angle !== undefined && !isNum(motion.angle)) err(`${path}.angle`, 'must be a number (degrees)');\n if (motion.bidirectional !== undefined && typeof motion.bidirectional !== 'boolean') err(`${path}.bidirectional`, 'must be a boolean');\n if (motion.bob !== undefined && !isNum(motion.bob)) err(`${path}.bob`, 'must be a number');\n validateEase(motion.ease, `${path}.ease`, err, warn);\n if (isRange(motion.speed) && motion.speed[1] < 1 && !isViewport) {\n warn(`${path}.speed`, 'near-zero-speed', `max speed is ${motion.speed[1]} px/sec — entities will appear frozen. Typical range: 10–200 px/sec`);\n }\n } else if (motion.type === 'rise') {\n knownSet = KNOWN_RISE;\n speedOk(motion.speed, `${path}.speed`);\n if (motion.sway !== undefined && !isNum(motion.sway)) err(`${path}.sway`, 'must be a number');\n validateEase(motion.ease, `${path}.ease`, err, warn);\n if (isRange(motion.speed) && motion.speed[1] < 1 && !isViewport) {\n warn(`${path}.speed`, 'near-zero-speed', `max speed is ${motion.speed[1]} px/sec — entities will appear frozen. Typical range: 5–80 px/sec`);\n }\n } else if (motion.type === 'bounce') {\n knownSet = KNOWN_BOUNCE;\n speedOk(motion.speed, `${path}.speed`);\n if (isRange(motion.speed) && motion.speed[1] < 1 && !isViewport) {\n warn(`${path}.speed`, 'near-zero-speed', `max speed is ${motion.speed[1]} px/sec — entities will appear frozen. Typical range: 20–150 px/sec`);\n }\n } else if (motion.type === 'static') {\n knownSet = KNOWN_STATIC;\n } else if (motion.type === 'orbit') {\n knownSet = KNOWN_ORBIT;\n if (!isRange(motion.speed)) err(`${path}.speed`, 'must be a [min,max] range');\n else {\n if (Math.abs(motion.speed[0]) > LIMITS.maxOrbitSpeed || Math.abs(motion.speed[1]) > LIMITS.maxOrbitSpeed) err(`${path}.speed`, `orbit speed exceeds cap ${LIMITS.maxOrbitSpeed} deg/sec`);\n if (Math.max(Math.abs(motion.speed[0]), Math.abs(motion.speed[1])) < 1) {\n warn(`${path}.speed`, 'near-zero-speed', `orbit speed is near zero — entities will appear frozen. Typical range: 5–60 deg/sec`);\n }\n }\n if (!isRange(motion.radius) || motion.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n if (motion.center !== undefined) {\n if (!isObj(motion.center)) {\n err(`${path}.center`, 'must be {x, y} (0..1) or { layer: key }');\n } else if ('layer' in motion.center) {\n if (!isStr(motion.center.layer) || motion.center.layer.trim() === '') {\n err(`${path}.center.layer`, 'must be a non-empty layer key');\n } else if (isObj(spec) && Array.isArray((spec as Record<string, unknown>).layers)) {\n // Scene-graph lite: parent must exist, be a single entity, and not itself\n // orbit a layer (strictly one level deep — keeps positionAt analytic).\n const layers = (spec as { layers: unknown[] }).layers;\n const parent = layers.find((l) => isObj(l) && l.key === (motion.center as { layer: string }).layer) as Record<string, unknown> | undefined;\n if (!parent) {\n err(`${path}.center.layer`, `no layer with key '${motion.center.layer}'`);\n } else {\n if (parent.count !== 1) err(`${path}.center.layer`, 'parent layer must have count: 1');\n const pm = parent.motion;\n if (isObj(pm) && pm.type === 'orbit' && isObj(pm.center) && 'layer' in pm.center) {\n err(`${path}.center.layer`, 'parent may not itself orbit a layer (one level deep only)');\n }\n }\n }\n } else if (!isNum(motion.center.x) || !isNum(motion.center.y)) {\n err(`${path}.center`, 'must be {x, y} with numbers 0..1');\n } else {\n if (motion.center.x < 0 || motion.center.x > 1) err(`${path}.center.x`, 'must be 0..1');\n if (motion.center.y < 0 || motion.center.y > 1) err(`${path}.center.y`, 'must be 0..1');\n }\n }\n } else if (motion.type === 'wander') {\n knownSet = KNOWN_WANDER;\n validateEase(motion.ease, `${path}.ease`, err, warn);\n speedOk(motion.speed, `${path}.speed`);\n if (motion.angle !== undefined && !isNum(motion.angle)) err(`${path}.angle`, 'must be a number (degrees)');\n const meanderCap = isViewport ? LIMITS.maxMeander / refVp : LIMITS.maxMeander;\n if (motion.meander !== undefined && (!isNum(motion.meander) || motion.meander <= 0 || motion.meander > meanderCap)) {\n err(`${path}.meander`, `must be > 0 and <= ${isViewport ? meanderCap.toFixed(3) + ' viewport-units' : LIMITS.maxMeander + ' px'}`);\n }\n if (motion.coherence !== undefined && (!isNum(motion.coherence) || motion.coherence < 0 || motion.coherence > 1)) {\n err(`${path}.coherence`, 'must be 0..1');\n }\n } else if (motion.type === 'warp') {\n knownSet = KNOWN_WARP;\n if (!isRange(motion.speed) || motion.speed[0] < 0) err(`${path}.speed`, 'must be a [min,max] range >= 0 (depth-units/sec)');\n else if (motion.speed[1] > LIMITS.maxWarpSpeed) err(`${path}.speed`, `warp speed exceeds cap ${LIMITS.maxWarpSpeed} depth-units/sec`);\n if (motion.center !== undefined) {\n if (!isObj(motion.center) || !isNum(motion.center.x) || !isNum(motion.center.y)) {\n err(`${path}.center`, 'must be {x, y} with numbers 0..1');\n } else {\n if (motion.center.x < 0 || motion.center.x > 1) err(`${path}.center.x`, 'must be 0..1');\n if (motion.center.y < 0 || motion.center.y > 1) err(`${path}.center.y`, 'must be 0..1');\n }\n }\n } else if (motion.type === 'path') {\n knownSet = KNOWN_PATH;\n if (!Array.isArray(motion.points) || motion.points.length < LIMITS.minPathPoints || motion.points.length > LIMITS.maxPathPoints) {\n err(`${path}.points`, `must be an array of ${LIMITS.minPathPoints}..${LIMITS.maxPathPoints} points`);\n } else {\n motion.points.forEach((p: unknown, pi: number) => {\n if (!isObj(p) || !isNum(p.x) || !isNum(p.y) || p.x < 0 || p.x > 1 || p.y < 0 || p.y > 1) {\n err(`${path}.points[${pi}]`, 'must be {x, y} with numbers 0..1');\n }\n });\n }\n if (!isNum(motion.duration) || motion.duration < LIMITS.minPathDuration) {\n err(`${path}.duration`, `must be >= ${LIMITS.minPathDuration} ms`);\n }\n if (motion.curve !== undefined && motion.curve !== 'linear' && motion.curve !== 'smooth') {\n err(`${path}.curve`, \"must be 'linear' | 'smooth'\");\n }\n if (motion.closed !== undefined && typeof motion.closed !== 'boolean') err(`${path}.closed`, 'must be a boolean');\n const scatterCap = isViewport ? LIMITS.maxMeander / refVp : LIMITS.maxMeander;\n if (motion.scatter !== undefined && (!isNum(motion.scatter) || motion.scatter <= 0 || motion.scatter > scatterCap)) {\n err(`${path}.scatter`, `must be > 0 and <= ${isViewport ? scatterCap.toFixed(3) + ' viewport-units' : LIMITS.maxMeander + ' px'}`);\n }\n } else {\n err(`${path}.type`, 'must be drift | rise | bounce | static | orbit | wander | warp | path');\n return;\n }\n\n for (const k of unknownKeys(motion, knownSet)) {\n warn(`${path}.${k}`, 'unknown-property', `unknown motion property '${k}' — will be ignored`);\n }\n}\n\n/** `points` for polygon/stroke: 2..24 (or 3..24) unit pairs inside the −1..1 box. */\nfunction validateShapePoints(points: unknown, path: string, min: number, err: (p: string, m: string) => void): void {\n if (!Array.isArray(points) || points.length < min || points.length > LIMITS.maxShapePoints) {\n return err(path, `must be ${min}..${LIMITS.maxShapePoints} [x, y] pairs in unit coordinates (-1..1)`);\n }\n for (let i = 0; i < points.length; i++) {\n const pt: unknown = points[i]; // by index, so a sparse array's holes are rejected too\n if (!Array.isArray(pt) || pt.length !== 2 || !isNum(pt[0]) || !isNum(pt[1]) || Math.abs(pt[0]) > 1 || Math.abs(pt[1]) > 1) {\n err(`${path}[${i}]`, 'must be an [x, y] pair with each coordinate in -1..1');\n }\n }\n}\n\nfunction validateEase(ease: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn): void {\n if (ease === undefined) return;\n if (!isObj(ease)) return err(path, \"must be an object { type: 'settle' | 'buoyant', tau }\");\n if (ease.type !== 'settle' && ease.type !== 'buoyant') err(`${path}.type`, \"must be 'settle' | 'buoyant'\");\n if (!isNum(ease.tau) || ease.tau < LIMITS.minEaseTau || ease.tau > LIMITS.maxEaseTau) {\n err(`${path}.tau`, `must be ${LIMITS.minEaseTau}..${LIMITS.maxEaseTau} ms`);\n }\n for (const k of unknownKeys(ease, new Set(['type', 'tau']))) {\n warn(`${path}.${k}`, 'unknown-property', `unknown ease property '${k}' — will be ignored`);\n }\n}\n\n/** Narrowing helper: validate + cast. Throws with a joined message when invalid. */\nexport function assertValidSpec(spec: unknown): SaverSpec {\n const r = validateSpec(spec);\n if (!r.valid) {\n throw new Error(`invalid saver spec:\\n${r.errors.map((e) => ` ${e.path || '<root>'}: ${e.message}`).join('\\n')}`);\n }\n return spec as SaverSpec;\n}\n\n/**\n * Validate a sequence envelope. Each segment's `scene` goes through `validateSpec`;\n * sequence-level rules (segment count, duration floors, key uniqueness, transition\n * bounds) are checked here.\n */\nexport function validateSequence(seq: unknown): ValidationResult {\n // Normalize each segment's scene (F3: colors-without-color auto-default)\n if (isObj(seq) && Array.isArray(seq.segments)) {\n for (const seg of seq.segments) {\n if (isObj(seg) && isObj((seg as Record<string, unknown>).scene)) {\n normalizeColors((seg as Record<string, unknown>).scene);\n }\n }\n }\n const errors: SpecError[] = [];\n const warnings: SpecWarning[] = [];\n const err = (path: string, message: string): void => void errors.push({ path, message });\n\n if (!isObj(seq)) return { valid: false, errors: [{ path: '', message: 'sequence must be an object' }], warnings: [] };\n\n if (seq.format !== 'idle-sequence') err('format', \"must be 'idle-sequence'\");\n if (seq.schemaVersion !== SCHEMA_VERSION) err('schemaVersion', `must be ${SCHEMA_VERSION}`);\n if (!isStr(seq.id) || seq.id.trim() === '') err('id', 'must be a non-empty string');\n if (!isStr(seq.label) || seq.label.trim() === '') err('label', 'must be a non-empty string');\n if (seq.seed !== undefined && !isNum(seq.seed)) err('seed', 'must be a number');\n if (typeof seq.loop !== 'boolean') err('loop', 'must be a boolean');\n\n if (!Array.isArray(seq.segments) || seq.segments.length === 0) {\n err('segments', 'must be a non-empty array');\n return { valid: false, errors, warnings };\n }\n\n if (seq.segments.length > LIMITS.maxSegments) {\n err('segments', `at most ${LIMITS.maxSegments} segments`);\n }\n\n const keys = new Set<string>();\n let hasDurationless = false;\n\n for (let i = 0; i < seq.segments.length; i++) {\n const s = seq.segments[i];\n const p = `segments[${i}]`;\n if (!isObj(s)) { err(p, 'must be an object'); continue; }\n\n if (!isStr(s.key) || s.key.trim() === '') {\n err(`${p}.key`, 'must be a non-empty string');\n } else if (keys.has(s.key as string)) {\n err(`${p}.key`, `duplicate key '${s.key}'`);\n } else {\n keys.add(s.key as string);\n }\n\n if (s.duration !== undefined) {\n if (hasDurationless) {\n err(`${p}.duration`, 'a segment after a durationless segment may not have a duration');\n }\n if (!isNum(s.duration) || s.duration < LIMITS.minSegmentDuration) {\n err(`${p}.duration`, `must be >= ${LIMITS.minSegmentDuration} ms`);\n }\n } else {\n if (i < seq.segments.length - 1) {\n err(`${p}.duration`, 'only the final segment may omit duration');\n }\n hasDurationless = true;\n }\n\n if (s.advance !== undefined && !['auto', 'input', 'either'].includes(s.advance as string)) {\n err(`${p}.advance`, \"must be 'auto' | 'input' | 'either'\");\n }\n\n if (s.transition !== undefined) {\n if (!isObj(s.transition)) {\n err(`${p}.transition`, 'must be an object');\n } else if (s.transition.type === 'morph') {\n if (!isNum(s.transition.dur) || s.transition.dur < LIMITS.minTransitionDur || s.transition.dur > LIMITS.maxTransitionDur) {\n err(`${p}.transition.dur`, `must be a number between ${LIMITS.minTransitionDur} and ${LIMITS.maxTransitionDur}`);\n }\n } else if (s.transition.type !== 'cut') {\n err(`${p}.transition.type`, \"must be 'cut' or 'morph'\");\n }\n }\n\n if (isObj(s.scene)) {\n const sceneResult = validateSpec(s.scene);\n for (const e of sceneResult.errors) errors.push({ path: `${p}.scene.${e.path}`, message: e.message });\n if (sceneResult.warnings) {\n for (const w of sceneResult.warnings) warnings.push({ path: `${p}.scene.${w.path}`, code: w.code, message: w.message });\n }\n } else {\n err(`${p}.scene`, 'must be a valid SaverSpec object');\n }\n }\n\n if (seq.loop === true && hasDurationless) {\n err('loop', 'loop: true requires all segments to have a duration');\n }\n\n // Warn when morph is requested but signatures differ (will fall back to cut)\n if (errors.length === 0 && Array.isArray(seq.segments)) {\n for (let i = 0; i < seq.segments.length; i++) {\n const s = seq.segments[i];\n if (!isObj(s) || !isObj(s.transition) || s.transition.type !== 'morph') continue;\n const next = seq.segments[i + 1];\n if (!next || !isObj(next) || !isObj(s.scene) || !isObj(next.scene)) continue;\n const sigA = structuralSignature(s.scene as unknown as SaverSpec);\n const sigB = structuralSignature((next as Record<string, unknown>).scene as unknown as SaverSpec);\n if (sigA !== sigB) {\n warnings.push({\n path: `segments[${i}].transition`,\n code: 'morph-structural-mismatch',\n message: `segments ${i}→${i + 1} differ structurally: morph will fall back to cut`,\n });\n }\n }\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\nexport function assertValidSequence(seq: unknown): IdleSequence {\n const r = validateSequence(seq);\n if (!r.valid) {\n throw new Error(`invalid sequence:\\n${r.errors.map((e) => ` ${e.path || '<root>'}: ${e.message}`).join('\\n')}`);\n }\n return seq as IdleSequence;\n}\n","/**\n * Shape glyph geometry — pure, renderer-free, shared by the compiler (what to\n * stroke/fill), perception (how much ink that is) and advise. Everything is\n * computed from the sprite spec + the entity's seeded size, so the canvas and\n * the analytic model agree by construction.\n *\n * Unit coordinates: `polygon.points` and `stroke.points` live in a −1..1 box\n * that is scaled by the entity's half-size (circumradius for polygons, half of\n * `length` for strokes), so the seeded size range is the glyph's bounding\n * diameter — the same rule `circle.radius` / `streak.length` already follow.\n */\nimport type { SpriteSpec } from './types';\n\nexport type ShapedSprite = Extract<SpriteSpec, { kind: 'circle' | 'ring' | 'streak' | 'rect' | 'polygon' | 'stroke' | 'bar' }>;\nexport type BarSprite = Extract<SpriteSpec, { kind: 'bar' }>;\nexport type PolygonSprite = Extract<SpriteSpec, { kind: 'polygon' }>;\nexport type StrokeSprite = Extract<SpriteSpec, { kind: 'stroke' }>;\n\n/** Every sprite that paints with `color` / `colors[]` (as opposed to glyphs). */\nexport function isShapedSprite(s: SpriteSpec): s is ShapedSprite {\n return s.kind === 'circle' || s.kind === 'ring' || s.kind === 'streak' || s.kind === 'rect' || s.kind === 'polygon' || s.kind === 'stroke' || s.kind === 'bar';\n}\n\n/** 0..1 fill of bar `index`: `values[i] / max`, `max` defaulting to the largest value. Read at paint time so steered values glide. */\nexport function barFraction(s: BarSprite, index: number): number {\n const n = s.values.length;\n if (n === 0) return 0;\n const v = s.values[((index % n) + n) % n] ?? 0;\n const max = s.max ?? s.values.reduce((m, x) => Math.max(m, x), 0);\n if (!(max > 0)) return 0;\n return Math.max(0, Math.min(1, v / max));\n}\n\n/** Box of a bar `len` long and `thick` thick growing from (0,0) toward `direction`: centre + half extents, px. */\nexport function barBox(direction: NonNullable<BarSprite['direction']>, len: number, thick: number): { cx: number; cy: number; halfX: number; halfY: number } {\n switch (direction) {\n case 'left': return { cx: -len / 2, cy: 0, halfX: len / 2, halfY: thick / 2 };\n case 'up': return { cx: 0, cy: -len / 2, halfX: thick / 2, halfY: len / 2 };\n case 'down': return { cx: 0, cy: len / 2, halfX: thick / 2, halfY: len / 2 };\n default: return { cx: len / 2, cy: 0, halfX: len / 2, halfY: thick / 2 };\n }\n}\n\nexport const DEFAULT_POLYGON_SIDES = 6;\n/** Minimum samples along a stroke path; grows with the control-point count (6 per segment). */\nexport const STROKE_SAMPLES = 24;\n\n/** Polygon vertices centred on (0,0), unrotated, circumradius `radius` px. Regular n-gons point up. */\nexport function polygonPoints(s: PolygonSprite, radius: number): Array<{ x: number; y: number }> {\n if (s.points && s.points.length >= 3) {\n return s.points.map(([x, y]) => ({ x: x * radius, y: y * radius }));\n }\n const n = Math.max(3, Math.round(s.sides ?? DEFAULT_POLYGON_SIDES));\n const out: Array<{ x: number; y: number }> = [];\n for (let k = 0; k < n; k++) {\n const a = -Math.PI / 2 + (2 * Math.PI * k) / n;\n out.push({ x: Math.cos(a) * radius, y: Math.sin(a) * radius });\n }\n return out;\n}\n\n/**\n * Signed-area magnitude of a polygon (shoelace), px². Exact for simple\n * polygons; a self-intersecting outline (a bow-tie) has lobes of opposite\n * winding that cancel here while the canvas's nonzero fill paints both, so\n * perception under-reports such glyphs. Author facets as simple polygons.\n */\nexport function polygonArea(pts: Array<{ x: number; y: number }>): number {\n let a = 0;\n for (let i = 0; i < pts.length; i++) {\n const p = pts[i]!;\n const q = pts[(i + 1) % pts.length]!;\n a += p.x * q.y - q.x * p.y;\n }\n return Math.abs(a) / 2;\n}\n\n/** Fraction of the circumscribed disc a polygon fills — the perception weight of a polygon splat. */\nexport function polygonFill(s: PolygonSprite, radius: number): number {\n if (radius <= 0) return 0;\n const disc = Math.PI * radius * radius;\n return Math.min(1, polygonArea(polygonPoints(s, radius)) / disc);\n}\n\nfunction catmullRom(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const u2 = u * u;\n const u3 = u2 * u;\n return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);\n}\n\n/**\n * The stroke's path, sampled: `n` points (default STROKE_SAMPLES) centred on\n * (0,0) and scaled so the unit box spans `halfSize` px each way. `curve:\n * 'smooth'` (default) is an open Catmull-Rom through the control points with\n * clamped ends; `'linear'` samples the polyline. Two control points give a\n * straight segment either way.\n */\nexport function strokeSamples(s: StrokeSprite, halfSize: number, n?: number): Array<{ x: number; y: number }> {\n const pts = s.points.map(([x, y]) => ({ x: x * halfSize, y: y * halfSize }));\n const m = pts.length;\n if (m < 2) return pts;\n const smooth = s.curve !== 'linear' && m >= 3;\n const segs = m - 1;\n // Enough samples that every spline segment gets interior points — a\n // 24-point stroke must not collapse to its control polyline.\n n = n ?? Math.max(STROKE_SAMPLES, segs * 6 + 1);\n const at = (k: number): { x: number; y: number } => pts[Math.max(0, Math.min(m - 1, k))]!;\n const out: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < n; i++) {\n const u = (i / (n - 1)) * segs;\n const seg = Math.min(segs - 1, Math.floor(u));\n const local = u - seg;\n const p1 = at(seg);\n const p2 = at(seg + 1);\n if (!smooth) {\n out.push({ x: p1.x + (p2.x - p1.x) * local, y: p1.y + (p2.y - p1.y) * local });\n } else {\n const p0 = at(seg - 1);\n const p3 = at(seg + 2);\n out.push({ x: catmullRom(p0.x, p1.x, p2.x, p3.x, local), y: catmullRom(p0.y, p1.y, p2.y, p3.y, local) });\n }\n }\n return out;\n}\n\n/** Total length of a sampled path, px. */\nexport function pathLength(pts: Array<{ x: number; y: number }>): number {\n let l = 0;\n for (let i = 1; i < pts.length; i++) {\n const dx = pts[i]!.x - pts[i - 1]!.x;\n const dy = pts[i]!.y - pts[i - 1]!.y;\n l += Math.sqrt(dx * dx + dy * dy);\n }\n return l;\n}\n\n/**\n * Taper profile along a stroke, 0..1 of the way along: a brush mark that\n * thins to (almost) nothing at both ends. Floored so a stroke never vanishes\n * mid-mark on a coarse display.\n */\nexport function strokeTaper(u: number): number {\n return Math.max(0.15, Math.sin(Math.PI * Math.max(0, Math.min(1, u))));\n}\n\n/** Stroke width in px for a sprite, with the same default rule as `ring`/`streak`. */\nexport function strokeWidthPx(s: { width?: number }, scale: number): number {\n return Math.max(0.5, (s.width ?? (scale === 1 ? 2 : 0.002)) * scale);\n}\n\n/**\n * Per-step alphas for a feathered rect drawn as `steps` nested fills from the\n * outside in, so the COMPOSITED alpha ramps linearly from 1/steps at the\n * outer edge to 1 at the core. Under source-over each fill sees the ones\n * before it, so step k needs 1/(steps−k+1); under additive blends the fills\n * simply sum, so each contributes 1/steps.\n */\nexport function featherAlphas(steps: number, additive: boolean): number[] {\n const out: number[] = [];\n for (let k = 1; k <= steps; k++) out.push(additive ? 1 / steps : 1 / (steps - k + 1));\n return out;\n}\nexport const FEATHER_STEPS = 6;\n","import type { Rng } from '@idle-screens/core';\nimport type { CycleSpec, LayerSpec, SpriteSpec } from './types';\nimport { LIMITS } from './types';\nimport { isShapedSprite } from './shapes';\n\n/** Near plane for warp motion. z lives in [WARP_NEAR, 1]; screen scale is 1/z. */\nexport const WARP_NEAR = 0.08;\n/** Cap on the 1/z size multiplier so near stars don't blow out. */\nconst WARP_MAX_SCALE = 8;\n\n/** One axis-pair of seeded harmonic octaves for wander motion (amps px, freqs rad/ms). */\nexport interface WanderOsc {\n ax: number[];\n fx: number[];\n phx: number[];\n ay: number[];\n fy: number[];\n phy: number[];\n}\n\n/** A seeded entity: initial state + resolved velocity. `positionAt` is a pure function\n * of this + time, so the rAF loop and renderFrame(t) produce identical results.\n * IMPORTANT (determinism/compat): fields for newer features are OPTIONAL and only\n * set when the feature is declared, so older specs snapshot byte-identically. */\nexport interface Entity {\n x0: number;\n y0: number;\n size: number;\n spriteIndex: number;\n phase: number;\n vx: number; // px/sec\n vy: number; // px/sec\n bob: number; // vertical bob / horizontal sway amplitude (px)\n motion: 'drift' | 'rise' | 'bounce' | 'static' | 'orbit' | 'wander' | 'warp' | 'path';\n headingLeft: boolean;\n alpha: number; // resolved base opacity (default 1)\n pulseAmp: number; // opacity breathing amplitude (0 = none)\n pulsePeriod: number; // ms\n pulsePhase: number;\n spinSpeed: number; // degrees/sec (0 = no rotation)\n spinPhase: number; // seeded starting angle (radians)\n growAmp: number; // size breathing amplitude as fraction (0 = none)\n growPeriod: number; // ms\n growPhase: number;\n orbitR: number; // orbit radius (px, 0 = not orbiting)\n orbitCx: number; // orbit center x (px)\n orbitCy: number; // orbit center y (px)\n colorIndex: number; // index into sprite colors[] (-1 = use sprite.color)\n cyclePeriod: number; // ms (0 = no cycling)\n /** Rect sprite second dimension (height px), or bar thickness. Only set for rect / bar sprites. */\n size2?: number;\n /** Reading-order index into `bar.values`. Only set for bar sprites. */\n barIndex?: number;\n /** Placed by a list/table layout: variants cycle from the ordered base index, in step. Only set for data layouts. */\n ordered?: true;\n /** Orbit parent layer key (motion.center = { layer }). Center resolved at render time. */\n orbitParent?: string;\n /** Present only when the layer explicitly disables edge wrapping. */\n wrapDisabled?: true;\n /** Harmonic drift params. Only set for wander motion. */\n wander?: { own: WanderOsc; shared: WanderOsc; coherence: number; margin: number };\n /** Depth-axis params. Only set for warp motion. */\n warp?: { ux: number; uy: number; z0: number; vz: number; cx: number; cy: number };\n /** Sparse-event window. Only set when `layer.emit` is declared. `phase` ms offset. */\n emit?: { every: number; life: number; phase: number; growFrom: number; growTo: number };\n /** Shared-clock time multiplier for pulse/grow/cycle. Only set when `layer.clock` is declared. */\n clockRate?: number;\n /** Shared cycle phase (radians). Only set when `layer.clock` is declared. */\n cyclePhase?: number;\n /** Velocity easing. Only set when the motion declares `ease`. */\n ease?: { type: 'settle' | 'buoyant'; tau: number };\n /** Spline params (pts in px, shared per layer). Only set for path motion. */\n path?: {\n pts: Array<{ x: number; y: number }>;\n duration: number;\n closed: boolean;\n smooth: boolean;\n phase: number; // 0..1 offset along the path\n offX: number; // per-entity scatter (px)\n offY: number;\n };\n}\n\nexport interface Placed {\n x: number;\n y: number;\n flip: boolean;\n}\n\nexport function spriteVariants(sprite: SpriteSpec): number {\n if (sprite.kind === 'emoji') return sprite.glyphs.length;\n if (sprite.kind === 'text') return sprite.strings.length;\n return 1;\n}\n\nconst OCT_AMP = [1, 0.5, 0.25];\nconst OCT_PERIOD: Array<[number, number]> = [\n [6000, 14000],\n [3000, 7000],\n [1500, 4000],\n];\n\n/** Draw one set of 3 harmonic octaves per axis (18 rng draws). `amp` in px. */\nfunction drawOsc(rng: Rng, amp: number): WanderOsc {\n const osc: WanderOsc = { ax: [], fx: [], phx: [], ay: [], fy: [], phy: [] };\n for (let i = 0; i < 3; i++) {\n osc.ax.push(amp * OCT_AMP[i]! * rng.range(0.6, 1.4));\n osc.fx.push((2 * Math.PI) / rng.range(OCT_PERIOD[i]![0], OCT_PERIOD[i]![1]));\n osc.phx.push(rng.range(0, Math.PI * 2));\n }\n for (let i = 0; i < 3; i++) {\n osc.ay.push(amp * OCT_AMP[i]! * rng.range(0.6, 1.4));\n osc.fy.push((2 * Math.PI) / rng.range(OCT_PERIOD[i]![0], OCT_PERIOD[i]![1]));\n osc.phy.push(rng.range(0, Math.PI * 2));\n }\n return osc;\n}\n\nconst GOLDEN = 0.6180339887498949;\n\n/**\n * Per-entity sparse-event parameters. NO rng draws: the scattered offset is a\n * fixed low-discrepancy (golden-ratio) sequence over the entity index, so\n * declaring `emit` never disturbs this layer's — or any later layer's —\n * seeded stream, and the same spec times its events identically under every\n * seed (event timing is composition, like a grid, not scatter). `jitter`\n * blends an even stagger (entity i at i/n of the period — a metronome) with\n * that scattered offset.\n */\nfunction emitParams(\n emit: NonNullable<LayerSpec['emit']>,\n i: number,\n n: number,\n): NonNullable<Entity['emit']> {\n const every = emit.every;\n const jitter = Math.max(0, Math.min(1, emit.jitter ?? 1));\n const scattered = (((i + 0.5) * GOLDEN) % 1) * every;\n const even = (i / Math.max(1, n)) * every;\n const phase = ((even * (1 - jitter) + scattered * jitter) % every + every) % every;\n return {\n every,\n life: Math.min(emit.life, every),\n phase,\n growFrom: emit.grow?.[0] ?? 1,\n growTo: emit.grow?.[1] ?? 1,\n };\n}\n\n/** Weighted index pick from a single uniform draw. Weights are validated positive. */\nfunction weightedIndex(u: number, weights: number[]): number {\n const total = weights.reduce((a, b) => a + b, 0);\n let acc = 0;\n for (let i = 0; i < weights.length; i++) {\n acc += weights[i]! / total;\n if (u < acc) return i;\n }\n return weights.length - 1;\n}\n\n/** Deterministically place a layer's entities using the seeded RNG (never Math.random).\n * `scale` multiplies every dimensional draw (default 1). Used for viewport units.\n * `countScale` multiplies entity count for density-aware scaling (default 1). */\nexport function buildEntities(layer: LayerSpec, rng: Rng, w: number, h: number, scale = 1, countScale = 1): Entity[] {\n // Grid layers are EXEMPT from count scaling. A grid is an exact lattice —\n // columns × rows, authored cell by cell — and scaling its count doesn't thin\n // it like a scatter field, it TRUNCATES it row-major: the last cells simply\n // never spawn. Found live (Entablature, 2026-08-14): on a viewport at\n // countScale ≈ 0.67, an 18-column single-row grid rendered 12 cells and died\n // at two-thirds width, while the analytic perception path (countScale 1)\n // showed it full-width — a renderer-vs-perception split that burned four\n // publishes to isolate. Upscaling is equally wrong: it invents phantom cells\n // beyond the authored lattice. Grid cost is already bounded by maxPerLayer.\n const effectiveCount = countScale === 1 || layer.layout !== undefined\n ? layer.count\n : Math.max(1, Math.min(\n Math.round(layer.count * countScale),\n layer.links ? LIMITS.maxLinkLayerCount : LIMITS.maxPerLayer,\n ));\n // Defaults are authored as their 1080p-equivalent viewport fractions. Using\n // the legacy px defaults directly would multiply 20..40 by the viewport.\n const defaultSize = scale === 1\n ? [20, 40] as const\n : [20 / LIMITS.referenceViewport, 40 / LIMITS.referenceViewport] as const;\n const [smin, smax] = layer.size ?? defaultSize;\n const variants = spriteVariants(layer.sprite);\n const sprite = layer.sprite;\n const spriteColors = isShapedSprite(sprite) ? sprite.colors : undefined;\n const colorWeights = isShapedSprite(sprite) ? sprite.colorWeights : undefined;\n const colorsLen = spriteColors?.length ?? 0;\n const cycle: CycleSpec | undefined = (sprite.kind === 'emoji' || sprite.kind === 'text') ? sprite.cycle : undefined;\n\n // Layer-level draws for new motion types happen BEFORE the entity loop, guarded by\n // the motion type so pre-existing specs keep bit-identical entity streams.\n const mSpec = layer.motion;\n let sharedOsc: WanderOsc | null = null;\n let meanderPx = 0;\n if (mSpec.type === 'wander') {\n meanderPx = (mSpec.meander ?? (scale === 1 ? 60 : 0.05)) * scale;\n sharedOsc = drawOsc(rng, meanderPx);\n }\n let pathPts: Array<{ x: number; y: number }> | null = null;\n if (mSpec.type === 'path') {\n pathPts = mSpec.points.map((p) => ({ x: p.x * w, y: p.y * h }));\n }\n const ease = (mSpec.type === 'drift' || mSpec.type === 'rise' || mSpec.type === 'wander') ? mSpec.ease : undefined;\n const clockPhase = layer.clock ? ((layer.clock.phase ?? 0) % 1) * Math.PI * 2 : 0;\n\n // Grid layout geometry (pure — no draws).\n const layout = layer.layout;\n // Data layouts (list / table): reading order from an anchor, no scatter.\n const ordered = layout?.type === 'list' || layout?.type === 'table';\n let gapX = 0;\n let gapY = 0;\n let listX0 = 0;\n let listY0 = 0;\n let listCols = 1;\n if (layout?.type === 'list' || layout?.type === 'table') {\n const dflt = scale === 1 ? LIMITS.defaultListGapPx : LIMITS.defaultListGap;\n const g = layout.gap ?? dflt;\n gapX = (typeof g === 'number' ? g : g.x ?? dflt) * scale;\n gapY = (typeof g === 'number' ? g : g.y ?? dflt) * scale;\n listCols = layout.type === 'list' ? 1 : Math.max(1, Math.round(layout.columns));\n const rows = Math.max(1, Math.ceil(effectiveCount / listCols));\n if (layer.position) {\n listX0 = layer.position.x * w;\n listY0 = layer.position.y * h;\n } else {\n const [rx0, rx1] = layer.region?.x ?? [0, 1];\n const [ry0, ry1] = layer.region?.y ?? [0, 1];\n listX0 = ((rx0 + rx1) / 2) * w - ((listCols - 1) * gapX) / 2;\n listY0 = ((ry0 + ry1) / 2) * h - ((rows - 1) * gapY) / 2;\n }\n }\n let gridCols = 0;\n let cellW = 0;\n let cellH = 0;\n let gridX0 = 0;\n let gridY0 = 0;\n if (layout?.type === 'grid') {\n const [rx0, rx1] = layer.region?.x ?? [0, 1];\n const [ry0, ry1] = layer.region?.y ?? [0, 1];\n const gw = Math.max(1, (rx1 - rx0) * w);\n const gh = Math.max(1, (ry1 - ry0) * h);\n gridCols = Math.min(\n layout.columns ?? Math.max(1, Math.round(Math.sqrt(effectiveCount * (gw / gh)))),\n LIMITS.maxGridColumns,\n );\n const gridRows = Math.max(1, Math.ceil(effectiveCount / gridCols));\n cellW = gw / gridCols;\n cellH = gh / gridRows;\n gridX0 = rx0 * w;\n gridY0 = ry0 * h;\n }\n\n const out: Entity[] = [];\n for (let i = 0; i < effectiveCount; i++) {\n const size =\n sprite.kind === 'textBlock'\n ? sprite.fontSize * scale\n : sprite.kind === 'circle' || sprite.kind === 'ring' || sprite.kind === 'polygon'\n ? rng.range(sprite.radius[0], sprite.radius[1]) * 2 * scale\n : sprite.kind === 'streak' || sprite.kind === 'stroke'\n ? rng.range(sprite.length[0], sprite.length[1]) * scale\n : sprite.kind === 'rect'\n ? rng.range(sprite.width[0], sprite.width[1]) * scale\n : sprite.kind === 'bar'\n ? sprite.length * scale\n : rng.range(smin, smax) * scale;\n // Guarded extra draw: only rect sprites with an aspect range consume it.\n const size2 = sprite.kind === 'rect'\n ? size * (sprite.aspect ? rng.range(sprite.aspect[0], sprite.aspect[1]) : 1)\n : sprite.kind === 'bar'\n ? sprite.thickness * scale\n : undefined;\n\n let vx = 0;\n let vy = 0;\n let bob = 0;\n let motion: Entity['motion'] = 'drift';\n let warpParams: Entity['warp'];\n let pathPhase = 0;\n let pathOffX = 0;\n let pathOffY = 0;\n const m = layer.motion;\n if (m.type === 'static') {\n motion = 'static';\n } else if (m.type === 'drift') {\n const s = rng.range(m.speed[0], m.speed[1]) * scale;\n let angle = ((m.angle ?? 0) * Math.PI) / 180;\n if (m.bidirectional && rng.next() < 0.5) angle = Math.PI - angle;\n vx = s * Math.cos(angle);\n vy = s * Math.sin(angle);\n bob = (m.bob ?? 0) * scale;\n } else if (m.type === 'rise') {\n motion = 'rise';\n vy = -rng.range(m.speed[0], m.speed[1]) * scale; // upward\n bob = (m.sway ?? 0) * scale;\n } else if (m.type === 'bounce') {\n motion = 'bounce';\n const s = rng.range(m.speed[0], m.speed[1]) * scale;\n const a = rng.range(0, Math.PI * 2);\n vx = s * Math.cos(a);\n vy = s * Math.sin(a);\n } else if (m.type === 'orbit') {\n motion = 'orbit';\n vx = rng.range(m.speed[0], m.speed[1]); // angular speed in deg/sec, stored in vx (not scaled)\n } else if (m.type === 'wander') {\n motion = 'wander';\n const s = rng.range(m.speed[0], m.speed[1]) * scale;\n const heading = m.angle !== undefined ? (m.angle * Math.PI) / 180 : rng.range(0, Math.PI * 2);\n vx = s * Math.cos(heading);\n vy = s * Math.sin(heading);\n } else if (m.type === 'warp') {\n motion = 'warp';\n const vz = rng.range(m.speed[0], m.speed[1]); // depth-units/sec (not scaled)\n const theta = rng.range(0, Math.PI * 2);\n const r = rng.range(0.15, 1); // radial offset in the projection plane\n warpParams = {\n ux: Math.cos(theta) * r,\n uy: Math.sin(theta) * r,\n z0: rng.range(WARP_NEAR, 1),\n vz,\n cx: (m.center?.x ?? 0.5) * w,\n cy: (m.center?.y ?? 0.5) * h,\n };\n } else if (m.type === 'path') {\n motion = 'path';\n pathPhase = rng.next();\n if (m.scatter) {\n pathOffX = rng.range(-1, 1) * m.scatter * scale;\n pathOffY = rng.range(-1, 1) * m.scatter * scale;\n }\n }\n\n let x0: number;\n let y0: number;\n if (layer.position && layer.count === 1) {\n x0 = layer.position.x * w;\n y0 = layer.position.y * h;\n } else if (layout?.type === 'list' || layout?.type === 'table') {\n // Reading order from the anchor. Burn the two scatter draws so toggling a\n // data layout on or off leaves the rest of this layer's stream intact.\n rng.next();\n rng.next();\n x0 = listX0 + (i % listCols) * gapX;\n y0 = listY0 + Math.floor(i / listCols) * gapY;\n } else if (layout?.type === 'grid') {\n // Grid cells row-major; same 2-draw budget as scatter so toggling layout\n // shifts only THIS layer's stream (layout is structural — rebuild anyway).\n const col = i % gridCols;\n const row = Math.floor(i / gridCols);\n const j = layout.jitter ?? 0;\n const jx = typeof j === 'number' ? j : j.x ?? 0;\n const jy = typeof j === 'number' ? j : j.y ?? 0;\n x0 = gridX0 + (col + 0.5) * cellW + rng.range(-0.5, 0.5) * jx * cellW;\n y0 = gridY0 + (row + 0.5) * cellH + rng.range(-0.5, 0.5) * jy * cellH;\n } else {\n // Spawn window defaults to the full viewport. IMPORTANT (determinism/compat):\n // optional features must only consume EXTRA rng draws when declared, so specs\n // written before a feature existed keep bit-identical entity streams.\n const [rx0, rx1] = layer.region?.x ?? [0, 1];\n const [ry0, ry1] = layer.region?.y ?? [0, 1];\n x0 = rng.range(rx0 * w, rx1 * w);\n y0 = rng.range(ry0 * h, ry1 * h);\n }\n\n const orbitParent = m.type === 'orbit' && m.center && 'layer' in m.center ? m.center.layer : undefined;\n\n out.push({\n x0,\n y0,\n size,\n // Data layouts read variants in order — strings[i] beside bar i. The\n // seeded draw is still consumed so a layout is placement only: toggling\n // list/table never disturbs the layer's alpha, pulse or spin stream.\n spriteIndex: variants > 1 ? (ordered ? (rng.int(0, variants - 1), i % variants) : rng.int(0, variants - 1)) : 0,\n phase: rng.range(0, Math.PI * 2),\n vx,\n vy,\n bob,\n motion,\n headingLeft: vx < 0,\n alpha: layer.alpha ? rng.range(layer.alpha[0], layer.alpha[1]) : 1,\n pulseAmp: layer.pulse?.amp ?? 0,\n pulsePeriod: layer.pulse?.period ?? 1000,\n pulsePhase: layer.pulse ? rng.range(0, Math.PI * 2) : 0,\n // New draws AFTER pulsePhase — guarded so existing specs keep identical streams.\n // Scalar spin: no draw here, one phase draw below (unchanged). Range spin\n // (new): one seeded speed draw here, then the phase draw — array form is new\n // so the extra draw can't perturb any existing spec's entity stream.\n spinSpeed:\n typeof layer.spin === 'number'\n ? (layer.spin * Math.PI) / 180 // deg/sec → rad/sec\n : Array.isArray(layer.spin)\n ? (rng.range(layer.spin[0], layer.spin[1]) * Math.PI) / 180\n : 0,\n spinPhase: layer.spin ? rng.range(0, Math.PI * 2) : 0,\n growAmp: layer.grow?.amp ?? 0,\n growPeriod: layer.grow?.period ?? 1000,\n growPhase: layer.grow ? rng.range(0, Math.PI * 2) : 0,\n orbitR: m.type === 'orbit' ? rng.range(m.radius[0], m.radius[1]) * scale : 0,\n orbitCx: m.type === 'orbit' && !orbitParent ? ((m.center as { x?: number } | undefined)?.x ?? 0.5) * w : 0,\n orbitCy: m.type === 'orbit' && !orbitParent ? ((m.center as { y?: number } | undefined)?.y ?? 0.5) * h : 0,\n // New draws AFTER orbit — guarded so existing specs keep identical streams.\n colorIndex: colorsLen > 0\n ? (colorWeights && colorWeights.length === colorsLen\n ? weightedIndex(rng.next(), colorWeights)\n : ordered\n ? (rng.int(0, colorsLen - 1), i % colorsLen) // data layouts: palette in reading order; draw burned for stream parity\n : rng.int(0, colorsLen - 1))\n : -1,\n cyclePeriod: cycle ? cycle.period : 0,\n // Optional feature fields last (guarded draws inside — wander draws 18 here).\n ...(size2 !== undefined ? { size2 } : {}),\n ...(sprite.kind === 'bar' ? { barIndex: i } : {}),\n ...(ordered ? { ordered: true as const } : {}),\n ...(orbitParent ? { orbitParent } : {}),\n ...(layer.wrap === false ? { wrapDisabled: true as const } : {}),\n ...(m.type === 'wander'\n ? {\n wander: {\n own: drawOsc(rng, meanderPx),\n shared: sharedOsc!,\n coherence: Math.max(0, Math.min(1, m.coherence ?? 0)),\n margin: meanderPx * (OCT_AMP[0]! + OCT_AMP[1]! + OCT_AMP[2]!) * 1.4,\n },\n }\n : {}),\n ...(warpParams ? { warp: warpParams } : {}),\n ...(m.type === 'path' && pathPts\n ? {\n path: {\n pts: pathPts,\n duration: m.duration,\n closed: m.closed !== false,\n smooth: m.curve !== 'linear',\n phase: pathPhase,\n offX: pathOffX,\n offY: pathOffY,\n },\n }\n : {}),\n // Time-structure fields (2026-09): ease draws nothing; emit's one draw\n // per entity happens in a pass AFTER this loop (see below).\n ...(ease ? { ease: { type: ease.type, tau: ease.tau } } : {}),\n });\n\n if (layer.clock) {\n // Phase-lock: the seeded pulse/grow phases were drawn above (stream\n // stays put); the shared phase replaces them here. Cycle gets its own\n // field — `phase` also drives bob/sway/orbit, which must stay per-entity.\n const ent = out[out.length - 1]!;\n ent.pulsePhase = clockPhase;\n ent.growPhase = clockPhase;\n ent.cyclePhase = clockPhase;\n ent.clockRate = layer.clock.rate ?? 1;\n }\n if (layer.pulse?.wave) {\n // Position-derived phase: sin(ωt + phase) becomes a traveling wave along\n // `angle`. Patched AFTER the push so the seeded pulsePhase draw stays in its\n // historical stream position (toggling wave must not shift other draws).\n // A clock's phase offsets the wave rather than flattening it.\n const wl = Math.max(1e-6, layer.pulse.wave.wavelength * scale);\n const ang = ((layer.pulse.wave.angle ?? 0) * Math.PI) / 180;\n out[out.length - 1]!.pulsePhase = clockPhase - ((x0 * Math.cos(ang) + y0 * Math.sin(ang)) / wl) * Math.PI * 2;\n }\n }\n if (layer.emit) {\n // Assigned after the loop and without any rng draw (see emitParams), so\n // toggling `emit` rearranges nothing — not this layer, not the ones after.\n for (let i = 0; i < out.length; i++) out[i]!.emit = emitParams(layer.emit, i, out.length);\n }\n return out;\n}\n\n/** Depth of a warp entity at time t: wraps from far (1) to near (WARP_NEAR). Pure. */\nfunction warpZ(e: Entity, t: number): number {\n const wp = e.warp!;\n return wrap(wp.z0 - wp.vz * (t / 1000), WARP_NEAR, 1);\n}\n\nfunction smoothstep(x: number): number {\n const c = x < 0 ? 0 : x > 1 ? 1 : x;\n return c * c * (3 - 2 * c);\n}\n\n/** Fraction of an emit window spent fading in; the rest fades out. */\nconst EMIT_ATTACK = 0.25;\n\n/**\n * Where entity `e` sits in its current emit window at time `t`: 0..1 across\n * the visible `life` ms, or null while dark (or when the layer has no `emit`).\n * Pure — the window index is `floor((t - phase) / every)`, no state.\n */\nexport function emitWindow(e: Entity, t: number): number | null {\n const em = e.emit;\n if (!em) return null;\n const local = (((t - em.phase) % em.every) + em.every) % em.every;\n return local < em.life ? local / em.life : null;\n}\n\n/** Alpha envelope across an emit window: fast smooth attack, slow smooth decay. */\nexport function emitEnvelope(u: number): number {\n if (u < 0 || u >= 1) return 0;\n return u < EMIT_ATTACK ? smoothstep(u / EMIT_ATTACK) : 1 - smoothstep((u - EMIT_ATTACK) / (1 - EMIT_ATTACK));\n}\n\n/** Scene time as the layer's clock sees it (pulse/grow/cycle only). */\nfunction clockTime(e: Entity, t: number): number {\n return e.clockRate ? t * e.clockRate : t;\n}\n\n/**\n * Seconds of travel at time `t` for the velocity-integral motions. Identity\n * without `ease`. `settle`: τ(1 − e^(−t/τ)) — decelerates to rest having\n * travelled speed·τ. `buoyant`: t − τ(1 − e^(−t/τ)) — from rest to terminal\n * speed. With `emit`, t is window-local so every event restarts the travel.\n */\nfunction motionSeconds(e: Entity, t: number): number {\n if (!e.ease) return t / 1000;\n let tl = t;\n if (e.emit) tl = (((t - e.emit.phase) % e.emit.every) + e.emit.every) % e.emit.every;\n const tau = e.ease.tau;\n const k = 1 - Math.exp(-tl / tau);\n return (e.ease.type === 'settle' ? tau * k : tl - tau * k) / 1000;\n}\n\n/** Analytic opacity of an entity at logical time `t` (ms). Pure, clamped to 0..1. */\nexport function alphaAt(e: Entity, t: number): number {\n let a = e.alpha;\n if (e.pulseAmp) a = e.alpha + e.pulseAmp * Math.sin((clockTime(e, t) * 2 * Math.PI) / e.pulsePeriod + e.pulsePhase);\n if (e.motion === 'warp') {\n // Fade in over the first 20% of depth after respawning at the far plane,\n // masking the wrap pop-in.\n const z = warpZ(e, t);\n a *= Math.max(0, Math.min(1, (1 - z) / 0.2));\n }\n if (e.emit) {\n const u = emitWindow(e, t);\n a = u === null ? 0 : a * emitEnvelope(u);\n }\n return a < 0 ? 0 : a > 1 ? 1 : a;\n}\n\n/** Analytic size multiplier at time `t` (ms). Pure, clamped to > 0. */\nexport function sizeAt(e: Entity, t: number): number {\n let s = e.size;\n if (e.growAmp) s = e.size * (1 + e.growAmp * Math.sin((clockTime(e, t) * 2 * Math.PI) / e.growPeriod + e.growPhase));\n if (e.motion === 'warp') s *= Math.min(1 / warpZ(e, t), WARP_MAX_SCALE);\n if (e.emit && (e.emit.growFrom !== 1 || e.emit.growTo !== 1)) {\n const u = emitWindow(e, t);\n if (u !== null) s *= e.emit.growFrom + (e.emit.growTo - e.emit.growFrom) * u;\n }\n return s > 0 ? s : 0.1;\n}\n\n/** Analytic rotation angle at time `t` (ms) in radians. Pure. */\nexport function rotationAt(e: Entity, t: number): number {\n if (!e.spinSpeed) return 0;\n return e.spinPhase + e.spinSpeed * (t / 1000);\n}\n\n/** Layer lifecycle alpha multiplier at time `t` (ms). Pure. 1 when `life` is unset. */\nexport function lifeAlphaAt(life: { enter?: number; exit?: number; fade?: number } | undefined, t: number): number {\n if (!life) return 1;\n const fade = life.fade ?? 1000;\n let a = 1;\n if (life.enter !== undefined) {\n if (t < life.enter) return 0;\n a = fade > 0 ? Math.min(1, (t - life.enter) / fade) : 1;\n }\n if (life.exit !== undefined && t >= life.exit) {\n a *= fade > 0 ? Math.max(0, 1 - (t - life.exit) / fade) : 0;\n }\n return a;\n}\n\nfunction wrap(v: number, min: number, max: number): number {\n const range = max - min;\n return ((((v - min) % range) + range) % range) + min;\n}\n\nfunction reflect(v: number, min: number, max: number): number {\n const range = max - min;\n if (range <= 0) return min;\n const period = 2 * range;\n const p = (((v - min) % period) + period) % period;\n return min + (p < range ? p : period - p);\n}\n\nfunction catmullRom(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const u2 = u * u;\n const u3 = u2 * u;\n return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);\n}\n\nfunction pathPosition(e: Entity, t: number): { x: number; y: number } {\n const p = e.path!;\n const n = p.pts.length;\n let s = ((t / p.duration) + p.phase) % 1;\n if (s < 0) s += 1;\n if (!p.closed) {\n // Ping-pong so open paths reverse smoothly instead of teleporting.\n const pp = s * 2;\n s = pp < 1 ? pp : 2 - pp;\n }\n const segs = p.closed ? n : n - 1;\n const u = Math.min(s * segs, segs - 1e-9);\n const i = Math.floor(u);\n const local = u - i;\n const at = (k: number): { x: number; y: number } =>\n p.closed ? p.pts[((k % n) + n) % n]! : p.pts[Math.max(0, Math.min(n - 1, k))]!;\n const p1 = at(i);\n const p2 = at(i + 1);\n if (!p.smooth) {\n return {\n x: p1.x + (p2.x - p1.x) * local + p.offX,\n y: p1.y + (p2.y - p1.y) * local + p.offY,\n };\n }\n const p0 = at(i - 1);\n const p3 = at(i + 2);\n return {\n x: catmullRom(p0.x, p1.x, p2.x, p3.x, local) + p.offX,\n y: catmullRom(p0.y, p1.y, p2.y, p3.y, local) + p.offY,\n };\n}\n\n/** Analytic position of an entity at logical time `t` (ms). Pure & deterministic. */\nexport function positionAt(e: Entity, t: number, w: number, h: number): Placed {\n if (e.motion === 'static') return { x: e.x0, y: e.y0, flip: false };\n if (e.motion === 'orbit') {\n const angle = e.phase + (e.vx * Math.PI / 180) * (t / 1000);\n return {\n x: e.orbitCx + e.orbitR * Math.cos(angle),\n y: e.orbitCy + e.orbitR * Math.sin(angle),\n flip: false,\n };\n }\n if (e.motion === 'warp') {\n const wp = e.warp!;\n const persp = 1 / warpZ(e, t);\n const halfMin = Math.min(w, h) / 2;\n return {\n x: wp.cx + wp.ux * halfMin * persp,\n y: wp.cy + wp.uy * halfMin * persp,\n flip: false,\n };\n }\n if (e.motion === 'path') {\n const pos = pathPosition(e, t);\n return { x: pos.x, y: pos.y, flip: false };\n }\n const dt = motionSeconds(e, t);\n const m = e.size;\n if (e.motion === 'bounce') {\n return {\n x: reflect(e.x0 + e.vx * dt, m / 2, w - m / 2),\n y: reflect(e.y0 + e.vy * dt, m / 2, h - m / 2),\n flip: false,\n };\n }\n if (e.motion === 'rise') {\n const y = e.y0 + e.vy * dt;\n return {\n x: e.x0 + (e.bob ? e.bob * Math.sin(t / 700 + e.phase) : 0),\n y: e.wrapDisabled ? y : wrap(y, -m, h + m),\n flip: false,\n };\n }\n if (e.motion === 'wander') {\n const wp = e.wander!;\n const c = wp.coherence;\n let hx = 0;\n let hy = 0;\n for (let i = 0; i < 3; i++) {\n if (c < 1) {\n hx += (1 - c) * wp.own.ax[i]! * Math.sin(wp.own.fx[i]! * t + wp.own.phx[i]!);\n hy += (1 - c) * wp.own.ay[i]! * Math.sin(wp.own.fy[i]! * t + wp.own.phy[i]!);\n }\n if (c > 0) {\n hx += c * wp.shared.ax[i]! * Math.sin(wp.shared.fx[i]! * t + wp.shared.phx[i]!);\n hy += c * wp.shared.ay[i]! * Math.sin(wp.shared.fy[i]! * t + wp.shared.phy[i]!);\n }\n }\n const margin = m + wp.margin;\n const x = e.x0 + e.vx * dt + hx;\n const y = e.y0 + e.vy * dt + hy;\n return {\n x: e.wrapDisabled ? x : wrap(x, -margin, w + margin),\n y: e.wrapDisabled ? y : wrap(y, -margin, h + margin),\n flip: e.headingLeft,\n };\n }\n // drift\n const rawX = e.x0 + e.vx * dt;\n const x = e.wrapDisabled ? rawX : wrap(rawX, -m, w + m);\n const rawY = e.y0 + e.vy * dt;\n let y = e.vy !== 0 && !e.wrapDisabled ? wrap(rawY, -m, h + m) : rawY;\n if (e.bob) y += e.bob * Math.sin(t / 500 + e.phase);\n return { x, y, flip: e.headingLeft };\n}\n\n/**\n * Analytic heading (radians) at time `t`, from a finite difference of positionAt.\n * Used to orient streak sprites. Returns null across a wrap seam (position jump\n * larger than half the viewport) — callers should skip orientation that frame.\n */\nexport function headingAt(e: Entity, t: number, w: number, h: number): number | null {\n const dtMs = 32;\n const t1 = t < dtMs ? t + dtMs : t;\n const t0 = t1 - dtMs;\n const a = positionAt(e, t0, w, h);\n const b = positionAt(e, t1, w, h);\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) return null;\n if (dx === 0 && dy === 0) return null;\n return Math.atan2(dy, dx);\n}\n\n/** Time-varying sprite index for text/emoji cycling. Returns static index when cyclePeriod is 0. */\nexport function spriteIndexAt(e: Entity, t: number, variants: number): number {\n if (!e.cyclePeriod || variants <= 1) return e.spriteIndex;\n // Under a data layout the rows keep their reading order and advance in\n // step — a marquee — instead of each entity cycling from its own phase.\n if (e.ordered) return (e.spriteIndex + Math.floor(clockTime(e, t) / e.cyclePeriod)) % variants;\n return Math.floor(clockTime(e, t) / e.cyclePeriod + (e.cyclePhase ?? e.phase) / (2 * Math.PI)) % variants;\n}\n\n/** An inter-entity link edge with its (wrap-aware) distance, for falloff alpha. */\nexport interface LinkEdge {\n i: number;\n j: number;\n dist: number;\n}\n\nfunction wrapDist(\n pi: { x: number; y: number },\n pj: { x: number; y: number },\n doWrap: boolean,\n w: number,\n h: number,\n): number {\n let dx = pj.x - pi.x;\n let dy = pj.y - pi.y;\n if (doWrap) {\n if (Math.abs(dx) > w / 2) dx = dx > 0 ? dx - w : dx + w;\n if (Math.abs(dy) > h / 2) dy = dy > 0 ? dy - h : dy + h;\n }\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * Edge list for a layer's `links`, dispatching on mode:\n * 'nearest' (default) k-nearest within maxDist; 'chain' sequential order\n * (Mystify — ignores k/maxDist, `closed` joins last to first); 'random' a fixed\n * golden-ratio-stride wiring filtered by maxDist (deterministic, no RNG draws).\n */\nexport function linkEdges(\n links: { k: number; maxDist: number; mode?: 'nearest' | 'chain' | 'random'; closed?: boolean },\n positions: Array<{ x: number; y: number }>,\n maxDistPx: number,\n doWrap: boolean,\n w: number,\n h: number,\n): LinkEdge[] {\n const n = positions.length;\n const mode = links.mode ?? 'nearest';\n if (mode === 'chain') {\n const out: LinkEdge[] = [];\n for (let i = 0; i < n - 1; i++) {\n out.push({ i, j: i + 1, dist: wrapDist(positions[i]!, positions[i + 1]!, doWrap, w, h) });\n }\n if (links.closed && n > 2) out.push({ i: n - 1, j: 0, dist: wrapDist(positions[n - 1]!, positions[0]!, doWrap, w, h) });\n return out;\n }\n if (mode === 'random') {\n const stride = Math.max(1, Math.round(n * 0.381966)); // golden-ratio conjugate — spreads partners\n const edges = new Set<string>();\n const out: LinkEdge[] = [];\n for (let i = 0; i < n; i++) {\n for (let mIdx = 1; mIdx <= links.k; mIdx++) {\n const j = (i + mIdx * stride) % n;\n if (j === i) continue;\n const dist = wrapDist(positions[i]!, positions[j]!, doWrap, w, h);\n if (dist > maxDistPx) continue;\n const key = `${Math.min(i, j)}:${Math.max(i, j)}`;\n if (!edges.has(key)) {\n edges.add(key);\n out.push({ i: Math.min(i, j), j: Math.max(i, j), dist });\n }\n }\n }\n return out;\n }\n return linkPairs(positions, links.k, maxDistPx, doWrap, w, h).map(([i, j]) => ({\n i,\n j,\n dist: wrapDist(positions[i]!, positions[j]!, doWrap, w, h),\n }));\n}\n\n/** K-nearest-neighbor edge list. Deterministic tie-break: (dist, index).\n * When `doWrap` is true, uses toroidal distance so links don't streak across wrap seams. */\nexport function linkPairs(\n positions: Array<{ x: number; y: number }>,\n k: number,\n maxDist: number,\n doWrap: boolean,\n w: number,\n h: number,\n): Array<[number, number]> {\n const n = positions.length;\n const edges = new Set<string>();\n const out: Array<[number, number]> = [];\n\n for (let i = 0; i < n; i++) {\n const pi = positions[i]!;\n const neighbors: Array<{ dist: number; j: number }> = [];\n for (let j = 0; j < n; j++) {\n if (i === j) continue;\n const pj = positions[j]!;\n let dx = pj.x - pi.x;\n let dy = pj.y - pi.y;\n if (doWrap) {\n if (Math.abs(dx) > w / 2) dx = dx > 0 ? dx - w : dx + w;\n if (Math.abs(dy) > h / 2) dy = dy > 0 ? dy - h : dy + h;\n }\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist <= maxDist) neighbors.push({ dist, j });\n }\n neighbors.sort((a, b) => a.dist - b.dist || a.j - b.j);\n for (let ni = 0; ni < Math.min(k, neighbors.length); ni++) {\n const j = neighbors[ni]!.j;\n const lo = Math.min(i, j);\n const hi = Math.max(i, j);\n const key = `${lo}:${hi}`;\n if (!edges.has(key)) {\n edges.add(key);\n out.push([lo, hi]);\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Deterministic text-block line breaking\n// ---------------------------------------------------------------------------\n\nconst CHAR_NARROW = new Set('iIljtf1!|.,;:\\'\"()[]{}');\nconst CHAR_WIDE = new Set('mwMWGOQD@%');\n\n/**\n * Approximate glyph width as a fraction of em. Uses character-class buckets\n * so line breaks are identical across platforms (no measureText). The average\n * across Latin text lands near 0.55, close to perceive.ts's 0.62 heuristic\n * but with per-class refinement.\n */\nfunction charWidthEm(ch: string): number {\n if (ch === ' ' || ch === '\\t') return 0.3;\n if (CHAR_NARROW.has(ch)) return 0.35;\n if (CHAR_WIDE.has(ch)) return 0.72;\n return 0.55;\n}\n\n/** Em-width of a string under the same character-class table `breakTextBlock` uses. */\nexport function textWidthEm(str: string): number {\n let w = 0;\n for (let i = 0; i < str.length; i++) w += charWidthEm(str[i]!);\n return w;\n}\n\nexport interface TextBlockLine {\n text: string;\n widthEm: number;\n}\n\n/**\n * Break `text` into lines that fit within `maxWidthEm` em-widths. Splits on\n * whitespace; a single word wider than the limit gets its own line unbroken.\n * Explicit `\\n` always forces a break. Pure, deterministic, no canvas needed.\n */\nexport function breakTextBlock(text: string, maxWidthEm: number): TextBlockLine[] {\n const paragraphs = text.split('\\n');\n const lines: TextBlockLine[] = [];\n\n for (const para of paragraphs) {\n if (para.length === 0) {\n lines.push({ text: '', widthEm: 0 });\n continue;\n }\n const words = para.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 0) {\n lines.push({ text: '', widthEm: 0 });\n continue;\n }\n\n let lineText = words[0]!;\n let lineW = textWidthEm(lineText);\n const spaceW = charWidthEm(' ');\n\n for (let i = 1; i < words.length; i++) {\n const word = words[i]!;\n const wordW = textWidthEm(word);\n if (lineW + spaceW + wordW <= maxWidthEm) {\n lineText += ' ' + word;\n lineW += spaceW + wordW;\n } else {\n lines.push({ text: lineText, widthEm: lineW });\n lineText = word;\n lineW = wordW;\n }\n }\n lines.push({ text: lineText, widthEm: lineW });\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// Deterministic text reveal (textBlock `reveal` — typing/deleting)\n// ---------------------------------------------------------------------------\n\n// Combining/attaching code points that must never be painted without their\n// base: combining diacritics, variation selectors, skin-tone modifiers,\n// keycap. Deliberately a fixed table rather than Intl.Segmenter, which is\n// not required to segment identically across engines — same philosophy (and\n// same determinism reason) as the charWidthEm buckets above.\nfunction isClusterExtend(cp: number): boolean {\n return (\n (cp >= 0x0300 && cp <= 0x036f) || // combining diacritics\n (cp >= 0x1ab0 && cp <= 0x1aff) ||\n (cp >= 0x20d0 && cp <= 0x20ff) ||\n (cp >= 0xfe00 && cp <= 0xfe0f) || // variation selectors\n (cp >= 0x1f3fb && cp <= 0x1f3ff) || // skin tones\n cp === 0x20e3 // combining enclosing keycap\n );\n}\n\nfunction isRegionalIndicator(cp: number): boolean {\n return cp >= 0x1f1e6 && cp <= 0x1f1ff;\n}\n\nconst ZWJ = 0x200d;\n\n/**\n * Split a string into paint-safe grapheme clusters: surrogate pairs stay\n * whole, combining marks / variation selectors / skin tones attach to their\n * base, ZWJ joins sequences (emoji families), regional indicators pair up\n * (flags). Deterministic across engines by construction.\n */\nexport function graphemeClusters(text: string): string[] {\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n const cp = text.codePointAt(i)!;\n let end = i + (cp > 0xffff ? 2 : 1);\n // Flag pair: two regional indicators form one cluster.\n if (isRegionalIndicator(cp) && end < text.length) {\n const next = text.codePointAt(end)!;\n if (isRegionalIndicator(next)) end += next > 0xffff ? 2 : 1;\n }\n // Attach extenders and ZWJ-joined sequences.\n while (end < text.length) {\n const next = text.codePointAt(end)!;\n if (isClusterExtend(next)) {\n end += next > 0xffff ? 2 : 1;\n } else if (next === ZWJ && end + 1 < text.length) {\n const after = text.codePointAt(end + 1)!;\n end += 1 + (after > 0xffff ? 2 : 1);\n } else {\n break;\n }\n }\n out.push(text.slice(i, end));\n i = end;\n }\n return out;\n}\n\nexport interface TextRevealInput {\n progress?: number;\n mode?: 'typewriter' | 'word' | 'line' | 'glyphFade';\n speed?: number;\n fade?: number;\n}\n\nexport interface RevealState {\n /** Effective 0..1 progress after combining authored progress and speed at t. */\n progress: number;\n /** Number of fully visible lines. */\n fullLines: number;\n /** Grapheme-safe visible prefix of the next line ('' when none). */\n partialText: string;\n /** Caret anchor: line index and the visible prefix on that line. */\n caretLine: number;\n caretPrefix: string;\n /**\n * `glyphFade` mode only: per-line per-grapheme alpha (0..1), indexed\n * parallel to `graphemeClusters(lines[i].text)`. Alphas only decrease in\n * reading order, so a renderer may stop at the first zero.\n */\n glyphAlphas?: number[][];\n}\n\n/**\n * Resolve which glyphs of a broken textBlock are visible at time `tMs`.\n * Pure function of (lines, reveal, tMs) — the renderer paints exactly this,\n * and perceive models exactly this, so agents and pixels agree. `speed` is\n * graphemes/sec regardless of mode; mode only quantizes the frontier.\n */\nexport function revealState(lines: TextBlockLine[], reveal: TextRevealInput, tMs: number): RevealState {\n const lineClusters = lines.map((l) => graphemeClusters(l.text));\n const totalGraphemes = lineClusters.reduce((n, c) => n + c.length, 0);\n\n const authored = Math.max(0, Math.min(1, reveal.progress ?? 1));\n const speed = reveal.speed ?? 0;\n const timed = speed > 0 && totalGraphemes > 0 ? Math.min(1, (speed * tMs) / 1000 / totalGraphemes) : 1;\n const progress = Math.min(authored, timed);\n\n const mode = reveal.mode ?? 'typewriter';\n let fullLines = 0;\n let partialText = '';\n\n // glyphFade: glyph g starts fading at (g/total)·(1−fade) and ramps to\n // opaque over a `fade`-wide window of progress, so every glyph is 0 at\n // progress 0 and 1 at progress 1. The frontier below (shared with\n // typewriter) still anchors the caret. Pure paint, like everything here.\n let glyphAlphas: number[][] | undefined;\n if (mode === 'glyphFade') {\n // The 0.01 floor is defensive only — validation already enforces the\n // public contract fade ∈ (0, 1] (FORMAT.md). It exists so direct callers\n // that skip validateSpec can't make the divide below infinite, not to\n // remap legal values: anything ≥ 0.01 passes through untouched.\n const f = Math.min(1, Math.max(0.01, reveal.fade ?? 0.15));\n let g = 0;\n glyphAlphas = lineClusters.map((clusters) =>\n clusters.map(() => {\n const start = totalGraphemes > 0 ? (g++ / totalGraphemes) * (1 - f) : 0;\n return Math.max(0, Math.min(1, (progress - start) / f));\n }),\n );\n }\n\n if (mode === 'line') {\n fullLines = Math.round(progress * lines.length);\n } else if (mode === 'word') {\n const lineWords = lines.map((l) => (l.text.length === 0 ? [] : l.text.split(' ')));\n const totalWords = lineWords.reduce((n, ws) => n + ws.length, 0);\n let remaining = Math.round(progress * totalWords);\n for (const ws of lineWords) {\n if (remaining >= ws.length) {\n remaining -= ws.length;\n fullLines++;\n // A zero-word (empty) line is \"full\" for free; keep consuming.\n continue;\n }\n if (remaining > 0) partialText = ws.slice(0, remaining).join(' ');\n break;\n }\n } else {\n let remaining = Math.round(progress * totalGraphemes);\n for (const clusters of lineClusters) {\n if (remaining >= clusters.length) {\n remaining -= clusters.length;\n fullLines++;\n continue;\n }\n if (remaining > 0) partialText = clusters.slice(0, remaining).join('');\n break;\n }\n }\n\n // Caret sits at the reveal frontier: end of the partial line, else end of\n // the last full line, else the start of the block.\n let caretLine: number;\n let caretPrefix: string;\n if (partialText.length > 0) {\n caretLine = fullLines;\n caretPrefix = partialText;\n } else if (fullLines > 0) {\n caretLine = fullLines - 1;\n caretPrefix = lines[fullLines - 1]!.text;\n } else {\n caretLine = 0;\n caretPrefix = '';\n }\n\n return { progress, fullLines, partialText, caretLine, caretPrefix, glyphAlphas };\n}\n","import {\n createRng,\n type ControlTrack,\n type ParamDelta,\n type SaverContext,\n type SaverInstance,\n type SaverManifest,\n type SaverPlugin,\n} from '@idle-screens/core';\nimport { assertValidSpec, assertValidSequence, validateSpec } from './validate';\nimport { alphaAt, breakTextBlock, buildEntities, graphemeClusters, headingAt, lifeAlphaAt, linkEdges, positionAt, revealState, rotationAt, sizeAt, spriteIndexAt, type Entity } from './simulate';\nimport {\n applyDeltasToSpec,\n easeSmooth,\n lerpSpec,\n structuralSignature,\n type SteerDelta,\n} from './steer';\nimport type { IdleSequence, LayerSpec, SaverSpec } from './types';\nimport { LIMITS } from './types';\nimport { resolveSegment, segmentStart } from './sequence';\nimport { FEATHER_STEPS, barBox, barFraction, featherAlphas, isShapedSprite, polygonPoints, strokeSamples, strokeTaper, strokeWidthPx } from './shapes';\n\nconst DEFAULT_STEER_DUR = 1000;\n\n/** Expand #rgb/#rrggbb to an rgba() string — needed for gradient stops with alpha. */\nfunction hexToRgba(hex: string, alpha: number): string {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${alpha})`;\n}\n\nconst FONT_PREFIX_RE = /^((?:(?:italic|oblique|bold|bolder|lighter|normal|\\d{3})\\s+)+)/;\n\n/**\n * Matches the size token in a CSS font shorthand (\"bold 26px monospace\").\n *\n * The digit runs are bounded on purpose. This ran as `(\\d*\\.?\\d+)px`, where\n * `\\d*` and `\\d+` can split the same digit run many ways, so a long run that\n * never reaches \"px\" makes the engine retry every split at every start\n * position. `sprite.font` comes straight from an authored SaverSpec, so that\n * input is reachable by anyone who can publish a scene: 1 000 digits took\n * 600 ms and 5 000 took 62 SECONDS, which is a denial of service rather than\n * a slow path. Bounding each run makes the work per start position constant —\n * 200 000 chars now costs about 4 ms.\n *\n * The bounds are far past anything real: no CSS font size needs more than\n * five integer digits or four decimals. `.5px` still parses via the second\n * branch.\n */\nconst FONT_PX_RE = /(\\d{1,5}(?:\\.\\d{1,4})?|\\.\\d{1,4})px/;\n\n/**\n * Rescale an explicit px size inside a font shorthand.\n *\n * A spec in the default `viewport` units expresses every other dimension as a\n * fraction of `min(w, h)`, so a font pinned to absolute pixels is the one thing\n * that does NOT adapt: `bold 26px monospace` renders 26px whether the canvas is\n * 1920 or 320 wide, which is how the dashboard's text came to overlap itself at\n * thumbnail size. Scaling it by `min(w, h) / referenceViewport` makes it behave\n * like the rest of the spec. Specs that opt into `units: 'px'` are asking for\n * absolute sizes and are left alone.\n */\nfunction scaleFontPx(font: string, factor: number): string {\n if (factor === 1) return font;\n return font.replace(FONT_PX_RE, (_m, n: string) => `${(Number(n) * factor).toFixed(2)}px`);\n}\n\n/** Build a valid CSS font shorthand: weight/style tokens must precede the size. */\nfunction composeFontShorthand(sz: number, font: string): string {\n const m = FONT_PREFIX_RE.exec(font);\n if (m) return `${m[1].trim()} ${sz}px ${font.slice(m[0].length)}`;\n return `${sz}px ${font}`;\n}\n\n/** Derive a manifest so a compiled spec composes with @idle-screens/capabilities. */\nexport function manifestFor(spec: SaverSpec): SaverManifest {\n const total = spec.layers.reduce((n, l) => n + l.count, 0);\n const costTier = total < 30 ? 'idle' : total < 150 ? 'low' : total < 400 ? 'medium' : 'high';\n return {\n id: spec.id,\n label: spec.label,\n // Declarative specs are closed-form by construction: every entity is a\n // pure function of (seed, t), which is the whole point of the format.\n timeModel: 'closed-form',\n passthrough: false,\n minBackend: 'canvas2d',\n costTier,\n motionIntensity: spec.motionIntensity ?? 'moderate',\n reducedMotionFallback: 'static',\n // Flash-safe by construction: static background + bounded sprites, no strobe\n // primitive. Proven by sampling a compiled spec through @idle-screens/validator.\n a11y: { flashSafe: true },\n workerReady: true,\n };\n}\n\ninterface Built {\n layer: LayerSpec;\n entities: Entity[];\n}\n\nclass SpecInstance implements SaverInstance {\n private readonly canvas: HTMLCanvasElement | OffscreenCanvas;\n private readonly ownsCanvas: boolean;\n private readonly ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n private readonly saverCtx: SaverContext;\n private readonly seed: number;\n private w: number;\n private h: number;\n private layers: Built[] = [];\n private frameId: number | null = null;\n private paused = false;\n private startT = 0;\n private baseT = 0; // elapsed logical time carried across pause/resume\n private lastT = 0;\n /** Last time painted — detects non-contiguous seeks for the ghosting warm-up replay. */\n private lastRenderT = Number.NEGATIVE_INFINITY;\n\n /** The spec currently being rendered (base spec + any applied steering). */\n private effSpec: SaverSpec;\n /** Active glide between two resolved specs (live setParam/applyTrack). */\n private transition: { from: SaverSpec; to: SaverSpec; startT: number; dur: number } | null = null;\n private lastStructural = '';\n\n constructor(\n private readonly spec: SaverSpec,\n ctx: SaverContext,\n ) {\n this.effSpec = spec;\n this.saverCtx = ctx;\n this.seed = ((spec.seed ?? ctx.seed) >>> 0) || 1;\n let canvas: HTMLCanvasElement | OffscreenCanvas;\n if (ctx.surface) {\n canvas = ctx.surface;\n this.ownsCanvas = false;\n } else {\n const el = document.createElement('canvas');\n el.style.cssText = 'display:block;width:100%;height:100%';\n el.setAttribute('aria-hidden', 'true');\n ctx.host.appendChild(el);\n canvas = el;\n this.ownsCanvas = true;\n }\n this.canvas = canvas;\n const c2d = canvas.getContext('2d', { alpha: false }) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;\n if (!c2d) throw new Error('schema saver: no 2d context');\n this.ctx = c2d;\n\n this.w = ctx.width;\n this.h = ctx.height;\n this.sizeCanvas();\n this.rebuild();\n\n this.paused = ctx.reducedMotion;\n if (this.paused) this.renderFrame(0, this.seed);\n else this.start();\n }\n\n /** Viewport factor for absolute px sizes — 1 for `units: 'px'` specs. */\n private fontScale(): number {\n if (this.effSpec.units === 'px') return 1;\n return Math.min(this.w, this.h) / (this.effSpec.referenceViewport ?? LIMITS.referenceViewport);\n }\n\n private sizeCanvas(): void {\n const dpr = Math.min(this.saverCtx.dpr, 2);\n this.canvas.width = Math.max(1, Math.round(this.w * dpr));\n this.canvas.height = Math.max(1, Math.round(this.h * dpr));\n this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n // Resizing clears the canvas — force a ghosting warm-up on the next frame.\n this.lastRenderT = Number.NEGATIVE_INFINITY;\n }\n\n /** (Re)seed and place all entities — deterministic for the seed + viewport. */\n private rebuild(): void {\n const rng = createRng(this.seed);\n const scale = this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h);\n const refVp = this.effSpec.referenceViewport ?? LIMITS.referenceViewport;\n let countScale = scale > 1 ? Math.min(this.w, this.h) / refVp : 1;\n if (countScale > 1) {\n const rawTotal = this.effSpec.layers.reduce((s, l) => s + Math.round(l.count * countScale), 0);\n if (rawTotal > LIMITS.maxTotal) countScale *= LIMITS.maxTotal / rawTotal;\n }\n this.layers = this.effSpec.layers.map((layer) => ({ layer, entities: buildEntities(layer, rng, this.w, this.h, scale, countScale) }));\n this.lastStructural = structuralSignature(this.effSpec);\n }\n\n private start(): void {\n if (this.frameId !== null || typeof requestAnimationFrame === 'undefined') return;\n this.startT = 0;\n this.frameId = requestAnimationFrame((now) => this.loop(now));\n }\n\n private stop(): void {\n if (this.frameId !== null) {\n cancelAnimationFrame(this.frameId);\n this.frameId = null;\n }\n // Freeze elapsed time so resume continues the scene instead of restarting at t=0.\n this.baseT = this.lastT;\n }\n\n private loop(now: number): void {\n this.frameId = requestAnimationFrame((n) => this.loop(n));\n if (this.startT === 0) this.startT = now;\n this.lastT = now - this.startT + this.baseT;\n this.renderFrame(this.lastT, this.seed);\n }\n\n private drawBackground(t: number): void {\n const { ctx, w, h } = this;\n const bg = this.effSpec.background;\n if (!bg || bg.type === 'solid') {\n ctx.fillStyle = bg?.color ?? '#05050a';\n ctx.fillRect(0, 0, w, h);\n return;\n }\n const g = ctx.createLinearGradient(0, 0, 0, h);\n const drift = bg.drift;\n for (let i = 0; i < bg.stops.length; i++) {\n const s = bg.stops[i]!;\n let at = s.at;\n if (drift) {\n const amount = drift.amount ?? 0.15;\n const phase = (i / bg.stops.length) * Math.PI * 2;\n at = Math.max(0, Math.min(1, at + amount * Math.sin((t * 2 * Math.PI) / drift.period + phase)));\n }\n g.addColorStop(at, s.color);\n }\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, w, h);\n if (bg.band) {\n ctx.fillStyle = bg.band.color;\n const bh = bg.band.height * (this.effSpec.units === 'px' ? 1 : Math.min(w, h));\n ctx.fillRect(0, h - bh, w, bh);\n }\n }\n\n /** Position with parent-orbit resolution: a layer-parented orbit entity's\n * positionAt is an offset around (0,0); add the parent's own analytic position. */\n private entityPos(e: Entity, t: number, parentE: Entity | null): { x: number; y: number; flip: boolean } {\n const p = positionAt(e, t, this.w, this.h);\n if (parentE && e.orbitParent) {\n const pp = positionAt(parentE, t, this.w, this.h);\n p.x += pp.x;\n p.y += pp.y;\n }\n return p;\n }\n\n /** Resolve the single parent entity for a layer-parented orbit layer (or null). */\n private parentEntityFor(built: Built): Entity | null {\n const m = built.layer.motion;\n if (m.type !== 'orbit' || !m.center || !('layer' in m.center)) return null;\n const key = m.center.layer;\n const parent = this.layers.find((b) => b.layer.key === key);\n return parent?.entities[0] ?? null;\n }\n\n private drawTrail(built: Built, e: Entity, t: number, lifeA: number, parentE: Entity | null): void {\n const trail = built.layer.trail;\n if (!trail) return;\n const { ctx, w, h } = this;\n const fade = trail.fade ?? 1;\n const n = Math.min(Math.ceil(trail.length / 50), LIMITS.maxTrailSamples);\n const headAlpha = alphaAt(e, t) * lifeA;\n const headSize = sizeAt(e, t);\n const sprite = built.layer.sprite;\n const resolvedColor = isShapedSprite(sprite)\n ? (sprite.colors?.[e.colorIndex] ?? sprite.color)\n : sprite.kind === 'text' || sprite.kind === 'textBlock' ? (sprite.color ?? '#e6e8ef') : '#e6e8ef';\n const isSoft = sprite.kind === 'circle' && sprite.soft;\n const wrap = built.layer.wrap !== false;\n\n const head = this.entityPos(e, t, parentE);\n let prevX = head.x;\n let prevY = head.y;\n\n for (let s = 1; s <= n; s++) {\n const k = s / n;\n const pastT = t - k * trail.length;\n if (pastT < 0) break;\n const pos = this.entityPos(e, pastT, parentE);\n\n if (wrap) {\n const dx = pos.x - prevX;\n const dy = pos.y - prevY;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) break;\n }\n prevX = pos.x;\n prevY = pos.y;\n\n const a = headAlpha * (1 - k * fade);\n if (a <= 0) break;\n const r = (headSize / 2) * (1 - k * 0.7);\n if (r < 0.2) break;\n\n ctx.globalAlpha = a;\n if (isSoft) {\n const g = ctx.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, r);\n g.addColorStop(0, resolvedColor);\n g.addColorStop(0.35, hexToRgba(resolvedColor, 0.75));\n g.addColorStop(1, hexToRgba(resolvedColor, 0));\n ctx.fillStyle = g;\n } else {\n ctx.fillStyle = resolvedColor;\n }\n ctx.beginPath();\n ctx.arc(pos.x, pos.y, r, 0, Math.PI * 2);\n ctx.fill();\n }\n }\n\n private drawEntity(built: Built, e: Entity, t: number, lifeA: number, parentE: Entity | null): void {\n const { ctx } = this;\n const p = this.entityPos(e, t, parentE);\n const sprite = built.layer.sprite;\n const sz = sizeAt(e, t);\n const rot = rotationAt(e, t);\n const unitScale = this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h);\n ctx.globalAlpha = alphaAt(e, t) * lifeA;\n if (sprite.kind === 'ring') {\n const r = sz / 2;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n ctx.strokeStyle = resolvedColor;\n ctx.lineWidth = Math.max(0.5, (sprite.width ?? (unitScale === 1 ? 2 : 0.002)) * unitScale);\n ctx.beginPath();\n ctx.arc(p.x, p.y, r, 0, Math.PI * 2);\n ctx.stroke();\n return;\n }\n if (sprite.kind === 'streak') {\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const heading = headingAt(e, t, this.w, this.h) ?? 0;\n const tailX = p.x - Math.cos(heading) * sz;\n const tailY = p.y - Math.sin(heading) * sz;\n const g = ctx.createLinearGradient(tailX, tailY, p.x, p.y);\n g.addColorStop(0, hexToRgba(resolvedColor, 0));\n g.addColorStop(1, resolvedColor);\n ctx.strokeStyle = g;\n ctx.lineWidth = Math.max(0.5, (sprite.width ?? (unitScale === 1 ? 2 : 0.002)) * unitScale);\n ctx.lineCap = 'round';\n ctx.beginPath();\n ctx.moveTo(tailX, tailY);\n ctx.lineTo(p.x, p.y);\n ctx.stroke();\n return;\n }\n if (sprite.kind === 'rect') {\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const rh = e.size2 !== undefined\n ? e.size2 * (e.size > 0 ? sz / e.size : 1) // grow/warp scale height with width\n : sz;\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n ctx.fillStyle = resolvedColor;\n const feather = sprite.feather ?? 0;\n if (feather > 0) {\n // Soft edge: nested fills from the OUTSIDE IN — the full-size rect\n // first at the faintest alpha, the core last at full — so the\n // composited alpha ramps linearly across the feathered band (see\n // featherAlphas). Only `lighter` sums alphas; `screen` still\n // composites source-over, so it takes the source-over schedule.\n const base = ctx.globalAlpha;\n const additive = built.layer.blend === 'lighter';\n const alphas = featherAlphas(FEATHER_STEPS, additive);\n for (let j = 1; j <= FEATHER_STEPS; j++) {\n const f = 1 - (feather * (j - 1)) / FEATHER_STEPS; // j=1 full size … j=K the core\n const fw = sz * f;\n const fh = rh * f;\n ctx.globalAlpha = base * alphas[j - 1]!;\n ctx.fillRect(-fw / 2, -fh / 2, fw, fh);\n }\n ctx.globalAlpha = base;\n } else {\n ctx.fillRect(-sz / 2, -rh / 2, sz, rh);\n }\n ctx.restore();\n return;\n }\n if (sprite.kind === 'bar') {\n const len = sz * barFraction(sprite, e.barIndex ?? 0);\n if (len <= 0) return;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const th = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz * 0.2;\n const box = barBox(sprite.direction ?? 'right', len, th);\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n ctx.fillStyle = resolvedColor;\n ctx.fillRect(box.cx - box.halfX, box.cy - box.halfY, box.halfX * 2, box.halfY * 2);\n ctx.restore();\n return;\n }\n if (sprite.kind === 'polygon') {\n const r = sz / 2;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const pts = polygonPoints(sprite, r);\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n if (sprite.soft) {\n const g = ctx.createRadialGradient(0, 0, 0, 0, 0, r);\n g.addColorStop(0, resolvedColor);\n g.addColorStop(0.35, hexToRgba(resolvedColor, 0.75));\n g.addColorStop(1, hexToRgba(resolvedColor, 0));\n ctx.fillStyle = g;\n } else {\n ctx.fillStyle = resolvedColor;\n }\n ctx.beginPath();\n ctx.moveTo(pts[0]!.x, pts[0]!.y);\n for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i]!.x, pts[i]!.y);\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n return;\n }\n if (sprite.kind === 'stroke') {\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const pts = strokeSamples(sprite, sz / 2);\n const lw = strokeWidthPx(sprite, unitScale);\n ctx.save();\n ctx.translate(p.x, p.y);\n let angle = rot;\n if (sprite.orient) angle += headingAt(e, t, this.w, this.h) ?? 0;\n if (angle) ctx.rotate(angle);\n ctx.strokeStyle = resolvedColor;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n if (sprite.taper) {\n // A brush mark: each sampled segment at its own width.\n for (let i = 1; i < pts.length; i++) {\n ctx.lineWidth = Math.max(0.5, lw * strokeTaper((i - 0.5) / (pts.length - 1)));\n ctx.beginPath();\n ctx.moveTo(pts[i - 1]!.x, pts[i - 1]!.y);\n ctx.lineTo(pts[i]!.x, pts[i]!.y);\n ctx.stroke();\n }\n } else {\n ctx.lineWidth = lw;\n ctx.beginPath();\n ctx.moveTo(pts[0]!.x, pts[0]!.y);\n for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i]!.x, pts[i]!.y);\n ctx.stroke();\n }\n ctx.restore();\n return;\n }\n if (sprite.kind === 'circle') {\n const r = sz / 2;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n ctx.save();\n if (rot) {\n ctx.translate(p.x, p.y);\n ctx.rotate(rot);\n ctx.translate(-p.x, -p.y);\n }\n if (sprite.soft) {\n const g = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, r);\n g.addColorStop(0, resolvedColor);\n g.addColorStop(0.35, hexToRgba(resolvedColor, 0.75));\n g.addColorStop(1, hexToRgba(resolvedColor, 0));\n ctx.fillStyle = g;\n } else {\n ctx.fillStyle = resolvedColor;\n }\n ctx.beginPath();\n ctx.arc(p.x, p.y, r, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n return;\n }\n if (sprite.kind === 'textBlock') {\n const unitScale = Math.min(this.w, this.h);\n const fsPx = sprite.fontSize * unitScale;\n const lh = (sprite.lineHeight ?? 1.4) * fsPx;\n const maxWPx = sprite.maxWidth * unitScale;\n const maxWEm = maxWPx / fsPx;\n const lines = breakTextBlock(sprite.text, maxWEm);\n const align = sprite.align ?? 'left';\n // Reveal masks glyphs; layout above always ran on the full text, so\n // lines never reflow while typing.\n const reveal = sprite.reveal;\n const rs = reveal ? revealState(lines, reveal, t) : null;\n const fullLines = rs ? rs.fullLines : lines.length;\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n ctx.font = `${fsPx}px system-ui, sans-serif`;\n ctx.fillStyle = sprite.color ?? '#e6e8ef';\n ctx.textBaseline = 'top';\n ctx.textAlign = align;\n const xOff = align === 'center' ? maxWPx / 2 : align === 'right' ? maxWPx : 0;\n if (rs?.glyphAlphas) {\n // glyphFade: the contiguous fully-opaque leading run draws as ONE\n // fillText — a single draw forms ligatures and pair kerning exactly\n // like the un-revealed path (pixel parity once fully revealed), and it\n // drops the O(n²) per-frame prefix re-measure for glyphs that have\n // finished fading. Only the fading tail draws glyph-by-glyph, each at\n // its full-line prefix advance. measureText is paint-only (the caret's\n // trick) — positions come from the platform's real glyph widths, never\n // the em table, and depend only on the fixed prefix, so glyphs never\n // shift as they fade.\n ctx.textAlign = 'left';\n const baseAlpha = ctx.globalAlpha;\n for (let li = 0; li < lines.length; li++) {\n const alphas = rs.glyphAlphas[li] ?? [];\n if (alphas.length > 0 && alphas[0]! <= 0) break;\n const clusters = graphemeClusters(lines[li]!.text);\n const lw = ctx.measureText(lines[li]!.text).width;\n const x0 = align === 'center' ? (maxWPx - lw) / 2 : align === 'right' ? maxWPx - lw : 0;\n let opaque = 0;\n while (opaque < clusters.length && (alphas[opaque] ?? 0) >= 1) opaque++;\n let prefix = '';\n if (opaque > 0) {\n prefix = clusters.slice(0, opaque).join('');\n ctx.globalAlpha = baseAlpha;\n ctx.fillText(prefix, x0, li * lh);\n }\n for (let gi = opaque; gi < clusters.length; gi++) {\n const a = alphas[gi] ?? 0;\n if (a <= 0) break; // alphas only fall in reading order\n ctx.globalAlpha = baseAlpha * a;\n ctx.fillText(clusters[gi]!, x0 + ctx.measureText(prefix).width, li * lh);\n prefix += clusters[gi]!;\n }\n }\n ctx.globalAlpha = baseAlpha;\n } else {\n for (let li = 0; li < fullLines; li++) {\n ctx.fillText(lines[li]!.text, xOff, li * lh);\n }\n if (rs && rs.partialText.length > 0) {\n ctx.fillText(rs.partialText, xOff, fullLines * lh);\n }\n }\n if (rs && reveal!.caret) {\n const cfg = reveal!.caret === true ? {} : reveal!.caret;\n const hz = Math.min(3, cfg.blink ?? 1.2);\n const on = hz <= 0 || Math.floor((t / 1000) * hz * 2) % 2 === 0;\n if (on) {\n // measureText is paint-only here: it positions the caret against the\n // platform's real glyph widths but never influences layout, which\n // stays on the fixed metrics table.\n const pw = ctx.measureText(rs.caretPrefix).width;\n const cx = align === 'center' ? xOff + pw / 2 : align === 'right' ? xOff : pw;\n ctx.fillStyle = cfg.color ?? sprite.color ?? '#e6e8ef';\n ctx.fillRect(cx + fsPx * 0.06, rs.caretLine * lh, Math.max(1, fsPx * 0.08), fsPx);\n }\n }\n ctx.restore();\n return;\n }\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n if (p.flip && built.layer.flip) ctx.scale(-1, 1);\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n if (sprite.kind === 'emoji') {\n const idx = spriteIndexAt(e, t, sprite.glyphs.length);\n ctx.font = `${sz}px serif`;\n ctx.fillText(sprite.glyphs[idx] ?? sprite.glyphs[0]!, 0, 0);\n } else {\n ctx.textAlign = sprite.align ?? 'center';\n ctx.textBaseline = sprite.baseline ?? 'middle';\n // A full CSS shorthand (contains a px size) is used verbatim; a family/weight\n // only ('bold monospace') composes with the seeded per-entity size.\n ctx.font = sprite.font\n ? (FONT_PX_RE.test(sprite.font)\n ? scaleFontPx(sprite.font, this.fontScale())\n : composeFontShorthand(sz, sprite.font))\n : `${sz}px system-ui, sans-serif`;\n ctx.fillStyle = sprite.color ?? '#e6e8ef';\n const idx = spriteIndexAt(e, t, sprite.strings.length);\n const text = sprite.strings[idx] ?? sprite.strings[0]!;\n const mw = sprite.maxWidth ? sprite.maxWidth * (this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h)) : undefined;\n if (mw) ctx.fillText(text, 0, 0, mw);\n else ctx.fillText(text, 0, 0);\n }\n ctx.restore();\n }\n\n /** Advance any live steering glide; rebuild entities on structural change. */\n private stepTransition(t: number): void {\n const tr = this.transition;\n if (!tr) return;\n const k = tr.dur <= 0 ? 1 : (t - tr.startT) / tr.dur;\n this.effSpec = k >= 1 ? tr.to : lerpSpec(tr.from, tr.to, easeSmooth(k));\n if (k >= 1) this.transition = null;\n // Placement/motion fields are baked into entities at build time; rebuild\n // (deterministic — same seed → same stream) only when those change.\n const sig = structuralSignature(this.effSpec);\n if (sig !== this.lastStructural) this.rebuild();\n else this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n }\n\n /**\n * Live steering: glide from what's currently rendered to the track's target\n * state (deltas applied last-wins). Duration = the longest delta `dur`.\n */\n applyTrack(track: ControlTrack): void {\n const deltas = (track?.deltas ?? []) as unknown as SteerDelta[];\n const target = applyDeltasToSpec(this.effSpec, deltas);\n if (!validateSpec(target).valid) return;\n const dur = deltas.length\n ? deltas.reduce((m, d) => Math.max(m, d.dur ?? DEFAULT_STEER_DUR), 0)\n : DEFAULT_STEER_DUR;\n this.transition = {\n from: JSON.parse(JSON.stringify(this.effSpec)) as SaverSpec,\n to: target,\n startT: this.lastT,\n dur,\n };\n if (this.paused) {\n // No frames will run the glide — jump straight to the target.\n this.transition = null;\n this.effSpec = target;\n if (structuralSignature(this.effSpec) !== this.lastStructural) this.rebuild();\n else this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n this.renderFrame(this.lastT, this.seed);\n }\n }\n\n private drawLinks(built: Built, t: number, lifeA: number, parentE: Entity | null): void {\n const { links } = built.layer;\n if (!links) return;\n const { ctx } = this;\n // Toroidal link drawing only makes sense for motions that actually wrap —\n // bounce/orbit/path entities never cross an edge, so a \"nearest image\" line\n // would cut across the screen.\n const motionWraps = ['drift', 'rise', 'wander'].includes(built.layer.motion.type);\n const wrap = built.layer.wrap !== false && motionWraps;\n const positions = built.entities.map((e) => this.entityPos(e, t, parentE));\n const maxDistPx = links.maxDist * (this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h));\n const edges = linkEdges(links, positions, maxDistPx, wrap, this.w, this.h);\n const unitScale = this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h);\n const defaultWidth = unitScale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const lw = (links.width ?? defaultWidth) * unitScale;\n ctx.lineWidth = lw;\n ctx.lineCap = 'butt'; // streak sprites set 'round'; reset so link ends stay crisp\n\n for (const { i, j, dist } of edges) {\n const pi = positions[i]!;\n const pj = positions[j]!;\n const ei = built.entities[i]!;\n let resolvedColor = links.color;\n if (!resolvedColor) {\n const sprite = built.layer.sprite;\n if (isShapedSprite(sprite)) {\n resolvedColor = sprite.colors?.[ei.colorIndex] ?? sprite.color;\n } else resolvedColor = '#e6e8ef';\n }\n let a = links.alpha ?? alphaAt(ei, t);\n if (links.falloff) a *= Math.max(0, 1 - dist / maxDistPx);\n ctx.globalAlpha = a * lifeA;\n ctx.strokeStyle = resolvedColor;\n // Draw toward nearest image of pj (avoids full-canvas streaks at wrap seams)\n let dx = pj.x - pi.x;\n let dy = pj.y - pi.y;\n if (wrap) {\n if (Math.abs(dx) > this.w / 2) dx = dx > 0 ? dx - this.w : dx + this.w;\n if (Math.abs(dy) > this.h / 2) dy = dy > 0 ? dy - this.h : dy + this.h;\n }\n ctx.beginPath();\n ctx.moveTo(pi.x, pi.y);\n ctx.lineTo(pi.x + dx, pi.y + dy);\n ctx.stroke();\n }\n }\n\n /** Paint one composite pass at time t. `bgAlpha` < 1 leaves the previous frame\n * showing through — the ghosting smear. */\n private paintFrame(t: number, bgAlpha: number): void {\n const { ctx } = this;\n ctx.globalAlpha = bgAlpha;\n ctx.globalCompositeOperation = 'source-over';\n this.drawBackground(t);\n ctx.globalAlpha = 1;\n for (const built of this.layers) {\n const lifeA = lifeAlphaAt(built.layer.life, t);\n if (lifeA <= 0) continue;\n const parentE = this.parentEntityFor(built);\n ctx.globalCompositeOperation = built.layer.blend ?? 'source-over';\n this.drawLinks(built, t, lifeA, parentE);\n for (const e of built.entities) {\n this.drawTrail(built, e, t, lifeA, parentE);\n this.drawEntity(built, e, t, lifeA, parentE);\n }\n }\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'source-over';\n }\n\n /**\n * Deterministic, frame-addressable render (shared by the rAF loop).\n *\n * With `ghosting` set, contiguous frames composite over the previous frame with a\n * refresh-rate-normalized fade. A non-contiguous seek (pause render, e2e frame\n * addressing) replays a bounded fixed-step warm-up from a full clear, so the\n * accumulated smear at time t is identical on every run — the determinism proof\n * survives statefulness because the \"state\" is reconstructed from pure history.\n */\n renderFrame(t: number, _seed: number): void {\n this.stepTransition(t);\n const g = this.effSpec.ghosting ?? 0;\n if (g > 0) {\n const dt = 1000 / 60;\n const contiguous = this.lastRenderT !== Number.NEGATIVE_INFINITY\n && t > this.lastRenderT\n && t - this.lastRenderT <= 250;\n if (contiguous) {\n this.paintFrame(t, 1 - Math.pow(g, (t - this.lastRenderT) / dt));\n } else {\n const k = Math.min(Math.ceil(Math.log(1 / 255) / Math.log(g)), LIMITS.maxGhostReplayFrames);\n const t0 = Math.max(0, t - k * dt);\n this.paintFrame(t0, 1);\n for (let ft = t0 + dt; ft < t - dt / 2; ft += dt) this.paintFrame(ft, 1 - g);\n if (t > t0) this.paintFrame(t, 1 - g);\n }\n } else {\n this.paintFrame(t, 1);\n }\n this.lastRenderT = t;\n }\n\n setPaused(paused: boolean): void {\n this.paused = paused;\n if (paused) {\n this.stop();\n } else {\n this.start();\n }\n }\n\n resize(width: number, height: number, dpr?: number): void {\n this.w = width;\n this.h = height;\n if (dpr !== undefined) this.saverCtx.dpr = dpr;\n this.sizeCanvas();\n this.rebuild();\n if (this.paused) this.renderFrame(0, this.seed);\n }\n\n /**\n * Replace the rendered spec without triggering a transition glide.\n * Checks structural signature — use `hotSwapPaint` when the caller\n * already knows the signature is unchanged (e.g. mid-morph lerp).\n */\n hotSwapSpec(spec: SaverSpec): void {\n this.effSpec = spec;\n const sig = structuralSignature(this.effSpec);\n if (sig !== this.lastStructural) this.rebuild();\n else this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n }\n\n /** Paint-only hot-swap: skips structuralSignature (caller guarantees match). */\n hotSwapPaint(spec: SaverSpec): void {\n this.effSpec = spec;\n this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n }\n\n dispose(): void {\n this.stop();\n if (this.ownsCanvas && typeof HTMLCanvasElement !== 'undefined' && this.canvas instanceof HTMLCanvasElement) this.canvas.remove();\n }\n}\n\n/**\n * Compile a declarative spec into a runnable SaverPlugin. Throws if the spec is invalid\n * (so an agent-authored spec is validated before it can run). The result is seeded,\n * deterministic, `renderFrame(t,seed)`-addressable, and flash-safe by construction.\n */\nexport function compileSaver(spec: unknown): SaverPlugin {\n const valid = assertValidSpec(spec);\n return {\n manifest: manifestFor(valid),\n mount: (ctx: SaverContext) => new SpecInstance(valid, ctx),\n spec: valid,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Sequence — multi-segment timeline compiled as a single SaverPlugin\n// ---------------------------------------------------------------------------\n\nclass SequenceInstance implements SaverInstance {\n private readonly seq: IdleSequence;\n private readonly childCtx: SaverContext;\n private readonly canvas: HTMLCanvasElement | null;\n private readonly children: (SpecInstance | null)[];\n private activeIndex = -1;\n private paused = false;\n /**\n * When a morph is active, the child at `morphFromIndex` renders with a\n * lerped spec. The child stays keyed to the *outgoing* segment's slot so\n * its seed (and entity placement) is continuous.\n */\n private morphFromIndex = -1;\n private readonly seed: number;\n private frameId: number | null = null;\n private startT = 0;\n private baseT = 0;\n private lastT = 0;\n /** The T most recently passed to renderFrame — the clock a steer displaces. */\n private renderedT = 0;\n /**\n * The clicker's two pieces of state. `clockOffset` is added to every T so\n * a `sequence.segment` steer lands the timeline at the target segment's\n * start and STAYS there as the wall clock keeps ticking — the steer moves\n * the clock instead of fighting it. `releasedBelow` records that the steer\n * counts as the presenter clicking past every `advance: 'input'` hold\n * before the target (see `resolveSegment`).\n */\n private clockOffset = 0;\n private releasedBelow = 0;\n\n constructor(seq: IdleSequence, ctx: SaverContext) {\n this.seq = seq;\n\n let surface = ctx.surface ?? null;\n let canvas: HTMLCanvasElement | null = null;\n if (!surface && typeof document !== 'undefined') {\n canvas = document.createElement('canvas');\n canvas.style.cssText = 'display:block;width:100%;height:100%';\n canvas.setAttribute('aria-hidden', 'true');\n ctx.host.appendChild(canvas);\n surface = canvas;\n }\n this.canvas = canvas;\n\n // Prefer the sequence's own seed (same precedence SpecInstance uses for\n // scene.seed ?? ctx.seed). Children still resolve per-segment via childSeed.\n this.seed = ((seq.seed ?? ctx.seed ?? 0) >>> 0) || 1;\n // Children are always parent-driven: reducedMotion:true keeps SpecInstance\n // from starting its own rAF. SequenceInstance.loop is the only clock.\n this.childCtx = { ...ctx, surface: surface!, reducedMotion: true };\n this.children = new Array(seq.segments.length).fill(null) as (SpecInstance | null)[];\n this.paused = ctx.reducedMotion;\n if (this.paused) this.renderFrame(0, this.seed);\n else this.start();\n }\n\n private childSeed(index: number, fallback: number): number {\n return this.seq.segments[index]!.scene.seed ?? this.seq.seed ?? fallback;\n }\n\n private childScene(index: number): SaverSpec {\n const seg = this.seq.segments[index]!;\n if (seg.scene.seed != null) return seg.scene;\n if (this.seq.seed != null) return { ...seg.scene, seed: this.seq.seed + index };\n return seg.scene;\n }\n\n /** Whether the boundary from `from` to `from+1` should morph. */\n private canMorph(from: number): boolean {\n const seg = this.seq.segments[from];\n if (!seg || seg.transition?.type !== 'morph') return false;\n const next = this.seq.segments[from + 1];\n if (!next) return false;\n return structuralSignature(seg.scene) === structuralSignature(next.scene);\n }\n\n /** Walk back through consecutive morph boundaries to find the chain origin. */\n private morphChainRoot(index: number): number {\n let i = index;\n while (i > 0 && this.canMorph(i - 1)) i--;\n return i;\n }\n\n private morphDur(from: number): number {\n const tr = this.seq.segments[from]?.transition;\n return tr?.type === 'morph' ? tr.dur : 0;\n }\n\n private ensureChild(index: number): SpecInstance {\n if (index < 0 || index >= this.seq.segments.length) index = 0;\n let child = this.children[index];\n if (!child) {\n child = new SpecInstance(this.childScene(index), this.childCtx);\n this.children[index] = child;\n // Belt-and-suspenders: never let a child self-drive, even if childCtx\n // reducedMotion is ever relaxed.\n child.setPaused(true);\n }\n return child;\n }\n\n private releaseChild(index: number): void {\n const child = this.children[index];\n if (child) {\n child.dispose();\n this.children[index] = null;\n }\n }\n\n private start(): void {\n if (this.frameId !== null || typeof requestAnimationFrame === 'undefined') return;\n this.startT = 0;\n this.frameId = requestAnimationFrame((now) => this.loop(now));\n }\n\n private stop(): void {\n if (this.frameId !== null) {\n cancelAnimationFrame(this.frameId);\n this.frameId = null;\n }\n this.baseT = this.lastT;\n }\n\n private loop(now: number): void {\n this.frameId = requestAnimationFrame((n) => this.loop(n));\n if (this.startT === 0) this.startT = now;\n this.lastT = now - this.startT + this.baseT;\n this.renderFrame(this.lastT, this.seed);\n }\n\n renderFrame(T: number, seed: number): void {\n this.renderedT = T;\n const resolved = resolveSegment(this.seq, T + this.clockOffset, { releasedBelow: this.releasedBelow });\n const { index, localT } = resolved;\n\n // Check if the *previous* segment has a morph into this one\n const prevIdx = index > 0 ? index - 1 : -1;\n const morphActive = prevIdx >= 0\n && this.canMorph(prevIdx)\n && localT < this.morphDur(prevIdx);\n\n if (morphActive) {\n // Morph in progress: keep the child keyed to the chain root\n // (preserves its seed/entity placement through chained morphs).\n const chainRoot = this.morphChainRoot(index);\n this.morphFromIndex = prevIdx;\n this.activeIndex = index;\n\n // Release all children except the chain root's slot\n for (let i = 0; i < this.children.length; i++) {\n if (i !== chainRoot) this.releaseChild(i);\n }\n\n const child = this.ensureChild(chainRoot);\n const dur = this.morphDur(prevIdx);\n const k = easeSmooth(localT / dur);\n const specA = this.childScene(prevIdx);\n const specB = this.childScene(index);\n child.hotSwapPaint(lerpSpec(specA, specB, k));\n child.renderFrame(localT, this.childSeed(chainRoot, seed));\n } else {\n // No morph (or morph complete). If we were morphing, finalize.\n if (this.morphFromIndex >= 0) {\n // Morph just completed — release the chain-root child.\n const oldRoot = this.morphChainRoot(this.morphFromIndex);\n this.releaseChild(oldRoot);\n if (oldRoot !== this.morphFromIndex) this.releaseChild(this.morphFromIndex);\n this.morphFromIndex = -1;\n }\n\n if (index !== this.activeIndex) {\n for (let i = 0; i < this.children.length; i++) {\n if (i !== index) this.releaseChild(i);\n }\n this.activeIndex = index;\n }\n\n // Determine the effective seed: if this segment was reached via a\n // morph chain, use the chain-root's seed so entity placement is\n // continuous across all morphed segments and seeks match playthrough.\n const chainRoot = this.morphChainRoot(index);\n const useMorphSeed = chainRoot < index;\n const effSeed = useMorphSeed ? this.childSeed(chainRoot, seed) : this.childSeed(index, seed);\n\n // If using morph seed, mount the child with the chain root's scene+seed\n // but immediately hot-swap to the current segment's spec.\n let child: SpecInstance;\n if (useMorphSeed && !this.children[index]) {\n const rootScene = this.childScene(chainRoot);\n child = new SpecInstance(rootScene, this.childCtx);\n this.children[index] = child;\n child.setPaused(true);\n child.hotSwapSpec(this.childScene(index));\n } else {\n child = this.ensureChild(index);\n }\n child.renderFrame(localT, effSeed);\n }\n }\n\n setPaused(paused: boolean): void {\n this.paused = paused;\n if (paused) this.stop();\n else this.start();\n // Do NOT forward pause=false to children — that would start SpecInstance\n // rAF loops alongside SequenceInstance.loop (double clock, wrong localT).\n // Children stay paused; the parent loop is the sole driver.\n for (const child of this.children) {\n child?.setPaused(true);\n }\n }\n\n resize(width: number, height: number, dpr?: number): void {\n // Children are created lazily (first rAF tick, segment switches, morph\n // finalization), so the new size must outlive the children that exist right\n // now. Without this, a resize while a slot is empty is forgotten and the\n // next child mounts at the stale mount-time size — a viewer that mounted\n // in a hidden/unpainted tab (width 0) stays a 1×1 canvas forever, and a\n // segment cut after any resize snaps back to the old dimensions.\n this.childCtx.width = width;\n this.childCtx.height = height;\n if (dpr !== undefined) this.childCtx.dpr = dpr;\n for (const child of this.children) {\n child?.resize(width, height, dpr);\n }\n }\n\n applyTrack(track: ControlTrack): void {\n const deltas = (track?.deltas ?? []) as unknown as SteerDelta[];\n const segDelta = deltas.find((d) => d.path === 'sequence.segment');\n if (segDelta !== undefined && typeof segDelta.value === 'number') {\n const idx = Math.max(0, Math.min(this.seq.segments.length - 1, Math.round(segDelta.value as number)));\n // Displace the clock so T + offset == the target segment's start: the\n // segment begins at localT 0 (its `life.enter` build replays) and the\n // next animation frame resolves to the same segment instead of snapping\n // back to whatever the wall clock said. The steer also releases every\n // `advance: 'input'` hold before the target; holds at and after it stay\n // armed, so steering backwards re-arms the ones in between.\n this.clockOffset = segmentStart(this.seq, idx) - this.renderedT;\n this.releasedBelow = idx;\n this.renderFrame(this.renderedT, this.seed);\n }\n\n const childDeltas = deltas.filter((d) => d.path !== 'sequence.segment');\n if (childDeltas.length > 0 && this.activeIndex >= 0) {\n const child = this.children[this.activeIndex];\n child?.applyTrack({ ...track, deltas: childDeltas as unknown as ParamDelta[] });\n }\n }\n\n dispose(): void {\n this.stop();\n for (let i = 0; i < this.children.length; i++) {\n this.releaseChild(i);\n }\n if (this.canvas) this.canvas.remove();\n }\n}\n\nfunction sequenceManifest(seq: IdleSequence): SaverManifest {\n const maxTotal = seq.segments.reduce((max, s) => {\n const t = s.scene.layers.reduce((n, l) => n + l.count, 0);\n return Math.max(max, t);\n }, 0);\n const costTier = maxTotal < 30 ? 'idle' : maxTotal < 150 ? 'low' : maxTotal < 400 ? 'medium' : 'high';\n return {\n id: seq.id,\n label: seq.label,\n timeModel: 'closed-form',\n passthrough: false,\n minBackend: 'canvas2d',\n costTier,\n motionIntensity: 'moderate',\n reducedMotionFallback: 'static',\n a11y: { flashSafe: true },\n workerReady: false,\n };\n}\n\nexport function compileSequence(spec: unknown): SaverPlugin {\n const valid = assertValidSequence(spec);\n return {\n manifest: sequenceManifest(valid),\n mount: (ctx: SaverContext) => new SequenceInstance(valid, ctx),\n spec: valid,\n };\n}\n","import type { IdleSequence } from './types';\n\nexport interface ResolvedSegment {\n index: number;\n localT: number;\n /** Cumulative start time of this segment in the global timeline. */\n startT: number;\n /**\n * Present (true) when the timeline has run past this segment's duration but\n * the segment has `advance: 'input'` and no input has released it yet — the\n * scene keeps animating (`localT` keeps growing) while the show waits for\n * the presenter.\n */\n held?: true;\n}\n\nexport interface ResolveOptions {\n /**\n * Segments below this index have been released by input: a `sequence.segment`\n * steer to index `n` counts as the presenter clicking past every hold before\n * `n`. `SequenceInstance` maintains this; callers resolving a bare timeline\n * leave it at 0, so every `advance: 'input'` hold is honoured.\n */\n releasedBelow?: number;\n}\n\n/** Global start time of segment `index` — the prefix sum of the durations before it. */\nexport function segmentStart(seq: IdleSequence, index: number): number {\n let t = 0;\n const n = Math.max(0, Math.min(index, seq.segments.length - 1));\n for (let i = 0; i < n; i++) t += seq.segments[i]!.duration ?? 0;\n return t;\n}\n\n/**\n * Map global time T to (segmentIndex, localT) via prefix sums of durations.\n * Segments are half-open: [start, start+duration). The final segment may omit\n * duration, in which case it holds indefinitely (T past the last timed segment\n * always resolves to the final one).\n *\n * `advance: 'input'` makes a timed segment hold at its end instead of yielding\n * to the next one — the clicker. `auto` (default) and `either` advance on the\n * timer. A hold is released by a `sequence.segment` steer (see\n * `ResolveOptions.releasedBelow`); the held scene keeps its clock running, so\n * `localT` grows past `duration` rather than freezing.\n *\n * With `loop: true`, T wraps modulo the total duration of all segments — but\n * only once every hold on the current lap has been released; after a wrap\n * every hold is armed again. If the final segment has no duration, looping is\n * over the timed prefix only — the durationless tail is unreachable in loop\n * mode (validated elsewhere).\n */\nexport function resolveSegment(seq: IdleSequence, T: number, opts: ResolveOptions = {}): ResolvedSegment {\n const { segments, loop } = seq;\n if (segments.length === 0) return { index: 0, localT: 0, startT: 0 };\n\n let totalTimed = 0;\n for (const seg of segments) {\n if (seg.duration != null) totalTimed += seg.duration;\n else break;\n }\n\n const t0 = Math.max(0, T);\n\n // Walk the timed prefix once; null means the clock ran off the end.\n const walk = (t: number, releasedBelow: number): ResolvedSegment | null => {\n let cumulative = 0;\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i]!;\n if (seg.duration == null) {\n // A durationless tail holds forever — except in loop mode, where it\n // is unreachable and the clock wraps instead.\n return loop ? null : { index: i, localT: t - cumulative, startT: cumulative };\n }\n if (t < cumulative + seg.duration) {\n return { index: i, localT: t - cumulative, startT: cumulative };\n }\n if (seg.advance === 'input' && i >= releasedBelow) {\n return { index: i, localT: t - cumulative, startT: cumulative, held: true };\n }\n cumulative += seg.duration;\n }\n return null;\n };\n\n const first = walk(t0, opts.releasedBelow ?? 0);\n if (first) return first;\n\n if (loop && totalTimed > 0) {\n // A fresh lap, with every hold armed again. Always modulo: subtracting\n // one lap (`t0 - totalTimed`) leaves later laps (T ≥ 2×totalTimed) still\n // past the end of the loop, so a released clock lands on the last hold\n // with a growing localT instead of wrapping.\n const wrapped = walk(t0 % totalTimed, 0);\n if (wrapped) return wrapped;\n }\n\n const last = segments.length - 1;\n const lastStart = totalTimed - (segments[last]!.duration ?? 0);\n return { index: last, localT: t0 - lastStart, startT: lastStart };\n}\n","import { createRng } from '@idle-screens/core';\nimport { backgroundLuma, backgroundRgb, colourSeparation, hexLuma, hexRgb, spriteHex } from './luma';\nimport { COHESION_T, cohesionOf, seamsWorthWarning } from './cohesion';\nimport { barFraction } from './shapes';\nimport { breakTextBlock, buildEntities, linkEdges, linkPairs, positionAt, textWidthEm, type Entity } from './simulate';\nimport { structuralSignature } from './steer';\nimport { LIMITS, type IdleSequence, type LayerSpec, type SaverSpec, type SpecWarning } from './types';\n\n/**\n * Minimum RGB-space colour distance (see `colourSeparation`) between a layer\n * and its background before the layer stops reading as a distinct thing.\n *\n * Calibrated against real specs rather than picked: a layer painted the literal\n * background hex measures 0.000, a near-background dark-on-dark layer ~0.036,\n * while every one of the 15 shipped examples and all 150 style-eval screens\n * clear it except the genuinely-flawed ones. Note this is a *colour* distance —\n * a Seurat-style gold-on-grey field separates by 0.39 here but only 0.013 in\n * luma, which is exactly why the measure is not luminance-based.\n */\nconst LOW_CONTRAST_FLOOR = 0.05;\n\n/**\n * A spec that declares `density: 'sparse'` is promising a mostly-empty frame.\n * Above this alpha-weighted coverage the promise is broken (2 % of the frame\n * is a comfortable field, not restraint — `lanterns` measures ~1.5 %).\n */\nconst SPARSE_DECLARED_MAX_COVERAGE = 0.02;\n\n/**\n * Non-blocking advisory warnings for a valid spec. Does NOT replace validateSpec —\n * call advise only on specs that have already passed validation.\n */\nexport function adviseSpec(\n spec: SaverSpec,\n viewport = { width: 1920, height: 1080 },\n /**\n * Sample point. `perceiveScene` forwards its own `t`/`seed` so the advisories\n * describe the same scene its other channels do — without them a caller\n * perceiving at t = 30 s would get `form` for that instant beside an\n * `overlap-seams` advisory computed for a different one.\n */\n opts: { t?: number; seed?: number } = {},\n): SpecWarning[] {\n const warnings: SpecWarning[] = [];\n const w = viewport.width;\n const h = viewport.height;\n const scale = spec.units === 'px' ? 1 : Math.min(w, h);\n const refVp = spec.referenceViewport ?? LIMITS.referenceViewport;\n // Mirror buildScene's maxTotal clamp: without it a dense scene above the\n // reference viewport is advised on more entities than the renderer will\n // build, and `perceiveScene` would pair a `form` channel counted one way\n // with an `overlap-seams` advisory counted the other. (Part of F49, which\n // tracks the same divergence for describeScene.)\n let countScale = scale > 1 ? Math.min(w, h) / refVp : 1;\n if (countScale > 1) {\n const rawTotal = spec.layers.reduce((sum, l) => sum + Math.round(l.count * countScale), 0);\n if (rawTotal > LIMITS.maxTotal) countScale *= LIMITS.maxTotal / rawTotal;\n }\n const rng = createRng(opts.seed ?? spec.seed ?? 42);\n const allEntities = spec.layers.map((l) => buildEntities(l, rng, w, h, scale, countScale));\n const bgLuma = backgroundLuma(spec);\n const bgRgb = backgroundRgb(spec);\n\n // Do overlapping layers actually merge? Computed once from the entities we\n // already built; the advisory below fires only on the case where the author\n // clearly wanted one shape and the paint settings defeat it.\n const cohesion = cohesionOf(\n spec.layers.map((layer, i) => ({ layer, entities: allEntities[i]! })),\n opts.t ?? COHESION_T, w, h,\n );\n\n let totalEntities = 0;\n let textLayerCount = 0;\n let motionLayerCount = 0;\n\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n const entities = allEntities[li]!;\n totalEntities += entities.length;\n\n const isText = layer.sprite.kind === 'text' || layer.sprite.kind === 'textBlock';\n const isStaticText = isText && layer.motion.type === 'static';\n if (isStaticText) textLayerCount++;\n if (layer.motion.type !== 'static') motionLayerCount++;\n\n const coh = cohesion[li]!;\n if (seamsWorthWarning(layer, coh, entities.length)) {\n warnings.push({\n path: `layers[${li}]`,\n code: 'overlap-seams',\n message:\n `entities bury ${Math.round((coh.overlap ?? 0) * 100)}% of each other's outlines, so this layer is drawn as one shape — `\n + `but ${coh.seamCause}, so every overlap paints a visible edge and it will read as a pile of sprites instead. `\n + 'A layer merges into a single silhouette only when it is one flat colour at alpha 1, hard-edged, with no blend and no pulse.',\n });\n }\n\n if (layer.trail && layer.motion.type === 'static') {\n warnings.push({\n path: `layers[${li}].trail`,\n code: 'trail-on-static',\n message: 'trail has no effect on static entities — they have no past positions to draw',\n });\n }\n\n if ((layer.sprite.kind === 'streak' || (layer.sprite.kind === 'stroke' && layer.sprite.orient)) && layer.motion.type === 'static') {\n warnings.push({\n path: `layers[${li}].sprite`,\n code: 'streak-on-static',\n message: `${layer.sprite.kind === 'streak' ? 'streak sprites orient' : 'an oriented stroke turns'} along the motion heading — static entities have none, so the heading contributes nothing${layer.spin ? ' (spin still rotates the mark)' : ' and it renders at angle 0'}`,\n });\n }\n\n if (layer.motion.type === 'wander' && layer.motion.coherence === 1 && entities.length >= 20) {\n warnings.push({\n path: `layers[${li}].motion.coherence`,\n code: 'full-coherence',\n message: 'coherence 1 makes every entity share identical harmonics — the layer moves as a rigid sheet. 0.5–0.8 reads as schooling',\n });\n }\n\n if (layer.sprite.kind === 'circle') {\n const maxR = entities.reduce((m, e) => Math.max(m, e.size / 2), 0);\n const maxAlpha = entities.reduce((m, e) => Math.max(m, e.alpha), 0);\n if (maxR * maxAlpha < 0.05) {\n warnings.push({\n path: `layers[${li}]`,\n code: 'invisible-layer',\n message: `layer's max visible radius (${maxR.toFixed(1)}px × ${maxAlpha.toFixed(2)} alpha) is below perceptual floor`,\n });\n }\n }\n\n // Colour separation: a layer painted the same brightness as the plate\n // behind it is invisible no matter how big or opaque it is. `invisible-layer`\n // above only measures radius × alpha, so a full-strength layer in a\n // background-matched colour passes every other check in this file.\n if (entities.length > 0 && layer.sprite.kind !== 'emoji') {\n // A palette layer is visible if ANY of its colours separates — flag only\n // when every colour it can paint with disappears into the plate.\n const seps = entities.map((e) => {\n const hex = spriteHex(layer, e);\n if (hex === null) return Infinity;\n return colourSeparation(layer, { rgb: hexRgb(hex), luma: hexLuma(hex) }, { rgb: bgRgb, luma: bgLuma });\n });\n const best = Math.max(...seps);\n if (best < LOW_CONTRAST_FLOOR) {\n const additive = layer.blend === 'lighter' || layer.blend === 'screen';\n warnings.push({\n path: `layers[${li}].sprite`,\n code: 'low-contrast-layer',\n message: additive\n ? `additive layer adds almost no light (luma ${best.toFixed(3)}) — a \"lighter\"/\"screen\" layer is only as visible as it is bright`\n : `layer colour is within ${best.toFixed(3)} of the background (floor ${LOW_CONTRAST_FLOOR}) — it will read as background, not as content`,\n });\n }\n }\n\n }\n\n // Alpha-weighted pixel coverage: how much of the viewport is \"visibly filled\"\n let totalCoverage = 0;\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n const entities = allEntities[li]!;\n for (const e of entities) {\n const r = e.size / 2;\n let pixArea: number;\n if (layer.sprite.kind === 'circle') {\n pixArea = Math.PI * r * r;\n } else if (layer.sprite.kind === 'bar') {\n pixArea = e.size * barFraction(layer.sprite, e.barIndex ?? 0) * (e.size2 ?? e.size * 0.2);\n } else if (layer.sprite.kind === 'textBlock') {\n const fsPx = layer.sprite.fontSize * scale;\n const lh = (layer.sprite.lineHeight ?? 1.4) * fsPx;\n const maxWPx = layer.sprite.maxWidth * scale;\n const lines = breakTextBlock(layer.sprite.text, maxWPx / fsPx);\n pixArea = maxWPx * lines.length * lh * 0.55;\n } else {\n pixArea = e.size * e.size; // text/emoji: approximate as square of font size\n }\n // Sparse-event layers are lit only for `life` of every `every` ms, at a\n // mean envelope of ~½, and at a mean grown size — judge their coverage\n // by that duty, not by whichever instant we happen to sample.\n let duty = 1;\n if (layer.emit) {\n // Area scales with size², so the time-mean over a linear size ramp\n // a→b is mean(f²) = (a² + ab + b²) / 3, not mean(f)².\n const [ga, gb] = layer.emit.grow ?? [1, 1];\n const g2 = (ga * ga + ga * gb + gb * gb) / 3;\n duty = (Math.min(layer.emit.life, layer.emit.every) / layer.emit.every) * 0.5 * g2;\n }\n totalCoverage += (pixArea * e.alpha * duty) / (w * h);\n }\n // Link lines are visual coverage too (for Mystify-style scenes they ARE the scene).\n if (layer.links) {\n const positions = entities.map((e) => positionAt(e, 0, w, h));\n const maxDistPx = layer.links.maxDist * scale;\n const edges = linkEdges(layer.links, positions, maxDistPx, layer.wrap !== false, w, h);\n const defaultWidth = scale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const lwPx = (layer.links.width ?? defaultWidth) * scale;\n const la = layer.links.alpha ?? 1;\n for (const edge of edges) totalCoverage += (edge.dist * lwPx * la) / (w * h);\n }\n }\n\n // A declared `density` is read before either density advisory fires — and\n // then checked against the measurement, so the declaration cannot be used\n // to silence a scene that is empty by accident rather than by intent.\n const density = spec.density ?? 'normal';\n const wouldBeSparse = totalCoverage < 0.0005 && spec.layers.length > 0;\n if (wouldBeSparse && density !== 'sparse') {\n warnings.push({\n path: 'layers',\n code: 'sparse-scene',\n message: `alpha-weighted coverage is ${(totalCoverage * 100).toFixed(4)}% — scene will look empty on most displays`,\n });\n }\n\n if (totalEntities > 500 && density !== 'dense') {\n warnings.push({\n path: 'layers',\n code: 'dense-scene',\n message: `${totalEntities} entities — scene may feel crowded and hurt performance on low-end devices`,\n });\n }\n\n if (density === 'sparse' && totalCoverage > SPARSE_DECLARED_MAX_COVERAGE) {\n warnings.push({\n path: 'density',\n code: 'density-mismatch',\n message: `declared sparse but alpha-weighted coverage is ${(totalCoverage * 100).toFixed(2)}% — either the declaration or the scene is wrong`,\n });\n } else if (density === 'dense' && wouldBeSparse) {\n warnings.push({\n path: 'density',\n code: 'density-mismatch',\n message: `declared dense but alpha-weighted coverage is ${(totalCoverage * 100).toFixed(4)}% — the scene will look empty`,\n });\n }\n\n if (spec.layers.length > 0 && textLayerCount > 0 && motionLayerCount === 0) {\n const textRatio = textLayerCount / spec.layers.length;\n if (textRatio >= 0.8) {\n warnings.push({\n path: 'layers',\n code: 'text-heavy',\n message: 'most layers are static text — reads as a document, not a screensaver',\n });\n }\n }\n\n // Link starvation: links layer where few edges actually form.\n // Chain mode always forms its edges — only distance-gated modes can starve.\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n if (!layer.links || layer.links.mode === 'chain') continue;\n const entities = allEntities[li]!;\n const positions = entities.map((e) => positionAt(e, 0, w, h));\n const maxDist = layer.links.maxDist * scale;\n const pairs = linkPairs(positions, layer.links.k, maxDist, layer.wrap !== false, w, h);\n const maxPossible = Math.min(entities.length * layer.links.k, entities.length * (entities.length - 1) / 2);\n if (maxPossible > 0 && pairs.length / maxPossible < 0.1) {\n warnings.push({\n path: `layers[${li}].links`,\n code: 'link-starvation',\n message: `only ${pairs.length}/${maxPossible} possible edges formed — raise count or widen links.maxDist`,\n });\n }\n }\n\n // Motion variety: all entities in a layer have nearly identical velocity\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n if (layer.motion.type === 'static') continue;\n const entities = allEntities[li]!;\n if (entities.length < 3) continue;\n const speeds = entities.map((e) => Math.sqrt(e.vx * e.vx + e.vy * e.vy));\n const mean = speeds.reduce((a, b) => a + b, 0) / speeds.length;\n if (mean === 0) continue;\n const maxDev = Math.max(...speeds.map((s) => Math.abs(s - mean)));\n if (maxDev / mean < 0.05) {\n warnings.push({\n path: `layers[${li}].motion`,\n code: 'uniform-motion',\n message: 'all entities move at nearly identical speed — widen the speed range for visual variety',\n });\n }\n }\n\n // Composition balance: entities clustered in one region. Motions that sweep the\n // whole viewport (bounce, warp, path) have transient spawn positions that say\n // nothing about composition — exclude them from the centroid.\n const composed = spec.layers\n .map((l, li) => ({ l, ents: allEntities[li]! }))\n .filter(({ l }) => !['bounce', 'warp', 'path'].includes(l.motion.type))\n // Layer-parented orbits position relative to their parent (resolved at render\n // time) — their raw positionAt is an offset around (0,0), not a screen position.\n .filter(({ l }) => !(l.motion.type === 'orbit' && l.motion.center && 'layer' in l.motion.center));\n const composedCount = composed.reduce((s, c) => s + c.ents.length, 0);\n if (composedCount >= 8) {\n const positions = composed.flatMap(({ ents }) => ents.map((e) => positionAt(e, 0, w, h)));\n const cx = positions.reduce((s, p) => s + p.x, 0) / positions.length;\n const cy = positions.reduce((s, p) => s + p.y, 0) / positions.length;\n const offX = Math.abs(cx / w - 0.5);\n const offY = Math.abs(cy / h - 0.5);\n if (offX > 0.2 || offY > 0.2) {\n warnings.push({\n path: 'layers',\n code: 'off-center',\n message: `centroid at (${(cx / w).toFixed(2)}, ${(cy / h).toFixed(2)}) — composition is heavily offset from center`,\n });\n }\n }\n\n // Spatial text: the one layout bug an author without eyes makes most and\n // cannot detect — a caption that runs off the frame, a title painted over a\n // body. Only static text is judged (moving text has no fixed box). Boxes use\n // the character-class width table the textBlock line-breaker uses, so the\n // estimate is the renderer's own idea of the text, not a separate guess.\n const textBoxes: TextBoxAt[] = [];\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n const s = layer.sprite;\n if (layer.motion.type !== 'static') continue;\n if (s.kind !== 'text' && s.kind !== 'textBlock') continue;\n const label = layer.key ? `\\`${layer.key}\\`` : `layers[${li}]`;\n for (const e of allEntities[li]!) {\n const p = positionAt(e, 0, w, h);\n const box = s.kind === 'textBlock' ? textBlockBoxAt(s, p, w, h) : textBoxAt(s, e, p, spec, w, h);\n textBoxes.push({ li, label, ...box });\n }\n }\n\n // Off-screen: any edge past the viewport by more than 1% of that dimension\n // (the width table is approximate; a hairline overhang is not a finding).\n const tolX = w * 0.01;\n const tolY = h * 0.01;\n const offFlagged = new Set<number>();\n for (const b of textBoxes) {\n if (offFlagged.has(b.li)) continue;\n const edges: string[] = [];\n if (b.x0 < -tolX) edges.push(`left edge by ~${Math.round(-b.x0)}px`);\n if (b.x1 > w + tolX) edges.push(`right edge by ~${Math.round(b.x1 - w)}px`);\n if (b.y0 < -tolY) edges.push(`top edge by ~${Math.round(-b.y0)}px`);\n if (b.y1 > h + tolY) edges.push(`bottom edge by ~${Math.round(b.y1 - h)}px`);\n if (edges.length === 0) continue;\n offFlagged.add(b.li);\n warnings.push({\n path: `layers[${b.li}]`,\n code: 'text-off-screen',\n message: `${b.label} text runs off the ${edges.join(' and the ')} at ${w}×${h} — move position, or shrink fontSize / maxWidth`,\n });\n }\n\n // Overlap: two different static text layers whose boxes share more than 10%\n // of the smaller box. Reported once per layer pair, on the earlier layer.\n const pairFlagged = new Set<string>();\n for (let i = 0; i < textBoxes.length; i++) {\n for (let j = i + 1; j < textBoxes.length; j++) {\n const a = textBoxes[i]!;\n const b = textBoxes[j]!;\n if (a.li === b.li) continue;\n const pair = `${Math.min(a.li, b.li)}:${Math.max(a.li, b.li)}`;\n if (pairFlagged.has(pair)) continue;\n const ix = Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0);\n const iy = Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0);\n if (ix <= 0 || iy <= 0) continue;\n const smaller = Math.min((a.x1 - a.x0) * (a.y1 - a.y0), (b.x1 - b.x0) * (b.y1 - b.y0));\n if (smaller <= 0) continue;\n const share = (ix * iy) / smaller;\n if (share <= 0.1) continue;\n pairFlagged.add(pair);\n const [first, second] = a.li < b.li ? [a, b] : [b, a];\n warnings.push({\n path: `layers[${first.li}]`,\n code: 'text-overlap',\n message: `${first.label} and ${second.label} text boxes overlap (~${Math.round(share * 100)}% of the smaller one) — they will paint over each other; move one or shrink it`,\n });\n }\n }\n\n return warnings;\n}\n\ninterface TextBoxAt {\n li: number;\n label: string;\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n}\n\ntype Box = Pick<TextBoxAt, 'x0' | 'y0' | 'x1' | 'y1'>;\n\n/**\n * Box of one `text` entity, mirroring the renderer: a `font` with a px size is\n * used verbatim (scaled by the same viewport/reference ratio the renderer\n * applies), otherwise the seeded per-entity size; `align`/`baseline` move the\n * anchor; `maxWidth` is a hard cap because `fillText(text, x, y, maxWidth)`\n * squeezes the glyphs to fit.\n */\nfunction textBoxAt(\n s: Extract<LayerSpec['sprite'], { kind: 'text' }>,\n e: Entity,\n p: { x: number; y: number },\n spec: SaverSpec,\n w: number,\n h: number,\n): Box {\n const m = s.font ? /(\\d{1,5}(?:\\.\\d{1,4})?|\\.\\d{1,4})px/.exec(s.font) : null;\n const fontScale = spec.units === 'px' ? 1 : Math.min(w, h) / (spec.referenceViewport ?? LIMITS.referenceViewport);\n const fh = m ? Number(m[1]) * fontScale : e.size;\n const str = s.strings[e.spriteIndex] ?? s.strings[0] ?? '';\n let fw = textWidthEm(str) * fh;\n if (s.maxWidth) fw = Math.min(fw, s.maxWidth * (spec.units === 'px' ? 1 : Math.min(w, h)));\n const align = s.align ?? 'center';\n const baseline = s.baseline ?? 'middle';\n const x0 = align === 'left' ? p.x : align === 'right' ? p.x - fw : p.x - fw / 2;\n const y0 = baseline === 'top' ? p.y : baseline === 'bottom' ? p.y - fh : p.y - fh / 2;\n return { x0, y0, x1: x0 + fw, y1: y0 + fh };\n}\n\n/**\n * Box of a `textBlock`, mirroring the renderer: `position` is the block's\n * top-left, lines break with `breakTextBlock`, `align` moves the painted lines\n * inside the `maxWidth` box (not the box itself).\n */\nfunction textBlockBoxAt(\n s: Extract<LayerSpec['sprite'], { kind: 'textBlock' }>,\n p: { x: number; y: number },\n w: number,\n h: number,\n): Box {\n const unit = Math.min(w, h);\n const fsPx = s.fontSize * unit;\n const lh = (s.lineHeight ?? 1.4) * fsPx;\n const maxWPx = s.maxWidth * unit;\n const lines = breakTextBlock(s.text, maxWPx / fsPx);\n const maxLineW = lines.reduce((mx, l) => Math.max(mx, l.widthEm), 0) * fsPx;\n const totalH = lines.length * lh;\n const align = s.align ?? 'left';\n const x0 = align === 'center' ? p.x + (maxWPx - maxLineW) / 2 : align === 'right' ? p.x + maxWPx - maxLineW : p.x;\n return { x0, y0: p.y, x1: x0 + maxLineW, y1: p.y + totalH };\n}\n\n/**\n * Non-blocking advisory warnings for a validated sequence envelope.\n * Checks cross-segment luminance jumps at boundaries and per-segment advisories.\n */\nexport function adviseSequence(\n seq: IdleSequence,\n viewport = { width: 1920, height: 1080 },\n): SpecWarning[] {\n const warnings: SpecWarning[] = [];\n\n for (let i = 0; i < seq.segments.length; i++) {\n const segWarnings = adviseSpec(seq.segments[i]!.scene, viewport);\n for (const w of segWarnings) {\n warnings.push({ path: `segments[${i}].scene.${w.path}`, code: w.code, message: w.message });\n }\n }\n\n for (let i = 0; i < seq.segments.length - 1; i++) {\n const lumaA = backgroundLuma(seq.segments[i]!.scene);\n const lumaB = backgroundLuma(seq.segments[i + 1]!.scene);\n const delta = Math.abs(lumaA - lumaB);\n if (delta > 0.5) {\n warnings.push({\n path: `segments[${i}]`,\n code: 'boundary-luminance-jump',\n message: `background luminance jumps ${delta.toFixed(2)} at boundary ${i}→${i + 1} — may flash on cut`,\n });\n }\n\n const tr = seq.segments[i]!.transition;\n if (tr?.type === 'morph') {\n const sigA = structuralSignature(seq.segments[i]!.scene);\n const sigB = structuralSignature(seq.segments[i + 1]!.scene);\n if (sigA !== sigB) {\n warnings.push({\n path: `segments[${i}].transition`,\n code: 'morph-structural-mismatch',\n message: `segments ${i}→${i + 1} differ structurally: morph will fall back to cut`,\n });\n }\n }\n }\n\n return warnings;\n}\n","/**\n * Shared luminance helpers.\n *\n * These live in their own module because both `perceive` (which ranks layers by\n * visual weight) and `advise` (which warns about layers that can't be seen)\n * need the same notion of \"how bright is this thing\" — and `perceive` already\n * imports `advise`, so the dependency can only run one way.\n */\n\nimport type { Entity } from './simulate';\nimport { isShapedSprite } from './shapes';\nimport type { LayerSpec, SaverSpec } from './types';\n\n/** Perceptual luma (0..1) of a hex colour. */\nexport function hexLuma(hex: string): number {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n if (Number.isNaN(n)) return 0.7;\n const r = ((n >> 16) & 255) / 255;\n const g = ((n >> 8) & 255) / 255;\n const b = (n & 255) / 255;\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\nexport function spriteLuma(layer: LayerSpec, e: Entity): number {\n const s = layer.sprite;\n if (isShapedSprite(s)) {\n return hexLuma(s.colors?.[e.colorIndex] ?? s.color);\n }\n if (s.kind === 'text' || s.kind === 'textBlock') return hexLuma(s.color ?? '#e6e8ef');\n return 0.75; // emoji: mid-bright approximation\n}\n\n/** The hex a given entity actually paints with, or null for glyph sprites. */\nexport function spriteHex(layer: LayerSpec, e: Entity): string | null {\n const s = layer.sprite;\n if (isShapedSprite(s)) {\n return s.colors?.[e.colorIndex] ?? s.color;\n }\n if (s.kind === 'text' || s.kind === 'textBlock') return s.color ?? '#e6e8ef';\n return null; // emoji carry their own palette\n}\n\n/** Mean luma of the background plate a layer is drawn against. */\nexport function backgroundLuma(spec: SaverSpec): number {\n const bg = spec.background;\n if (!bg || bg.type === 'solid') return hexLuma(bg?.color ?? '#05050a');\n return bg.stops.reduce((s, st) => s + hexLuma(st.color), 0) / bg.stops.length;\n}\n\n/** Unpack a hex colour to 0..1 RGB. */\nexport function hexRgb(hex: string): { r: number; g: number; b: number } {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n if (Number.isNaN(n)) return { r: 0.7, g: 0.7, b: 0.7 };\n return { r: ((n >> 16) & 255) / 255, g: ((n >> 8) & 255) / 255, b: (n & 255) / 255 };\n}\n\n/** Mean RGB of the background plate. */\nexport function backgroundRgb(spec: SaverSpec): { r: number; g: number; b: number } {\n const bg = spec.background;\n if (!bg || bg.type === 'solid') return hexRgb(bg?.color ?? '#05050a');\n const acc = bg.stops.reduce(\n (s, st) => {\n const c = hexRgb(st.color);\n return { r: s.r + c.r, g: s.g + c.g, b: s.b + c.b };\n },\n { r: 0, g: 0, b: 0 },\n );\n const n = bg.stops.length || 1;\n return { r: acc.r / n, g: acc.g / n, b: acc.b / n };\n}\n\n/**\n * How far a layer's colour separates from its background, ignoring alpha and\n * geometry — purely \"can this be told apart from the plate behind it\".\n *\n * **This is a colour distance, not a luminance one, and that distinction is\n * load-bearing.** Equal-luminance/contrasting-hue is a real technique, not a\n * mistake: a Seurat-style field of golden `#e8c060` dots over a pale grey-blue\n * plate differs by 0.013 in luma and is perfectly visible, because the\n * separation lives entirely in hue. A luma-only test flags exactly the\n * pointillist screens it should leave alone.\n *\n * Additive blends are a different question again. Under `lighter`/`screen` the\n * sprite ADDS light, so a colour matching the background is still visible (it\n * doubles it); what makes such a layer vanish is having little light to add —\n * which genuinely is a luminance question.\n *\n * Alpha and radius are deliberately excluded — `invisible-layer` already owns\n * that axis, and the schema actively recommends faint atmospheric layers\n * (\"80 tiny soft circles at alpha 0.2\"), which must not be flagged here.\n */\nexport function colourSeparation(\n layer: LayerSpec,\n sprite: { rgb: { r: number; g: number; b: number }; luma: number },\n bg: { rgb: { r: number; g: number; b: number }; luma: number },\n): number {\n if (layer.blend === 'lighter' || layer.blend === 'screen') return sprite.luma;\n const dr = sprite.rgb.r - bg.rgb.r;\n const dg = sprite.rgb.g - bg.rgb.g;\n const db = sprite.rgb.b - bg.rgb.b;\n // Euclidean in RGB, normalised so 1 = black-to-white. Crude next to CIEDE2000\n // but it separates hue from value, which is the whole point here.\n return Math.sqrt((dr * dr + dg * dg + db * db) / 3);\n}\n","/**\n * Layer cohesion — does a layer read as ONE form, or as N separate marks?\n *\n * The gap this closes: every other perception channel reports a heavily\n * overlapping layer identically whether its sprites merge into a silhouette or\n * stay legible as individual discs. Luminance, coverage, dominance and the\n * braille map are all blind to it, because they measure ink, not edges. An\n * agent drawing a *shape* out of sprites therefore cannot tell success from\n * failure without publishing and looking at real pixels.\n *\n * Two independent facts decide it, so both are reported:\n *\n * - `overlap` — geometry. What fraction of a typical entity's outline is buried\n * inside a sibling. Scattered fields sit near 0; a deliberate mass sits high.\n * - `seamless` — paint. Whether an overlap between two of this layer's entities\n * paints as an invisible join. Only a hard-edged, fully opaque, single-colour,\n * un-blended layer merges; anything else shows every internal edge.\n *\n * Both are analytic, deterministic and renderer-free, like the rest of\n * `perceive.ts`.\n */\n\nimport { polygonArea, polygonPoints } from './shapes';\nimport { lifeAlphaAt, positionAt, rotationAt, sizeAt, type Entity } from './simulate';\nimport type { LayerSpec } from './types';\n\n/**\n * Above this mean covered-outline fraction a layer is treated as *trying* to be\n * one form rather than a field of marks.\n *\n * Calibrated against the shipped examples rather than picked. Measured across\n * all 42 fillable layers in `src/examples/`, the particle fields top out at\n * 0.154 (`facets/planes`; snowfall, lanterns and constellation are all 0.000,\n * `comets/stars` 0.001, `aquarium` 0.015, `procession/lanterns` 0.087), while\n * a layer authored as a silhouette — circles packed several times over their\n * own area, the idiom that draws a wave or a mountain — measures 0.79 to 0.85.\n * `aurora`'s wander curtains are the one shipped layer in the upper band, at\n * 0.892, and they are a deliberate overlapping wash. Nothing sits between\n * 0.154 and 0.786, so the exact threshold is not delicate.\n */\nconst MERGE_FLOOR = 0.35;\n\n/**\n * Below this base opacity a heavily overlapping layer is an atmospheric wash by\n * intent — the playbook's own advice is a field of soft circles at alpha ~0.2 —\n * and its visible internal edges are the effect, not a defect. The advisory\n * stays silent there; the numbers are still reported.\n */\nconst WASH_ALPHA_MAX = 0.45;\n\n/**\n * Sample time for a spec-level cohesion read, matching `perceiveScene`'s own\n * default so the advisory and the reported numbers agree on the usual call.\n * Past all typical `life.enter` staging; `grow` has had time to breathe.\n */\nexport const COHESION_T = 5000;\n\n/** Outline samples per entity. 24 resolves a half-covered circle to ~4 %. */\nconst OUTLINE_SAMPLES = 24;\n\n/**\n * Cap on the entities whose outlines are traced. Above this the measured set is\n * a deterministic stride through the layer (every k-th entity); coverage is\n * still tested against *every* sibling, so the estimate stays unbiased.\n */\nconst MAX_TRACED = 240;\n\n/** What a layer will read as on the wall. */\nexport type CohesionRead =\n /** Entities merge into a single silhouette — the layer draws a shape. */\n | 'mass'\n /** Entities overlap heavily but every overlap paints a visible edge. */\n | 'seamed'\n /** Entities stand alone — a field of marks, which most layers are. */\n | 'marks';\n\nexport interface LayerCohesion {\n layerIndex: number;\n key: string | undefined;\n /**\n * Mean fraction of an entity's outline covered by a same-layer sibling, 0..1.\n * `null` for sprite kinds where a merged silhouette is not a meaningful idea\n * (lines, glyphs and text: ring, streak, stroke, bar, emoji, text, textBlock).\n */\n overlap: number | null;\n /** Do this layer's overlaps paint as invisible joins? */\n seamless: boolean;\n /** Why not, when not — the field to act on. `null` when seamless. */\n seamCause: string | null;\n /** The verdict. `null` when `overlap` is null. */\n reads: CohesionRead | null;\n}\n\n// ---------------------------------------------------------------------------\n// Geometry\n// ---------------------------------------------------------------------------\n\ninterface Shape {\n cx: number;\n cy: number;\n /** Bounding radius, for the pairwise prefilter. */\n br: number;\n /** Enclosed area in px². Zero means the sprite paints nothing — collinear\n * polygon vertices reach here with a nonzero bounding radius. */\n area: number;\n contains(x: number, y: number): boolean;\n outline(n: number): Array<{ x: number; y: number }>;\n}\n\n/**\n * Outline samples are stepped this far INSIDE their own shape, as a fraction of\n * its bounding radius, before being tested. The question asked is then \"is the\n * ink just inside my edge also covered?\" rather than \"is a point exactly on my\n * edge inside a sibling?\".\n *\n * Exact-boundary tests are degenerate in both directions: coincident circles\n * sample every point exactly on the sibling's rim, and a polygon point lying on\n * a horizontal edge fails the ray-cast's `(a.y > y) !== (b.y > y)` test — two\n * flat rects sharing a y therefore reported their buried long edges as exposed.\n *\n * The step follows the edge's inward NORMAL, not the direction of the entity\n * centre: a concave polygon can have its centre outside its own filled area, so\n * a centre-directed nudge would push samples across the concavity and out of\n * the shape. Relative, so it holds at any viewport scale, and four orders of\n * magnitude below a pixel for any real sprite.\n */\nconst EDGE_INSET = 1e-4;\n\nfunction circleShape(cx: number, cy: number, r: number): Shape {\n return {\n cx, cy, br: r, area: Math.PI * r * r,\n contains: (x, y) => (x - cx) * (x - cx) + (y - cy) * (y - cy) < r * r,\n outline: (n) => Array.from({ length: n }, (_, i) => {\n const a = (i / n) * Math.PI * 2;\n const inner = r * (1 - EDGE_INSET); // inward normal of a circle is its radius\n return { x: cx + inner * Math.cos(a), y: cy + inner * Math.sin(a) };\n }),\n };\n}\n\n/** A convex or concave polygon given by absolute vertices. */\nfunction polyShape(cx: number, cy: number, raw: Array<{ x: number; y: number }>): Shape | null {\n // Drop consecutive coincident vertices up front. A zero-length edge has no\n // normal to step along, and leaving one in would emit a sample sitting\n // exactly on the boundary — the degeneracy EDGE_INSET exists to avoid.\n const abs = raw.filter((p, i) => {\n const q = raw[(i + 1) % raw.length]!;\n return Math.hypot(q.x - p.x, q.y - p.y) > 0;\n });\n // Fewer than three distinct vertices encloses no area — the renderer fills\n // nothing, so there is no silhouette to ask about.\n if (abs.length < 3) return null;\n\n let br = 0;\n for (const p of abs) br = Math.max(br, Math.hypot(p.x - cx, p.y - cy));\n const inside = (x: number, y: number): boolean => {\n let hit = false;\n for (let i = 0, j = abs.length - 1; i < abs.length; j = i++) {\n const a = abs[i]!;\n const b = abs[j]!;\n if ((a.y > y) !== (b.y > y) && x < ((b.x - a.x) * (y - a.y)) / (b.y - a.y) + a.x) hit = !hit;\n }\n return hit;\n };\n const seg = abs.map((p, i) => {\n const q = abs[(i + 1) % abs.length]!;\n return Math.hypot(q.x - p.x, q.y - p.y);\n });\n const perimeter = seg.reduce((a, b) => a + b, 0);\n // A shape thinner than the nominal inset would have BOTH normal candidates\n // overshoot it, so the step is bounded by the shortest edge as well as by\n // the bounding radius.\n const shortest = Math.min(...seg);\n const step = Math.min(br * EDGE_INSET, shortest * 0.25);\n const area = polygonArea(abs);\n if (!(area > 0)) return null; // collinear vertices enclose nothing\n return {\n cx, cy, br, area,\n contains: inside,\n /**\n * `n` points spread along the perimeter by ARC LENGTH, not one share per\n * edge — a long skinny rectangle has two edges carrying almost all of its\n * perimeter, and an equal-per-edge split would report a fully buried long\n * side as only a quarter covered. Each point is then stepped along its\n * edge's inward normal, whichever of the two candidates lands inside.\n */\n outline: (n) => {\n if (!(perimeter > 0)) return [];\n const out: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < n; i++) {\n let d = (i / n) * perimeter;\n let k = 0;\n while (k < seg.length - 1 && d > seg[k]!) { d -= seg[k]!; k++; }\n const a = abs[k]!;\n const b = abs[(k + 1) % abs.length]!;\n const len = seg[k]!;\n const f = d / len;\n const px = a.x + (b.x - a.x) * f;\n const py = a.y + (b.y - a.y) * f;\n const ux = (b.x - a.x) / len;\n const uy = (b.y - a.y) / len;\n // Back off until a candidate lands inside: a sliver thinner than even\n // the bounded step still gets the best sample available rather than\n // one outside its own shape.\n // A sample that cannot be placed strictly inside is DROPPED rather than\n // emitted on the boundary: an exact-edge point is the degeneracy the\n // inset exists to remove, and reporting it as exposed would be a guess.\n // The caller measures the samples it got, so an unmeasurable sliver\n // reports no outline instead of a wrong one.\n for (let t = step; t > 0; t /= 8) {\n const qx1 = px - uy * t;\n const qy1 = py + ux * t;\n if (inside(qx1, qy1)) { out.push({ x: qx1, y: qy1 }); break; }\n const qx2 = px + uy * t;\n const qy2 = py - ux * t;\n if (inside(qx2, qy2)) { out.push({ x: qx2, y: qy2 }); break; }\n if (t < step * 1e-3) break;\n }\n }\n return out;\n },\n };\n}\n\nfunction rectShape(cx: number, cy: number, halfW: number, halfH: number, rot: number): Shape | null {\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n const corner = (lx: number, ly: number) => ({ x: cx + lx * cos - ly * sin, y: cy + lx * sin + ly * cos });\n return polyShape(cx, cy, [\n corner(-halfW, -halfH), corner(halfW, -halfH), corner(halfW, halfH), corner(-halfW, halfH),\n ]);\n}\n\nfunction polygonShape(cx: number, cy: number, pts: Array<{ x: number; y: number }>, rot: number): Shape | null {\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n return polyShape(cx, cy, pts.map((p) => ({ x: cx + p.x * cos - p.y * sin, y: cy + p.x * sin + p.y * cos })));\n}\n\n/** The shape an entity paints at `t`, or null for kinds with no fillable area. */\nfunction shapeOf(layer: LayerSpec, e: Entity, t: number, w: number, h: number): Shape | null {\n const s = layer.sprite;\n if (s.kind !== 'circle' && s.kind !== 'rect' && s.kind !== 'polygon') return null;\n const p = positionAt(e, t, w, h);\n const sz = sizeAt(e, t);\n if (!(sz > 0)) return null;\n if (s.kind === 'circle') return circleShape(p.x, p.y, sz / 2);\n const rot = rotationAt(e, t);\n if (s.kind === 'rect') {\n const h2 = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz;\n return rectShape(p.x, p.y, sz / 2, h2 / 2, rot);\n }\n return polygonShape(p.x, p.y, polygonPoints(s, sz / 2), rot);\n}\n\n// ---------------------------------------------------------------------------\n// Paint: will an overlap show?\n// ---------------------------------------------------------------------------\n\n/**\n * Why this layer's overlaps paint a visible edge, or null when they vanish.\n *\n * Opacity is judged over the whole timeline, not this instant: a layer that\n * breathes with `pulse` is translucent at some point in every cycle, so its\n * seams appear even if the sampled frame happens to catch it at full alpha.\n */\nexport function seamCauseOf(layer: LayerSpec): string | null {\n const s = layer.sprite;\n if ((s.kind === 'circle' || s.kind === 'polygon') && s.soft) {\n return 'sprite.soft — radial falloff never forms a hard union';\n }\n if (s.kind === 'rect' && s.feather) {\n return 'rect.feather — a feathered edge never forms a hard union';\n }\n if (layer.blend) {\n return `blend: ${layer.blend} — overlaps composite instead of covering`;\n }\n const [lo, hi] = layer.alpha ?? [1, 1];\n if (lo < 1 || hi < 1) {\n return `alpha ${lo === hi ? lo : `${lo}..${hi}`} — every overlap paints a darker patch`;\n }\n if (layer.pulse && layer.pulse.amp > 0) {\n return 'pulse — the layer is translucent for part of every cycle';\n }\n // Only palette entries the seeded pick can actually reach count: a\n // `colorWeights` entry of 0 means that colour is never drawn, so it cannot\n // put a seam between two neighbours.\n const palette = 'colors' in s && Array.isArray(s.colors) ? s.colors : null;\n const weights = 'colorWeights' in s && Array.isArray(s.colorWeights) ? s.colorWeights : null;\n if (palette) {\n const aligned = weights !== null && weights.length === palette.length;\n const reachable = new Set(palette.filter((_, i) => !aligned || (weights![i] ?? 0) > 0));\n if (reachable.size > 1) {\n return `sprite.colors has ${reachable.size} reachable colours — neighbours of unlike colour show their join`;\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Public\n// ---------------------------------------------------------------------------\n\n/**\n * Per-layer cohesion for an already-built scene. Takes entities rather than a\n * spec so `perceiveScene` and `adviseSpec` can each pass the scene they already\n * built instead of building a third one.\n */\nexport function cohesionOf(\n layers: Array<{ layer: LayerSpec; entities: Entity[] }>,\n t: number,\n w: number,\n h: number,\n): LayerCohesion[] {\n return layers.map(({ layer, entities }, layerIndex) => {\n const seamCause = seamCauseOf(layer);\n const base: Omit<LayerCohesion, 'overlap' | 'reads'> = {\n layerIndex,\n key: layer.key,\n seamless: seamCause === null,\n seamCause,\n };\n\n // A layer staged out by `life` paints nothing at this instant, so asking\n // what it reads as has no answer — same as an unsupported sprite kind.\n if (lifeAlphaAt(layer.life, t) <= 0) return { ...base, overlap: null, reads: null };\n\n const shapes: Array<Shape | null> = entities.map((e) => shapeOf(layer, e, t, w, h));\n // A sprite that fills nothing is not a sibling: it cannot cover a\n // neighbour's outline and it must not make a lone sprite look like a pair.\n const solid = shapes.filter((x): x is Shape => x !== null && x.area > 0);\n // A single entity has no sibling to merge with, and unsupported kinds have\n // no fillable outline — in both cases the question does not apply.\n if (solid.length < 2) return { ...base, overlap: null, reads: null };\n\n const stride = Math.max(1, Math.ceil(solid.length / MAX_TRACED));\n let covered = 0;\n let traced = 0;\n for (let i = 0; i < solid.length; i += stride) {\n const self = solid[i]!;\n const pts = self.outline(OUTLINE_SAMPLES);\n if (pts.length === 0) continue; // no measurable outline; not 'exposed'\n let hit = 0;\n for (const p of pts) {\n for (let j = 0; j < solid.length; j++) {\n if (j === i) continue;\n const other = solid[j]!;\n const dx = p.x - other.cx;\n const dy = p.y - other.cy;\n if (dx * dx + dy * dy > other.br * other.br) continue; // cheap reject\n if (other.contains(p.x, p.y)) { hit++; break; }\n }\n }\n covered += hit / pts.length;\n traced++;\n }\n\n if (traced === 0) return { ...base, overlap: null, reads: null };\n const overlap = Number((covered / traced).toFixed(4));\n const reads: CohesionRead = overlap < MERGE_FLOOR ? 'marks' : seamCause === null ? 'mass' : 'seamed';\n return { ...base, overlap, reads };\n });\n}\n\n/**\n * True when a `seamed` layer is worth warning about: dense enough to be\n * deliberate, and opaque enough that it cannot be an atmospheric wash. Keeps\n * the advisory off the soft low-alpha glow fields the playbook recommends.\n */\nexport function seamsWorthWarning(layer: LayerSpec, c: LayerCohesion, entityCount: number): boolean {\n if (c.reads !== 'seamed' || entityCount < 6) return false;\n const [lo, hi] = layer.alpha ?? [1, 1];\n if ((lo + hi) / 2 < WASH_ALPHA_MAX) return false;\n return layer.blend !== 'lighter' && layer.blend !== 'screen';\n}\n","import { createRng } from '@idle-screens/core';\nimport { buildEntities, linkPairs, positionAt } from './simulate';\nimport { LIMITS, type SaverSpec } from './types';\n\nexport interface LayerSnapshot {\n key: string | undefined;\n count: number;\n centroid: { x: number; y: number };\n coverage: number;\n meanAlpha: number;\n linksDrawn: number | null;\n linksExpected: number | null;\n connectedComponents: number | null;\n isolatedNodes: number | null;\n}\n\nexport interface SceneSnapshot {\n t: number;\n viewport: { w: number; h: number };\n layers: LayerSnapshot[];\n warnings: string[];\n}\n\nexport interface SceneDescription {\n spec: { id: string; label: string; units: string };\n snapshots: SceneSnapshot[];\n}\n\n/**\n * Deterministic scene analysis at one or more time values. Reuses `buildEntities`\n * and `linkPairs` — no render needed. Returns structured data a non-vision model\n * can use to understand what a spec looks like when rendered.\n */\nexport function describeScene(\n spec: SaverSpec,\n options: {\n viewport?: { width: number; height: number };\n seed?: number;\n times?: number[];\n } = {},\n): SceneDescription {\n const { width: w, height: h } = options.viewport ?? { width: 1920, height: 1080 };\n const seed = options.seed ?? spec.seed ?? 42;\n const times = options.times ?? [0, 5000, 15000];\n const scale = spec.units === 'viewport' ? Math.min(w, h) : 1;\n const refVp = spec.referenceViewport ?? LIMITS.referenceViewport;\n const countScale = scale > 1 ? Math.min(w, h) / refVp : 1;\n\n const rng = createRng(seed);\n const builtLayers = spec.layers.map((layer) => ({\n layer,\n entities: buildEntities(layer, rng, w, h, scale, countScale),\n }));\n\n const snapshots: SceneSnapshot[] = times.map((t) => {\n const layerSnapshots: LayerSnapshot[] = builtLayers.map(({ layer, entities }) => {\n const positions = entities.map((e) => positionAt(e, t, w, h));\n const cx = positions.length > 0 ? positions.reduce((s, p) => s + p.x, 0) / positions.length : 0;\n const cy = positions.length > 0 ? positions.reduce((s, p) => s + p.y, 0) / positions.length : 0;\n\n // Coverage: fraction of viewport area covered by entity bounding circles\n let pixArea = 0;\n for (const e of entities) {\n const r = e.size / 2;\n pixArea += layer.sprite.kind === 'circle' ? Math.PI * r * r : e.size * e.size;\n }\n const coverage = pixArea / (w * h);\n const meanAlpha = entities.length > 0\n ? entities.reduce((s, e) => s + e.alpha, 0) / entities.length\n : 0;\n\n // Link analysis\n let linksDrawn: number | null = null;\n let linksExpected: number | null = null;\n let connectedComponents: number | null = null;\n let isolatedNodes: number | null = null;\n if (layer.links) {\n const maxDist = layer.links.maxDist * scale;\n const pairs = linkPairs(positions, layer.links.k, maxDist, layer.wrap !== false, w, h);\n linksDrawn = pairs.length;\n linksExpected = Math.min(entities.length * layer.links.k, entities.length * (entities.length - 1) / 2);\n // Connected components via union-find\n const parent = Array.from({ length: entities.length }, (_, i) => i);\n const find = (x: number): number => {\n while (parent[x] !== x) { parent[x] = parent[parent[x]!]!; x = parent[x]!; }\n return x;\n };\n for (const [a, b] of pairs) {\n const ra = find(a); const rb = find(b);\n if (ra !== rb) parent[ra] = rb;\n }\n const roots = new Set(entities.map((_, i) => find(i)));\n connectedComponents = roots.size;\n // Isolated = nodes with zero edges\n const degree = new Uint16Array(entities.length);\n for (const [a, b] of pairs) { degree[a]!++; degree[b]!++; }\n isolatedNodes = degree.filter((d) => d === 0).length;\n }\n\n return {\n key: layer.key,\n count: entities.length,\n centroid: { x: +(cx / w).toFixed(3), y: +(cy / h).toFixed(3) },\n coverage: +coverage.toFixed(4),\n meanAlpha: +meanAlpha.toFixed(3),\n linksDrawn,\n linksExpected,\n connectedComponents,\n isolatedNodes,\n };\n });\n\n // Warnings derived from the numbers\n const warnings: string[] = [];\n for (const ls of layerSnapshots) {\n const label = ls.key ?? `layer`;\n if (ls.coverage * ls.meanAlpha < 0.0005) {\n warnings.push(`${label}: effectively invisible (coverage×alpha=${(ls.coverage * ls.meanAlpha).toFixed(5)})`);\n }\n if (ls.linksDrawn !== null && ls.linksExpected !== null && ls.linksExpected > 0) {\n const ratio = ls.linksDrawn / ls.linksExpected;\n if (ratio < 0.1) {\n warnings.push(`${label}: link starvation — ${ls.linksDrawn}/${ls.linksExpected} edges formed`);\n }\n }\n if (ls.isolatedNodes !== null && ls.count > 0 && ls.isolatedNodes / ls.count > 0.5) {\n warnings.push(`${label}: ${ls.isolatedNodes}/${ls.count} nodes isolated — graph is disconnected`);\n }\n }\n\n return { t, viewport: { w, h }, layers: layerSnapshots, warnings };\n });\n\n return {\n spec: { id: spec.id, label: spec.label, units: spec.units ?? 'px' },\n snapshots,\n };\n}\n","/**\n * Perception tools for non-vision agents. Everything here is computed\n * ANALYTICALLY from the spec — positions, sizes, and alphas are pure functions\n * of (seed, t), so no canvas or renderer is involved: these run in Node, are\n * fully deterministic, and are cheap enough to call in an authoring loop.\n *\n * The design premise: a text model doesn't need mimicked eyes, it needs vision\n * translated into modalities it is already strong in —\n * - a compact PICTURE it can actually read (braille luminance map: each Unicode\n * braille char encodes a 2×4 dot cell, ~8× ASCII resolution per token),\n * - 1D structure (row/column luminance profiles — the skeleton of a composition),\n * - OBJECT-level ranking (dominance: where does the eye go),\n * - RELATIVE judgement (diffScenes: \"is B better than A\" beats \"is A good\"),\n * - MOTION as numbers (per-layer displacement stats).\n */\nimport { createRng } from '@idle-screens/core';\nimport { adviseSpec } from './advise';\nimport { cohesionOf, type LayerCohesion } from './cohesion';\nimport { backgroundLuma, hexLuma, spriteLuma } from './luma';\nimport { barBox, barFraction, pathLength, polygonArea, polygonFill, polygonPoints, strokeSamples, strokeTaper, strokeWidthPx } from './shapes';\nimport {\n alphaAt,\n breakTextBlock,\n buildEntities,\n headingAt,\n lifeAlphaAt,\n linkEdges,\n positionAt,\n revealState,\n rotationAt,\n sizeAt,\n type Entity,\n} from './simulate';\nimport { LIMITS, type LayerSpec, type SaverSpec } from './types';\n\n// ---------------------------------------------------------------------------\n// Calibration constants\n//\n// The two knobs that tune how closely this analytical model matches the real\n// canvas. Kept together at module level so a calibration pass has one place to\n// look — neither is a per-entity detail.\n// ---------------------------------------------------------------------------\n\n/**\n * How far an additive glow blooms past its radius, as a multiple of that radius.\n * A soft circle drawn with `lighter`/`screen` spreads well beyond its geometric\n * edge on the real canvas (shadowBlur halos, stacked soft discs), so a\n * hard-edged analytical disc badly under-reports coverage for glow-heavy scenes.\n *\n * First pass, tuned by intuition rather than measurement: it fixes the direction\n * and rough magnitude, not the exact number. A playground-calibrated value is\n * future work (docs/future-ideas.md G1).\n */\nconst GLOW_SPREAD = 2.4;\n\n/**\n * How much more visually prominent line-like ink is than the same area of fill.\n * Rings, streaks and link lines catch the eye far more than their pixel area\n * implies, so weighting dominance by raw area alone makes a bright ring lose to\n * a dim disc. Also a first-pass estimate.\n */\nconst LINE_SALIENCE = 3.5;\n\n/**\n * How many past-frame samples model the `ghosting` smear. The live renderer\n * composites every 60 fps frame with persistence `g`, so ink from m frames ago\n * survives at weight g^m; the analytic model samples that decay at GHOST_TAPS\n * points across the visible window (until weight falls below 1/255, capped at\n * LIMITS.maxGhostReplayFrames — the same bound as the renderer's seek warm-up\n * replay), each tap carrying its bracket's summed weight. More taps sharpen the\n * smear's shape; the total energy is set by `g`, not by this constant.\n */\nconst GHOST_TAPS = 12;\n\n// ---------------------------------------------------------------------------\n// Shared scene construction (mirrors describeScene/adviseSpec)\n// ---------------------------------------------------------------------------\n\ninterface BuiltScene {\n w: number;\n h: number;\n scale: number;\n layers: Array<{ layer: LayerSpec; entities: Entity[] }>;\n byKey: Map<string, Entity[]>;\n}\n\nexport interface PerceiveOptions {\n viewport?: { width: number; height: number };\n seed?: number;\n /** Sample time in ms. Default 5000 (past all typical life.enter staging). */\n t?: number;\n}\n\nfunction buildScene(spec: SaverSpec, opts: PerceiveOptions): BuiltScene {\n const { width: w, height: h } = opts.viewport ?? { width: 1920, height: 1080 };\n const seed = opts.seed ?? spec.seed ?? 42;\n const scale = spec.units === 'px' ? 1 : Math.min(w, h);\n const refVp = spec.referenceViewport ?? LIMITS.referenceViewport;\n let countScale = scale > 1 ? Math.min(w, h) / refVp : 1;\n if (countScale > 1) {\n const rawTotal = spec.layers.reduce((s, l) => s + Math.round(l.count * countScale), 0);\n if (rawTotal > LIMITS.maxTotal) countScale *= LIMITS.maxTotal / rawTotal;\n }\n const rng = createRng(seed);\n const layers = spec.layers.map((layer) => ({ layer, entities: buildEntities(layer, rng, w, h, scale, countScale) }));\n const byKey = new Map<string, Entity[]>();\n for (const { layer, entities } of layers) if (layer.key) byKey.set(layer.key, entities);\n return { w, h, scale, layers, byKey };\n}\n\n/** Position with layer-parented-orbit resolution (matches the renderer). */\nfunction posOf(scene: BuiltScene, e: Entity, t: number): { x: number; y: number } {\n const p = positionAt(e, t, scene.w, scene.h);\n if (e.orbitParent) {\n const parent = scene.byKey.get(e.orbitParent)?.[0];\n if (parent) {\n const pp = positionAt(parent, t, scene.w, scene.h);\n p.x += pp.x;\n p.y += pp.y;\n }\n }\n return p;\n}\n\n/**\n * Text bounding box + anchor, matching the renderer's font rule: a CSS\n * shorthand containing a px size overrides the seeded per-entity size.\n * Returns the box CENTRE (accounting for align/baseline) and half-extents.\n */\nfunction textBox(\n s: Extract<LayerSpec['sprite'], { kind: 'text' }>,\n e: Entity,\n p: { x: number; y: number },\n): { cx: number; cy: number; halfX: number; halfY: number } {\n const m = s.font ? /(\\d+(?:\\.\\d+)?)px/.exec(s.font) : null;\n const fh = m ? Number(m[1]) : e.size;\n const str = s.strings[e.spriteIndex] ?? s.strings[0] ?? '';\n const fw = Math.max(fh, 0.62 * fh * Math.min(str.length, 48));\n const align = s.align ?? 'center';\n const baseline = s.baseline ?? 'middle';\n return {\n cx: align === 'left' ? p.x + fw / 2 : align === 'right' ? p.x - fw / 2 : p.x,\n cy: baseline === 'top' ? p.y + fh * 0.6 : baseline === 'bottom' ? p.y - fh * 0.6 : p.y,\n halfX: fw / 2,\n halfY: fh * 0.6,\n };\n}\n\nfunction textBlockBox(\n s: Extract<LayerSpec['sprite'], { kind: 'textBlock' }>,\n _e: Entity,\n p: { x: number; y: number },\n w: number,\n h: number,\n): { cx: number; cy: number; halfX: number; halfY: number } {\n const unitScale = Math.min(w, h);\n const fsPx = s.fontSize * unitScale;\n const lh = (s.lineHeight ?? 1.4) * fsPx;\n const maxWPx = s.maxWidth * unitScale;\n const maxWEm = maxWPx / fsPx;\n const lines = breakTextBlock(s.text, maxWEm);\n const totalH = lines.length * lh;\n const maxLineW = lines.reduce((m, l) => Math.max(m, l.widthEm), 0) * fsPx;\n const align = s.align ?? 'left';\n const cx = align === 'center' ? p.x + maxWPx / 2\n : align === 'right' ? p.x + maxWPx - maxLineW / 2\n : p.x + maxLineW / 2;\n return {\n cx,\n cy: p.y + totalH / 2,\n halfX: maxLineW / 2,\n halfY: totalH / 2,\n };\n}\n\n/**\n * Effective reveal fraction of a textBlock at time t (1 = fully shown).\n * Mirrors the renderer's `revealState` exactly — same line breaking, same\n * grapheme counting — so the perceived ink matches the painted ink.\n */\nfunction textBlockRevealFraction(\n s: Extract<LayerSpec['sprite'], { kind: 'textBlock' }>,\n w: number,\n h: number,\n t: number,\n): number {\n if (!s.reveal) return 1;\n const unitScale = Math.min(w, h);\n const maxWEm = (s.maxWidth * unitScale) / (s.fontSize * unitScale);\n const lines = breakTextBlock(s.text, maxWEm);\n const rs = revealState(lines, s.reveal, t);\n if (rs.glyphAlphas) {\n // glyphFade paints partial-alpha glyphs, so the ink fraction is the mean\n // glyph alpha, not the frontier progress.\n let sum = 0;\n let n = 0;\n for (const line of rs.glyphAlphas) for (const a of line) { sum += a; n++; }\n return n > 0 ? sum / n : 1;\n }\n return rs.progress;\n}\n\n// ---------------------------------------------------------------------------\n// Luminance grid\n// ---------------------------------------------------------------------------\n\nexport interface LuminanceGrid {\n cols: number;\n rows: number;\n /** Row-major luminance 0..1 including the background. */\n cells: number[];\n /** Per-row background luminance (what an empty scene would be). */\n background: number[];\n meanLuminance: number;\n /** Fraction of cells deviating perceptibly (> 0.03) from the background. */\n coverage: number;\n /** Deviation-weighted centre of visual mass as viewport fractions, or null for a flat scene. */\n centroid: { x: number; y: number } | null;\n /** Mean deviation-from-background per row/column — 1D transects of the composition. */\n rowProfile: number[];\n colProfile: number[];\n}\n\nexport interface LuminanceGridOptions extends PerceiveOptions {\n /** Grid resolution. Defaults 80×48 (→ a 40×12 braille map). */\n cols?: number;\n rows?: number;\n}\n\n/**\n * Sample the spec into a coarse luminance image — analytically, no renderer.\n * Persistence is modeled, not simulated: because positions are pure functions\n * of (seed, t), `ghosting` is a decayed sum of past-frame splats (weight g^m\n * for ink m frames old, mirroring the renderer's warm-up replay) and `trail`\n * re-uses drawTrail's sampling — past positions with decaying alpha and\n * shrinking radius. Remaining approximations (documented, deliberate): soft\n * circles use a linear falloff, background drift is sampled at its rest\n * position. Good enough to perceive composition, focus, balance — and now\n * smear.\n */\nexport function luminanceGrid(spec: SaverSpec, opts: LuminanceGridOptions = {}): LuminanceGrid {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const cols = Math.max(8, Math.min(200, opts.cols ?? 80));\n const rows = Math.max(8, Math.min(200, opts.rows ?? 48));\n const { w, h, scale } = scene;\n const cellW = w / cols;\n const cellH = h / rows;\n\n // Background: vertical gradient (or solid) + optional bottom band.\n const bg = spec.background;\n const bgRow: number[] = new Array(rows).fill(0);\n if (!bg || bg.type === 'solid') {\n bgRow.fill(hexLuma(bg?.color ?? '#05050a'));\n } else {\n const stops = [...bg.stops].sort((a, b) => a.at - b.at);\n for (let r = 0; r < rows; r++) {\n const y = (r + 0.5) / rows;\n let lum: number;\n if (y <= stops[0]!.at) lum = hexLuma(stops[0]!.color);\n else if (y >= stops[stops.length - 1]!.at) lum = hexLuma(stops[stops.length - 1]!.color);\n else {\n let i = 0;\n while (i < stops.length - 1 && stops[i + 1]!.at < y) i++;\n const a = stops[i]!;\n const b = stops[i + 1]!;\n const k = b.at === a.at ? 0 : (y - a.at) / (b.at - a.at);\n lum = hexLuma(a.color) + (hexLuma(b.color) - hexLuma(a.color)) * k;\n }\n bgRow[r] = lum;\n }\n if (bg.band) {\n const bandPx = bg.band.height * (spec.units === 'px' ? 1 : Math.min(w, h));\n const fromRow = Math.max(0, Math.floor((h - bandPx) / cellH));\n for (let r = fromRow; r < rows; r++) bgRow[r] = hexLuma(bg.band.color);\n }\n }\n\n const cells = new Array<number>(cols * rows);\n for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) cells[r * cols + c] = bgRow[r]!;\n\n const compose = (idx: number, lum: number, a: number, blend: LayerSpec['blend']): void => {\n const cur = cells[idx]!;\n if (blend === 'lighter' || blend === 'screen') cells[idx] = Math.min(1, cur + lum * a);\n else if (blend === 'multiply') cells[idx] = cur * (1 - a * (1 - lum));\n else cells[idx] = cur * (1 - a) + lum * a;\n };\n\n // Afterglow dots behind a moving entity — the analytic mirror of the\n // renderer's drawTrail: past positions sampled with decaying alpha and\n // shrinking radius, stopping at wrap seams.\n const splatTrail = (layer: LayerSpec, e: Entity, tPass: number, lifeA: number, alphaScale: number): void => {\n const trail = layer.trail;\n if (!trail) return;\n const fade = trail.fade ?? 1;\n const n = Math.min(Math.ceil(trail.length / 50), LIMITS.maxTrailSamples);\n const headAlpha = alphaAt(e, tPass) * lifeA;\n const headSize = sizeAt(e, tPass);\n const lum = spriteLuma(layer, e);\n const soft = layer.sprite.kind === 'circle' && !!layer.sprite.soft;\n const wrapOn = layer.wrap !== false;\n const head = posOf(scene, e, tPass);\n let prevX = head.x;\n let prevY = head.y;\n for (let s = 1; s <= n; s++) {\n const k = s / n;\n const pastT = tPass - k * trail.length;\n if (pastT < 0) break;\n const pos = posOf(scene, e, pastT);\n if (wrapOn && (Math.abs(pos.x - prevX) > w / 2 || Math.abs(pos.y - prevY) > h / 2)) break;\n prevX = pos.x;\n prevY = pos.y;\n const a = headAlpha * (1 - k * fade) * alphaScale;\n if (a <= 0.004) break;\n const rad = (headSize / 2) * (1 - k * 0.7);\n if (rad < 0.2) break;\n const c0 = Math.max(0, Math.floor((pos.x - rad) / cellW));\n const c1 = Math.min(cols - 1, Math.floor((pos.x + rad) / cellW));\n const r0 = Math.max(0, Math.floor((pos.y - rad) / cellH));\n const r1 = Math.min(rows - 1, Math.floor((pos.y + rad) / cellH));\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const dx = (c + 0.5) * cellW - pos.x;\n const dy = (r + 0.5) * cellH - pos.y;\n const d = Math.sqrt(dx * dx + dy * dy);\n if (d > rad + Math.min(cellW, cellH) / 2) continue;\n const wgt = soft ? Math.max(0.1, 1 - d / Math.max(rad, 1e-6)) : 1;\n compose(r * cols + c, lum, Math.min(1, a * wgt), layer.blend);\n }\n }\n }\n };\n\n // One composite pass at time tPass with all ink scaled by alphaScale — the\n // analytic mirror of the renderer's paintFrame. Ghost passes call this with\n // decayed weights; the live frame calls it with alphaScale 1.\n const splatPass = (tPass: number, alphaScale: number): void => {\n for (const { layer, entities } of scene.layers) {\n const lifeA = lifeAlphaAt(layer.life, tPass);\n if (lifeA <= 0) continue;\n\n for (const e of entities) {\n splatTrail(layer, e, tPass, lifeA, alphaScale);\n const a = Math.min(1, alphaAt(e, tPass) * lifeA) * alphaScale;\n if (a <= 0.004) continue;\n const lum = spriteLuma(layer, e);\n const p = posOf(scene, e, tPass);\n const sz = sizeAt(e, tPass);\n const s = layer.sprite;\n\n if (s.kind === 'stroke') {\n // Stamp along the sampled path, rotated like the renderer does.\n const pts = strokeSamples(s, sz / 2);\n let angle = rotationAt(e, tPass);\n if (s.orient) angle += headingAt(e, tPass, w, h) ?? 0;\n const ca = Math.cos(angle);\n const sa = Math.sin(angle);\n const lw = strokeWidthPx(s, scale);\n const stampAt = (q: { x: number; y: number }, u: number): void => {\n const x = p.x + q.x * ca - q.y * sa;\n const y = p.y + q.x * sa + q.y * ca;\n const c = Math.floor(x / cellW);\n const r = Math.floor(y / cellH);\n if (c < 0 || c >= cols || r < 0 || r >= rows) return;\n const taper = s.taper ? strokeTaper(u) : 1;\n compose(r * cols + c, lum, a * Math.min(1, (lw * taper) / cellH), layer.blend);\n };\n // Rasterize each segment at half-cell steps so a long stroke leaves a\n // continuous line of ink, not a dotted one.\n const step = Math.min(cellW, cellH) / 2;\n stampAt(pts[0]!, 0);\n for (let i = 1; i < pts.length; i++) {\n const q0 = pts[i - 1]!;\n const q1 = pts[i]!;\n const segLen = Math.hypot(q1.x - q0.x, q1.y - q0.y);\n const sub = Math.max(1, Math.ceil(segLen / step));\n for (let k = 1; k <= sub; k++) {\n const f = k / sub;\n stampAt({ x: q0.x + (q1.x - q0.x) * f, y: q0.y + (q1.y - q0.y) * f }, (i - 1 + f) / (pts.length - 1));\n }\n }\n continue;\n }\n if (s.kind === 'streak') {\n // Stamp along the segment from tail to head.\n const heading = headingAt(e, tPass, w, h) ?? 0;\n const steps = Math.max(2, Math.ceil(sz / Math.min(cellW, cellH)));\n const wgt = Math.min(1, ((s.width ?? (scale === 1 ? 2 : 0.002)) * scale) / cellH);\n for (let i = 0; i <= steps; i++) {\n const k = i / steps;\n const x = p.x - Math.cos(heading) * sz * (1 - k);\n const y = p.y - Math.sin(heading) * sz * (1 - k);\n const c = Math.floor(x / cellW);\n const r = Math.floor(y / cellH);\n if (c < 0 || c >= cols || r < 0 || r >= rows) continue;\n compose(r * cols + c, lum, a * k * wgt, layer.blend);\n }\n continue;\n }\n\n let centerX = p.x;\n let centerY = p.y;\n let halfX = sz / 2;\n let halfY = s.kind === 'rect' ? ((e.size2 ?? sz) * (e.size > 0 ? sz / e.size : 1)) / 2 : sz / 2;\n if (s.kind === 'text') {\n const box = textBox(s, e, p);\n centerX = box.cx;\n centerY = box.cy;\n halfX = box.halfX;\n halfY = box.halfY;\n } else if (s.kind === 'textBlock') {\n const box = textBlockBox(s, e, p, w, h);\n centerX = box.cx;\n centerY = box.cy;\n halfX = box.halfX;\n halfY = box.halfY;\n } else if (s.kind === 'bar') {\n const len = sz * barFraction(s, e.barIndex ?? 0);\n if (len <= 0) continue;\n const th = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz * 0.2;\n const box = barBox(s.direction ?? 'right', len, th);\n // The renderer rotates the bar about the entity with `spin`; rotate\n // the box's offset the same way and take the rotated box's AABB.\n const rot = rotationAt(e, tPass);\n const cr = Math.cos(rot);\n const sr = Math.sin(rot);\n centerX = p.x + box.cx * cr - box.cy * sr;\n centerY = p.y + box.cx * sr + box.cy * cr;\n halfX = Math.abs(box.halfX * cr) + Math.abs(box.halfY * sr);\n halfY = Math.abs(box.halfX * sr) + Math.abs(box.halfY * cr);\n }\n const circular = s.kind === 'circle' || s.kind === 'ring' || s.kind === 'polygon';\n const soft = (s.kind === 'circle' || s.kind === 'polygon') && !!s.soft;\n // A polygon fills only part of its disc; a feathered rect only part of\n // its box. Scale the splat weight rather than trace the outline.\n const shapeWeight = s.kind === 'polygon'\n ? polygonFill(s, sz / 2)\n : s.kind === 'rect' && s.feather\n ? (1 - s.feather / 2) * (1 - s.feather / 2)\n : 1;\n const additive = layer.blend === 'lighter' || layer.blend === 'screen';\n // Model the halo (see GLOW_SPREAD): reach past the radius with a quadratic\n // falloff outside the solid core, so coverage tracks what the audience\n // actually sees. Non-additive / hard-edged sprites are unchanged.\n const glow = soft && additive;\n const reachX = glow ? halfX * GLOW_SPREAD : halfX;\n const reachY = glow ? halfY * GLOW_SPREAD : halfY;\n const c0 = Math.max(0, Math.floor((centerX - reachX) / cellW));\n const c1 = Math.min(cols - 1, Math.floor((centerX + reachX) / cellW));\n const r0 = Math.max(0, Math.floor((centerY - reachY) / cellH));\n const r1 = Math.min(rows - 1, Math.floor((centerY + reachY) / cellH));\n // Glyphs don't fill their box — ink is sparse. A revealing textBlock\n // has proportionally less ink lit.\n const inkWeight = (s.kind === 'text' || s.kind === 'emoji' || s.kind === 'textBlock' ? 0.55 : 1)\n * (s.kind === 'textBlock' ? textBlockRevealFraction(s, w, h, t) : 1);\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const dx = (c + 0.5) * cellW - centerX;\n const dy = (r + 0.5) * cellH - centerY;\n if (circular) {\n const d = Math.sqrt(dx * dx + dy * dy);\n const reach = glow ? reachX : halfX;\n if (d > reach + Math.min(cellW, cellH) / 2) continue;\n if (s.kind === 'ring') {\n const strokeW = (s.width ?? (scale === 1 ? 2 : 0.002)) * scale;\n if (d < halfX - strokeW) continue;\n }\n let wgt: number;\n if (glow) {\n const core = halfX;\n if (d <= core) wgt = 1;\n else {\n const f = Math.max(0, 1 - (d - core) / Math.max(reachX - core, 1e-6));\n wgt = f * f;\n }\n } else {\n wgt = soft ? Math.max(0.1, 1 - d / Math.max(halfX, 1e-6)) : 1;\n }\n compose(r * cols + c, lum, a * wgt * shapeWeight, layer.blend);\n } else {\n compose(r * cols + c, lum, a * inkWeight * shapeWeight, layer.blend);\n }\n }\n }\n }\n\n // Link lines are visual mass too (for chain scenes they ARE the scene).\n if (layer.links) {\n const positions = entities.map((e) => posOf(scene, e, tPass));\n const maxDistPx = layer.links.maxDist * scale;\n const motionWraps = ['drift', 'rise', 'wander'].includes(layer.motion.type);\n const edges = linkEdges(layer.links, positions, maxDistPx, layer.wrap !== false && motionWraps, w, h);\n const la = Math.min(1, (layer.links.alpha ?? 0.6) * lifeA);\n const lum = layer.links.color ? hexLuma(layer.links.color) : 0.7;\n const defaultWidth = scale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const wgt = Math.min(1, ((layer.links.width ?? defaultWidth) * scale) / cellH) * la * alphaScale;\n for (const edge of edges) {\n const pi = positions[edge.i]!;\n const pj = positions[edge.j]!;\n const steps = Math.max(1, Math.ceil(edge.dist / Math.min(cellW, cellH)));\n for (let i = 0; i <= steps; i++) {\n const k = i / steps;\n const c = Math.floor((pi.x + (pj.x - pi.x) * k) / cellW);\n const r = Math.floor((pi.y + (pj.y - pi.y) * k) / cellH);\n if (c < 0 || c >= cols || r < 0 || r >= rows) continue;\n compose(r * cols + c, lum, wgt, layer.blend);\n }\n }\n }\n }\n };\n\n // Ghosting: the renderer composites each 60 fps frame over the last with\n // persistence g, so ink from m frames ago survives at weight g^m. Sample\n // that decay across the visible window (weight ≥ 1/255, capped at the same\n // maxGhostReplayFrames bound as the renderer's seek replay), oldest first so\n // newer ink composites on top. Each tap stands in for the frames in its\n // bracket and carries their summed surviving weight (geometric sum).\n const ghost = spec.ghosting ?? 0;\n if (ghost > 0) {\n const dt = 1000 / 60;\n const windowFrames = Math.min(Math.ceil(Math.log(1 / 255) / Math.log(ghost)), LIMITS.maxGhostReplayFrames);\n const taps = Math.min(GHOST_TAPS, windowFrames);\n const spacing = windowFrames / taps;\n for (let i = taps; i >= 1; i--) {\n const tPass = t - i * spacing * dt;\n if (tPass < 0) continue;\n const bracketWeight =\n (Math.pow(ghost, (i - 1) * spacing + 1) * (1 - Math.pow(ghost, spacing))) / (1 - ghost);\n splatPass(tPass, Math.min(1, bracketWeight));\n }\n }\n splatPass(t, 1);\n\n // Deviation stats\n let sum = 0;\n let covered = 0;\n let devSum = 0;\n let cxAcc = 0;\n let cyAcc = 0;\n const rowProfile = new Array<number>(rows).fill(0);\n const colProfile = new Array<number>(cols).fill(0);\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const v = cells[r * cols + c]!;\n sum += v;\n const dev = Math.abs(v - bgRow[r]!);\n if (dev > 0.03) covered++;\n devSum += dev;\n cxAcc += dev * (c + 0.5);\n cyAcc += dev * (r + 0.5);\n rowProfile[r]! += dev;\n colProfile[c]! += dev;\n }\n }\n for (let r = 0; r < rows; r++) rowProfile[r] = rowProfile[r]! / cols;\n for (let c = 0; c < cols; c++) colProfile[c] = colProfile[c]! / rows;\n\n return {\n cols,\n rows,\n cells,\n background: bgRow,\n meanLuminance: sum / (cols * rows),\n coverage: covered / (cols * rows),\n centroid: devSum > 1e-6 ? { x: cxAcc / devSum / cols, y: cyAcc / devSum / rows } : null,\n rowProfile,\n colProfile,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Braille rendering\n// ---------------------------------------------------------------------------\n\n// Ordered-dither thresholds for a 2×4 braille cell (spatially spread).\nconst DITHER: number[][] = [\n [0.5 / 8, 4.5 / 8],\n [2.5 / 8, 6.5 / 8],\n [1.5 / 8, 5.5 / 8],\n [3.5 / 8, 7.5 / 8],\n];\n// Braille dot bit for (row 0..3, col 0..1): dots 1-2-3-7 left, 4-5-6-8 right.\nconst DOT_BIT: number[][] = [\n [0x01, 0x08],\n [0x02, 0x10],\n [0x04, 0x20],\n [0x40, 0x80],\n];\n\n/**\n * Auto-exposure curve for a grid: most savers live in the bottom of the\n * luminance range, so cells are normalized (min → 98th percentile) with a\n * slight gamma before quantizing — like a camera exposing for the scene. Stats\n * on the grid itself stay raw.\n *\n * Shared by every renderer below, deliberately: if the curve is ever\n * recalibrated (e.g. once GLOW_SPREAD is tuned and coverage shifts), the braille\n * and density views must move together or they'd silently disagree about the\n * same scene.\n */\nfunction autoExpose(grid: LuminanceGrid): (v: number) => number {\n const sorted = [...grid.cells].sort((a, b) => a - b);\n const lo = sorted[0]!;\n const hi = Math.max(sorted[Math.floor(sorted.length * 0.98)]!, lo + 0.08);\n return (v: number): number => Math.pow(Math.max(0, Math.min(1, (v - lo) / (hi - lo))), 0.8);\n}\n\n/**\n * Encode a luminance grid as a braille \"image\": each output character is a 2×4\n * pixel cell, ordered-dithered so mid-tones render as dot density. A grid of\n * 80×48 becomes 12 lines of 40 chars — a picture a text model can read whole.\n */\nexport function renderBrailleMap(grid: LuminanceGrid): string {\n const expose = autoExpose(grid);\n\n const outRows: string[] = [];\n for (let br = 0; br < Math.floor(grid.rows / 4); br++) {\n let line = '';\n for (let bc = 0; bc < Math.floor(grid.cols / 2); bc++) {\n let bits = 0;\n for (let dr = 0; dr < 4; dr++) {\n for (let dc = 0; dc < 2; dc++) {\n const v = expose(grid.cells[(br * 4 + dr) * grid.cols + (bc * 2 + dc)]!);\n if (v > DITHER[dr]![dc]!) bits |= DOT_BIT[dr]![dc]!;\n }\n }\n line += String.fromCharCode(0x2800 + bits);\n }\n outRows.push(line);\n }\n return outRows.join('\\n');\n}\n\n// Density ramp, dark → bright. One char per grid cell (vs braille's 2×4), so a\n// higher-resolution grid reads as a sharper picture — the channel agents found\n// most legible for structure (rings, grids, text blocks) that braille blurs.\nconst DENSITY_RAMP = ' .:-=+*#%@';\n\n/**\n * Encode a luminance grid as a one-char-per-cell ASCII density map. Unlike the\n * braille map (compact, 2×4 dots/char) this is 1:1 with the grid, so pairing it\n * with a larger `cols`/`rows` gives a non-vision agent a genuinely higher-detail\n * read: 120×48 resolves concentric rings and text blocks braille smears into a\n * blob. Shares the braille map's auto-exposure so both views agree.\n */\nexport function renderDensityMap(grid: LuminanceGrid): string {\n const expose = autoExpose(grid);\n const ramp = DENSITY_RAMP;\n const lines: string[] = [];\n for (let r = 0; r < grid.rows; r++) {\n let line = '';\n for (let c = 0; c < grid.cols; c++) {\n const v = expose(grid.cells[r * grid.cols + c]!);\n line += ramp[Math.min(ramp.length - 1, Math.floor(v * ramp.length))]!;\n }\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Text sprite listing\n// ---------------------------------------------------------------------------\n\nexport interface TextSpriteInfo {\n layerIndex: number;\n key: string | undefined;\n /** The literal strings this layer draws (glyphs are invisible in the maps). */\n strings: string[];\n /** How many entities carry text. */\n count: number;\n /** Representative rendered glyph height in px at the sample viewport. */\n sizePx: number;\n /** For a revealing textBlock: effective 0..1 fraction shown at sample t. */\n revealed?: number;\n}\n\n/**\n * List every text layer's actual strings and rendered size. No grid resolution\n * renders glyphs legibly, so a non-vision agent otherwise can't tell whether the\n * words it wrote are on screen, how big, or whether they'll overlap. This closes\n * that blind spot analytically.\n */\nexport function textSprites(spec: SaverSpec, opts: PerceiveOptions = {}): TextSpriteInfo[] {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const out: TextSpriteInfo[] = [];\n scene.layers.forEach(({ layer, entities }, layerIndex) => {\n if (layer.sprite.kind === 'textBlock') {\n const s = layer.sprite;\n const unitScale = Math.min(scene.w, scene.h);\n const sizePx = s.fontSize * unitScale;\n const info: TextSpriteInfo = { layerIndex, key: layer.key, strings: [s.text], count: entities.length, sizePx: Math.round(sizePx) };\n if (s.reveal) info.revealed = Math.round(textBlockRevealFraction(s, scene.w, scene.h, t) * 100) / 100;\n out.push(info);\n return;\n }\n if (layer.sprite.kind !== 'text') return;\n const s = layer.sprite;\n const m = s.font ? /(\\d+(?:\\.\\d+)?)px/.exec(s.font) : null;\n const sizePx = m ? Number(m[1]) : entities[0] ? sizeAt(entities[0], t) : 0;\n out.push({ layerIndex, key: layer.key, strings: [...s.strings], count: entities.length, sizePx: Math.round(sizePx) });\n });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Dominance ranking\n// ---------------------------------------------------------------------------\n\nexport interface DominanceEntry {\n rank: number;\n layerIndex: number;\n key: string | undefined;\n /** Normalized share of total visual weight, 0..1 (all entries sum to 1). */\n share: number;\n entityCount: number;\n meanLuma: number;\n factors: { area: number; contrast: number; blendBoost: number; motionBoost: number };\n}\n\n/**\n * Rank layers by estimated visual weight — where the eye goes. Weight is\n * on-screen area × alpha, scaled by contrast against the background, an\n * additive-glow boost, and a motion boost. Link lines count as area, and so\n * does persistence ink: trail ribbons and ghosting smear are modeled as swept\n * ribbons, so a comet layer is ranked by its comet, not just its head.\n */\nexport function dominanceRanking(spec: SaverSpec, opts: PerceiveOptions = {}): DominanceEntry[] {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const { w, h, scale } = scene;\n\n const bgMean = backgroundLuma(spec);\n\n\n // Persistence smears every moving sprite into a ribbon of real visual mass —\n // for a comet layer the trail IS the visual event. Model both effects as\n // swept ribbons (path length × stroke width × mean surviving alpha), using\n // the straight-line displacement as a lower-bound path length and skipping\n // wrap seams. First-pass fidelity, same spirit as GLOW_SPREAD.\n const ghost = spec.ghosting ?? 0;\n let ghostWindowMs = 0;\n let ghostMeanW = 0;\n if (ghost > 0) {\n const dt = 1000 / 60;\n const frames = Math.min(Math.ceil(Math.log(1 / 255) / Math.log(ghost)), LIMITS.maxGhostReplayFrames);\n ghostWindowMs = frames * dt;\n ghostMeanW = (ghost * (1 - Math.pow(ghost, frames))) / (1 - ghost) / frames;\n }\n const sweptDistance = (e: Entity, spanMs: number): number => {\n const span = Math.min(spanMs, t);\n if (span <= 0) return 0;\n const p0 = posOf(scene, e, t - span);\n const p1 = posOf(scene, e, t);\n const dx = p1.x - p0.x;\n const dy = p1.y - p0.y;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) return 0; // wrapped: ambiguous\n return Math.sqrt(dx * dx + dy * dy);\n };\n\n const raw = scene.layers.map(({ layer, entities }, layerIndex) => {\n const lifeA = lifeAlphaAt(layer.life, t);\n let area = 0;\n let lumAcc = 0;\n for (const e of entities) {\n const a = alphaAt(e, t) * lifeA;\n const sz = sizeAt(e, t);\n const s = layer.sprite;\n let entArea: number;\n if (s.kind === 'circle') entArea = Math.PI * (sz / 2) * (sz / 2);\n else if (s.kind === 'ring') entArea = Math.PI * sz * ((s.width ?? (scale === 1 ? 2 : 0.002)) * scale) * LINE_SALIENCE;\n else if (s.kind === 'streak') entArea = sz * ((s.width ?? (scale === 1 ? 2 : 0.002)) * scale) * LINE_SALIENCE;\n else if (s.kind === 'rect') {\n const h2 = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz;\n const f = s.feather ? (1 - s.feather / 2) * (1 - s.feather / 2) : 1;\n entArea = sz * h2 * f;\n }\n else if (s.kind === 'polygon') entArea = polygonArea(polygonPoints(s, sz / 2));\n else if (s.kind === 'bar') {\n const th = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz * 0.2;\n entArea = sz * barFraction(s, e.barIndex ?? 0) * th;\n }\n else if (s.kind === 'stroke') {\n const meanTaper = s.taper ? 0.64 : 1; // ∫ sin(πu) du = 2/π\n entArea = pathLength(strokeSamples(s, sz / 2)) * strokeWidthPx(s, scale) * meanTaper * LINE_SALIENCE;\n }\n else if (s.kind === 'text') {\n const box = textBox(s, e, { x: 0, y: 0 });\n entArea = box.halfX * 2 * box.halfY * 2 * 0.55;\n } else if (s.kind === 'textBlock') {\n const box = textBlockBox(s, e, { x: 0, y: 0 }, w, h);\n entArea = box.halfX * 2 * box.halfY * 2 * 0.55 * textBlockRevealFraction(s, w, h, t);\n } else entArea = sz * sz * 0.55; // emoji\n\n area += entArea * a;\n\n // Trail ribbon: dots shrink to 0.3× and fade along the tail, so mean\n // width ≈ 0.65×size and mean alpha ≈ (1 - fade/2) of the head's.\n if (layer.trail) {\n const fade = layer.trail.fade ?? 1;\n const span = sweptDistance(e, layer.trail.length);\n area += span * sz * 0.65 * Math.max(0, 1 - fade / 2) * a;\n }\n // Ghost smear: ink from m frames back survives at g^m, so the sweep over\n // the visible window carries the window's mean surviving weight.\n if (ghost > 0) {\n area += sweptDistance(e, ghostWindowMs) * sz * ghostMeanW * a;\n }\n lumAcc += spriteLuma(layer, e);\n }\n if (layer.links && entities.length > 1) {\n const positions = entities.map((e) => posOf(scene, e, t));\n const motionWraps = ['drift', 'rise', 'wander'].includes(layer.motion.type);\n const edges = linkEdges(layer.links, positions, layer.links.maxDist * scale, layer.wrap !== false && motionWraps, w, h);\n const la = (layer.links.alpha ?? 0.6) * lifeA;\n const defaultWidth = scale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const lw = (layer.links.width ?? defaultWidth) * scale;\n for (const edge of edges) area += edge.dist * lw * la * LINE_SALIENCE;\n }\n const meanLuma = entities.length ? lumAcc / entities.length : 0;\n const contrast = Math.abs(meanLuma - bgMean) + 0.1;\n const blendBoost = layer.blend === 'lighter' || layer.blend === 'screen' ? 1.3 : layer.blend === 'multiply' ? 1.1 : 1;\n const motionBoost = layer.motion.type === 'static' ? 1 : 1.2;\n const weight = (area / (w * h)) * contrast * blendBoost * motionBoost;\n return { layerIndex, key: layer.key, weight, entityCount: entities.length, meanLuma, factors: { area: area / (w * h), contrast, blendBoost, motionBoost } };\n });\n\n const total = raw.reduce((s, r) => s + r.weight, 0) || 1;\n return raw\n .slice()\n .sort((a, b) => b.weight - a.weight)\n .map((r, i) => ({\n rank: i + 1,\n layerIndex: r.layerIndex,\n key: r.key,\n share: r.weight / total,\n entityCount: r.entityCount,\n meanLuma: r.meanLuma,\n factors: r.factors,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Motion stats\n// ---------------------------------------------------------------------------\n\n/**\n * Does each layer read as one merged form or as separate marks? The one thing\n * the luminance maps cannot answer — they measure ink, not edges, so a layer\n * that merged into a silhouette and one that stayed a pile of discs look\n * identical in every other channel. See `cohesion.ts`.\n */\nexport function layerCohesion(spec: SaverSpec, opts: PerceiveOptions = {}): LayerCohesion[] {\n const scene = buildScene(spec, opts);\n return cohesionOf(scene.layers, opts.t ?? 5000, scene.w, scene.h);\n}\n\nexport interface LayerMotionStats {\n layerIndex: number;\n key: string | undefined;\n /** Mean / max on-screen speed in px per second (wrap jumps excluded). */\n meanSpeed: number;\n maxSpeed: number;\n moving: boolean;\n}\n\n/** Per-layer displacement between t and t+dt — choreography as numbers. */\nexport function motionStats(spec: SaverSpec, opts: PerceiveOptions & { dt?: number } = {}): LayerMotionStats[] {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const dt = opts.dt ?? 500;\n const { w, h } = scene;\n return scene.layers.map(({ layer, entities }, layerIndex) => {\n let acc = 0;\n let max = 0;\n let n = 0;\n for (const e of entities) {\n const p0 = posOf(scene, e, t);\n const p1 = posOf(scene, e, t + dt);\n const dx = p1.x - p0.x;\n const dy = p1.y - p0.y;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) continue; // wrap seam\n const speed = (Math.sqrt(dx * dx + dy * dy) / dt) * 1000;\n acc += speed;\n max = Math.max(max, speed);\n n++;\n }\n const meanSpeed = n ? acc / n : 0;\n return { layerIndex, key: layer.key, meanSpeed, maxSpeed: max, moving: meanSpeed > 0.5 };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Scene diff — relative sight\n// ---------------------------------------------------------------------------\n\nconst REGION_NAMES = [\n 'top-left', 'top-center', 'top-right',\n 'mid-left', 'center', 'mid-right',\n 'bottom-left', 'bottom-center', 'bottom-right',\n] as const;\n\nfunction regionMeans(grid: LuminanceGrid): number[] {\n const out = new Array<number>(9).fill(0);\n const cnt = new Array<number>(9).fill(0);\n for (let r = 0; r < grid.rows; r++) {\n for (let c = 0; c < grid.cols; c++) {\n const region = Math.min(2, Math.floor((r / grid.rows) * 3)) * 3 + Math.min(2, Math.floor((c / grid.cols) * 3));\n out[region]! += Math.abs(grid.cells[r * grid.cols + c]! - grid.background[r]!);\n cnt[region]!++;\n }\n }\n return out.map((v, i) => (cnt[i]! ? v / cnt[i]! : 0));\n}\n\nexport interface SceneDiff {\n t: number;\n coverage: { a: number; b: number; delta: number };\n meanLuminance: { a: number; b: number; delta: number };\n /** Shift of the visual-mass centroid from A to B, in viewport fractions. */\n balanceShift: { dx: number; dy: number } | null;\n /** Mean deviation-from-background per third-by-third region, with deltas. */\n regions: Array<{ region: (typeof REGION_NAMES)[number]; a: number; b: number; delta: number }>;\n /** Dominance changes, matched by layer key (falls back to index). Sorted by |share delta|. */\n dominance: Array<{ key: string; rankA: number | null; rankB: number | null; shareA: number; shareB: number }>;\n advisories: { added: string[]; removed: string[] };\n}\n\n/**\n * Compare two specs at the same time/viewport — relative perception. A text\n * model is far better at \"is B better than A\" than \"is A good\"; this returns\n * the deltas that question needs: coverage, balance, per-region visual mass,\n * dominance-rank movement, and advisory changes.\n */\nexport function diffScenes(a: SaverSpec, b: SaverSpec, opts: LuminanceGridOptions = {}): SceneDiff {\n const t = opts.t ?? 5000;\n const gridA = luminanceGrid(a, opts);\n const gridB = luminanceGrid(b, opts);\n const regsA = regionMeans(gridA);\n const regsB = regionMeans(gridB);\n const domA = dominanceRanking(a, opts);\n const domB = dominanceRanking(b, opts);\n\n const nameOf = (d: DominanceEntry): string => d.key ?? `layer-${d.layerIndex}`;\n const names = new Set<string>([...domA.map(nameOf), ...domB.map(nameOf)]);\n const dominance = [...names].map((key) => {\n const inA = domA.find((d) => nameOf(d) === key);\n const inB = domB.find((d) => nameOf(d) === key);\n return {\n key,\n rankA: inA?.rank ?? null,\n rankB: inB?.rank ?? null,\n shareA: inA?.share ?? 0,\n shareB: inB?.share ?? 0,\n };\n }).sort((x, y) => Math.abs(y.shareB - y.shareA) - Math.abs(x.shareB - x.shareA));\n\n const codesA = new Set(adviseSpec(a).map((w) => w.code));\n const codesB = new Set(adviseSpec(b).map((w) => w.code));\n\n return {\n t,\n coverage: { a: gridA.coverage, b: gridB.coverage, delta: gridB.coverage - gridA.coverage },\n meanLuminance: { a: gridA.meanLuminance, b: gridB.meanLuminance, delta: gridB.meanLuminance - gridA.meanLuminance },\n balanceShift: gridA.centroid && gridB.centroid\n ? { dx: gridB.centroid.x - gridA.centroid.x, dy: gridB.centroid.y - gridA.centroid.y }\n : null,\n regions: REGION_NAMES.map((region, i) => ({ region, a: regsA[i]!, b: regsB[i]!, delta: regsB[i]! - regsA[i]! })),\n dominance,\n advisories: {\n added: [...codesB].filter((c) => !codesA.has(c)),\n removed: [...codesA].filter((c) => !codesB.has(c)),\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// One-call perception bundle\n// ---------------------------------------------------------------------------\n\nexport interface ScenePerception {\n t: number;\n /** The picture: a braille luminance map (each char = 2×4 pixels), compact. */\n braille: string;\n /**\n * A one-char-per-cell ASCII density map at the grid resolution — higher\n * fidelity than braille for structure (rings, grids, text blocks). Pair with\n * a larger `cols`/`rows` for a sharper read.\n */\n density: string;\n coverage: number;\n meanLuminance: number;\n centroid: { x: number; y: number } | null;\n rowProfile: number[];\n colProfile: number[];\n dominance: DominanceEntry[];\n motion: LayerMotionStats[];\n /** Per layer: merged silhouette, seamed overlap, or separate marks. */\n form: LayerCohesion[];\n /** Literal strings + sizes of any text layers (glyphs don't show in the maps). */\n text: TextSpriteInfo[];\n advisories: ReturnType<typeof adviseSpec>;\n}\n\n/**\n * Everything a non-vision agent needs to \"see\" a spec in one deterministic\n * call: the braille picture, a higher-res density map, composition transects,\n * dominance ranking, motion stats, the literal text on screen, and advisories.\n * Intended as the payload behind an MCP previewScene.\n */\nexport function perceiveScene(spec: SaverSpec, opts: LuminanceGridOptions = {}): ScenePerception {\n const grid = luminanceGrid(spec, opts);\n return {\n t: opts.t ?? 5000,\n braille: renderBrailleMap(grid),\n density: renderDensityMap(grid),\n coverage: grid.coverage,\n meanLuminance: grid.meanLuminance,\n centroid: grid.centroid,\n rowProfile: grid.rowProfile,\n colProfile: grid.colProfile,\n dominance: dominanceRanking(spec, opts),\n motion: motionStats(spec, opts),\n form: layerCohesion(spec, opts),\n text: textSprites(spec, opts),\n advisories: adviseSpec(spec, opts.viewport ?? { width: 1920, height: 1080 }, { t: opts.t, seed: opts.seed }),\n };\n}\n","import type { SaverSpec } from '../types';\n\n/**\n * Reproduces the hand-coded Fish Aquarium saver as pure DATA — the discriminating test\n * that the schema is actually expressive: two layers (fish drifting both ways at varied\n * speeds with a bob + flip, over a gradient with a seafloor band; bubbles rising with sway).\n */\nexport const AQUARIUM_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'aquarium',\n label: 'Aquarium',\n seed: 42,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a3a52' },\n { at: 0.6, color: '#062534' },\n { at: 1, color: '#02141d' },\n ],\n band: { color: '#0b1a12', height: 0.02222 },\n },\n layers: [\n {\n count: 14,\n sprite: { kind: 'emoji', glyphs: ['🐟', '🐠', '🐡', '🦈', '🐙'] },\n size: [0.03148, 0.06667],\n motion: { type: 'drift', speed: [0.02778, 0.1019], bidirectional: true, bob: 0.005556 },\n flip: true,\n },\n {\n count: 22,\n sprite: { kind: 'circle', radius: [0.001852, 0.006481], color: '#c8ebff' },\n motion: { type: 'rise', speed: [0.02222, 0.07222], sway: 0.007407 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Aurora Borealis: the \"fake fluid\" recipe — showcases `wander` motion (harmonic\n * drift) with high `coherence` so the curtain undulates as one body, `pulse.wave`\n * (a traveling shimmer across the star field), weighted palettes, additive blend,\n * and `ghosting` smearing the soft glows into continuous curtains of light.\n */\nexport const AURORA_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'aurora',\n label: 'Aurora',\n seed: 66,\n motionIntensity: 'calm',\n ghosting: 0.85,\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#02030d' },\n { at: 0.65, color: '#050a18' },\n { at: 1, color: '#0a1220' },\n ],\n drift: { period: 40000, amount: 0.1 },\n },\n layers: [\n {\n key: 'stars',\n count: 110,\n sprite: { kind: 'circle', radius: [0.0005, 0.0015], color: '#e8ecff', soft: true },\n motion: { type: 'static' },\n region: { y: [0, 0.75] },\n alpha: [0.2, 0.6],\n // A slow shimmer travels across the sky instead of stars twinkling independently.\n pulse: { amp: 0.25, period: 6000, wave: { wavelength: 0.5, angle: 15 } },\n },\n {\n key: 'curtain-green',\n count: 100,\n sprite: {\n kind: 'circle',\n radius: [0.055, 0.11],\n color: '#1fd68a',\n soft: true,\n colors: ['#1fd68a', '#2ee6c8', '#4bd1ff'],\n colorWeights: [5, 2, 1],\n },\n motion: { type: 'wander', speed: [0.004, 0.012], angle: 0, meander: 0.13, coherence: 0.7 },\n region: { y: [0.1, 0.42] },\n alpha: [0.04, 0.1],\n blend: 'lighter',\n grow: { amp: 0.25, period: 9000 },\n },\n {\n key: 'curtain-violet',\n count: 60,\n sprite: {\n kind: 'circle',\n radius: [0.045, 0.09],\n color: '#8d5bff',\n soft: true,\n colors: ['#8d5bff', '#d14bff', '#ff4bd8'],\n colorWeights: [4, 1.5, 0.5],\n },\n motion: { type: 'wander', speed: [0.003, 0.01], angle: 180, meander: 0.1, coherence: 0.55 },\n region: { y: [0.04, 0.28] },\n alpha: [0.03, 0.08],\n blend: 'lighter',\n grow: { amp: 0.3, period: 12000 },\n },\n {\n key: 'fireflies',\n count: 14,\n sprite: { kind: 'circle', radius: [0.001, 0.003], color: '#b8ffe1', soft: true },\n motion: { type: 'wander', speed: [0.006, 0.02], meander: 0.06 },\n region: { y: [0.55, 0.95] },\n alpha: [0.2, 0.55],\n pulse: { amp: 0.3, period: 3500 },\n blend: 'lighter',\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Comet Shower: showcases trails (afterglow behind moving entities) and background\n * drift (gradient stops breathing slowly). Three layers: a static star field, fast\n * comets with long trails, and slow fireflies with short trails and pulse.\n */\nexport const COMETS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'comets',\n label: 'Comet Shower',\n seed: 42,\n motionIntensity: 'moderate',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a0015' },\n { at: 0.5, color: '#0d1b2a' },\n { at: 1, color: '#1b0a2e' },\n ],\n drift: { period: 25000, amount: 0.12 },\n },\n layers: [\n {\n key: 'stars',\n count: 120,\n sprite: { kind: 'circle', radius: [0.000463, 0.001852], color: '#ffffff', soft: true },\n motion: { type: 'static' },\n alpha: [0.3, 0.7],\n pulse: { amp: 0.15, period: 3000 },\n },\n {\n key: 'comets',\n count: 8,\n sprite: { kind: 'circle', radius: [0.002778, 0.007407], color: '#88ccff', soft: true },\n motion: { type: 'drift', speed: [0.07407, 0.1852], angle: 225 },\n alpha: [0.7, 1],\n blend: 'lighter',\n trail: { length: 1500, fade: 1 },\n },\n {\n key: 'fireflies',\n count: 20,\n sprite: { kind: 'circle', radius: [0.001852, 0.00463], color: '#ffdd44', soft: true },\n motion: { type: 'drift', speed: [0.009259, 0.02778], bidirectional: true, bob: 0.01852 },\n alpha: [0.4, 0.8],\n pulse: { amp: 0.3, period: 2000 },\n blend: 'lighter',\n trail: { length: 800 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Constellation: drifting stars connected by faint k-nearest links. Exercises\n * colors[] (multi-hued stars), links (k-nearest neighbor lines), and cycle\n * (emoji asterisms rotate glyphs). Stars are soft circles in viewport units.\n */\nexport const CONSTELLATION_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'constellation',\n label: 'Constellation',\n seed: 73,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#020212' },\n { at: 0.5, color: '#050520' },\n { at: 1, color: '#0a0830' },\n ],\n },\n layers: [\n // Distant static stars (no links, just atmosphere)\n {\n count: 100,\n sprite: { kind: 'circle', radius: [0.0009259, 0.002778], color: '#667799', colors: ['#8899cc', '#99aadd', '#aabbee', '#7788aa'] },\n alpha: [0.2, 0.7],\n pulse: { amp: 0.2, period: 3000 },\n motion: { type: 'static' },\n },\n // Connected constellation nodes — slow drift, linked\n {\n key: 'nodes',\n count: 40,\n sprite: { kind: 'circle', radius: [0.001852, 0.00463], color: '#88aaff', colors: ['#88aaff', '#aaccff', '#ffcc88', '#ff8866'], soft: true },\n alpha: [0.5, 0.9],\n blend: 'lighter',\n motion: { type: 'drift', speed: [0.001852, 0.007407], bidirectional: true, bob: 0.002778 },\n links: { k: 3, maxDist: 0.1852, alpha: 0.15, width: 0.000463 },\n },\n // Cycling asterism markers\n {\n count: 6,\n sprite: { kind: 'emoji', glyphs: ['✦', '✧', '⋆', '∗'], cycle: { period: 2000 } },\n size: [0.01296, 0.02037],\n alpha: [0.4, 0.7],\n motion: { type: 'drift', speed: [0.0009259, 0.003704], bidirectional: true },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Control Center — VIREO-9, Trans-Lunar Relay Operations.\n *\n * A mission-control WALL BOARD, laid out the way real ops rooms lay them out:\n * framed zones with a clear reading order, one hero display (the orbital\n * plot), dense-but-calm peripheral telemetry, and a boot sequence when the\n * board comes up. The fiction: a small relay station somewhere past GEO,\n * mid-shift, tracking a five-craft fleet (named for this library's own\n * savers — the station runs our little universe).\n *\n * Composed against the validator's 36-layer ceiling deliberately — every\n * layer earns its slot. Schema exercises: grid `layout` LED wall with a\n * traveling `pulse.wave`, `orbit` motion with `trail`s and chain `links`\n * (the relay web between the fleet), `ring` orbit guides, wave-phased rect\n * meters, staged `life` boots per zone. Every reading is keyed so an agent\n * can steer the fiction live (`signal-value`, `feed-1`, `alert`, ...).\n */\nexport const DASHBOARD_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'dev-dashboard',\n label: 'Control Center',\n seed: 256,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#05070d' },\n { at: 0.55, color: '#080b14' },\n { at: 1, color: '#0a0d18' },\n ],\n },\n layers: [\n // ---- ambient: the LED wall behind everything ----\n {\n key: 'led-wall',\n count: 240,\n sprite: { kind: 'circle', radius: [0.0007, 0.0011], color: '#22344c' },\n alpha: [0.04, 0.1],\n layout: { type: 'grid', columns: 24, jitter: 0.1 },\n pulse: { amp: 0.3, period: 6200, wave: { wavelength: 0.4, angle: 24 } },\n motion: { type: 'static' },\n },\n // ---- frame chrome (boots first) ----\n {\n key: 'rule-header', count: 1,\n position: { x: 0.5, y: 0.085 },\n sprite: { kind: 'rect', width: [0.93, 0.93], aspect: [0.0012, 0.0012], color: '#24384f' },\n alpha: [0.8, 0.8],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n {\n key: 'rule-footer', count: 1,\n position: { x: 0.5, y: 0.915 },\n sprite: { kind: 'rect', width: [0.93, 0.93], aspect: [0.0012, 0.0012], color: '#24384f' },\n alpha: [0.8, 0.8],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n {\n key: 'rule-col-left', count: 1,\n position: { x: 0.265, y: 0.5 },\n sprite: { kind: 'rect', width: [0.0009, 0.0009], aspect: [620, 620], color: '#1c2c40' },\n alpha: [0.7, 0.7],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n {\n key: 'rule-col-right', count: 1,\n position: { x: 0.645, y: 0.5 },\n sprite: { kind: 'rect', width: [0.0009, 0.0009], aspect: [620, 620], color: '#1c2c40' },\n alpha: [0.7, 0.7],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n // ---- header band ----\n {\n key: 'title', count: 1,\n position: { x: 0.035, y: 0.052 },\n sprite: { kind: 'text', strings: ['VIREO-9 · TRANS-LUNAR RELAY · OPS WALL 03'], color: '#7f93ab',\n font: \"600 13px 'SF Mono', monospace\", align: 'left' },\n motion: { type: 'static' },\n life: { enter: 200, fade: 600 },\n },\n {\n key: 'clock', count: 1,\n position: { x: 0.5, y: 0.058 },\n sprite: { kind: 'text', strings: ['04:17:26 UTC'], color: '#c8d4e4',\n font: \"600 20px 'SF Mono', monospace\", align: 'center' },\n motion: { type: 'static' },\n life: { enter: 200, fade: 600 },\n },\n {\n key: 'status', count: 1,\n position: { x: 0.965, y: 0.052 },\n sprite: { kind: 'text', strings: ['● UPLINK LOCKED · WATCH C'], color: '#46d17a',\n font: \"bold 11px 'SF Mono', monospace\", align: 'right' },\n pulse: { amp: 0.18, period: 2600 },\n motion: { type: 'static' },\n life: { enter: 200, fade: 600 },\n },\n // ---- left column: arrays (boots second) ----\n {\n key: 'dish1', count: 1,\n position: { x: 0.035, y: 0.148 },\n sprite: { kind: 'text', strings: ['DSA-1 EAST AZ 214.6° EL 38.2°'], color: '#9fb2c8',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 700, fade: 600 },\n },\n {\n key: 'dish1-bars', count: 14,\n sprite: { kind: 'rect', width: [0.0038, 0.0038], aspect: [0.5, 2.6], color: '#2ee6c8' },\n alpha: [0.3, 0.65],\n layout: { type: 'grid', columns: 14 },\n region: { x: [0.035, 0.15], y: [0.183, 0.203] },\n pulse: { amp: 0.42, period: 1500, wave: { wavelength: 0.09, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 700, fade: 600 },\n },\n {\n key: 'dish2', count: 1,\n position: { x: 0.035, y: 0.243 },\n sprite: { kind: 'text', strings: ['DSA-2 WEST AZ 097.1° EL 61.7°'], color: '#9fb2c8',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 850, fade: 600 },\n },\n {\n key: 'dish2-bars', count: 14,\n sprite: { kind: 'rect', width: [0.0038, 0.0038], aspect: [0.5, 2.2], color: '#44aaff' },\n alpha: [0.3, 0.6],\n layout: { type: 'grid', columns: 14 },\n region: { x: [0.035, 0.15], y: [0.278, 0.298] },\n pulse: { amp: 0.4, period: 1900, wave: { wavelength: 0.11, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 850, fade: 600 },\n },\n {\n key: 'dish3', count: 1,\n position: { x: 0.035, y: 0.338 },\n sprite: { kind: 'text', strings: ['DSA-3 POLAR AZ 002.4° EL 12.9° △ WIND'], color: '#5d7089',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1000, fade: 600 },\n },\n {\n key: 'dish3-bars', count: 14,\n sprite: { kind: 'rect', width: [0.0038, 0.0038], aspect: [0.4, 1.1], color: '#5d7089' },\n alpha: [0.2, 0.4],\n layout: { type: 'grid', columns: 14 },\n region: { x: [0.035, 0.15], y: [0.373, 0.393] },\n pulse: { amp: 0.3, period: 2600, wave: { wavelength: 0.14, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 1000, fade: 600 },\n },\n {\n key: 'dish-leds', count: 3,\n sprite: { kind: 'circle', radius: [0.004, 0.004], color: '#46d17a' },\n alpha: [0.9, 0.9],\n layout: { type: 'grid', columns: 1 },\n region: { x: [0.238, 0.246], y: [0.15, 0.35] },\n pulse: { amp: 0.25, period: 2100 },\n motion: { type: 'static' },\n life: { enter: 1000, fade: 600 },\n },\n // carrier + doppler + station env\n {\n key: 'carrier-wave', count: 30,\n sprite: { kind: 'rect', width: [0.0032, 0.0032], aspect: [0.4, 3.6], color: '#2ee6c8' },\n alpha: [0.25, 0.6],\n layout: { type: 'grid', columns: 30 },\n region: { x: [0.035, 0.245], y: [0.47, 0.5] },\n pulse: { amp: 0.5, period: 2100, wave: { wavelength: 0.16, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 1150, fade: 600 },\n },\n {\n key: 'doppler', count: 1,\n position: { x: 0.035, y: 0.535 },\n sprite: { kind: 'text', strings: ['CARRIER X-BAND · DOPPLER +2.114 kHz · DRIFT 0.03'], color: '#9fb2c8',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1150, fade: 600 },\n },\n {\n key: 'env-line', count: 1,\n position: { x: 0.035, y: 0.6 },\n sprite: { kind: 'text', strings: ['STATION · PWR 28.1 V · THERM 312 K · GYRO NOM · PROP 81%'], color: '#5d7089',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1300, fade: 600 },\n },\n // ---- center: the orbital plot (boots third) ----\n {\n key: 'moon', count: 1,\n position: { x: 0.455, y: 0.4 },\n sprite: { kind: 'circle', radius: [0.028, 0.028], color: '#8fa3bd', soft: true },\n alpha: [0.9, 0.9],\n motion: { type: 'static' },\n life: { enter: 1200, fade: 700 },\n },\n {\n key: 'orbit-guides', count: 3,\n // All three guides pin to the plot centre; the seeded radius range\n // spreads them into concentric orbits (`position` is count:1-only).\n region: { x: [0.455, 0.455], y: [0.4, 0.4] },\n sprite: { kind: 'ring', radius: [0.075, 0.185], color: '#1e3a52', width: 0.0011 },\n alpha: [0.55, 0.55],\n motion: { type: 'static' },\n life: { enter: 1200, fade: 700 },\n },\n {\n key: 'fleet',\n count: 5,\n sprite: { kind: 'circle', radius: [0.0045, 0.0065], color: '#2ee6c8',\n colors: ['#2ee6c8', '#44aaff', '#ffd166', '#aa88ff', '#ff9f43'] },\n alpha: [0.85, 0.95],\n blend: 'lighter',\n motion: { type: 'orbit', speed: [4, 11], radius: [0.075, 0.185], center: { x: 0.455, y: 0.4 } },\n trail: { length: 9, fade: 0.75 },\n // The relay web: each craft holds a comm chain to its neighbours.\n links: { k: 2, maxDist: 0.5, color: '#2ee6c8', alpha: 0.2, width: 0.0012, mode: 'chain' },\n life: { enter: 1350, fade: 700 },\n },\n {\n key: 'fleet-legend', count: 1,\n position: { x: 0.455, y: 0.63 },\n sprite: { kind: 'text', strings: ['TRACKING 5 · KESTREL TIDE-2 LIMELIGHT CATWALK-1 SLIPSTREAM'], color: '#5d7089',\n font: \"9px 'SF Mono', monospace\", align: 'center', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1500, fade: 700 },\n },\n // pass schedule under the plot\n {\n key: 'pass-label', count: 1,\n position: { x: 0.3, y: 0.69 },\n sprite: { kind: 'text', strings: ['PASS SCHEDULE'], color: '#41536b',\n font: \"9px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1650, fade: 600 },\n },\n {\n key: 'pass-1', count: 1,\n position: { x: 0.3, y: 0.72 },\n sprite: { kind: 'text', strings: ['04:41 CATWALK-1 ACQUIRE · DSA-1 ▲ 12 MIN'], color: '#c8d4e4',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1650, fade: 600 },\n },\n {\n key: 'pass-2', count: 1,\n position: { x: 0.3, y: 0.757 },\n sprite: { kind: 'text', strings: ['05:03 TIDE-2 OCCULT EXIT · DSA-2'], color: '#7f93ab',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1750, fade: 600 },\n },\n {\n key: 'pass-3', count: 1,\n position: { x: 0.3, y: 0.794 },\n sprite: { kind: 'text', strings: ['05:47 KESTREL RANGING · DSA-1+2'], color: '#7f93ab',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1850, fade: 600 },\n },\n // ---- right column: telemetry (boots fourth) ----\n {\n key: 'signal-label', count: 1,\n position: { x: 0.665, y: 0.115 },\n sprite: { kind: 'text', strings: ['PRIMARY CARRIER · CATWALK-1'], color: '#41536b',\n font: \"9px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1700, fade: 600 },\n },\n {\n key: 'signal-value', count: 1,\n position: { x: 0.665, y: 0.14 },\n sprite: { kind: 'text', strings: ['-112.4 dBm'], color: '#ffd166',\n font: \"bold 30px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1700, fade: 600 },\n },\n {\n key: 'telemetry-row', count: 1,\n position: { x: 0.665, y: 0.215 },\n sprite: { kind: 'text', strings: ['RANGE 1.28 LS DOWNLINK 2.048 Mb/s BUFFER 38%'], color: '#9fb2c8',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1800, fade: 600 },\n },\n // event log\n {\n key: 'feed-1', count: 1,\n position: { x: 0.665, y: 0.3 },\n sprite: { kind: 'text', strings: ['04:15:02 DSA-1 LOCK RE-ACQUIRED'], color: '#9fb2c8',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1950, fade: 600 },\n },\n {\n key: 'feed-2', count: 1,\n position: { x: 0.665, y: 0.334 },\n sprite: { kind: 'text', strings: ['04:12:47 CATWALK-1 WHEEL DESAT OK'], color: '#7f93ab',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 2050, fade: 600 },\n },\n {\n key: 'feed-3', count: 1,\n position: { x: 0.665, y: 0.368 },\n sprite: { kind: 'text', strings: ['04:09:31 RANGING RESIDUAL 0.4 m'], color: '#5d7089',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 2150, fade: 600 },\n },\n // alert + relay load\n {\n key: 'alert', count: 1,\n position: { x: 0.665, y: 0.49 },\n sprite: { kind: 'text', strings: ['△ SOLAR FLUX ELEVATED — MONITORING'], color: '#ff9f43',\n font: \"bold 11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n pulse: { amp: 0.22, period: 3400 },\n motion: { type: 'static' },\n life: { enter: 2450, fade: 600 },\n },\n {\n key: 'load-bars', count: 24,\n sprite: { kind: 'rect', width: [0.0042, 0.0042], aspect: [0.5, 3.2],\n color: '#aa88ff', colors: ['#aa88ff', '#44aaff', '#2ee6c8'], colorWeights: [2, 2, 3] },\n alpha: [0.3, 0.65],\n layout: { type: 'grid', columns: 24 },\n region: { x: [0.665, 0.965], y: [0.58, 0.615] },\n pulse: { amp: 0.45, period: 1800, wave: { wavelength: 0.12, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 2550, fade: 600 },\n },\n {\n key: 'load-note', count: 1,\n position: { x: 0.665, y: 0.65 },\n sprite: { kind: 'text', strings: ['RELAY LOAD · QUEUE 14 FRAMES · NOMINAL'], color: '#5d7089',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 2550, fade: 600 },\n },\n // ---- footer band ----\n {\n key: 'footer', count: 1,\n position: { x: 0.035, y: 0.95 },\n sprite: { kind: 'text', strings: ['NET STATE GREEN · 3 ARRAYS · 5 CARRIERS · DSN HANDOVER 23:34 · NEXT WINDOW 04:41:00'], color: '#41536b',\n font: \"9px 'SF Mono', monospace\", align: 'left' },\n motion: { type: 'static' },\n life: { enter: 2750, fade: 600 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Facets — a composition in the manner of the early abstractionists: three\n * soft-edged colour planes (feathered `rect`) breathing slowly behind a field\n * of tumbling triangular facets (custom `polygon`), tapered brush arcs\n * (`stroke`) drifting across, and a few glowing hexagons (soft regular\n * `polygon`). Every glyph here is a path, not a disc — the shape family nine\n * of the fifteen style profiles asked for.\n */\nexport const FACETS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'facets',\n label: 'Facets',\n seed: 1911,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#101626' },\n { at: 1, color: '#1c1a2e' },\n ],\n },\n layers: [\n {\n key: 'planes',\n count: 3,\n sprite: {\n kind: 'rect',\n width: [0.28, 0.42],\n aspect: [0.6, 1.4],\n color: '#b3402f',\n colors: ['#b3402f', '#c9862b', '#2d4f8a'],\n feather: 0.6,\n },\n alpha: [0.35, 0.5],\n region: { x: [0.2, 0.8], y: [0.2, 0.8] },\n motion: { type: 'wander', speed: [0.001, 0.003], meander: 0.02 },\n spin: [-2, 2],\n },\n {\n key: 'facets',\n count: 14,\n sprite: {\n kind: 'polygon',\n radius: [0.02, 0.06],\n points: [[-1, 0.9], [0.2, -1], [1, 0.4]],\n color: '#f2e8c9',\n colors: ['#f2e8c9', '#e0b53a', '#6fa8dc', '#d94f3d'],\n },\n alpha: [0.6, 0.9],\n motion: { type: 'wander', speed: [0.003, 0.008], meander: 0.03 },\n spin: [-8, 8],\n },\n {\n key: 'arcs',\n count: 12,\n sprite: {\n kind: 'stroke',\n length: [0.08, 0.18],\n points: [[-1, 0.3], [-0.5, -0.6], [0.3, -0.7], [1, 0.1]],\n width: 0.004,\n taper: true,\n color: '#f2e8c9',\n },\n alpha: [0.5, 0.8],\n motion: { type: 'drift', speed: [0.004, 0.01], angle: 20, bidirectional: true },\n spin: [-4, 4],\n },\n {\n key: 'hexes',\n count: 8,\n sprite: { kind: 'polygon', radius: [0.008, 0.016], sides: 6, color: '#e0b53a', soft: true },\n alpha: [0.5, 0.8],\n blend: 'lighter',\n motion: { type: 'wander', speed: [0.002, 0.005] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/** Haiku: a centered text block with a slowly drifting haiku over deep indigo. */\nexport const HAIKU_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'haiku',\n label: 'Haiku',\n seed: 42,\n background: { type: 'solid', color: '#080812' },\n layers: [\n {\n count: 1,\n sprite: {\n kind: 'textBlock',\n text: 'An old silent pond\\nA frog jumps into the pond —\\nSplash! Silence again.',\n maxWidth: 0.8,\n fontSize: 0.05,\n lineHeight: 1.8,\n align: 'center',\n color: '#c8cad4',\n },\n motion: { type: 'static' },\n position: { x: 0.1, y: 0.35 },\n },\n {\n count: 30,\n sprite: { kind: 'circle', radius: [0.0005, 0.0015], color: '#3a3a5c' },\n motion: { type: 'drift', speed: [0.002, 0.006], angle: 270 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Night Lanterns (Yi Peng festival sky): depth from four correlated parallax cues —\n * closer layers are LARGER, FASTER, SWAY WIDER, and glow WARMER/BRIGHTER. v2 of this\n * composition exercises the expressive additions the first draft exposed as missing:\n * soft glow orbs + additive blend (lantern light that sums where it overlaps), bounded\n * alpha pulse with per-entity phases (breathing flames, strobe-proof by construction),\n * and spawn regions (stars only above the horizon; dim ember shimmer kept low near\n * the water line).\n */\nexport const LANTERNS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'lanterns',\n label: 'Night Lanterns',\n seed: 88,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#04060f' },\n { at: 0.55, color: '#0b1026' },\n { at: 0.85, color: '#251731' },\n { at: 1, color: '#472518' },\n ],\n },\n layers: [\n {\n count: 60,\n sprite: { kind: 'circle', radius: [0.000463, 0.001296], color: '#8fa0c8' },\n alpha: [0.35, 1],\n region: { y: [0, 0.62] },\n motion: { type: 'drift', speed: [0.000463, 0.001852], bob: 0.0009259 },\n },\n {\n count: 36,\n sprite: {\n kind: 'circle',\n radius: [0.001389, 0.002778],\n color: '#b06a2a',\n soft: true,\n },\n alpha: [0.5, 0.9],\n blend: 'lighter',\n pulse: { amp: 0.18, period: 2800 },\n motion: { type: 'rise', speed: [0.005556, 0.01296], sway: 0.003704 },\n },\n {\n count: 14,\n sprite: {\n kind: 'circle',\n radius: [0.003241, 0.006019],\n color: '#e08a34',\n soft: true,\n },\n alpha: [0.6, 1],\n blend: 'lighter',\n pulse: { amp: 0.22, period: 3400 },\n motion: { type: 'rise', speed: [0.01481, 0.02593], sway: 0.006481 },\n },\n {\n count: 8,\n sprite: { kind: 'emoji', glyphs: ['🏮'] },\n size: [0.02407, 0.04074],\n alpha: [0.85, 1],\n motion: { type: 'rise', speed: [0.02778, 0.04444], sway: 0.009259 },\n },\n {\n count: 4,\n sprite: { kind: 'emoji', glyphs: ['🏮'] },\n size: [0.0537, 0.07778],\n motion: { type: 'rise', speed: [0.04815, 0.06852], sway: 0.01296 },\n },\n {\n count: 12,\n sprite: { kind: 'circle', radius: [0.001852, 0.00463], color: '#e08a34', soft: true },\n alpha: [0.12, 0.35],\n blend: 'lighter',\n region: { y: [0.93, 1] },\n pulse: { amp: 0.1, period: 2200 },\n motion: { type: 'drift', speed: [0.001852, 0.005556], bob: 0.001852 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Matrix Rain: showcases `layout: grid` with per-axis jitter ({ y: 1 } keeps the\n * columns crisp while de-syncing them vertically), glyph `cycle`, and `ghosting`\n * doing the classic fading-trail work. Two depths of rain plus rare bright heads.\n */\nexport const MATRIX_RAIN_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'matrix-rain',\n label: 'Matrix Rain',\n seed: 1999,\n motionIntensity: 'moderate',\n ghosting: 0.88,\n background: { type: 'solid', color: '#010401' },\n layers: [\n {\n key: 'rain-far',\n count: 64,\n sprite: {\n kind: 'text',\n strings: ['ア', 'カ', 'サ', 'タ', 'ナ', 'ハ', 'マ', 'ヤ', 'ラ', 'ワ', '0', '1', '7', 'Z', 'X', 'K'],\n color: '#1c7a2e',\n font: 'bold monospace',\n cycle: { period: 900 },\n },\n size: [0.014, 0.02],\n layout: { type: 'grid', columns: 32, jitter: { y: 1 } },\n motion: { type: 'drift', speed: [0.06, 0.14], angle: 90 },\n alpha: [0.35, 0.6],\n },\n {\n key: 'rain-near',\n count: 40,\n sprite: {\n kind: 'text',\n strings: ['ミ', 'ネ', 'リ', 'ソ', 'ツ', 'ヌ', 'ホ', 'ユ', '3', '8', '9', 'V', 'N'],\n color: '#2ecc40',\n font: 'bold monospace',\n cycle: { period: 700 },\n },\n size: [0.022, 0.03],\n layout: { type: 'grid', columns: 20, jitter: { y: 1 } },\n motion: { type: 'drift', speed: [0.16, 0.3], angle: 90 },\n alpha: [0.6, 0.9],\n },\n {\n key: 'heads',\n count: 12,\n sprite: {\n kind: 'text',\n strings: ['ケ', 'メ', 'エ', 'ム', 'ヲ', '5', '2'],\n color: '#c8ffd4',\n font: 'bold monospace',\n cycle: { period: 500 },\n },\n size: [0.024, 0.032],\n layout: { type: 'grid', columns: 12, jitter: { y: 1 } },\n motion: { type: 'drift', speed: [0.2, 0.34], angle: 90 },\n alpha: [0.9, 1],\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Tarkovsky — Nostalghia's candle: a single point of devotion.\n * Near-black warm ground; one small warm-white flame at center with grow/pulse\n * wobble; faint smoke rising; sparse amber embers with long fading trails;\n * a wide near-invisible halo breathing on a 10s cycle. Minimalism as tension —\n * most of the screen is darkness.\n *\n * Note: `pulse.amp` is ADDED to base alpha (not multiplied), so the halo's amp\n * must stay below its base alpha or the trough clamps to fully invisible.\n */\nexport const NOSTALGHIA_CANDLE_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'nostalghia-candle',\n label: \"Nostalghia's Candle\",\n seed: 1983,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#050302' },\n { at: 0.55, color: '#0a0704' },\n { at: 1, color: '#120c08' },\n ],\n },\n layers: [\n {\n key: 'halo',\n count: 1,\n position: { x: 0.5, y: 0.52 },\n sprite: {\n kind: 'circle',\n radius: [0.11, 0.11],\n color: '#c4782a',\n soft: true,\n },\n // Base 0.04 + amp 0.02 → breathes ~0.02..0.06; never clamps to 0.\n // (pulse.amp is ADDED to alpha, not multiplied.) Kept subordinate to the flame.\n alpha: [0.04, 0.04],\n blend: 'lighter',\n pulse: { amp: 0.02, period: 10000 },\n grow: { amp: 0.08, period: 10000 },\n motion: { type: 'static' },\n },\n {\n key: 'smoke',\n count: 3,\n sprite: {\n kind: 'circle',\n radius: [0.01, 0.022],\n color: '#6a6258',\n soft: true,\n },\n alpha: [0.02, 0.04],\n blend: 'lighter',\n region: { x: [0.46, 0.54], y: [0.36, 0.48] },\n pulse: { amp: 0.015, period: 4500 },\n motion: { type: 'rise', speed: [0.002, 0.004], sway: 0.008 },\n },\n {\n key: 'flame-glow',\n count: 1,\n sprite: {\n kind: 'circle',\n radius: [0.028, 0.028],\n color: '#ffb040',\n soft: true,\n },\n alpha: [0.32, 0.32],\n blend: 'lighter',\n pulse: { amp: 0.12, period: 1400 },\n grow: { amp: 0.4, period: 1600 },\n // Tiny orbit = positional lean without drifting off-center (wander has vx).\n motion: {\n type: 'orbit',\n speed: [18, 18],\n radius: [0.003, 0.003],\n center: { x: 0.5, y: 0.52 },\n },\n },\n {\n key: 'flame-core',\n count: 1,\n sprite: {\n kind: 'circle',\n radius: [0.014, 0.014],\n color: '#fff6e0',\n soft: true,\n },\n alpha: [0.95, 0.95],\n blend: 'lighter',\n pulse: { amp: 0.25, period: 900 },\n grow: { amp: 0.55, period: 1100 },\n motion: {\n type: 'orbit',\n speed: [22, 22],\n radius: [0.0025, 0.0025],\n center: { x: 0.5, y: 0.52 },\n },\n },\n {\n key: 'embers',\n count: 7,\n sprite: {\n kind: 'circle',\n radius: [0.0018, 0.004],\n color: '#e08a34',\n soft: true,\n },\n alpha: [0.4, 0.8],\n blend: 'lighter',\n region: { x: [0.35, 0.65], y: [0.4, 0.7] },\n pulse: { amp: 0.2, period: 2200 },\n trail: { length: 2200, fade: 1 },\n motion: {\n type: 'drift',\n speed: [0.004, 0.012],\n angle: 270,\n bob: 0.008,\n },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Polygons: the classic Mystify-style bouncing-polygon saver, expressed as chain links + heavy\n * ghosting. Showcases `links.mode: 'chain'` with `closed` (vertices wired in order\n * into a polygon), `bounce` motion, and high `ghosting` (the decaying after-images\n * ARE the effect — no per-entity trail sampling involved).\n */\nexport const POLYGONS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'polygons',\n label: 'Polygons',\n seed: 1995,\n motionIntensity: 'moderate',\n ghosting: 0.95,\n background: { type: 'solid', color: '#04040a' },\n layers: [\n {\n key: 'poly-cyan',\n count: 4,\n sprite: { kind: 'circle', radius: [0.0025, 0.0025], color: '#37e5d7' },\n motion: { type: 'bounce', speed: [0.14, 0.24] },\n wrap: false,\n alpha: [0.9, 0.9],\n links: { k: 1, maxDist: 3, mode: 'chain', closed: true, color: '#37e5d7', alpha: 0.85, width: 0.0018 },\n },\n {\n key: 'poly-magenta',\n count: 4,\n sprite: { kind: 'circle', radius: [0.0025, 0.0025], color: '#e83e9c' },\n motion: { type: 'bounce', speed: [0.1, 0.2] },\n wrap: false,\n alpha: [0.9, 0.9],\n links: { k: 1, maxDist: 3, mode: 'chain', closed: true, color: '#e83e9c', alpha: 0.85, width: 0.0018 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Orrery: a mechanical solar system. Exercises orbit motion (concentric rings\n * at different speeds), spin (planets rotate on their axes), and grow (the sun\n * pulses). Soft glow circles with additive blending create the corona and\n * planetary halos.\n */\nexport const ORRERY_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'orrery',\n label: 'Orrery',\n seed: 7,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#020210' },\n { at: 0.5, color: '#06051a' },\n { at: 1, color: '#0a0820' },\n ],\n },\n layers: [\n // Distant stars\n {\n count: 80,\n sprite: { kind: 'circle', radius: [0.0002778, 0.001111], color: '#8899cc' },\n alpha: [0.2, 0.8],\n pulse: { amp: 0.3, period: 3000 },\n motion: { type: 'static' },\n },\n // Sun corona (soft glow)\n {\n key: 'corona',\n count: 1,\n sprite: { kind: 'circle', radius: [0.05556, 0.05556], color: '#ffaa22', soft: true },\n blend: 'lighter',\n alpha: [0.6, 0.6],\n grow: { amp: 0.15, period: 4000 },\n motion: { type: 'static' },\n position: { x: 0.5, y: 0.5 },\n },\n // Sun body\n {\n key: 'sun',\n count: 1,\n sprite: { kind: 'emoji', glyphs: ['☀️'] },\n size: [0.04444, 0.04444],\n grow: { amp: 0.08, period: 4000 },\n motion: { type: 'static' },\n position: { x: 0.5, y: 0.5 },\n },\n // Inner ring — small fast planets\n {\n key: 'inner',\n count: 3,\n sprite: { kind: 'emoji', glyphs: ['🪨', '🔴', '🟠'] },\n size: [0.01481, 0.02037],\n spin: 30,\n motion: { type: 'orbit', speed: [28, 42], radius: [0.07407, 0.1111] },\n },\n // Middle ring — gas giants\n {\n key: 'middle',\n count: 2,\n sprite: { kind: 'emoji', glyphs: ['🟤', '🪐'] },\n size: [0.02593, 0.03519],\n spin: -15,\n motion: { type: 'orbit', speed: [12, 20], radius: [0.1481, 0.1852] },\n },\n // Outer ring — ice giants\n {\n key: 'outer',\n count: 2,\n sprite: { kind: 'emoji', glyphs: ['🔵', '💎'] },\n size: [0.02037, 0.02778],\n spin: 10,\n motion: { type: 'orbit', speed: [5, 10], radius: [0.2222, 0.2778] },\n },\n // Orbital dust ring (soft glow particles orbiting slowly)\n {\n count: 24,\n sprite: { kind: 'circle', radius: [0.0009259, 0.002778], color: '#ccaa66', soft: true },\n alpha: [0.15, 0.4],\n blend: 'lighter',\n pulse: { amp: 0.2, period: 2500 },\n motion: { type: 'orbit', speed: [2, 8], radius: [0.09259, 0.2963] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Pings — almost nothing, almost never.\n * A near-black ground and one teal hue. Three rings take turns: each one\n * appears, grows sixteenfold (0.15× → 2.4× its radius) and fades over four\n * seconds, then the frame is empty until the next — `emit` with `jitter: 0`\n * spaces them evenly, one event every four seconds, and `life` is kept at\n * the stagger so no two rings are ever lit together. Underneath, a few motes rise,\n * `settle` to rest and fade on their own, longer, seeded schedule. Nothing\n * travels; everything grows and goes. The house style Fathom describes this\n * exactly and, before `emit`, could not be authored.\n */\nexport const PINGS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'pings',\n label: 'Pings',\n seed: 7,\n motionIntensity: 'calm',\n ghosting: 0.9,\n background: { type: 'solid', color: '#03060a' },\n layers: [\n {\n key: 'ping',\n count: 3,\n sprite: { kind: 'ring', radius: [0.05, 0.05], color: '#4fb3a8', width: 0.0015 },\n alpha: [0.35, 0.35],\n blend: 'lighter',\n region: { x: [0.2, 0.8], y: [0.25, 0.75] },\n motion: { type: 'static' },\n // One ring at a time: three entities evenly staggered across 12 s.\n emit: { every: 12000, life: 4000, jitter: 0, grow: [0.15, 2.4] },\n },\n {\n key: 'motes',\n count: 14,\n sprite: { kind: 'circle', radius: [0.0012, 0.002], color: '#4fb3a8', soft: true },\n alpha: [0.1, 0.22],\n blend: 'lighter',\n // Each mote is flung upward and comes to rest within ~2.5 s of its event.\n motion: { type: 'rise', speed: [0.01, 0.02], sway: 0.004, ease: { type: 'settle', tau: 2500 } },\n emit: { every: 16000, life: 7000, grow: [0.6, 1.4] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Night Procession: a choreographed scene. Showcases `path` motion (a smooth\n * figure-eight lantern route with scatter), layer-parented `orbit` (moths circling\n * a wandering lantern-bearer), `life` staging (stars first, the procession enters\n * at 4 s, moths at 7 s), plus `ring` and `rect` sprites.\n */\nexport const PROCESSION_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'procession',\n label: 'Night Procession',\n seed: 8,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#060612' },\n { at: 0.8, color: '#101024' },\n { at: 1, color: '#1a1428' },\n ],\n drift: { period: 30000, amount: 0.08 },\n },\n layers: [\n {\n key: 'stars',\n count: 90,\n sprite: { kind: 'circle', radius: [0.0006, 0.0016], color: '#f0ead8', soft: true },\n motion: { type: 'static' },\n region: { y: [0, 0.6] },\n alpha: [0.25, 0.6],\n pulse: { amp: 0.15, period: 5000 },\n },\n {\n key: 'lanterns',\n count: 9,\n sprite: {\n kind: 'rect',\n width: [0.012, 0.02],\n aspect: [1.3, 1.7],\n color: '#ffb347',\n colors: ['#ffb347', '#ff8c69', '#ffd97a'],\n colorWeights: [3, 1, 2],\n },\n motion: {\n type: 'path',\n points: [\n { x: 0.12, y: 0.72 },\n { x: 0.38, y: 0.58 },\n { x: 0.62, y: 0.78 },\n { x: 0.88, y: 0.62 },\n { x: 0.62, y: 0.5 },\n { x: 0.38, y: 0.72 },\n ],\n duration: 36000,\n curve: 'smooth',\n closed: true,\n scatter: 0.02,\n },\n alpha: [0.65, 0.9],\n pulse: { amp: 0.15, period: 2600 },\n life: { enter: 4000, fade: 2500 },\n trail: { length: 1200, fade: 1 },\n },\n {\n key: 'bearer',\n count: 1,\n sprite: { kind: 'circle', radius: [0.014, 0.014], color: '#ffe9b0', soft: true },\n motion: { type: 'wander', speed: [0.008, 0.012], meander: 0.08 },\n alpha: [0.8, 0.8],\n blend: 'lighter',\n life: { enter: 4000, fade: 2500 },\n },\n {\n key: 'moths',\n count: 7,\n sprite: { kind: 'ring', radius: [0.002, 0.005], color: '#d8f6ff', width: 0.001 },\n motion: { type: 'orbit', speed: [20, 55], radius: [0.03, 0.09], center: { layer: 'bearer' } },\n alpha: [0.3, 0.7],\n life: { enter: 7000, fade: 2000 },\n trail: { length: 600 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/** Rain: dense text streaks falling straight down over a near-black sky. */\nexport const RAIN_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'rain',\n label: 'Rain',\n seed: 7,\n motionIntensity: 'moderate',\n background: { type: 'solid', color: '#05070a' },\n layers: [\n {\n count: 140,\n sprite: { kind: 'text', strings: ['│'], color: '#9fd0ff' },\n size: [0.01111, 0.02407],\n motion: { type: 'drift', angle: 90, speed: [0.4815, 0.8333] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Relay Board — a six-row status chart in five layers instead of twenty-five.\n * One `list` of labels, one `list` of `bar`s whose lengths are the numbers,\n * one `list` of readouts, a title block, and a slow dust field behind so the\n * board reads as a live wall, not a document. Steer `bars.values` and the\n * bars glide to the new figures; the labels never move.\n */\nexport const RELAY_BOARD_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'relay-board',\n label: 'Relay Board',\n seed: 9,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#05070d' },\n { at: 1, color: '#0a0d18' },\n ],\n },\n layers: [\n {\n key: 'dust',\n count: 40,\n sprite: { kind: 'circle', radius: [0.0008, 0.0016], color: '#22344a', soft: true },\n alpha: [0.2, 0.45],\n blend: 'lighter',\n motion: { type: 'wander', speed: [0.001, 0.003] },\n },\n {\n key: 'title',\n count: 1,\n sprite: { kind: 'textBlock', text: 'RELAY LINKS — UPLINK MARGIN', maxWidth: 0.6, fontSize: 0.028, color: '#9fb4c9' },\n motion: { type: 'static' },\n position: { x: 0.12, y: 0.16 },\n },\n {\n key: 'labels',\n count: 6,\n sprite: { kind: 'text', strings: ['VIREO-9', 'TIDE', 'ORRERY', 'COMET', 'LANTERN', 'SAKURA'], font: 'bold monospace', align: 'left', color: '#e6e8ef' },\n size: [0.024, 0.024],\n motion: { type: 'static' },\n position: { x: 0.12, y: 0.3 },\n layout: { type: 'list', gap: 0.075 },\n },\n {\n key: 'bars',\n count: 6,\n sprite: {\n kind: 'bar',\n values: [82, 64, 91, 37, 58, 73],\n max: 100,\n length: 0.5,\n thickness: 0.02,\n color: '#17e8c8',\n colors: ['#17e8c8', '#35d0ff', '#ffd93b', '#ff6ad5', '#ad8cff', '#17e8c8'],\n },\n alpha: [0.85, 0.85],\n motion: { type: 'static' },\n position: { x: 0.3, y: 0.3 },\n layout: { type: 'list', gap: 0.075 },\n },\n {\n key: 'readouts',\n count: 6,\n sprite: { kind: 'text', strings: ['82%', '64%', '91%', '37%', '58%', '73%'], font: 'monospace', align: 'left', color: '#9fb4c9' },\n size: [0.02, 0.02],\n motion: { type: 'static' },\n position: { x: 0.86, y: 0.3 },\n layout: { type: 'list', gap: 0.075 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Sakura Drift: cherry-blossom petals carried on a spring twilight breeze.\n * Glow-up pass (v1-ceiling features): petals ride `wander` harmonics with shared\n * `coherence` so gusts move the whole fall together, `spin` tumbles the glyphs,\n * faint `streak` wind-lines cross the frame, the blossom-glow backdrop shimmers\n * as a traveling `pulse.wave`, and dusk fireflies wander the lower field. The\n * ground is a warm plum earth blended out of the sunset (no more abrupt dark\n * band), with slow background `drift` keeping the sky alive.\n */\nexport const SAKURA_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'sakura',\n label: 'Sakura Drift',\n seed: 314,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#1b1d38' },\n { at: 0.45, color: '#3a2645' },\n { at: 0.78, color: '#7d3d4e' },\n { at: 0.92, color: '#4a2438' },\n { at: 1, color: '#1c1018' },\n ],\n drift: { period: 35000, amount: 0.08 },\n },\n layers: [\n {\n key: 'blossom-glow',\n count: 60,\n sprite: {\n kind: 'circle',\n radius: [0.0005556, 0.001481],\n color: '#ffe3ec',\n soft: true,\n },\n alpha: [0.3, 0.9],\n blend: 'lighter',\n region: { y: [0, 0.72] },\n // Shimmer travels across the sky instead of orbs twinkling independently.\n pulse: { amp: 0.22, period: 4000, wave: { wavelength: 0.45, angle: 10 } },\n motion: { type: 'drift', speed: [0.0002778, 0.001111], bob: 0.0009259 },\n },\n {\n key: 'petals-far',\n count: 28,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [0.01204, 0.01852],\n alpha: [0.5, 0.8],\n spin: 16,\n motion: {\n type: 'wander',\n speed: [0.011, 0.024],\n angle: 100,\n meander: 0.025,\n coherence: 0.35,\n },\n },\n {\n key: 'petals-mid',\n count: 18,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [0.01852, 0.02963],\n alpha: [0.7, 0.95],\n spin: 24,\n motion: {\n type: 'wander',\n speed: [0.022, 0.041],\n angle: 100,\n meander: 0.045,\n coherence: 0.35,\n },\n },\n {\n key: 'petals-near',\n count: 10,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [0.03148, 0.05],\n alpha: [0.85, 1],\n spin: 32,\n motion: {\n type: 'wander',\n speed: [0.039, 0.063],\n angle: 100,\n meander: 0.07,\n coherence: 0.35,\n },\n },\n {\n key: 'gusts',\n count: 7,\n sprite: {\n kind: 'streak',\n length: [0.02, 0.045],\n width: 0.0012,\n color: '#ffd9e6',\n },\n alpha: [0.1, 0.22],\n blend: 'lighter',\n motion: { type: 'drift', speed: [0.09, 0.14], angle: 100 },\n },\n {\n key: 'fireflies',\n count: 6,\n sprite: {\n kind: 'circle',\n radius: [0.0009, 0.002],\n color: '#ffe9a8',\n soft: true,\n },\n alpha: [0.15, 0.5],\n blend: 'lighter',\n region: { y: [0.6, 0.9] },\n pulse: { amp: 0.3, period: 2800 },\n motion: { type: 'wander', speed: [0.004, 0.01], meander: 0.05 },\n },\n {\n key: 'fallen-petals',\n count: 16,\n sprite: {\n kind: 'circle',\n radius: [0.001389, 0.003704],\n color: '#ff9bb5',\n soft: true,\n },\n alpha: [0.1, 0.3],\n blend: 'lighter',\n region: { y: [0.9, 1] },\n // Settled petals catch the last light in a slow wave along the ground.\n pulse: { amp: 0.15, period: 3200, wave: { wavelength: 0.3, angle: 0 } },\n motion: {\n type: 'drift',\n speed: [0.0002778, 0.001389],\n angle: 180,\n bob: 0.0009259,\n },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/** Snowfall: three depth layers of white circles drifting down with horizontal bob. */\nexport const SNOWFALL_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'snowfall',\n label: 'Snowfall',\n seed: 12,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a1628' },\n { at: 0.7, color: '#0d1f3c' },\n { at: 1, color: '#121212' },\n ],\n },\n layers: [\n {\n count: 50,\n sprite: { kind: 'circle', radius: [0.0009259, 0.002315], color: '#8899aa' },\n motion: { type: 'drift', angle: 90, speed: [0.01389, 0.03704], bob: 0.002778 },\n },\n {\n count: 35,\n sprite: { kind: 'circle', radius: [0.001852, 0.004167], color: '#c0cdd8' },\n motion: { type: 'drift', angle: 85, speed: [0.03241, 0.07407], bob: 0.005556 },\n },\n {\n count: 15,\n sprite: { kind: 'circle', radius: [0.003241, 0.006481], color: '#e8eff5' },\n motion: { type: 'drift', angle: 82, speed: [0.05093, 0.1111], bob: 0.009259 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Warp Tunnel: showcases `warp` motion (perspective depth — size/alpha/speed scale\n * with 1/z), `streak` sprites oriented along the analytic heading, `colorWeights`\n * (mostly white stars, occasional blue/amber), and light `ghosting` for smear.\n */\nexport const WARP_TUNNEL_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'warp-tunnel',\n label: 'Warp Tunnel',\n seed: 1701,\n motionIntensity: 'energetic',\n ghosting: 0.55,\n background: { type: 'solid', color: '#020208' },\n layers: [\n {\n key: 'far-stars',\n count: 150,\n sprite: {\n kind: 'streak',\n length: [0.008, 0.02],\n width: 0.0015,\n color: '#cfd8ff',\n colors: ['#cfd8ff', '#ffffff', '#8ab4ff', '#ffd9a0'],\n colorWeights: [5, 3, 1.5, 0.5],\n },\n motion: { type: 'warp', speed: [0.06, 0.16] },\n alpha: [0.5, 0.9],\n blend: 'lighter',\n },\n {\n key: 'near-stars',\n count: 50,\n sprite: {\n kind: 'streak',\n length: [0.025, 0.06],\n width: 0.0025,\n color: '#ffffff',\n colors: ['#ffffff', '#a8c8ff'],\n colorWeights: [3, 1],\n },\n motion: { type: 'warp', speed: [0.3, 0.55] },\n alpha: [0.7, 1],\n blend: 'lighter',\n },\n {\n key: 'core-glow',\n count: 1,\n sprite: { kind: 'circle', radius: [0.06, 0.06], color: '#3a4a8f', soft: true },\n motion: { type: 'static' },\n position: { x: 0.5, y: 0.5 },\n alpha: [0.35, 0.35],\n pulse: { amp: 0.15, period: 5000 },\n blend: 'lighter',\n },\n ],\n};\n","import type { SaverSpec } from '../types';\nimport { AQUARIUM_SPEC } from './aquarium';\nimport { AURORA_SPEC } from './aurora';\nimport { COMETS_SPEC } from './comets';\nimport { CONSTELLATION_SPEC } from './constellation';\nimport { DASHBOARD_SPEC } from './dev-dashboard';\nimport { FACETS_SPEC } from './facets';\nimport { HAIKU_SPEC } from './haiku';\nimport { LANTERNS_SPEC } from './lanterns';\nimport { MATRIX_RAIN_SPEC } from './matrix-rain';\nimport { NOSTALGHIA_CANDLE_SPEC } from './nostalghia-candle';\nimport { POLYGONS_SPEC } from './polygons';\nimport { ORRERY_SPEC } from './orrery';\nimport { PINGS_SPEC } from './pings';\nimport { PROCESSION_SPEC } from './procession';\nimport { RAIN_SPEC } from './rain';\nimport { RELAY_BOARD_SPEC } from './relay-board';\nimport { SAKURA_SPEC } from './sakura';\nimport { SNOWFALL_SPEC } from './snowfall';\nimport { WARP_TUNNEL_SPEC } from './warp-tunnel';\n\nexport { AQUARIUM_SPEC } from './aquarium';\nexport { COMETS_SPEC } from './comets';\nexport { CONSTELLATION_SPEC } from './constellation';\nexport { RAIN_SPEC } from './rain';\nexport { SNOWFALL_SPEC } from './snowfall';\nexport { LANTERNS_SPEC } from './lanterns';\nexport { SAKURA_SPEC } from './sakura';\nexport { DASHBOARD_SPEC } from './dev-dashboard';\nexport { HAIKU_SPEC } from './haiku';\nexport { ORRERY_SPEC } from './orrery';\nexport { AURORA_SPEC } from './aurora';\nexport { MATRIX_RAIN_SPEC } from './matrix-rain';\nexport { NOSTALGHIA_CANDLE_SPEC } from './nostalghia-candle';\nexport { PINGS_SPEC } from './pings';\nexport { FACETS_SPEC } from './facets';\nexport { RELAY_BOARD_SPEC } from './relay-board';\nexport { POLYGONS_SPEC } from './polygons';\nexport { PROCESSION_SPEC } from './procession';\nexport { WARP_TUNNEL_SPEC } from './warp-tunnel';\n\n/** Catalog entry for a bundled schema example. */\nexport interface SchemaExample {\n id: string;\n label: string;\n spec: SaverSpec;\n}\n\n/** Ordered catalog of bundled schema examples. Add new specs as standalone files, then register here. */\nexport const SCHEMA_EXAMPLES: readonly SchemaExample[] = [\n { id: 'aquarium', label: 'Aquarium', spec: AQUARIUM_SPEC },\n { id: 'rain', label: 'Rain', spec: RAIN_SPEC },\n { id: 'snowfall', label: 'Snowfall', spec: SNOWFALL_SPEC },\n { id: 'lanterns', label: 'Night Lanterns', spec: LANTERNS_SPEC },\n { id: 'sakura', label: 'Sakura Drift', spec: SAKURA_SPEC },\n { id: 'dev-dashboard', label: 'Control Center', spec: DASHBOARD_SPEC },\n { id: 'orrery', label: 'Orrery', spec: ORRERY_SPEC },\n { id: 'constellation', label: 'Constellation', spec: CONSTELLATION_SPEC },\n { id: 'comets', label: 'Comet Shower', spec: COMETS_SPEC },\n { id: 'aurora', label: 'Aurora', spec: AURORA_SPEC },\n { id: 'warp-tunnel', label: 'Warp Tunnel', spec: WARP_TUNNEL_SPEC },\n { id: 'polygons', label: 'Polygons', spec: POLYGONS_SPEC },\n { id: 'matrix-rain', label: 'Matrix Rain', spec: MATRIX_RAIN_SPEC },\n { id: 'procession', label: 'Night Procession', spec: PROCESSION_SPEC },\n { id: 'nostalghia-candle', label: \"Nostalghia's Candle\", spec: NOSTALGHIA_CANDLE_SPEC },\n { id: 'haiku', label: 'Haiku', spec: HAIKU_SPEC },\n { id: 'pings', label: 'Pings', spec: PINGS_SPEC },\n { id: 'facets', label: 'Facets', spec: FACETS_SPEC },\n { id: 'relay-board', label: 'Relay Board', spec: RELAY_BOARD_SPEC },\n] as const;\n\n/** All example specs in catalog order (tests, batch compile). */\nexport const EXAMPLE_SPECS: SaverSpec[] = SCHEMA_EXAMPLES.map((e) => e.spec);\n\n/** Lookup by saver id. */\nexport const EXAMPLE_BY_ID: Readonly<Record<string, SaverSpec>> = Object.fromEntries(\n SCHEMA_EXAMPLES.map((e) => [e.id, e.spec]),\n);\n"],"mappings":"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","names":["HEX","catmullRom","y","x","wrap","unitScale","createRng","createRng","createRng","createRng","createRng","createRng","s","sizePx"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/steer.ts","../src/validate.ts","../src/shapes.ts","../src/simulate.ts","../src/compile.ts","../src/sequence.ts","../src/advise.ts","../src/luma.ts","../src/cohesion.ts","../src/describe.ts","../src/perceive.ts","../src/examples/aquarium.ts","../src/examples/aurora.ts","../src/examples/comets.ts","../src/examples/constellation.ts","../src/examples/dev-dashboard.ts","../src/examples/facets.ts","../src/examples/haiku.ts","../src/examples/lanterns.ts","../src/examples/lobby-talk.ts","../src/examples/matrix-rain.ts","../src/examples/nostalghia-candle.ts","../src/examples/polygons.ts","../src/examples/orrery.ts","../src/examples/pings.ts","../src/examples/procession.ts","../src/examples/rain.ts","../src/examples/relay-board.ts","../src/examples/sakura.ts","../src/examples/snowfall.ts","../src/examples/warp-tunnel.ts","../src/examples/index.ts"],"sourcesContent":["/**\n * Declarative, agent-authorable saver format. A `SaverSpec` describes a saver as DATA\n * (no code), which `compileSaver` turns into a seeded, deterministic, flash-safe\n * SaverPlugin. It models the \"drifting sprite field\" family that covers most classic\n * savers (fish, toasters, DVD, rain, messages): a static background plus one or more\n * layers of entities that move.\n *\n * SAFETY INVARIANT: there is deliberately NO full-field strobe/flash primitive — the\n * background is static and entities are bounded sprites — so a compiled spec cannot\n * produce photosensitive flashing by construction (proven by sampling a compiled spec\n * through @idle-screens/validator).\n */\nexport const SCHEMA_VERSION = 1 as const;\n\nexport interface SaverSpec {\n schemaVersion: 1;\n id: string;\n label: string;\n /** Deterministic seed; falls back to the host's SaverContext.seed. */\n seed?: number;\n background?: BackgroundSpec;\n layers: LayerSpec[];\n motionIntensity?: 'calm' | 'moderate' | 'energetic';\n /**\n * Declared density intent. `sparse` says the emptiness is the point (one\n * mark on a dark ground, long silences): `adviseSpec` withholds\n * `sparse-scene`, and scorers that gate on coverage should read this before\n * calling a faithful scene broken. `dense` withholds `dense-scene` the same\n * way. Either declaration is checked against the measured coverage and a\n * `density-mismatch` advisory fires when the scene contradicts it. Omitted\n * means `normal`. A hint only — it changes no pixel.\n */\n density?: 'sparse' | 'normal' | 'dense';\n /**\n * Frame persistence (0..1, capped at LIMITS.maxGhosting). Instead of fully clearing,\n * each frame the background is painted at reduced alpha so moving entities leave\n * decaying after-images (Mystify smears, long-exposure light). Inherently\n * flash-safe: ghosting can only smooth luminance changes, never sharpen them.\n * `renderFrame(t)` stays deterministic for seeks via a fixed-step warm-up replay.\n */\n ghosting?: number;\n /** Dimensional unit system. 'viewport' (default) = all sizes/speeds/distances are fractions of min(w,h). */\n units?: 'viewport' | 'px';\n /**\n * Resolution at which this spec was designed. Density scaling kicks in above this\n * threshold: entity counts scale by min(w,h) / referenceViewport. Default: 1080.\n * Set to your design resolution so a spec authored at 4K doesn't over-densify.\n */\n referenceViewport?: number;\n}\n\nexport type BackgroundSpec =\n | { type: 'solid'; color: string }\n | { type: 'gradient'; stops: GradientStop[]; band?: BandSpec; drift?: BackgroundDrift };\n\n/** A vertical gradient stop (`at` 0 = top, 1 = bottom). */\nexport interface GradientStop {\n at: number;\n color: string;\n}\n\n/** An optional solid band at the bottom (e.g. an aquarium seafloor). */\nexport interface BandSpec {\n color: string;\n /** Band height — px or a viewport fraction, per the spec's `units`. */\n height: number;\n}\n\n/** Slow oscillation of gradient stop positions — makes the background feel alive. */\nexport interface BackgroundDrift {\n /** Full cycle period in ms. Floor: LIMITS.minDriftPeriod (10 s). */\n period: number;\n /** How far stops shift (fraction of the 0..1 range). Default 0.15, max 0.3. */\n amount?: number;\n}\n\nexport interface LayerSpec {\n count: number;\n sprite: SpriteSpec;\n /** Sprite size range in px (font size for emoji/text; ignored for circle). */\n size?: [number, number];\n motion: MotionSpec;\n /** Wrap around the opposite edge when leaving the viewport. Default true. */\n wrap?: boolean;\n /** Flip the sprite horizontally to face its heading. Default false. */\n flip?: boolean;\n /** Per-entity opacity range, both 0..1. Default [1,1]. */\n alpha?: [number, number];\n /**\n * Compositing for this layer. 'lighter' = additive (glow stacking); 'screen' =\n * gentler additive for pale backgrounds; 'multiply' = darkening (shadows,\n * silhouettes). Default source-over. None of these can strobe.\n */\n blend?: 'lighter' | 'screen' | 'multiply';\n /**\n * Fractional spawn window (0 = left/top, 1 = right/bottom). Constrains where\n * entities are PLACED, not where they may travel. Default full viewport.\n */\n region?: { x?: [number, number]; y?: [number, number] };\n /**\n * Sinusoidal opacity breathing. SAFETY: amp is capped (LIMITS.maxPulseAmp),\n * period has a floor (LIMITS.minPulsePeriod — max 2 Hz), and every entity gets\n * its own seeded phase, so a layer can never strobe in unison. Effective alpha\n * is clamped to 0..1.\n *\n * `wave` derives each entity's phase from its spawn position instead of a seeded\n * draw, turning independent breathing into a traveling wave across the field\n * (ripples, wind through grass). `wavelength` is dimensional (px or viewport\n * units); `angle` is the propagation direction in degrees (0 = rightward,\n * default 0). Still flash-safe: neighbors are out of phase by construction.\n */\n pulse?: { amp: number; period: number; wave?: { wavelength: number; angle?: number } };\n /**\n * Per-entity rotation speed in degrees/sec (positive = clockwise).\n * Each entity gets a seeded starting angle. Composes with any motion type.\n * A scalar applies one speed to every entity; a `[min, max]` range gives each\n * entity a seeded speed within the range (like `speed`/`alpha`) — confetti,\n * tumbling debris, foliage. Existing scalar specs are unaffected (the range\n * form draws one extra seeded value, only when present).\n */\n spin?: number | [number, number];\n /**\n * Sinusoidal size breathing, parallel to `pulse` for opacity. `amp` is a\n * fraction of base size (0.3 = ±30 %). `period` in ms with the same\n * flash-safety floor as pulse. Per-entity seeded phase.\n */\n grow?: { amp: number; period: number };\n /**\n * Addressable name for this layer. Enables `setParam` to use `key.field` paths\n * instead of `layers.N.field` indices. Also makes specs self-documenting.\n */\n key?: string;\n /**\n * Exact fractional position {x, y} for a single entity (0 = left/top, 1 = right/bottom).\n * Only valid when `count` is 1 — or, with a `list` / `table` layout, as the\n * top-left anchor of the whole block. Overrides `region` scatter placement.\n */\n position?: { x: number; y: number };\n /**\n * Inter-entity links. `mode` picks the wiring:\n * - 'nearest' (default): each entity's k nearest neighbors within maxDist.\n * - 'chain': entities connected in order (0-1-2-…) — Mystify polygons, string\n * art. Ignores k/maxDist; `closed` joins the last entity back to the first.\n * - 'random': a fixed golden-ratio-stride wiring (k partners per entity,\n * deterministic, no RNG draws) — breaks the crystalline k-nearest look.\n * `falloff` fades link alpha with distance/maxDist, killing pop-in at the cutoff.\n * Capped at LIMITS.maxLinksK. Layer count must be <= LIMITS.maxLinkLayerCount when set.\n */\n links?: {\n k: number;\n maxDist: number;\n color?: string;\n alpha?: number;\n width?: number;\n mode?: 'nearest' | 'chain' | 'random';\n falloff?: boolean;\n closed?: boolean;\n };\n /**\n * Afterglow trail behind moving entities. Samples past positions analytically\n * (no state, fully deterministic). `length` in ms, `fade` 0..1 (default 1 = full fade).\n */\n trail?: { length: number; fade?: number };\n /**\n * Grid placement instead of random scatter: entities fill cells row-major within\n * `region`. `columns` defaults to an aspect-fit square-ish grid; `jitter` (0..1,\n * scalar or per-axis) offsets each entity within its cell by a seeded fraction of\n * the cell size — `{ y: 1 }` keeps columns crisp while scattering vertically\n * (Matrix rain). Unlocks column effects, LED walls, mosaics, uniform dot fields.\n */\n layout?:\n | { type: 'grid'; columns?: number; jitter?: number | { x?: number; y?: number } }\n /**\n * Data layouts — entities in READING ORDER, no scatter. `list` stacks them\n * in one column `gap` apart (viewport units of min(w,h), default 0.06);\n * `table` fills `columns` row-major with `gap` `{x, y}` (one number = both).\n * Text and emoji sprites take `strings[i]` / `glyphs[i]` in order instead of\n * a seeded pick, and palette `colors[i]` likewise, so N labels or N bars are\n * ONE layer. `position` (with any count) is the block's top-left anchor;\n * without it the block is centred in `region`.\n */\n | { type: 'list'; gap?: number }\n | { type: 'table'; columns: number; gap?: number | { x?: number; y?: number } };\n /**\n * Layer lifecycle for act structure — a pure function of t, no state. Alpha is 0\n * before `enter` (ms), ramps up over `fade` ms (default 1000), holds at 1, then\n * ramps down starting at `exit`. Entities are skipped entirely while at alpha 0.\n */\n life?: { enter?: number; exit?: number; fade?: number };\n /**\n * Sparse events — marks that appear, expand and fade in place, one at a time,\n * with long silences between (the \"one ping\" primitive). Each entity is dark\n * except for a window of `life` ms that recurs every `every` ms at a\n * per-entity offset: `jitter` 1 (default) scatters the offsets (a fixed\n * low-discrepancy sequence — not seeded, so declaring `emit` disturbs no\n * other draw and the same spec times its events identically under every\n * seed), 0 spreads the entities evenly across the period — a metronome, one\n * event at a time as long as `life ≤ every / count`.\n * Inside a window the entity fades in over the first quarter and out over\n * the rest; `grow` scales its size from `grow[0]` to `grow[1]` across the\n * window — expansion rather than travel. A pure function of t. Flash safety:\n * `every` ≥ 1000 ms and `life` ≥ 500 ms, so no entity fires more than once a\n * second and never as a hard cut. Composes with `pulse`, `life`, `trail` and\n * every motion; with `motion.ease` the eased travel restarts on every event.\n */\n emit?: { every: number; life: number; jitter?: number; grow?: [number, number] };\n /**\n * Phase-lock. Replaces the seeded per-entity phases of `pulse`, `grow` and\n * `cycle` with one shared phase (`phase` in turns, 0..1, default 0) and runs\n * those three at `rate` × scene time (default 1). Two layers declaring the\n * same clock breathe in step; different phases give a fixed offset (call and\n * response). `pulse.wave` still adds its position-derived phase on top, so a\n * clocked wave stays a wave. Because a clocked layer moves in unison, its\n * `pulse`/`grow` periods must satisfy `period / rate ≥ 1000 ms` (1 Hz).\n */\n clock?: { phase?: number; rate?: number };\n}\n\n/**\n * Closed-form velocity easing for `drift`, `rise` and `wander`. `settle`\n * starts at the entity's speed and decelerates to rest with time constant\n * `tau` ms — it travels `speed × tau` and stops, a mark flung and coming to\n * rest. `buoyant` starts at rest and approaches the speed over `tau` — a\n * bubble reaching terminal velocity. Position stays an analytic function of\n * t (no integration state). With `emit`, the eased travel restarts from the\n * spawn point on every event. For `wander` only the base velocity eases —\n * the harmonic meander keeps breathing, so a settled wanderer hovers rather\n * than freezes.\n */\nexport interface MotionEase {\n type: 'settle' | 'buoyant';\n tau: number;\n}\n\nexport type SpriteSpec =\n | { kind: 'emoji'; glyphs: string[]; cycle?: CycleSpec }\n | {\n kind: 'text';\n strings: string[];\n color?: string;\n font?: string;\n align?: 'left' | 'center' | 'right';\n baseline?: 'top' | 'middle' | 'bottom';\n maxWidth?: number;\n cycle?: CycleSpec;\n /** See `TextRole`. Absent ⇒ no legibility advisories, no pixel change. */\n role?: TextRole;\n }\n /** `soft` renders a radial falloff (glow orb) instead of a hard disc.\n * `colorWeights` (same length as `colors`) biases the seeded per-entity pick —\n * \"mostly cool tones, occasional ember\" without duplicating entries. */\n | { kind: 'circle'; radius: [number, number]; color: string; soft?: boolean; colors?: string[]; colorWeights?: number[] }\n /** Unfilled circle (bubbles, portals, sonar pings). `width` = stroke width. */\n | { kind: 'ring'; radius: [number, number]; color: string; width?: number; colors?: string[]; colorWeights?: number[] }\n /**\n * A line segment oriented along the entity's instantaneous heading (derived\n * analytically from its motion) with a faded tail — rain that reads as rain,\n * shooting stars, warp stars. `length` is the segment length range; `width` the\n * stroke width.\n */\n | { kind: 'streak'; length: [number, number]; color: string; width?: number; colors?: string[]; colorWeights?: number[] }\n /**\n * Axis-aligned rectangle (rotates with `spin`). `width` is the horizontal size\n * range; `aspect` the height/width ratio range (default [1,1] = squares).\n * `feather` (0..1) softens the edges: that fraction of the half-size fades\n * out toward the border — Rothko's soft-edged block at 0.5–0.8.\n * Mondrian blocks, confetti, city lights.\n */\n | { kind: 'rect'; width: [number, number]; aspect?: [number, number]; color: string; feather?: number; colors?: string[]; colorWeights?: number[] }\n /**\n * A data bar. Entity i draws a bar `length × values[i] / max` long (viewport\n * units of min(w,h)), `thickness` thick, growing from its position toward\n * `direction` (default 'right'). `values` are PAINT — steer\n * `layers.N.sprite.values` and the bars glide; `max` defaults to the largest\n * value. Pair with a `list` layout: a chart is one layer, labels another.\n */\n | {\n kind: 'bar';\n values: number[];\n length: number;\n thickness: number;\n color: string;\n max?: number;\n direction?: 'right' | 'left' | 'up' | 'down';\n colors?: string[];\n colorWeights?: number[];\n }\n /**\n * Regular or custom polygon. `sides` (3..12, default 6) draws a regular\n * n-gon of the seeded `radius` (circumradius), point up; `points` (3..24\n * unit coordinates in −1..1, scaled by the radius) draws any facet — a\n * Picasso shard, a Kandinsky triangle, a Mondrian plane. `soft` feathers\n * the fill from the centre like a soft circle. Rotates with `spin`.\n */\n | { kind: 'polygon'; radius: [number, number]; color: string; sides?: number; points?: Array<[number, number]>; soft?: boolean; colors?: string[]; colorWeights?: number[] }\n /**\n * A freehand mark: a path through `points` (2..24 unit coordinates in\n * −1..1, scaled by the seeded `length`) stroked `width` wide with round\n * joins. `curve: 'smooth'` (default) runs a Catmull-Rom spline through the\n * points, `'linear'` a polyline. `taper` thins the mark to almost nothing at\n * both ends — a brush stroke rather than a line. `orient` turns the path's\n * +x along the entity's heading (like `streak`). Rotates with `spin`. Van\n * Gogh's stroke, Hokusai's contour, O'Keeffe's petal, Basquiat's scrawl.\n */\n | {\n kind: 'stroke';\n length: [number, number];\n points: Array<[number, number]>;\n color: string;\n width?: number;\n curve?: 'smooth' | 'linear';\n taper?: boolean;\n orient?: boolean;\n colors?: string[];\n colorWeights?: number[];\n }\n /**\n * Multi-line text block with deterministic line-breaking. Unlike `text` (one\n * string drawn as a single fillText call), `textBlock` wraps `text` within\n * `maxWidth` using a fixed metrics table so line breaks are identical across\n * platforms (same seed → same frames). All dimensions are viewport-fraction\n * (of `min(w,h)`), not px — addresses the absolute-font-size inconsistency.\n * Use with `count: 1`, `motion: { type: 'static' }`, and `position`.\n */\n | {\n kind: 'textBlock';\n text: string;\n /** Wrap width as a fraction of `min(w,h)` (up to 2.0 — `text-off-screen` catches overflow). */\n maxWidth: number;\n fontSize: number;\n lineHeight?: number;\n /** Moves the painted lines inside the wrap width (ragged edge); never the block. */\n align?: 'left' | 'center' | 'right';\n color?: string;\n reveal?: TextRevealSpec;\n /**\n * Which point of the rendered text (widest line × lines·lineHeight, as\n * `align` lays it out) `position` names. Absent: today's behaviour —\n * `position` is the top-left of the `maxWidth` layout box. With\n * `'center'` the block is centred at `position` on every aspect ratio.\n * Placement, so it is in the structural signature.\n */\n anchor?: TextBlockAnchor;\n /**\n * CSS font family and/or weight/style only (`\"bold monospace\"`,\n * `\"300 'Inter', sans-serif\"`). A size inside it is rejected —\n * `fontSize` owns size. Absent: `system-ui, sans-serif`.\n */\n font?: string;\n /**\n * 0..1 multiplier on the block's paint alpha (default 1). Paint, not\n * carpentry: excluded from the structural signature, so steering it\n * with `dur` glides the block in or out without a rebuild. Declare it\n * (`\"opacity\": 1`) to make the path steerable.\n */\n opacity?: number;\n /** See `TextRole`. Absent ⇒ no legibility advisories, no pixel change. */\n role?: TextRole;\n };\n\n/**\n * What a text layer is *for* — a declaration, not a pixel. `read` says the\n * words must be readable from across the room and opts the layer into\n * `adviseSpec`'s legibility advisories (`text-legibility`, `text-safe-area`).\n * `atmosphere` says the text is texture (a haiku fading in a corner, dim\n * labels on a wall board) and is the same as absent: silent. Changes no\n * pixel anywhere, on any client; never part of the structural signature.\n */\nexport type TextRole = 'read' | 'atmosphere';\n\n/** Compass points of a `textBlock`'s rendered box that `position` may name. */\nexport type TextBlockAnchor =\n | 'top-left' | 'top' | 'top-right'\n | 'left' | 'center' | 'right'\n | 'bottom-left' | 'bottom' | 'bottom-right';\n\n/**\n * Animated typing/deleting for `textBlock`. Layout always runs on the FULL\n * text — reveal only masks which glyphs are painted, so lines never reflow\n * and the block's box never changes size. `progress` is a numeric paint\n * param (excluded from the structural signature), so steering it with\n * `dur`/`ease` animates typing client-side in one call; gliding it back to 0\n * deletes. With center/right `align`, the revealing line stays anchored to\n * its alignment as it types (only left-aligned text reads as a classic\n * typewriter).\n */\nexport interface TextRevealSpec {\n /**\n * 0..1 fraction of the text revealed (default 1 = fully shown). Quantized\n * by `mode`. Steerable paint — glide it to animate typing or deleting.\n */\n progress?: number;\n /**\n * Reveal granularity: per-grapheme (default), per-word, per-line, or\n * `glyphFade` — each glyph fades in over a staggered alpha ramp instead of\n * appearing whole (the caption look). Still a pure function of `progress`.\n */\n mode?: 'typewriter' | 'word' | 'line' | 'glyphFade';\n /**\n * Self-typing rate in graphemes/second from scene start (media time). The\n * effective progress is `min(progress, speed·t/total)` — so a steered\n * `progress` can hold or delete even while `speed` is set. 0 = off.\n */\n speed?: number;\n /**\n * Caret at the reveal frontier. `true` for defaults, or configure blink\n * rate (Hz, full cycles/sec, capped at 3 for flash safety) and color.\n * Blink is a square wave of `t` — deterministic like everything else.\n */\n caret?: boolean | { blink?: number; color?: string };\n /**\n * `glyphFade` only: each glyph's fade window as a fraction of progress\n * (0 exclusive to 1, default 0.15). Small = soft typewriter; large = a\n * wave of overlapping fades. Ignored by the other modes.\n */\n fade?: number;\n}\n\n/** Rotate through sprite variants over time. Each entity offsets by its seeded phase. */\nexport interface CycleSpec {\n period: number;\n}\n\nexport type MotionSpec =\n /**\n * Drift at a per-entity speed picked from `speed` (px/sec) along `angle` degrees\n * (0 = right, 90 = down; default 0). `bidirectional` randomly flips horizontal\n * direction per entity (e.g. fish swimming both ways); `bob` adds a small vertical\n * wobble amplitude (px). Covers horizontal fields, diagonals (toasters) and rain\n * (angle 90).\n */\n | { type: 'drift'; speed: [number, number]; angle?: number; bidirectional?: boolean; bob?: number; ease?: MotionEase }\n /** Rise upward (px/sec) with an optional horizontal sway amplitude (px) — bubbles. */\n | { type: 'rise'; speed: [number, number]; sway?: number; ease?: MotionEase }\n /** Bounce diagonally at a per-entity speed, reflecting off the edges (px/sec). */\n | { type: 'bounce'; speed: [number, number] }\n /** Entity stays exactly where placed. No movement. Use with `position` for pinned elements. */\n | { type: 'static' }\n /**\n * Orbit around a center point. Each entity gets a seeded radius from `radius`\n * and a seeded phase. `speed` is angular velocity in degrees/sec. `center` is\n * fractional {x, y} (default {0.5, 0.5} = viewport center) — or\n * `{ layer: key }` to orbit a single-entity parent layer (moons around a\n * wandering planet). Strictly one level deep: the parent may not itself\n * orbit a layer, and must have `count: 1`.\n */\n | { type: 'orbit'; speed: [number, number]; radius: [number, number]; center?: { x: number; y: number } | { layer: string } }\n /**\n * Organic harmonic drift — the analytic flow field. Each entity moves at a base\n * velocity from `speed` plus 3 seeded sine octaves per axis, producing flowing\n * curved paths (Flurry streams, aurora, jellyfish) with zero simulation state.\n * `angle` fixes the base heading in degrees (omit for a seeded heading per\n * entity); `meander` scales the harmonic amplitude (dimensional, default 0.05\n * viewport units); `coherence` (0..1) blends every entity's harmonics toward a\n * shared layer-level set — at 1 the field undulates in unison (fake flocking).\n */\n | { type: 'wander'; speed: [number, number]; angle?: number; meander?: number; coherence?: number; ease?: MotionEase }\n /**\n * Perspective starfield: entities live on a depth axis and stream toward the\n * viewer, projected as `screen = center + offset / z`. Size and alpha scale\n * with 1/z (small and faint at the far plane, large and fast up close), and z\n * wraps — the honest warp tunnel. `speed` is in depth-units/sec\n * (1 = full near-to-far span per second, capped at LIMITS.maxWarpSpeed).\n */\n | { type: 'warp'; speed: [number, number]; center?: { x: number; y: number } }\n /**\n * Choreographed spline motion: entities traverse `points` (fractional {x,y})\n * over `duration` ms. `curve: 'smooth'` (default) uses Catmull-Rom through the\n * points; 'linear' uses straight segments. `closed` (default true) loops the\n * path; open paths ping-pong. Each entity gets a seeded phase offset along the\n * path, and `scatter` (dimensional) adds a seeded per-entity offset so shared\n * paths don't stack. Figure-eights, sweeping arcs, patrol routes.\n */\n | {\n type: 'path';\n points: Array<{ x: number; y: number }>;\n duration: number;\n curve?: 'linear' | 'smooth';\n closed?: boolean;\n scatter?: number;\n };\n\n/** A validation problem, pointing at a JSON path within the spec. */\nexport interface SpecError {\n path: string;\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: SpecError[];\n /** Non-blocking warnings about unknown/misplaced properties or likely authoring mistakes. */\n warnings?: SpecWarning[];\n}\n\n/** An advisory warning (non-blocking). Returned by `adviseSpec`. */\nexport interface SpecWarning {\n path: string;\n code: string;\n message: string;\n /**\n * Viewport-fraction boxes (`x`, `y`, `w`, `h` of `width`/`height`) the\n * warning is about — `text-overlap` carries the two text boxes so an agent\n * can move one without re-deriving the layout. Present only where a\n * warning has geometry to report.\n */\n boxes?: WarningBox[];\n}\n\n/** A rectangle in viewport fractions (x/w of width, y/h of height). */\nexport interface WarningBox {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** Perf/safety caps enforced by `validateSpec`. */\nexport const LIMITS = {\n maxPerLayer: 400,\n maxTotal: 800,\n maxLayers: 36,\n maxSpeed: 4000, // px/sec — bounds motion so nothing teleports\n maxPulseAmp: 0.5, // opacity breathing amplitude cap\n minPulsePeriod: 500, // ms — caps pulse at 2 Hz (WCAG flash threshold is 3 Hz)\n maxSpin: 360, // degrees/sec — one full revolution per second\n maxGrowAmp: 0.8, // size breathing amplitude cap (fraction of base size)\n maxOrbitSpeed: 180, // degrees/sec — half a revolution per second\n maxLinksK: 8,\n maxLinkLayerCount: 200,\n minCyclePeriod: 500, // ms — same flash-safety floor as pulse\n referenceViewport: 1080, // for validating viewport-unit dimensional caps\n maxTrailLength: 5000, // ms — cap trail duration\n maxTrailSamples: 24, // dots per trail\n minDriftPeriod: 10000, // ms — background drift floor (10 s)\n maxDriftAmount: 0.3, // fraction of gradient stop shift\n maxGhosting: 0.95, // frame persistence cap — bounds the seek warm-up replay\n maxGhostReplayFrames: 120, // fixed-step frames replayed on a non-contiguous seek\n maxMeander: 500, // px — wander harmonic amplitude cap (viewport cap: /referenceViewport)\n maxWarpSpeed: 1.5, // depth-units/sec — full near-to-far span in ~0.7 s at max\n minPathPoints: 2,\n maxPathPoints: 24,\n minPathDuration: 2000, // ms — a path lap can't be faster than this\n maxGridColumns: 100,\n maxTextBlockLength: 2000,\n minTextBlockFontSize: 0.01,\n maxTextBlockFontSize: 0.2,\n maxTextBlockMaxWidth: 2.0, // of min(w,h) — wider than the frame is legal; text-off-screen reports the overflow\n maxRevealSpeed: 120, // graphemes/sec — faster than any readable typing\n maxCaretBlinkHz: 3, // full blink cycles/sec — WCAG 2.3.1 flash-safety cap\n maxSegments: 24,\n minSegmentDuration: 1000, // ms — flash-safety floor: segment cuts are luminance transitions\n maxTransitionDur: 5000,\n minTransitionDur: 200,\n minEmitEvery: 1000, // ms — at most one event per second per entity (flash safety)\n maxEmitEvery: 600000, // ms — ten minutes; longer silences than that are `life.enter`\n minEmitLife: 500, // ms — an event is a smooth envelope, never a cut\n maxEmitGrow: 8, // × base size across an event window\n minClockedPeriod: 1000, // ms — a `clock`ed layer breathes in unison, so 1 Hz not 2\n minClockRate: 0.1,\n maxClockRate: 4,\n defaultListGap: 0.06, // viewport units between list/table cells (40 px in px specs)\n defaultListGapPx: 40,\n minPolygonSides: 3,\n maxPolygonSides: 12,\n maxShapePoints: 24, // polygon.points / stroke.points\n minEaseTau: 100, // ms\n maxEaseTau: 120000, // ms\n} as const;\n\n// ---------------------------------------------------------------------------\n// Sequence envelope — multi-segment timeline over unmodified SaverSpecs\n// ---------------------------------------------------------------------------\n\nexport type SequenceTransition =\n | { type: 'cut' }\n /**\n * Interpolate numbers and hex colours into the next (structurally\n * identical) segment over `dur` ms. Strings step on the first frame —\n * unless `text: 'crossfade'`, which draws each `text` / `textBlock` layer\n * whose string(s) differ twice for the window: the outgoing string at\n * `1 − k`, the incoming at `k` (k = the morph's eased progress). Default\n * `'step'`, today's behaviour, byte for byte.\n */\n | { type: 'morph'; dur: number; text?: 'step' | 'crossfade' }\n /**\n * Cross-fade into the next segment over `dur` ms: the outgoing segment\n * stays alive on its own canvas and is composited over the incoming one\n * at `1 − easeSmooth(localT / dur)`. Works between unlike segments (no\n * structural requirement). Hosts on the `basic`/`minimal` capability tier\n * render it as `cut` (see `SequenceMountContext.capabilityTier`).\n */\n | { type: 'fade'; dur: number };\n\nexport interface SequenceSegment {\n key: string;\n scene: SaverSpec;\n /** Segment duration in ms. Only the final segment may omit this (holds until input). */\n duration?: number;\n /** How the segment advances: 'auto' (timer), 'input' (external event), 'either'. */\n advance?: 'auto' | 'input' | 'either';\n transition?: SequenceTransition;\n}\n\nexport interface IdleSequence {\n format: 'idle-sequence';\n schemaVersion: 1;\n id: string;\n label: string;\n seed?: number;\n loop: boolean;\n /**\n * What the sequence clock is anchored to. `mount` (default — today's\n * behaviour): every viewer starts at T = 0 when it mounts, so a joiner sees\n * segment 0 (pre-roll semantics). `epoch`: a viewer handed `sequenceBaseT`\n * on its mount context (the host's `Date.now() − epoch`) starts its clock\n * there, so every screen in a room shows the same segment — a late joiner\n * lands mid-loop. `advance: 'input'` holds stay armed under either mode.\n */\n sync?: 'mount' | 'epoch';\n /**\n * A scene drawn under every segment on the sequence's **global** clock —\n * the ground that does not reset at a boundary or under a `sequence.segment`\n * steer. Segments render over it transparently (their `background` and\n * `ghosting` are ignored; the bed may declare its own). Its entities count\n * toward the perf cap together with the largest segment's, since the two\n * are live at once. Steer it with `bed.<path>`. Absent ⇒ every segment\n * paints its own ground, exactly as before the field existed.\n */\n bed?: SaverSpec;\n segments: SequenceSegment[];\n}\n","/**\n * Pure helpers for LIVE steering of compiled specs (setParam / applyTrack).\n * A track's deltas address spec fields by dot-path (\"layers.0.count\",\n * \"background.stops.1.color\") or layer key (\"fireflies.count\"). Steering\n * changes existing values only — unknown paths are ignored (the server\n * validates and rejects them; the runtime stays lenient).\n */\nimport type { IdleSequence, SaverSpec, SpriteSpec } from './types';\n\ninterface PathTarget {\n parent: Record<string, unknown> | unknown[];\n key: string | number;\n}\n\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\nconst STEERABLE_ROOT_KEYS = new Set(['ghosting', 'referenceViewport']);\n\n/** Resolve a dot-path (key-aware) to its parent + final key; null if absent. */\nexport function resolveSpecPath(spec: unknown, path: string): PathTarget | null {\n if (!spec || typeof spec !== 'object' || !path) return null;\n const parts = path.split('.');\n if (parts.some((p) => UNSAFE_KEYS.has(p))) return null;\n const s = spec as { layers?: Array<Record<string, unknown>> };\n if (parts[0] !== 'layers' && parts[0] !== 'background' && !STEERABLE_ROOT_KEYS.has(parts[0]!) && Array.isArray(s.layers)) {\n const idx = s.layers.findIndex((l) => l && l.key === parts[0]);\n if (idx === -1) return null;\n parts.splice(0, 1, 'layers', String(idx));\n }\n let node: unknown = spec;\n for (let i = 0; i < parts.length - 1; i++) {\n if (node === null || typeof node !== 'object') return null;\n node = (node as Record<string, unknown>)[parts[i]!];\n }\n if (node === null || typeof node !== 'object') return null;\n const last = parts[parts.length - 1]!;\n const key: string | number = Array.isArray(node) ? Number(last) : last;\n const exists = Array.isArray(node)\n ? Number.isInteger(key as number) && (key as number) >= 0 && (key as number) < node.length\n : last in (node as Record<string, unknown>);\n return exists ? { parent: node as PathTarget['parent'], key } : null;\n}\n\n/** A steering delta as carried on a channel control-track. */\nexport interface SteerDelta {\n t: number;\n path: string;\n value: unknown;\n ease?: string;\n dur?: number;\n}\n\n/** Apply deltas to a deep copy of the spec (last-wins, target values). */\nexport function applyDeltasToSpec(spec: SaverSpec, deltas: SteerDelta[]): SaverSpec {\n const copy = JSON.parse(JSON.stringify(spec)) as SaverSpec;\n for (const d of deltas) {\n const loc = resolveSpecPath(copy, d.path);\n if (loc) (loc.parent as Record<string | number, unknown>)[loc.key] = d.value;\n }\n return copy;\n}\n\nconst HEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\nfunction lerpHex(a: string, b: string, k: number): string {\n const ca = hexToRgb(a);\n const cb = hexToRgb(b);\n const mix = ca.map((v, i) => Math.round(v + (cb[i]! - v) * k));\n return `#${mix.map((v) => v.toString(16).padStart(2, '0')).join('')}`;\n}\n\n/**\n * Interpolate between two structurally-similar specs at progress k (0..1).\n * Numbers lerp, hex colours lerp per channel, everything else steps to the\n * target immediately (k > 0). Layer counts round to integers.\n */\nexport function lerpSpec(from: SaverSpec, to: SaverSpec, k: number): SaverSpec {\n const kk = Math.max(0, Math.min(1, k));\n const walk = (a: unknown, b: unknown, key?: string | number): unknown => {\n if (typeof a === 'number' && typeof b === 'number') {\n const v = a + (b - a) * kk;\n return key === 'count' ? Math.max(1, Math.round(v)) : v;\n }\n if (typeof a === 'string' && typeof b === 'string' && HEX.test(a) && HEX.test(b)) {\n return lerpHex(a, b, kk);\n }\n if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {\n return b.map((bv, i) => walk(a[i], bv, i));\n }\n if (a && b && typeof a === 'object' && typeof b === 'object' && !Array.isArray(a) && !Array.isArray(b)) {\n const out: Record<string, unknown> = {};\n for (const kName of Object.keys(b as Record<string, unknown>)) {\n out[kName] = walk((a as Record<string, unknown>)[kName], (b as Record<string, unknown>)[kName], kName);\n }\n return out;\n }\n return kk > 0 ? b : a; // non-interpolable → step to target\n };\n return walk(from, to) as SaverSpec;\n}\n\n/**\n * The string(s) a text layer paints — `strings` of a `text` sprite, `text`\n * of a `textBlock` — or null for every other sprite.\n */\nexport function textStringsOf(sprite: SpriteSpec): string[] | null {\n if (sprite.kind === 'text') return sprite.strings;\n if (sprite.kind === 'textBlock') return [sprite.text];\n return null;\n}\n\n/**\n * Whether the text layer at index `i` paints different words in `a` and\n * `b` — the layers a morph `text: 'crossfade'` draws twice. False for\n * non-text layers and when the strings match.\n */\nexport function textStringsDiffer(a: SaverSpec, b: SaverSpec, i: number): boolean {\n const sa = a.layers[i]?.sprite;\n const sb = b.layers[i]?.sprite;\n if (!sa || !sb) return false;\n const ta = textStringsOf(sa);\n const tb = textStringsOf(sb);\n if (!ta || !tb) return false;\n return ta.length !== tb.length || ta.some((s, j) => s !== tb[j]);\n}\n\n/**\n * True when a morph from `a` to `b` has nothing to interpolate: the two specs\n * differ, yet every difference is a value lerpSpec steps (strings such as\n * `textBlock.text`, mismatched arrays) rather than a number or hex colour it\n * glides. Such a morph looks exactly like a cut. Identical specs return\n * false: a no-op morph is continuity, not a cut. Under `textCrossfade`\n * (the transition declared `text: 'crossfade'`) differing text is something\n * to morph — the words cross-fade — so such twins return false too.\n *\n * Walks `a`/`b` directly rather than sampling `lerpSpec(a, b, 0.5)`: two hex\n * colours a single 8-bit step apart (`#000000` → `#010101`) round their\n * midpoint to the target channel-for-channel, which would make a genuine\n * (if subtle) colour glide look identical to a step. `id`/`label`/\n * `schemaVersion`/layer `key` are identification metadata, never rendered\n * (excluded from `structuralSignature`/`steerablePaths` for the same reason)\n * — a segment pair that differs only there renders identically and is not a\n * morph at all.\n */\nconst NON_RENDERED_KEYS = new Set(['id', 'label', 'schemaVersion', 'key']);\n\nexport function morphNothingMorphable(a: SaverSpec, b: SaverSpec, opts: { textCrossfade?: boolean } = {}): boolean {\n if (opts.textCrossfade && a.layers.some((_, i) => textStringsDiffer(a, b, i))) return false;\n let hasDiff = false;\n let hasGlide = false;\n const walk = (x: unknown, y: unknown, key?: string): void => {\n if (key !== undefined && NON_RENDERED_KEYS.has(key)) return;\n if (x === y) return;\n if (typeof x === 'number' && typeof y === 'number') {\n hasDiff = true;\n hasGlide = true;\n return;\n }\n if (typeof x === 'string' && typeof y === 'string' && HEX.test(x) && HEX.test(y)) {\n const ca = hexToRgb(x);\n const cb = hexToRgb(y);\n if (ca.some((v, i) => v !== cb[i])) {\n hasDiff = true;\n hasGlide = true;\n }\n // else: same colour under a different spelling (case, 3- vs 6-digit) — a no-op, not a difference.\n return;\n }\n if (Array.isArray(x) && Array.isArray(y) && x.length === y.length) {\n for (let i = 0; i < y.length; i++) walk(x[i], y[i]);\n return;\n }\n if (x && y && typeof x === 'object' && typeof y === 'object' && !Array.isArray(x) && !Array.isArray(y)) {\n const keys = new Set([...Object.keys(x as Record<string, unknown>), ...Object.keys(y as Record<string, unknown>)]);\n for (const k of keys) {\n walk((x as Record<string, unknown>)[k], (y as Record<string, unknown>)[k], k);\n }\n return;\n }\n hasDiff = true; // non-interpolable → steps to target\n };\n walk(a, b);\n return hasDiff && !hasGlide;\n}\n\n/**\n * Enumerate all steerable leaf paths in a (resolved) spec. Returns dot-paths\n * like \"layers.0.count\", \"background.stops.1.color\", etc. Metadata fields\n * (id, label, schemaVersion, seed, units, kind, type, key) are excluded —\n * they describe structure, not tuneable values.\n *\n * Layer keys are NOT substituted: paths always use numeric indices.\n * Consumers can map to key-based paths via resolveSpecPath if needed.\n */\nexport function steerablePaths(spec: unknown): string[] {\n if (!spec || typeof spec !== 'object') return [];\n const SKIP = new Set(['kind', 'type', 'key', 'schemaVersion', 'id', 'label', 'seed', 'units', 'motionIntensity', 'mode', 'curve', 'layer']);\n const INDEXED = new Set(['layers', 'stops']);\n const out: string[] = [];\n const walk = (node: unknown, prefix: string, key: string): void => {\n if (Array.isArray(node) && INDEXED.has(key)) {\n node.forEach((child, i) => walk(child, `${prefix}.${i}`, ''));\n return;\n }\n if (Array.isArray(node)) {\n if (prefix) out.push(prefix);\n return;\n }\n if (node && typeof node === 'object') {\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (SKIP.has(k)) continue;\n walk(v, prefix ? `${prefix}.${k}` : k, k);\n }\n return;\n }\n if (prefix) out.push(prefix);\n };\n walk(spec, '', '');\n return out;\n}\n\n/**\n * Every path a sequence accepts on its track: `sequence.segment` (the\n * clicker), the bed's paths under the `bed.` prefix, and the union of every\n * segment's paths (a segment path lands on whichever segment owns it — see\n * `SequenceInstance.applyTrack`). Deduplicated, numeric layer indices as in\n * `steerablePaths`.\n */\nexport function sequenceSteerablePaths(seq: IdleSequence): string[] {\n const out = new Set<string>(['sequence.segment']);\n if (seq.bed) for (const p of steerablePaths(seq.bed)) out.add(`bed.${p}`);\n for (const seg of seq.segments) for (const p of steerablePaths(seg.scene)) out.add(p);\n return [...out];\n}\n\n/** Smooth (ease-in-out) progress curve used for glides. */\nexport function easeSmooth(k: number): number {\n const c = Math.max(0, Math.min(1, k));\n return c * c * (3 - 2 * c);\n}\n\n/**\n * Fields that require re-seeding entities when they change (placement/motion\n * are baked at build time). Colour/alpha/pulse-only changes redraw in place.\n */\nexport function structuralSignature(spec: SaverSpec): string {\n return JSON.stringify([\n spec.units,\n spec.referenceViewport,\n spec.layers.map((l) => {\n const s = l.sprite as Record<string, unknown>;\n return [\n l.count,\n l.size,\n l.region,\n l.position,\n l.motion,\n l.wrap,\n l.flip,\n l.alpha,\n l.pulse,\n l.spin,\n l.grow,\n l.layout,\n l.emit,\n l.clock,\n l.sprite.kind,\n // Dimensional draws baked into entities: radius (circle/ring), length\n // (streak), width+aspect (rect), palette pick (all shaped sprites).\n s.radius,\n s.length,\n l.sprite.kind === 'rect' ? [s.width, s.aspect] : l.sprite.kind === 'bar' ? [s.length, s.thickness] : undefined,\n Array.isArray(s.colors) ? s.colors.length : undefined,\n s.colorWeights,\n l.sprite.kind === 'emoji'\n ? [l.sprite.glyphs.length, l.sprite.cycle?.period]\n : l.sprite.kind === 'text'\n ? [l.sprite.strings.length, l.sprite.cycle?.period]\n : l.sprite.kind === 'textBlock'\n // `anchor` is placement (in); `font`/`opacity`/`text` are paint\n // (out — opacity must glide). Appended only when set so every\n // existing spec's signature string is byte-identical.\n ? (l.sprite.anchor ? [l.sprite.fontSize, l.sprite.anchor] : [l.sprite.fontSize])\n : undefined,\n ];\n }),\n ]);\n}\n","import { LIMITS, SCHEMA_VERSION, type IdleSequence, type SaverSpec, type SpecError, type SpecWarning, type ValidationResult } from './types';\nimport { morphNothingMorphable, structuralSignature } from './steer';\n\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst isObj = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst isStr = (v: unknown): v is string => typeof v === 'string';\nconst isNum = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nconst isRange = (v: unknown): v is [number, number] =>\n Array.isArray(v) && v.length === 2 && isNum(v[0]) && isNum(v[1]) && v[0] <= v[1];\n\n// Known properties at each level — used to detect unknown/misplaced fields\nconst KNOWN_TOP = new Set(['schemaVersion', 'id', 'label', 'seed', 'motionIntensity', 'density', 'units', 'referenceViewport', 'background', 'layers', 'ghosting']);\nconst KNOWN_LAYER = new Set([\n 'count', 'sprite', 'motion', 'size', 'wrap', 'flip', 'alpha', 'blend',\n 'region', 'pulse', 'spin', 'grow', 'key', 'position', 'trail', 'links',\n 'layout', 'life', 'emit', 'clock',\n]);\nconst KNOWN_CIRCLE = new Set(['kind', 'radius', 'color', 'soft', 'colors', 'colorWeights']);\nconst KNOWN_RING = new Set(['kind', 'radius', 'color', 'width', 'colors', 'colorWeights']);\nconst KNOWN_STREAK = new Set(['kind', 'length', 'color', 'width', 'colors', 'colorWeights']);\nconst KNOWN_RECT = new Set(['kind', 'width', 'aspect', 'color', 'feather', 'colors', 'colorWeights']);\nconst KNOWN_BAR = new Set(['kind', 'values', 'length', 'thickness', 'color', 'max', 'direction', 'colors', 'colorWeights']);\nconst KNOWN_POLYGON = new Set(['kind', 'radius', 'color', 'sides', 'points', 'soft', 'colors', 'colorWeights']);\nconst KNOWN_STROKE = new Set(['kind', 'length', 'points', 'color', 'width', 'curve', 'taper', 'orient', 'colors', 'colorWeights']);\nconst KNOWN_EMOJI = new Set(['kind', 'glyphs', 'cycle']);\nconst KNOWN_TEXT = new Set(['kind', 'strings', 'color', 'font', 'align', 'baseline', 'maxWidth', 'cycle', 'role']);\nconst KNOWN_TEXT_BLOCK = new Set(['kind', 'text', 'maxWidth', 'fontSize', 'lineHeight', 'align', 'color', 'reveal', 'anchor', 'font', 'opacity', 'role']);\nconst TEXT_ROLES = new Set(['read', 'atmosphere']);\nconst TEXT_BLOCK_ANCHORS = new Set(['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right']);\n/**\n * A CSS length inside a textBlock `font` — size belongs to `fontSize`. No\n * trailing boundary check: a `\\b`-based (or lookahead-based) version misses\n * \"50% monospace\" (`%` isn't a word character, so there is no boundary after\n * it when the next char is whitespace) and \"14pxmonospace\" (glued straight\n * onto the family name, so the word boundary between two word characters\n * passes it through). The leading `\\d` immediately before the unit is enough\n * to identify an embedded size regardless of what follows it.\n */\nconst FONT_SIZE_RE = /\\d(?:px|pt|pc|em|rem|ex|ch|vw|vh|vmin|vmax|%)/i;\nconst KNOWN_REVEAL = new Set(['progress', 'mode', 'speed', 'caret', 'fade']);\nconst KNOWN_REVEAL_CARET = new Set(['blink', 'color']);\nconst KNOWN_DRIFT = new Set(['type', 'speed', 'angle', 'bidirectional', 'bob', 'ease']);\nconst KNOWN_RISE = new Set(['type', 'speed', 'sway', 'ease']);\nconst KNOWN_BOUNCE = new Set(['type', 'speed']);\nconst KNOWN_STATIC = new Set(['type']);\nconst KNOWN_ORBIT = new Set(['type', 'speed', 'radius', 'center']);\nconst KNOWN_WANDER = new Set(['type', 'speed', 'angle', 'meander', 'coherence', 'ease']);\nconst KNOWN_WARP = new Set(['type', 'speed', 'center']);\nconst KNOWN_PATH = new Set(['type', 'points', 'duration', 'curve', 'closed', 'scatter']);\nconst KNOWN_BG_SOLID = new Set(['type', 'color']);\nconst KNOWN_BG_GRADIENT = new Set(['type', 'stops', 'band', 'drift']);\n\n// Layer-level properties that models commonly misplace inside sprite\nconst LAYER_PROPS_ON_SPRITE = new Set(['blend', 'trail', 'alpha', 'pulse', 'spin', 'grow', 'region', 'links', 'flip', 'wrap', 'key', 'emit', 'clock', 'life', 'layout']);\n\nfunction unknownKeys(obj: Record<string, unknown>, known: Set<string>): string[] {\n return Object.keys(obj).filter((k) => !known.has(k));\n}\n\n/**\n * Validate an untrusted (agent- or JSON-authored) spec structurally + semantically.\n * Returns typed errors and warnings; never throws. `compileSaver` refuses to run an invalid spec.\n *\n * Warnings are non-blocking advisories about unknown/misplaced properties and\n * near-zero speeds. They don't prevent compilation but indicate likely authoring mistakes.\n */\n/**\n * Normalize: if a sprite has `colors[]` but no `color`, default `color` to\n * `colors[0]`. Author intent is unambiguous (pick from the palette), and\n * requiring both is a known footgun (F3). Mutates the spec in place — the\n * added field is always correct.\n */\nfunction normalizeColors(spec: unknown): void {\n if (!isObj(spec) || !Array.isArray(spec.layers)) return;\n for (const layer of spec.layers) {\n if (!isObj(layer)) continue;\n const sprite = (layer as Record<string, unknown>).sprite;\n if (!isObj(sprite)) continue;\n const sp = sprite as Record<string, unknown>;\n if (Array.isArray(sp.colors) && sp.colors.length > 0 && sp.color === undefined) {\n sp.color = sp.colors[0];\n }\n }\n}\n\nexport function validateSpec(spec: unknown): ValidationResult {\n normalizeColors(spec);\n const errors: SpecError[] = [];\n const warnings: SpecWarning[] = [];\n const err = (path: string, message: string): void => void errors.push({ path, message });\n const warn = (path: string, code: string, message: string): void => void warnings.push({ path, code, message });\n\n if (!isObj(spec)) return { valid: false, errors: [{ path: '', message: 'spec must be an object' }], warnings: [] };\n\n if (spec.schemaVersion !== SCHEMA_VERSION) err('schemaVersion', `must be ${SCHEMA_VERSION}`);\n if (!isStr(spec.id) || spec.id.trim() === '') err('id', 'must be a non-empty string');\n if (!isStr(spec.label) || spec.label.trim() === '') err('label', 'must be a non-empty string');\n if (spec.seed !== undefined && !isNum(spec.seed)) err('seed', 'must be a number');\n if (spec.motionIntensity !== undefined && !['calm', 'moderate', 'energetic'].includes(spec.motionIntensity as string)) {\n err('motionIntensity', 'must be calm | moderate | energetic');\n }\n if (spec.density !== undefined && !['sparse', 'normal', 'dense'].includes(spec.density as string)) {\n err('density', 'must be sparse | normal | dense');\n }\n if (spec.units !== undefined && spec.units !== 'px' && spec.units !== 'viewport') {\n err('units', \"must be 'px' | 'viewport'\");\n }\n if (spec.units === 'px' && Array.isArray(spec.layers)) {\n for (const l of spec.layers) {\n if (isObj(l) && isObj((l as Record<string, unknown>).sprite) && ((l as Record<string, unknown>).sprite as Record<string, unknown>).kind === 'textBlock') {\n err('units', \"textBlock dimensions are viewport fractions — units: 'px' is not supported with textBlock sprites\");\n break;\n }\n }\n }\n if (spec.referenceViewport !== undefined) {\n if (!isNum(spec.referenceViewport) || spec.referenceViewport < 100 || spec.referenceViewport > 8640) {\n err('referenceViewport', 'must be a number between 100 and 8640');\n }\n }\n if (spec.ghosting !== undefined && (!isNum(spec.ghosting) || spec.ghosting < 0 || spec.ghosting > LIMITS.maxGhosting)) {\n err('ghosting', `must be a number 0..${LIMITS.maxGhosting}`);\n }\n\n for (const k of unknownKeys(spec, KNOWN_TOP)) {\n warn(k, 'unknown-property', `unknown top-level property '${k}' — will be ignored`);\n }\n\n if (spec.background !== undefined) validateBackground(spec.background, err, warn);\n\n if (!Array.isArray(spec.layers) || spec.layers.length === 0) {\n err('layers', 'must be a non-empty array');\n } else {\n if (spec.layers.length > LIMITS.maxLayers) err('layers', `at most ${LIMITS.maxLayers} layers`);\n let total = 0;\n spec.layers.forEach((layer, i) => {\n total += isObj(layer) && isNum(layer.count) ? layer.count : 0;\n validateLayer(layer, `layers[${i}]`, err, warn, spec);\n });\n if (total > LIMITS.maxTotal) err('layers', `total entities ${total} exceeds cap ${LIMITS.maxTotal}`);\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\nfunction color(v: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isStr(v) || !HEX.test(v)) err(path, 'must be a hex colour like #0a3a52');\n}\n\ntype WarnFn = (path: string, code: string, message: string) => void;\n\nfunction validateBackground(bg: unknown, err: (p: string, m: string) => void, warn: WarnFn): void {\n if (!isObj(bg)) return err('background', 'must be an object');\n if (bg.type === 'solid') {\n color(bg.color, 'background.color', err);\n for (const k of unknownKeys(bg, KNOWN_BG_SOLID)) {\n warn(`background.${k}`, 'unknown-property', `unknown background property '${k}' — will be ignored`);\n }\n } else if (bg.type === 'gradient') {\n if (!Array.isArray(bg.stops) || bg.stops.length < 2) {\n err('background.stops', 'gradient needs at least 2 stops');\n } else {\n bg.stops.forEach((s, i) => {\n if (!isObj(s) || !isNum(s.at) || s.at < 0 || s.at > 1) err(`background.stops[${i}].at`, 'must be 0..1');\n color(isObj(s) ? s.color : undefined, `background.stops[${i}].color`, err);\n });\n }\n if (bg.drift !== undefined) {\n if (!isObj(bg.drift)) err('background.drift', 'must be an object');\n else {\n if (!isNum(bg.drift.period) || bg.drift.period < LIMITS.minDriftPeriod) {\n err('background.drift.period', `must be >= ${LIMITS.minDriftPeriod} ms`);\n }\n if (bg.drift.amount !== undefined && (!isNum(bg.drift.amount) || bg.drift.amount <= 0 || bg.drift.amount > LIMITS.maxDriftAmount)) {\n err('background.drift.amount', `must be > 0 and <= ${LIMITS.maxDriftAmount}`);\n }\n }\n }\n if (bg.band !== undefined) {\n if (!isObj(bg.band)) err('background.band', 'must be an object');\n else {\n color(bg.band.color, 'background.band.color', err);\n if (!isNum(bg.band.height) || bg.band.height <= 0) err('background.band.height', 'must be > 0');\n }\n }\n for (const k of unknownKeys(bg, KNOWN_BG_GRADIENT)) {\n warn(`background.${k}`, 'unknown-property', `unknown background property '${k}' — will be ignored`);\n }\n } else {\n err('background.type', 'must be solid | gradient');\n }\n}\n\nfunction validateLayer(layer: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn, spec?: unknown): void {\n if (!isObj(layer)) return err(path, 'must be an object');\n\n for (const k of unknownKeys(layer, KNOWN_LAYER)) {\n if (k === 'id') {\n warn(`${path}.id`, 'misplaced-property', `'id' is not a layer property — did you mean 'key'? Use 'key' to name a layer`);\n } else if (k === 'depth') {\n warn(`${path}.depth`, 'unknown-property', `'depth' is not a layer property — use motion type 'warp' for true perspective depth, or fake parallax with size/speed/alpha across layers`);\n } else {\n warn(`${path}.${k}`, 'unknown-property', `unknown layer property '${k}' — will be ignored`);\n }\n }\n if (!isNum(layer.count) || !Number.isInteger(layer.count) || layer.count < 1) {\n err(`${path}.count`, 'must be a positive integer');\n } else if (layer.count > LIMITS.maxPerLayer) {\n err(`${path}.count`, `at most ${LIMITS.maxPerLayer} per layer`);\n }\n if (layer.size !== undefined && (!isRange(layer.size) || layer.size[0] <= 0)) {\n err(`${path}.size`, 'must be a [min,max] range of positive px');\n }\n if (layer.wrap !== undefined && typeof layer.wrap !== 'boolean') err(`${path}.wrap`, 'must be a boolean');\n if (layer.flip !== undefined && typeof layer.flip !== 'boolean') err(`${path}.flip`, 'must be a boolean');\n\n if (layer.alpha !== undefined && (!isRange(layer.alpha) || layer.alpha[0] < 0 || layer.alpha[1] > 1)) {\n err(`${path}.alpha`, 'must be a [min,max] range within 0..1');\n }\n if (layer.blend !== undefined && !['lighter', 'screen', 'multiply'].includes(layer.blend as string)) {\n err(`${path}.blend`, \"must be 'lighter' | 'screen' | 'multiply' when set\");\n }\n if (layer.key !== undefined && (!isStr(layer.key) || layer.key.trim() === '')) {\n err(`${path}.key`, 'must be a non-empty string');\n }\n if (layer.position !== undefined) {\n if (!isObj(layer.position) || !isNum(layer.position.x) || !isNum(layer.position.y)) {\n err(`${path}.position`, 'must be {x, y} with numbers 0..1');\n } else {\n if (layer.position.x < 0 || layer.position.x > 1) err(`${path}.position.x`, 'must be 0..1');\n if (layer.position.y < 0 || layer.position.y > 1) err(`${path}.position.y`, 'must be 0..1');\n const dataLayout = isObj(layer.layout) && (layer.layout.type === 'list' || layer.layout.type === 'table');\n if (isNum(layer.count) && layer.count !== 1 && !dataLayout) {\n err(`${path}.position`, \"position requires count: 1 — or a layout of type 'list' / 'table', where it anchors the whole block\");\n }\n }\n }\n if (layer.region !== undefined) {\n if (!isObj(layer.region)) err(`${path}.region`, 'must be an object');\n else {\n for (const axis of ['x', 'y'] as const) {\n const r = layer.region[axis];\n if (r !== undefined && (!isRange(r) || r[0] < 0 || r[1] > 1)) {\n err(`${path}.region.${axis}`, 'must be a [min,max] range within 0..1');\n }\n }\n }\n }\n if (layer.pulse !== undefined) {\n if (!isObj(layer.pulse)) err(`${path}.pulse`, 'must be an object');\n else {\n if (!isNum(layer.pulse.amp) || layer.pulse.amp <= 0 || layer.pulse.amp > LIMITS.maxPulseAmp) {\n err(`${path}.pulse.amp`, `must be within 0..${LIMITS.maxPulseAmp}`);\n }\n if (!isNum(layer.pulse.period) || layer.pulse.period < LIMITS.minPulsePeriod) {\n err(`${path}.pulse.period`, `must be >= ${LIMITS.minPulsePeriod} ms (flash-safety floor)`);\n }\n if (layer.pulse.wave !== undefined) {\n if (!isObj(layer.pulse.wave)) err(`${path}.pulse.wave`, 'must be an object');\n else {\n if (!isNum(layer.pulse.wave.wavelength) || layer.pulse.wave.wavelength <= 0) {\n err(`${path}.pulse.wave.wavelength`, 'must be > 0 (px or viewport-units)');\n }\n if (layer.pulse.wave.angle !== undefined && !isNum(layer.pulse.wave.angle)) {\n err(`${path}.pulse.wave.angle`, 'must be a number (degrees)');\n }\n }\n }\n }\n }\n if (layer.spin !== undefined) {\n if (isRange(layer.spin)) {\n if (Math.abs(layer.spin[0]) > LIMITS.maxSpin || Math.abs(layer.spin[1]) > LIMITS.maxSpin) {\n err(`${path}.spin`, `each end of the range must be within ±${LIMITS.maxSpin} deg/sec`);\n }\n } else if (!isNum(layer.spin)) {\n err(`${path}.spin`, 'must be a number or a [min,max] range (degrees/sec)');\n } else if (Math.abs(layer.spin) > LIMITS.maxSpin) {\n err(`${path}.spin`, `must be within ±${LIMITS.maxSpin} deg/sec`);\n }\n }\n if (layer.grow !== undefined) {\n if (!isObj(layer.grow)) err(`${path}.grow`, 'must be an object');\n else {\n if (!isNum(layer.grow.amp) || layer.grow.amp <= 0 || layer.grow.amp > LIMITS.maxGrowAmp) {\n err(`${path}.grow.amp`, `must be within 0..${LIMITS.maxGrowAmp}`);\n }\n if (!isNum(layer.grow.period) || layer.grow.period < LIMITS.minPulsePeriod) {\n err(`${path}.grow.period`, `must be >= ${LIMITS.minPulsePeriod} ms (flash-safety floor)`);\n }\n }\n }\n\n if (layer.links !== undefined) {\n if (!isObj(layer.links)) err(`${path}.links`, 'must be an object');\n else {\n if (!isNum(layer.links.k) || !Number.isInteger(layer.links.k) || layer.links.k < 1 || layer.links.k > LIMITS.maxLinksK) {\n err(`${path}.links.k`, `must be an integer 1..${LIMITS.maxLinksK}`);\n }\n if (!isNum(layer.links.maxDist) || layer.links.maxDist <= 0) {\n err(`${path}.links.maxDist`, 'must be > 0');\n }\n if (layer.links.color !== undefined) color(layer.links.color, `${path}.links.color`, err);\n if (layer.links.alpha !== undefined && (!isNum(layer.links.alpha) || layer.links.alpha < 0 || layer.links.alpha > 1)) {\n err(`${path}.links.alpha`, 'must be 0..1');\n }\n if (layer.links.width !== undefined && (!isNum(layer.links.width) || layer.links.width <= 0)) {\n err(`${path}.links.width`, 'must be > 0');\n }\n if (layer.links.mode !== undefined && !['nearest', 'chain', 'random'].includes(layer.links.mode as string)) {\n err(`${path}.links.mode`, \"must be 'nearest' | 'chain' | 'random'\");\n }\n if (layer.links.falloff !== undefined && typeof layer.links.falloff !== 'boolean') {\n err(`${path}.links.falloff`, 'must be a boolean');\n }\n if (layer.links.closed !== undefined && typeof layer.links.closed !== 'boolean') {\n err(`${path}.links.closed`, 'must be a boolean');\n }\n if (isNum(layer.count) && layer.count > LIMITS.maxLinkLayerCount) {\n err(`${path}.links`, `layer count must be <= ${LIMITS.maxLinkLayerCount} when links is set`);\n }\n }\n }\n\n if (layer.layout !== undefined) {\n if (isObj(layer.layout) && (layer.layout.type === 'list' || layer.layout.type === 'table')) {\n const lay = layer.layout;\n if (lay.type === 'table' && (!isNum(lay.columns) || !Number.isInteger(lay.columns) || lay.columns < 1 || lay.columns > LIMITS.maxGridColumns)) {\n err(`${path}.layout.columns`, `must be an integer 1..${LIMITS.maxGridColumns}`);\n }\n const gapOk = (v: unknown): boolean => isNum(v) && v > 0;\n if (lay.gap !== undefined) {\n if (isNum(lay.gap)) {\n if (!gapOk(lay.gap)) err(`${path}.layout.gap`, 'must be > 0 (viewport units of min(w,h), or px)');\n } else if (lay.type === 'table' && isObj(lay.gap)) {\n if (lay.gap.x !== undefined && !gapOk(lay.gap.x)) err(`${path}.layout.gap.x`, 'must be > 0');\n if (lay.gap.y !== undefined && !gapOk(lay.gap.y)) err(`${path}.layout.gap.y`, 'must be > 0');\n for (const k of unknownKeys(lay.gap, new Set(['x', 'y']))) {\n warn(`${path}.layout.gap.${k}`, 'unknown-property', `unknown gap property '${k}' — will be ignored`);\n }\n } else {\n err(`${path}.layout.gap`, lay.type === 'table' ? 'must be a number > 0 or { x?, y? }' : 'must be a number > 0');\n }\n }\n for (const k of unknownKeys(lay, new Set(lay.type === 'list' ? ['type', 'gap'] : ['type', 'columns', 'gap']))) {\n warn(`${path}.layout.${k}`, 'unknown-property', `unknown layout property '${k}' — will be ignored`);\n }\n // A data layout reads variants in order: N labels want N strings.\n const sp = layer.sprite;\n if (isObj(sp) && isNum(layer.count)) {\n const variants = sp.kind === 'text' && Array.isArray(sp.strings) ? sp.strings.length\n : sp.kind === 'emoji' && Array.isArray(sp.glyphs) ? sp.glyphs.length\n : sp.kind === 'bar' && Array.isArray(sp.values) ? sp.values.length : null;\n if (variants !== null && variants !== layer.count) {\n warn(`${path}.count`, 'list-length-mismatch', `count is ${layer.count} but the sprite carries ${variants} ${sp.kind === 'bar' ? 'values' : 'variants'} — a ${lay.type} layout reads them in order, so they cycle or go unused`);\n }\n }\n } else if (!isObj(layer.layout) || layer.layout.type !== 'grid') {\n err(`${path}.layout`, \"must be an object with type: 'grid' | 'list' | 'table'\");\n } else {\n if (layer.layout.columns !== undefined && (!isNum(layer.layout.columns) || !Number.isInteger(layer.layout.columns) || layer.layout.columns < 1 || layer.layout.columns > LIMITS.maxGridColumns)) {\n err(`${path}.layout.columns`, `must be an integer 1..${LIMITS.maxGridColumns}`);\n }\n const jit = layer.layout.jitter;\n if (jit !== undefined) {\n const jitterOk = (v: unknown): boolean => isNum(v) && v >= 0 && v <= 1;\n if (isNum(jit)) {\n if (!jitterOk(jit)) err(`${path}.layout.jitter`, 'must be 0..1');\n } else if (isObj(jit)) {\n if (jit.x !== undefined && !jitterOk(jit.x)) err(`${path}.layout.jitter.x`, 'must be 0..1');\n if (jit.y !== undefined && !jitterOk(jit.y)) err(`${path}.layout.jitter.y`, 'must be 0..1');\n } else {\n err(`${path}.layout.jitter`, 'must be a number 0..1 or { x?, y? }');\n }\n }\n if (layer.position !== undefined) {\n warn(`${path}.layout`, 'layout-with-position', 'position overrides layout for the single entity — layout has no effect');\n }\n }\n }\n\n if (layer.life !== undefined) {\n if (!isObj(layer.life)) err(`${path}.life`, 'must be an object');\n else {\n if (layer.life.enter !== undefined && (!isNum(layer.life.enter) || layer.life.enter < 0)) {\n err(`${path}.life.enter`, 'must be >= 0 (ms)');\n }\n if (layer.life.exit !== undefined && (!isNum(layer.life.exit) || layer.life.exit < 0)) {\n err(`${path}.life.exit`, 'must be >= 0 (ms)');\n }\n if (isNum(layer.life.enter) && isNum(layer.life.exit) && layer.life.exit <= layer.life.enter) {\n err(`${path}.life.exit`, 'must be greater than life.enter');\n }\n if (layer.life.fade !== undefined && (!isNum(layer.life.fade) || layer.life.fade < 0)) {\n err(`${path}.life.fade`, 'must be >= 0 (ms)');\n }\n }\n }\n\n if (layer.trail !== undefined) {\n if (!isObj(layer.trail)) err(`${path}.trail`, 'must be an object');\n else {\n if (!isNum(layer.trail.length) || layer.trail.length <= 0 || layer.trail.length > LIMITS.maxTrailLength) {\n err(`${path}.trail.length`, `must be > 0 and <= ${LIMITS.maxTrailLength} ms`);\n }\n if (layer.trail.fade !== undefined && (!isNum(layer.trail.fade) || layer.trail.fade < 0 || layer.trail.fade > 1)) {\n err(`${path}.trail.fade`, 'must be 0..1');\n }\n }\n }\n\n if (layer.emit !== undefined) {\n if (!isObj(layer.emit)) err(`${path}.emit`, 'must be an object { every, life, jitter?, grow? }');\n else {\n const em = layer.emit;\n if (!isNum(em.every) || em.every < LIMITS.minEmitEvery || em.every > LIMITS.maxEmitEvery) {\n err(`${path}.emit.every`, `must be ${LIMITS.minEmitEvery}..${LIMITS.maxEmitEvery} ms (at most one event per second per entity)`);\n }\n if (!isNum(em.life) || em.life < LIMITS.minEmitLife) {\n err(`${path}.emit.life`, `must be >= ${LIMITS.minEmitLife} ms (an event is a smooth envelope, never a cut)`);\n } else if (isNum(em.every) && em.life > em.every) {\n err(`${path}.emit.life`, 'must be <= emit.every (the visible window cannot outlast its period)');\n }\n if (em.jitter !== undefined && (!isNum(em.jitter) || em.jitter < 0 || em.jitter > 1)) {\n err(`${path}.emit.jitter`, 'must be 0..1 (0 = evenly staggered, 1 = scattered by a fixed sequence)');\n }\n if (em.grow !== undefined) {\n if (!Array.isArray(em.grow) || em.grow.length !== 2 || !isNum(em.grow[0]) || !isNum(em.grow[1])) {\n err(`${path}.emit.grow`, 'must be [from, to] size multipliers');\n } else if (em.grow[0] < 0 || em.grow[1] < 0 || em.grow[0] > LIMITS.maxEmitGrow || em.grow[1] > LIMITS.maxEmitGrow) {\n err(`${path}.emit.grow`, `each multiplier must be 0..${LIMITS.maxEmitGrow}`);\n }\n }\n // jitter 0 promises one event at a time; that only holds while a window\n // is shorter than the stagger between entities.\n if (em.jitter === 0 && isNum(em.every) && isNum(em.life) && isNum(layer.count) && layer.count > 1 && em.life > em.every / layer.count) {\n warn(`${path}.emit.life`, 'emit-overlap', `jitter 0 staggers ${layer.count} entities ${(em.every / layer.count).toFixed(0)} ms apart but each stays lit ${em.life} ms — windows overlap, so more than one event is visible at a time. Shorten life or lengthen every`);\n }\n for (const k of unknownKeys(em, new Set(['every', 'life', 'jitter', 'grow']))) {\n warn(`${path}.emit.${k}`, 'unknown-property', `unknown emit property '${k}' — will be ignored`);\n }\n }\n }\n if (layer.clock !== undefined) {\n if (!isObj(layer.clock)) err(`${path}.clock`, 'must be an object { phase?, rate? }');\n else {\n const ck = layer.clock;\n if (ck.phase !== undefined && (!isNum(ck.phase) || ck.phase < 0 || ck.phase > 1)) {\n err(`${path}.clock.phase`, 'must be 0..1 (turns)');\n }\n const rate = ck.rate === undefined ? 1 : ck.rate;\n if (!isNum(rate) || rate < LIMITS.minClockRate || rate > LIMITS.maxClockRate) {\n err(`${path}.clock.rate`, `must be ${LIMITS.minClockRate}..${LIMITS.maxClockRate}`);\n } else {\n // A clocked layer pulses in unison — every entity at once — so the\n // per-entity-phase defence is gone and the period floor doubles.\n const floor = LIMITS.minClockedPeriod * rate;\n if (isObj(layer.pulse) && isNum(layer.pulse.period) && layer.pulse.period < floor) {\n err(`${path}.pulse.period`, `must be >= ${floor} ms when the layer has a clock (period / rate >= ${LIMITS.minClockedPeriod} — the whole layer breathes in unison)`);\n }\n if (isObj(layer.grow) && isNum(layer.grow.period) && layer.grow.period < floor) {\n err(`${path}.grow.period`, `must be >= ${floor} ms when the layer has a clock (period / rate >= ${LIMITS.minClockedPeriod})`);\n }\n const sp = layer.sprite;\n if (isObj(sp) && isObj(sp.cycle) && isNum(sp.cycle.period) && sp.cycle.period < floor) {\n err(`${path}.sprite.cycle.period`, `must be >= ${floor} ms when the layer has a clock (period / rate >= ${LIMITS.minClockedPeriod})`);\n }\n }\n for (const k of unknownKeys(ck, new Set(['phase', 'rate']))) {\n warn(`${path}.clock.${k}`, 'unknown-property', `unknown clock property '${k}' — will be ignored`);\n }\n }\n }\n validateSprite(layer.sprite, `${path}.sprite`, err, warn);\n validateMotion(layer.motion, `${path}.motion`, err, warn, spec);\n}\n\nfunction validateSprite(sprite: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn): void {\n if (!isObj(sprite)) return err(path, 'must be an object');\n\n let knownSet: Set<string>;\n if (sprite.kind === 'emoji') {\n knownSet = KNOWN_EMOJI;\n if (!Array.isArray(sprite.glyphs) || sprite.glyphs.length === 0 || !sprite.glyphs.every(isStr)) {\n err(`${path}.glyphs`, 'must be a non-empty array of strings');\n }\n validateCycle(sprite, path, err);\n } else if (sprite.kind === 'text') {\n knownSet = KNOWN_TEXT;\n if (!Array.isArray(sprite.strings) || sprite.strings.length === 0 || !sprite.strings.every(isStr)) {\n err(`${path}.strings`, 'must be a non-empty array of strings');\n }\n if (sprite.color !== undefined) color(sprite.color, `${path}.color`, err);\n if (sprite.font !== undefined && !isStr(sprite.font)) {\n err(`${path}.font`, 'must be a string');\n }\n if (sprite.align !== undefined && !['left', 'center', 'right'].includes(sprite.align as string)) {\n err(`${path}.align`, 'must be left | center | right');\n }\n if (sprite.baseline !== undefined && !['top', 'middle', 'bottom'].includes(sprite.baseline as string)) {\n err(`${path}.baseline`, 'must be top | middle | bottom');\n }\n if (sprite.maxWidth !== undefined && (!isNum(sprite.maxWidth) || sprite.maxWidth <= 0)) {\n err(`${path}.maxWidth`, 'must be a positive number');\n }\n validateTextRole(sprite, path, err);\n validateCycle(sprite, path, err);\n } else if (sprite.kind === 'circle') {\n knownSet = KNOWN_CIRCLE;\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n if (sprite.soft !== undefined && typeof sprite.soft !== 'boolean') err(`${path}.soft`, 'must be a boolean');\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'ring') {\n knownSet = KNOWN_RING;\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n if (sprite.width !== undefined && (!isNum(sprite.width) || sprite.width <= 0)) err(`${path}.width`, 'must be > 0');\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'streak') {\n knownSet = KNOWN_STREAK;\n if (!isRange(sprite.length) || sprite.length[0] <= 0) err(`${path}.length`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n if (sprite.width !== undefined && (!isNum(sprite.width) || sprite.width <= 0)) err(`${path}.width`, 'must be > 0');\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'rect') {\n knownSet = KNOWN_RECT;\n if (!isRange(sprite.width) || sprite.width[0] <= 0) err(`${path}.width`, 'must be a [min,max] range of positive px');\n if (sprite.aspect !== undefined && (!isRange(sprite.aspect) || sprite.aspect[0] <= 0)) {\n err(`${path}.aspect`, 'must be a [min,max] range of positive height/width ratios');\n }\n if (sprite.feather !== undefined && (!isNum(sprite.feather) || sprite.feather < 0 || sprite.feather > 1)) {\n err(`${path}.feather`, 'must be 0..1 (fraction of the half-size that fades out)');\n }\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'bar') {\n knownSet = KNOWN_BAR;\n if (!Array.isArray(sprite.values) || sprite.values.length === 0 || sprite.values.length > LIMITS.maxPerLayer || !sprite.values.every((v) => isNum(v) && v >= 0)) {\n err(`${path}.values`, `must be 1..${LIMITS.maxPerLayer} numbers >= 0`);\n }\n if (!isNum(sprite.length) || sprite.length <= 0) err(`${path}.length`, 'must be > 0 (full-scale bar length)');\n if (!isNum(sprite.thickness) || sprite.thickness <= 0) err(`${path}.thickness`, 'must be > 0');\n if (sprite.max !== undefined && (!isNum(sprite.max) || sprite.max <= 0)) err(`${path}.max`, 'must be > 0');\n if (sprite.direction !== undefined && !['right', 'left', 'up', 'down'].includes(sprite.direction as string)) {\n err(`${path}.direction`, \"must be 'right' | 'left' | 'up' | 'down'\");\n }\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'polygon') {\n knownSet = KNOWN_POLYGON;\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px (circumradius)');\n if (sprite.sides !== undefined && sprite.points !== undefined) {\n err(`${path}.sides`, 'use sides (a regular polygon) or points (a custom one), not both');\n }\n if (sprite.sides !== undefined && (!isNum(sprite.sides) || !Number.isInteger(sprite.sides) || sprite.sides < LIMITS.minPolygonSides || sprite.sides > LIMITS.maxPolygonSides)) {\n err(`${path}.sides`, `must be an integer ${LIMITS.minPolygonSides}..${LIMITS.maxPolygonSides}`);\n }\n if (sprite.points !== undefined) validateShapePoints(sprite.points, `${path}.points`, 3, err);\n if (sprite.soft !== undefined && typeof sprite.soft !== 'boolean') err(`${path}.soft`, 'must be a boolean');\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'stroke') {\n knownSet = KNOWN_STROKE;\n if (!isRange(sprite.length) || sprite.length[0] <= 0) err(`${path}.length`, 'must be a [min,max] range of positive px (the mark\\'s bounding size)');\n validateShapePoints(sprite.points, `${path}.points`, 2, err);\n if (sprite.width !== undefined && (!isNum(sprite.width) || sprite.width <= 0)) err(`${path}.width`, 'must be > 0');\n if (sprite.curve !== undefined && sprite.curve !== 'smooth' && sprite.curve !== 'linear') err(`${path}.curve`, \"must be 'smooth' | 'linear'\");\n if (sprite.taper !== undefined && typeof sprite.taper !== 'boolean') err(`${path}.taper`, 'must be a boolean');\n if (sprite.orient !== undefined && typeof sprite.orient !== 'boolean') err(`${path}.orient`, 'must be a boolean');\n color(sprite.color, `${path}.color`, err);\n validatePalette(sprite, path, err);\n } else if (sprite.kind === 'textBlock') {\n knownSet = KNOWN_TEXT_BLOCK;\n if (typeof sprite.text !== 'string' || sprite.text.length === 0) {\n err(`${path}.text`, 'must be a non-empty string');\n } else if (sprite.text.length > LIMITS.maxTextBlockLength) {\n err(`${path}.text`, `must be at most ${LIMITS.maxTextBlockLength} characters`);\n }\n if (!isNum(sprite.maxWidth) || sprite.maxWidth <= 0 || sprite.maxWidth > LIMITS.maxTextBlockMaxWidth) {\n err(`${path}.maxWidth`, `must be a positive number up to ${LIMITS.maxTextBlockMaxWidth} (viewport fraction)`);\n }\n if (!isNum(sprite.fontSize) || sprite.fontSize < LIMITS.minTextBlockFontSize || sprite.fontSize > LIMITS.maxTextBlockFontSize) {\n err(`${path}.fontSize`, `must be between ${LIMITS.minTextBlockFontSize} and ${LIMITS.maxTextBlockFontSize} (viewport fraction)`);\n }\n if (sprite.lineHeight !== undefined && (!isNum(sprite.lineHeight) || sprite.lineHeight < 0.5 || sprite.lineHeight > 4)) {\n err(`${path}.lineHeight`, 'must be between 0.5 and 4 (multiplier)');\n }\n if (sprite.align !== undefined && !['left', 'center', 'right'].includes(sprite.align as string)) {\n err(`${path}.align`, \"must be 'left' | 'center' | 'right'\");\n }\n if (sprite.color !== undefined) color(sprite.color, `${path}.color`, err);\n if (sprite.anchor !== undefined && !TEXT_BLOCK_ANCHORS.has(sprite.anchor as string)) {\n err(`${path}.anchor`, \"must be 'top-left' | 'top' | 'top-right' | 'left' | 'center' | 'right' | 'bottom-left' | 'bottom' | 'bottom-right'\");\n }\n if (sprite.font !== undefined) {\n if (!isStr(sprite.font) || sprite.font.trim() === '') {\n err(`${path}.font`, 'must be a non-empty string (family and/or weight)');\n } else if (FONT_SIZE_RE.test(sprite.font)) {\n err(`${path}.font`, 'must name a family and/or weight only — fontSize owns the size');\n }\n }\n if (sprite.opacity !== undefined && (!isNum(sprite.opacity) || sprite.opacity < 0 || sprite.opacity > 1)) {\n err(`${path}.opacity`, 'must be a number between 0 and 1');\n }\n validateTextRole(sprite, path, err);\n if (sprite.reveal !== undefined) {\n const rv = sprite.reveal as Record<string, unknown>;\n if (typeof rv !== 'object' || rv === null || Array.isArray(rv)) {\n err(`${path}.reveal`, 'must be an object');\n } else {\n for (const k of Object.keys(rv)) {\n if (!KNOWN_REVEAL.has(k)) err(`${path}.reveal.${k}`, 'unknown reveal field');\n }\n if (rv.progress !== undefined && (!isNum(rv.progress) || rv.progress < 0 || rv.progress > 1)) {\n err(`${path}.reveal.progress`, 'must be a number between 0 and 1');\n }\n if (rv.mode !== undefined && !['typewriter', 'word', 'line', 'glyphFade'].includes(rv.mode as string)) {\n err(`${path}.reveal.mode`, \"must be 'typewriter' | 'word' | 'line' | 'glyphFade'\");\n }\n if (rv.fade !== undefined && (!isNum(rv.fade) || rv.fade <= 0 || rv.fade > 1)) {\n err(`${path}.reveal.fade`, 'must be between 0 (exclusive) and 1 (fraction of progress)');\n }\n if (rv.speed !== undefined && (!isNum(rv.speed) || rv.speed < 0 || rv.speed > LIMITS.maxRevealSpeed)) {\n err(`${path}.reveal.speed`, `must be between 0 and ${LIMITS.maxRevealSpeed} (graphemes/sec)`);\n }\n if (rv.caret !== undefined && typeof rv.caret !== 'boolean') {\n const caret = rv.caret as Record<string, unknown>;\n if (typeof caret !== 'object' || caret === null || Array.isArray(caret)) {\n err(`${path}.reveal.caret`, 'must be a boolean or an object');\n } else {\n for (const k of Object.keys(caret)) {\n if (!KNOWN_REVEAL_CARET.has(k)) err(`${path}.reveal.caret.${k}`, 'unknown caret field');\n }\n if (caret.blink !== undefined && (!isNum(caret.blink) || caret.blink <= 0 || caret.blink > LIMITS.maxCaretBlinkHz)) {\n err(`${path}.reveal.caret.blink`, `must be between 0 (exclusive) and ${LIMITS.maxCaretBlinkHz} Hz (flash safety)`);\n }\n if (caret.color !== undefined) color(caret.color, `${path}.reveal.caret.color`, err);\n }\n }\n }\n }\n } else {\n err(`${path}.kind`, 'must be emoji | text | circle | ring | streak | rect | bar | polygon | stroke | textBlock');\n return;\n }\n\n for (const k of unknownKeys(sprite, knownSet)) {\n if (LAYER_PROPS_ON_SPRITE.has(k)) {\n warn(`${path}.${k}`, 'misplaced-property', `'${k}' belongs on the layer, not inside sprite — move it up one level`);\n } else {\n warn(`${path}.${k}`, 'unknown-property', `unknown sprite property '${k}' — will be ignored`);\n }\n }\n}\n\n/** Shared colors[] + colorWeights[] validation for circle/ring/streak/rect sprites. */\nfunction validatePalette(sprite: Record<string, unknown>, path: string, err: (p: string, m: string) => void): void {\n if (sprite.colors !== undefined) {\n if (!Array.isArray(sprite.colors) || sprite.colors.length === 0) {\n err(`${path}.colors`, 'must be a non-empty array of hex colours');\n } else {\n sprite.colors.forEach((c: unknown, ci: number) => color(c, `${path}.colors[${ci}]`, err));\n }\n }\n if (sprite.colorWeights !== undefined) {\n if (!Array.isArray(sprite.colors)) {\n err(`${path}.colorWeights`, 'requires colors to be set');\n } else if (!Array.isArray(sprite.colorWeights) || sprite.colorWeights.length !== sprite.colors.length) {\n err(`${path}.colorWeights`, 'must be an array the same length as colors');\n } else if (!sprite.colorWeights.every((v: unknown) => isNum(v) && v >= 0) || !sprite.colorWeights.some((v: unknown) => isNum(v) && v > 0)) {\n err(`${path}.colorWeights`, 'weights must be >= 0 with at least one > 0');\n }\n }\n}\n\n/** `role` on `text` / `textBlock`: a declaration of intent, one of two words. */\nfunction validateTextRole(sprite: Record<string, unknown>, path: string, err: (p: string, m: string) => void): void {\n if (sprite.role !== undefined && !TEXT_ROLES.has(sprite.role as string)) {\n err(`${path}.role`, \"must be 'read' | 'atmosphere'\");\n }\n}\n\nfunction validateCycle(sprite: Record<string, unknown>, path: string, err: (p: string, m: string) => void): void {\n if (sprite.cycle === undefined) return;\n if (!isObj(sprite.cycle)) return err(`${path}.cycle`, 'must be an object');\n if (!isNum(sprite.cycle.period) || sprite.cycle.period < LIMITS.minCyclePeriod) {\n err(`${path}.cycle.period`, `must be >= ${LIMITS.minCyclePeriod} ms (flash-safety floor)`);\n }\n}\n\nfunction validateMotion(motion: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn, spec?: unknown): void {\n if (!isObj(motion)) return err(path, 'must be an object');\n const isViewport = !isObj(spec) || (spec as Record<string, unknown>).units !== 'px';\n const refVp = isObj(spec) && isNum((spec as Record<string, unknown>).referenceViewport) ? (spec as Record<string, unknown>).referenceViewport as number : LIMITS.referenceViewport;\n const speedCap = isViewport ? LIMITS.maxSpeed / refVp : LIMITS.maxSpeed;\n const speedOk = (v: unknown, p: string): void => {\n if (!isRange(v)) err(p, 'must be a [min,max] range');\n else if (v[0] < 0) err(p, 'speed lower bound must be >= 0');\n else if (v[1] > speedCap) err(p, `speed exceeds cap ${isViewport ? speedCap.toFixed(2) + ' viewport-units/sec' : LIMITS.maxSpeed + ' px/sec'}`);\n };\n\n let knownSet: Set<string>;\n if (motion.type === 'drift') {\n knownSet = KNOWN_DRIFT;\n speedOk(motion.speed, `${path}.speed`);\n if (motion.angle !== undefined && !isNum(motion.angle)) err(`${path}.angle`, 'must be a number (degrees)');\n if (motion.bidirectional !== undefined && typeof motion.bidirectional !== 'boolean') err(`${path}.bidirectional`, 'must be a boolean');\n if (motion.bob !== undefined && !isNum(motion.bob)) err(`${path}.bob`, 'must be a number');\n validateEase(motion.ease, `${path}.ease`, err, warn);\n if (isRange(motion.speed) && motion.speed[1] < 1 && !isViewport) {\n warn(`${path}.speed`, 'near-zero-speed', `max speed is ${motion.speed[1]} px/sec — entities will appear frozen. Typical range: 10–200 px/sec`);\n }\n } else if (motion.type === 'rise') {\n knownSet = KNOWN_RISE;\n speedOk(motion.speed, `${path}.speed`);\n if (motion.sway !== undefined && !isNum(motion.sway)) err(`${path}.sway`, 'must be a number');\n validateEase(motion.ease, `${path}.ease`, err, warn);\n if (isRange(motion.speed) && motion.speed[1] < 1 && !isViewport) {\n warn(`${path}.speed`, 'near-zero-speed', `max speed is ${motion.speed[1]} px/sec — entities will appear frozen. Typical range: 5–80 px/sec`);\n }\n } else if (motion.type === 'bounce') {\n knownSet = KNOWN_BOUNCE;\n speedOk(motion.speed, `${path}.speed`);\n if (isRange(motion.speed) && motion.speed[1] < 1 && !isViewport) {\n warn(`${path}.speed`, 'near-zero-speed', `max speed is ${motion.speed[1]} px/sec — entities will appear frozen. Typical range: 20–150 px/sec`);\n }\n } else if (motion.type === 'static') {\n knownSet = KNOWN_STATIC;\n } else if (motion.type === 'orbit') {\n knownSet = KNOWN_ORBIT;\n if (!isRange(motion.speed)) err(`${path}.speed`, 'must be a [min,max] range');\n else {\n if (Math.abs(motion.speed[0]) > LIMITS.maxOrbitSpeed || Math.abs(motion.speed[1]) > LIMITS.maxOrbitSpeed) err(`${path}.speed`, `orbit speed exceeds cap ${LIMITS.maxOrbitSpeed} deg/sec`);\n if (Math.max(Math.abs(motion.speed[0]), Math.abs(motion.speed[1])) < 1) {\n warn(`${path}.speed`, 'near-zero-speed', `orbit speed is near zero — entities will appear frozen. Typical range: 5–60 deg/sec`);\n }\n }\n if (!isRange(motion.radius) || motion.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n if (motion.center !== undefined) {\n if (!isObj(motion.center)) {\n err(`${path}.center`, 'must be {x, y} (0..1) or { layer: key }');\n } else if ('layer' in motion.center) {\n if (!isStr(motion.center.layer) || motion.center.layer.trim() === '') {\n err(`${path}.center.layer`, 'must be a non-empty layer key');\n } else if (isObj(spec) && Array.isArray((spec as Record<string, unknown>).layers)) {\n // Scene-graph lite: parent must exist, be a single entity, and not itself\n // orbit a layer (strictly one level deep — keeps positionAt analytic).\n const layers = (spec as { layers: unknown[] }).layers;\n const parent = layers.find((l) => isObj(l) && l.key === (motion.center as { layer: string }).layer) as Record<string, unknown> | undefined;\n if (!parent) {\n err(`${path}.center.layer`, `no layer with key '${motion.center.layer}'`);\n } else {\n if (parent.count !== 1) err(`${path}.center.layer`, 'parent layer must have count: 1');\n const pm = parent.motion;\n if (isObj(pm) && pm.type === 'orbit' && isObj(pm.center) && 'layer' in pm.center) {\n err(`${path}.center.layer`, 'parent may not itself orbit a layer (one level deep only)');\n }\n }\n }\n } else if (!isNum(motion.center.x) || !isNum(motion.center.y)) {\n err(`${path}.center`, 'must be {x, y} with numbers 0..1');\n } else {\n if (motion.center.x < 0 || motion.center.x > 1) err(`${path}.center.x`, 'must be 0..1');\n if (motion.center.y < 0 || motion.center.y > 1) err(`${path}.center.y`, 'must be 0..1');\n }\n }\n } else if (motion.type === 'wander') {\n knownSet = KNOWN_WANDER;\n validateEase(motion.ease, `${path}.ease`, err, warn);\n speedOk(motion.speed, `${path}.speed`);\n if (motion.angle !== undefined && !isNum(motion.angle)) err(`${path}.angle`, 'must be a number (degrees)');\n const meanderCap = isViewport ? LIMITS.maxMeander / refVp : LIMITS.maxMeander;\n if (motion.meander !== undefined && (!isNum(motion.meander) || motion.meander <= 0 || motion.meander > meanderCap)) {\n err(`${path}.meander`, `must be > 0 and <= ${isViewport ? meanderCap.toFixed(3) + ' viewport-units' : LIMITS.maxMeander + ' px'}`);\n }\n if (motion.coherence !== undefined && (!isNum(motion.coherence) || motion.coherence < 0 || motion.coherence > 1)) {\n err(`${path}.coherence`, 'must be 0..1');\n }\n } else if (motion.type === 'warp') {\n knownSet = KNOWN_WARP;\n if (!isRange(motion.speed) || motion.speed[0] < 0) err(`${path}.speed`, 'must be a [min,max] range >= 0 (depth-units/sec)');\n else if (motion.speed[1] > LIMITS.maxWarpSpeed) err(`${path}.speed`, `warp speed exceeds cap ${LIMITS.maxWarpSpeed} depth-units/sec`);\n if (motion.center !== undefined) {\n if (!isObj(motion.center) || !isNum(motion.center.x) || !isNum(motion.center.y)) {\n err(`${path}.center`, 'must be {x, y} with numbers 0..1');\n } else {\n if (motion.center.x < 0 || motion.center.x > 1) err(`${path}.center.x`, 'must be 0..1');\n if (motion.center.y < 0 || motion.center.y > 1) err(`${path}.center.y`, 'must be 0..1');\n }\n }\n } else if (motion.type === 'path') {\n knownSet = KNOWN_PATH;\n if (!Array.isArray(motion.points) || motion.points.length < LIMITS.minPathPoints || motion.points.length > LIMITS.maxPathPoints) {\n err(`${path}.points`, `must be an array of ${LIMITS.minPathPoints}..${LIMITS.maxPathPoints} points`);\n } else {\n motion.points.forEach((p: unknown, pi: number) => {\n if (!isObj(p) || !isNum(p.x) || !isNum(p.y) || p.x < 0 || p.x > 1 || p.y < 0 || p.y > 1) {\n err(`${path}.points[${pi}]`, 'must be {x, y} with numbers 0..1');\n }\n });\n }\n if (!isNum(motion.duration) || motion.duration < LIMITS.minPathDuration) {\n err(`${path}.duration`, `must be >= ${LIMITS.minPathDuration} ms`);\n }\n if (motion.curve !== undefined && motion.curve !== 'linear' && motion.curve !== 'smooth') {\n err(`${path}.curve`, \"must be 'linear' | 'smooth'\");\n }\n if (motion.closed !== undefined && typeof motion.closed !== 'boolean') err(`${path}.closed`, 'must be a boolean');\n const scatterCap = isViewport ? LIMITS.maxMeander / refVp : LIMITS.maxMeander;\n if (motion.scatter !== undefined && (!isNum(motion.scatter) || motion.scatter <= 0 || motion.scatter > scatterCap)) {\n err(`${path}.scatter`, `must be > 0 and <= ${isViewport ? scatterCap.toFixed(3) + ' viewport-units' : LIMITS.maxMeander + ' px'}`);\n }\n } else {\n err(`${path}.type`, 'must be drift | rise | bounce | static | orbit | wander | warp | path');\n return;\n }\n\n for (const k of unknownKeys(motion, knownSet)) {\n warn(`${path}.${k}`, 'unknown-property', `unknown motion property '${k}' — will be ignored`);\n }\n}\n\n/** `points` for polygon/stroke: 2..24 (or 3..24) unit pairs inside the −1..1 box. */\nfunction validateShapePoints(points: unknown, path: string, min: number, err: (p: string, m: string) => void): void {\n if (!Array.isArray(points) || points.length < min || points.length > LIMITS.maxShapePoints) {\n return err(path, `must be ${min}..${LIMITS.maxShapePoints} [x, y] pairs in unit coordinates (-1..1)`);\n }\n for (let i = 0; i < points.length; i++) {\n const pt: unknown = points[i]; // by index, so a sparse array's holes are rejected too\n if (!Array.isArray(pt) || pt.length !== 2 || !isNum(pt[0]) || !isNum(pt[1]) || Math.abs(pt[0]) > 1 || Math.abs(pt[1]) > 1) {\n err(`${path}[${i}]`, 'must be an [x, y] pair with each coordinate in -1..1');\n }\n }\n}\n\nfunction validateEase(ease: unknown, path: string, err: (p: string, m: string) => void, warn: WarnFn): void {\n if (ease === undefined) return;\n if (!isObj(ease)) return err(path, \"must be an object { type: 'settle' | 'buoyant', tau }\");\n if (ease.type !== 'settle' && ease.type !== 'buoyant') err(`${path}.type`, \"must be 'settle' | 'buoyant'\");\n if (!isNum(ease.tau) || ease.tau < LIMITS.minEaseTau || ease.tau > LIMITS.maxEaseTau) {\n err(`${path}.tau`, `must be ${LIMITS.minEaseTau}..${LIMITS.maxEaseTau} ms`);\n }\n for (const k of unknownKeys(ease, new Set(['type', 'tau']))) {\n warn(`${path}.${k}`, 'unknown-property', `unknown ease property '${k}' — will be ignored`);\n }\n}\n\n/** Narrowing helper: validate + cast. Throws with a joined message when invalid. */\nexport function assertValidSpec(spec: unknown): SaverSpec {\n const r = validateSpec(spec);\n if (!r.valid) {\n throw new Error(`invalid saver spec:\\n${r.errors.map((e) => ` ${e.path || '<root>'}: ${e.message}`).join('\\n')}`);\n }\n return spec as SaverSpec;\n}\n\n/**\n * Validate a sequence envelope. Each segment's `scene` goes through `validateSpec`;\n * sequence-level rules (segment count, duration floors, key uniqueness, transition\n * bounds) are checked here.\n */\nexport function validateSequence(seq: unknown): ValidationResult {\n // Normalize each segment's scene (F3: colors-without-color auto-default)\n if (isObj(seq) && Array.isArray(seq.segments)) {\n for (const seg of seq.segments) {\n if (isObj(seg) && isObj((seg as Record<string, unknown>).scene)) {\n normalizeColors((seg as Record<string, unknown>).scene);\n }\n }\n }\n if (isObj(seq) && isObj(seq.bed)) normalizeColors(seq.bed);\n const errors: SpecError[] = [];\n const warnings: SpecWarning[] = [];\n const err = (path: string, message: string): void => void errors.push({ path, message });\n\n if (!isObj(seq)) return { valid: false, errors: [{ path: '', message: 'sequence must be an object' }], warnings: [] };\n\n if (seq.format !== 'idle-sequence') err('format', \"must be 'idle-sequence'\");\n if (seq.schemaVersion !== SCHEMA_VERSION) err('schemaVersion', `must be ${SCHEMA_VERSION}`);\n if (!isStr(seq.id) || seq.id.trim() === '') err('id', 'must be a non-empty string');\n if (!isStr(seq.label) || seq.label.trim() === '') err('label', 'must be a non-empty string');\n if (seq.seed !== undefined && !isNum(seq.seed)) err('seed', 'must be a number');\n if (typeof seq.loop !== 'boolean') err('loop', 'must be a boolean');\n if (seq.sync !== undefined && seq.sync !== 'mount' && seq.sync !== 'epoch') err('sync', \"must be 'mount' | 'epoch'\");\n\n if (!Array.isArray(seq.segments) || seq.segments.length === 0) {\n err('segments', 'must be a non-empty array');\n return { valid: false, errors, warnings };\n }\n\n if (seq.segments.length > LIMITS.maxSegments) {\n err('segments', `at most ${LIMITS.maxSegments} segments`);\n }\n\n const keys = new Set<string>();\n let hasDurationless = false;\n\n for (let i = 0; i < seq.segments.length; i++) {\n const s = seq.segments[i];\n const p = `segments[${i}]`;\n if (!isObj(s)) { err(p, 'must be an object'); continue; }\n\n if (!isStr(s.key) || s.key.trim() === '') {\n err(`${p}.key`, 'must be a non-empty string');\n } else if (keys.has(s.key as string)) {\n err(`${p}.key`, `duplicate key '${s.key}'`);\n } else {\n keys.add(s.key as string);\n }\n\n if (s.duration !== undefined) {\n if (hasDurationless) {\n err(`${p}.duration`, 'a segment after a durationless segment may not have a duration');\n }\n if (!isNum(s.duration) || s.duration < LIMITS.minSegmentDuration) {\n err(`${p}.duration`, `must be >= ${LIMITS.minSegmentDuration} ms`);\n }\n } else {\n if (i < seq.segments.length - 1) {\n err(`${p}.duration`, 'only the final segment may omit duration');\n }\n hasDurationless = true;\n }\n\n if (s.advance !== undefined && !['auto', 'input', 'either'].includes(s.advance as string)) {\n err(`${p}.advance`, \"must be 'auto' | 'input' | 'either'\");\n }\n\n if (s.transition !== undefined) {\n if (!isObj(s.transition)) {\n err(`${p}.transition`, 'must be an object');\n } else if (s.transition.type === 'morph' || s.transition.type === 'fade') {\n if (!isNum(s.transition.dur) || s.transition.dur < LIMITS.minTransitionDur || s.transition.dur > LIMITS.maxTransitionDur) {\n err(`${p}.transition.dur`, `must be a number between ${LIMITS.minTransitionDur} and ${LIMITS.maxTransitionDur}`);\n }\n } else if (s.transition.type !== 'cut') {\n err(`${p}.transition.type`, \"must be 'cut', 'morph' or 'fade'\");\n }\n if (isObj(s.transition) && s.transition.text !== undefined) {\n if (s.transition.type !== 'morph') {\n err(`${p}.transition.text`, 'is a morph option (fade already cross-fades whole frames; cut has no window)');\n } else if (s.transition.text !== 'step' && s.transition.text !== 'crossfade') {\n err(`${p}.transition.text`, \"must be 'step' | 'crossfade'\");\n }\n }\n }\n\n if (isObj(s.scene)) {\n const sceneResult = validateSpec(s.scene);\n for (const e of sceneResult.errors) errors.push({ path: `${p}.scene.${e.path}`, message: e.message });\n if (sceneResult.warnings) {\n for (const w of sceneResult.warnings) warnings.push({ path: `${p}.scene.${w.path}`, code: w.code, message: w.message });\n }\n } else {\n err(`${p}.scene`, 'must be a valid SaverSpec object');\n }\n }\n\n if (seq.loop === true && hasDurationless) {\n err('loop', 'loop: true requires all segments to have a duration');\n }\n\n // The bed: a full SaverSpec, live alongside whichever segment is up.\n if (seq.bed !== undefined) {\n if (!isObj(seq.bed)) {\n err('bed', 'must be a SaverSpec object');\n } else {\n const bedResult = validateSpec(seq.bed);\n for (const e of bedResult.errors) errors.push({ path: `bed.${e.path}`, message: e.message });\n for (const w of bedResult.warnings ?? []) warnings.push({ path: `bed.${w.path}`, code: w.code, message: w.message });\n if (bedResult.valid) {\n const entityTotal = (spec: unknown): number =>\n isObj(spec) && Array.isArray(spec.layers)\n ? spec.layers.reduce<number>((n, l) => n + (isObj(l) && isNum(l.count) ? l.count : 0), 0)\n : 0;\n const bedTotal = entityTotal(seq.bed);\n const largest = seq.segments.reduce<number>((m, s) => Math.max(m, isObj(s) ? entityTotal(s.scene) : 0), 0);\n if (bedTotal + largest > LIMITS.maxTotal) {\n err('bed', `bed entities ${bedTotal} + largest segment ${largest} = ${bedTotal + largest} exceeds cap ${LIMITS.maxTotal} (the two are live at once)`);\n }\n // The bed owns the ground: a segment background is never painted over it.\n seq.segments.forEach((s, i) => {\n if (isObj(s) && isObj(s.scene) && s.scene.background !== undefined) {\n warnings.push({\n path: `segments[${i}].scene.background`,\n code: 'bed-hides-segment-background',\n message: `segment ${i} declares a background but the sequence has a bed — segments render transparently over the bed, so this background is never painted`,\n });\n }\n });\n }\n }\n }\n\n // Warn when morph is requested but signatures differ (will fall back to cut)\n if (errors.length === 0 && Array.isArray(seq.segments)) {\n for (let i = 0; i < seq.segments.length; i++) {\n const s = seq.segments[i];\n if (!isObj(s) || !isObj(s.transition) || s.transition.type !== 'morph') continue;\n const next = seq.segments[i + 1];\n if (!next || !isObj(next) || !isObj(s.scene) || !isObj(next.scene)) continue;\n const sigA = structuralSignature(s.scene as unknown as SaverSpec);\n const sigB = structuralSignature((next as Record<string, unknown>).scene as unknown as SaverSpec);\n if (sigA !== sigB) {\n warnings.push({\n path: `segments[${i}].transition`,\n code: 'morph-structural-mismatch',\n message: `segments ${i}→${i + 1} differ structurally: morph will fall back to cut`,\n });\n } else if (morphNothingMorphable(s.scene as unknown as SaverSpec, (next as Record<string, unknown>).scene as unknown as SaverSpec, { textCrossfade: s.transition.text === 'crossfade' })) {\n // Structural twins whose only differences are values lerpSpec steps\n // (strings — textBlock.text above all). The morph runs, but every\n // frame of it shows segment i+1: it reads as a cut. A warning, never\n // an error, so every stored sequence stays valid.\n warnings.push({\n path: `segments[${i}].transition`,\n code: 'morph-nothing-morphable',\n message: `segments ${i}→${i + 1} differ only in values morph cannot interpolate (strings such as textBlock.text step on the first frame): the morph will look like a cut — fade text via colour or reveal.progress`,\n });\n }\n }\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\nexport function assertValidSequence(seq: unknown): IdleSequence {\n const r = validateSequence(seq);\n if (!r.valid) {\n throw new Error(`invalid sequence:\\n${r.errors.map((e) => ` ${e.path || '<root>'}: ${e.message}`).join('\\n')}`);\n }\n return seq as IdleSequence;\n}\n","/**\n * Shape glyph geometry — pure, renderer-free, shared by the compiler (what to\n * stroke/fill), perception (how much ink that is) and advise. Everything is\n * computed from the sprite spec + the entity's seeded size, so the canvas and\n * the analytic model agree by construction.\n *\n * Unit coordinates: `polygon.points` and `stroke.points` live in a −1..1 box\n * that is scaled by the entity's half-size (circumradius for polygons, half of\n * `length` for strokes), so the seeded size range is the glyph's bounding\n * diameter — the same rule `circle.radius` / `streak.length` already follow.\n */\nimport type { SpriteSpec } from './types';\n\nexport type ShapedSprite = Extract<SpriteSpec, { kind: 'circle' | 'ring' | 'streak' | 'rect' | 'polygon' | 'stroke' | 'bar' }>;\nexport type BarSprite = Extract<SpriteSpec, { kind: 'bar' }>;\nexport type PolygonSprite = Extract<SpriteSpec, { kind: 'polygon' }>;\nexport type StrokeSprite = Extract<SpriteSpec, { kind: 'stroke' }>;\n\n/** Every sprite that paints with `color` / `colors[]` (as opposed to glyphs). */\nexport function isShapedSprite(s: SpriteSpec): s is ShapedSprite {\n return s.kind === 'circle' || s.kind === 'ring' || s.kind === 'streak' || s.kind === 'rect' || s.kind === 'polygon' || s.kind === 'stroke' || s.kind === 'bar';\n}\n\n/** 0..1 fill of bar `index`: `values[i] / max`, `max` defaulting to the largest value. Read at paint time so steered values glide. */\nexport function barFraction(s: BarSprite, index: number): number {\n const n = s.values.length;\n if (n === 0) return 0;\n const v = s.values[((index % n) + n) % n] ?? 0;\n const max = s.max ?? s.values.reduce((m, x) => Math.max(m, x), 0);\n if (!(max > 0)) return 0;\n return Math.max(0, Math.min(1, v / max));\n}\n\n/** Box of a bar `len` long and `thick` thick growing from (0,0) toward `direction`: centre + half extents, px. */\nexport function barBox(direction: NonNullable<BarSprite['direction']>, len: number, thick: number): { cx: number; cy: number; halfX: number; halfY: number } {\n switch (direction) {\n case 'left': return { cx: -len / 2, cy: 0, halfX: len / 2, halfY: thick / 2 };\n case 'up': return { cx: 0, cy: -len / 2, halfX: thick / 2, halfY: len / 2 };\n case 'down': return { cx: 0, cy: len / 2, halfX: thick / 2, halfY: len / 2 };\n default: return { cx: len / 2, cy: 0, halfX: len / 2, halfY: thick / 2 };\n }\n}\n\nexport const DEFAULT_POLYGON_SIDES = 6;\n/** Minimum samples along a stroke path; grows with the control-point count (6 per segment). */\nexport const STROKE_SAMPLES = 24;\n\n/** Polygon vertices centred on (0,0), unrotated, circumradius `radius` px. Regular n-gons point up. */\nexport function polygonPoints(s: PolygonSprite, radius: number): Array<{ x: number; y: number }> {\n if (s.points && s.points.length >= 3) {\n return s.points.map(([x, y]) => ({ x: x * radius, y: y * radius }));\n }\n const n = Math.max(3, Math.round(s.sides ?? DEFAULT_POLYGON_SIDES));\n const out: Array<{ x: number; y: number }> = [];\n for (let k = 0; k < n; k++) {\n const a = -Math.PI / 2 + (2 * Math.PI * k) / n;\n out.push({ x: Math.cos(a) * radius, y: Math.sin(a) * radius });\n }\n return out;\n}\n\n/**\n * Signed-area magnitude of a polygon (shoelace), px². Exact for simple\n * polygons; a self-intersecting outline (a bow-tie) has lobes of opposite\n * winding that cancel here while the canvas's nonzero fill paints both, so\n * perception under-reports such glyphs. Author facets as simple polygons.\n */\nexport function polygonArea(pts: Array<{ x: number; y: number }>): number {\n let a = 0;\n for (let i = 0; i < pts.length; i++) {\n const p = pts[i]!;\n const q = pts[(i + 1) % pts.length]!;\n a += p.x * q.y - q.x * p.y;\n }\n return Math.abs(a) / 2;\n}\n\n/** Fraction of the circumscribed disc a polygon fills — the perception weight of a polygon splat. */\nexport function polygonFill(s: PolygonSprite, radius: number): number {\n if (radius <= 0) return 0;\n const disc = Math.PI * radius * radius;\n return Math.min(1, polygonArea(polygonPoints(s, radius)) / disc);\n}\n\nfunction catmullRom(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const u2 = u * u;\n const u3 = u2 * u;\n return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);\n}\n\n/**\n * The stroke's path, sampled: `n` points (default STROKE_SAMPLES) centred on\n * (0,0) and scaled so the unit box spans `halfSize` px each way. `curve:\n * 'smooth'` (default) is an open Catmull-Rom through the control points with\n * clamped ends; `'linear'` samples the polyline. Two control points give a\n * straight segment either way.\n */\nexport function strokeSamples(s: StrokeSprite, halfSize: number, n?: number): Array<{ x: number; y: number }> {\n const pts = s.points.map(([x, y]) => ({ x: x * halfSize, y: y * halfSize }));\n const m = pts.length;\n if (m < 2) return pts;\n const smooth = s.curve !== 'linear' && m >= 3;\n const segs = m - 1;\n // Enough samples that every spline segment gets interior points — a\n // 24-point stroke must not collapse to its control polyline.\n n = n ?? Math.max(STROKE_SAMPLES, segs * 6 + 1);\n const at = (k: number): { x: number; y: number } => pts[Math.max(0, Math.min(m - 1, k))]!;\n const out: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < n; i++) {\n const u = (i / (n - 1)) * segs;\n const seg = Math.min(segs - 1, Math.floor(u));\n const local = u - seg;\n const p1 = at(seg);\n const p2 = at(seg + 1);\n if (!smooth) {\n out.push({ x: p1.x + (p2.x - p1.x) * local, y: p1.y + (p2.y - p1.y) * local });\n } else {\n const p0 = at(seg - 1);\n const p3 = at(seg + 2);\n out.push({ x: catmullRom(p0.x, p1.x, p2.x, p3.x, local), y: catmullRom(p0.y, p1.y, p2.y, p3.y, local) });\n }\n }\n return out;\n}\n\n/** Total length of a sampled path, px. */\nexport function pathLength(pts: Array<{ x: number; y: number }>): number {\n let l = 0;\n for (let i = 1; i < pts.length; i++) {\n const dx = pts[i]!.x - pts[i - 1]!.x;\n const dy = pts[i]!.y - pts[i - 1]!.y;\n l += Math.sqrt(dx * dx + dy * dy);\n }\n return l;\n}\n\n/**\n * Taper profile along a stroke, 0..1 of the way along: a brush mark that\n * thins to (almost) nothing at both ends. Floored so a stroke never vanishes\n * mid-mark on a coarse display.\n */\nexport function strokeTaper(u: number): number {\n return Math.max(0.15, Math.sin(Math.PI * Math.max(0, Math.min(1, u))));\n}\n\n/** Stroke width in px for a sprite, with the same default rule as `ring`/`streak`. */\nexport function strokeWidthPx(s: { width?: number }, scale: number): number {\n return Math.max(0.5, (s.width ?? (scale === 1 ? 2 : 0.002)) * scale);\n}\n\n/**\n * Per-step alphas for a feathered rect drawn as `steps` nested fills from the\n * outside in, so the COMPOSITED alpha ramps linearly from 1/steps at the\n * outer edge to 1 at the core. Under source-over each fill sees the ones\n * before it, so step k needs 1/(steps−k+1); under additive blends the fills\n * simply sum, so each contributes 1/steps.\n */\nexport function featherAlphas(steps: number, additive: boolean): number[] {\n const out: number[] = [];\n for (let k = 1; k <= steps; k++) out.push(additive ? 1 / steps : 1 / (steps - k + 1));\n return out;\n}\nexport const FEATHER_STEPS = 6;\n","import type { Rng } from '@idle-screens/core';\nimport type { CycleSpec, LayerSpec, SpriteSpec, TextBlockAnchor } from './types';\nimport { LIMITS } from './types';\nimport { isShapedSprite } from './shapes';\n\n/** Near plane for warp motion. z lives in [WARP_NEAR, 1]; screen scale is 1/z. */\nexport const WARP_NEAR = 0.08;\n/** Cap on the 1/z size multiplier so near stars don't blow out. */\nexport const WARP_MAX_SCALE = 8;\n\n/** One axis-pair of seeded harmonic octaves for wander motion (amps px, freqs rad/ms). */\nexport interface WanderOsc {\n ax: number[];\n fx: number[];\n phx: number[];\n ay: number[];\n fy: number[];\n phy: number[];\n}\n\n/** A seeded entity: initial state + resolved velocity. `positionAt` is a pure function\n * of this + time, so the rAF loop and renderFrame(t) produce identical results.\n * IMPORTANT (determinism/compat): fields for newer features are OPTIONAL and only\n * set when the feature is declared, so older specs snapshot byte-identically. */\nexport interface Entity {\n x0: number;\n y0: number;\n size: number;\n spriteIndex: number;\n phase: number;\n vx: number; // px/sec\n vy: number; // px/sec\n bob: number; // vertical bob / horizontal sway amplitude (px)\n motion: 'drift' | 'rise' | 'bounce' | 'static' | 'orbit' | 'wander' | 'warp' | 'path';\n headingLeft: boolean;\n alpha: number; // resolved base opacity (default 1)\n pulseAmp: number; // opacity breathing amplitude (0 = none)\n pulsePeriod: number; // ms\n pulsePhase: number;\n spinSpeed: number; // degrees/sec (0 = no rotation)\n spinPhase: number; // seeded starting angle (radians)\n growAmp: number; // size breathing amplitude as fraction (0 = none)\n growPeriod: number; // ms\n growPhase: number;\n orbitR: number; // orbit radius (px, 0 = not orbiting)\n orbitCx: number; // orbit center x (px)\n orbitCy: number; // orbit center y (px)\n colorIndex: number; // index into sprite colors[] (-1 = use sprite.color)\n cyclePeriod: number; // ms (0 = no cycling)\n /** Rect sprite second dimension (height px), or bar thickness. Only set for rect / bar sprites. */\n size2?: number;\n /** Reading-order index into `bar.values`. Only set for bar sprites. */\n barIndex?: number;\n /** Placed by a list/table layout: variants cycle from the ordered base index, in step. Only set for data layouts. */\n ordered?: true;\n /** Orbit parent layer key (motion.center = { layer }). Center resolved at render time. */\n orbitParent?: string;\n /** Present only when the layer explicitly disables edge wrapping. */\n wrapDisabled?: true;\n /** Harmonic drift params. Only set for wander motion. */\n wander?: { own: WanderOsc; shared: WanderOsc; coherence: number; margin: number };\n /** Depth-axis params. Only set for warp motion. */\n warp?: { ux: number; uy: number; z0: number; vz: number; cx: number; cy: number };\n /** Sparse-event window. Only set when `layer.emit` is declared. `phase` ms offset. */\n emit?: { every: number; life: number; phase: number; growFrom: number; growTo: number };\n /** Shared-clock time multiplier for pulse/grow/cycle. Only set when `layer.clock` is declared. */\n clockRate?: number;\n /** Shared cycle phase (radians). Only set when `layer.clock` is declared. */\n cyclePhase?: number;\n /** Velocity easing. Only set when the motion declares `ease`. */\n ease?: { type: 'settle' | 'buoyant'; tau: number };\n /** Spline params (pts in px, shared per layer). Only set for path motion. */\n path?: {\n pts: Array<{ x: number; y: number }>;\n duration: number;\n closed: boolean;\n smooth: boolean;\n phase: number; // 0..1 offset along the path\n offX: number; // per-entity scatter (px)\n offY: number;\n };\n}\n\nexport interface Placed {\n x: number;\n y: number;\n flip: boolean;\n}\n\nexport function spriteVariants(sprite: SpriteSpec): number {\n if (sprite.kind === 'emoji') return sprite.glyphs.length;\n if (sprite.kind === 'text') return sprite.strings.length;\n return 1;\n}\n\nconst OCT_AMP = [1, 0.5, 0.25];\nconst OCT_PERIOD: Array<[number, number]> = [\n [6000, 14000],\n [3000, 7000],\n [1500, 4000],\n];\n\n/** Draw one set of 3 harmonic octaves per axis (18 rng draws). `amp` in px. */\nfunction drawOsc(rng: Rng, amp: number): WanderOsc {\n const osc: WanderOsc = { ax: [], fx: [], phx: [], ay: [], fy: [], phy: [] };\n for (let i = 0; i < 3; i++) {\n osc.ax.push(amp * OCT_AMP[i]! * rng.range(0.6, 1.4));\n osc.fx.push((2 * Math.PI) / rng.range(OCT_PERIOD[i]![0], OCT_PERIOD[i]![1]));\n osc.phx.push(rng.range(0, Math.PI * 2));\n }\n for (let i = 0; i < 3; i++) {\n osc.ay.push(amp * OCT_AMP[i]! * rng.range(0.6, 1.4));\n osc.fy.push((2 * Math.PI) / rng.range(OCT_PERIOD[i]![0], OCT_PERIOD[i]![1]));\n osc.phy.push(rng.range(0, Math.PI * 2));\n }\n return osc;\n}\n\nconst GOLDEN = 0.6180339887498949;\n\n/**\n * Per-entity sparse-event parameters. NO rng draws: the scattered offset is a\n * fixed low-discrepancy (golden-ratio) sequence over the entity index, so\n * declaring `emit` never disturbs this layer's — or any later layer's —\n * seeded stream, and the same spec times its events identically under every\n * seed (event timing is composition, like a grid, not scatter). `jitter`\n * blends an even stagger (entity i at i/n of the period — a metronome) with\n * that scattered offset.\n */\nfunction emitParams(\n emit: NonNullable<LayerSpec['emit']>,\n i: number,\n n: number,\n): NonNullable<Entity['emit']> {\n const every = emit.every;\n const jitter = Math.max(0, Math.min(1, emit.jitter ?? 1));\n const scattered = (((i + 0.5) * GOLDEN) % 1) * every;\n const even = (i / Math.max(1, n)) * every;\n const phase = ((even * (1 - jitter) + scattered * jitter) % every + every) % every;\n return {\n every,\n life: Math.min(emit.life, every),\n phase,\n growFrom: emit.grow?.[0] ?? 1,\n growTo: emit.grow?.[1] ?? 1,\n };\n}\n\n/** Weighted index pick from a single uniform draw. Weights are validated positive. */\nfunction weightedIndex(u: number, weights: number[]): number {\n const total = weights.reduce((a, b) => a + b, 0);\n let acc = 0;\n for (let i = 0; i < weights.length; i++) {\n acc += weights[i]! / total;\n if (u < acc) return i;\n }\n return weights.length - 1;\n}\n\n/** Deterministically place a layer's entities using the seeded RNG (never Math.random).\n * `scale` multiplies every dimensional draw (default 1). Used for viewport units.\n * `countScale` multiplies entity count for density-aware scaling (default 1). */\nexport function buildEntities(layer: LayerSpec, rng: Rng, w: number, h: number, scale = 1, countScale = 1): Entity[] {\n // Grid layers are EXEMPT from count scaling. A grid is an exact lattice —\n // columns × rows, authored cell by cell — and scaling its count doesn't thin\n // it like a scatter field, it TRUNCATES it row-major: the last cells simply\n // never spawn. Found live (Entablature, 2026-08-14): on a viewport at\n // countScale ≈ 0.67, an 18-column single-row grid rendered 12 cells and died\n // at two-thirds width, while the analytic perception path (countScale 1)\n // showed it full-width — a renderer-vs-perception split that burned four\n // publishes to isolate. Upscaling is equally wrong: it invents phantom cells\n // beyond the authored lattice. Grid cost is already bounded by maxPerLayer.\n const effectiveCount = countScale === 1 || layer.layout !== undefined\n ? layer.count\n : Math.max(1, Math.min(\n Math.round(layer.count * countScale),\n layer.links ? LIMITS.maxLinkLayerCount : LIMITS.maxPerLayer,\n ));\n // Defaults are authored as their 1080p-equivalent viewport fractions. Using\n // the legacy px defaults directly would multiply 20..40 by the viewport.\n const defaultSize = scale === 1\n ? [20, 40] as const\n : [20 / LIMITS.referenceViewport, 40 / LIMITS.referenceViewport] as const;\n const [smin, smax] = layer.size ?? defaultSize;\n const variants = spriteVariants(layer.sprite);\n const sprite = layer.sprite;\n const spriteColors = isShapedSprite(sprite) ? sprite.colors : undefined;\n const colorWeights = isShapedSprite(sprite) ? sprite.colorWeights : undefined;\n const colorsLen = spriteColors?.length ?? 0;\n const cycle: CycleSpec | undefined = (sprite.kind === 'emoji' || sprite.kind === 'text') ? sprite.cycle : undefined;\n\n // Layer-level draws for new motion types happen BEFORE the entity loop, guarded by\n // the motion type so pre-existing specs keep bit-identical entity streams.\n const mSpec = layer.motion;\n let sharedOsc: WanderOsc | null = null;\n let meanderPx = 0;\n if (mSpec.type === 'wander') {\n meanderPx = (mSpec.meander ?? (scale === 1 ? 60 : 0.05)) * scale;\n sharedOsc = drawOsc(rng, meanderPx);\n }\n let pathPts: Array<{ x: number; y: number }> | null = null;\n if (mSpec.type === 'path') {\n pathPts = mSpec.points.map((p) => ({ x: p.x * w, y: p.y * h }));\n }\n const ease = (mSpec.type === 'drift' || mSpec.type === 'rise' || mSpec.type === 'wander') ? mSpec.ease : undefined;\n const clockPhase = layer.clock ? ((layer.clock.phase ?? 0) % 1) * Math.PI * 2 : 0;\n\n // Grid layout geometry (pure — no draws).\n const layout = layer.layout;\n // Data layouts (list / table): reading order from an anchor, no scatter.\n const ordered = layout?.type === 'list' || layout?.type === 'table';\n let gapX = 0;\n let gapY = 0;\n let listX0 = 0;\n let listY0 = 0;\n let listCols = 1;\n if (layout?.type === 'list' || layout?.type === 'table') {\n const dflt = scale === 1 ? LIMITS.defaultListGapPx : LIMITS.defaultListGap;\n const g = layout.gap ?? dflt;\n gapX = (typeof g === 'number' ? g : g.x ?? dflt) * scale;\n gapY = (typeof g === 'number' ? g : g.y ?? dflt) * scale;\n listCols = layout.type === 'list' ? 1 : Math.max(1, Math.round(layout.columns));\n const rows = Math.max(1, Math.ceil(effectiveCount / listCols));\n if (layer.position) {\n listX0 = layer.position.x * w;\n listY0 = layer.position.y * h;\n } else {\n const [rx0, rx1] = layer.region?.x ?? [0, 1];\n const [ry0, ry1] = layer.region?.y ?? [0, 1];\n listX0 = ((rx0 + rx1) / 2) * w - ((listCols - 1) * gapX) / 2;\n listY0 = ((ry0 + ry1) / 2) * h - ((rows - 1) * gapY) / 2;\n }\n }\n let gridCols = 0;\n let cellW = 0;\n let cellH = 0;\n let gridX0 = 0;\n let gridY0 = 0;\n if (layout?.type === 'grid') {\n const [rx0, rx1] = layer.region?.x ?? [0, 1];\n const [ry0, ry1] = layer.region?.y ?? [0, 1];\n const gw = Math.max(1, (rx1 - rx0) * w);\n const gh = Math.max(1, (ry1 - ry0) * h);\n gridCols = Math.min(\n layout.columns ?? Math.max(1, Math.round(Math.sqrt(effectiveCount * (gw / gh)))),\n LIMITS.maxGridColumns,\n );\n const gridRows = Math.max(1, Math.ceil(effectiveCount / gridCols));\n cellW = gw / gridCols;\n cellH = gh / gridRows;\n gridX0 = rx0 * w;\n gridY0 = ry0 * h;\n }\n\n const out: Entity[] = [];\n for (let i = 0; i < effectiveCount; i++) {\n const size =\n sprite.kind === 'textBlock'\n ? sprite.fontSize * scale\n : sprite.kind === 'circle' || sprite.kind === 'ring' || sprite.kind === 'polygon'\n ? rng.range(sprite.radius[0], sprite.radius[1]) * 2 * scale\n : sprite.kind === 'streak' || sprite.kind === 'stroke'\n ? rng.range(sprite.length[0], sprite.length[1]) * scale\n : sprite.kind === 'rect'\n ? rng.range(sprite.width[0], sprite.width[1]) * scale\n : sprite.kind === 'bar'\n ? sprite.length * scale\n : rng.range(smin, smax) * scale;\n // Guarded extra draw: only rect sprites with an aspect range consume it.\n const size2 = sprite.kind === 'rect'\n ? size * (sprite.aspect ? rng.range(sprite.aspect[0], sprite.aspect[1]) : 1)\n : sprite.kind === 'bar'\n ? sprite.thickness * scale\n : undefined;\n\n let vx = 0;\n let vy = 0;\n let bob = 0;\n let motion: Entity['motion'] = 'drift';\n let warpParams: Entity['warp'];\n let pathPhase = 0;\n let pathOffX = 0;\n let pathOffY = 0;\n const m = layer.motion;\n if (m.type === 'static') {\n motion = 'static';\n } else if (m.type === 'drift') {\n const s = rng.range(m.speed[0], m.speed[1]) * scale;\n let angle = ((m.angle ?? 0) * Math.PI) / 180;\n if (m.bidirectional && rng.next() < 0.5) angle = Math.PI - angle;\n vx = s * Math.cos(angle);\n vy = s * Math.sin(angle);\n bob = (m.bob ?? 0) * scale;\n } else if (m.type === 'rise') {\n motion = 'rise';\n vy = -rng.range(m.speed[0], m.speed[1]) * scale; // upward\n bob = (m.sway ?? 0) * scale;\n } else if (m.type === 'bounce') {\n motion = 'bounce';\n const s = rng.range(m.speed[0], m.speed[1]) * scale;\n const a = rng.range(0, Math.PI * 2);\n vx = s * Math.cos(a);\n vy = s * Math.sin(a);\n } else if (m.type === 'orbit') {\n motion = 'orbit';\n vx = rng.range(m.speed[0], m.speed[1]); // angular speed in deg/sec, stored in vx (not scaled)\n } else if (m.type === 'wander') {\n motion = 'wander';\n const s = rng.range(m.speed[0], m.speed[1]) * scale;\n const heading = m.angle !== undefined ? (m.angle * Math.PI) / 180 : rng.range(0, Math.PI * 2);\n vx = s * Math.cos(heading);\n vy = s * Math.sin(heading);\n } else if (m.type === 'warp') {\n motion = 'warp';\n const vz = rng.range(m.speed[0], m.speed[1]); // depth-units/sec (not scaled)\n const theta = rng.range(0, Math.PI * 2);\n const r = rng.range(0.15, 1); // radial offset in the projection plane\n warpParams = {\n ux: Math.cos(theta) * r,\n uy: Math.sin(theta) * r,\n z0: rng.range(WARP_NEAR, 1),\n vz,\n cx: (m.center?.x ?? 0.5) * w,\n cy: (m.center?.y ?? 0.5) * h,\n };\n } else if (m.type === 'path') {\n motion = 'path';\n pathPhase = rng.next();\n if (m.scatter) {\n pathOffX = rng.range(-1, 1) * m.scatter * scale;\n pathOffY = rng.range(-1, 1) * m.scatter * scale;\n }\n }\n\n let x0: number;\n let y0: number;\n if (layer.position && layer.count === 1) {\n x0 = layer.position.x * w;\n y0 = layer.position.y * h;\n } else if (layout?.type === 'list' || layout?.type === 'table') {\n // Reading order from the anchor. Burn the two scatter draws so toggling a\n // data layout on or off leaves the rest of this layer's stream intact.\n rng.next();\n rng.next();\n x0 = listX0 + (i % listCols) * gapX;\n y0 = listY0 + Math.floor(i / listCols) * gapY;\n } else if (layout?.type === 'grid') {\n // Grid cells row-major; same 2-draw budget as scatter so toggling layout\n // shifts only THIS layer's stream (layout is structural — rebuild anyway).\n const col = i % gridCols;\n const row = Math.floor(i / gridCols);\n const j = layout.jitter ?? 0;\n const jx = typeof j === 'number' ? j : j.x ?? 0;\n const jy = typeof j === 'number' ? j : j.y ?? 0;\n x0 = gridX0 + (col + 0.5) * cellW + rng.range(-0.5, 0.5) * jx * cellW;\n y0 = gridY0 + (row + 0.5) * cellH + rng.range(-0.5, 0.5) * jy * cellH;\n } else {\n // Spawn window defaults to the full viewport. IMPORTANT (determinism/compat):\n // optional features must only consume EXTRA rng draws when declared, so specs\n // written before a feature existed keep bit-identical entity streams.\n const [rx0, rx1] = layer.region?.x ?? [0, 1];\n const [ry0, ry1] = layer.region?.y ?? [0, 1];\n x0 = rng.range(rx0 * w, rx1 * w);\n y0 = rng.range(ry0 * h, ry1 * h);\n }\n\n const orbitParent = m.type === 'orbit' && m.center && 'layer' in m.center ? m.center.layer : undefined;\n\n out.push({\n x0,\n y0,\n size,\n // Data layouts read variants in order — strings[i] beside bar i. The\n // seeded draw is still consumed so a layout is placement only: toggling\n // list/table never disturbs the layer's alpha, pulse or spin stream.\n spriteIndex: variants > 1 ? (ordered ? (rng.int(0, variants - 1), i % variants) : rng.int(0, variants - 1)) : 0,\n phase: rng.range(0, Math.PI * 2),\n vx,\n vy,\n bob,\n motion,\n headingLeft: vx < 0,\n alpha: layer.alpha ? rng.range(layer.alpha[0], layer.alpha[1]) : 1,\n pulseAmp: layer.pulse?.amp ?? 0,\n pulsePeriod: layer.pulse?.period ?? 1000,\n pulsePhase: layer.pulse ? rng.range(0, Math.PI * 2) : 0,\n // New draws AFTER pulsePhase — guarded so existing specs keep identical streams.\n // Scalar spin: no draw here, one phase draw below (unchanged). Range spin\n // (new): one seeded speed draw here, then the phase draw — array form is new\n // so the extra draw can't perturb any existing spec's entity stream.\n spinSpeed:\n typeof layer.spin === 'number'\n ? (layer.spin * Math.PI) / 180 // deg/sec → rad/sec\n : Array.isArray(layer.spin)\n ? (rng.range(layer.spin[0], layer.spin[1]) * Math.PI) / 180\n : 0,\n spinPhase: layer.spin ? rng.range(0, Math.PI * 2) : 0,\n growAmp: layer.grow?.amp ?? 0,\n growPeriod: layer.grow?.period ?? 1000,\n growPhase: layer.grow ? rng.range(0, Math.PI * 2) : 0,\n orbitR: m.type === 'orbit' ? rng.range(m.radius[0], m.radius[1]) * scale : 0,\n orbitCx: m.type === 'orbit' && !orbitParent ? ((m.center as { x?: number } | undefined)?.x ?? 0.5) * w : 0,\n orbitCy: m.type === 'orbit' && !orbitParent ? ((m.center as { y?: number } | undefined)?.y ?? 0.5) * h : 0,\n // New draws AFTER orbit — guarded so existing specs keep identical streams.\n colorIndex: colorsLen > 0\n ? (colorWeights && colorWeights.length === colorsLen\n ? weightedIndex(rng.next(), colorWeights)\n : ordered\n ? (rng.int(0, colorsLen - 1), i % colorsLen) // data layouts: palette in reading order; draw burned for stream parity\n : rng.int(0, colorsLen - 1))\n : -1,\n cyclePeriod: cycle ? cycle.period : 0,\n // Optional feature fields last (guarded draws inside — wander draws 18 here).\n ...(size2 !== undefined ? { size2 } : {}),\n ...(sprite.kind === 'bar' ? { barIndex: i } : {}),\n ...(ordered ? { ordered: true as const } : {}),\n ...(orbitParent ? { orbitParent } : {}),\n ...(layer.wrap === false ? { wrapDisabled: true as const } : {}),\n ...(m.type === 'wander'\n ? {\n wander: {\n own: drawOsc(rng, meanderPx),\n shared: sharedOsc!,\n coherence: Math.max(0, Math.min(1, m.coherence ?? 0)),\n margin: meanderPx * (OCT_AMP[0]! + OCT_AMP[1]! + OCT_AMP[2]!) * 1.4,\n },\n }\n : {}),\n ...(warpParams ? { warp: warpParams } : {}),\n ...(m.type === 'path' && pathPts\n ? {\n path: {\n pts: pathPts,\n duration: m.duration,\n closed: m.closed !== false,\n smooth: m.curve !== 'linear',\n phase: pathPhase,\n offX: pathOffX,\n offY: pathOffY,\n },\n }\n : {}),\n // Time-structure fields (2026-09): ease draws nothing; emit's one draw\n // per entity happens in a pass AFTER this loop (see below).\n ...(ease ? { ease: { type: ease.type, tau: ease.tau } } : {}),\n });\n\n if (layer.clock) {\n // Phase-lock: the seeded pulse/grow phases were drawn above (stream\n // stays put); the shared phase replaces them here. Cycle gets its own\n // field — `phase` also drives bob/sway/orbit, which must stay per-entity.\n const ent = out[out.length - 1]!;\n ent.pulsePhase = clockPhase;\n ent.growPhase = clockPhase;\n ent.cyclePhase = clockPhase;\n ent.clockRate = layer.clock.rate ?? 1;\n }\n if (layer.pulse?.wave) {\n // Position-derived phase: sin(ωt + phase) becomes a traveling wave along\n // `angle`. Patched AFTER the push so the seeded pulsePhase draw stays in its\n // historical stream position (toggling wave must not shift other draws).\n // A clock's phase offsets the wave rather than flattening it.\n const wl = Math.max(1e-6, layer.pulse.wave.wavelength * scale);\n const ang = ((layer.pulse.wave.angle ?? 0) * Math.PI) / 180;\n out[out.length - 1]!.pulsePhase = clockPhase - ((x0 * Math.cos(ang) + y0 * Math.sin(ang)) / wl) * Math.PI * 2;\n }\n }\n if (layer.emit) {\n // Assigned after the loop and without any rng draw (see emitParams), so\n // toggling `emit` rearranges nothing — not this layer, not the ones after.\n for (let i = 0; i < out.length; i++) out[i]!.emit = emitParams(layer.emit, i, out.length);\n }\n return out;\n}\n\n/** Depth of a warp entity at time t: wraps from far (1) to near (WARP_NEAR). Pure. */\nfunction warpZ(e: Entity, t: number): number {\n const wp = e.warp!;\n return wrap(wp.z0 - wp.vz * (t / 1000), WARP_NEAR, 1);\n}\n\nfunction smoothstep(x: number): number {\n const c = x < 0 ? 0 : x > 1 ? 1 : x;\n return c * c * (3 - 2 * c);\n}\n\n/** Fraction of an emit window spent fading in; the rest fades out. */\nconst EMIT_ATTACK = 0.25;\n\n/**\n * Where entity `e` sits in its current emit window at time `t`: 0..1 across\n * the visible `life` ms, or null while dark (or when the layer has no `emit`).\n * Pure — the window index is `floor((t - phase) / every)`, no state.\n */\nexport function emitWindow(e: Entity, t: number): number | null {\n const em = e.emit;\n if (!em) return null;\n const local = (((t - em.phase) % em.every) + em.every) % em.every;\n return local < em.life ? local / em.life : null;\n}\n\n/** Alpha envelope across an emit window: fast smooth attack, slow smooth decay. */\nexport function emitEnvelope(u: number): number {\n if (u < 0 || u >= 1) return 0;\n return u < EMIT_ATTACK ? smoothstep(u / EMIT_ATTACK) : 1 - smoothstep((u - EMIT_ATTACK) / (1 - EMIT_ATTACK));\n}\n\n/** Scene time as the layer's clock sees it (pulse/grow/cycle only). */\nfunction clockTime(e: Entity, t: number): number {\n return e.clockRate ? t * e.clockRate : t;\n}\n\n/**\n * Seconds of travel at time `t` for the velocity-integral motions. Identity\n * without `ease`. `settle`: τ(1 − e^(−t/τ)) — decelerates to rest having\n * travelled speed·τ. `buoyant`: t − τ(1 − e^(−t/τ)) — from rest to terminal\n * speed. With `emit`, t is window-local so every event restarts the travel.\n */\nfunction motionSeconds(e: Entity, t: number): number {\n if (!e.ease) return t / 1000;\n let tl = t;\n if (e.emit) tl = (((t - e.emit.phase) % e.emit.every) + e.emit.every) % e.emit.every;\n const tau = e.ease.tau;\n const k = 1 - Math.exp(-tl / tau);\n return (e.ease.type === 'settle' ? tau * k : tl - tau * k) / 1000;\n}\n\n/** Analytic opacity of an entity at logical time `t` (ms). Pure, clamped to 0..1. */\nexport function alphaAt(e: Entity, t: number): number {\n let a = e.alpha;\n if (e.pulseAmp) a = e.alpha + e.pulseAmp * Math.sin((clockTime(e, t) * 2 * Math.PI) / e.pulsePeriod + e.pulsePhase);\n if (e.motion === 'warp') {\n // Fade in over the first 20% of depth after respawning at the far plane,\n // masking the wrap pop-in.\n const z = warpZ(e, t);\n a *= Math.max(0, Math.min(1, (1 - z) / 0.2));\n }\n if (e.emit) {\n const u = emitWindow(e, t);\n a = u === null ? 0 : a * emitEnvelope(u);\n }\n return a < 0 ? 0 : a > 1 ? 1 : a;\n}\n\n/** Analytic size multiplier at time `t` (ms). Pure, clamped to > 0. */\nexport function sizeAt(e: Entity, t: number): number {\n let s = e.size;\n if (e.growAmp) s = e.size * (1 + e.growAmp * Math.sin((clockTime(e, t) * 2 * Math.PI) / e.growPeriod + e.growPhase));\n if (e.motion === 'warp') s *= Math.min(1 / warpZ(e, t), WARP_MAX_SCALE);\n if (e.emit && (e.emit.growFrom !== 1 || e.emit.growTo !== 1)) {\n const u = emitWindow(e, t);\n if (u !== null) s *= e.emit.growFrom + (e.emit.growTo - e.emit.growFrom) * u;\n }\n return s > 0 ? s : 0.1;\n}\n\n/** Analytic rotation angle at time `t` (ms) in radians. Pure. */\nexport function rotationAt(e: Entity, t: number): number {\n if (!e.spinSpeed) return 0;\n return e.spinPhase + e.spinSpeed * (t / 1000);\n}\n\n/** Layer lifecycle alpha multiplier at time `t` (ms). Pure. 1 when `life` is unset. */\nexport function lifeAlphaAt(life: { enter?: number; exit?: number; fade?: number } | undefined, t: number): number {\n if (!life) return 1;\n const fade = life.fade ?? 1000;\n let a = 1;\n if (life.enter !== undefined) {\n if (t < life.enter) return 0;\n a = fade > 0 ? Math.min(1, (t - life.enter) / fade) : 1;\n }\n if (life.exit !== undefined && t >= life.exit) {\n a *= fade > 0 ? Math.max(0, 1 - (t - life.exit) / fade) : 0;\n }\n return a;\n}\n\nfunction wrap(v: number, min: number, max: number): number {\n const range = max - min;\n return ((((v - min) % range) + range) % range) + min;\n}\n\nfunction reflect(v: number, min: number, max: number): number {\n const range = max - min;\n if (range <= 0) return min;\n const period = 2 * range;\n const p = (((v - min) % period) + period) % period;\n return min + (p < range ? p : period - p);\n}\n\nfunction catmullRom(p0: number, p1: number, p2: number, p3: number, u: number): number {\n const u2 = u * u;\n const u3 = u2 * u;\n return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);\n}\n\nfunction pathPosition(e: Entity, t: number): { x: number; y: number } {\n const p = e.path!;\n const n = p.pts.length;\n let s = ((t / p.duration) + p.phase) % 1;\n if (s < 0) s += 1;\n if (!p.closed) {\n // Ping-pong so open paths reverse smoothly instead of teleporting.\n const pp = s * 2;\n s = pp < 1 ? pp : 2 - pp;\n }\n const segs = p.closed ? n : n - 1;\n const u = Math.min(s * segs, segs - 1e-9);\n const i = Math.floor(u);\n const local = u - i;\n const at = (k: number): { x: number; y: number } =>\n p.closed ? p.pts[((k % n) + n) % n]! : p.pts[Math.max(0, Math.min(n - 1, k))]!;\n const p1 = at(i);\n const p2 = at(i + 1);\n if (!p.smooth) {\n return {\n x: p1.x + (p2.x - p1.x) * local + p.offX,\n y: p1.y + (p2.y - p1.y) * local + p.offY,\n };\n }\n const p0 = at(i - 1);\n const p3 = at(i + 2);\n return {\n x: catmullRom(p0.x, p1.x, p2.x, p3.x, local) + p.offX,\n y: catmullRom(p0.y, p1.y, p2.y, p3.y, local) + p.offY,\n };\n}\n\n/** Analytic position of an entity at logical time `t` (ms). Pure & deterministic. */\nexport function positionAt(e: Entity, t: number, w: number, h: number): Placed {\n if (e.motion === 'static') return { x: e.x0, y: e.y0, flip: false };\n if (e.motion === 'orbit') {\n const angle = e.phase + (e.vx * Math.PI / 180) * (t / 1000);\n return {\n x: e.orbitCx + e.orbitR * Math.cos(angle),\n y: e.orbitCy + e.orbitR * Math.sin(angle),\n flip: false,\n };\n }\n if (e.motion === 'warp') {\n const wp = e.warp!;\n const persp = 1 / warpZ(e, t);\n const halfMin = Math.min(w, h) / 2;\n return {\n x: wp.cx + wp.ux * halfMin * persp,\n y: wp.cy + wp.uy * halfMin * persp,\n flip: false,\n };\n }\n if (e.motion === 'path') {\n const pos = pathPosition(e, t);\n return { x: pos.x, y: pos.y, flip: false };\n }\n const dt = motionSeconds(e, t);\n const m = e.size;\n if (e.motion === 'bounce') {\n return {\n x: reflect(e.x0 + e.vx * dt, m / 2, w - m / 2),\n y: reflect(e.y0 + e.vy * dt, m / 2, h - m / 2),\n flip: false,\n };\n }\n if (e.motion === 'rise') {\n const y = e.y0 + e.vy * dt;\n return {\n x: e.x0 + (e.bob ? e.bob * Math.sin(t / 700 + e.phase) : 0),\n y: e.wrapDisabled ? y : wrap(y, -m, h + m),\n flip: false,\n };\n }\n if (e.motion === 'wander') {\n const wp = e.wander!;\n const c = wp.coherence;\n let hx = 0;\n let hy = 0;\n for (let i = 0; i < 3; i++) {\n if (c < 1) {\n hx += (1 - c) * wp.own.ax[i]! * Math.sin(wp.own.fx[i]! * t + wp.own.phx[i]!);\n hy += (1 - c) * wp.own.ay[i]! * Math.sin(wp.own.fy[i]! * t + wp.own.phy[i]!);\n }\n if (c > 0) {\n hx += c * wp.shared.ax[i]! * Math.sin(wp.shared.fx[i]! * t + wp.shared.phx[i]!);\n hy += c * wp.shared.ay[i]! * Math.sin(wp.shared.fy[i]! * t + wp.shared.phy[i]!);\n }\n }\n const margin = m + wp.margin;\n const x = e.x0 + e.vx * dt + hx;\n const y = e.y0 + e.vy * dt + hy;\n return {\n x: e.wrapDisabled ? x : wrap(x, -margin, w + margin),\n y: e.wrapDisabled ? y : wrap(y, -margin, h + margin),\n flip: e.headingLeft,\n };\n }\n // drift\n const rawX = e.x0 + e.vx * dt;\n const x = e.wrapDisabled ? rawX : wrap(rawX, -m, w + m);\n const rawY = e.y0 + e.vy * dt;\n let y = e.vy !== 0 && !e.wrapDisabled ? wrap(rawY, -m, h + m) : rawY;\n if (e.bob) y += e.bob * Math.sin(t / 500 + e.phase);\n return { x, y, flip: e.headingLeft };\n}\n\n/**\n * Analytic heading (radians) at time `t`, from a finite difference of positionAt.\n * Used to orient streak sprites. Returns null across a wrap seam (position jump\n * larger than half the viewport) — callers should skip orientation that frame.\n */\nexport function headingAt(e: Entity, t: number, w: number, h: number): number | null {\n const dtMs = 32;\n const t1 = t < dtMs ? t + dtMs : t;\n const t0 = t1 - dtMs;\n const a = positionAt(e, t0, w, h);\n const b = positionAt(e, t1, w, h);\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) return null;\n if (dx === 0 && dy === 0) return null;\n return Math.atan2(dy, dx);\n}\n\n/** Time-varying sprite index for text/emoji cycling. Returns static index when cyclePeriod is 0. */\nexport function spriteIndexAt(e: Entity, t: number, variants: number): number {\n if (!e.cyclePeriod || variants <= 1) return e.spriteIndex;\n // Under a data layout the rows keep their reading order and advance in\n // step — a marquee — instead of each entity cycling from its own phase.\n if (e.ordered) return (e.spriteIndex + Math.floor(clockTime(e, t) / e.cyclePeriod)) % variants;\n return Math.floor(clockTime(e, t) / e.cyclePeriod + (e.cyclePhase ?? e.phase) / (2 * Math.PI)) % variants;\n}\n\n/** An inter-entity link edge with its (wrap-aware) distance, for falloff alpha. */\nexport interface LinkEdge {\n i: number;\n j: number;\n dist: number;\n}\n\nfunction wrapDist(\n pi: { x: number; y: number },\n pj: { x: number; y: number },\n doWrap: boolean,\n w: number,\n h: number,\n): number {\n let dx = pj.x - pi.x;\n let dy = pj.y - pi.y;\n if (doWrap) {\n if (Math.abs(dx) > w / 2) dx = dx > 0 ? dx - w : dx + w;\n if (Math.abs(dy) > h / 2) dy = dy > 0 ? dy - h : dy + h;\n }\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * Edge list for a layer's `links`, dispatching on mode:\n * 'nearest' (default) k-nearest within maxDist; 'chain' sequential order\n * (Mystify — ignores k/maxDist, `closed` joins last to first); 'random' a fixed\n * golden-ratio-stride wiring filtered by maxDist (deterministic, no RNG draws).\n */\nexport function linkEdges(\n links: { k: number; maxDist: number; mode?: 'nearest' | 'chain' | 'random'; closed?: boolean },\n positions: Array<{ x: number; y: number }>,\n maxDistPx: number,\n doWrap: boolean,\n w: number,\n h: number,\n): LinkEdge[] {\n const n = positions.length;\n const mode = links.mode ?? 'nearest';\n if (mode === 'chain') {\n const out: LinkEdge[] = [];\n for (let i = 0; i < n - 1; i++) {\n out.push({ i, j: i + 1, dist: wrapDist(positions[i]!, positions[i + 1]!, doWrap, w, h) });\n }\n if (links.closed && n > 2) out.push({ i: n - 1, j: 0, dist: wrapDist(positions[n - 1]!, positions[0]!, doWrap, w, h) });\n return out;\n }\n if (mode === 'random') {\n const stride = Math.max(1, Math.round(n * 0.381966)); // golden-ratio conjugate — spreads partners\n const edges = new Set<string>();\n const out: LinkEdge[] = [];\n for (let i = 0; i < n; i++) {\n for (let mIdx = 1; mIdx <= links.k; mIdx++) {\n const j = (i + mIdx * stride) % n;\n if (j === i) continue;\n const dist = wrapDist(positions[i]!, positions[j]!, doWrap, w, h);\n if (dist > maxDistPx) continue;\n const key = `${Math.min(i, j)}:${Math.max(i, j)}`;\n if (!edges.has(key)) {\n edges.add(key);\n out.push({ i: Math.min(i, j), j: Math.max(i, j), dist });\n }\n }\n }\n return out;\n }\n return linkPairs(positions, links.k, maxDistPx, doWrap, w, h).map(([i, j]) => ({\n i,\n j,\n dist: wrapDist(positions[i]!, positions[j]!, doWrap, w, h),\n }));\n}\n\n/** K-nearest-neighbor edge list. Deterministic tie-break: (dist, index).\n * When `doWrap` is true, uses toroidal distance so links don't streak across wrap seams. */\nexport function linkPairs(\n positions: Array<{ x: number; y: number }>,\n k: number,\n maxDist: number,\n doWrap: boolean,\n w: number,\n h: number,\n): Array<[number, number]> {\n const n = positions.length;\n const edges = new Set<string>();\n const out: Array<[number, number]> = [];\n\n for (let i = 0; i < n; i++) {\n const pi = positions[i]!;\n const neighbors: Array<{ dist: number; j: number }> = [];\n for (let j = 0; j < n; j++) {\n if (i === j) continue;\n const pj = positions[j]!;\n let dx = pj.x - pi.x;\n let dy = pj.y - pi.y;\n if (doWrap) {\n if (Math.abs(dx) > w / 2) dx = dx > 0 ? dx - w : dx + w;\n if (Math.abs(dy) > h / 2) dy = dy > 0 ? dy - h : dy + h;\n }\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist <= maxDist) neighbors.push({ dist, j });\n }\n neighbors.sort((a, b) => a.dist - b.dist || a.j - b.j);\n for (let ni = 0; ni < Math.min(k, neighbors.length); ni++) {\n const j = neighbors[ni]!.j;\n const lo = Math.min(i, j);\n const hi = Math.max(i, j);\n const key = `${lo}:${hi}`;\n if (!edges.has(key)) {\n edges.add(key);\n out.push([lo, hi]);\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Deterministic text-block line breaking\n// ---------------------------------------------------------------------------\n\nconst CHAR_NARROW = new Set('iIljtf1!|.,;:\\'\"()[]{}');\nconst CHAR_WIDE = new Set('mwMWGOQD@%');\n\n/**\n * Which advance table the line-breaker uses. `proportional` is the\n * character-class table below (the default, and the only table until\n * `textBlock.font` existed); `mono` is a uniform 0.6 em advance — the classic\n * monospace cell (Courier, Menlo, SF Mono all sit within a percent of it).\n */\nexport type TextMetricsClass = 'proportional' | 'mono';\n\nconst MONO_FAMILY_RE = /\\b(?:ui-)?mono(?:space)?\\b|courier|menlo|monaco|sfmono|consolas|inconsolata|fira\\s*code|source\\s*code|jetbrains|ibm\\s*plex\\s*mono|roboto\\s*mono/i;\n\n/**\n * Metrics class for a `textBlock.font` string: `mono` when the family names\n * a monospace face (the generic `monospace`, or a well-known fixed-pitch\n * family), else `proportional`. Absent font ⇒ proportional, as before.\n */\nexport function textMetricsClassFor(font?: string): TextMetricsClass {\n return font && MONO_FAMILY_RE.test(font) ? 'mono' : 'proportional';\n}\n\nconst MONO_ADVANCE_EM = 0.6;\n\n/**\n * Approximate glyph width as a fraction of em. Uses character-class buckets\n * so line breaks are identical across platforms (no measureText). The average\n * across Latin text lands near 0.55, close to perceive.ts's 0.62 heuristic\n * but with per-class refinement. Under `mono` every glyph (space included)\n * advances the same cell.\n */\nfunction charWidthEm(ch: string, metrics: TextMetricsClass = 'proportional'): number {\n if (metrics === 'mono') return MONO_ADVANCE_EM;\n if (ch === ' ' || ch === '\\t') return 0.3;\n if (CHAR_NARROW.has(ch)) return 0.35;\n if (CHAR_WIDE.has(ch)) return 0.72;\n return 0.55;\n}\n\n/**\n * Em-width of a string under the same character-class table `breakTextBlock`\n * uses. `mono` counts grapheme clusters, not UTF-16 code units — an emoji or\n * combining/ZWJ sequence is one advance-width cell, matching what's painted,\n * not one cell per surrogate half or combining mark.\n */\nexport function textWidthEm(str: string, metrics: TextMetricsClass = 'proportional'): number {\n if (metrics === 'mono') return graphemeClusters(str).length * MONO_ADVANCE_EM;\n let w = 0;\n for (let i = 0; i < str.length; i++) w += charWidthEm(str[i]!, metrics);\n return w;\n}\n\nexport interface TextBlockLine {\n text: string;\n widthEm: number;\n}\n\n/**\n * Break `text` into lines that fit within `maxWidthEm` em-widths. Splits on\n * whitespace; a single word wider than the limit gets its own line unbroken.\n * Explicit `\\n` always forces a break. Pure, deterministic, no canvas needed.\n */\nexport function breakTextBlock(text: string, maxWidthEm: number, metrics: TextMetricsClass = 'proportional'): TextBlockLine[] {\n const paragraphs = text.split('\\n');\n const lines: TextBlockLine[] = [];\n\n for (const para of paragraphs) {\n if (para.length === 0) {\n lines.push({ text: '', widthEm: 0 });\n continue;\n }\n const words = para.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 0) {\n lines.push({ text: '', widthEm: 0 });\n continue;\n }\n\n let lineText = words[0]!;\n let lineW = textWidthEm(lineText, metrics);\n const spaceW = charWidthEm(' ', metrics);\n\n for (let i = 1; i < words.length; i++) {\n const word = words[i]!;\n const wordW = textWidthEm(word, metrics);\n if (lineW + spaceW + wordW <= maxWidthEm) {\n lineText += ' ' + word;\n lineW += spaceW + wordW;\n } else {\n lines.push({ text: lineText, widthEm: lineW });\n lineText = word;\n lineW = wordW;\n }\n }\n lines.push({ text: lineText, widthEm: lineW });\n }\n\n return lines;\n}\n\n/**\n * Where an anchored textBlock's layout origin sits relative to `position`:\n * the (dx, dy) to ADD to `position` so that the named point of the rendered\n * text lands on it. The rendered box is the widest line wide (placed inside\n * the `maxWidth` box by `align`) and `lines × lineHeight` tall — so `anchor`\n * says where the block sits and `align` only shapes its ragged edge. Absent\n * anchor ⇒ (0, 0): `position` stays the layout box's top-left, exactly as\n * before the field existed. Renderer, perception and advisories all call\n * this, so their boxes agree by construction.\n */\nexport function textBlockAnchorOffset(\n s: { anchor?: TextBlockAnchor; align?: 'left' | 'center' | 'right' },\n maxWPx: number,\n maxLineW: number,\n totalH: number,\n): { dx: number; dy: number } {\n if (!s.anchor) return { dx: 0, dy: 0 };\n const ax = s.anchor.endsWith('left') ? 0 : s.anchor.endsWith('right') ? 1 : 0.5;\n const ay = s.anchor.startsWith('top') ? 0 : s.anchor.startsWith('bottom') ? 1 : 0.5;\n // Ink left edge relative to the layout origin, as `align` places it.\n const inkX0 = s.align === 'center' ? (maxWPx - maxLineW) / 2 : s.align === 'right' ? maxWPx - maxLineW : 0;\n return { dx: -(inkX0 + ax * maxLineW), dy: -(ay * totalH) };\n}\n\n// ---------------------------------------------------------------------------\n// Deterministic text reveal (textBlock `reveal` — typing/deleting)\n// ---------------------------------------------------------------------------\n\n// Combining/attaching code points that must never be painted without their\n// base: combining diacritics, variation selectors, skin-tone modifiers,\n// keycap. Deliberately a fixed table rather than Intl.Segmenter, which is\n// not required to segment identically across engines — same philosophy (and\n// same determinism reason) as the charWidthEm buckets above.\nfunction isClusterExtend(cp: number): boolean {\n return (\n (cp >= 0x0300 && cp <= 0x036f) || // combining diacritics\n (cp >= 0x1ab0 && cp <= 0x1aff) ||\n (cp >= 0x20d0 && cp <= 0x20ff) ||\n (cp >= 0xfe00 && cp <= 0xfe0f) || // variation selectors\n (cp >= 0x1f3fb && cp <= 0x1f3ff) || // skin tones\n cp === 0x20e3 // combining enclosing keycap\n );\n}\n\nfunction isRegionalIndicator(cp: number): boolean {\n return cp >= 0x1f1e6 && cp <= 0x1f1ff;\n}\n\nconst ZWJ = 0x200d;\n\n/**\n * Split a string into paint-safe grapheme clusters: surrogate pairs stay\n * whole, combining marks / variation selectors / skin tones attach to their\n * base, ZWJ joins sequences (emoji families), regional indicators pair up\n * (flags). Deterministic across engines by construction.\n */\nexport function graphemeClusters(text: string): string[] {\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n const cp = text.codePointAt(i)!;\n let end = i + (cp > 0xffff ? 2 : 1);\n // Flag pair: two regional indicators form one cluster.\n if (isRegionalIndicator(cp) && end < text.length) {\n const next = text.codePointAt(end)!;\n if (isRegionalIndicator(next)) end += next > 0xffff ? 2 : 1;\n }\n // Attach extenders and ZWJ-joined sequences.\n while (end < text.length) {\n const next = text.codePointAt(end)!;\n if (isClusterExtend(next)) {\n end += next > 0xffff ? 2 : 1;\n } else if (next === ZWJ && end + 1 < text.length) {\n const after = text.codePointAt(end + 1)!;\n end += 1 + (after > 0xffff ? 2 : 1);\n } else {\n break;\n }\n }\n out.push(text.slice(i, end));\n i = end;\n }\n return out;\n}\n\nexport interface TextRevealInput {\n progress?: number;\n mode?: 'typewriter' | 'word' | 'line' | 'glyphFade';\n speed?: number;\n fade?: number;\n}\n\nexport interface RevealState {\n /** Effective 0..1 progress after combining authored progress and speed at t. */\n progress: number;\n /** Number of fully visible lines. */\n fullLines: number;\n /** Grapheme-safe visible prefix of the next line ('' when none). */\n partialText: string;\n /** Caret anchor: line index and the visible prefix on that line. */\n caretLine: number;\n caretPrefix: string;\n /**\n * `glyphFade` mode only: per-line per-grapheme alpha (0..1), indexed\n * parallel to `graphemeClusters(lines[i].text)`. Alphas only decrease in\n * reading order, so a renderer may stop at the first zero.\n */\n glyphAlphas?: number[][];\n}\n\n/**\n * Resolve which glyphs of a broken textBlock are visible at time `tMs`.\n * Pure function of (lines, reveal, tMs) — the renderer paints exactly this,\n * and perceive models exactly this, so agents and pixels agree. `speed` is\n * graphemes/sec regardless of mode; mode only quantizes the frontier.\n */\nexport function revealState(lines: TextBlockLine[], reveal: TextRevealInput, tMs: number): RevealState {\n const lineClusters = lines.map((l) => graphemeClusters(l.text));\n const totalGraphemes = lineClusters.reduce((n, c) => n + c.length, 0);\n\n const authored = Math.max(0, Math.min(1, reveal.progress ?? 1));\n const speed = reveal.speed ?? 0;\n const timed = speed > 0 && totalGraphemes > 0 ? Math.min(1, (speed * tMs) / 1000 / totalGraphemes) : 1;\n const progress = Math.min(authored, timed);\n\n const mode = reveal.mode ?? 'typewriter';\n let fullLines = 0;\n let partialText = '';\n\n // glyphFade: glyph g starts fading at (g/total)·(1−fade) and ramps to\n // opaque over a `fade`-wide window of progress, so every glyph is 0 at\n // progress 0 and 1 at progress 1. The frontier below (shared with\n // typewriter) still anchors the caret. Pure paint, like everything here.\n let glyphAlphas: number[][] | undefined;\n if (mode === 'glyphFade') {\n // The 0.01 floor is defensive only — validation already enforces the\n // public contract fade ∈ (0, 1] (FORMAT.md). It exists so direct callers\n // that skip validateSpec can't make the divide below infinite, not to\n // remap legal values: anything ≥ 0.01 passes through untouched.\n const f = Math.min(1, Math.max(0.01, reveal.fade ?? 0.15));\n let g = 0;\n glyphAlphas = lineClusters.map((clusters) =>\n clusters.map(() => {\n const start = totalGraphemes > 0 ? (g++ / totalGraphemes) * (1 - f) : 0;\n return Math.max(0, Math.min(1, (progress - start) / f));\n }),\n );\n }\n\n if (mode === 'line') {\n fullLines = Math.round(progress * lines.length);\n } else if (mode === 'word') {\n const lineWords = lines.map((l) => (l.text.length === 0 ? [] : l.text.split(' ')));\n const totalWords = lineWords.reduce((n, ws) => n + ws.length, 0);\n let remaining = Math.round(progress * totalWords);\n for (const ws of lineWords) {\n if (remaining >= ws.length) {\n remaining -= ws.length;\n fullLines++;\n // A zero-word (empty) line is \"full\" for free; keep consuming.\n continue;\n }\n if (remaining > 0) partialText = ws.slice(0, remaining).join(' ');\n break;\n }\n } else {\n let remaining = Math.round(progress * totalGraphemes);\n for (const clusters of lineClusters) {\n if (remaining >= clusters.length) {\n remaining -= clusters.length;\n fullLines++;\n continue;\n }\n if (remaining > 0) partialText = clusters.slice(0, remaining).join('');\n break;\n }\n }\n\n // Caret sits at the reveal frontier: end of the partial line, else end of\n // the last full line, else the start of the block.\n let caretLine: number;\n let caretPrefix: string;\n if (partialText.length > 0) {\n caretLine = fullLines;\n caretPrefix = partialText;\n } else if (fullLines > 0) {\n caretLine = fullLines - 1;\n caretPrefix = lines[fullLines - 1]!.text;\n } else {\n caretLine = 0;\n caretPrefix = '';\n }\n\n return { progress, fullLines, partialText, caretLine, caretPrefix, glyphAlphas };\n}\n","import {\n createRng,\n type ControlTrack,\n type ParamDelta,\n type SaverContext,\n type SaverInstance,\n type SaverManifest,\n type SaverPlugin,\n} from '@idle-screens/core';\nimport { assertValidSpec, assertValidSequence, validateSpec } from './validate';\nimport { alphaAt, breakTextBlock, buildEntities, graphemeClusters, headingAt, lifeAlphaAt, linkEdges, positionAt, revealState, rotationAt, sizeAt, spriteIndexAt, textBlockAnchorOffset, textMetricsClassFor, type Entity } from './simulate';\nimport {\n applyDeltasToSpec,\n easeSmooth,\n lerpSpec,\n resolveSpecPath,\n structuralSignature,\n textStringsDiffer,\n type SteerDelta,\n} from './steer';\nimport type { IdleSequence, LayerSpec, SaverSpec, SpriteSpec } from './types';\nimport { LIMITS } from './types';\nimport { canMorph, morphChainRoot, normalizeSeed, resolveSegment, segmentStart } from './sequence';\nimport { FEATHER_STEPS, barBox, barFraction, featherAlphas, isShapedSprite, polygonPoints, strokeSamples, strokeTaper, strokeWidthPx } from './shapes';\n\nconst DEFAULT_STEER_DUR = 1000;\n\n/**\n * Apply steering deltas to a spec one at a time, keeping each only if its\n * path resolves on this spec AND the result validates. This is the routing\n * rule for a sequence's retained track: a key path (`bars.sprite.values`) lands on\n * whichever segment owns the key and is a no-op on the others, and one delta\n * that is out of bounds for a given segment does not take the rest down with\n * it. Returns `spec` itself (same reference) when nothing applied, so callers\n * can skip work — and so a sequence with no track is byte-identical.\n */\nfunction applyRetainedDeltas(spec: SaverSpec, deltas: Iterable<SteerDelta>): SaverSpec {\n let out = spec;\n for (const d of deltas) {\n if (!resolveSpecPath(out, d.path)) continue;\n const next = applyDeltasToSpec(out, [d]);\n if (validateSpec(next).valid) out = next;\n }\n return out;\n}\n\n/** Expand #rgb/#rrggbb to an rgba() string — needed for gradient stops with alpha. */\nfunction hexToRgba(hex: string, alpha: number): string {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${alpha})`;\n}\n\nconst FONT_PREFIX_RE = /^((?:(?:italic|oblique|bold|bolder|lighter|normal|\\d{3})\\s+)+)/;\n\n/**\n * Matches the size token in a CSS font shorthand (\"bold 26px monospace\").\n *\n * The digit runs are bounded on purpose. This ran as `(\\d*\\.?\\d+)px`, where\n * `\\d*` and `\\d+` can split the same digit run many ways, so a long run that\n * never reaches \"px\" makes the engine retry every split at every start\n * position. `sprite.font` comes straight from an authored SaverSpec, so that\n * input is reachable by anyone who can publish a scene: 1 000 digits took\n * 600 ms and 5 000 took 62 SECONDS, which is a denial of service rather than\n * a slow path. Bounding each run makes the work per start position constant —\n * 200 000 chars now costs about 4 ms.\n *\n * The bounds are far past anything real: no CSS font size needs more than\n * five integer digits or four decimals. `.5px` still parses via the second\n * branch.\n */\nconst FONT_PX_RE = /(\\d{1,5}(?:\\.\\d{1,4})?|\\.\\d{1,4})px/;\n\n/**\n * Rescale an explicit px size inside a font shorthand.\n *\n * A spec in the default `viewport` units expresses every other dimension as a\n * fraction of `min(w, h)`, so a font pinned to absolute pixels is the one thing\n * that does NOT adapt: `bold 26px monospace` renders 26px whether the canvas is\n * 1920 or 320 wide, which is how the dashboard's text came to overlap itself at\n * thumbnail size. Scaling it by `min(w, h) / referenceViewport` makes it behave\n * like the rest of the spec. Specs that opt into `units: 'px'` are asking for\n * absolute sizes and are left alone.\n */\nfunction scaleFontPx(font: string, factor: number): string {\n if (factor === 1) return font;\n return font.replace(FONT_PX_RE, (_m, n: string) => `${(Number(n) * factor).toFixed(2)}px`);\n}\n\n/** Build a valid CSS font shorthand: weight/style tokens must precede the size. */\nfunction composeFontShorthand(sz: number, font: string): string {\n const m = FONT_PREFIX_RE.exec(font);\n if (m) return `${m[1].trim()} ${sz}px ${font.slice(m[0].length)}`;\n return `${sz}px ${font}`;\n}\n\n/** Derive a manifest so a compiled spec composes with @idle-screens/capabilities. */\nexport function manifestFor(spec: SaverSpec): SaverManifest {\n const total = spec.layers.reduce((n, l) => n + l.count, 0);\n const costTier = total < 30 ? 'idle' : total < 150 ? 'low' : total < 400 ? 'medium' : 'high';\n return {\n id: spec.id,\n label: spec.label,\n // Declarative specs are closed-form by construction: every entity is a\n // pure function of (seed, t), which is the whole point of the format.\n timeModel: 'closed-form',\n passthrough: false,\n minBackend: 'canvas2d',\n costTier,\n motionIntensity: spec.motionIntensity ?? 'moderate',\n reducedMotionFallback: 'static',\n // Flash-safe by construction: static background + bounded sprites, no strobe\n // primitive. Proven by sampling a compiled spec through @idle-screens/validator.\n a11y: { flashSafe: true },\n workerReady: true,\n };\n}\n\ninterface Built {\n layer: LayerSpec;\n entities: Entity[];\n}\n\n/**\n * Internal, per-layer: paint the layer twice for a window — the `outgoing`\n * sprite (the same sprite with the previous words) at `1 − k`, the layer's\n * own sprite at `k`. Set by a `SequenceInstance` for the `text` / `textBlock`\n * layers of a morph declared `text: 'crossfade'`; never from a spec field.\n * Only text sprites are ever drawn this way.\n */\ninterface LayerPaintOverride {\n outgoing: SpriteSpec;\n k: number;\n}\n\n/** One draw's paint override: which sprite to paint, and an alpha multiplier on top of the entity's own. */\ninterface PaintPass {\n sprite?: SpriteSpec;\n alpha: number;\n}\n\n/** Per-instance options a host (today: `SequenceInstance`) sets; a plain compileSaver mount sets none. */\ninterface SpecInstanceOptions {\n /**\n * Draw over whatever is already on the surface: `drawBackground` is skipped,\n * the frame is not cleared to a colour, and `ghosting` is ignored (a smear\n * needs an opaque ground to decay into — the surface owner may declare its\n * own). The instance never clears the surface either; the owner does.\n * A sequence's segment children over a `bed` render this way.\n */\n transparent?: boolean;\n /**\n * Skip the constructor's own eager paused-mount paint. For a transparent\n * instance whose owner is about to call `renderFrame` again immediately\n * with paint overrides already set (a morph chain-root child, mounted\n * mid-morph) — the constructor's plain paint would otherwise leave a\n * stray full-opacity frame on the shared surface underneath, which a\n * partial-alpha override pass (`text: 'crossfade'`) then composites over\n * rather than replaces.\n */\n skipInitialPaint?: boolean;\n}\n\nclass SpecInstance implements SaverInstance {\n private readonly canvas: HTMLCanvasElement | OffscreenCanvas;\n private readonly ownsCanvas: boolean;\n private readonly transparent: boolean;\n private readonly ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n private readonly saverCtx: SaverContext;\n private readonly seed: number;\n private w: number;\n private h: number;\n private layers: Built[] = [];\n private frameId: number | null = null;\n private paused = false;\n private startT = 0;\n private baseT = 0; // elapsed logical time carried across pause/resume\n private lastT = 0;\n /** Last time painted — detects non-contiguous seeks for the ghosting warm-up replay. */\n private lastRenderT = Number.NEGATIVE_INFINITY;\n\n /** The spec currently being rendered (base spec + any applied steering). */\n private effSpec: SaverSpec;\n /** Active glide between two resolved specs (live setParam/applyTrack). */\n private transition: { from: SaverSpec; to: SaverSpec; startT: number; dur: number } | null = null;\n private lastStructural = '';\n /** See `LayerPaintOverride`; null (the default, and every plain mount) draws every layer once. */\n private paintOverrides: ReadonlyMap<number, LayerPaintOverride> | null = null;\n\n constructor(\n private readonly spec: SaverSpec,\n ctx: SaverContext,\n opts: SpecInstanceOptions = {},\n ) {\n this.effSpec = spec;\n this.saverCtx = ctx;\n this.transparent = opts.transparent === true;\n this.seed = normalizeSeed(spec.seed ?? ctx.seed);\n let canvas: HTMLCanvasElement | OffscreenCanvas;\n if (ctx.surface) {\n canvas = ctx.surface;\n this.ownsCanvas = false;\n } else {\n const el = document.createElement('canvas');\n el.style.cssText = 'display:block;width:100%;height:100%';\n el.setAttribute('aria-hidden', 'true');\n ctx.host.appendChild(el);\n canvas = el;\n this.ownsCanvas = true;\n }\n this.canvas = canvas;\n // Transparent instances (a bed's own offscreen fade canvas) never paint a\n // background, so their cleared/unpainted pixels must stay actually\n // transparent for `composite()`'s drawImage to blend only the ink onto\n // the bed — an opaque (alpha: false) context turns those pixels solid\n // black instead. Opaque instances keep alpha: false (unchanged).\n const c2d = canvas.getContext('2d', { alpha: this.transparent }) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;\n if (!c2d) throw new Error('schema saver: no 2d context');\n this.ctx = c2d;\n\n this.w = ctx.width;\n this.h = ctx.height;\n this.sizeCanvas();\n this.rebuild();\n\n this.paused = ctx.reducedMotion;\n if (this.paused) {\n if (!opts.skipInitialPaint) this.renderFrame(0, this.seed);\n } else {\n this.start();\n }\n }\n\n /** Viewport factor for absolute px sizes — 1 for `units: 'px'` specs. */\n private fontScale(): number {\n if (this.effSpec.units === 'px') return 1;\n return Math.min(this.w, this.h) / (this.effSpec.referenceViewport ?? LIMITS.referenceViewport);\n }\n\n private sizeCanvas(): void {\n const dpr = Math.min(this.saverCtx.dpr, 2);\n this.canvas.width = Math.max(1, Math.round(this.w * dpr));\n this.canvas.height = Math.max(1, Math.round(this.h * dpr));\n this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n // Resizing clears the canvas — force a ghosting warm-up on the next frame.\n this.lastRenderT = Number.NEGATIVE_INFINITY;\n }\n\n /** (Re)seed and place all entities — deterministic for the seed + viewport. */\n private rebuild(): void {\n const rng = createRng(this.seed);\n const scale = this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h);\n const refVp = this.effSpec.referenceViewport ?? LIMITS.referenceViewport;\n let countScale = scale > 1 ? Math.min(this.w, this.h) / refVp : 1;\n if (countScale > 1) {\n const rawTotal = this.effSpec.layers.reduce((s, l) => s + Math.round(l.count * countScale), 0);\n if (rawTotal > LIMITS.maxTotal) countScale *= LIMITS.maxTotal / rawTotal;\n }\n this.layers = this.effSpec.layers.map((layer) => ({ layer, entities: buildEntities(layer, rng, this.w, this.h, scale, countScale) }));\n this.lastStructural = structuralSignature(this.effSpec);\n }\n\n private start(): void {\n if (this.frameId !== null || typeof requestAnimationFrame === 'undefined') return;\n this.startT = 0;\n this.frameId = requestAnimationFrame((now) => this.loop(now));\n }\n\n private stop(): void {\n if (this.frameId !== null) {\n cancelAnimationFrame(this.frameId);\n this.frameId = null;\n }\n // Freeze elapsed time so resume continues the scene instead of restarting at t=0.\n this.baseT = this.lastT;\n }\n\n private loop(now: number): void {\n this.frameId = requestAnimationFrame((n) => this.loop(n));\n if (this.startT === 0) this.startT = now;\n this.lastT = now - this.startT + this.baseT;\n this.renderFrame(this.lastT, this.seed);\n }\n\n private drawBackground(t: number): void {\n const { ctx, w, h } = this;\n const bg = this.effSpec.background;\n if (!bg || bg.type === 'solid') {\n ctx.fillStyle = bg?.color ?? '#05050a';\n ctx.fillRect(0, 0, w, h);\n return;\n }\n const g = ctx.createLinearGradient(0, 0, 0, h);\n const drift = bg.drift;\n for (let i = 0; i < bg.stops.length; i++) {\n const s = bg.stops[i]!;\n let at = s.at;\n if (drift) {\n const amount = drift.amount ?? 0.15;\n const phase = (i / bg.stops.length) * Math.PI * 2;\n at = Math.max(0, Math.min(1, at + amount * Math.sin((t * 2 * Math.PI) / drift.period + phase)));\n }\n g.addColorStop(at, s.color);\n }\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, w, h);\n if (bg.band) {\n ctx.fillStyle = bg.band.color;\n const bh = bg.band.height * (this.effSpec.units === 'px' ? 1 : Math.min(w, h));\n ctx.fillRect(0, h - bh, w, bh);\n }\n }\n\n /** Position with parent-orbit resolution: a layer-parented orbit entity's\n * positionAt is an offset around (0,0); add the parent's own analytic position. */\n private entityPos(e: Entity, t: number, parentE: Entity | null): { x: number; y: number; flip: boolean } {\n const p = positionAt(e, t, this.w, this.h);\n if (parentE && e.orbitParent) {\n const pp = positionAt(parentE, t, this.w, this.h);\n p.x += pp.x;\n p.y += pp.y;\n }\n return p;\n }\n\n /** Resolve the single parent entity for a layer-parented orbit layer (or null). */\n private parentEntityFor(built: Built): Entity | null {\n const m = built.layer.motion;\n if (m.type !== 'orbit' || !m.center || !('layer' in m.center)) return null;\n const key = m.center.layer;\n const parent = this.layers.find((b) => b.layer.key === key);\n return parent?.entities[0] ?? null;\n }\n\n private drawTrail(built: Built, e: Entity, t: number, lifeA: number, parentE: Entity | null): void {\n const trail = built.layer.trail;\n if (!trail) return;\n const { ctx, w, h } = this;\n const fade = trail.fade ?? 1;\n const n = Math.min(Math.ceil(trail.length / 50), LIMITS.maxTrailSamples);\n const headAlpha = alphaAt(e, t) * lifeA;\n const headSize = sizeAt(e, t);\n const sprite = built.layer.sprite;\n const resolvedColor = isShapedSprite(sprite)\n ? (sprite.colors?.[e.colorIndex] ?? sprite.color)\n : sprite.kind === 'text' || sprite.kind === 'textBlock' ? (sprite.color ?? '#e6e8ef') : '#e6e8ef';\n const isSoft = sprite.kind === 'circle' && sprite.soft;\n const wrap = built.layer.wrap !== false;\n\n const head = this.entityPos(e, t, parentE);\n let prevX = head.x;\n let prevY = head.y;\n\n for (let s = 1; s <= n; s++) {\n const k = s / n;\n const pastT = t - k * trail.length;\n if (pastT < 0) break;\n const pos = this.entityPos(e, pastT, parentE);\n\n if (wrap) {\n const dx = pos.x - prevX;\n const dy = pos.y - prevY;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) break;\n }\n prevX = pos.x;\n prevY = pos.y;\n\n const a = headAlpha * (1 - k * fade);\n if (a <= 0) break;\n const r = (headSize / 2) * (1 - k * 0.7);\n if (r < 0.2) break;\n\n ctx.globalAlpha = a;\n if (isSoft) {\n const g = ctx.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, r);\n g.addColorStop(0, resolvedColor);\n g.addColorStop(0.35, hexToRgba(resolvedColor, 0.75));\n g.addColorStop(1, hexToRgba(resolvedColor, 0));\n ctx.fillStyle = g;\n } else {\n ctx.fillStyle = resolvedColor;\n }\n ctx.beginPath();\n ctx.arc(pos.x, pos.y, r, 0, Math.PI * 2);\n ctx.fill();\n }\n }\n\n private drawEntity(built: Built, e: Entity, t: number, lifeA: number, parentE: Entity | null, paint?: PaintPass): void {\n const { ctx } = this;\n const p = this.entityPos(e, t, parentE);\n const sprite = paint?.sprite ?? built.layer.sprite;\n const sz = sizeAt(e, t);\n const rot = rotationAt(e, t);\n const unitScale = this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h);\n ctx.globalAlpha = alphaAt(e, t) * lifeA * (paint?.alpha ?? 1);\n if (sprite.kind === 'ring') {\n const r = sz / 2;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n ctx.strokeStyle = resolvedColor;\n ctx.lineWidth = Math.max(0.5, (sprite.width ?? (unitScale === 1 ? 2 : 0.002)) * unitScale);\n ctx.beginPath();\n ctx.arc(p.x, p.y, r, 0, Math.PI * 2);\n ctx.stroke();\n return;\n }\n if (sprite.kind === 'streak') {\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const heading = headingAt(e, t, this.w, this.h) ?? 0;\n const tailX = p.x - Math.cos(heading) * sz;\n const tailY = p.y - Math.sin(heading) * sz;\n const g = ctx.createLinearGradient(tailX, tailY, p.x, p.y);\n g.addColorStop(0, hexToRgba(resolvedColor, 0));\n g.addColorStop(1, resolvedColor);\n ctx.strokeStyle = g;\n ctx.lineWidth = Math.max(0.5, (sprite.width ?? (unitScale === 1 ? 2 : 0.002)) * unitScale);\n ctx.lineCap = 'round';\n ctx.beginPath();\n ctx.moveTo(tailX, tailY);\n ctx.lineTo(p.x, p.y);\n ctx.stroke();\n return;\n }\n if (sprite.kind === 'rect') {\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const rh = e.size2 !== undefined\n ? e.size2 * (e.size > 0 ? sz / e.size : 1) // grow/warp scale height with width\n : sz;\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n ctx.fillStyle = resolvedColor;\n const feather = sprite.feather ?? 0;\n if (feather > 0) {\n // Soft edge: nested fills from the OUTSIDE IN — the full-size rect\n // first at the faintest alpha, the core last at full — so the\n // composited alpha ramps linearly across the feathered band (see\n // featherAlphas). Only `lighter` sums alphas; `screen` still\n // composites source-over, so it takes the source-over schedule.\n const base = ctx.globalAlpha;\n const additive = built.layer.blend === 'lighter';\n const alphas = featherAlphas(FEATHER_STEPS, additive);\n for (let j = 1; j <= FEATHER_STEPS; j++) {\n const f = 1 - (feather * (j - 1)) / FEATHER_STEPS; // j=1 full size … j=K the core\n const fw = sz * f;\n const fh = rh * f;\n ctx.globalAlpha = base * alphas[j - 1]!;\n ctx.fillRect(-fw / 2, -fh / 2, fw, fh);\n }\n ctx.globalAlpha = base;\n } else {\n ctx.fillRect(-sz / 2, -rh / 2, sz, rh);\n }\n ctx.restore();\n return;\n }\n if (sprite.kind === 'bar') {\n const len = sz * barFraction(sprite, e.barIndex ?? 0);\n if (len <= 0) return;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const th = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz * 0.2;\n const box = barBox(sprite.direction ?? 'right', len, th);\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n ctx.fillStyle = resolvedColor;\n ctx.fillRect(box.cx - box.halfX, box.cy - box.halfY, box.halfX * 2, box.halfY * 2);\n ctx.restore();\n return;\n }\n if (sprite.kind === 'polygon') {\n const r = sz / 2;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const pts = polygonPoints(sprite, r);\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n if (sprite.soft) {\n const g = ctx.createRadialGradient(0, 0, 0, 0, 0, r);\n g.addColorStop(0, resolvedColor);\n g.addColorStop(0.35, hexToRgba(resolvedColor, 0.75));\n g.addColorStop(1, hexToRgba(resolvedColor, 0));\n ctx.fillStyle = g;\n } else {\n ctx.fillStyle = resolvedColor;\n }\n ctx.beginPath();\n ctx.moveTo(pts[0]!.x, pts[0]!.y);\n for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i]!.x, pts[i]!.y);\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n return;\n }\n if (sprite.kind === 'stroke') {\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n const pts = strokeSamples(sprite, sz / 2);\n const lw = strokeWidthPx(sprite, unitScale);\n ctx.save();\n ctx.translate(p.x, p.y);\n let angle = rot;\n if (sprite.orient) angle += headingAt(e, t, this.w, this.h) ?? 0;\n if (angle) ctx.rotate(angle);\n ctx.strokeStyle = resolvedColor;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n if (sprite.taper) {\n // A brush mark: each sampled segment at its own width.\n for (let i = 1; i < pts.length; i++) {\n ctx.lineWidth = Math.max(0.5, lw * strokeTaper((i - 0.5) / (pts.length - 1)));\n ctx.beginPath();\n ctx.moveTo(pts[i - 1]!.x, pts[i - 1]!.y);\n ctx.lineTo(pts[i]!.x, pts[i]!.y);\n ctx.stroke();\n }\n } else {\n ctx.lineWidth = lw;\n ctx.beginPath();\n ctx.moveTo(pts[0]!.x, pts[0]!.y);\n for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i]!.x, pts[i]!.y);\n ctx.stroke();\n }\n ctx.restore();\n return;\n }\n if (sprite.kind === 'circle') {\n const r = sz / 2;\n const resolvedColor = sprite.colors?.[e.colorIndex] ?? sprite.color;\n ctx.save();\n if (rot) {\n ctx.translate(p.x, p.y);\n ctx.rotate(rot);\n ctx.translate(-p.x, -p.y);\n }\n if (sprite.soft) {\n const g = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, r);\n g.addColorStop(0, resolvedColor);\n g.addColorStop(0.35, hexToRgba(resolvedColor, 0.75));\n g.addColorStop(1, hexToRgba(resolvedColor, 0));\n ctx.fillStyle = g;\n } else {\n ctx.fillStyle = resolvedColor;\n }\n ctx.beginPath();\n ctx.arc(p.x, p.y, r, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n return;\n }\n if (sprite.kind === 'textBlock') {\n const unitScale = Math.min(this.w, this.h);\n const fsPx = sprite.fontSize * unitScale;\n const lh = (sprite.lineHeight ?? 1.4) * fsPx;\n const maxWPx = sprite.maxWidth * unitScale;\n const maxWEm = maxWPx / fsPx;\n const lines = breakTextBlock(sprite.text, maxWEm, textMetricsClassFor(sprite.font));\n const align = sprite.align ?? 'left';\n // Reveal masks glyphs; layout above always ran on the full text, so\n // lines never reflow while typing.\n const reveal = sprite.reveal;\n const rs = reveal ? revealState(lines, reveal, t) : null;\n const fullLines = rs ? rs.fullLines : lines.length;\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n if (sprite.anchor) {\n // `position` names a point of the rendered text, not the layout box's\n // top-left. Offset after line-breaking so the block's real extent\n // (widest line × lines) is what gets anchored; rotation stays about\n // the anchor point. Same arithmetic as perceive/advise (simulate.ts).\n const maxLineW = lines.reduce((m, l) => Math.max(m, l.widthEm), 0) * fsPx;\n const { dx, dy } = textBlockAnchorOffset(sprite, maxWPx, maxLineW, lines.length * lh);\n if (dx !== 0 || dy !== 0) ctx.translate(dx, dy);\n }\n // Paint-level alpha for the block only (layer `alpha` is baked per entity).\n if (sprite.opacity !== undefined) ctx.globalAlpha *= sprite.opacity;\n ctx.font = sprite.font ? composeFontShorthand(fsPx, sprite.font) : `${fsPx}px system-ui, sans-serif`;\n ctx.fillStyle = sprite.color ?? '#e6e8ef';\n ctx.textBaseline = 'top';\n ctx.textAlign = align;\n const xOff = align === 'center' ? maxWPx / 2 : align === 'right' ? maxWPx : 0;\n if (rs?.glyphAlphas) {\n // glyphFade: the contiguous fully-opaque leading run draws as ONE\n // fillText — a single draw forms ligatures and pair kerning exactly\n // like the un-revealed path (pixel parity once fully revealed), and it\n // drops the O(n²) per-frame prefix re-measure for glyphs that have\n // finished fading. Only the fading tail draws glyph-by-glyph, each at\n // its full-line prefix advance. measureText is paint-only (the caret's\n // trick) — positions come from the platform's real glyph widths, never\n // the em table, and depend only on the fixed prefix, so glyphs never\n // shift as they fade.\n ctx.textAlign = 'left';\n const baseAlpha = ctx.globalAlpha;\n for (let li = 0; li < lines.length; li++) {\n const alphas = rs.glyphAlphas[li] ?? [];\n if (alphas.length > 0 && alphas[0]! <= 0) break;\n const clusters = graphemeClusters(lines[li]!.text);\n const lw = ctx.measureText(lines[li]!.text).width;\n const x0 = align === 'center' ? (maxWPx - lw) / 2 : align === 'right' ? maxWPx - lw : 0;\n let opaque = 0;\n while (opaque < clusters.length && (alphas[opaque] ?? 0) >= 1) opaque++;\n let prefix = '';\n if (opaque > 0) {\n prefix = clusters.slice(0, opaque).join('');\n ctx.globalAlpha = baseAlpha;\n ctx.fillText(prefix, x0, li * lh);\n }\n for (let gi = opaque; gi < clusters.length; gi++) {\n const a = alphas[gi] ?? 0;\n if (a <= 0) break; // alphas only fall in reading order\n ctx.globalAlpha = baseAlpha * a;\n ctx.fillText(clusters[gi]!, x0 + ctx.measureText(prefix).width, li * lh);\n prefix += clusters[gi]!;\n }\n }\n ctx.globalAlpha = baseAlpha;\n } else {\n for (let li = 0; li < fullLines; li++) {\n ctx.fillText(lines[li]!.text, xOff, li * lh);\n }\n if (rs && rs.partialText.length > 0) {\n ctx.fillText(rs.partialText, xOff, fullLines * lh);\n }\n }\n if (rs && reveal!.caret) {\n const cfg = reveal!.caret === true ? {} : reveal!.caret;\n const hz = Math.min(3, cfg.blink ?? 1.2);\n const on = hz <= 0 || Math.floor((t / 1000) * hz * 2) % 2 === 0;\n if (on) {\n // measureText is paint-only here: it positions the caret against the\n // platform's real glyph widths but never influences layout, which\n // stays on the fixed metrics table.\n const pw = ctx.measureText(rs.caretPrefix).width;\n const cx = align === 'center' ? xOff + pw / 2 : align === 'right' ? xOff : pw;\n ctx.fillStyle = cfg.color ?? sprite.color ?? '#e6e8ef';\n ctx.fillRect(cx + fsPx * 0.06, rs.caretLine * lh, Math.max(1, fsPx * 0.08), fsPx);\n }\n }\n ctx.restore();\n return;\n }\n ctx.save();\n ctx.translate(p.x, p.y);\n if (rot) ctx.rotate(rot);\n if (p.flip && built.layer.flip) ctx.scale(-1, 1);\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n if (sprite.kind === 'emoji') {\n const idx = spriteIndexAt(e, t, sprite.glyphs.length);\n ctx.font = `${sz}px serif`;\n ctx.fillText(sprite.glyphs[idx] ?? sprite.glyphs[0]!, 0, 0);\n } else {\n ctx.textAlign = sprite.align ?? 'center';\n ctx.textBaseline = sprite.baseline ?? 'middle';\n // A full CSS shorthand (contains a px size) is used verbatim; a family/weight\n // only ('bold monospace') composes with the seeded per-entity size.\n ctx.font = sprite.font\n ? (FONT_PX_RE.test(sprite.font)\n ? scaleFontPx(sprite.font, this.fontScale())\n : composeFontShorthand(sz, sprite.font))\n : `${sz}px system-ui, sans-serif`;\n ctx.fillStyle = sprite.color ?? '#e6e8ef';\n const idx = spriteIndexAt(e, t, sprite.strings.length);\n const text = sprite.strings[idx] ?? sprite.strings[0]!;\n const mw = sprite.maxWidth ? sprite.maxWidth * (this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h)) : undefined;\n if (mw) ctx.fillText(text, 0, 0, mw);\n else ctx.fillText(text, 0, 0);\n }\n ctx.restore();\n }\n\n /** Advance any live steering glide; rebuild entities on structural change. */\n private stepTransition(t: number): void {\n const tr = this.transition;\n if (!tr) return;\n const k = tr.dur <= 0 ? 1 : (t - tr.startT) / tr.dur;\n this.effSpec = k >= 1 ? tr.to : lerpSpec(tr.from, tr.to, easeSmooth(k));\n if (k >= 1) this.transition = null;\n // Placement/motion fields are baked into entities at build time; rebuild\n // (deterministic — same seed → same stream) only when those change.\n const sig = structuralSignature(this.effSpec);\n if (sig !== this.lastStructural) this.rebuild();\n else this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n }\n\n /**\n * Live steering: glide from what's currently rendered to the track's target\n * state (deltas applied last-wins). Duration = the longest delta `dur`.\n */\n applyTrack(track: ControlTrack): void {\n const deltas = (track?.deltas ?? []) as unknown as SteerDelta[];\n const target = applyDeltasToSpec(this.effSpec, deltas);\n if (!validateSpec(target).valid) return;\n const dur = deltas.length\n ? deltas.reduce((m, d) => Math.max(m, d.dur ?? DEFAULT_STEER_DUR), 0)\n : DEFAULT_STEER_DUR;\n this.transition = {\n from: JSON.parse(JSON.stringify(this.effSpec)) as SaverSpec,\n to: target,\n startT: this.lastT,\n dur,\n };\n if (this.paused) {\n // No frames will run the glide — jump straight to the target.\n this.transition = null;\n this.effSpec = target;\n if (structuralSignature(this.effSpec) !== this.lastStructural) this.rebuild();\n else this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n this.renderFrame(this.lastT, this.seed);\n }\n }\n\n /**\n * Apply steering deltas immediately: no glide, no frame painted. Each delta\n * is routed by `applyRetainedDeltas` (unresolvable or invalid ones are\n * skipped on this spec alone). `SequenceInstance` uses this to hand a\n * freshly created child the track the sequence has retained, so a steer\n * made while another segment was active lands on the segment that owns the\n * path. Not painting matters: a child is created inside the parent's\n * renderFrame, and a stray t=0 paint here would make the real frame that\n * follows look \"contiguous\" to the ghosting warm-up — but the constructor\n * already painted ONE stray t=0 frame of the pre-steer spec (SpecInstance's\n * own mount does an immediate render when paused, which every sequence\n * child is), so `lastRenderT` must be reset too: otherwise, with `ghosting`\n * on, the real frame that follows still finds itself \"contiguous\" with\n * that stray paint and composites over it at partial alpha, briefly\n * showing a ghost of the un-steered scene.\n */\n applyDeltasNow(deltas: Iterable<SteerDelta>): void {\n const next = applyRetainedDeltas(this.effSpec, deltas);\n if (next === this.effSpec) return;\n this.transition = null;\n this.lastRenderT = Number.NEGATIVE_INFINITY;\n this.effSpec = next;\n if (structuralSignature(this.effSpec) !== this.lastStructural) this.rebuild();\n else this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n }\n\n private drawLinks(built: Built, t: number, lifeA: number, parentE: Entity | null): void {\n const { links } = built.layer;\n if (!links) return;\n const { ctx } = this;\n // Toroidal link drawing only makes sense for motions that actually wrap —\n // bounce/orbit/path entities never cross an edge, so a \"nearest image\" line\n // would cut across the screen.\n const motionWraps = ['drift', 'rise', 'wander'].includes(built.layer.motion.type);\n const wrap = built.layer.wrap !== false && motionWraps;\n const positions = built.entities.map((e) => this.entityPos(e, t, parentE));\n const maxDistPx = links.maxDist * (this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h));\n const edges = linkEdges(links, positions, maxDistPx, wrap, this.w, this.h);\n const unitScale = this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h);\n const defaultWidth = unitScale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const lw = (links.width ?? defaultWidth) * unitScale;\n ctx.lineWidth = lw;\n ctx.lineCap = 'butt'; // streak sprites set 'round'; reset so link ends stay crisp\n\n for (const { i, j, dist } of edges) {\n const pi = positions[i]!;\n const pj = positions[j]!;\n const ei = built.entities[i]!;\n let resolvedColor = links.color;\n if (!resolvedColor) {\n const sprite = built.layer.sprite;\n if (isShapedSprite(sprite)) {\n resolvedColor = sprite.colors?.[ei.colorIndex] ?? sprite.color;\n } else resolvedColor = '#e6e8ef';\n }\n let a = links.alpha ?? alphaAt(ei, t);\n if (links.falloff) a *= Math.max(0, 1 - dist / maxDistPx);\n ctx.globalAlpha = a * lifeA;\n ctx.strokeStyle = resolvedColor;\n // Draw toward nearest image of pj (avoids full-canvas streaks at wrap seams)\n let dx = pj.x - pi.x;\n let dy = pj.y - pi.y;\n if (wrap) {\n if (Math.abs(dx) > this.w / 2) dx = dx > 0 ? dx - this.w : dx + this.w;\n if (Math.abs(dy) > this.h / 2) dy = dy > 0 ? dy - this.h : dy + this.h;\n }\n ctx.beginPath();\n ctx.moveTo(pi.x, pi.y);\n ctx.lineTo(pi.x + dx, pi.y + dy);\n ctx.stroke();\n }\n }\n\n /** Paint one composite pass at time t. `bgAlpha` < 1 leaves the previous frame\n * showing through — the ghosting smear. */\n private paintFrame(t: number, bgAlpha: number): void {\n const { ctx } = this;\n if (!this.transparent) {\n ctx.globalAlpha = bgAlpha;\n ctx.globalCompositeOperation = 'source-over';\n this.drawBackground(t);\n }\n ctx.globalAlpha = 1;\n for (let li = 0; li < this.layers.length; li++) {\n const built = this.layers[li]!;\n const lifeA = lifeAlphaAt(built.layer.life, t);\n if (lifeA <= 0) continue;\n const parentE = this.parentEntityFor(built);\n ctx.globalCompositeOperation = built.layer.blend ?? 'source-over';\n this.drawLinks(built, t, lifeA, parentE);\n const override = this.paintOverrides?.get(li) ?? null;\n for (const e of built.entities) {\n this.drawTrail(built, e, t, lifeA, parentE);\n if (override === null) {\n this.drawEntity(built, e, t, lifeA, parentE);\n continue;\n }\n // A text cross-fade: the previous words fading out under the new\n // ones fading in. Either pass at alpha 0 is skipped, so k = 0 and\n // k = 1 each cost exactly one draw, like a plain frame.\n if (override.k < 1) this.drawEntity(built, e, t, lifeA, parentE, { sprite: override.outgoing, alpha: 1 - override.k });\n if (override.k > 0) this.drawEntity(built, e, t, lifeA, parentE, { alpha: override.k });\n }\n }\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'source-over';\n }\n\n /**\n * Deterministic, frame-addressable render (shared by the rAF loop).\n *\n * With `ghosting` set, contiguous frames composite over the previous frame with a\n * refresh-rate-normalized fade. A non-contiguous seek (pause render, e2e frame\n * addressing) replays a bounded fixed-step warm-up from a full clear, so the\n * accumulated smear at time t is identical on every run — the determinism proof\n * survives statefulness because the \"state\" is reconstructed from pure history.\n */\n renderFrame(t: number, _seed: number): void {\n this.stepTransition(t);\n const g = this.transparent ? 0 : (this.effSpec.ghosting ?? 0);\n if (g > 0) {\n const dt = 1000 / 60;\n const contiguous = this.lastRenderT !== Number.NEGATIVE_INFINITY\n && t > this.lastRenderT\n && t - this.lastRenderT <= 250;\n if (contiguous) {\n this.paintFrame(t, 1 - Math.pow(g, (t - this.lastRenderT) / dt));\n } else {\n const k = Math.min(Math.ceil(Math.log(1 / 255) / Math.log(g)), LIMITS.maxGhostReplayFrames);\n const t0 = Math.max(0, t - k * dt);\n this.paintFrame(t0, 1);\n for (let ft = t0 + dt; ft < t - dt / 2; ft += dt) this.paintFrame(ft, 1 - g);\n if (t > t0) this.paintFrame(t, 1 - g);\n }\n } else {\n this.paintFrame(t, 1);\n }\n this.lastRenderT = t;\n }\n\n setPaused(paused: boolean): void {\n this.paused = paused;\n if (paused) {\n this.stop();\n } else {\n this.start();\n }\n }\n\n resize(width: number, height: number, dpr?: number): void {\n this.w = width;\n this.h = height;\n if (dpr !== undefined) this.saverCtx.dpr = dpr;\n this.sizeCanvas();\n this.rebuild();\n if (this.paused) this.renderFrame(0, this.seed);\n }\n\n /**\n * Replace the rendered spec without triggering a transition glide.\n * Checks structural signature — use `hotSwapPaint` only when the caller\n * already knows the signature is unchanged.\n */\n hotSwapSpec(spec: SaverSpec): void {\n this.effSpec = spec;\n const sig = structuralSignature(this.effSpec);\n if (sig !== this.lastStructural) this.rebuild();\n else this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n }\n\n /** Paint-only hot-swap: skips structuralSignature (caller guarantees match). */\n hotSwapPaint(spec: SaverSpec): void {\n this.effSpec = spec;\n this.layers.forEach((b, i) => { b.layer = this.effSpec.layers[i] ?? b.layer; });\n }\n\n /**\n * Internal (see `LayerPaintOverride`): draw the listed layers twice —\n * outgoing sprite at `1 − k`, own sprite at `k` — until cleared with\n * `null`. Keyed by layer index. A `SequenceInstance` sets it per morph\n * frame under `text: 'crossfade'`; nothing else does.\n */\n setLayerPaintOverrides(overrides: ReadonlyMap<number, LayerPaintOverride> | null): void {\n this.paintOverrides = overrides && overrides.size > 0 ? overrides : null;\n }\n\n dispose(): void {\n this.stop();\n if (this.ownsCanvas && typeof HTMLCanvasElement !== 'undefined' && this.canvas instanceof HTMLCanvasElement) this.canvas.remove();\n }\n}\n\n/**\n * Compile a declarative spec into a runnable SaverPlugin. Throws if the spec is invalid\n * (so an agent-authored spec is validated before it can run). The result is seeded,\n * deterministic, `renderFrame(t,seed)`-addressable, and flash-safe by construction.\n */\nexport function compileSaver(spec: unknown): SaverPlugin {\n const valid = assertValidSpec(spec);\n return {\n manifest: manifestFor(valid),\n mount: (ctx: SaverContext) => new SpecInstance(valid, ctx),\n spec: valid,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Sequence — multi-segment timeline compiled as a single SaverPlugin\n// ---------------------------------------------------------------------------\n\n/**\n * Mount context for a compiled sequence. A plain `SaverContext` works — the\n * clock starts at 0, as every SaverPlugin's does. `sequenceBaseT` is read\n * only when the sequence declares `sync: 'epoch'`; hosts pass the shared\n * clock's elapsed ms (idlescreens.com: `Date.now() − scene.epoch`) so every\n * viewer of that sequence resolves the same segment.\n */\nexport interface SequenceMountContext extends SaverContext {\n /** ms already elapsed on the shared sequence clock. Ignored unless `sync: 'epoch'`. */\n sequenceBaseT?: number;\n /**\n * The device's compute tier (`computeTier` from `@idle-screens/capabilities`;\n * the string union is repeated here so schema does not depend on that\n * package). A `fade` transition keeps two segments live for `dur`, which\n * `basic` (canvas2d only) and `minimal` cannot afford: on those tiers fade\n * renders as `cut`. Absent ⇒ fade enabled.\n */\n capabilityTier?: 'minimal' | 'basic' | 'standard' | 'high';\n}\n\n/** A segment child on a canvas of its own, composited onto the shared surface during a `fade`. */\ninterface OffscreenChild {\n index: number;\n child: SpecInstance;\n canvas: HTMLCanvasElement | OffscreenCanvas;\n}\n\n/** `bed.<path>` routes a steer to the sequence's bed when one exists. */\nconst BED_PREFIX = 'bed.';\n\nclass SequenceInstance implements SaverInstance {\n private readonly seq: IdleSequence;\n private readonly childCtx: SaverContext;\n private readonly canvas: HTMLCanvasElement | null;\n private readonly children: (SpecInstance | null)[];\n private activeIndex = -1;\n private paused = false;\n /**\n * When a morph is active, the child at `morphFromIndex` renders with a\n * lerped spec. The child stays keyed to the *outgoing* segment's slot so\n * its seed (and entity placement) is continuous.\n */\n private morphFromIndex = -1;\n private readonly seed: number;\n private frameId: number | null = null;\n private startT = 0;\n private baseT = 0;\n private lastT = 0;\n /** The T most recently passed to renderFrame — the clock a steer displaces. */\n private renderedT = 0;\n /**\n * The clicker's two pieces of state. `clockOffset` is added to every T so\n * a `sequence.segment` steer lands the timeline at the target segment's\n * start and STAYS there as the wall clock keeps ticking — the steer moves\n * the clock instead of fighting it. `releasedBelow` records that the steer\n * counts as the presenter clicking past every `advance: 'input'` hold\n * before the target (see `resolveSegment`).\n */\n private clockOffset = 0;\n private releasedBelow = 0;\n /**\n * Set by a `sequence.segment` steer that targets segment 0 under `loop:\n * true`: the steer resets the clock to segment 0's own start (localT 0),\n * so `renderFrame`'s wrap check (which compares the raw, ever-increasing\n * clock against `timedTotal()`) can no longer recognize the jump as a\n * wrap. This flag lets the clicker's jump to 0 still count as one, so the\n * last segment's fade plays instead of a hard cut. Cleared once the wrap\n * window (if any) has passed.\n */\n private pendingWrapFade = false;\n /**\n * Every non-`sequence.segment` delta this instance has been handed, last\n * wins per path, merged across `applyTrack` calls. Children are created\n * lazily and disposed on every segment switch, so a steer forwarded only\n * to the active child would evaporate at the next boundary — and a steer\n * to a path only a *later* segment owns (`bars.sprite.values` while the title\n * slide is up) would land nowhere. Re-applied to every child on creation\n * and folded into the morph endpoints; each child keeps the deltas that\n * resolve on it (see `applyRetainedDeltas`).\n */\n private readonly retainedDeltas = new Map<string, SteerDelta>();\n /** The outgoing segment while a `fade` runs; null otherwise. */\n private fading: OffscreenChild | null = null;\n /**\n * The incoming segment while a `fade` runs over a `bed`. Children over a\n * bed are transparent, so a cross-fade needs both of them on canvases of\n * their own — the incoming composited at k, the outgoing at 1 − k. Without\n * a bed the incoming paints its own opaque ground on the shared surface and\n * this stays null.\n */\n private fadingIn: OffscreenChild | null = null;\n /** False on the `basic`/`minimal` capability tiers — fade renders as cut. */\n private readonly fadeEnabled: boolean;\n /**\n * The sequence's `bed`: one scene on the shared surface, drawn first every\n * frame at the sequence clock — WITHOUT `clockOffset`, so a\n * `sequence.segment` steer rewinds the segment and never the bed — and never\n * re-created. Segments render over it transparently. Null when absent.\n */\n private readonly bed: SpecInstance | null;\n\n constructor(seq: IdleSequence, ctx: SequenceMountContext) {\n this.seq = seq;\n const { sequenceBaseT, capabilityTier, ...plainCtx } = ctx;\n this.fadeEnabled = capabilityTier !== 'basic' && capabilityTier !== 'minimal';\n // `sync: 'epoch'`: seed the clock from the host's shared time, the same\n // way `baseT` carries SpecInstance's clock across pause/resume — the first\n // frame renders at `baseT`, not 0. Absent/`mount` ignores the hint and T\n // starts at 0 exactly as before the field existed. Holds are untouched:\n // `releasedBelow` stays 0, so a late joiner whose clock is past an\n // unreleased `advance: 'input'` hold lands ON the held segment.\n if (seq.sync === 'epoch' && typeof sequenceBaseT === 'number' && Number.isFinite(sequenceBaseT)) {\n this.baseT = Math.max(0, sequenceBaseT);\n this.lastT = this.baseT;\n this.renderedT = this.baseT;\n }\n\n let surface = ctx.surface ?? null;\n let canvas: HTMLCanvasElement | null = null;\n if (!surface && typeof document !== 'undefined') {\n canvas = document.createElement('canvas');\n canvas.style.cssText = 'display:block;width:100%;height:100%';\n canvas.setAttribute('aria-hidden', 'true');\n ctx.host.appendChild(canvas);\n surface = canvas;\n }\n this.canvas = canvas;\n\n // Prefer the sequence's own seed (same precedence SpecInstance uses for\n // scene.seed ?? ctx.seed). Children still resolve per-segment via childSeed.\n this.seed = ((seq.seed ?? ctx.seed ?? 0) >>> 0) || 1;\n // Children are always parent-driven: reducedMotion:true keeps SpecInstance\n // from starting its own rAF. SequenceInstance.loop is the only clock.\n this.childCtx = { ...plainCtx, surface: surface!, reducedMotion: true };\n this.children = new Array(seq.segments.length).fill(null) as (SpecInstance | null)[];\n if (seq.bed) {\n this.bed = new SpecInstance(this.bedScene(seq.bed), this.childCtx);\n this.bed.setPaused(true);\n } else {\n this.bed = null;\n }\n this.paused = ctx.reducedMotion;\n if (this.paused) this.renderFrame(this.baseT, this.seed);\n else this.start();\n }\n\n private childSeed(index: number, fallback: number): number {\n return this.seq.segments[index]!.scene.seed ?? this.seq.seed ?? fallback;\n }\n\n /**\n * The bed's seed follows the segment rule (own seed, else the sequence seed)\n * but offset by `maxSegments`, past every segment's `seed + index`, so a bed\n * and segment 0 never share an entity stream and adding a segment does not\n * re-seat the bed.\n */\n private bedScene(bed: SaverSpec): SaverSpec {\n if (bed.seed != null) return bed;\n if (this.seq.seed != null) return { ...bed, seed: this.seq.seed + LIMITS.maxSegments };\n return bed;\n }\n\n private childScene(index: number): SaverSpec {\n const seg = this.seq.segments[index]!;\n if (seg.scene.seed != null) return seg.scene;\n if (this.seq.seed != null) return { ...seg.scene, seed: this.seq.seed + index };\n return seg.scene;\n }\n\n /** Whether the boundary from `from` to `from+1` should morph. */\n private canMorph(from: number): boolean {\n return canMorph(this.seq, from);\n }\n\n /** Walk back through consecutive morph boundaries to find the chain origin. */\n private morphChainRoot(index: number): number {\n return morphChainRoot(this.seq, index);\n }\n\n private morphDur(from: number): number {\n const tr = this.seq.segments[from]?.transition;\n return tr?.type === 'morph' ? tr.dur : 0;\n }\n\n /** Whether the morph out of `from` cross-fades its text (default `step`: strings switch at k > 0). */\n private morphTextCrossfades(from: number): boolean {\n const tr = this.seq.segments[from]?.transition;\n return tr?.type === 'morph' && tr.text === 'crossfade';\n }\n\n /**\n * The paint overrides for one crossfade frame: every text layer whose\n * words differ between the outgoing and incoming specs, painting the\n * outgoing words (in the lerped frame's paint — colour and alpha glide as\n * usual) at `1 − k` under the incoming at `k`. Null when nothing differs,\n * so a crossfade between same-worded twins is a plain morph frame.\n */\n private crossfadeOverrides(specA: SaverSpec, specB: SaverSpec, lerped: SaverSpec, k: number): Map<number, LayerPaintOverride> | null {\n let map: Map<number, LayerPaintOverride> | null = null;\n for (let i = 0; i < lerped.layers.length; i++) {\n if (!textStringsDiffer(specA, specB, i)) continue;\n const from = specA.layers[i]!.sprite;\n const now = lerped.layers[i]!.sprite;\n const outgoing: SpriteSpec = from.kind === 'text' && now.kind === 'text'\n ? { ...now, strings: from.strings }\n : from.kind === 'textBlock' && now.kind === 'textBlock'\n ? { ...now, text: from.text }\n : now;\n if (outgoing === now) continue;\n (map ??= new Map()).set(i, { outgoing, k });\n }\n return map;\n }\n\n /** Length of the fade out of segment `from`, or 0 (no fade, or a tier that plays it as cut). */\n private fadeDur(from: number): number {\n const tr = this.seq.segments[from]?.transition;\n return this.fadeEnabled && tr?.type === 'fade' ? tr.dur : 0;\n }\n\n /** Sum of every timed segment — the lap length under `loop: true`. */\n private timedTotal(): number {\n const last = this.seq.segments.length - 1;\n return segmentStart(this.seq, last) + (this.seq.segments[last]!.duration ?? 0);\n }\n\n private releaseFading(): void {\n if (this.fading) {\n this.fading.child.dispose();\n this.fading = null;\n }\n if (this.fadingIn) {\n this.fadingIn.child.dispose();\n this.fadingIn = null;\n }\n }\n\n /**\n * A segment child on a canvas of its own. Like a morph it mounts on its\n * chain root's scene and seed (so its entities are the ones the viewer was\n * watching) and hot-swaps to the segment's spec; the retained track is\n * applied last. Transparent over a bed, opaque otherwise.\n */\n private offscreenChild(index: number, root: number): OffscreenChild {\n const canvas: HTMLCanvasElement | OffscreenCanvas = typeof document !== 'undefined'\n ? document.createElement('canvas')\n : new OffscreenCanvas(Math.max(1, this.childCtx.width), Math.max(1, this.childCtx.height));\n const child = new SpecInstance(this.childScene(root), { ...this.childCtx, surface: canvas }, { transparent: this.bed !== null });\n child.setPaused(true);\n if (root !== index) child.hotSwapSpec(this.childScene(index));\n if (this.retainedDeltas.size > 0) child.applyDeltasNow(this.retainedDeltas.values());\n return { index, child, canvas };\n }\n\n /** Render an offscreen child; a transparent one never clears, so its owner does here. */\n private renderOffscreen(oc: OffscreenChild, t: number, seed: number): void {\n if (this.bed) {\n const c = oc.canvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;\n c?.clearRect(0, 0, this.childCtx.width, this.childCtx.height);\n }\n oc.child.renderFrame(t, seed);\n }\n\n /** Draw an offscreen canvas onto the shared surface at `alpha`. */\n private composite(canvas: HTMLCanvasElement | OffscreenCanvas, alpha: number): void {\n const main = this.childCtx.surface?.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null | undefined;\n if (!main) return;\n main.save();\n main.globalAlpha = alpha;\n main.globalCompositeOperation = 'source-over';\n main.drawImage(canvas, 0, 0, this.childCtx.width, this.childCtx.height);\n main.restore();\n }\n\n /**\n * Render the outgoing segment `from` of a live fade onto its own canvas. It\n * keeps animating at `duration(from) + localT` (it does not freeze — and if\n * it was an `advance: 'input'` hold it resumes from its duration, not from\n * wherever the hold had reached). Two live segments for `dur` only; the\n * outgoing one is disposed when the fade ends.\n */\n private renderOutgoing(from: number, localT: number, seed: number): OffscreenChild {\n if (this.fading && this.fading.index !== from) {\n this.fading.child.dispose();\n this.fading = null;\n }\n if (!this.fading) this.fading = this.offscreenChild(from, this.morphChainRoot(from));\n const outDur = this.seq.segments[from]!.duration ?? 0;\n this.renderOffscreen(this.fading, outDur + localT, this.childSeed(this.morphChainRoot(from), seed));\n return this.fading;\n }\n\n /** A segment's scene with the retained track applied — `scene` itself when nothing resolves on it. */\n private steeredScene(scene: SaverSpec): SaverSpec {\n return this.retainedDeltas.size === 0 ? scene : applyRetainedDeltas(scene, this.retainedDeltas.values());\n }\n\n /**\n * The child for segment `index`, created paused on the shared surface if\n * the slot is empty. `rootScene` (a morph chain's root) mounts the child\n * with the root's scene so its seed and entity placement are continuous\n * with the chain, then hot-swaps to the segment's own spec. Either way the\n * retained track is applied last, so a steer made while another segment\n * was up is already in effect on this child's first frame. `skipInitialPaint`\n * is for a caller (the morph branch) that is about to render a real frame,\n * paint overrides included, in this same call — see `SpecInstanceOptions`.\n */\n private ensureChild(index: number, rootScene?: SaverSpec, skipInitialPaint?: boolean): SpecInstance {\n if (index < 0 || index >= this.seq.segments.length) index = 0;\n let child = this.children[index];\n if (!child) {\n child = new SpecInstance(rootScene ?? this.childScene(index), this.childCtx, { transparent: this.bed !== null, skipInitialPaint });\n this.children[index] = child;\n // Belt-and-suspenders: never let a child self-drive, even if childCtx\n // reducedMotion is ever relaxed.\n child.setPaused(true);\n if (rootScene) child.hotSwapSpec(this.childScene(index));\n if (this.retainedDeltas.size > 0) child.applyDeltasNow(this.retainedDeltas.values());\n }\n return child;\n }\n\n private releaseChild(index: number): void {\n const child = this.children[index];\n if (child) {\n child.dispose();\n this.children[index] = null;\n }\n }\n\n private start(): void {\n if (this.frameId !== null || typeof requestAnimationFrame === 'undefined') return;\n this.startT = 0;\n this.frameId = requestAnimationFrame((now) => this.loop(now));\n }\n\n private stop(): void {\n if (this.frameId !== null) {\n cancelAnimationFrame(this.frameId);\n this.frameId = null;\n }\n this.baseT = this.lastT;\n }\n\n private loop(now: number): void {\n this.frameId = requestAnimationFrame((n) => this.loop(n));\n if (this.startT === 0) this.startT = now;\n this.lastT = now - this.startT + this.baseT;\n this.renderFrame(this.lastT, this.seed);\n }\n\n renderFrame(T: number, seed: number): void {\n this.renderedT = T;\n const resolved = resolveSegment(this.seq, T + this.clockOffset, { releasedBelow: this.releasedBelow });\n const { index, localT } = resolved;\n\n // The bed is the ground: painted first, on the global clock. `T` here is\n // the sequence clock before `clockOffset`, so the clicker never rewinds it.\n this.bed?.renderFrame(T, this.seq.bed?.seed ?? this.seq.seed ?? seed);\n\n // Check if the *previous* segment has a morph into this one\n const prevIdx = index > 0 ? index - 1 : -1;\n const morphActive = prevIdx >= 0\n && this.canMorph(prevIdx)\n && localT < this.morphDur(prevIdx);\n\n // A fade comes from the previous segment in the list — or, under\n // `loop: true`, from the last segment when the lap wraps to 0, so the\n // last segment's `fade` is the wrap's transition. Cut and morph paths\n // are untouched: fadeDur is 0 for them.\n const lastIdx = this.seq.segments.length - 1;\n const wrapped = this.seq.loop && index === 0 && lastIdx > 0\n && (T + this.clockOffset >= this.timedTotal() || this.pendingWrapFade);\n const fadeFrom = prevIdx >= 0 ? prevIdx : wrapped ? lastIdx : -1;\n const fadeActive = fadeFrom >= 0 && localT < this.fadeDur(fadeFrom);\n if (!fadeActive && this.fading) this.releaseFading();\n // The flag only needs to survive the frames still inside the wrap fade\n // window; once that ends (or the clock moves off segment 0) it has done\n // its job.\n if (this.pendingWrapFade && (index !== 0 || !fadeActive)) this.pendingWrapFade = false;\n\n if (morphActive) {\n // Morph in progress: keep the child keyed to the chain root\n // (preserves its seed/entity placement through chained morphs).\n const chainRoot = this.morphChainRoot(index);\n this.morphFromIndex = prevIdx;\n this.activeIndex = index;\n\n // Release all children except the chain root's slot\n for (let i = 0; i < this.children.length; i++) {\n if (i !== chainRoot) this.releaseChild(i);\n }\n\n // A fresh mount here is about to be repainted for real a few lines\n // down (hotSwapPaint + overrides + renderFrame) within this same call.\n // Only `text: 'crossfade'` needs the constructor's own paint skipped —\n // its partial-alpha passes would otherwise composite over a stray\n // full-opacity frame underneath; `step` (the common case) is left to\n // paint at construction as it always has, so a fresh mount's ghosting\n // contiguity (`lastRenderT`) is unaffected.\n const child = this.ensureChild(chainRoot, undefined, this.morphTextCrossfades(prevIdx));\n const dur = this.morphDur(prevIdx);\n const k = easeSmooth(localT / dur);\n // The lerp endpoints carry the retained track, so without this a\n // steered colour would vanish for `dur` and snap back when the morph\n // finalises. `canMorph` only guarantees specA/specB share structure\n // BEFORE the retained set is applied — a structural delta (`layers.0.\n // count`, a motion change) could validate on one endpoint and not the\n // other, or change both identically but differ from what this child\n // was last built with. hotSwapSpec (not hotSwapPaint) re-checks the\n // signature every frame and rebuilds when it moved, so a structural\n // steer actually takes effect instead of leaving stale entities.\n const specA = this.steeredScene(this.childScene(prevIdx));\n const specB = this.steeredScene(this.childScene(index));\n const lerped = lerpSpec(specA, specB, k);\n child.hotSwapSpec(lerped);\n // Default (`step`): no overrides, the frame is what it always was —\n // strings already switched inside `lerped` at k > 0.\n child.setLayerPaintOverrides(this.morphTextCrossfades(prevIdx) ? this.crossfadeOverrides(specA, specB, lerped, k) : null);\n child.renderFrame(localT, this.childSeed(chainRoot, seed));\n } else {\n // No morph (or morph complete). If we were morphing, finalize.\n if (this.morphFromIndex >= 0) {\n // Morph just completed — release the chain-root child.\n const oldRoot = this.morphChainRoot(this.morphFromIndex);\n this.releaseChild(oldRoot);\n if (oldRoot !== this.morphFromIndex) this.releaseChild(this.morphFromIndex);\n this.morphFromIndex = -1;\n }\n\n if (index !== this.activeIndex) {\n for (let i = 0; i < this.children.length; i++) {\n if (i !== index) this.releaseChild(i);\n }\n this.activeIndex = index;\n }\n\n // Determine the effective seed: if this segment was reached via a\n // morph chain, use the chain-root's seed so entity placement is\n // continuous across all morphed segments and seeks match playthrough.\n const chainRoot = this.morphChainRoot(index);\n const useMorphSeed = chainRoot < index;\n const effSeed = useMorphSeed ? this.childSeed(chainRoot, seed) : this.childSeed(index, seed);\n\n if (fadeActive && this.bed) {\n // Over a bed both segments are transparent ink, so both go to canvases\n // of their own: incoming at k, outgoing over it at 1 − k. The incoming\n // moves to the shared surface (via ensureChild) once the fade ends.\n const k = easeSmooth(localT / this.fadeDur(fadeFrom));\n if (this.fadingIn && this.fadingIn.index !== index) {\n this.fadingIn.child.dispose();\n this.fadingIn = null;\n }\n if (!this.fadingIn) this.fadingIn = this.offscreenChild(index, useMorphSeed ? chainRoot : index);\n this.renderOffscreen(this.fadingIn, localT, effSeed);\n const out = this.renderOutgoing(fadeFrom, localT, seed);\n this.composite(this.fadingIn.canvas, k);\n this.composite(out.canvas, 1 - k);\n return;\n }\n\n // If using morph seed, mount the child with the chain root's scene+seed\n // but immediately hot-swap to the current segment's spec.\n const child = useMorphSeed ? this.ensureChild(index, this.childScene(chainRoot)) : this.ensureChild(index);\n child.renderFrame(localT, effSeed);\n if (fadeActive) {\n // The outgoing segment on its own canvas over the incoming frame at\n // 1 − easeSmooth(k): the incoming's opaque ground fades in beneath it.\n const out = this.renderOutgoing(fadeFrom, localT, seed);\n this.composite(out.canvas, 1 - easeSmooth(localT / this.fadeDur(fadeFrom)));\n }\n }\n }\n\n setPaused(paused: boolean): void {\n this.paused = paused;\n if (paused) this.stop();\n else this.start();\n // Do NOT forward pause=false to children — that would start SpecInstance\n // rAF loops alongside SequenceInstance.loop (double clock, wrong localT).\n // Children stay paused; the parent loop is the sole driver.\n for (const child of this.children) {\n child?.setPaused(true);\n }\n this.fading?.child.setPaused(true);\n this.fadingIn?.child.setPaused(true);\n this.bed?.setPaused(true);\n }\n\n resize(width: number, height: number, dpr?: number): void {\n // Children are created lazily (first rAF tick, segment switches, morph\n // finalization), so the new size must outlive the children that exist right\n // now. Without this, a resize while a slot is empty is forgotten and the\n // next child mounts at the stale mount-time size — a viewer that mounted\n // in a hidden/unpainted tab (width 0) stays a 1×1 canvas forever, and a\n // segment cut after any resize snaps back to the old dimensions.\n this.childCtx.width = width;\n this.childCtx.height = height;\n if (dpr !== undefined) this.childCtx.dpr = dpr;\n for (const child of this.children) {\n child?.resize(width, height, dpr);\n }\n this.fading?.child.resize(width, height, dpr);\n this.fadingIn?.child.resize(width, height, dpr);\n this.bed?.resize(width, height, dpr);\n }\n\n applyTrack(track: ControlTrack): void {\n const all = (track?.deltas ?? []) as unknown as SteerDelta[];\n // `bed.<path>` goes to the bed with the prefix stripped — only when a bed\n // exists; otherwise the path reaches the segments as today (a layer keyed\n // `bed` keeps working).\n const isBedPath = (d: SteerDelta): boolean => this.bed !== null && typeof d.path === 'string' && d.path.startsWith(BED_PREFIX);\n const bedDeltas = all.filter(isBedPath).map((d) => ({ ...d, path: d.path.slice(BED_PREFIX.length) }));\n if (bedDeltas.length > 0) this.bed!.applyTrack({ ...track, deltas: bedDeltas as unknown as ParamDelta[] });\n const deltas = all.filter((d) => !isBedPath(d));\n // Retain first: a `sequence.segment` steer in the same track creates the\n // target child inside renderFrame below, and it must see these deltas.\n for (const d of deltas) {\n if (d.path !== 'sequence.segment' && typeof d.path === 'string') this.retainedDeltas.set(d.path, d);\n }\n const segDelta = deltas.find((d) => d.path === 'sequence.segment');\n let switchedSegment = false;\n if (segDelta !== undefined && typeof segDelta.value === 'number') {\n const idx = Math.max(0, Math.min(this.seq.segments.length - 1, Math.round(segDelta.value as number)));\n // A steer to segment 0 under loop is the clicker doing the same jump\n // the wall clock does on a natural lap wrap — it should trigger the\n // last segment's fade the same way (see `pendingWrapFade`).\n this.pendingWrapFade = this.seq.loop && idx === 0 && this.seq.segments.length > 1;\n // Displace the clock so T + offset == the target segment's start: the\n // segment begins at localT 0 (its `life.enter` build replays) and the\n // next animation frame resolves to the same segment instead of snapping\n // back to whatever the wall clock said. The steer also releases every\n // `advance: 'input'` hold before the target; holds at and after it stay\n // armed, so steering backwards re-arms the ones in between.\n this.clockOffset = segmentStart(this.seq, idx) - this.renderedT;\n this.releasedBelow = idx;\n this.renderFrame(this.renderedT, this.seed);\n switchedSegment = true;\n }\n\n const childDeltas = deltas.filter((d) => d.path !== 'sequence.segment');\n if (childDeltas.length > 0) {\n if (this.morphFromIndex >= 0) {\n // Mid-morph, the rendered child lives at the chain-root slot, not\n // `children[activeIndex]` — forwarding a child.applyTrack() there\n // would silently no-op AND get overwritten by the morph's own\n // hotSwapSpec on the very next frame regardless, so a transition\n // glide on this path can't coexist with the morph's own cross-fade.\n // The delta is already retained above, so a re-render is all that's\n // needed to reach it via steeredScene: it takes effect this frame,\n // immediately rather than gliding over its own `dur`. Skip only when\n // the segDelta branch above already re-rendered with these deltas\n // retained.\n if (!switchedSegment) this.renderFrame(this.renderedT, this.seed);\n } else if (this.activeIndex >= 0) {\n // Not mid-morph: the active child still gets the track directly, as\n // before retention — a steer to a path it owns glides on this call\n // rather than snapping at the next boundary.\n const child = this.children[this.activeIndex];\n child?.applyTrack({ ...track, deltas: childDeltas as unknown as ParamDelta[] });\n }\n // The outgoing segment during a fade — and, over a bed, the incoming\n // one too, since both are standalone offscreen SpecInstances, not\n // `this.children` — would otherwise freeze at whatever they last\n // rendered instead of picking up a mid-fade steer like the active\n // child does. Independent of the morph/active branching above: fade\n // and morph are mutually exclusive per-frame states.\n this.fading?.child.applyTrack({ ...track, deltas: childDeltas as unknown as ParamDelta[] });\n this.fadingIn?.child.applyTrack({ ...track, deltas: childDeltas as unknown as ParamDelta[] });\n }\n }\n\n dispose(): void {\n this.stop();\n this.releaseFading();\n for (let i = 0; i < this.children.length; i++) {\n this.releaseChild(i);\n }\n this.bed?.dispose();\n if (this.canvas) this.canvas.remove();\n }\n}\n\nfunction sequenceManifest(seq: IdleSequence): SaverManifest {\n const maxSegment = seq.segments.reduce((max, s) => {\n const t = s.scene.layers.reduce((n, l) => n + l.count, 0);\n return Math.max(max, t);\n }, 0);\n // A bed is live alongside whichever segment is up, so it costs on top of the largest.\n const bedTotal = seq.bed ? seq.bed.layers.reduce((n, l) => n + l.count, 0) : 0;\n const maxTotal = bedTotal + maxSegment;\n const costTier = maxTotal < 30 ? 'idle' : maxTotal < 150 ? 'low' : maxTotal < 400 ? 'medium' : 'high';\n return {\n id: seq.id,\n label: seq.label,\n timeModel: 'closed-form',\n passthrough: false,\n minBackend: 'canvas2d',\n costTier,\n motionIntensity: 'moderate',\n reducedMotionFallback: 'static',\n a11y: { flashSafe: true },\n workerReady: false,\n };\n}\n\nexport function compileSequence(spec: unknown): SaverPlugin {\n const valid = assertValidSequence(spec);\n return {\n manifest: sequenceManifest(valid),\n mount: (ctx: SaverContext) => new SequenceInstance(valid, ctx),\n spec: valid,\n };\n}\n","import { structuralSignature } from './steer';\nimport { LIMITS, type IdleSequence } from './types';\n\nexport interface ResolvedSegment {\n index: number;\n localT: number;\n /** Cumulative start time of this segment in the global timeline. */\n startT: number;\n /**\n * Present (true) when the timeline has run past this segment's duration but\n * the segment has `advance: 'input'` and no input has released it yet — the\n * scene keeps animating (`localT` keeps growing) while the show waits for\n * the presenter.\n */\n held?: true;\n}\n\nexport interface ResolveOptions {\n /**\n * Segments below this index have been released by input: a `sequence.segment`\n * steer to index `n` counts as the presenter clicking past every hold before\n * `n`. `SequenceInstance` maintains this; callers resolving a bare timeline\n * leave it at 0, so every `advance: 'input'` hold is honoured.\n */\n releasedBelow?: number;\n}\n\n/** Global start time of segment `index` — the prefix sum of the durations before it. */\nexport function segmentStart(seq: IdleSequence, index: number): number {\n let t = 0;\n const n = Math.max(0, Math.min(index, seq.segments.length - 1));\n for (let i = 0; i < n; i++) t += seq.segments[i]!.duration ?? 0;\n return t;\n}\n\n/**\n * Map global time T to (segmentIndex, localT) via prefix sums of durations.\n * Segments are half-open: [start, start+duration). The final segment may omit\n * duration, in which case it holds indefinitely (T past the last timed segment\n * always resolves to the final one).\n *\n * `advance: 'input'` makes a timed segment hold at its end instead of yielding\n * to the next one — the clicker. `auto` (default) and `either` advance on the\n * timer. A hold is released by a `sequence.segment` steer (see\n * `ResolveOptions.releasedBelow`); the held scene keeps its clock running, so\n * `localT` grows past `duration` rather than freezing.\n *\n * With `loop: true`, T wraps modulo the total duration of all segments — but\n * only once every hold on the current lap has been released; after a wrap\n * every hold is armed again. If the final segment has no duration, looping is\n * over the timed prefix only — the durationless tail is unreachable in loop\n * mode (validated elsewhere).\n */\nexport function resolveSegment(seq: IdleSequence, T: number, opts: ResolveOptions = {}): ResolvedSegment {\n const { segments, loop } = seq;\n if (segments.length === 0) return { index: 0, localT: 0, startT: 0 };\n\n let totalTimed = 0;\n for (const seg of segments) {\n if (seg.duration != null) totalTimed += seg.duration;\n else break;\n }\n\n const t0 = Math.max(0, T);\n\n // Walk the timed prefix once; null means the clock ran off the end.\n const walk = (t: number, releasedBelow: number): ResolvedSegment | null => {\n let cumulative = 0;\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i]!;\n if (seg.duration == null) {\n // A durationless tail holds forever — except in loop mode, where it\n // is unreachable and the clock wraps instead.\n return loop ? null : { index: i, localT: t - cumulative, startT: cumulative };\n }\n if (t < cumulative + seg.duration) {\n return { index: i, localT: t - cumulative, startT: cumulative };\n }\n if (seg.advance === 'input' && i >= releasedBelow) {\n return { index: i, localT: t - cumulative, startT: cumulative, held: true };\n }\n cumulative += seg.duration;\n }\n return null;\n };\n\n const first = walk(t0, opts.releasedBelow ?? 0);\n if (first) return first;\n\n if (loop && totalTimed > 0) {\n // A fresh lap, with every hold armed again. Always modulo: subtracting\n // one lap (`t0 - totalTimed`) leaves later laps (T ≥ 2×totalTimed) still\n // past the end of the loop, so a released clock lands on the last hold\n // with a growing localT instead of wrapping.\n const wrapped = walk(t0 % totalTimed, 0);\n if (wrapped) return wrapped;\n }\n\n const last = segments.length - 1;\n const lastStart = totalTimed - (segments[last]!.duration ?? 0);\n return { index: last, localT: t0 - lastStart, startT: lastStart };\n}\n\n// ---------------------------------------------------------------------------\n// Render seeds — shared by SequenceInstance (compile.ts) and\n// perceiveSequenceFrame (perceive.ts), so both derive the same seed from the\n// same sequence. Kept in one place after two review rounds found the\n// perception side had drifted from the renderer's exact derivation.\n// ---------------------------------------------------------------------------\n\n/** Whether the boundary from `from` to `from + 1` morphs: same scene structure, `morph` transition. */\nexport function canMorph(seq: IdleSequence, from: number): boolean {\n const seg = seq.segments[from];\n if (!seg || seg.transition?.type !== 'morph') return false;\n const next = seq.segments[from + 1];\n if (!next) return false;\n return structuralSignature(seg.scene) === structuralSignature(next.scene);\n}\n\n/**\n * Walk back through consecutive `morph` boundaries to the chain's origin. A\n * morph-chained segment's entities are never re-seeded at the boundary —\n * they're the same stream continued from wherever the chain started — so its\n * actual render seed (see `segmentRenderSeed`) is always the chain root's,\n * never its own index's.\n */\nexport function morphChainRoot(seq: IdleSequence, index: number): number {\n let i = index;\n while (i > 0 && canMorph(seq, i - 1)) i--;\n return i;\n}\n\n/** `SpecInstance`'s seed normalization: 0 is falsy, so a valid `seed: 0` lands on 1. */\nexport function normalizeSeed(seed: number): number {\n return (seed >>> 0) || 1;\n}\n\n/**\n * The seed segment `index`'s entities actually render with — its chain\n * root's own seed, else `seq.seed + ` the chain root's index, normalized\n * exactly like `SpecInstance`. `undefined` when neither is set: the same\n * \"unknowable ahead of time\" case a bare `SaverSpec` has via `ctx.seed`,\n * which callers fall back to their own default for (as `perceiveScene` does).\n */\nexport function segmentRenderSeed(seq: IdleSequence, index: number): number | undefined {\n const root = morphChainRoot(seq, index);\n const scene = seq.segments[root]?.scene;\n if (!scene) return undefined;\n const raw = scene.seed ?? (seq.seed !== undefined ? seq.seed + root : undefined);\n return raw === undefined ? undefined : normalizeSeed(raw);\n}\n\n/**\n * The seed the bed's entities actually render with — its own seed, else\n * `seq.seed + LIMITS.maxSegments` (past every segment's `seq.seed + index`,\n * so a bed and segment 0 never share a stream), normalized like\n * `SpecInstance`. `undefined` when there's no bed or no derivable seed.\n */\nexport function bedRenderSeed(seq: IdleSequence): number | undefined {\n if (!seq.bed) return undefined;\n const raw = seq.bed.seed ?? (seq.seed !== undefined ? seq.seed + LIMITS.maxSegments : undefined);\n return raw === undefined ? undefined : normalizeSeed(raw);\n}\n","import { createRng } from '@idle-screens/core';\nimport { additivePlate, backgroundLuma, backgroundRgb, backgroundRgbAt, colourSeparation, hexLuma, hexRgb, legibilityRatio, relativeLuminance, sourceOverPlate, spriteHex, type Rgb } from './luma';\nimport { COHESION_T, cohesionOf, seamsWorthWarning } from './cohesion';\nimport { barFraction } from './shapes';\nimport { breakTextBlock, buildEntities, linkEdges, linkPairs, positionAt, textBlockAnchorOffset, textMetricsClassFor, textWidthEm, WARP_MAX_SCALE, type Entity } from './simulate';\nimport { morphNothingMorphable, structuralSignature } from './steer';\nimport { LIMITS, type IdleSequence, type LayerSpec, type SaverSpec, type SpecWarning, type WarningBox } from './types';\n\n/**\n * Minimum RGB-space colour distance (see `colourSeparation`) between a layer\n * and its background before the layer stops reading as a distinct thing.\n *\n * Calibrated against real specs rather than picked: a layer painted the literal\n * background hex measures 0.000, a near-background dark-on-dark layer ~0.036,\n * while every one of the 15 shipped examples and all 150 style-eval screens\n * clear it except the genuinely-flawed ones. Note this is a *colour* distance —\n * a Seurat-style gold-on-grey field separates by 0.39 here but only 0.013 in\n * luma, which is exactly why the measure is not luminance-based.\n */\nconst LOW_CONTRAST_FLOOR = 0.05;\n\n/**\n * A spec that declares `density: 'sparse'` is promising a mostly-empty frame.\n * Above this alpha-weighted coverage the promise is broken (2 % of the frame\n * is a comfortable field, not restraint — `lanterns` measures ~1.5 %).\n */\nconst SPARSE_DECLARED_MAX_COVERAGE = 0.02;\n\n/**\n * WCAG AA floor for body text. Only layers that declare `role: 'read'` are\n * measured against it — atmospheric text is texture, not copy, and the\n * shipped examples paint it at 2–3:1 on purpose.\n */\nconst READ_LEGIBILITY_FLOOR = 4.5;\n\n/** A `role: 'read'` box closer than this to any edge is in the overscan / bezel zone. */\nconst READ_SAFE_AREA = 0.05;\n\n/**\n * Non-blocking advisory warnings for a valid spec. Does NOT replace validateSpec —\n * call advise only on specs that have already passed validation.\n */\nexport function adviseSpec(\n spec: SaverSpec,\n viewport = { width: 1920, height: 1080 },\n /**\n * Sample point. `perceiveScene` forwards its own `t`/`seed` so the advisories\n * describe the same scene its other channels do — without them a caller\n * perceiving at t = 30 s would get `form` for that instant beside an\n * `overlap-seams` advisory computed for a different one.\n */\n opts: { t?: number; seed?: number } = {},\n): SpecWarning[] {\n const warnings: SpecWarning[] = [];\n const w = viewport.width;\n const h = viewport.height;\n const scale = spec.units === 'px' ? 1 : Math.min(w, h);\n const refVp = spec.referenceViewport ?? LIMITS.referenceViewport;\n // Mirror buildScene's maxTotal clamp: without it a dense scene above the\n // reference viewport is advised on more entities than the renderer will\n // build, and `perceiveScene` would pair a `form` channel counted one way\n // with an `overlap-seams` advisory counted the other. (Part of F49, which\n // tracks the same divergence for describeScene.)\n let countScale = scale > 1 ? Math.min(w, h) / refVp : 1;\n if (countScale > 1) {\n const rawTotal = spec.layers.reduce((sum, l) => sum + Math.round(l.count * countScale), 0);\n if (rawTotal > LIMITS.maxTotal) countScale *= LIMITS.maxTotal / rawTotal;\n }\n const rng = createRng(opts.seed ?? spec.seed ?? 42);\n const allEntities = spec.layers.map((l) => buildEntities(l, rng, w, h, scale, countScale));\n const bgLuma = backgroundLuma(spec);\n const bgRgb = backgroundRgb(spec);\n\n // Do overlapping layers actually merge? Computed once from the entities we\n // already built; the advisory below fires only on the case where the author\n // clearly wanted one shape and the paint settings defeat it.\n const cohesion = cohesionOf(\n spec.layers.map((layer, i) => ({ layer, entities: allEntities[i]! })),\n opts.t ?? COHESION_T, w, h,\n );\n\n let totalEntities = 0;\n let textLayerCount = 0;\n let motionLayerCount = 0;\n\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n const entities = allEntities[li]!;\n totalEntities += entities.length;\n\n const isText = layer.sprite.kind === 'text' || layer.sprite.kind === 'textBlock';\n const isStaticText = isText && layer.motion.type === 'static';\n if (isStaticText) textLayerCount++;\n if (layer.motion.type !== 'static') motionLayerCount++;\n\n const coh = cohesion[li]!;\n if (seamsWorthWarning(layer, coh, entities.length)) {\n warnings.push({\n path: `layers[${li}]`,\n code: 'overlap-seams',\n message:\n `entities bury ${Math.round((coh.overlap ?? 0) * 100)}% of each other's outlines, so this layer is drawn as one shape — `\n + `but ${coh.seamCause}, so every overlap paints a visible edge and it will read as a pile of sprites instead. `\n + 'A layer merges into a single silhouette only when it is one flat colour at alpha 1, hard-edged, with no blend and no pulse.',\n });\n }\n\n if (layer.trail && layer.motion.type === 'static') {\n warnings.push({\n path: `layers[${li}].trail`,\n code: 'trail-on-static',\n message: 'trail has no effect on static entities — they have no past positions to draw',\n });\n }\n\n if ((layer.sprite.kind === 'streak' || (layer.sprite.kind === 'stroke' && layer.sprite.orient)) && layer.motion.type === 'static') {\n warnings.push({\n path: `layers[${li}].sprite`,\n code: 'streak-on-static',\n message: `${layer.sprite.kind === 'streak' ? 'streak sprites orient' : 'an oriented stroke turns'} along the motion heading — static entities have none, so the heading contributes nothing${layer.spin ? ' (spin still rotates the mark)' : ' and it renders at angle 0'}`,\n });\n }\n\n if (layer.motion.type === 'wander' && layer.motion.coherence === 1 && entities.length >= 20) {\n warnings.push({\n path: `layers[${li}].motion.coherence`,\n code: 'full-coherence',\n message: 'coherence 1 makes every entity share identical harmonics — the layer moves as a rigid sheet. 0.5–0.8 reads as schooling',\n });\n }\n\n if (layer.sprite.kind === 'circle') {\n const maxR = entities.reduce((m, e) => Math.max(m, e.size / 2), 0);\n const maxAlpha = entities.reduce((m, e) => Math.max(m, e.alpha), 0);\n if (maxR * maxAlpha < 0.05) {\n warnings.push({\n path: `layers[${li}]`,\n code: 'invisible-layer',\n message: `layer's max visible radius (${maxR.toFixed(1)}px × ${maxAlpha.toFixed(2)} alpha) is below perceptual floor`,\n });\n }\n }\n\n // Colour separation: a layer painted the same brightness as the plate\n // behind it is invisible no matter how big or opaque it is. `invisible-layer`\n // above only measures radius × alpha, so a full-strength layer in a\n // background-matched colour passes every other check in this file.\n if (entities.length > 0 && layer.sprite.kind !== 'emoji') {\n // A palette layer is visible if ANY of its colours separates — flag only\n // when every colour it can paint with disappears into the plate.\n const seps = entities.map((e) => {\n const hex = spriteHex(layer, e);\n if (hex === null) return Infinity;\n return colourSeparation(layer, { rgb: hexRgb(hex), luma: hexLuma(hex) }, { rgb: bgRgb, luma: bgLuma });\n });\n const best = Math.max(...seps);\n if (best < LOW_CONTRAST_FLOOR) {\n const additive = layer.blend === 'lighter' || layer.blend === 'screen';\n warnings.push({\n path: `layers[${li}].sprite`,\n code: 'low-contrast-layer',\n message: additive\n ? `additive layer adds almost no light (luma ${best.toFixed(3)}) — a \"lighter\"/\"screen\" layer is only as visible as it is bright`\n : `layer colour is within ${best.toFixed(3)} of the background (floor ${LOW_CONTRAST_FLOOR}) — it will read as background, not as content`,\n });\n }\n }\n\n }\n\n // Alpha-weighted pixel coverage: how much of the viewport is \"visibly filled\"\n let totalCoverage = 0;\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n const entities = allEntities[li]!;\n for (const e of entities) {\n const r = e.size / 2;\n let pixArea: number;\n if (layer.sprite.kind === 'circle') {\n pixArea = Math.PI * r * r;\n } else if (layer.sprite.kind === 'bar') {\n pixArea = e.size * barFraction(layer.sprite, e.barIndex ?? 0) * (e.size2 ?? e.size * 0.2);\n } else if (layer.sprite.kind === 'textBlock') {\n const fsPx = layer.sprite.fontSize * scale;\n const lh = (layer.sprite.lineHeight ?? 1.4) * fsPx;\n const maxWPx = layer.sprite.maxWidth * scale;\n const lines = breakTextBlock(layer.sprite.text, maxWPx / fsPx, textMetricsClassFor(layer.sprite.font));\n pixArea = maxWPx * lines.length * lh * 0.55 * (layer.sprite.opacity ?? 1);\n } else {\n pixArea = e.size * e.size; // text/emoji: approximate as square of font size\n }\n // Sparse-event layers are lit only for `life` of every `every` ms, at a\n // mean envelope of ~½, and at a mean grown size — judge their coverage\n // by that duty, not by whichever instant we happen to sample.\n let duty = 1;\n if (layer.emit) {\n // Area scales with size², so the time-mean over a linear size ramp\n // a→b is mean(f²) = (a² + ab + b²) / 3, not mean(f)².\n const [ga, gb] = layer.emit.grow ?? [1, 1];\n const g2 = (ga * ga + ga * gb + gb * gb) / 3;\n duty = (Math.min(layer.emit.life, layer.emit.every) / layer.emit.every) * 0.5 * g2;\n }\n totalCoverage += (pixArea * e.alpha * duty) / (w * h);\n }\n // Link lines are visual coverage too (for Mystify-style scenes they ARE the scene).\n if (layer.links) {\n const positions = entities.map((e) => positionAt(e, 0, w, h));\n const maxDistPx = layer.links.maxDist * scale;\n const edges = linkEdges(layer.links, positions, maxDistPx, layer.wrap !== false, w, h);\n const defaultWidth = scale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const lwPx = (layer.links.width ?? defaultWidth) * scale;\n const la = layer.links.alpha ?? 1;\n for (const edge of edges) totalCoverage += (edge.dist * lwPx * la) / (w * h);\n }\n }\n\n // A declared `density` is read before either density advisory fires — and\n // then checked against the measurement, so the declaration cannot be used\n // to silence a scene that is empty by accident rather than by intent.\n const density = spec.density ?? 'normal';\n const wouldBeSparse = totalCoverage < 0.0005 && spec.layers.length > 0;\n if (wouldBeSparse && density !== 'sparse') {\n warnings.push({\n path: 'layers',\n code: 'sparse-scene',\n message: `alpha-weighted coverage is ${(totalCoverage * 100).toFixed(4)}% — scene will look empty on most displays`,\n });\n }\n\n if (totalEntities > 500 && density !== 'dense') {\n warnings.push({\n path: 'layers',\n code: 'dense-scene',\n message: `${totalEntities} entities — scene may feel crowded and hurt performance on low-end devices`,\n });\n }\n\n if (density === 'sparse' && totalCoverage > SPARSE_DECLARED_MAX_COVERAGE) {\n warnings.push({\n path: 'density',\n code: 'density-mismatch',\n message: `declared sparse but alpha-weighted coverage is ${(totalCoverage * 100).toFixed(2)}% — either the declaration or the scene is wrong`,\n });\n } else if (density === 'dense' && wouldBeSparse) {\n warnings.push({\n path: 'density',\n code: 'density-mismatch',\n message: `declared dense but alpha-weighted coverage is ${(totalCoverage * 100).toFixed(4)}% — the scene will look empty`,\n });\n }\n\n if (spec.layers.length > 0 && textLayerCount > 0 && motionLayerCount === 0) {\n const textRatio = textLayerCount / spec.layers.length;\n if (textRatio >= 0.8) {\n warnings.push({\n path: 'layers',\n code: 'text-heavy',\n message: 'most layers are static text — reads as a document, not a screensaver',\n });\n }\n }\n\n // Link starvation: links layer where few edges actually form.\n // Chain mode always forms its edges — only distance-gated modes can starve.\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n if (!layer.links || layer.links.mode === 'chain') continue;\n const entities = allEntities[li]!;\n const positions = entities.map((e) => positionAt(e, 0, w, h));\n const maxDist = layer.links.maxDist * scale;\n const pairs = linkPairs(positions, layer.links.k, maxDist, layer.wrap !== false, w, h);\n const maxPossible = Math.min(entities.length * layer.links.k, entities.length * (entities.length - 1) / 2);\n if (maxPossible > 0 && pairs.length / maxPossible < 0.1) {\n warnings.push({\n path: `layers[${li}].links`,\n code: 'link-starvation',\n message: `only ${pairs.length}/${maxPossible} possible edges formed — raise count or widen links.maxDist`,\n });\n }\n }\n\n // Motion variety: all entities in a layer have nearly identical velocity\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n if (layer.motion.type === 'static') continue;\n const entities = allEntities[li]!;\n if (entities.length < 3) continue;\n const speeds = entities.map((e) => Math.sqrt(e.vx * e.vx + e.vy * e.vy));\n const mean = speeds.reduce((a, b) => a + b, 0) / speeds.length;\n if (mean === 0) continue;\n const maxDev = Math.max(...speeds.map((s) => Math.abs(s - mean)));\n if (maxDev / mean < 0.05) {\n warnings.push({\n path: `layers[${li}].motion`,\n code: 'uniform-motion',\n message: 'all entities move at nearly identical speed — widen the speed range for visual variety',\n });\n }\n }\n\n // Composition balance: entities clustered in one region. Motions that sweep the\n // whole viewport (bounce, warp, path) have transient spawn positions that say\n // nothing about composition — exclude them from the centroid.\n const composed = spec.layers\n .map((l, li) => ({ l, ents: allEntities[li]! }))\n .filter(({ l }) => !['bounce', 'warp', 'path'].includes(l.motion.type))\n // Layer-parented orbits position relative to their parent (resolved at render\n // time) — their raw positionAt is an offset around (0,0), not a screen position.\n .filter(({ l }) => !(l.motion.type === 'orbit' && l.motion.center && 'layer' in l.motion.center));\n const composedCount = composed.reduce((s, c) => s + c.ents.length, 0);\n if (composedCount >= 8) {\n const positions = composed.flatMap(({ ents }) => ents.map((e) => positionAt(e, 0, w, h)));\n const cx = positions.reduce((s, p) => s + p.x, 0) / positions.length;\n const cy = positions.reduce((s, p) => s + p.y, 0) / positions.length;\n const offX = Math.abs(cx / w - 0.5);\n const offY = Math.abs(cy / h - 0.5);\n if (offX > 0.2 || offY > 0.2) {\n warnings.push({\n path: 'layers',\n code: 'off-center',\n message: `centroid at (${(cx / w).toFixed(2)}, ${(cy / h).toFixed(2)}) — composition is heavily offset from center`,\n });\n }\n }\n\n // Spatial text: the one layout bug an author without eyes makes most and\n // cannot detect — a caption that runs off the frame, a title painted over a\n // body. Only static text is judged (moving text has no fixed box). Boxes use\n // the character-class width table the textBlock line-breaker uses, so the\n // estimate is the renderer's own idea of the text, not a separate guess.\n const textBoxes: TextBoxAt[] = [];\n for (let li = 0; li < spec.layers.length; li++) {\n const layer = spec.layers[li]!;\n const s = layer.sprite;\n if (layer.motion.type !== 'static') continue;\n if (s.kind !== 'text' && s.kind !== 'textBlock') continue;\n const label = layer.key ? `\\`${layer.key}\\`` : `layers[${li}]`;\n for (const e of allEntities[li]!) {\n const p = positionAt(e, 0, w, h);\n const box = s.kind === 'textBlock' ? textBlockBoxAt(s, p, w, h) : textBoxAt(s, e, p, spec, w, h);\n // What the layer guarantees it paints, worst case: base alpha minus its\n // pulse trough (ignoring `emit`'s on/off envelope — a mark's on-screen\n // duty cycle is a readability question, not an ink-colour one; sampling\n // at `t = 0` would otherwise flag every emitting layer as invisible)\n // times a textBlock's own `opacity` — so faint or invisible\n // `role: 'read'` text can't hide behind an unmeasured alpha.\n const alpha = Math.max(0, Math.min(1, e.alpha - e.pulseAmp)) * (s.kind === 'textBlock' ? (s.opacity ?? 1) : 1);\n textBoxes.push({ li, label, alpha, ...box });\n }\n }\n const asFraction = (b: Pick<Box, 'x0' | 'y0' | 'x1' | 'y1'>): WarningBox => ({\n x: +(b.x0 / w).toFixed(4),\n y: +(b.y0 / h).toFixed(4),\n w: +((b.x1 - b.x0) / w).toFixed(4),\n h: +((b.y1 - b.y0) / h).toFixed(4),\n });\n\n // Off-screen: any edge past the viewport by more than 1% of that dimension\n // (the width table is approximate; a hairline overhang is not a finding).\n const tolX = w * 0.01;\n const tolY = h * 0.01;\n const offFlagged = new Set<number>();\n for (const b of textBoxes) {\n if (offFlagged.has(b.li)) continue;\n const edges: string[] = [];\n if (b.x0 < -tolX) edges.push(`left edge by ~${Math.round(-b.x0)}px`);\n if (b.x1 > w + tolX) edges.push(`right edge by ~${Math.round(b.x1 - w)}px`);\n if (b.y0 < -tolY) edges.push(`top edge by ~${Math.round(-b.y0)}px`);\n if (b.y1 > h + tolY) edges.push(`bottom edge by ~${Math.round(b.y1 - h)}px`);\n if (edges.length === 0) continue;\n offFlagged.add(b.li);\n warnings.push({\n path: `layers[${b.li}]`,\n code: 'text-off-screen',\n message: `${b.label} text runs off the ${edges.join(' and the ')} at ${w}×${h} — move position, or shrink fontSize / maxWidth`,\n });\n }\n\n // Overlap: two different static text layers whose boxes share more than 10%\n // of the smaller box. Reported once per layer pair, on the earlier layer.\n const pairFlagged = new Set<string>();\n for (let i = 0; i < textBoxes.length; i++) {\n for (let j = i + 1; j < textBoxes.length; j++) {\n const a = textBoxes[i]!;\n const b = textBoxes[j]!;\n if (a.li === b.li) continue;\n const pair = `${Math.min(a.li, b.li)}:${Math.max(a.li, b.li)}`;\n if (pairFlagged.has(pair)) continue;\n const ix = Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0);\n const iy = Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0);\n if (ix <= 0 || iy <= 0) continue;\n const smaller = Math.min((a.x1 - a.x0) * (a.y1 - a.y0), (b.x1 - b.x0) * (b.y1 - b.y0));\n if (smaller <= 0) continue;\n const share = (ix * iy) / smaller;\n if (share <= 0.1) continue;\n pairFlagged.add(pair);\n const [first, second] = a.li < b.li ? [a, b] : [b, a];\n warnings.push({\n path: `layers[${first.li}]`,\n code: 'text-overlap',\n message: `${first.label} and ${second.label} text boxes overlap (~${Math.round(share * 100)}% of the smaller one) — they will paint over each other; move one or shrink it`,\n // The two boxes, so an agent can move one without re-deriving the\n // layout. Additive: the message is unchanged.\n boxes: [asFraction(first), asFraction(second)],\n });\n }\n }\n\n // Legibility, for text that declared it must be read (`role: 'read'`).\n // Everything below is opt-in: a layer without the role is never measured,\n // so the atmospheric text the examples paint at 2–3:1 stays silent.\n const readFlagged = new Set<number>();\n for (const b of textBoxes) {\n if (readFlagged.has(b.li)) continue;\n const layer = spec.layers[b.li]!;\n const s = layer.sprite;\n if ((s.kind !== 'text' && s.kind !== 'textBlock') || s.role !== 'read') continue;\n // Every box of the layer (a `list` of labels is several), worst one wins.\n const boxes = textBoxes.filter((x) => x.li === b.li);\n readFlagged.add(b.li);\n\n const ink = hexRgb(s.color ?? '#e6e8ef');\n // What the layer actually paints over `base`, at its own alpha and blend —\n // a `role: 'read'` label at low opacity, or under `lighter`/`screen`/\n // `multiply`, is not free to hide behind a source-over assumption.\n const textPlate = (base: Rgb, alpha: number): Rgb => {\n if (layer.blend === 'lighter' || layer.blend === 'screen') return additivePlate(base, ink, alpha, layer.blend);\n if (layer.blend === 'multiply') {\n return {\n r: base.r * (1 - alpha + ink.r * alpha),\n g: base.g * (1 - alpha + ink.g * alpha),\n b: base.b * (1 - alpha + ink.b * alpha),\n };\n }\n return sourceOverPlate(base, ink, alpha);\n };\n let worst: { ground: number; plate: number; plateLabel: string | null } | null = null;\n for (const box of boxes) {\n const cy = (box.y0 + box.y1) / 2;\n const groundRgb = backgroundRgbAt(spec, cy, h, scale);\n const ground = legibilityRatio(textPlate(groundRgb, box.alpha), groundRgb);\n const lit = brightestAdditivePlate(spec, allEntities, groundRgb, box, w, h);\n const plate = lit ? legibilityRatio(textPlate(lit.rgb, box.alpha), lit.rgb) : Infinity;\n if (!worst || Math.min(ground, plate) < Math.min(worst.ground, worst.plate)) {\n worst = { ground, plate, plateLabel: lit?.label ?? null };\n }\n }\n if (worst && Math.min(worst.ground, worst.plate) < READ_LEGIBILITY_FLOOR) {\n const under = worst.plateLabel\n ? ` and ${worst.plate.toFixed(1)}:1 under ${worst.plateLabel} at its brightest`\n : '';\n warnings.push({\n path: `layers[${b.li}].sprite`,\n code: 'text-legibility',\n message: `${b.label} is declared role: 'read' but its colour reads at ${worst.ground.toFixed(1)}:1 against the background at the box centre${under} — below ${READ_LEGIBILITY_FLOOR}:1; brighten the text, darken the ground under it, or declare role: 'atmosphere' if it is texture`,\n });\n }\n\n // Safe area: readable text that sits in the outer 5 % of the frame lands\n // in the bezel / overscan zone on a real display.\n const edges: string[] = [];\n const x0 = Math.min(...boxes.map((x) => x.x0));\n const x1 = Math.max(...boxes.map((x) => x.x1));\n const y0 = Math.min(...boxes.map((x) => x.y0));\n const y1 = Math.max(...boxes.map((x) => x.y1));\n if (x0 < w * READ_SAFE_AREA) edges.push('left');\n if (x1 > w * (1 - READ_SAFE_AREA)) edges.push('right');\n if (y0 < h * READ_SAFE_AREA) edges.push('top');\n if (y1 > h * (1 - READ_SAFE_AREA)) edges.push('bottom');\n if (edges.length > 0) {\n warnings.push({\n path: `layers[${b.li}]`,\n code: 'text-safe-area',\n message: `${b.label} is declared role: 'read' but its box is within ${READ_SAFE_AREA * 100}% of the ${edges.join(' and ')} edge${edges.length === 1 ? '' : 's'} at ${w}×${h} — displays crop and bezels hide that zone; move it inward`,\n boxes: [asFraction({ x0, y0, x1, y1 })],\n });\n }\n }\n\n return warnings;\n}\n\n/**\n * The brightest ground a `role: 'read'` box can find itself on: for every\n * additive layer (`lighter` / `screen`) whose entities can reach the box and\n * are big enough to sit under a glyph, the brightest per-entity plate — its\n * own colour composited at its own peak alpha (base + pulse), never a\n * different entity's alpha borrowed onto it. Reach is judged at rest: a\n * static entity is its disc at `t = 0`; an orbit is its centre ± radius;\n * every travelling motion can be anywhere. The disc's diameter is the\n * entity's largest possible rendered extent — grow breathing, a rect/bar's\n * second dimension (thickness/aspect height can exceed the primary size),\n * and the peak scale warp/emit reach over their lifecycle — so a mote that\n * balloons under a line is not dismissed as dust because it starts small.\n */\nfunction brightestAdditivePlate(\n spec: SaverSpec,\n allEntities: Entity[][],\n ground: Rgb,\n box: TextBoxAt,\n w: number,\n h: number,\n): { rgb: Rgb; label: string } | null {\n let best: { rgb: Rgb; label: string; lum: number } | null = null;\n for (let lj = 0; lj < spec.layers.length; lj++) {\n const layer = spec.layers[lj]!;\n const blend = layer.blend;\n if (blend !== 'lighter' && blend !== 'screen') continue;\n if (lj === box.li) continue;\n const entities = allEntities[lj]!;\n for (const e of entities) {\n const hex = spriteHex(layer, e);\n if (hex === null) continue;\n const growScale = (e.motion === 'warp' ? WARP_MAX_SCALE : 1) * (e.emit ? Math.max(e.emit.growFrom, e.emit.growTo) : 1);\n const maxDim = Math.max(e.size, e.size2 ?? 0) * (1 + e.growAmp) * growScale;\n if (maxDim < box.fs) continue;\n if (!entityReachesBox(e, maxDim / 2, box, w, h)) continue;\n const a = Math.min(1, e.alpha + e.pulseAmp);\n if (a <= 0) continue;\n const plate = additivePlate(ground, hexRgb(hex), a, blend);\n const lum = relativeLuminance(plate);\n if (!best || lum > best.lum) {\n best = { rgb: plate, label: layer.key ? `\\`${layer.key}\\`` : `layers[${lj}]`, lum };\n }\n }\n }\n return best ? { rgb: best.rgb, label: best.label } : null;\n}\n\n/** Whether an entity's disc of half-extent `r` can overlap `box` (see `brightestAdditivePlate`). */\nfunction entityReachesBox(e: Entity, r: number, box: TextBoxAt, w: number, h: number): boolean {\n if (e.motion === 'static') {\n const p = positionAt(e, 0, w, h);\n return p.x + r > box.x0 && p.x - r < box.x1 && p.y + r > box.y0 && p.y - r < box.y1;\n }\n if (e.motion === 'orbit' && !e.orbitParent) {\n const span = e.orbitR + r;\n return e.orbitCx + span > box.x0 && e.orbitCx - span < box.x1 && e.orbitCy + span > box.y0 && e.orbitCy - span < box.y1;\n }\n return true;\n}\n\ninterface TextBoxAt {\n li: number;\n label: string;\n /**\n * Worst case, not \"at rest\": base alpha minus its pulse trough (never the\n * `emit` envelope, whose on/off duty cycle is excluded on purpose) times a\n * textBlock's own `opacity`.\n */\n alpha: number;\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n /** Glyph height in px — what an additive layer must out-size to sit under a line. */\n fs: number;\n}\n\ntype Box = Pick<TextBoxAt, 'x0' | 'y0' | 'x1' | 'y1' | 'fs'>;\n\n/**\n * Box of one `text` entity, mirroring the renderer: a `font` with a px size is\n * used verbatim (scaled by the same viewport/reference ratio the renderer\n * applies), otherwise the seeded per-entity size; `align`/`baseline` move the\n * anchor; `maxWidth` is a hard cap because `fillText(text, x, y, maxWidth)`\n * squeezes the glyphs to fit.\n */\nfunction textBoxAt(\n s: Extract<LayerSpec['sprite'], { kind: 'text' }>,\n e: Entity,\n p: { x: number; y: number },\n spec: SaverSpec,\n w: number,\n h: number,\n): Box {\n const m = s.font ? /(\\d{1,5}(?:\\.\\d{1,4})?|\\.\\d{1,4})px/.exec(s.font) : null;\n const fontScale = spec.units === 'px' ? 1 : Math.min(w, h) / (spec.referenceViewport ?? LIMITS.referenceViewport);\n const fh = m ? Number(m[1]) * fontScale : e.size;\n const str = s.strings[e.spriteIndex] ?? s.strings[0] ?? '';\n let fw = textWidthEm(str) * fh;\n if (s.maxWidth) fw = Math.min(fw, s.maxWidth * (spec.units === 'px' ? 1 : Math.min(w, h)));\n const align = s.align ?? 'center';\n const baseline = s.baseline ?? 'middle';\n const x0 = align === 'left' ? p.x : align === 'right' ? p.x - fw : p.x - fw / 2;\n const y0 = baseline === 'top' ? p.y : baseline === 'bottom' ? p.y - fh : p.y - fh / 2;\n return { x0, y0, x1: x0 + fw, y1: y0 + fh, fs: fh };\n}\n\n/**\n * Box of a `textBlock`, mirroring the renderer: `position` is the block's\n * top-left, lines break with `breakTextBlock`, `align` moves the painted lines\n * inside the `maxWidth` box (not the box itself).\n */\nfunction textBlockBoxAt(\n s: Extract<LayerSpec['sprite'], { kind: 'textBlock' }>,\n p: { x: number; y: number },\n w: number,\n h: number,\n): Box {\n const unit = Math.min(w, h);\n const fsPx = s.fontSize * unit;\n const lh = (s.lineHeight ?? 1.4) * fsPx;\n const maxWPx = s.maxWidth * unit;\n const lines = breakTextBlock(s.text, maxWPx / fsPx, textMetricsClassFor(s.font));\n const maxLineW = lines.reduce((mx, l) => Math.max(mx, l.widthEm), 0) * fsPx;\n const totalH = lines.length * lh;\n const align = s.align ?? 'left';\n const x0 = align === 'center' ? p.x + (maxWPx - maxLineW) / 2 : align === 'right' ? p.x + maxWPx - maxLineW : p.x;\n // Anchor moves the whole block the same way the renderer does (0,0 when absent).\n const { dx, dy } = textBlockAnchorOffset(s, maxWPx, maxLineW, totalH);\n return { x0: x0 + dx, y0: p.y + dy, x1: x0 + dx + maxLineW, y1: p.y + dy + totalH, fs: fsPx };\n}\n\n/**\n * Non-blocking advisory warnings for a validated sequence envelope.\n * Checks cross-segment luminance jumps at boundaries and per-segment advisories.\n */\nexport function adviseSequence(\n seq: IdleSequence,\n viewport = { width: 1920, height: 1080 },\n): SpecWarning[] {\n const warnings: SpecWarning[] = [];\n\n for (let i = 0; i < seq.segments.length; i++) {\n const segWarnings = adviseSpec(seq.segments[i]!.scene, viewport);\n for (const w of segWarnings) {\n warnings.push({ path: `segments[${i}].scene.${w.path}`, code: w.code, message: w.message, boxes: w.boxes });\n }\n }\n\n // Informational, once per sequence: a fade costs two live segments for\n // `dur`, which the lowest tiers cannot afford, so they play it as a cut.\n // A `fade` on the last segment only ever runs under `loop: true` (it's the\n // wrap's transition into segment 0) — without loop there is no next\n // segment for it to transition into, so it never executes and should not\n // be counted.\n const fadeBound = seq.loop ? seq.segments.length : seq.segments.length - 1;\n const fades = seq.segments.slice(0, fadeBound).filter((s) => s.transition?.type === 'fade').length;\n if (fades > 0) {\n const first = seq.segments.slice(0, fadeBound).findIndex((s) => s.transition?.type === 'fade');\n warnings.push({\n path: `segments[${first}].transition`,\n code: 'fade-degrades-on-low-tier',\n message: `informational: ${fades} fade transition${fades === 1 ? '' : 's'} declared — viewers on the 'basic' or 'minimal' capability tier render fade as cut (two live segments for dur is over that budget); the show still plays`,\n });\n }\n\n for (let i = 0; i < seq.segments.length - 1; i++) {\n const lumaA = backgroundLuma(seq.segments[i]!.scene);\n const lumaB = backgroundLuma(seq.segments[i + 1]!.scene);\n const delta = Math.abs(lumaA - lumaB);\n if (delta > 0.5) {\n warnings.push({\n path: `segments[${i}]`,\n code: 'boundary-luminance-jump',\n message: `background luminance jumps ${delta.toFixed(2)} at boundary ${i}→${i + 1} — may flash on cut`,\n });\n }\n\n const tr = seq.segments[i]!.transition;\n if (tr?.type === 'morph') {\n const sigA = structuralSignature(seq.segments[i]!.scene);\n const sigB = structuralSignature(seq.segments[i + 1]!.scene);\n if (sigA !== sigB) {\n warnings.push({\n path: `segments[${i}].transition`,\n code: 'morph-structural-mismatch',\n message: `segments ${i}→${i + 1} differ structurally: morph will fall back to cut`,\n });\n } else if (morphNothingMorphable(seq.segments[i]!.scene, seq.segments[i + 1]!.scene, { textCrossfade: tr.text === 'crossfade' })) {\n warnings.push({\n path: `segments[${i}].transition`,\n code: 'morph-nothing-morphable',\n message: `segments ${i}→${i + 1} differ only in values morph cannot interpolate (strings such as textBlock.text step on the first frame): the morph will look like a cut — fade text via colour or reveal.progress`,\n });\n }\n }\n }\n\n return warnings;\n}\n","/**\n * Shared luminance helpers.\n *\n * These live in their own module because both `perceive` (which ranks layers by\n * visual weight) and `advise` (which warns about layers that can't be seen)\n * need the same notion of \"how bright is this thing\" — and `perceive` already\n * imports `advise`, so the dependency can only run one way.\n */\n\nimport type { Entity } from './simulate';\nimport { isShapedSprite } from './shapes';\nimport type { LayerSpec, SaverSpec } from './types';\n\n/** Perceptual luma (0..1) of a hex colour. */\nexport function hexLuma(hex: string): number {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n if (Number.isNaN(n)) return 0.7;\n const r = ((n >> 16) & 255) / 255;\n const g = ((n >> 8) & 255) / 255;\n const b = (n & 255) / 255;\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\nexport function spriteLuma(layer: LayerSpec, e: Entity): number {\n const s = layer.sprite;\n if (isShapedSprite(s)) {\n return hexLuma(s.colors?.[e.colorIndex] ?? s.color);\n }\n if (s.kind === 'text' || s.kind === 'textBlock') return hexLuma(s.color ?? '#e6e8ef');\n return 0.75; // emoji: mid-bright approximation\n}\n\n/** The hex a given entity actually paints with, or null for glyph sprites. */\nexport function spriteHex(layer: LayerSpec, e: Entity): string | null {\n const s = layer.sprite;\n if (isShapedSprite(s)) {\n return s.colors?.[e.colorIndex] ?? s.color;\n }\n if (s.kind === 'text' || s.kind === 'textBlock') return s.color ?? '#e6e8ef';\n return null; // emoji carry their own palette\n}\n\n/** Mean luma of the background plate a layer is drawn against. */\nexport function backgroundLuma(spec: SaverSpec): number {\n const bg = spec.background;\n if (!bg || bg.type === 'solid') return hexLuma(bg?.color ?? '#05050a');\n return bg.stops.reduce((s, st) => s + hexLuma(st.color), 0) / bg.stops.length;\n}\n\n/** Unpack a hex colour to 0..1 RGB. */\nexport function hexRgb(hex: string): { r: number; g: number; b: number } {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n if (Number.isNaN(n)) return { r: 0.7, g: 0.7, b: 0.7 };\n return { r: ((n >> 16) & 255) / 255, g: ((n >> 8) & 255) / 255, b: (n & 255) / 255 };\n}\n\n/** Mean RGB of the background plate. */\nexport function backgroundRgb(spec: SaverSpec): { r: number; g: number; b: number } {\n const bg = spec.background;\n if (!bg || bg.type === 'solid') return hexRgb(bg?.color ?? '#05050a');\n const acc = bg.stops.reduce(\n (s, st) => {\n const c = hexRgb(st.color);\n return { r: s.r + c.r, g: s.g + c.g, b: s.b + c.b };\n },\n { r: 0, g: 0, b: 0 },\n );\n const n = bg.stops.length || 1;\n return { r: acc.r / n, g: acc.g / n, b: acc.b / n };\n}\n\n/**\n * How far a layer's colour separates from its background, ignoring alpha and\n * geometry — purely \"can this be told apart from the plate behind it\".\n *\n * **This is a colour distance, not a luminance one, and that distinction is\n * load-bearing.** Equal-luminance/contrasting-hue is a real technique, not a\n * mistake: a Seurat-style field of golden `#e8c060` dots over a pale grey-blue\n * plate differs by 0.013 in luma and is perfectly visible, because the\n * separation lives entirely in hue. A luma-only test flags exactly the\n * pointillist screens it should leave alone.\n *\n * Additive blends are a different question again. Under `lighter`/`screen` the\n * sprite ADDS light, so a colour matching the background is still visible (it\n * doubles it); what makes such a layer vanish is having little light to add —\n * which genuinely is a luminance question.\n *\n * Alpha and radius are deliberately excluded — `invisible-layer` already owns\n * that axis, and the schema actively recommends faint atmospheric layers\n * (\"80 tiny soft circles at alpha 0.2\"), which must not be flagged here.\n */\nexport function colourSeparation(\n layer: LayerSpec,\n sprite: { rgb: { r: number; g: number; b: number }; luma: number },\n bg: { rgb: { r: number; g: number; b: number }; luma: number },\n): number {\n if (layer.blend === 'lighter' || layer.blend === 'screen') return sprite.luma;\n const dr = sprite.rgb.r - bg.rgb.r;\n const dg = sprite.rgb.g - bg.rgb.g;\n const db = sprite.rgb.b - bg.rgb.b;\n // Euclidean in RGB, normalised so 1 = black-to-white. Crude next to CIEDE2000\n // but it separates hue from value, which is the whole point here.\n return Math.sqrt((dr * dr + dg * dg + db * db) / 3);\n}\n\n// ---------------------------------------------------------------------------\n// Legibility — WCAG 2.x relative luminance and the ratio between two colours.\n// Used only by layers that declare `role: 'read'`; `hexLuma` above stays the\n// perceptual (gamma-space) weight the perception grid is built on.\n// ---------------------------------------------------------------------------\n\nexport type Rgb = { r: number; g: number; b: number };\n\n/** sRGB channel (0..1) → linear light, per WCAG 2.x. */\nfunction srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n}\n\n/** WCAG relative luminance (0..1, linear light) of a 0..1 RGB triple. */\nexport function relativeLuminance(rgb: Rgb): number {\n return 0.2126 * srgbToLinear(rgb.r) + 0.7152 * srgbToLinear(rgb.g) + 0.0722 * srgbToLinear(rgb.b);\n}\n\n/**\n * WCAG legibility ratio (1..21) between two colours, order-free:\n * `(L_lighter + 0.05) / (L_darker + 0.05)`. 4.5 is the AA floor for body\n * text; 3 for large text.\n */\nexport function legibilityRatio(a: Rgb, b: Rgb): number {\n const la = relativeLuminance(a);\n const lb = relativeLuminance(b);\n const hi = Math.max(la, lb);\n const lo = Math.min(la, lb);\n return (hi + 0.05) / (lo + 0.05);\n}\n\n/**\n * The background colour under one point, `yPx` down a `h`-tall viewport:\n * a solid is itself; a gradient is its stops interpolated in sRGB at their\n * rest positions (`drift` moves them ±`amount` over time — the rest position\n * is the mean); a `band` wins where the point falls inside it. `unit` is the\n * spec's dimensional unit (1 for `px`, `min(w,h)` otherwise), for the band.\n */\nexport function backgroundRgbAt(spec: SaverSpec, yPx: number, h: number, unit: number): Rgb {\n const bg = spec.background;\n if (!bg || bg.type === 'solid') return hexRgb(bg?.color ?? '#05050a');\n if (bg.band) {\n const bh = bg.band.height * unit;\n if (yPx >= h - bh) return hexRgb(bg.band.color);\n }\n const stops = [...bg.stops].sort((a, b) => a.at - b.at);\n const y = h > 0 ? Math.max(0, Math.min(1, yPx / h)) : 0;\n const first = stops[0]!;\n const last = stops[stops.length - 1]!;\n if (y <= first.at) return hexRgb(first.color);\n if (y >= last.at) return hexRgb(last.color);\n for (let i = 1; i < stops.length; i++) {\n const a = stops[i - 1]!;\n const b = stops[i]!;\n if (y > b.at) continue;\n const span = b.at - a.at;\n const k = span > 0 ? (y - a.at) / span : 1;\n const ca = hexRgb(a.color);\n const cb = hexRgb(b.color);\n return { r: ca.r + (cb.r - ca.r) * k, g: ca.g + (cb.g - ca.g) * k, b: ca.b + (cb.b - ca.b) * k };\n }\n return hexRgb(last.color);\n}\n\n/**\n * Standard alpha (source-over) composite of `colour` at `alpha` over `ground` —\n * what a translucent or faint layer actually paints, rather than its\n * configured colour at full strength. Used so a `role: 'read'` text at low\n * alpha (or a `textBlock` with `opacity < 1`) is measured for what it really\n * puts on screen, not the undiluted ink colour.\n */\nexport function sourceOverPlate(ground: Rgb, colour: Rgb, alpha: number): Rgb {\n return {\n r: ground.r + (colour.r - ground.r) * alpha,\n g: ground.g + (colour.g - ground.g) * alpha,\n b: ground.b + (colour.b - ground.b) * alpha,\n };\n}\n\n/**\n * The plate an additive layer leaves behind it at full strength: `colour ×\n * alpha` added to the ground (`lighter`), or screened onto it (`screen`).\n * Per channel, clamped to 1 — the same arithmetic the canvas applies, minus\n * the soft falloff (the centre of a soft disc is at full strength).\n */\nexport function additivePlate(ground: Rgb, colour: Rgb, alpha: number, blend: 'lighter' | 'screen'): Rgb {\n const mix = (g: number, c: number): number => {\n const v = c * alpha;\n return blend === 'lighter' ? Math.min(1, g + v) : 1 - (1 - g) * (1 - v);\n };\n return { r: mix(ground.r, colour.r), g: mix(ground.g, colour.g), b: mix(ground.b, colour.b) };\n}\n","/**\n * Layer cohesion — does a layer read as ONE form, or as N separate marks?\n *\n * The gap this closes: every other perception channel reports a heavily\n * overlapping layer identically whether its sprites merge into a silhouette or\n * stay legible as individual discs. Luminance, coverage, dominance and the\n * braille map are all blind to it, because they measure ink, not edges. An\n * agent drawing a *shape* out of sprites therefore cannot tell success from\n * failure without publishing and looking at real pixels.\n *\n * Two independent facts decide it, so both are reported:\n *\n * - `overlap` — geometry. What fraction of a typical entity's outline is buried\n * inside a sibling. Scattered fields sit near 0; a deliberate mass sits high.\n * - `seamless` — paint. Whether an overlap between two of this layer's entities\n * paints as an invisible join. Only a hard-edged, fully opaque, single-colour,\n * un-blended layer merges; anything else shows every internal edge.\n *\n * Both are analytic, deterministic and renderer-free, like the rest of\n * `perceive.ts`.\n */\n\nimport { polygonArea, polygonPoints } from './shapes';\nimport { lifeAlphaAt, positionAt, rotationAt, sizeAt, type Entity } from './simulate';\nimport type { LayerSpec } from './types';\n\n/**\n * Above this mean covered-outline fraction a layer is treated as *trying* to be\n * one form rather than a field of marks.\n *\n * Calibrated against the shipped examples rather than picked. Measured across\n * all 42 fillable layers in `src/examples/`, the particle fields top out at\n * 0.154 (`facets/planes`; snowfall, lanterns and constellation are all 0.000,\n * `comets/stars` 0.001, `aquarium` 0.015, `procession/lanterns` 0.087), while\n * a layer authored as a silhouette — circles packed several times over their\n * own area, the idiom that draws a wave or a mountain — measures 0.79 to 0.85.\n * `aurora`'s wander curtains are the one shipped layer in the upper band, at\n * 0.892, and they are a deliberate overlapping wash. Nothing sits between\n * 0.154 and 0.786, so the exact threshold is not delicate.\n */\nconst MERGE_FLOOR = 0.35;\n\n/**\n * Below this base opacity a heavily overlapping layer is an atmospheric wash by\n * intent — the playbook's own advice is a field of soft circles at alpha ~0.2 —\n * and its visible internal edges are the effect, not a defect. The advisory\n * stays silent there; the numbers are still reported.\n */\nconst WASH_ALPHA_MAX = 0.45;\n\n/**\n * Sample time for a spec-level cohesion read, matching `perceiveScene`'s own\n * default so the advisory and the reported numbers agree on the usual call.\n * Past all typical `life.enter` staging; `grow` has had time to breathe.\n */\nexport const COHESION_T = 5000;\n\n/** Outline samples per entity. 24 resolves a half-covered circle to ~4 %. */\nconst OUTLINE_SAMPLES = 24;\n\n/**\n * Cap on the entities whose outlines are traced. Above this the measured set is\n * a deterministic stride through the layer (every k-th entity); coverage is\n * still tested against *every* sibling, so the estimate stays unbiased.\n */\nconst MAX_TRACED = 240;\n\n/** What a layer will read as on the wall. */\nexport type CohesionRead =\n /** Entities merge into a single silhouette — the layer draws a shape. */\n | 'mass'\n /** Entities overlap heavily but every overlap paints a visible edge. */\n | 'seamed'\n /** Entities stand alone — a field of marks, which most layers are. */\n | 'marks';\n\nexport interface LayerCohesion {\n layerIndex: number;\n key: string | undefined;\n /**\n * Mean fraction of an entity's outline covered by a same-layer sibling, 0..1.\n * `null` for sprite kinds where a merged silhouette is not a meaningful idea\n * (lines, glyphs and text: ring, streak, stroke, bar, emoji, text, textBlock).\n */\n overlap: number | null;\n /** Do this layer's overlaps paint as invisible joins? */\n seamless: boolean;\n /** Why not, when not — the field to act on. `null` when seamless. */\n seamCause: string | null;\n /** The verdict. `null` when `overlap` is null. */\n reads: CohesionRead | null;\n}\n\n// ---------------------------------------------------------------------------\n// Geometry\n// ---------------------------------------------------------------------------\n\ninterface Shape {\n cx: number;\n cy: number;\n /** Bounding radius, for the pairwise prefilter. */\n br: number;\n /** Enclosed area in px². Zero means the sprite paints nothing — collinear\n * polygon vertices reach here with a nonzero bounding radius. */\n area: number;\n contains(x: number, y: number): boolean;\n outline(n: number): Array<{ x: number; y: number }>;\n}\n\n/**\n * Outline samples are stepped this far INSIDE their own shape, as a fraction of\n * its bounding radius, before being tested. The question asked is then \"is the\n * ink just inside my edge also covered?\" rather than \"is a point exactly on my\n * edge inside a sibling?\".\n *\n * Exact-boundary tests are degenerate in both directions: coincident circles\n * sample every point exactly on the sibling's rim, and a polygon point lying on\n * a horizontal edge fails the ray-cast's `(a.y > y) !== (b.y > y)` test — two\n * flat rects sharing a y therefore reported their buried long edges as exposed.\n *\n * The step follows the edge's inward NORMAL, not the direction of the entity\n * centre: a concave polygon can have its centre outside its own filled area, so\n * a centre-directed nudge would push samples across the concavity and out of\n * the shape. Relative, so it holds at any viewport scale, and four orders of\n * magnitude below a pixel for any real sprite.\n */\nconst EDGE_INSET = 1e-4;\n\nfunction circleShape(cx: number, cy: number, r: number): Shape {\n return {\n cx, cy, br: r, area: Math.PI * r * r,\n contains: (x, y) => (x - cx) * (x - cx) + (y - cy) * (y - cy) < r * r,\n outline: (n) => Array.from({ length: n }, (_, i) => {\n const a = (i / n) * Math.PI * 2;\n const inner = r * (1 - EDGE_INSET); // inward normal of a circle is its radius\n return { x: cx + inner * Math.cos(a), y: cy + inner * Math.sin(a) };\n }),\n };\n}\n\n/** A convex or concave polygon given by absolute vertices. */\nfunction polyShape(cx: number, cy: number, raw: Array<{ x: number; y: number }>): Shape | null {\n // Drop consecutive coincident vertices up front. A zero-length edge has no\n // normal to step along, and leaving one in would emit a sample sitting\n // exactly on the boundary — the degeneracy EDGE_INSET exists to avoid.\n const abs = raw.filter((p, i) => {\n const q = raw[(i + 1) % raw.length]!;\n return Math.hypot(q.x - p.x, q.y - p.y) > 0;\n });\n // Fewer than three distinct vertices encloses no area — the renderer fills\n // nothing, so there is no silhouette to ask about.\n if (abs.length < 3) return null;\n\n let br = 0;\n for (const p of abs) br = Math.max(br, Math.hypot(p.x - cx, p.y - cy));\n const inside = (x: number, y: number): boolean => {\n let hit = false;\n for (let i = 0, j = abs.length - 1; i < abs.length; j = i++) {\n const a = abs[i]!;\n const b = abs[j]!;\n if ((a.y > y) !== (b.y > y) && x < ((b.x - a.x) * (y - a.y)) / (b.y - a.y) + a.x) hit = !hit;\n }\n return hit;\n };\n const seg = abs.map((p, i) => {\n const q = abs[(i + 1) % abs.length]!;\n return Math.hypot(q.x - p.x, q.y - p.y);\n });\n const perimeter = seg.reduce((a, b) => a + b, 0);\n // A shape thinner than the nominal inset would have BOTH normal candidates\n // overshoot it, so the step is bounded by the shortest edge as well as by\n // the bounding radius.\n const shortest = Math.min(...seg);\n const step = Math.min(br * EDGE_INSET, shortest * 0.25);\n const area = polygonArea(abs);\n if (!(area > 0)) return null; // collinear vertices enclose nothing\n return {\n cx, cy, br, area,\n contains: inside,\n /**\n * `n` points spread along the perimeter by ARC LENGTH, not one share per\n * edge — a long skinny rectangle has two edges carrying almost all of its\n * perimeter, and an equal-per-edge split would report a fully buried long\n * side as only a quarter covered. Each point is then stepped along its\n * edge's inward normal, whichever of the two candidates lands inside.\n */\n outline: (n) => {\n if (!(perimeter > 0)) return [];\n const out: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < n; i++) {\n let d = (i / n) * perimeter;\n let k = 0;\n while (k < seg.length - 1 && d > seg[k]!) { d -= seg[k]!; k++; }\n const a = abs[k]!;\n const b = abs[(k + 1) % abs.length]!;\n const len = seg[k]!;\n const f = d / len;\n const px = a.x + (b.x - a.x) * f;\n const py = a.y + (b.y - a.y) * f;\n const ux = (b.x - a.x) / len;\n const uy = (b.y - a.y) / len;\n // Back off until a candidate lands inside: a sliver thinner than even\n // the bounded step still gets the best sample available rather than\n // one outside its own shape.\n // A sample that cannot be placed strictly inside is DROPPED rather than\n // emitted on the boundary: an exact-edge point is the degeneracy the\n // inset exists to remove, and reporting it as exposed would be a guess.\n // The caller measures the samples it got, so an unmeasurable sliver\n // reports no outline instead of a wrong one.\n for (let t = step; t > 0; t /= 8) {\n const qx1 = px - uy * t;\n const qy1 = py + ux * t;\n if (inside(qx1, qy1)) { out.push({ x: qx1, y: qy1 }); break; }\n const qx2 = px + uy * t;\n const qy2 = py - ux * t;\n if (inside(qx2, qy2)) { out.push({ x: qx2, y: qy2 }); break; }\n if (t < step * 1e-3) break;\n }\n }\n return out;\n },\n };\n}\n\nfunction rectShape(cx: number, cy: number, halfW: number, halfH: number, rot: number): Shape | null {\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n const corner = (lx: number, ly: number) => ({ x: cx + lx * cos - ly * sin, y: cy + lx * sin + ly * cos });\n return polyShape(cx, cy, [\n corner(-halfW, -halfH), corner(halfW, -halfH), corner(halfW, halfH), corner(-halfW, halfH),\n ]);\n}\n\nfunction polygonShape(cx: number, cy: number, pts: Array<{ x: number; y: number }>, rot: number): Shape | null {\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n return polyShape(cx, cy, pts.map((p) => ({ x: cx + p.x * cos - p.y * sin, y: cy + p.x * sin + p.y * cos })));\n}\n\n/** The shape an entity paints at `t`, or null for kinds with no fillable area. */\nfunction shapeOf(layer: LayerSpec, e: Entity, t: number, w: number, h: number): Shape | null {\n const s = layer.sprite;\n if (s.kind !== 'circle' && s.kind !== 'rect' && s.kind !== 'polygon') return null;\n const p = positionAt(e, t, w, h);\n const sz = sizeAt(e, t);\n if (!(sz > 0)) return null;\n if (s.kind === 'circle') return circleShape(p.x, p.y, sz / 2);\n const rot = rotationAt(e, t);\n if (s.kind === 'rect') {\n const h2 = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz;\n return rectShape(p.x, p.y, sz / 2, h2 / 2, rot);\n }\n return polygonShape(p.x, p.y, polygonPoints(s, sz / 2), rot);\n}\n\n// ---------------------------------------------------------------------------\n// Paint: will an overlap show?\n// ---------------------------------------------------------------------------\n\n/**\n * Why this layer's overlaps paint a visible edge, or null when they vanish.\n *\n * Opacity is judged over the whole timeline, not this instant: a layer that\n * breathes with `pulse` is translucent at some point in every cycle, so its\n * seams appear even if the sampled frame happens to catch it at full alpha.\n */\nexport function seamCauseOf(layer: LayerSpec): string | null {\n const s = layer.sprite;\n if ((s.kind === 'circle' || s.kind === 'polygon') && s.soft) {\n return 'sprite.soft — radial falloff never forms a hard union';\n }\n if (s.kind === 'rect' && s.feather) {\n return 'rect.feather — a feathered edge never forms a hard union';\n }\n if (layer.blend) {\n return `blend: ${layer.blend} — overlaps composite instead of covering`;\n }\n const [lo, hi] = layer.alpha ?? [1, 1];\n if (lo < 1 || hi < 1) {\n return `alpha ${lo === hi ? lo : `${lo}..${hi}`} — every overlap paints a darker patch`;\n }\n if (layer.pulse && layer.pulse.amp > 0) {\n return 'pulse — the layer is translucent for part of every cycle';\n }\n // Only palette entries the seeded pick can actually reach count: a\n // `colorWeights` entry of 0 means that colour is never drawn, so it cannot\n // put a seam between two neighbours.\n const palette = 'colors' in s && Array.isArray(s.colors) ? s.colors : null;\n const weights = 'colorWeights' in s && Array.isArray(s.colorWeights) ? s.colorWeights : null;\n if (palette) {\n const aligned = weights !== null && weights.length === palette.length;\n const reachable = new Set(palette.filter((_, i) => !aligned || (weights![i] ?? 0) > 0));\n if (reachable.size > 1) {\n return `sprite.colors has ${reachable.size} reachable colours — neighbours of unlike colour show their join`;\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Public\n// ---------------------------------------------------------------------------\n\n/**\n * Per-layer cohesion for an already-built scene. Takes entities rather than a\n * spec so `perceiveScene` and `adviseSpec` can each pass the scene they already\n * built instead of building a third one.\n */\nexport function cohesionOf(\n layers: Array<{ layer: LayerSpec; entities: Entity[] }>,\n t: number,\n w: number,\n h: number,\n): LayerCohesion[] {\n return layers.map(({ layer, entities }, layerIndex) => {\n const seamCause = seamCauseOf(layer);\n const base: Omit<LayerCohesion, 'overlap' | 'reads'> = {\n layerIndex,\n key: layer.key,\n seamless: seamCause === null,\n seamCause,\n };\n\n // A layer staged out by `life` paints nothing at this instant, so asking\n // what it reads as has no answer — same as an unsupported sprite kind.\n if (lifeAlphaAt(layer.life, t) <= 0) return { ...base, overlap: null, reads: null };\n\n const shapes: Array<Shape | null> = entities.map((e) => shapeOf(layer, e, t, w, h));\n // A sprite that fills nothing is not a sibling: it cannot cover a\n // neighbour's outline and it must not make a lone sprite look like a pair.\n const solid = shapes.filter((x): x is Shape => x !== null && x.area > 0);\n // A single entity has no sibling to merge with, and unsupported kinds have\n // no fillable outline — in both cases the question does not apply.\n if (solid.length < 2) return { ...base, overlap: null, reads: null };\n\n const stride = Math.max(1, Math.ceil(solid.length / MAX_TRACED));\n let covered = 0;\n let traced = 0;\n for (let i = 0; i < solid.length; i += stride) {\n const self = solid[i]!;\n const pts = self.outline(OUTLINE_SAMPLES);\n if (pts.length === 0) continue; // no measurable outline; not 'exposed'\n let hit = 0;\n for (const p of pts) {\n for (let j = 0; j < solid.length; j++) {\n if (j === i) continue;\n const other = solid[j]!;\n const dx = p.x - other.cx;\n const dy = p.y - other.cy;\n if (dx * dx + dy * dy > other.br * other.br) continue; // cheap reject\n if (other.contains(p.x, p.y)) { hit++; break; }\n }\n }\n covered += hit / pts.length;\n traced++;\n }\n\n if (traced === 0) return { ...base, overlap: null, reads: null };\n const overlap = Number((covered / traced).toFixed(4));\n const reads: CohesionRead = overlap < MERGE_FLOOR ? 'marks' : seamCause === null ? 'mass' : 'seamed';\n return { ...base, overlap, reads };\n });\n}\n\n/**\n * True when a `seamed` layer is worth warning about: dense enough to be\n * deliberate, and opaque enough that it cannot be an atmospheric wash. Keeps\n * the advisory off the soft low-alpha glow fields the playbook recommends.\n */\nexport function seamsWorthWarning(layer: LayerSpec, c: LayerCohesion, entityCount: number): boolean {\n if (c.reads !== 'seamed' || entityCount < 6) return false;\n const [lo, hi] = layer.alpha ?? [1, 1];\n if ((lo + hi) / 2 < WASH_ALPHA_MAX) return false;\n return layer.blend !== 'lighter' && layer.blend !== 'screen';\n}\n","import { createRng } from '@idle-screens/core';\nimport { buildEntities, linkPairs, positionAt } from './simulate';\nimport { LIMITS, type SaverSpec } from './types';\n\nexport interface LayerSnapshot {\n key: string | undefined;\n count: number;\n centroid: { x: number; y: number };\n coverage: number;\n meanAlpha: number;\n linksDrawn: number | null;\n linksExpected: number | null;\n connectedComponents: number | null;\n isolatedNodes: number | null;\n}\n\nexport interface SceneSnapshot {\n t: number;\n viewport: { w: number; h: number };\n layers: LayerSnapshot[];\n warnings: string[];\n}\n\nexport interface SceneDescription {\n spec: { id: string; label: string; units: string };\n snapshots: SceneSnapshot[];\n}\n\n/**\n * Deterministic scene analysis at one or more time values. Reuses `buildEntities`\n * and `linkPairs` — no render needed. Returns structured data a non-vision model\n * can use to understand what a spec looks like when rendered.\n */\nexport function describeScene(\n spec: SaverSpec,\n options: {\n viewport?: { width: number; height: number };\n seed?: number;\n times?: number[];\n } = {},\n): SceneDescription {\n const { width: w, height: h } = options.viewport ?? { width: 1920, height: 1080 };\n const seed = options.seed ?? spec.seed ?? 42;\n const times = options.times ?? [0, 5000, 15000];\n const scale = spec.units === 'viewport' ? Math.min(w, h) : 1;\n const refVp = spec.referenceViewport ?? LIMITS.referenceViewport;\n const countScale = scale > 1 ? Math.min(w, h) / refVp : 1;\n\n const rng = createRng(seed);\n const builtLayers = spec.layers.map((layer) => ({\n layer,\n entities: buildEntities(layer, rng, w, h, scale, countScale),\n }));\n\n const snapshots: SceneSnapshot[] = times.map((t) => {\n const layerSnapshots: LayerSnapshot[] = builtLayers.map(({ layer, entities }) => {\n const positions = entities.map((e) => positionAt(e, t, w, h));\n const cx = positions.length > 0 ? positions.reduce((s, p) => s + p.x, 0) / positions.length : 0;\n const cy = positions.length > 0 ? positions.reduce((s, p) => s + p.y, 0) / positions.length : 0;\n\n // Coverage: fraction of viewport area covered by entity bounding circles\n let pixArea = 0;\n for (const e of entities) {\n const r = e.size / 2;\n pixArea += layer.sprite.kind === 'circle' ? Math.PI * r * r : e.size * e.size;\n }\n const coverage = pixArea / (w * h);\n const meanAlpha = entities.length > 0\n ? entities.reduce((s, e) => s + e.alpha, 0) / entities.length\n : 0;\n\n // Link analysis\n let linksDrawn: number | null = null;\n let linksExpected: number | null = null;\n let connectedComponents: number | null = null;\n let isolatedNodes: number | null = null;\n if (layer.links) {\n const maxDist = layer.links.maxDist * scale;\n const pairs = linkPairs(positions, layer.links.k, maxDist, layer.wrap !== false, w, h);\n linksDrawn = pairs.length;\n linksExpected = Math.min(entities.length * layer.links.k, entities.length * (entities.length - 1) / 2);\n // Connected components via union-find\n const parent = Array.from({ length: entities.length }, (_, i) => i);\n const find = (x: number): number => {\n while (parent[x] !== x) { parent[x] = parent[parent[x]!]!; x = parent[x]!; }\n return x;\n };\n for (const [a, b] of pairs) {\n const ra = find(a); const rb = find(b);\n if (ra !== rb) parent[ra] = rb;\n }\n const roots = new Set(entities.map((_, i) => find(i)));\n connectedComponents = roots.size;\n // Isolated = nodes with zero edges\n const degree = new Uint16Array(entities.length);\n for (const [a, b] of pairs) { degree[a]!++; degree[b]!++; }\n isolatedNodes = degree.filter((d) => d === 0).length;\n }\n\n return {\n key: layer.key,\n count: entities.length,\n centroid: { x: +(cx / w).toFixed(3), y: +(cy / h).toFixed(3) },\n coverage: +coverage.toFixed(4),\n meanAlpha: +meanAlpha.toFixed(3),\n linksDrawn,\n linksExpected,\n connectedComponents,\n isolatedNodes,\n };\n });\n\n // Warnings derived from the numbers\n const warnings: string[] = [];\n for (const ls of layerSnapshots) {\n const label = ls.key ?? `layer`;\n if (ls.coverage * ls.meanAlpha < 0.0005) {\n warnings.push(`${label}: effectively invisible (coverage×alpha=${(ls.coverage * ls.meanAlpha).toFixed(5)})`);\n }\n if (ls.linksDrawn !== null && ls.linksExpected !== null && ls.linksExpected > 0) {\n const ratio = ls.linksDrawn / ls.linksExpected;\n if (ratio < 0.1) {\n warnings.push(`${label}: link starvation — ${ls.linksDrawn}/${ls.linksExpected} edges formed`);\n }\n }\n if (ls.isolatedNodes !== null && ls.count > 0 && ls.isolatedNodes / ls.count > 0.5) {\n warnings.push(`${label}: ${ls.isolatedNodes}/${ls.count} nodes isolated — graph is disconnected`);\n }\n }\n\n return { t, viewport: { w, h }, layers: layerSnapshots, warnings };\n });\n\n return {\n spec: { id: spec.id, label: spec.label, units: spec.units ?? 'px' },\n snapshots,\n };\n}\n","/**\n * Perception tools for non-vision agents. Everything here is computed\n * ANALYTICALLY from the spec — positions, sizes, and alphas are pure functions\n * of (seed, t), so no canvas or renderer is involved: these run in Node, are\n * fully deterministic, and are cheap enough to call in an authoring loop.\n *\n * The design premise: a text model doesn't need mimicked eyes, it needs vision\n * translated into modalities it is already strong in —\n * - a compact PICTURE it can actually read (braille luminance map: each Unicode\n * braille char encodes a 2×4 dot cell, ~8× ASCII resolution per token),\n * - 1D structure (row/column luminance profiles — the skeleton of a composition),\n * - OBJECT-level ranking (dominance: where does the eye go),\n * - RELATIVE judgement (diffScenes: \"is B better than A\" beats \"is A good\"),\n * - MOTION as numbers (per-layer displacement stats).\n */\nimport { createRng } from '@idle-screens/core';\nimport { adviseSpec } from './advise';\nimport { cohesionOf, type LayerCohesion } from './cohesion';\nimport { backgroundLuma, hexLuma, spriteLuma } from './luma';\nimport { barBox, barFraction, pathLength, polygonArea, polygonFill, polygonPoints, strokeSamples, strokeTaper, strokeWidthPx } from './shapes';\nimport {\n alphaAt,\n breakTextBlock,\n buildEntities,\n headingAt,\n lifeAlphaAt,\n linkEdges,\n positionAt,\n revealState,\n rotationAt,\n sizeAt,\n textBlockAnchorOffset,\n textMetricsClassFor,\n type Entity,\n} from './simulate';\nimport { bedRenderSeed, resolveSegment, segmentRenderSeed } from './sequence';\nimport { LIMITS, type IdleSequence, type LayerSpec, type SaverSpec } from './types';\n\n// ---------------------------------------------------------------------------\n// Calibration constants\n//\n// The two knobs that tune how closely this analytical model matches the real\n// canvas. Kept together at module level so a calibration pass has one place to\n// look — neither is a per-entity detail.\n// ---------------------------------------------------------------------------\n\n/**\n * How far an additive glow blooms past its radius, as a multiple of that radius.\n * A soft circle drawn with `lighter`/`screen` spreads well beyond its geometric\n * edge on the real canvas (shadowBlur halos, stacked soft discs), so a\n * hard-edged analytical disc badly under-reports coverage for glow-heavy scenes.\n *\n * First pass, tuned by intuition rather than measurement: it fixes the direction\n * and rough magnitude, not the exact number. A playground-calibrated value is\n * future work (docs/future-ideas.md G1).\n */\nconst GLOW_SPREAD = 2.4;\n\n/**\n * How much more visually prominent line-like ink is than the same area of fill.\n * Rings, streaks and link lines catch the eye far more than their pixel area\n * implies, so weighting dominance by raw area alone makes a bright ring lose to\n * a dim disc. Also a first-pass estimate.\n */\nconst LINE_SALIENCE = 3.5;\n\n/**\n * How many past-frame samples model the `ghosting` smear. The live renderer\n * composites every 60 fps frame with persistence `g`, so ink from m frames ago\n * survives at weight g^m; the analytic model samples that decay at GHOST_TAPS\n * points across the visible window (until weight falls below 1/255, capped at\n * LIMITS.maxGhostReplayFrames — the same bound as the renderer's seek warm-up\n * replay), each tap carrying its bracket's summed weight. More taps sharpen the\n * smear's shape; the total energy is set by `g`, not by this constant.\n */\nconst GHOST_TAPS = 12;\n\n// ---------------------------------------------------------------------------\n// Shared scene construction (mirrors describeScene/adviseSpec)\n// ---------------------------------------------------------------------------\n\ninterface BuiltScene {\n w: number;\n h: number;\n scale: number;\n layers: Array<{ layer: LayerSpec; entities: Entity[] }>;\n byKey: Map<string, Entity[]>;\n}\n\nexport interface PerceiveOptions {\n viewport?: { width: number; height: number };\n seed?: number;\n /** Sample time in ms. Default 5000 (past all typical life.enter staging). */\n t?: number;\n}\n\nfunction buildScene(spec: SaverSpec, opts: PerceiveOptions): BuiltScene {\n const { width: w, height: h } = opts.viewport ?? { width: 1920, height: 1080 };\n const seed = opts.seed ?? spec.seed ?? 42;\n const scale = spec.units === 'px' ? 1 : Math.min(w, h);\n const refVp = spec.referenceViewport ?? LIMITS.referenceViewport;\n let countScale = scale > 1 ? Math.min(w, h) / refVp : 1;\n if (countScale > 1) {\n const rawTotal = spec.layers.reduce((s, l) => s + Math.round(l.count * countScale), 0);\n if (rawTotal > LIMITS.maxTotal) countScale *= LIMITS.maxTotal / rawTotal;\n }\n const rng = createRng(seed);\n const layers = spec.layers.map((layer) => ({ layer, entities: buildEntities(layer, rng, w, h, scale, countScale) }));\n const byKey = new Map<string, Entity[]>();\n for (const { layer, entities } of layers) if (layer.key) byKey.set(layer.key, entities);\n return { w, h, scale, layers, byKey };\n}\n\n/** Position with layer-parented-orbit resolution (matches the renderer). */\nfunction posOf(scene: BuiltScene, e: Entity, t: number): { x: number; y: number } {\n const p = positionAt(e, t, scene.w, scene.h);\n if (e.orbitParent) {\n const parent = scene.byKey.get(e.orbitParent)?.[0];\n if (parent) {\n const pp = positionAt(parent, t, scene.w, scene.h);\n p.x += pp.x;\n p.y += pp.y;\n }\n }\n return p;\n}\n\n/**\n * Text bounding box + anchor, matching the renderer's font rule: a CSS\n * shorthand containing a px size overrides the seeded per-entity size.\n * Returns the box CENTRE (accounting for align/baseline) and half-extents.\n */\nfunction textBox(\n s: Extract<LayerSpec['sprite'], { kind: 'text' }>,\n e: Entity,\n p: { x: number; y: number },\n): { cx: number; cy: number; halfX: number; halfY: number } {\n const m = s.font ? /(\\d+(?:\\.\\d+)?)px/.exec(s.font) : null;\n const fh = m ? Number(m[1]) : e.size;\n const str = s.strings[e.spriteIndex] ?? s.strings[0] ?? '';\n const fw = Math.max(fh, 0.62 * fh * Math.min(str.length, 48));\n const align = s.align ?? 'center';\n const baseline = s.baseline ?? 'middle';\n return {\n cx: align === 'left' ? p.x + fw / 2 : align === 'right' ? p.x - fw / 2 : p.x,\n cy: baseline === 'top' ? p.y + fh * 0.6 : baseline === 'bottom' ? p.y - fh * 0.6 : p.y,\n halfX: fw / 2,\n halfY: fh * 0.6,\n };\n}\n\nfunction textBlockBox(\n s: Extract<LayerSpec['sprite'], { kind: 'textBlock' }>,\n _e: Entity,\n p: { x: number; y: number },\n w: number,\n h: number,\n): { cx: number; cy: number; halfX: number; halfY: number } {\n const unitScale = Math.min(w, h);\n const fsPx = s.fontSize * unitScale;\n const lh = (s.lineHeight ?? 1.4) * fsPx;\n const maxWPx = s.maxWidth * unitScale;\n const maxWEm = maxWPx / fsPx;\n const lines = breakTextBlock(s.text, maxWEm, textMetricsClassFor(s.font));\n const totalH = lines.length * lh;\n const maxLineW = lines.reduce((m, l) => Math.max(m, l.widthEm), 0) * fsPx;\n const align = s.align ?? 'left';\n const cx = align === 'center' ? p.x + maxWPx / 2\n : align === 'right' ? p.x + maxWPx - maxLineW / 2\n : p.x + maxLineW / 2;\n // Anchor moves the whole block the same way the renderer does (0,0 when absent).\n const { dx, dy } = textBlockAnchorOffset(s, maxWPx, maxLineW, totalH);\n return {\n cx: cx + dx,\n cy: p.y + totalH / 2 + dy,\n halfX: maxLineW / 2,\n halfY: totalH / 2,\n };\n}\n\n/**\n * Effective reveal fraction of a textBlock at time t (1 = fully shown).\n * Mirrors the renderer's `revealState` exactly — same line breaking, same\n * grapheme counting — so the perceived ink matches the painted ink.\n */\nfunction textBlockRevealFraction(\n s: Extract<LayerSpec['sprite'], { kind: 'textBlock' }>,\n w: number,\n h: number,\n t: number,\n): number {\n if (!s.reveal) return 1;\n const unitScale = Math.min(w, h);\n const maxWEm = (s.maxWidth * unitScale) / (s.fontSize * unitScale);\n const lines = breakTextBlock(s.text, maxWEm, textMetricsClassFor(s.font));\n const rs = revealState(lines, s.reveal, t);\n if (rs.glyphAlphas) {\n // glyphFade paints partial-alpha glyphs, so the ink fraction is the mean\n // glyph alpha, not the frontier progress.\n let sum = 0;\n let n = 0;\n for (const line of rs.glyphAlphas) for (const a of line) { sum += a; n++; }\n return n > 0 ? sum / n : 1;\n }\n return rs.progress;\n}\n\n// ---------------------------------------------------------------------------\n// Luminance grid\n// ---------------------------------------------------------------------------\n\nexport interface LuminanceGrid {\n cols: number;\n rows: number;\n /** Row-major luminance 0..1 including the background. */\n cells: number[];\n /** Per-row background luminance (what an empty scene would be). */\n background: number[];\n meanLuminance: number;\n /** Fraction of cells deviating perceptibly (> 0.03) from the background. */\n coverage: number;\n /** Deviation-weighted centre of visual mass as viewport fractions, or null for a flat scene. */\n centroid: { x: number; y: number } | null;\n /** Mean deviation-from-background per row/column — 1D transects of the composition. */\n rowProfile: number[];\n colProfile: number[];\n}\n\nexport interface LuminanceGridOptions extends PerceiveOptions {\n /** Grid resolution. Defaults 80×48 (→ a 40×12 braille map). */\n cols?: number;\n rows?: number;\n}\n\n/**\n * Sample the spec into a coarse luminance image — analytically, no renderer.\n * Persistence is modeled, not simulated: because positions are pure functions\n * of (seed, t), `ghosting` is a decayed sum of past-frame splats (weight g^m\n * for ink m frames old, mirroring the renderer's warm-up replay) and `trail`\n * re-uses drawTrail's sampling — past positions with decaying alpha and\n * shrinking radius. Remaining approximations (documented, deliberate): soft\n * circles use a linear falloff, background drift is sampled at its rest\n * position. Good enough to perceive composition, focus, balance — and now\n * smear.\n */\nexport function luminanceGrid(spec: SaverSpec, opts: LuminanceGridOptions = {}): LuminanceGrid {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const cols = Math.max(8, Math.min(200, opts.cols ?? 80));\n const rows = Math.max(8, Math.min(200, opts.rows ?? 48));\n const { w, h, scale } = scene;\n const cellW = w / cols;\n const cellH = h / rows;\n\n // Background: vertical gradient (or solid) + optional bottom band.\n const bg = spec.background;\n const bgRow: number[] = new Array(rows).fill(0);\n if (!bg || bg.type === 'solid') {\n bgRow.fill(hexLuma(bg?.color ?? '#05050a'));\n } else {\n const stops = [...bg.stops].sort((a, b) => a.at - b.at);\n for (let r = 0; r < rows; r++) {\n const y = (r + 0.5) / rows;\n let lum: number;\n if (y <= stops[0]!.at) lum = hexLuma(stops[0]!.color);\n else if (y >= stops[stops.length - 1]!.at) lum = hexLuma(stops[stops.length - 1]!.color);\n else {\n let i = 0;\n while (i < stops.length - 1 && stops[i + 1]!.at < y) i++;\n const a = stops[i]!;\n const b = stops[i + 1]!;\n const k = b.at === a.at ? 0 : (y - a.at) / (b.at - a.at);\n lum = hexLuma(a.color) + (hexLuma(b.color) - hexLuma(a.color)) * k;\n }\n bgRow[r] = lum;\n }\n if (bg.band) {\n const bandPx = bg.band.height * (spec.units === 'px' ? 1 : Math.min(w, h));\n const fromRow = Math.max(0, Math.floor((h - bandPx) / cellH));\n for (let r = fromRow; r < rows; r++) bgRow[r] = hexLuma(bg.band.color);\n }\n }\n\n const cells = new Array<number>(cols * rows);\n for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) cells[r * cols + c] = bgRow[r]!;\n\n const compose = (idx: number, lum: number, a: number, blend: LayerSpec['blend']): void => {\n const cur = cells[idx]!;\n if (blend === 'lighter' || blend === 'screen') cells[idx] = Math.min(1, cur + lum * a);\n else if (blend === 'multiply') cells[idx] = cur * (1 - a * (1 - lum));\n else cells[idx] = cur * (1 - a) + lum * a;\n };\n\n // Afterglow dots behind a moving entity — the analytic mirror of the\n // renderer's drawTrail: past positions sampled with decaying alpha and\n // shrinking radius, stopping at wrap seams.\n const splatTrail = (layer: LayerSpec, e: Entity, tPass: number, lifeA: number, alphaScale: number): void => {\n const trail = layer.trail;\n if (!trail) return;\n const fade = trail.fade ?? 1;\n const n = Math.min(Math.ceil(trail.length / 50), LIMITS.maxTrailSamples);\n const headAlpha = alphaAt(e, tPass) * lifeA;\n const headSize = sizeAt(e, tPass);\n const lum = spriteLuma(layer, e);\n const soft = layer.sprite.kind === 'circle' && !!layer.sprite.soft;\n const wrapOn = layer.wrap !== false;\n const head = posOf(scene, e, tPass);\n let prevX = head.x;\n let prevY = head.y;\n for (let s = 1; s <= n; s++) {\n const k = s / n;\n const pastT = tPass - k * trail.length;\n if (pastT < 0) break;\n const pos = posOf(scene, e, pastT);\n if (wrapOn && (Math.abs(pos.x - prevX) > w / 2 || Math.abs(pos.y - prevY) > h / 2)) break;\n prevX = pos.x;\n prevY = pos.y;\n const a = headAlpha * (1 - k * fade) * alphaScale;\n if (a <= 0.004) break;\n const rad = (headSize / 2) * (1 - k * 0.7);\n if (rad < 0.2) break;\n const c0 = Math.max(0, Math.floor((pos.x - rad) / cellW));\n const c1 = Math.min(cols - 1, Math.floor((pos.x + rad) / cellW));\n const r0 = Math.max(0, Math.floor((pos.y - rad) / cellH));\n const r1 = Math.min(rows - 1, Math.floor((pos.y + rad) / cellH));\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const dx = (c + 0.5) * cellW - pos.x;\n const dy = (r + 0.5) * cellH - pos.y;\n const d = Math.sqrt(dx * dx + dy * dy);\n if (d > rad + Math.min(cellW, cellH) / 2) continue;\n const wgt = soft ? Math.max(0.1, 1 - d / Math.max(rad, 1e-6)) : 1;\n compose(r * cols + c, lum, Math.min(1, a * wgt), layer.blend);\n }\n }\n }\n };\n\n // One composite pass at time tPass with all ink scaled by alphaScale — the\n // analytic mirror of the renderer's paintFrame. Ghost passes call this with\n // decayed weights; the live frame calls it with alphaScale 1.\n const splatPass = (tPass: number, alphaScale: number): void => {\n for (const { layer, entities } of scene.layers) {\n const lifeA = lifeAlphaAt(layer.life, tPass);\n if (lifeA <= 0) continue;\n\n for (const e of entities) {\n splatTrail(layer, e, tPass, lifeA, alphaScale);\n const a = Math.min(1, alphaAt(e, tPass) * lifeA) * alphaScale;\n if (a <= 0.004) continue;\n const lum = spriteLuma(layer, e);\n const p = posOf(scene, e, tPass);\n const sz = sizeAt(e, tPass);\n const s = layer.sprite;\n\n if (s.kind === 'stroke') {\n // Stamp along the sampled path, rotated like the renderer does.\n const pts = strokeSamples(s, sz / 2);\n let angle = rotationAt(e, tPass);\n if (s.orient) angle += headingAt(e, tPass, w, h) ?? 0;\n const ca = Math.cos(angle);\n const sa = Math.sin(angle);\n const lw = strokeWidthPx(s, scale);\n const stampAt = (q: { x: number; y: number }, u: number): void => {\n const x = p.x + q.x * ca - q.y * sa;\n const y = p.y + q.x * sa + q.y * ca;\n const c = Math.floor(x / cellW);\n const r = Math.floor(y / cellH);\n if (c < 0 || c >= cols || r < 0 || r >= rows) return;\n const taper = s.taper ? strokeTaper(u) : 1;\n compose(r * cols + c, lum, a * Math.min(1, (lw * taper) / cellH), layer.blend);\n };\n // Rasterize each segment at half-cell steps so a long stroke leaves a\n // continuous line of ink, not a dotted one.\n const step = Math.min(cellW, cellH) / 2;\n stampAt(pts[0]!, 0);\n for (let i = 1; i < pts.length; i++) {\n const q0 = pts[i - 1]!;\n const q1 = pts[i]!;\n const segLen = Math.hypot(q1.x - q0.x, q1.y - q0.y);\n const sub = Math.max(1, Math.ceil(segLen / step));\n for (let k = 1; k <= sub; k++) {\n const f = k / sub;\n stampAt({ x: q0.x + (q1.x - q0.x) * f, y: q0.y + (q1.y - q0.y) * f }, (i - 1 + f) / (pts.length - 1));\n }\n }\n continue;\n }\n if (s.kind === 'streak') {\n // Stamp along the segment from tail to head.\n const heading = headingAt(e, tPass, w, h) ?? 0;\n const steps = Math.max(2, Math.ceil(sz / Math.min(cellW, cellH)));\n const wgt = Math.min(1, ((s.width ?? (scale === 1 ? 2 : 0.002)) * scale) / cellH);\n for (let i = 0; i <= steps; i++) {\n const k = i / steps;\n const x = p.x - Math.cos(heading) * sz * (1 - k);\n const y = p.y - Math.sin(heading) * sz * (1 - k);\n const c = Math.floor(x / cellW);\n const r = Math.floor(y / cellH);\n if (c < 0 || c >= cols || r < 0 || r >= rows) continue;\n compose(r * cols + c, lum, a * k * wgt, layer.blend);\n }\n continue;\n }\n\n let centerX = p.x;\n let centerY = p.y;\n let halfX = sz / 2;\n let halfY = s.kind === 'rect' ? ((e.size2 ?? sz) * (e.size > 0 ? sz / e.size : 1)) / 2 : sz / 2;\n if (s.kind === 'text') {\n const box = textBox(s, e, p);\n centerX = box.cx;\n centerY = box.cy;\n halfX = box.halfX;\n halfY = box.halfY;\n } else if (s.kind === 'textBlock') {\n const box = textBlockBox(s, e, p, w, h);\n centerX = box.cx;\n centerY = box.cy;\n halfX = box.halfX;\n halfY = box.halfY;\n } else if (s.kind === 'bar') {\n const len = sz * barFraction(s, e.barIndex ?? 0);\n if (len <= 0) continue;\n const th = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz * 0.2;\n const box = barBox(s.direction ?? 'right', len, th);\n // The renderer rotates the bar about the entity with `spin`; rotate\n // the box's offset the same way and take the rotated box's AABB.\n const rot = rotationAt(e, tPass);\n const cr = Math.cos(rot);\n const sr = Math.sin(rot);\n centerX = p.x + box.cx * cr - box.cy * sr;\n centerY = p.y + box.cx * sr + box.cy * cr;\n halfX = Math.abs(box.halfX * cr) + Math.abs(box.halfY * sr);\n halfY = Math.abs(box.halfX * sr) + Math.abs(box.halfY * cr);\n }\n const circular = s.kind === 'circle' || s.kind === 'ring' || s.kind === 'polygon';\n const soft = (s.kind === 'circle' || s.kind === 'polygon') && !!s.soft;\n // A polygon fills only part of its disc; a feathered rect only part of\n // its box. Scale the splat weight rather than trace the outline.\n const shapeWeight = s.kind === 'polygon'\n ? polygonFill(s, sz / 2)\n : s.kind === 'rect' && s.feather\n ? (1 - s.feather / 2) * (1 - s.feather / 2)\n : 1;\n const additive = layer.blend === 'lighter' || layer.blend === 'screen';\n // Model the halo (see GLOW_SPREAD): reach past the radius with a quadratic\n // falloff outside the solid core, so coverage tracks what the audience\n // actually sees. Non-additive / hard-edged sprites are unchanged.\n const glow = soft && additive;\n const reachX = glow ? halfX * GLOW_SPREAD : halfX;\n const reachY = glow ? halfY * GLOW_SPREAD : halfY;\n const c0 = Math.max(0, Math.floor((centerX - reachX) / cellW));\n const c1 = Math.min(cols - 1, Math.floor((centerX + reachX) / cellW));\n const r0 = Math.max(0, Math.floor((centerY - reachY) / cellH));\n const r1 = Math.min(rows - 1, Math.floor((centerY + reachY) / cellH));\n // Glyphs don't fill their box — ink is sparse. A revealing textBlock\n // has proportionally less ink lit.\n const inkWeight = (s.kind === 'text' || s.kind === 'emoji' || s.kind === 'textBlock' ? 0.55 : 1)\n * (s.kind === 'textBlock' ? textBlockRevealFraction(s, w, h, t) * (s.opacity ?? 1) : 1);\n for (let r = r0; r <= r1; r++) {\n for (let c = c0; c <= c1; c++) {\n const dx = (c + 0.5) * cellW - centerX;\n const dy = (r + 0.5) * cellH - centerY;\n if (circular) {\n const d = Math.sqrt(dx * dx + dy * dy);\n const reach = glow ? reachX : halfX;\n if (d > reach + Math.min(cellW, cellH) / 2) continue;\n if (s.kind === 'ring') {\n const strokeW = (s.width ?? (scale === 1 ? 2 : 0.002)) * scale;\n if (d < halfX - strokeW) continue;\n }\n let wgt: number;\n if (glow) {\n const core = halfX;\n if (d <= core) wgt = 1;\n else {\n const f = Math.max(0, 1 - (d - core) / Math.max(reachX - core, 1e-6));\n wgt = f * f;\n }\n } else {\n wgt = soft ? Math.max(0.1, 1 - d / Math.max(halfX, 1e-6)) : 1;\n }\n compose(r * cols + c, lum, a * wgt * shapeWeight, layer.blend);\n } else {\n compose(r * cols + c, lum, a * inkWeight * shapeWeight, layer.blend);\n }\n }\n }\n }\n\n // Link lines are visual mass too (for chain scenes they ARE the scene).\n if (layer.links) {\n const positions = entities.map((e) => posOf(scene, e, tPass));\n const maxDistPx = layer.links.maxDist * scale;\n const motionWraps = ['drift', 'rise', 'wander'].includes(layer.motion.type);\n const edges = linkEdges(layer.links, positions, maxDistPx, layer.wrap !== false && motionWraps, w, h);\n const la = Math.min(1, (layer.links.alpha ?? 0.6) * lifeA);\n const lum = layer.links.color ? hexLuma(layer.links.color) : 0.7;\n const defaultWidth = scale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const wgt = Math.min(1, ((layer.links.width ?? defaultWidth) * scale) / cellH) * la * alphaScale;\n for (const edge of edges) {\n const pi = positions[edge.i]!;\n const pj = positions[edge.j]!;\n const steps = Math.max(1, Math.ceil(edge.dist / Math.min(cellW, cellH)));\n for (let i = 0; i <= steps; i++) {\n const k = i / steps;\n const c = Math.floor((pi.x + (pj.x - pi.x) * k) / cellW);\n const r = Math.floor((pi.y + (pj.y - pi.y) * k) / cellH);\n if (c < 0 || c >= cols || r < 0 || r >= rows) continue;\n compose(r * cols + c, lum, wgt, layer.blend);\n }\n }\n }\n }\n };\n\n // Ghosting: the renderer composites each 60 fps frame over the last with\n // persistence g, so ink from m frames ago survives at weight g^m. Sample\n // that decay across the visible window (weight ≥ 1/255, capped at the same\n // maxGhostReplayFrames bound as the renderer's seek replay), oldest first so\n // newer ink composites on top. Each tap stands in for the frames in its\n // bracket and carries their summed surviving weight (geometric sum).\n const ghost = spec.ghosting ?? 0;\n if (ghost > 0) {\n const dt = 1000 / 60;\n const windowFrames = Math.min(Math.ceil(Math.log(1 / 255) / Math.log(ghost)), LIMITS.maxGhostReplayFrames);\n const taps = Math.min(GHOST_TAPS, windowFrames);\n const spacing = windowFrames / taps;\n for (let i = taps; i >= 1; i--) {\n const tPass = t - i * spacing * dt;\n if (tPass < 0) continue;\n const bracketWeight =\n (Math.pow(ghost, (i - 1) * spacing + 1) * (1 - Math.pow(ghost, spacing))) / (1 - ghost);\n splatPass(tPass, Math.min(1, bracketWeight));\n }\n }\n splatPass(t, 1);\n\n // Deviation stats\n return finishGrid(cols, rows, cells, bgRow);\n}\n\n/** The stats every grid carries, from its cells and per-row background. */\nfunction finishGrid(cols: number, rows: number, cells: number[], bgRow: number[]): LuminanceGrid {\n let sum = 0;\n let covered = 0;\n let devSum = 0;\n let cxAcc = 0;\n let cyAcc = 0;\n const rowProfile = new Array<number>(rows).fill(0);\n const colProfile = new Array<number>(cols).fill(0);\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const v = cells[r * cols + c]!;\n sum += v;\n const dev = Math.abs(v - bgRow[r]!);\n if (dev > 0.03) covered++;\n devSum += dev;\n cxAcc += dev * (c + 0.5);\n cyAcc += dev * (r + 0.5);\n rowProfile[r]! += dev;\n colProfile[c]! += dev;\n }\n }\n for (let r = 0; r < rows; r++) rowProfile[r] = rowProfile[r]! / cols;\n for (let c = 0; c < cols; c++) colProfile[c] = colProfile[c]! / rows;\n\n return {\n cols,\n rows,\n cells,\n background: bgRow,\n meanLuminance: sum / (cols * rows),\n coverage: covered / (cols * rows),\n centroid: devSum > 1e-6 ? { x: cxAcc / devSum / cols, y: cyAcc / devSum / rows } : null,\n rowProfile,\n colProfile,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Braille rendering\n// ---------------------------------------------------------------------------\n\n// Ordered-dither thresholds for a 2×4 braille cell (spatially spread).\nconst DITHER: number[][] = [\n [0.5 / 8, 4.5 / 8],\n [2.5 / 8, 6.5 / 8],\n [1.5 / 8, 5.5 / 8],\n [3.5 / 8, 7.5 / 8],\n];\n// Braille dot bit for (row 0..3, col 0..1): dots 1-2-3-7 left, 4-5-6-8 right.\nconst DOT_BIT: number[][] = [\n [0x01, 0x08],\n [0x02, 0x10],\n [0x04, 0x20],\n [0x40, 0x80],\n];\n\n/**\n * Auto-exposure curve for a grid: most savers live in the bottom of the\n * luminance range, so cells are normalized (min → 98th percentile) with a\n * slight gamma before quantizing — like a camera exposing for the scene. Stats\n * on the grid itself stay raw.\n *\n * Shared by every renderer below, deliberately: if the curve is ever\n * recalibrated (e.g. once GLOW_SPREAD is tuned and coverage shifts), the braille\n * and density views must move together or they'd silently disagree about the\n * same scene.\n */\nfunction autoExpose(grid: LuminanceGrid): (v: number) => number {\n const sorted = [...grid.cells].sort((a, b) => a - b);\n const lo = sorted[0]!;\n const hi = Math.max(sorted[Math.floor(sorted.length * 0.98)]!, lo + 0.08);\n return (v: number): number => Math.pow(Math.max(0, Math.min(1, (v - lo) / (hi - lo))), 0.8);\n}\n\n/**\n * Encode a luminance grid as a braille \"image\": each output character is a 2×4\n * pixel cell, ordered-dithered so mid-tones render as dot density. A grid of\n * 80×48 becomes 12 lines of 40 chars — a picture a text model can read whole.\n */\nexport function renderBrailleMap(grid: LuminanceGrid): string {\n const expose = autoExpose(grid);\n\n const outRows: string[] = [];\n for (let br = 0; br < Math.floor(grid.rows / 4); br++) {\n let line = '';\n for (let bc = 0; bc < Math.floor(grid.cols / 2); bc++) {\n let bits = 0;\n for (let dr = 0; dr < 4; dr++) {\n for (let dc = 0; dc < 2; dc++) {\n const v = expose(grid.cells[(br * 4 + dr) * grid.cols + (bc * 2 + dc)]!);\n if (v > DITHER[dr]![dc]!) bits |= DOT_BIT[dr]![dc]!;\n }\n }\n line += String.fromCharCode(0x2800 + bits);\n }\n outRows.push(line);\n }\n return outRows.join('\\n');\n}\n\n// Density ramp, dark → bright. One char per grid cell (vs braille's 2×4), so a\n// higher-resolution grid reads as a sharper picture — the channel agents found\n// most legible for structure (rings, grids, text blocks) that braille blurs.\nconst DENSITY_RAMP = ' .:-=+*#%@';\n\n/**\n * Encode a luminance grid as a one-char-per-cell ASCII density map. Unlike the\n * braille map (compact, 2×4 dots/char) this is 1:1 with the grid, so pairing it\n * with a larger `cols`/`rows` gives a non-vision agent a genuinely higher-detail\n * read: 120×48 resolves concentric rings and text blocks braille smears into a\n * blob. Shares the braille map's auto-exposure so both views agree.\n */\nexport function renderDensityMap(grid: LuminanceGrid): string {\n const expose = autoExpose(grid);\n const ramp = DENSITY_RAMP;\n const lines: string[] = [];\n for (let r = 0; r < grid.rows; r++) {\n let line = '';\n for (let c = 0; c < grid.cols; c++) {\n const v = expose(grid.cells[r * grid.cols + c]!);\n line += ramp[Math.min(ramp.length - 1, Math.floor(v * ramp.length))]!;\n }\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Text sprite listing\n// ---------------------------------------------------------------------------\n\nexport interface TextSpriteInfo {\n layerIndex: number;\n key: string | undefined;\n /** The literal strings this layer draws (glyphs are invisible in the maps). */\n strings: string[];\n /** How many entities carry text. */\n count: number;\n /** Representative rendered glyph height in px at the sample viewport. */\n sizePx: number;\n /** For a revealing textBlock: effective 0..1 fraction shown at sample t. */\n revealed?: number;\n}\n\n/**\n * List every text layer's actual strings and rendered size. No grid resolution\n * renders glyphs legibly, so a non-vision agent otherwise can't tell whether the\n * words it wrote are on screen, how big, or whether they'll overlap. This closes\n * that blind spot analytically.\n */\nexport function textSprites(spec: SaverSpec, opts: PerceiveOptions = {}): TextSpriteInfo[] {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const out: TextSpriteInfo[] = [];\n scene.layers.forEach(({ layer, entities }, layerIndex) => {\n if (layer.sprite.kind === 'textBlock') {\n const s = layer.sprite;\n const unitScale = Math.min(scene.w, scene.h);\n const sizePx = s.fontSize * unitScale;\n const info: TextSpriteInfo = { layerIndex, key: layer.key, strings: [s.text], count: entities.length, sizePx: Math.round(sizePx) };\n if (s.reveal) info.revealed = Math.round(textBlockRevealFraction(s, scene.w, scene.h, t) * 100) / 100;\n out.push(info);\n return;\n }\n if (layer.sprite.kind !== 'text') return;\n const s = layer.sprite;\n const m = s.font ? /(\\d+(?:\\.\\d+)?)px/.exec(s.font) : null;\n const sizePx = m ? Number(m[1]) : entities[0] ? sizeAt(entities[0], t) : 0;\n out.push({ layerIndex, key: layer.key, strings: [...s.strings], count: entities.length, sizePx: Math.round(sizePx) });\n });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Dominance ranking\n// ---------------------------------------------------------------------------\n\nexport interface DominanceEntry {\n rank: number;\n layerIndex: number;\n key: string | undefined;\n /** Normalized share of total visual weight, 0..1 (all entries sum to 1). */\n share: number;\n entityCount: number;\n meanLuma: number;\n factors: { area: number; contrast: number; blendBoost: number; motionBoost: number };\n}\n\n/**\n * Rank layers by estimated visual weight — where the eye goes. Weight is\n * on-screen area × alpha, scaled by contrast against the background, an\n * additive-glow boost, and a motion boost. Link lines count as area, and so\n * does persistence ink: trail ribbons and ghosting smear are modeled as swept\n * ribbons, so a comet layer is ranked by its comet, not just its head.\n */\nexport function dominanceRanking(spec: SaverSpec, opts: PerceiveOptions = {}): DominanceEntry[] {\n return rankDominance(rawDominance(spec, opts));\n}\n\ninterface RawDominance {\n layerIndex: number;\n key: string | undefined;\n weight: number;\n entityCount: number;\n meanLuma: number;\n factors: DominanceEntry['factors'];\n}\n\n/** Normalize raw weights to shares and rank — shared by a scene and a composed sequence frame. */\nfunction rankDominance(raw: RawDominance[]): DominanceEntry[] {\n const total = raw.reduce((s, r) => s + r.weight, 0) || 1;\n return raw\n .slice()\n .sort((a, b) => b.weight - a.weight)\n .map((r, i) => ({\n rank: i + 1,\n layerIndex: r.layerIndex,\n key: r.key,\n share: r.weight / total,\n entityCount: r.entityCount,\n meanLuma: r.meanLuma,\n factors: r.factors,\n }));\n}\n\n/** Per-layer un-normalized visual weight at `opts.t` — the body of dominanceRanking. */\nfunction rawDominance(spec: SaverSpec, opts: PerceiveOptions = {}): RawDominance[] {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const { w, h, scale } = scene;\n\n const bgMean = backgroundLuma(spec);\n\n\n // Persistence smears every moving sprite into a ribbon of real visual mass —\n // for a comet layer the trail IS the visual event. Model both effects as\n // swept ribbons (path length × stroke width × mean surviving alpha), using\n // the straight-line displacement as a lower-bound path length and skipping\n // wrap seams. First-pass fidelity, same spirit as GLOW_SPREAD.\n const ghost = spec.ghosting ?? 0;\n let ghostWindowMs = 0;\n let ghostMeanW = 0;\n if (ghost > 0) {\n const dt = 1000 / 60;\n const frames = Math.min(Math.ceil(Math.log(1 / 255) / Math.log(ghost)), LIMITS.maxGhostReplayFrames);\n ghostWindowMs = frames * dt;\n ghostMeanW = (ghost * (1 - Math.pow(ghost, frames))) / (1 - ghost) / frames;\n }\n const sweptDistance = (e: Entity, spanMs: number): number => {\n const span = Math.min(spanMs, t);\n if (span <= 0) return 0;\n const p0 = posOf(scene, e, t - span);\n const p1 = posOf(scene, e, t);\n const dx = p1.x - p0.x;\n const dy = p1.y - p0.y;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) return 0; // wrapped: ambiguous\n return Math.sqrt(dx * dx + dy * dy);\n };\n\n const raw = scene.layers.map(({ layer, entities }, layerIndex) => {\n const lifeA = lifeAlphaAt(layer.life, t);\n let area = 0;\n let lumAcc = 0;\n for (const e of entities) {\n const a = alphaAt(e, t) * lifeA;\n const sz = sizeAt(e, t);\n const s = layer.sprite;\n let entArea: number;\n if (s.kind === 'circle') entArea = Math.PI * (sz / 2) * (sz / 2);\n else if (s.kind === 'ring') entArea = Math.PI * sz * ((s.width ?? (scale === 1 ? 2 : 0.002)) * scale) * LINE_SALIENCE;\n else if (s.kind === 'streak') entArea = sz * ((s.width ?? (scale === 1 ? 2 : 0.002)) * scale) * LINE_SALIENCE;\n else if (s.kind === 'rect') {\n const h2 = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz;\n const f = s.feather ? (1 - s.feather / 2) * (1 - s.feather / 2) : 1;\n entArea = sz * h2 * f;\n }\n else if (s.kind === 'polygon') entArea = polygonArea(polygonPoints(s, sz / 2));\n else if (s.kind === 'bar') {\n const th = e.size2 !== undefined ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz * 0.2;\n entArea = sz * barFraction(s, e.barIndex ?? 0) * th;\n }\n else if (s.kind === 'stroke') {\n const meanTaper = s.taper ? 0.64 : 1; // ∫ sin(πu) du = 2/π\n entArea = pathLength(strokeSamples(s, sz / 2)) * strokeWidthPx(s, scale) * meanTaper * LINE_SALIENCE;\n }\n else if (s.kind === 'text') {\n const box = textBox(s, e, { x: 0, y: 0 });\n entArea = box.halfX * 2 * box.halfY * 2 * 0.55;\n } else if (s.kind === 'textBlock') {\n const box = textBlockBox(s, e, { x: 0, y: 0 }, w, h);\n entArea = box.halfX * 2 * box.halfY * 2 * 0.55 * textBlockRevealFraction(s, w, h, t) * (s.opacity ?? 1);\n } else entArea = sz * sz * 0.55; // emoji\n\n area += entArea * a;\n\n // Trail ribbon: dots shrink to 0.3× and fade along the tail, so mean\n // width ≈ 0.65×size and mean alpha ≈ (1 - fade/2) of the head's.\n if (layer.trail) {\n const fade = layer.trail.fade ?? 1;\n const span = sweptDistance(e, layer.trail.length);\n area += span * sz * 0.65 * Math.max(0, 1 - fade / 2) * a;\n }\n // Ghost smear: ink from m frames back survives at g^m, so the sweep over\n // the visible window carries the window's mean surviving weight.\n if (ghost > 0) {\n area += sweptDistance(e, ghostWindowMs) * sz * ghostMeanW * a;\n }\n lumAcc += spriteLuma(layer, e);\n }\n if (layer.links && entities.length > 1) {\n const positions = entities.map((e) => posOf(scene, e, t));\n const motionWraps = ['drift', 'rise', 'wander'].includes(layer.motion.type);\n const edges = linkEdges(layer.links, positions, layer.links.maxDist * scale, layer.wrap !== false && motionWraps, w, h);\n const la = (layer.links.alpha ?? 0.6) * lifeA;\n const defaultWidth = scale === 1 ? 1 : 1 / LIMITS.referenceViewport;\n const lw = (layer.links.width ?? defaultWidth) * scale;\n for (const edge of edges) area += edge.dist * lw * la * LINE_SALIENCE;\n }\n const meanLuma = entities.length ? lumAcc / entities.length : 0;\n const contrast = Math.abs(meanLuma - bgMean) + 0.1;\n const blendBoost = layer.blend === 'lighter' || layer.blend === 'screen' ? 1.3 : layer.blend === 'multiply' ? 1.1 : 1;\n const motionBoost = layer.motion.type === 'static' ? 1 : 1.2;\n const weight = (area / (w * h)) * contrast * blendBoost * motionBoost;\n return { layerIndex, key: layer.key, weight, entityCount: entities.length, meanLuma, factors: { area: area / (w * h), contrast, blendBoost, motionBoost } };\n });\n\n return raw;\n}\n\n// ---------------------------------------------------------------------------\n// Motion stats\n// ---------------------------------------------------------------------------\n\n/**\n * Does each layer read as one merged form or as separate marks? The one thing\n * the luminance maps cannot answer — they measure ink, not edges, so a layer\n * that merged into a silhouette and one that stayed a pile of discs look\n * identical in every other channel. See `cohesion.ts`.\n */\nexport function layerCohesion(spec: SaverSpec, opts: PerceiveOptions = {}): LayerCohesion[] {\n const scene = buildScene(spec, opts);\n return cohesionOf(scene.layers, opts.t ?? 5000, scene.w, scene.h);\n}\n\nexport interface LayerMotionStats {\n layerIndex: number;\n key: string | undefined;\n /** Mean / max on-screen speed in px per second (wrap jumps excluded). */\n meanSpeed: number;\n maxSpeed: number;\n moving: boolean;\n}\n\n/** Per-layer displacement between t and t+dt — choreography as numbers. */\nexport function motionStats(spec: SaverSpec, opts: PerceiveOptions & { dt?: number } = {}): LayerMotionStats[] {\n const scene = buildScene(spec, opts);\n const t = opts.t ?? 5000;\n const dt = opts.dt ?? 500;\n const { w, h } = scene;\n return scene.layers.map(({ layer, entities }, layerIndex) => {\n let acc = 0;\n let max = 0;\n let n = 0;\n for (const e of entities) {\n const p0 = posOf(scene, e, t);\n const p1 = posOf(scene, e, t + dt);\n const dx = p1.x - p0.x;\n const dy = p1.y - p0.y;\n if (Math.abs(dx) > w / 2 || Math.abs(dy) > h / 2) continue; // wrap seam\n const speed = (Math.sqrt(dx * dx + dy * dy) / dt) * 1000;\n acc += speed;\n max = Math.max(max, speed);\n n++;\n }\n const meanSpeed = n ? acc / n : 0;\n return { layerIndex, key: layer.key, meanSpeed, maxSpeed: max, moving: meanSpeed > 0.5 };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Scene diff — relative sight\n// ---------------------------------------------------------------------------\n\nconst REGION_NAMES = [\n 'top-left', 'top-center', 'top-right',\n 'mid-left', 'center', 'mid-right',\n 'bottom-left', 'bottom-center', 'bottom-right',\n] as const;\n\nfunction regionMeans(grid: LuminanceGrid): number[] {\n const out = new Array<number>(9).fill(0);\n const cnt = new Array<number>(9).fill(0);\n for (let r = 0; r < grid.rows; r++) {\n for (let c = 0; c < grid.cols; c++) {\n const region = Math.min(2, Math.floor((r / grid.rows) * 3)) * 3 + Math.min(2, Math.floor((c / grid.cols) * 3));\n out[region]! += Math.abs(grid.cells[r * grid.cols + c]! - grid.background[r]!);\n cnt[region]!++;\n }\n }\n return out.map((v, i) => (cnt[i]! ? v / cnt[i]! : 0));\n}\n\nexport interface SceneDiff {\n t: number;\n coverage: { a: number; b: number; delta: number };\n meanLuminance: { a: number; b: number; delta: number };\n /** Shift of the visual-mass centroid from A to B, in viewport fractions. */\n balanceShift: { dx: number; dy: number } | null;\n /** Mean deviation-from-background per third-by-third region, with deltas. */\n regions: Array<{ region: (typeof REGION_NAMES)[number]; a: number; b: number; delta: number }>;\n /** Dominance changes, matched by layer key (falls back to index). Sorted by |share delta|. */\n dominance: Array<{ key: string; rankA: number | null; rankB: number | null; shareA: number; shareB: number }>;\n advisories: { added: string[]; removed: string[] };\n}\n\n/**\n * Compare two specs at the same time/viewport — relative perception. A text\n * model is far better at \"is B better than A\" than \"is A good\"; this returns\n * the deltas that question needs: coverage, balance, per-region visual mass,\n * dominance-rank movement, and advisory changes.\n */\nexport function diffScenes(a: SaverSpec, b: SaverSpec, opts: LuminanceGridOptions = {}): SceneDiff {\n const t = opts.t ?? 5000;\n const gridA = luminanceGrid(a, opts);\n const gridB = luminanceGrid(b, opts);\n const regsA = regionMeans(gridA);\n const regsB = regionMeans(gridB);\n const domA = dominanceRanking(a, opts);\n const domB = dominanceRanking(b, opts);\n\n const nameOf = (d: DominanceEntry): string => d.key ?? `layer-${d.layerIndex}`;\n const names = new Set<string>([...domA.map(nameOf), ...domB.map(nameOf)]);\n const dominance = [...names].map((key) => {\n const inA = domA.find((d) => nameOf(d) === key);\n const inB = domB.find((d) => nameOf(d) === key);\n return {\n key,\n rankA: inA?.rank ?? null,\n rankB: inB?.rank ?? null,\n shareA: inA?.share ?? 0,\n shareB: inB?.share ?? 0,\n };\n }).sort((x, y) => Math.abs(y.shareB - y.shareA) - Math.abs(x.shareB - x.shareA));\n\n const codesA = new Set(adviseSpec(a).map((w) => w.code));\n const codesB = new Set(adviseSpec(b).map((w) => w.code));\n\n return {\n t,\n coverage: { a: gridA.coverage, b: gridB.coverage, delta: gridB.coverage - gridA.coverage },\n meanLuminance: { a: gridA.meanLuminance, b: gridB.meanLuminance, delta: gridB.meanLuminance - gridA.meanLuminance },\n balanceShift: gridA.centroid && gridB.centroid\n ? { dx: gridB.centroid.x - gridA.centroid.x, dy: gridB.centroid.y - gridA.centroid.y }\n : null,\n regions: REGION_NAMES.map((region, i) => ({ region, a: regsA[i]!, b: regsB[i]!, delta: regsB[i]! - regsA[i]! })),\n dominance,\n advisories: {\n added: [...codesB].filter((c) => !codesA.has(c)),\n removed: [...codesA].filter((c) => !codesB.has(c)),\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// One-call perception bundle\n// ---------------------------------------------------------------------------\n\nexport interface ScenePerception {\n t: number;\n /** The picture: a braille luminance map (each char = 2×4 pixels), compact. */\n braille: string;\n /**\n * A one-char-per-cell ASCII density map at the grid resolution — higher\n * fidelity than braille for structure (rings, grids, text blocks). Pair with\n * a larger `cols`/`rows` for a sharper read.\n */\n density: string;\n coverage: number;\n meanLuminance: number;\n centroid: { x: number; y: number } | null;\n rowProfile: number[];\n colProfile: number[];\n dominance: DominanceEntry[];\n motion: LayerMotionStats[];\n /** Per layer: merged silhouette, seamed overlap, or separate marks. */\n form: LayerCohesion[];\n /** Literal strings + sizes of any text layers (glyphs don't show in the maps). */\n text: TextSpriteInfo[];\n advisories: ReturnType<typeof adviseSpec>;\n}\n\n/**\n * Everything a non-vision agent needs to \"see\" a spec in one deterministic\n * call: the braille picture, a higher-res density map, composition transects,\n * dominance ranking, motion stats, the literal text on screen, and advisories.\n * Intended as the payload behind an MCP previewScene.\n */\nexport function perceiveScene(spec: SaverSpec, opts: LuminanceGridOptions = {}): ScenePerception {\n const grid = luminanceGrid(spec, opts);\n return {\n t: opts.t ?? 5000,\n braille: renderBrailleMap(grid),\n density: renderDensityMap(grid),\n coverage: grid.coverage,\n meanLuminance: grid.meanLuminance,\n centroid: grid.centroid,\n rowProfile: grid.rowProfile,\n colProfile: grid.colProfile,\n dominance: dominanceRanking(spec, opts),\n motion: motionStats(spec, opts),\n form: layerCohesion(spec, opts),\n text: textSprites(spec, opts),\n advisories: adviseSpec(spec, opts.viewport ?? { width: 1920, height: 1080 }, { t: opts.t, seed: opts.seed }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Sequence frames — bed + segment\n// ---------------------------------------------------------------------------\n\nexport interface SequenceFramePerception extends ScenePerception {\n /** Which segment the global time `T` resolved to, and where in it. */\n segment: { index: number; key: string; localT: number; held?: true };\n /** True when a bed was composed under the segment. */\n bed: boolean;\n}\n\nexport interface PerceiveSequenceOptions extends Omit<LuminanceGridOptions, 't'> {\n /** Holds released by the clicker so far — see `ResolveOptions.releasedBelow`. */\n releasedBelow?: number;\n}\n\n/** Prefix bed layers so they read apart from the segment's in a merged list. */\nconst bedKey = (key: string | undefined, layerIndex: number): string => `bed:${key ?? layerIndex}`;\n\n/**\n * Perceive one frame of a sequence at global time `T`: resolve the segment,\n * then — when the sequence has a `bed` — compose the bed at `T` (its clock\n * never resets) under the segment's ink at `localT`, the segment's own\n * background dropped, exactly as the renderer stacks them. The luminance maps\n * add the two grids (clamped), so coverage, centroid and the profiles are of\n * the composite; dominance ranks bed and segment layers together by their raw\n * weights, bed layers keyed `bed:<key|index>`; text, motion and form list bed\n * layers first with the same prefix. Bed and segment are assumed to share\n * `units`/`referenceViewport`, as the renderer's shared canvas assumes. The\n * bed and segment seeds come from `segmentRenderSeed`/`bedRenderSeed`\n * (`./sequence`) — the same derivation `SequenceInstance` uses, chain roots\n * and zero-seed normalization included — so the composed frame matches what\n * the renderer actually draws at `T`, not just what the raw specs would show.\n * Without a bed this is `perceiveScene(segment, localT)` plus the `segment`\n * field. Intended as the payload behind a sequence-aware previewScene.\n *\n * Two known approximations, both accepted for a coarse, cheap, renderer-free\n * tool rather than fixed here:\n * - **The transition WINDOW isn't composed.** During a live `fade` or `morph`\n * (i.e. `localT < transition.dur`) the renderer also paints the outgoing\n * (or interpolating) segment, but this only ever perceives the segment\n * `resolveSegment` resolves to — call it at a `T` outside the transition's\n * `dur` for an accurate read. (Outside that window, a morph-chained\n * segment's entities and seed ARE correct — `segmentRenderSeed` already\n * resolves the chain root.) Composing the live window properly needs the\n * same capability-tier gate `SequenceInstance` uses to decide whether\n * `fade` even plays; this analytical path has no such context.\n * - **Ink composites onto the bed by addition, not by blend mode.** This\n * matches a plain `source-over`, opaque-ink segment (the common case), but\n * a segment layer with `blend: 'multiply'`/`'screen'`/etc. or partial alpha\n * composites directionally differently on the real canvas than adding\n * luminance values ever can (`multiply` darkens; addition only brightens).\n * The per-cell grids don't retain per-layer blend/alpha to composite\n * correctly at this resolution.\n */\nexport function perceiveSequenceFrame(seq: IdleSequence, T: number, opts: PerceiveSequenceOptions = {}): SequenceFramePerception {\n const { releasedBelow, ...gridOpts } = opts;\n const r = resolveSegment(seq, T, { releasedBelow });\n const seg = seq.segments[r.index]!;\n const segment: SequenceFramePerception['segment'] = { index: r.index, key: seg.key, localT: r.localT, ...(r.held ? { held: true } : {}) };\n const segOpts: LuminanceGridOptions = { ...gridOpts, t: r.localT, seed: gridOpts.seed ?? segmentRenderSeed(seq, r.index) };\n if (!seq.bed) return { ...perceiveScene(seg.scene, segOpts), segment, bed: false };\n\n const bedOpts: LuminanceGridOptions = { ...gridOpts, t: T, seed: gridOpts.seed ?? bedRenderSeed(seq) };\n const viewport = gridOpts.viewport ?? { width: 1920, height: 1080 };\n // The segment's ink alone: a black ground contributes nothing to the sum,\n // and no ghosting — a transparent child ignores it, as the renderer does.\n const ink: SaverSpec = { ...seg.scene, background: { type: 'solid', color: '#000000' } };\n delete ink.ghosting;\n // For contrast, ink is judged against what is actually behind it: the bed.\n const inkOverBed: SaverSpec = { ...ink, background: seq.bed.background ?? { type: 'solid', color: '#05050a' } };\n\n const bedGrid = luminanceGrid(seq.bed, bedOpts);\n const inkGrid = luminanceGrid(ink, segOpts);\n const cells = bedGrid.cells.map((v, i) => Math.min(1, v + inkGrid.cells[i]!));\n const grid = finishGrid(bedGrid.cols, bedGrid.rows, cells, bedGrid.background);\n\n const bedLayers = seq.bed.layers.length;\n const dominance = rankDominance([\n ...rawDominance(seq.bed, bedOpts).map((d) => ({ ...d, key: bedKey(d.key, d.layerIndex) })),\n ...rawDominance(inkOverBed, segOpts).map((d) => ({ ...d, layerIndex: d.layerIndex + bedLayers })),\n ]);\n const shift = <X extends { layerIndex: number }>(x: X): X => ({ ...x, layerIndex: x.layerIndex + bedLayers });\n const prefix = <X extends { layerIndex: number; key: string | undefined }>(x: X): X => ({ ...x, key: bedKey(x.key, x.layerIndex) });\n\n return {\n t: r.localT,\n braille: renderBrailleMap(grid),\n density: renderDensityMap(grid),\n coverage: grid.coverage,\n meanLuminance: grid.meanLuminance,\n centroid: grid.centroid,\n rowProfile: grid.rowProfile,\n colProfile: grid.colProfile,\n dominance,\n motion: [...motionStats(seq.bed, bedOpts).map(prefix), ...motionStats(ink, segOpts).map(shift)],\n form: [...layerCohesion(seq.bed, bedOpts).map(prefix), ...layerCohesion(ink, segOpts).map(shift)],\n text: [...textSprites(seq.bed, bedOpts).map(prefix), ...textSprites(ink, segOpts).map(shift)],\n advisories: [\n ...adviseSpec(seq.bed, viewport, { t: T, seed: bedOpts.seed }).map((w) => ({ ...w, path: `bed.${w.path}` })),\n ...adviseSpec(inkOverBed, viewport, { t: r.localT, seed: segOpts.seed }),\n ],\n segment,\n bed: true,\n };\n}\n","import type { SaverSpec } from '../types';\n\n/**\n * Reproduces the hand-coded Fish Aquarium saver as pure DATA — the discriminating test\n * that the schema is actually expressive: two layers (fish drifting both ways at varied\n * speeds with a bob + flip, over a gradient with a seafloor band; bubbles rising with sway).\n */\nexport const AQUARIUM_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'aquarium',\n label: 'Aquarium',\n seed: 42,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a3a52' },\n { at: 0.6, color: '#062534' },\n { at: 1, color: '#02141d' },\n ],\n band: { color: '#0b1a12', height: 0.02222 },\n },\n layers: [\n {\n count: 14,\n sprite: { kind: 'emoji', glyphs: ['🐟', '🐠', '🐡', '🦈', '🐙'] },\n size: [0.03148, 0.06667],\n motion: { type: 'drift', speed: [0.02778, 0.1019], bidirectional: true, bob: 0.005556 },\n flip: true,\n },\n {\n count: 22,\n sprite: { kind: 'circle', radius: [0.001852, 0.006481], color: '#c8ebff' },\n motion: { type: 'rise', speed: [0.02222, 0.07222], sway: 0.007407 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Aurora Borealis: the \"fake fluid\" recipe — showcases `wander` motion (harmonic\n * drift) with high `coherence` so the curtain undulates as one body, `pulse.wave`\n * (a traveling shimmer across the star field), weighted palettes, additive blend,\n * and `ghosting` smearing the soft glows into continuous curtains of light.\n */\nexport const AURORA_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'aurora',\n label: 'Aurora',\n seed: 66,\n motionIntensity: 'calm',\n ghosting: 0.85,\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#02030d' },\n { at: 0.65, color: '#050a18' },\n { at: 1, color: '#0a1220' },\n ],\n drift: { period: 40000, amount: 0.1 },\n },\n layers: [\n {\n key: 'stars',\n count: 110,\n sprite: { kind: 'circle', radius: [0.0005, 0.0015], color: '#e8ecff', soft: true },\n motion: { type: 'static' },\n region: { y: [0, 0.75] },\n alpha: [0.2, 0.6],\n // A slow shimmer travels across the sky instead of stars twinkling independently.\n pulse: { amp: 0.25, period: 6000, wave: { wavelength: 0.5, angle: 15 } },\n },\n {\n key: 'curtain-green',\n count: 100,\n sprite: {\n kind: 'circle',\n radius: [0.055, 0.11],\n color: '#1fd68a',\n soft: true,\n colors: ['#1fd68a', '#2ee6c8', '#4bd1ff'],\n colorWeights: [5, 2, 1],\n },\n motion: { type: 'wander', speed: [0.004, 0.012], angle: 0, meander: 0.13, coherence: 0.7 },\n region: { y: [0.1, 0.42] },\n alpha: [0.04, 0.1],\n blend: 'lighter',\n grow: { amp: 0.25, period: 9000 },\n },\n {\n key: 'curtain-violet',\n count: 60,\n sprite: {\n kind: 'circle',\n radius: [0.045, 0.09],\n color: '#8d5bff',\n soft: true,\n colors: ['#8d5bff', '#d14bff', '#ff4bd8'],\n colorWeights: [4, 1.5, 0.5],\n },\n motion: { type: 'wander', speed: [0.003, 0.01], angle: 180, meander: 0.1, coherence: 0.55 },\n region: { y: [0.04, 0.28] },\n alpha: [0.03, 0.08],\n blend: 'lighter',\n grow: { amp: 0.3, period: 12000 },\n },\n {\n key: 'fireflies',\n count: 14,\n sprite: { kind: 'circle', radius: [0.001, 0.003], color: '#b8ffe1', soft: true },\n motion: { type: 'wander', speed: [0.006, 0.02], meander: 0.06 },\n region: { y: [0.55, 0.95] },\n alpha: [0.2, 0.55],\n pulse: { amp: 0.3, period: 3500 },\n blend: 'lighter',\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Comet Shower: showcases trails (afterglow behind moving entities) and background\n * drift (gradient stops breathing slowly). Three layers: a static star field, fast\n * comets with long trails, and slow fireflies with short trails and pulse.\n */\nexport const COMETS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'comets',\n label: 'Comet Shower',\n seed: 42,\n motionIntensity: 'moderate',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a0015' },\n { at: 0.5, color: '#0d1b2a' },\n { at: 1, color: '#1b0a2e' },\n ],\n drift: { period: 25000, amount: 0.12 },\n },\n layers: [\n {\n key: 'stars',\n count: 120,\n sprite: { kind: 'circle', radius: [0.000463, 0.001852], color: '#ffffff', soft: true },\n motion: { type: 'static' },\n alpha: [0.3, 0.7],\n pulse: { amp: 0.15, period: 3000 },\n },\n {\n key: 'comets',\n count: 8,\n sprite: { kind: 'circle', radius: [0.002778, 0.007407], color: '#88ccff', soft: true },\n motion: { type: 'drift', speed: [0.07407, 0.1852], angle: 225 },\n alpha: [0.7, 1],\n blend: 'lighter',\n trail: { length: 1500, fade: 1 },\n },\n {\n key: 'fireflies',\n count: 20,\n sprite: { kind: 'circle', radius: [0.001852, 0.00463], color: '#ffdd44', soft: true },\n motion: { type: 'drift', speed: [0.009259, 0.02778], bidirectional: true, bob: 0.01852 },\n alpha: [0.4, 0.8],\n pulse: { amp: 0.3, period: 2000 },\n blend: 'lighter',\n trail: { length: 800 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Constellation: drifting stars connected by faint k-nearest links. Exercises\n * colors[] (multi-hued stars), links (k-nearest neighbor lines), and cycle\n * (emoji asterisms rotate glyphs). Stars are soft circles in viewport units.\n */\nexport const CONSTELLATION_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'constellation',\n label: 'Constellation',\n seed: 73,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#020212' },\n { at: 0.5, color: '#050520' },\n { at: 1, color: '#0a0830' },\n ],\n },\n layers: [\n // Distant static stars (no links, just atmosphere)\n {\n count: 100,\n sprite: { kind: 'circle', radius: [0.0009259, 0.002778], color: '#667799', colors: ['#8899cc', '#99aadd', '#aabbee', '#7788aa'] },\n alpha: [0.2, 0.7],\n pulse: { amp: 0.2, period: 3000 },\n motion: { type: 'static' },\n },\n // Connected constellation nodes — slow drift, linked\n {\n key: 'nodes',\n count: 40,\n sprite: { kind: 'circle', radius: [0.001852, 0.00463], color: '#88aaff', colors: ['#88aaff', '#aaccff', '#ffcc88', '#ff8866'], soft: true },\n alpha: [0.5, 0.9],\n blend: 'lighter',\n motion: { type: 'drift', speed: [0.001852, 0.007407], bidirectional: true, bob: 0.002778 },\n links: { k: 3, maxDist: 0.1852, alpha: 0.15, width: 0.000463 },\n },\n // Cycling asterism markers\n {\n count: 6,\n sprite: { kind: 'emoji', glyphs: ['✦', '✧', '⋆', '∗'], cycle: { period: 2000 } },\n size: [0.01296, 0.02037],\n alpha: [0.4, 0.7],\n motion: { type: 'drift', speed: [0.0009259, 0.003704], bidirectional: true },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Control Center — VIREO-9, Trans-Lunar Relay Operations.\n *\n * A mission-control WALL BOARD, laid out the way real ops rooms lay them out:\n * framed zones with a clear reading order, one hero display (the orbital\n * plot), dense-but-calm peripheral telemetry, and a boot sequence when the\n * board comes up. The fiction: a small relay station somewhere past GEO,\n * mid-shift, tracking a five-craft fleet (named for this library's own\n * savers — the station runs our little universe).\n *\n * Composed against the validator's 36-layer ceiling deliberately — every\n * layer earns its slot. Schema exercises: grid `layout` LED wall with a\n * traveling `pulse.wave`, `orbit` motion with `trail`s and chain `links`\n * (the relay web between the fleet), `ring` orbit guides, wave-phased rect\n * meters, staged `life` boots per zone. Every reading is keyed so an agent\n * can steer the fiction live (`signal-value`, `feed-1`, `alert`, ...).\n */\nexport const DASHBOARD_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'dev-dashboard',\n label: 'Control Center',\n seed: 256,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#05070d' },\n { at: 0.55, color: '#080b14' },\n { at: 1, color: '#0a0d18' },\n ],\n },\n layers: [\n // ---- ambient: the LED wall behind everything ----\n {\n key: 'led-wall',\n count: 240,\n sprite: { kind: 'circle', radius: [0.0007, 0.0011], color: '#22344c' },\n alpha: [0.04, 0.1],\n layout: { type: 'grid', columns: 24, jitter: 0.1 },\n pulse: { amp: 0.3, period: 6200, wave: { wavelength: 0.4, angle: 24 } },\n motion: { type: 'static' },\n },\n // ---- frame chrome (boots first) ----\n {\n key: 'rule-header', count: 1,\n position: { x: 0.5, y: 0.085 },\n sprite: { kind: 'rect', width: [0.93, 0.93], aspect: [0.0012, 0.0012], color: '#24384f' },\n alpha: [0.8, 0.8],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n {\n key: 'rule-footer', count: 1,\n position: { x: 0.5, y: 0.915 },\n sprite: { kind: 'rect', width: [0.93, 0.93], aspect: [0.0012, 0.0012], color: '#24384f' },\n alpha: [0.8, 0.8],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n {\n key: 'rule-col-left', count: 1,\n position: { x: 0.265, y: 0.5 },\n sprite: { kind: 'rect', width: [0.0009, 0.0009], aspect: [620, 620], color: '#1c2c40' },\n alpha: [0.7, 0.7],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n {\n key: 'rule-col-right', count: 1,\n position: { x: 0.645, y: 0.5 },\n sprite: { kind: 'rect', width: [0.0009, 0.0009], aspect: [620, 620], color: '#1c2c40' },\n alpha: [0.7, 0.7],\n motion: { type: 'static' },\n life: { enter: 100, fade: 400 },\n },\n // ---- header band ----\n {\n key: 'title', count: 1,\n position: { x: 0.035, y: 0.052 },\n sprite: { kind: 'text', strings: ['VIREO-9 · TRANS-LUNAR RELAY · OPS WALL 03'], color: '#7f93ab',\n font: \"600 13px 'SF Mono', monospace\", align: 'left' },\n motion: { type: 'static' },\n life: { enter: 200, fade: 600 },\n },\n {\n key: 'clock', count: 1,\n position: { x: 0.5, y: 0.058 },\n sprite: { kind: 'text', strings: ['04:17:26 UTC'], color: '#c8d4e4',\n font: \"600 20px 'SF Mono', monospace\", align: 'center' },\n motion: { type: 'static' },\n life: { enter: 200, fade: 600 },\n },\n {\n key: 'status', count: 1,\n position: { x: 0.965, y: 0.052 },\n sprite: { kind: 'text', strings: ['● UPLINK LOCKED · WATCH C'], color: '#46d17a',\n font: \"bold 11px 'SF Mono', monospace\", align: 'right' },\n pulse: { amp: 0.18, period: 2600 },\n motion: { type: 'static' },\n life: { enter: 200, fade: 600 },\n },\n // ---- left column: arrays (boots second) ----\n {\n key: 'dish1', count: 1,\n position: { x: 0.035, y: 0.148 },\n sprite: { kind: 'text', strings: ['DSA-1 EAST AZ 214.6° EL 38.2°'], color: '#9fb2c8',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 700, fade: 600 },\n },\n {\n key: 'dish1-bars', count: 14,\n sprite: { kind: 'rect', width: [0.0038, 0.0038], aspect: [0.5, 2.6], color: '#2ee6c8' },\n alpha: [0.3, 0.65],\n layout: { type: 'grid', columns: 14 },\n region: { x: [0.035, 0.15], y: [0.183, 0.203] },\n pulse: { amp: 0.42, period: 1500, wave: { wavelength: 0.09, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 700, fade: 600 },\n },\n {\n key: 'dish2', count: 1,\n position: { x: 0.035, y: 0.243 },\n sprite: { kind: 'text', strings: ['DSA-2 WEST AZ 097.1° EL 61.7°'], color: '#9fb2c8',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 850, fade: 600 },\n },\n {\n key: 'dish2-bars', count: 14,\n sprite: { kind: 'rect', width: [0.0038, 0.0038], aspect: [0.5, 2.2], color: '#44aaff' },\n alpha: [0.3, 0.6],\n layout: { type: 'grid', columns: 14 },\n region: { x: [0.035, 0.15], y: [0.278, 0.298] },\n pulse: { amp: 0.4, period: 1900, wave: { wavelength: 0.11, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 850, fade: 600 },\n },\n {\n key: 'dish3', count: 1,\n position: { x: 0.035, y: 0.338 },\n sprite: { kind: 'text', strings: ['DSA-3 POLAR AZ 002.4° EL 12.9° △ WIND'], color: '#5d7089',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1000, fade: 600 },\n },\n {\n key: 'dish3-bars', count: 14,\n sprite: { kind: 'rect', width: [0.0038, 0.0038], aspect: [0.4, 1.1], color: '#5d7089' },\n alpha: [0.2, 0.4],\n layout: { type: 'grid', columns: 14 },\n region: { x: [0.035, 0.15], y: [0.373, 0.393] },\n pulse: { amp: 0.3, period: 2600, wave: { wavelength: 0.14, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 1000, fade: 600 },\n },\n {\n key: 'dish-leds', count: 3,\n sprite: { kind: 'circle', radius: [0.004, 0.004], color: '#46d17a' },\n alpha: [0.9, 0.9],\n layout: { type: 'grid', columns: 1 },\n region: { x: [0.238, 0.246], y: [0.15, 0.35] },\n pulse: { amp: 0.25, period: 2100 },\n motion: { type: 'static' },\n life: { enter: 1000, fade: 600 },\n },\n // carrier + doppler + station env\n {\n key: 'carrier-wave', count: 30,\n sprite: { kind: 'rect', width: [0.0032, 0.0032], aspect: [0.4, 3.6], color: '#2ee6c8' },\n alpha: [0.25, 0.6],\n layout: { type: 'grid', columns: 30 },\n region: { x: [0.035, 0.245], y: [0.47, 0.5] },\n pulse: { amp: 0.5, period: 2100, wave: { wavelength: 0.16, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 1150, fade: 600 },\n },\n {\n key: 'doppler', count: 1,\n position: { x: 0.035, y: 0.535 },\n sprite: { kind: 'text', strings: ['CARRIER X-BAND · DOPPLER +2.114 kHz · DRIFT 0.03'], color: '#9fb2c8',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1150, fade: 600 },\n },\n {\n key: 'env-line', count: 1,\n position: { x: 0.035, y: 0.6 },\n sprite: { kind: 'text', strings: ['STATION · PWR 28.1 V · THERM 312 K · GYRO NOM · PROP 81%'], color: '#5d7089',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1300, fade: 600 },\n },\n // ---- center: the orbital plot (boots third) ----\n {\n key: 'moon', count: 1,\n position: { x: 0.455, y: 0.4 },\n sprite: { kind: 'circle', radius: [0.028, 0.028], color: '#8fa3bd', soft: true },\n alpha: [0.9, 0.9],\n motion: { type: 'static' },\n life: { enter: 1200, fade: 700 },\n },\n {\n key: 'orbit-guides', count: 3,\n // All three guides pin to the plot centre; the seeded radius range\n // spreads them into concentric orbits (`position` is count:1-only).\n region: { x: [0.455, 0.455], y: [0.4, 0.4] },\n sprite: { kind: 'ring', radius: [0.075, 0.185], color: '#1e3a52', width: 0.0011 },\n alpha: [0.55, 0.55],\n motion: { type: 'static' },\n life: { enter: 1200, fade: 700 },\n },\n {\n key: 'fleet',\n count: 5,\n sprite: { kind: 'circle', radius: [0.0045, 0.0065], color: '#2ee6c8',\n colors: ['#2ee6c8', '#44aaff', '#ffd166', '#aa88ff', '#ff9f43'] },\n alpha: [0.85, 0.95],\n blend: 'lighter',\n motion: { type: 'orbit', speed: [4, 11], radius: [0.075, 0.185], center: { x: 0.455, y: 0.4 } },\n trail: { length: 9, fade: 0.75 },\n // The relay web: each craft holds a comm chain to its neighbours.\n links: { k: 2, maxDist: 0.5, color: '#2ee6c8', alpha: 0.2, width: 0.0012, mode: 'chain' },\n life: { enter: 1350, fade: 700 },\n },\n {\n key: 'fleet-legend', count: 1,\n position: { x: 0.455, y: 0.63 },\n sprite: { kind: 'text', strings: ['TRACKING 5 · KESTREL TIDE-2 LIMELIGHT CATWALK-1 SLIPSTREAM'], color: '#5d7089',\n font: \"9px 'SF Mono', monospace\", align: 'center', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1500, fade: 700 },\n },\n // pass schedule under the plot\n {\n key: 'pass-label', count: 1,\n position: { x: 0.3, y: 0.69 },\n sprite: { kind: 'text', strings: ['PASS SCHEDULE'], color: '#41536b',\n font: \"9px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1650, fade: 600 },\n },\n {\n key: 'pass-1', count: 1,\n position: { x: 0.3, y: 0.72 },\n sprite: { kind: 'text', strings: ['04:41 CATWALK-1 ACQUIRE · DSA-1 ▲ 12 MIN'], color: '#c8d4e4',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1650, fade: 600 },\n },\n {\n key: 'pass-2', count: 1,\n position: { x: 0.3, y: 0.757 },\n sprite: { kind: 'text', strings: ['05:03 TIDE-2 OCCULT EXIT · DSA-2'], color: '#7f93ab',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1750, fade: 600 },\n },\n {\n key: 'pass-3', count: 1,\n position: { x: 0.3, y: 0.794 },\n sprite: { kind: 'text', strings: ['05:47 KESTREL RANGING · DSA-1+2'], color: '#7f93ab',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1850, fade: 600 },\n },\n // ---- right column: telemetry (boots fourth) ----\n {\n key: 'signal-label', count: 1,\n position: { x: 0.665, y: 0.115 },\n sprite: { kind: 'text', strings: ['PRIMARY CARRIER · CATWALK-1'], color: '#41536b',\n font: \"9px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1700, fade: 600 },\n },\n {\n key: 'signal-value', count: 1,\n position: { x: 0.665, y: 0.14 },\n sprite: { kind: 'text', strings: ['-112.4 dBm'], color: '#ffd166',\n font: \"bold 30px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1700, fade: 600 },\n },\n {\n key: 'telemetry-row', count: 1,\n position: { x: 0.665, y: 0.215 },\n sprite: { kind: 'text', strings: ['RANGE 1.28 LS DOWNLINK 2.048 Mb/s BUFFER 38%'], color: '#9fb2c8',\n font: \"11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1800, fade: 600 },\n },\n // event log\n {\n key: 'feed-1', count: 1,\n position: { x: 0.665, y: 0.3 },\n sprite: { kind: 'text', strings: ['04:15:02 DSA-1 LOCK RE-ACQUIRED'], color: '#9fb2c8',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 1950, fade: 600 },\n },\n {\n key: 'feed-2', count: 1,\n position: { x: 0.665, y: 0.334 },\n sprite: { kind: 'text', strings: ['04:12:47 CATWALK-1 WHEEL DESAT OK'], color: '#7f93ab',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 2050, fade: 600 },\n },\n {\n key: 'feed-3', count: 1,\n position: { x: 0.665, y: 0.368 },\n sprite: { kind: 'text', strings: ['04:09:31 RANGING RESIDUAL 0.4 m'], color: '#5d7089',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 2150, fade: 600 },\n },\n // alert + relay load\n {\n key: 'alert', count: 1,\n position: { x: 0.665, y: 0.49 },\n sprite: { kind: 'text', strings: ['△ SOLAR FLUX ELEVATED — MONITORING'], color: '#ff9f43',\n font: \"bold 11px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n pulse: { amp: 0.22, period: 3400 },\n motion: { type: 'static' },\n life: { enter: 2450, fade: 600 },\n },\n {\n key: 'load-bars', count: 24,\n sprite: { kind: 'rect', width: [0.0042, 0.0042], aspect: [0.5, 3.2],\n color: '#aa88ff', colors: ['#aa88ff', '#44aaff', '#2ee6c8'], colorWeights: [2, 2, 3] },\n alpha: [0.3, 0.65],\n layout: { type: 'grid', columns: 24 },\n region: { x: [0.665, 0.965], y: [0.58, 0.615] },\n pulse: { amp: 0.45, period: 1800, wave: { wavelength: 0.12, angle: 0 } },\n motion: { type: 'static' },\n life: { enter: 2550, fade: 600 },\n },\n {\n key: 'load-note', count: 1,\n position: { x: 0.665, y: 0.65 },\n sprite: { kind: 'text', strings: ['RELAY LOAD · QUEUE 14 FRAMES · NOMINAL'], color: '#5d7089',\n font: \"10px 'SF Mono', monospace\", align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n life: { enter: 2550, fade: 600 },\n },\n // ---- footer band ----\n {\n key: 'footer', count: 1,\n position: { x: 0.035, y: 0.95 },\n sprite: { kind: 'text', strings: ['NET STATE GREEN · 3 ARRAYS · 5 CARRIERS · DSN HANDOVER 23:34 · NEXT WINDOW 04:41:00'], color: '#41536b',\n font: \"9px 'SF Mono', monospace\", align: 'left' },\n motion: { type: 'static' },\n life: { enter: 2750, fade: 600 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Facets — a composition in the manner of the early abstractionists: three\n * soft-edged colour planes (feathered `rect`) breathing slowly behind a field\n * of tumbling triangular facets (custom `polygon`), tapered brush arcs\n * (`stroke`) drifting across, and a few glowing hexagons (soft regular\n * `polygon`). Every glyph here is a path, not a disc — the shape family nine\n * of the fifteen style profiles asked for.\n */\nexport const FACETS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'facets',\n label: 'Facets',\n seed: 1911,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#101626' },\n { at: 1, color: '#1c1a2e' },\n ],\n },\n layers: [\n {\n key: 'planes',\n count: 3,\n sprite: {\n kind: 'rect',\n width: [0.28, 0.42],\n aspect: [0.6, 1.4],\n color: '#b3402f',\n colors: ['#b3402f', '#c9862b', '#2d4f8a'],\n feather: 0.6,\n },\n alpha: [0.35, 0.5],\n region: { x: [0.2, 0.8], y: [0.2, 0.8] },\n motion: { type: 'wander', speed: [0.001, 0.003], meander: 0.02 },\n spin: [-2, 2],\n },\n {\n key: 'facets',\n count: 14,\n sprite: {\n kind: 'polygon',\n radius: [0.02, 0.06],\n points: [[-1, 0.9], [0.2, -1], [1, 0.4]],\n color: '#f2e8c9',\n colors: ['#f2e8c9', '#e0b53a', '#6fa8dc', '#d94f3d'],\n },\n alpha: [0.6, 0.9],\n motion: { type: 'wander', speed: [0.003, 0.008], meander: 0.03 },\n spin: [-8, 8],\n },\n {\n key: 'arcs',\n count: 12,\n sprite: {\n kind: 'stroke',\n length: [0.08, 0.18],\n points: [[-1, 0.3], [-0.5, -0.6], [0.3, -0.7], [1, 0.1]],\n width: 0.004,\n taper: true,\n color: '#f2e8c9',\n },\n alpha: [0.5, 0.8],\n motion: { type: 'drift', speed: [0.004, 0.01], angle: 20, bidirectional: true },\n spin: [-4, 4],\n },\n {\n key: 'hexes',\n count: 8,\n sprite: { kind: 'polygon', radius: [0.008, 0.016], sides: 6, color: '#e0b53a', soft: true },\n alpha: [0.5, 0.8],\n blend: 'lighter',\n motion: { type: 'wander', speed: [0.002, 0.005] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/** Haiku: a centered text block with a slowly drifting haiku over deep indigo. */\nexport const HAIKU_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'haiku',\n label: 'Haiku',\n seed: 42,\n background: { type: 'solid', color: '#080812' },\n layers: [\n {\n count: 1,\n sprite: {\n kind: 'textBlock',\n text: 'An old silent pond\\nA frog jumps into the pond —\\nSplash! Silence again.',\n maxWidth: 0.8,\n fontSize: 0.05,\n lineHeight: 1.8,\n align: 'center',\n color: '#c8cad4',\n },\n motion: { type: 'static' },\n position: { x: 0.1, y: 0.35 },\n },\n {\n count: 30,\n sprite: { kind: 'circle', radius: [0.0005, 0.0015], color: '#3a3a5c' },\n motion: { type: 'drift', speed: [0.002, 0.006], angle: 270 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Night Lanterns (Yi Peng festival sky): depth from four correlated parallax cues —\n * closer layers are LARGER, FASTER, SWAY WIDER, and glow WARMER/BRIGHTER. v2 of this\n * composition exercises the expressive additions the first draft exposed as missing:\n * soft glow orbs + additive blend (lantern light that sums where it overlaps), bounded\n * alpha pulse with per-entity phases (breathing flames, strobe-proof by construction),\n * and spawn regions (stars only above the horizon; dim ember shimmer kept low near\n * the water line).\n */\nexport const LANTERNS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'lanterns',\n label: 'Night Lanterns',\n seed: 88,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#04060f' },\n { at: 0.55, color: '#0b1026' },\n { at: 0.85, color: '#251731' },\n { at: 1, color: '#472518' },\n ],\n },\n layers: [\n {\n count: 60,\n sprite: { kind: 'circle', radius: [0.000463, 0.001296], color: '#8fa0c8' },\n alpha: [0.35, 1],\n region: { y: [0, 0.62] },\n motion: { type: 'drift', speed: [0.000463, 0.001852], bob: 0.0009259 },\n },\n {\n count: 36,\n sprite: {\n kind: 'circle',\n radius: [0.001389, 0.002778],\n color: '#b06a2a',\n soft: true,\n },\n alpha: [0.5, 0.9],\n blend: 'lighter',\n pulse: { amp: 0.18, period: 2800 },\n motion: { type: 'rise', speed: [0.005556, 0.01296], sway: 0.003704 },\n },\n {\n count: 14,\n sprite: {\n kind: 'circle',\n radius: [0.003241, 0.006019],\n color: '#e08a34',\n soft: true,\n },\n alpha: [0.6, 1],\n blend: 'lighter',\n pulse: { amp: 0.22, period: 3400 },\n motion: { type: 'rise', speed: [0.01481, 0.02593], sway: 0.006481 },\n },\n {\n count: 8,\n sprite: { kind: 'emoji', glyphs: ['🏮'] },\n size: [0.02407, 0.04074],\n alpha: [0.85, 1],\n motion: { type: 'rise', speed: [0.02778, 0.04444], sway: 0.009259 },\n },\n {\n count: 4,\n sprite: { kind: 'emoji', glyphs: ['🏮'] },\n size: [0.0537, 0.07778],\n motion: { type: 'rise', speed: [0.04815, 0.06852], sway: 0.01296 },\n },\n {\n count: 12,\n sprite: { kind: 'circle', radius: [0.001852, 0.00463], color: '#e08a34', soft: true },\n alpha: [0.12, 0.35],\n blend: 'lighter',\n region: { y: [0.93, 1] },\n pulse: { amp: 0.1, period: 2200 },\n motion: { type: 'drift', speed: [0.001852, 0.005556], bob: 0.001852 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Lobby Talk — one screen of a \"quarter in review\" that runs on a lobby wall\n * between meetings: a five-row adoption chart over the same slow haze and\n * dust the whole talk shares. The words are the point, so every text layer\n * declares `role: 'read'` — the opt-in that turns on `adviseSpec`'s\n * legibility advisories (`text-legibility` against the ground *and* the\n * brightest additive layer that can sit under a line, `text-safe-area` for\n * the bezel zone). Tuned to zero advisories: the haze is bright enough to\n * matter and dim enough to leave every label above 4.5:1 at its peak.\n *\n * Schema exercises: `role: 'read'` on both `textBlock` and `text`, a\n * `list`-laid chart in three layers (labels, `bar`s, readouts), additive\n * atmosphere (`lighter` soft circles with `pulse`) under readable copy.\n * Steer `bars.sprite.values` to change the numbers live.\n */\nexport const LOBBY_TALK_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'lobby-talk',\n label: 'Lobby Talk',\n seed: 1207,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#060912' },\n { at: 1, color: '#0b1224' },\n ],\n drift: { period: 40000, amount: 0.1 },\n },\n layers: [\n {\n key: 'haze',\n count: 3,\n sprite: { kind: 'circle', radius: [0.22, 0.3], soft: true, color: '#123a4a', colors: ['#123a4a', '#2a1e4a', '#0e2a3a'] },\n alpha: [0.35, 0.5],\n blend: 'lighter',\n region: { x: [0.2, 0.8], y: [0.3, 0.7] },\n motion: { type: 'wander', speed: [0.002, 0.004], meander: 0.05 },\n pulse: { amp: 0.15, period: 9000 },\n },\n {\n key: 'dust',\n count: 50,\n sprite: { kind: 'circle', radius: [0.0008, 0.0018], soft: true, color: '#7fb8c9' },\n alpha: [0.2, 0.5],\n blend: 'lighter',\n motion: { type: 'wander', speed: [0.001, 0.003] },\n },\n {\n key: 'title',\n count: 1,\n sprite: { kind: 'textBlock', text: 'Adoption by feature, % of accounts', maxWidth: 1.0, fontSize: 0.034, color: '#f2f4f8', role: 'read' },\n motion: { type: 'static' },\n position: { x: 0.12, y: 0.16 },\n },\n {\n key: 'labels',\n count: 5,\n sprite: { kind: 'text', strings: ['Onboarding', 'Search', 'Billing', 'Exports', 'Mobile'], font: 'system-ui', align: 'left', baseline: 'middle', color: '#a9b7cc', role: 'read' },\n size: [0.03, 0.03],\n motion: { type: 'static' },\n position: { x: 0.12, y: 0.32 },\n layout: { type: 'list', gap: 0.085 },\n },\n {\n key: 'bars',\n count: 5,\n sprite: {\n kind: 'bar',\n values: [82, 64, 91, 37, 58],\n max: 100,\n length: 0.42,\n thickness: 0.026,\n color: '#7fe0d2',\n colors: ['#7fe0d2', '#7fe0d2', '#ffcf7a', '#7fe0d2', '#7fe0d2'],\n },\n alpha: [0.9, 0.9],\n motion: { type: 'static' },\n position: { x: 0.33, y: 0.32 },\n layout: { type: 'list', gap: 0.085 },\n },\n {\n key: 'readouts',\n count: 5,\n sprite: { kind: 'text', strings: ['82%', '64%', '91%', '37%', '58%'], font: 'bold system-ui', align: 'left', baseline: 'middle', color: '#f2f4f8', role: 'read' },\n size: [0.03, 0.03],\n motion: { type: 'static' },\n position: { x: 0.78, y: 0.32 },\n layout: { type: 'list', gap: 0.085 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Matrix Rain: showcases `layout: grid` with per-axis jitter ({ y: 1 } keeps the\n * columns crisp while de-syncing them vertically), glyph `cycle`, and `ghosting`\n * doing the classic fading-trail work. Two depths of rain plus rare bright heads.\n */\nexport const MATRIX_RAIN_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'matrix-rain',\n label: 'Matrix Rain',\n seed: 1999,\n motionIntensity: 'moderate',\n ghosting: 0.88,\n background: { type: 'solid', color: '#010401' },\n layers: [\n {\n key: 'rain-far',\n count: 64,\n sprite: {\n kind: 'text',\n strings: ['ア', 'カ', 'サ', 'タ', 'ナ', 'ハ', 'マ', 'ヤ', 'ラ', 'ワ', '0', '1', '7', 'Z', 'X', 'K'],\n color: '#1c7a2e',\n font: 'bold monospace',\n cycle: { period: 900 },\n },\n size: [0.014, 0.02],\n layout: { type: 'grid', columns: 32, jitter: { y: 1 } },\n motion: { type: 'drift', speed: [0.06, 0.14], angle: 90 },\n alpha: [0.35, 0.6],\n },\n {\n key: 'rain-near',\n count: 40,\n sprite: {\n kind: 'text',\n strings: ['ミ', 'ネ', 'リ', 'ソ', 'ツ', 'ヌ', 'ホ', 'ユ', '3', '8', '9', 'V', 'N'],\n color: '#2ecc40',\n font: 'bold monospace',\n cycle: { period: 700 },\n },\n size: [0.022, 0.03],\n layout: { type: 'grid', columns: 20, jitter: { y: 1 } },\n motion: { type: 'drift', speed: [0.16, 0.3], angle: 90 },\n alpha: [0.6, 0.9],\n },\n {\n key: 'heads',\n count: 12,\n sprite: {\n kind: 'text',\n strings: ['ケ', 'メ', 'エ', 'ム', 'ヲ', '5', '2'],\n color: '#c8ffd4',\n font: 'bold monospace',\n cycle: { period: 500 },\n },\n size: [0.024, 0.032],\n layout: { type: 'grid', columns: 12, jitter: { y: 1 } },\n motion: { type: 'drift', speed: [0.2, 0.34], angle: 90 },\n alpha: [0.9, 1],\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Tarkovsky — Nostalghia's candle: a single point of devotion.\n * Near-black warm ground; one small warm-white flame at center with grow/pulse\n * wobble; faint smoke rising; sparse amber embers with long fading trails;\n * a wide near-invisible halo breathing on a 10s cycle. Minimalism as tension —\n * most of the screen is darkness.\n *\n * Note: `pulse.amp` is ADDED to base alpha (not multiplied), so the halo's amp\n * must stay below its base alpha or the trough clamps to fully invisible.\n */\nexport const NOSTALGHIA_CANDLE_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'nostalghia-candle',\n label: \"Nostalghia's Candle\",\n seed: 1983,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#050302' },\n { at: 0.55, color: '#0a0704' },\n { at: 1, color: '#120c08' },\n ],\n },\n layers: [\n {\n key: 'halo',\n count: 1,\n position: { x: 0.5, y: 0.52 },\n sprite: {\n kind: 'circle',\n radius: [0.11, 0.11],\n color: '#c4782a',\n soft: true,\n },\n // Base 0.04 + amp 0.02 → breathes ~0.02..0.06; never clamps to 0.\n // (pulse.amp is ADDED to alpha, not multiplied.) Kept subordinate to the flame.\n alpha: [0.04, 0.04],\n blend: 'lighter',\n pulse: { amp: 0.02, period: 10000 },\n grow: { amp: 0.08, period: 10000 },\n motion: { type: 'static' },\n },\n {\n key: 'smoke',\n count: 3,\n sprite: {\n kind: 'circle',\n radius: [0.01, 0.022],\n color: '#6a6258',\n soft: true,\n },\n alpha: [0.02, 0.04],\n blend: 'lighter',\n region: { x: [0.46, 0.54], y: [0.36, 0.48] },\n pulse: { amp: 0.015, period: 4500 },\n motion: { type: 'rise', speed: [0.002, 0.004], sway: 0.008 },\n },\n {\n key: 'flame-glow',\n count: 1,\n sprite: {\n kind: 'circle',\n radius: [0.028, 0.028],\n color: '#ffb040',\n soft: true,\n },\n alpha: [0.32, 0.32],\n blend: 'lighter',\n pulse: { amp: 0.12, period: 1400 },\n grow: { amp: 0.4, period: 1600 },\n // Tiny orbit = positional lean without drifting off-center (wander has vx).\n motion: {\n type: 'orbit',\n speed: [18, 18],\n radius: [0.003, 0.003],\n center: { x: 0.5, y: 0.52 },\n },\n },\n {\n key: 'flame-core',\n count: 1,\n sprite: {\n kind: 'circle',\n radius: [0.014, 0.014],\n color: '#fff6e0',\n soft: true,\n },\n alpha: [0.95, 0.95],\n blend: 'lighter',\n pulse: { amp: 0.25, period: 900 },\n grow: { amp: 0.55, period: 1100 },\n motion: {\n type: 'orbit',\n speed: [22, 22],\n radius: [0.0025, 0.0025],\n center: { x: 0.5, y: 0.52 },\n },\n },\n {\n key: 'embers',\n count: 7,\n sprite: {\n kind: 'circle',\n radius: [0.0018, 0.004],\n color: '#e08a34',\n soft: true,\n },\n alpha: [0.4, 0.8],\n blend: 'lighter',\n region: { x: [0.35, 0.65], y: [0.4, 0.7] },\n pulse: { amp: 0.2, period: 2200 },\n trail: { length: 2200, fade: 1 },\n motion: {\n type: 'drift',\n speed: [0.004, 0.012],\n angle: 270,\n bob: 0.008,\n },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Polygons: the classic Mystify-style bouncing-polygon saver, expressed as chain links + heavy\n * ghosting. Showcases `links.mode: 'chain'` with `closed` (vertices wired in order\n * into a polygon), `bounce` motion, and high `ghosting` (the decaying after-images\n * ARE the effect — no per-entity trail sampling involved).\n */\nexport const POLYGONS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'polygons',\n label: 'Polygons',\n seed: 1995,\n motionIntensity: 'moderate',\n ghosting: 0.95,\n background: { type: 'solid', color: '#04040a' },\n layers: [\n {\n key: 'poly-cyan',\n count: 4,\n sprite: { kind: 'circle', radius: [0.0025, 0.0025], color: '#37e5d7' },\n motion: { type: 'bounce', speed: [0.14, 0.24] },\n wrap: false,\n alpha: [0.9, 0.9],\n links: { k: 1, maxDist: 3, mode: 'chain', closed: true, color: '#37e5d7', alpha: 0.85, width: 0.0018 },\n },\n {\n key: 'poly-magenta',\n count: 4,\n sprite: { kind: 'circle', radius: [0.0025, 0.0025], color: '#e83e9c' },\n motion: { type: 'bounce', speed: [0.1, 0.2] },\n wrap: false,\n alpha: [0.9, 0.9],\n links: { k: 1, maxDist: 3, mode: 'chain', closed: true, color: '#e83e9c', alpha: 0.85, width: 0.0018 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Orrery: a mechanical solar system. Exercises orbit motion (concentric rings\n * at different speeds), spin (planets rotate on their axes), and grow (the sun\n * pulses). Soft glow circles with additive blending create the corona and\n * planetary halos.\n */\nexport const ORRERY_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'orrery',\n label: 'Orrery',\n seed: 7,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#020210' },\n { at: 0.5, color: '#06051a' },\n { at: 1, color: '#0a0820' },\n ],\n },\n layers: [\n // Distant stars\n {\n count: 80,\n sprite: { kind: 'circle', radius: [0.0002778, 0.001111], color: '#8899cc' },\n alpha: [0.2, 0.8],\n pulse: { amp: 0.3, period: 3000 },\n motion: { type: 'static' },\n },\n // Sun corona (soft glow)\n {\n key: 'corona',\n count: 1,\n sprite: { kind: 'circle', radius: [0.05556, 0.05556], color: '#ffaa22', soft: true },\n blend: 'lighter',\n alpha: [0.6, 0.6],\n grow: { amp: 0.15, period: 4000 },\n motion: { type: 'static' },\n position: { x: 0.5, y: 0.5 },\n },\n // Sun body\n {\n key: 'sun',\n count: 1,\n sprite: { kind: 'emoji', glyphs: ['☀️'] },\n size: [0.04444, 0.04444],\n grow: { amp: 0.08, period: 4000 },\n motion: { type: 'static' },\n position: { x: 0.5, y: 0.5 },\n },\n // Inner ring — small fast planets\n {\n key: 'inner',\n count: 3,\n sprite: { kind: 'emoji', glyphs: ['🪨', '🔴', '🟠'] },\n size: [0.01481, 0.02037],\n spin: 30,\n motion: { type: 'orbit', speed: [28, 42], radius: [0.07407, 0.1111] },\n },\n // Middle ring — gas giants\n {\n key: 'middle',\n count: 2,\n sprite: { kind: 'emoji', glyphs: ['🟤', '🪐'] },\n size: [0.02593, 0.03519],\n spin: -15,\n motion: { type: 'orbit', speed: [12, 20], radius: [0.1481, 0.1852] },\n },\n // Outer ring — ice giants\n {\n key: 'outer',\n count: 2,\n sprite: { kind: 'emoji', glyphs: ['🔵', '💎'] },\n size: [0.02037, 0.02778],\n spin: 10,\n motion: { type: 'orbit', speed: [5, 10], radius: [0.2222, 0.2778] },\n },\n // Orbital dust ring (soft glow particles orbiting slowly)\n {\n count: 24,\n sprite: { kind: 'circle', radius: [0.0009259, 0.002778], color: '#ccaa66', soft: true },\n alpha: [0.15, 0.4],\n blend: 'lighter',\n pulse: { amp: 0.2, period: 2500 },\n motion: { type: 'orbit', speed: [2, 8], radius: [0.09259, 0.2963] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Pings — almost nothing, almost never.\n * A near-black ground and one teal hue. Three rings take turns: each one\n * appears, grows sixteenfold (0.15× → 2.4× its radius) and fades over four\n * seconds, then the frame is empty until the next — `emit` with `jitter: 0`\n * spaces them evenly, one event every four seconds, and `life` is kept at\n * the stagger so no two rings are ever lit together. Underneath, a few motes rise,\n * `settle` to rest and fade on their own, longer, seeded schedule. Nothing\n * travels; everything grows and goes. The house style Fathom describes this\n * exactly and, before `emit`, could not be authored.\n */\nexport const PINGS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'pings',\n label: 'Pings',\n seed: 7,\n motionIntensity: 'calm',\n ghosting: 0.9,\n background: { type: 'solid', color: '#03060a' },\n layers: [\n {\n key: 'ping',\n count: 3,\n sprite: { kind: 'ring', radius: [0.05, 0.05], color: '#4fb3a8', width: 0.0015 },\n alpha: [0.35, 0.35],\n blend: 'lighter',\n region: { x: [0.2, 0.8], y: [0.25, 0.75] },\n motion: { type: 'static' },\n // One ring at a time: three entities evenly staggered across 12 s.\n emit: { every: 12000, life: 4000, jitter: 0, grow: [0.15, 2.4] },\n },\n {\n key: 'motes',\n count: 14,\n sprite: { kind: 'circle', radius: [0.0012, 0.002], color: '#4fb3a8', soft: true },\n alpha: [0.1, 0.22],\n blend: 'lighter',\n // Each mote is flung upward and comes to rest within ~2.5 s of its event.\n motion: { type: 'rise', speed: [0.01, 0.02], sway: 0.004, ease: { type: 'settle', tau: 2500 } },\n emit: { every: 16000, life: 7000, grow: [0.6, 1.4] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Night Procession: a choreographed scene. Showcases `path` motion (a smooth\n * figure-eight lantern route with scatter), layer-parented `orbit` (moths circling\n * a wandering lantern-bearer), `life` staging (stars first, the procession enters\n * at 4 s, moths at 7 s), plus `ring` and `rect` sprites.\n */\nexport const PROCESSION_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'procession',\n label: 'Night Procession',\n seed: 8,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#060612' },\n { at: 0.8, color: '#101024' },\n { at: 1, color: '#1a1428' },\n ],\n drift: { period: 30000, amount: 0.08 },\n },\n layers: [\n {\n key: 'stars',\n count: 90,\n sprite: { kind: 'circle', radius: [0.0006, 0.0016], color: '#f0ead8', soft: true },\n motion: { type: 'static' },\n region: { y: [0, 0.6] },\n alpha: [0.25, 0.6],\n pulse: { amp: 0.15, period: 5000 },\n },\n {\n key: 'lanterns',\n count: 9,\n sprite: {\n kind: 'rect',\n width: [0.012, 0.02],\n aspect: [1.3, 1.7],\n color: '#ffb347',\n colors: ['#ffb347', '#ff8c69', '#ffd97a'],\n colorWeights: [3, 1, 2],\n },\n motion: {\n type: 'path',\n points: [\n { x: 0.12, y: 0.72 },\n { x: 0.38, y: 0.58 },\n { x: 0.62, y: 0.78 },\n { x: 0.88, y: 0.62 },\n { x: 0.62, y: 0.5 },\n { x: 0.38, y: 0.72 },\n ],\n duration: 36000,\n curve: 'smooth',\n closed: true,\n scatter: 0.02,\n },\n alpha: [0.65, 0.9],\n pulse: { amp: 0.15, period: 2600 },\n life: { enter: 4000, fade: 2500 },\n trail: { length: 1200, fade: 1 },\n },\n {\n key: 'bearer',\n count: 1,\n sprite: { kind: 'circle', radius: [0.014, 0.014], color: '#ffe9b0', soft: true },\n motion: { type: 'wander', speed: [0.008, 0.012], meander: 0.08 },\n alpha: [0.8, 0.8],\n blend: 'lighter',\n life: { enter: 4000, fade: 2500 },\n },\n {\n key: 'moths',\n count: 7,\n sprite: { kind: 'ring', radius: [0.002, 0.005], color: '#d8f6ff', width: 0.001 },\n motion: { type: 'orbit', speed: [20, 55], radius: [0.03, 0.09], center: { layer: 'bearer' } },\n alpha: [0.3, 0.7],\n life: { enter: 7000, fade: 2000 },\n trail: { length: 600 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/** Rain: dense text streaks falling straight down over a near-black sky. */\nexport const RAIN_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'rain',\n label: 'Rain',\n seed: 7,\n motionIntensity: 'moderate',\n background: { type: 'solid', color: '#05070a' },\n layers: [\n {\n count: 140,\n sprite: { kind: 'text', strings: ['│'], color: '#9fd0ff' },\n size: [0.01111, 0.02407],\n motion: { type: 'drift', angle: 90, speed: [0.4815, 0.8333] },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Relay Board — a six-row status chart in five layers instead of twenty-five.\n * One `list` of labels, one `list` of `bar`s whose lengths are the numbers,\n * one `list` of readouts, a title block, and a slow dust field behind so the\n * board reads as a live wall, not a document. Steer `bars.sprite.values` and the\n * bars glide to the new figures; the labels never move.\n */\nexport const RELAY_BOARD_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'relay-board',\n label: 'Relay Board',\n seed: 9,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#05070d' },\n { at: 1, color: '#0a0d18' },\n ],\n },\n layers: [\n {\n key: 'dust',\n count: 40,\n sprite: { kind: 'circle', radius: [0.0008, 0.0016], color: '#22344a', soft: true },\n alpha: [0.2, 0.45],\n blend: 'lighter',\n motion: { type: 'wander', speed: [0.001, 0.003] },\n },\n {\n key: 'title',\n count: 1,\n sprite: { kind: 'textBlock', text: 'RELAY LINKS — UPLINK MARGIN', maxWidth: 0.6, fontSize: 0.028, color: '#9fb4c9' },\n motion: { type: 'static' },\n position: { x: 0.12, y: 0.16 },\n },\n {\n key: 'labels',\n count: 6,\n sprite: { kind: 'text', strings: ['VIREO-9', 'TIDE', 'ORRERY', 'COMET', 'LANTERN', 'SAKURA'], font: 'bold monospace', align: 'left', color: '#e6e8ef' },\n size: [0.024, 0.024],\n motion: { type: 'static' },\n position: { x: 0.12, y: 0.3 },\n layout: { type: 'list', gap: 0.075 },\n },\n {\n key: 'bars',\n count: 6,\n sprite: {\n kind: 'bar',\n values: [82, 64, 91, 37, 58, 73],\n max: 100,\n length: 0.5,\n thickness: 0.02,\n color: '#17e8c8',\n colors: ['#17e8c8', '#35d0ff', '#ffd93b', '#ff6ad5', '#ad8cff', '#17e8c8'],\n },\n alpha: [0.85, 0.85],\n motion: { type: 'static' },\n position: { x: 0.3, y: 0.3 },\n layout: { type: 'list', gap: 0.075 },\n },\n {\n key: 'readouts',\n count: 6,\n sprite: { kind: 'text', strings: ['82%', '64%', '91%', '37%', '58%', '73%'], font: 'monospace', align: 'left', color: '#9fb4c9' },\n size: [0.02, 0.02],\n motion: { type: 'static' },\n position: { x: 0.86, y: 0.3 },\n layout: { type: 'list', gap: 0.075 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Sakura Drift: cherry-blossom petals carried on a spring twilight breeze.\n * Glow-up pass (v1-ceiling features): petals ride `wander` harmonics with shared\n * `coherence` so gusts move the whole fall together, `spin` tumbles the glyphs,\n * faint `streak` wind-lines cross the frame, the blossom-glow backdrop shimmers\n * as a traveling `pulse.wave`, and dusk fireflies wander the lower field. The\n * ground is a warm plum earth blended out of the sunset (no more abrupt dark\n * band), with slow background `drift` keeping the sky alive.\n */\nexport const SAKURA_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'sakura',\n label: 'Sakura Drift',\n seed: 314,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#1b1d38' },\n { at: 0.45, color: '#3a2645' },\n { at: 0.78, color: '#7d3d4e' },\n { at: 0.92, color: '#4a2438' },\n { at: 1, color: '#1c1018' },\n ],\n drift: { period: 35000, amount: 0.08 },\n },\n layers: [\n {\n key: 'blossom-glow',\n count: 60,\n sprite: {\n kind: 'circle',\n radius: [0.0005556, 0.001481],\n color: '#ffe3ec',\n soft: true,\n },\n alpha: [0.3, 0.9],\n blend: 'lighter',\n region: { y: [0, 0.72] },\n // Shimmer travels across the sky instead of orbs twinkling independently.\n pulse: { amp: 0.22, period: 4000, wave: { wavelength: 0.45, angle: 10 } },\n motion: { type: 'drift', speed: [0.0002778, 0.001111], bob: 0.0009259 },\n },\n {\n key: 'petals-far',\n count: 28,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [0.01204, 0.01852],\n alpha: [0.5, 0.8],\n spin: 16,\n motion: {\n type: 'wander',\n speed: [0.011, 0.024],\n angle: 100,\n meander: 0.025,\n coherence: 0.35,\n },\n },\n {\n key: 'petals-mid',\n count: 18,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [0.01852, 0.02963],\n alpha: [0.7, 0.95],\n spin: 24,\n motion: {\n type: 'wander',\n speed: [0.022, 0.041],\n angle: 100,\n meander: 0.045,\n coherence: 0.35,\n },\n },\n {\n key: 'petals-near',\n count: 10,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [0.03148, 0.05],\n alpha: [0.85, 1],\n spin: 32,\n motion: {\n type: 'wander',\n speed: [0.039, 0.063],\n angle: 100,\n meander: 0.07,\n coherence: 0.35,\n },\n },\n {\n key: 'gusts',\n count: 7,\n sprite: {\n kind: 'streak',\n length: [0.02, 0.045],\n width: 0.0012,\n color: '#ffd9e6',\n },\n alpha: [0.1, 0.22],\n blend: 'lighter',\n motion: { type: 'drift', speed: [0.09, 0.14], angle: 100 },\n },\n {\n key: 'fireflies',\n count: 6,\n sprite: {\n kind: 'circle',\n radius: [0.0009, 0.002],\n color: '#ffe9a8',\n soft: true,\n },\n alpha: [0.15, 0.5],\n blend: 'lighter',\n region: { y: [0.6, 0.9] },\n pulse: { amp: 0.3, period: 2800 },\n motion: { type: 'wander', speed: [0.004, 0.01], meander: 0.05 },\n },\n {\n key: 'fallen-petals',\n count: 16,\n sprite: {\n kind: 'circle',\n radius: [0.001389, 0.003704],\n color: '#ff9bb5',\n soft: true,\n },\n alpha: [0.1, 0.3],\n blend: 'lighter',\n region: { y: [0.9, 1] },\n // Settled petals catch the last light in a slow wave along the ground.\n pulse: { amp: 0.15, period: 3200, wave: { wavelength: 0.3, angle: 0 } },\n motion: {\n type: 'drift',\n speed: [0.0002778, 0.001389],\n angle: 180,\n bob: 0.0009259,\n },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/** Snowfall: three depth layers of white circles drifting down with horizontal bob. */\nexport const SNOWFALL_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'snowfall',\n label: 'Snowfall',\n seed: 12,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a1628' },\n { at: 0.7, color: '#0d1f3c' },\n { at: 1, color: '#121212' },\n ],\n },\n layers: [\n {\n count: 50,\n sprite: { kind: 'circle', radius: [0.0009259, 0.002315], color: '#8899aa' },\n motion: { type: 'drift', angle: 90, speed: [0.01389, 0.03704], bob: 0.002778 },\n },\n {\n count: 35,\n sprite: { kind: 'circle', radius: [0.001852, 0.004167], color: '#c0cdd8' },\n motion: { type: 'drift', angle: 85, speed: [0.03241, 0.07407], bob: 0.005556 },\n },\n {\n count: 15,\n sprite: { kind: 'circle', radius: [0.003241, 0.006481], color: '#e8eff5' },\n motion: { type: 'drift', angle: 82, speed: [0.05093, 0.1111], bob: 0.009259 },\n },\n ],\n};\n","import type { SaverSpec } from '../types';\n\n/**\n * Warp Tunnel: showcases `warp` motion (perspective depth — size/alpha/speed scale\n * with 1/z), `streak` sprites oriented along the analytic heading, `colorWeights`\n * (mostly white stars, occasional blue/amber), and light `ghosting` for smear.\n */\nexport const WARP_TUNNEL_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'warp-tunnel',\n label: 'Warp Tunnel',\n seed: 1701,\n motionIntensity: 'energetic',\n ghosting: 0.55,\n background: { type: 'solid', color: '#020208' },\n layers: [\n {\n key: 'far-stars',\n count: 150,\n sprite: {\n kind: 'streak',\n length: [0.008, 0.02],\n width: 0.0015,\n color: '#cfd8ff',\n colors: ['#cfd8ff', '#ffffff', '#8ab4ff', '#ffd9a0'],\n colorWeights: [5, 3, 1.5, 0.5],\n },\n motion: { type: 'warp', speed: [0.06, 0.16] },\n alpha: [0.5, 0.9],\n blend: 'lighter',\n },\n {\n key: 'near-stars',\n count: 50,\n sprite: {\n kind: 'streak',\n length: [0.025, 0.06],\n width: 0.0025,\n color: '#ffffff',\n colors: ['#ffffff', '#a8c8ff'],\n colorWeights: [3, 1],\n },\n motion: { type: 'warp', speed: [0.3, 0.55] },\n alpha: [0.7, 1],\n blend: 'lighter',\n },\n {\n key: 'core-glow',\n count: 1,\n sprite: { kind: 'circle', radius: [0.06, 0.06], color: '#3a4a8f', soft: true },\n motion: { type: 'static' },\n position: { x: 0.5, y: 0.5 },\n alpha: [0.35, 0.35],\n pulse: { amp: 0.15, period: 5000 },\n blend: 'lighter',\n },\n ],\n};\n","import type { SaverSpec } from '../types';\nimport { AQUARIUM_SPEC } from './aquarium';\nimport { AURORA_SPEC } from './aurora';\nimport { COMETS_SPEC } from './comets';\nimport { CONSTELLATION_SPEC } from './constellation';\nimport { DASHBOARD_SPEC } from './dev-dashboard';\nimport { FACETS_SPEC } from './facets';\nimport { HAIKU_SPEC } from './haiku';\nimport { LANTERNS_SPEC } from './lanterns';\nimport { LOBBY_TALK_SPEC } from './lobby-talk';\nimport { MATRIX_RAIN_SPEC } from './matrix-rain';\nimport { NOSTALGHIA_CANDLE_SPEC } from './nostalghia-candle';\nimport { POLYGONS_SPEC } from './polygons';\nimport { ORRERY_SPEC } from './orrery';\nimport { PINGS_SPEC } from './pings';\nimport { PROCESSION_SPEC } from './procession';\nimport { RAIN_SPEC } from './rain';\nimport { RELAY_BOARD_SPEC } from './relay-board';\nimport { SAKURA_SPEC } from './sakura';\nimport { SNOWFALL_SPEC } from './snowfall';\nimport { WARP_TUNNEL_SPEC } from './warp-tunnel';\n\nexport { AQUARIUM_SPEC } from './aquarium';\nexport { COMETS_SPEC } from './comets';\nexport { CONSTELLATION_SPEC } from './constellation';\nexport { RAIN_SPEC } from './rain';\nexport { SNOWFALL_SPEC } from './snowfall';\nexport { LANTERNS_SPEC } from './lanterns';\nexport { LOBBY_TALK_SPEC } from './lobby-talk';\nexport { SAKURA_SPEC } from './sakura';\nexport { DASHBOARD_SPEC } from './dev-dashboard';\nexport { HAIKU_SPEC } from './haiku';\nexport { ORRERY_SPEC } from './orrery';\nexport { AURORA_SPEC } from './aurora';\nexport { MATRIX_RAIN_SPEC } from './matrix-rain';\nexport { NOSTALGHIA_CANDLE_SPEC } from './nostalghia-candle';\nexport { PINGS_SPEC } from './pings';\nexport { FACETS_SPEC } from './facets';\nexport { RELAY_BOARD_SPEC } from './relay-board';\nexport { POLYGONS_SPEC } from './polygons';\nexport { PROCESSION_SPEC } from './procession';\nexport { WARP_TUNNEL_SPEC } from './warp-tunnel';\n\n/** Catalog entry for a bundled schema example. */\nexport interface SchemaExample {\n id: string;\n label: string;\n spec: SaverSpec;\n}\n\n/** Ordered catalog of bundled schema examples. Add new specs as standalone files, then register here. */\nexport const SCHEMA_EXAMPLES: readonly SchemaExample[] = [\n { id: 'aquarium', label: 'Aquarium', spec: AQUARIUM_SPEC },\n { id: 'rain', label: 'Rain', spec: RAIN_SPEC },\n { id: 'snowfall', label: 'Snowfall', spec: SNOWFALL_SPEC },\n { id: 'lanterns', label: 'Night Lanterns', spec: LANTERNS_SPEC },\n { id: 'sakura', label: 'Sakura Drift', spec: SAKURA_SPEC },\n { id: 'dev-dashboard', label: 'Control Center', spec: DASHBOARD_SPEC },\n { id: 'orrery', label: 'Orrery', spec: ORRERY_SPEC },\n { id: 'constellation', label: 'Constellation', spec: CONSTELLATION_SPEC },\n { id: 'comets', label: 'Comet Shower', spec: COMETS_SPEC },\n { id: 'aurora', label: 'Aurora', spec: AURORA_SPEC },\n { id: 'warp-tunnel', label: 'Warp Tunnel', spec: WARP_TUNNEL_SPEC },\n { id: 'polygons', label: 'Polygons', spec: POLYGONS_SPEC },\n { id: 'matrix-rain', label: 'Matrix Rain', spec: MATRIX_RAIN_SPEC },\n { id: 'procession', label: 'Night Procession', spec: PROCESSION_SPEC },\n { id: 'nostalghia-candle', label: \"Nostalghia's Candle\", spec: NOSTALGHIA_CANDLE_SPEC },\n { id: 'haiku', label: 'Haiku', spec: HAIKU_SPEC },\n { id: 'pings', label: 'Pings', spec: PINGS_SPEC },\n { id: 'facets', label: 'Facets', spec: FACETS_SPEC },\n { id: 'relay-board', label: 'Relay Board', spec: RELAY_BOARD_SPEC },\n { id: 'lobby-talk', label: 'Lobby Talk', spec: LOBBY_TALK_SPEC },\n] as const;\n\n/** All example specs in catalog order (tests, batch compile). */\nexport const EXAMPLE_SPECS: SaverSpec[] = SCHEMA_EXAMPLES.map((e) => e.spec);\n\n/** Lookup by saver id. */\nexport const EXAMPLE_BY_ID: Readonly<Record<string, SaverSpec>> = Object.fromEntries(\n SCHEMA_EXAMPLES.map((e) => [e.id, e.spec]),\n);\n"],"mappings":"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","names":["HEX","catmullRom","y","x","wrap","unitScale","createRng","createRng","createRng","createRng","createRng","createRng","s","sizePx"]}