@idle-screens/schema 3.6.0 → 3.6.1
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/FORMAT.md +135 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +29 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/saver-spec.schema.json +55 -1
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']);\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' && 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', '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.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.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 /** 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 const [smin, smax] = layer.size ?? [20, 40];\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 ...(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 return {\n x: e.x0 + (e.bob ? e.bob * Math.sin(t / 700 + e.phase) : 0),\n y: wrap(e.y0 + e.vy * dt, -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 return {\n x: wrap(e.x0 + e.vx * dt + hx, -margin, w + margin),\n y: wrap(e.y0 + e.vy * dt + hy, -margin, h + margin),\n flip: e.headingLeft,\n };\n }\n // drift\n const x = wrap(e.x0 + e.vx * dt, -m, w + m);\n let y = e.vy !== 0 ? wrap(e.y0 + e.vy * dt, -m, h + m) : e.y0;\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 lw = (links.width ?? 1) * (this.effSpec.units === 'px' ? 1 : Math.min(this.w, this.h));\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 if (useMorphSeed) child.hotSwapSpec(this.childScene(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 lwPx = (layer.links.width ?? 1) * 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 wgt = Math.min(1, ((layer.links.width ?? 1) * 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 lw = (layer.links.width ?? 1) * 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","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/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"]}
|