onda-engine 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../player/src/canvas-renderer.ts","../../player/src/engine-drawer.ts","../../player/src/audio-engine.ts","../../player/src/audio.ts","../../player/src/images.ts","../../player/src/video.ts","../../player/src/player.tsx"],"names":["inflight","Player","playbackRate"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA","file":"player.js","sourcesContent":["//! Canvas2D **preview** renderer (the stopgap path).\n//!\n//! Draws an ONDA scene graph to a `CanvasRenderingContext2D` for a fast,\n//! dependency-free in-browser preview. It interprets the *same* scene graph the\n//! engine renders, and now covers shapes (rect/ellipse/path), gradients, clips,\n//! transforms, and opacity — but it is **not** the engine and is **not\n//! pixel-accurate**:\n//!\n//! - Text uses the browser's font rasterizer (and a heuristic baseline), not\n//! the engine's cosmic-text + bundled Open Sans, so glyph shapes/metrics\n//! differ.\n//! - Anti-aliasing, gradient color-space, and path/stroke geometry follow the\n//! browser's Canvas2D, not Vello.\n//!\n//! The pixel-exact output is `onda render` / `onda export`, and in the browser\n//! the {@link @onda-engine/wasm} `OndaEngine` (the real Rust renderer compiled to wasm).\n//! Prefer that drawer in `<Player>` when it is available; this Canvas2D renderer\n//! is the graceful fallback. A WebGPU *present* path (see `WEBGPU.md`) is the\n//! planned way to make in-browser preview == export at real-time speed.\n\nimport type { Color, Gradient, Scene, SceneNode, ShapeGeometry } from '@onda-engine/react'\n\n/** Paints a scene onto a 2D context. The default is {@link drawScene}; the\n * playground and `<Player>` swap in a WASM-engine drawer (real renderer →\n * `putImageData`) when `@onda-engine/wasm` is present. */\nexport type FrameDrawer = (ctx: CanvasRenderingContext2D, scene: Scene) => void\n\n/** Draw `scene` onto `ctx`, clearing first. The context should be sized to the\n * composition's resolution. */\nexport function drawScene(ctx: CanvasRenderingContext2D, scene: Scene): void {\n const { width, height } = scene.composition\n ctx.clearRect(0, 0, width, height)\n ctx.save()\n ctx.globalAlpha = 1\n drawNode(ctx, scene.root)\n ctx.restore()\n}\n\nfunction drawNode(ctx: CanvasRenderingContext2D, node: SceneNode): void {\n ctx.save()\n\n const transform = node.transform\n if (transform?.translate) ctx.translate(transform.translate.x, transform.translate.y)\n if (transform?.scale) ctx.scale(transform.scale.x, transform.scale.y)\n if (typeof node.opacity === 'number') ctx.globalAlpha *= node.opacity\n\n // Clip this node's subtree to its (local-space) geometry, if any.\n if (node.clip) {\n geometryPath(ctx, node.clip)\n ctx.clip()\n }\n\n const kind = node.kind\n switch (kind.type) {\n case 'group':\n break\n case 'shape':\n drawShape(ctx, kind)\n break\n case 'text':\n drawText(ctx, kind)\n break\n // Images and inline SVG are not previewed in Canvas2D (the WASM engine\n // renders them faithfully); they're skipped rather than drawn wrong.\n case 'image':\n case 'svg':\n break\n }\n\n for (const child of node.children ?? []) drawNode(ctx, child)\n\n ctx.restore()\n}\n\n/** Trace a {@link ShapeGeometry} as the current path (no fill/stroke). Used by\n * both shape drawing and clipping so the two stay consistent. */\nfunction geometryPath(ctx: CanvasRenderingContext2D, geometry: ShapeGeometry): void {\n ctx.beginPath()\n switch (geometry.shape) {\n case 'rect': {\n const { width, height } = geometry.size\n if (geometry.corner_radius) ctx.roundRect(0, 0, width, height, geometry.corner_radius)\n else ctx.rect(0, 0, width, height)\n break\n }\n case 'ellipse': {\n const rx = geometry.size.width / 2\n const ry = geometry.size.height / 2\n ctx.ellipse(rx, ry, rx, ry, 0, 0, Math.PI * 2)\n break\n }\n case 'path':\n // SVG path data maps directly onto a Path2D the browser can trace.\n ctx.beginPath()\n tracePath(ctx, geometry.data)\n break\n }\n}\n\n/** Trace SVG path data into `ctx`. Uses `Path2D` where available (browsers);\n * no-ops on platforms without it (e.g. headless test stubs). */\nfunction tracePath(ctx: CanvasRenderingContext2D, data: string): void {\n if (typeof Path2D === 'undefined') return\n // Stash the Path2D so fill/stroke can target it (Canvas2D can fill a Path2D).\n pendingPath = new Path2D(data)\n}\n\nlet pendingPath: Path2D | null = null\n\nfunction drawShape(\n ctx: CanvasRenderingContext2D,\n shape: Extract<SceneNode['kind'], { type: 'shape' }>,\n): void {\n pendingPath = null\n geometryPath(ctx, shape.geometry)\n\n // A gradient paint takes precedence over a solid fill (mirrors @onda-engine/react).\n const paint = shape.gradient\n ? gradientStyle(ctx, shape.geometry, shape.gradient)\n : shape.fill\n ? cssColor(shape.fill)\n : null\n\n if (paint) {\n ctx.fillStyle = paint\n if (pendingPath) ctx.fill(pendingPath)\n else ctx.fill()\n }\n if (shape.stroke) {\n ctx.strokeStyle = cssColor(shape.stroke.color)\n ctx.lineWidth = shape.stroke.width\n if (pendingPath) ctx.stroke(pendingPath)\n else ctx.stroke()\n }\n pendingPath = null\n}\n\n/** Build a Canvas2D gradient from the engine's {@link Gradient} (local space).\n * Note: Canvas2D interpolates in sRGB, so colors won't match Vello exactly. */\nfunction gradientStyle(\n ctx: CanvasRenderingContext2D,\n geometry: ShapeGeometry,\n gradient: Gradient,\n): CanvasGradient {\n let g: CanvasGradient\n if (gradient.gradient === 'linear') {\n g = ctx.createLinearGradient(gradient.start.x, gradient.start.y, gradient.end.x, gradient.end.y)\n } else if (gradient.gradient === 'radial') {\n g = ctx.createRadialGradient(\n gradient.center.x,\n gradient.center.y,\n 0,\n gradient.center.x,\n gradient.center.y,\n gradient.radius,\n )\n } else {\n // `fbm` is a procedural GPU shader the Canvas2D fallback can't reproduce —\n // approximate it as a linear sweep across the shape bounds using the same\n // stops (this fallback never matches Vello exactly; the goal is \"doesn't throw\n // / roughly right\", and the real engine paths are pixel-exact).\n const [w, h] = geometryExtent(geometry)\n g = ctx.createLinearGradient(0, 0, w, h)\n }\n for (const stop of gradient.stops) {\n g.addColorStop(Math.min(1, Math.max(0, stop.offset)), cssColor(stop.color))\n }\n return g\n}\n\n/** A rough local-space extent for the fbm fallback: the shape's own size for\n * rect/ellipse, or a default span for paths (no cheap bounds in the fallback). */\nfunction geometryExtent(geometry: ShapeGeometry): [number, number] {\n if (geometry.shape === 'rect' || geometry.shape === 'ellipse') {\n return [geometry.size.width, geometry.size.height]\n }\n return [256, 256]\n}\n\nfunction drawText(\n ctx: CanvasRenderingContext2D,\n text: Extract<SceneNode['kind'], { type: 'text' }>,\n): void {\n ctx.fillStyle = cssColor(text.color ?? { r: 1, g: 1, b: 1 })\n ctx.textBaseline = 'alphabetic'\n const size = text.font_size ?? 48\n ctx.font = `${size}px sans-serif`\n // The engine places text by its top-left; nudge down by ~the ascent so the\n // preview roughly lines up with the real render (still only approximate).\n ctx.fillText(text.content, 0, size * 0.8)\n}\n\n/** Convert the engine's 0..1 straight-alpha sRGB color to a CSS `rgba()`. */\nexport function cssColor(color: Color): string {\n const to255 = (c: number) => Math.round(Math.min(1, Math.max(0, c)) * 255)\n return `rgba(${to255(color.r)}, ${to255(color.g)}, ${to255(color.b)}, ${color.a ?? 1})`\n}\n","//! Bridge the **real** ONDA renderer (the `@onda-engine/wasm` `OndaEngine`) into a\n//! `<Player>` {@link FrameDrawer}.\n//!\n//! The wasm engine is the same Rust renderer `onda export` uses (cosmic-text +\n//! the bundled Open Sans, Vello-class shape/path/gradient/clip semantics), so a\n//! preview drawn through it is **pixel-identical to the native/CLI render** — no\n//! DOM, no Chromium. This is the charter-true preview path; the Canvas2D\n//! {@link drawScene} renderer is the dependency-free fallback.\n//!\n//! To keep `@onda-engine/player` free of a hard dependency on `@onda-engine/wasm`, the engine\n//! is accepted *structurally*: any object exposing `render(json) -> RenderedFrame`\n//! works. The app owns wasm init and constructs the engine.\n\nimport type { Scene } from '@onda-engine/react'\nimport type { FrameDrawer } from './canvas-renderer.js'\n\n/** A rendered frame as returned by `@onda-engine/wasm`'s `OndaEngine.render`: a flat\n * straight-alpha RGBA8 buffer plus dimensions. */\nexport interface RenderedFrame {\n readonly width: number\n readonly height: number\n readonly pixels: Uint8Array | Uint8ClampedArray\n}\n\n/** The minimal shape of `@onda-engine/wasm`'s `OndaEngine` the player needs. Structural\n * typing avoids a build/runtime dependency on the wasm package. */\nexport interface RenderEngine {\n /** Rasterize a scene-graph JSON document to RGBA8 pixels. */\n render(sceneJson: string): RenderedFrame\n}\n\n/**\n * Build a {@link FrameDrawer} that paints each frame with the real ONDA engine\n * (`@onda-engine/wasm`). Construct the engine once and memoize the returned drawer:\n *\n * ```tsx\n * import { OndaEngine, default as initWasm } from '@onda-engine/wasm'\n * import wasmUrl from '@onda-engine/wasm/pkg/onda_wasm_bg.wasm?url'\n * import { Player, engineDrawer } from '@onda-engine/player'\n *\n * await initWasm(wasmUrl)\n * const engine = new OndaEngine()\n * const draw = engineDrawer(engine) // memoize with useMemo in components\n *\n * <Player composition={hello} draw={draw} />\n * ```\n *\n * The engine renders the scene to RGBA8 and the drawer blits it with\n * `putImageData` — pixel-exact, the real renderer.\n */\nexport function engineDrawer(engine: RenderEngine): FrameDrawer {\n return (ctx, scene: Scene) => {\n const frame = engine.render(JSON.stringify(scene))\n // `ImageData` needs a `Uint8ClampedArray`; the wasm engine returns a\n // `Uint8Array`, so wrap (no copy) when it isn't already clamped.\n const buffer =\n frame.pixels instanceof Uint8ClampedArray\n ? frame.pixels\n : new Uint8ClampedArray(frame.pixels.buffer, frame.pixels.byteOffset, frame.pixels.length)\n // The DOM lib's ImageDataArray wants an ArrayBuffer-backed view; the runtime\n // value always is one, so assert the element type for the constructor.\n const image = new ImageData(buffer as Uint8ClampedArray<ArrayBuffer>, frame.width, frame.height)\n ctx.putImageData(image, 0, 0)\n }\n}\n","//! Web Audio transport for the Player's preview.\n//!\n//! The preview's visual frame-clock pegs the main thread (the per-frame wasm/GPU\n//! render), and an HTML `<audio>` element leans on the main thread for buffering\n//! and servicing — so under that load it underruns and glitches every second or\n//! two. This plays each clip through the **Web Audio API** instead: the source is\n//! decoded ONCE into an in-memory `AudioBuffer` and scheduled on the audio render\n//! thread, which is immune to main-thread jank. No streaming, no per-frame seeks,\n//! no loop-seam click.\n//!\n//! Model: the timeline is the master clock. On play we anchor the audio to the\n//! playhead (a `compTime` ↔ `AudioContext.currentTime` mapping) and schedule clip\n//! instances cycle-by-cycle with a look-ahead, so a looping timeline is gapless\n//! (the next cycle is queued before the current one ends — no JS seek at the wrap).\n//! We re-anchor only on an explicit play/seek/rate change, never to chase drift.\n//!\n//! Export is unaffected — it muxes the same nodes through the native pipeline.\n\nimport type { AudioClip } from './audio.js'\n\n/** Seconds of audio kept scheduled ahead of the playhead. Comfortably spans a\n * background tab's throttled top-up interval so playback never runs dry. */\nconst LOOKAHEAD = 2\n/** How often (ms) we top up the schedule with upcoming loop cycles. */\nconst TOPUP_INTERVAL = 250\n/** Master-gain ramp (s) — a short ramp instead of a step avoids a click on\n * mute/unmute and volume changes. */\nconst GAIN_RAMP = 0.012\n\ninterface ClipState {\n clip: AudioClip\n buffer: AudioBuffer | null\n gain: GainNode | null\n decoding: boolean\n}\n\n/** One per `<Player>`. Browser-only — instantiate inside an effect. The\n * `AudioContext` is created lazily on first {@link play} so we never spin one up\n * before a user gesture (autoplay policy) or during SSR. */\nexport class PreviewAudio {\n private ctx: AudioContext | null = null\n private master: GainNode | null = null\n private clips: ClipState[] = []\n /** Decoded buffers keyed by src, reused across `setClips` so the editor's\n * frequent composition edits don't re-fetch/re-decode unchanged audio. */\n private bufferCache = new Map<string, AudioBuffer>()\n /** Bumped on every `setClips` so a stale in-flight decode can't apply. */\n private clipsToken = 0\n\n private period = 1 // one timeline cycle, seconds (always > 0)\n private loop = false\n private rate = 1\n private volume = 1\n private muted = false\n\n private playing = false\n private anchorCtx = 0 // AudioContext time at `anchorComp`\n private anchorComp = 0 // composition time (s) at the anchor\n private nextCycle: number[] = [] // per clip: next loop cycle index to schedule\n private active: AudioBufferSourceNode[] = []\n private timer: ReturnType<typeof setInterval> | null = null\n\n // ── public API ──────────────────────────────────────────────────────────\n\n /** Master volume × mute. Applied as a short ramp (click-free). */\n setGain(volume: number, muted: boolean): void {\n this.volume = volume\n this.muted = muted\n this.applyMaster()\n }\n\n setLoop(loop: boolean): void {\n this.loop = loop // the top-up loop reads this each tick; no reschedule needed\n }\n\n /** Swap the clip set (composition changed) and the timeline period. Tears down\n * the current schedule, (re)decodes as needed, and reschedules if playing. */\n setClips(clips: AudioClip[], periodSeconds: number): void {\n this.period = Math.max(0.001, periodSeconds)\n this.stopActive()\n const token = ++this.clipsToken\n this.clips = clips.map((clip) => ({ clip, buffer: null, gain: null, decoding: false }))\n if (this.ctx) {\n this.wireClipGains()\n for (const cs of this.clips) this.ensureDecoded(cs, token)\n if (this.playing) this.reanchor(this.currentComp())\n }\n // No ctx yet → decode + wiring deferred to the first play().\n }\n\n setRate(rate: number): void {\n if (this.rate === rate) return\n const comp = this.playing ? this.currentComp() : this.anchorComp\n this.rate = rate\n // We only play at 1× (off-speed would pitch-shift); re-anchoring restarts the\n // schedule, which `scheduleAhead` then skips while rate ≠ 1.\n if (this.playing) this.reanchor(comp)\n else this.applyMaster()\n }\n\n /** Start (or restart) playback anchored at `compTime` (seconds). */\n play(compTime: number): void {\n const ctx = this.ensureCtx()\n void ctx.resume().catch(() => {})\n this.playing = true\n const token = this.clipsToken\n for (const cs of this.clips) this.ensureDecoded(cs, token)\n this.reanchor(compTime)\n this.startTimer()\n }\n\n pause(): void {\n this.playing = false\n this.stopActive()\n this.stopTimer()\n }\n\n /** Re-anchor to a new playhead. While playing this restarts the schedule from\n * `compTime`; while paused it just records the position for the next play. */\n seek(compTime: number): void {\n if (this.playing) this.reanchor(compTime)\n else this.anchorComp = compTime\n }\n\n dispose(): void {\n this.stopActive()\n this.stopTimer()\n this.clips = []\n this.bufferCache.clear()\n if (this.ctx) {\n void this.ctx.close().catch(() => {})\n this.ctx = null\n this.master = null\n }\n }\n\n // ── internals ───────────────────────────────────────────────────────────\n\n private ensureCtx(): AudioContext {\n if (!this.ctx) {\n const Ctor =\n window.AudioContext ??\n (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext\n this.ctx = new Ctor()\n this.master = this.ctx.createGain()\n this.master.connect(this.ctx.destination)\n this.applyMaster()\n this.wireClipGains()\n }\n return this.ctx\n }\n\n /** Give every clip a per-clip gain (its own volume) feeding the master. */\n private wireClipGains(): void {\n if (!this.ctx || !this.master) return\n for (const cs of this.clips) {\n if (!cs.gain) {\n const g = this.ctx.createGain()\n g.gain.value = Math.max(0, Math.min(1, cs.clip.volume))\n g.connect(this.master)\n cs.gain = g\n }\n }\n }\n\n private ensureDecoded(cs: ClipState, token: number): void {\n if (cs.buffer || cs.decoding || !this.ctx) return\n const cached = this.bufferCache.get(cs.clip.src)\n if (cached) {\n cs.buffer = cached\n return\n }\n cs.decoding = true\n const ctx = this.ctx\n void (async () => {\n try {\n const res = await fetch(cs.clip.src)\n const bytes = await res.arrayBuffer()\n const decoded = await ctx.decodeAudioData(bytes)\n if (token !== this.clipsToken) return // superseded by a newer setClips\n this.bufferCache.set(cs.clip.src, decoded)\n cs.buffer = decoded\n cs.decoding = false\n if (this.playing) this.scheduleAhead() // newly-ready clip joins the schedule\n } catch (err) {\n cs.decoding = false\n // Leave buffer null → the clip is silently skipped (not fatal to preview).\n console.warn('[onda] preview audio decode failed:', cs.clip.src, err)\n }\n })()\n }\n\n /** Composition time (s) currently under the playhead, derived from the anchor. */\n private currentComp(): number {\n if (!this.ctx) return this.anchorComp\n return this.anchorComp + (this.ctx.currentTime - this.anchorCtx) * this.rate\n }\n\n private compToCtx(compTime: number): number {\n return this.anchorCtx + (compTime - this.anchorComp) / this.rate\n }\n\n private reanchor(compTime: number): void {\n this.stopActive()\n const ctx = this.ensureCtx()\n this.anchorCtx = ctx.currentTime\n this.anchorComp = compTime\n const startCycle = this.loop ? Math.floor(compTime / this.period) : 0\n this.nextCycle = this.clips.map(() => startCycle)\n this.applyMaster()\n this.scheduleAhead()\n }\n\n /** Queue every clip instance whose start falls within the look-ahead window.\n * Idempotent + incremental: `nextCycle[i]` tracks how far each clip is queued,\n * so repeated calls only add the newly-reachable cycles. */\n private scheduleAhead(): void {\n // Off-speed preview plays silent (raw playbackRate would chipmunk) — schedule\n // nothing until the rate returns to 1×.\n if (!this.playing || !this.ctx || this.rate !== 1) return\n const ctx = this.ctx\n const horizon = ctx.currentTime + LOOKAHEAD\n for (let i = 0; i < this.clips.length; i++) {\n const cs = this.clips[i]\n if (!cs || !cs.buffer || !cs.gain) continue\n const bufDur = cs.buffer.duration\n for (let guard = 0; guard < 512; guard++) {\n const k = this.nextCycle[i] ?? 0\n const compClipStart = k * this.period + cs.clip.start\n let ctxStart = this.compToCtx(compClipStart)\n if (ctxStart >= horizon) break\n\n let offset = cs.clip.startAt\n // The clip plays until the source ends OR the timeline cycle wraps.\n let dur = Math.min(bufDur - offset, this.period - cs.clip.start)\n // If this instance's start is already behind the playhead (the partial\n // cycle at the anchor, or a clip that began before we anchored), begin it\n // now from the corresponding offset instead of in the past.\n if (ctxStart < ctx.currentTime) {\n const late = (ctx.currentTime - ctxStart) * this.rate\n offset += late\n dur -= late\n ctxStart = ctx.currentTime\n }\n if (dur > 0.005 && offset < bufDur) {\n const src = ctx.createBufferSource()\n src.buffer = cs.buffer\n src.connect(cs.gain)\n src.onended = () => {\n const idx = this.active.indexOf(src)\n if (idx >= 0) this.active.splice(idx, 1)\n try {\n src.disconnect()\n } catch {\n // already torn down\n }\n }\n // playbackRate stays 1 (we only schedule at 1×); `dur` is buffer-seconds.\n try {\n src.start(ctxStart, offset, dur)\n this.active.push(src)\n } catch {\n // start() can throw if the ctx is mid-teardown — ignore.\n }\n }\n this.nextCycle[i] = k + 1\n if (!this.loop) break // non-looping: only the current cycle exists\n }\n }\n }\n\n private applyMaster(): void {\n if (!this.master || !this.ctx) return\n const target = this.muted || this.rate !== 1 ? 0 : Math.max(0, Math.min(1, this.volume))\n this.master.gain.setTargetAtTime(target, this.ctx.currentTime, GAIN_RAMP)\n }\n\n private stopActive(): void {\n for (const src of this.active) {\n src.onended = null\n try {\n src.stop()\n } catch {\n // not started / already stopped\n }\n try {\n src.disconnect()\n } catch {\n // already disconnected\n }\n }\n this.active = []\n }\n\n private startTimer(): void {\n if (this.timer != null) return\n this.timer = setInterval(() => this.scheduleAhead(), TOPUP_INTERVAL)\n }\n\n private stopTimer(): void {\n if (this.timer != null) {\n clearInterval(this.timer)\n this.timer = null\n }\n }\n}\n","//! Audio playback support for the Player.\n//!\n//! Non-visual `<Audio>` nodes ride in the scene graph; the player finds them here\n//! and plays them via plain `<audio>` elements, synced to play/pause + scrub at\n//! the player's volume. (Export muxes the same nodes via the native pipeline.)\n\n/** The minimal scene-node shape this walker touches. */\ninterface AudioSceneNode {\n kind?: {\n type?: string\n src?: string\n start?: number\n start_at?: number\n volume?: number\n }\n children?: AudioSceneNode[]\n}\n\n/** An audio clip to play for preview. */\nexport interface AudioClip {\n src: string\n /** Composition time (seconds) the clip begins at. */\n start: number\n /** Seconds into the source to begin from (trim the head). */\n startAt: number\n /** Linear gain, 0..1. */\n volume: number\n}\n\n/** Collect every `<Audio>` clip in a scene (non-visual; the player plays them). */\nexport function collectAudioClips(root: AudioSceneNode | undefined): AudioClip[] {\n const out: AudioClip[] = []\n const walk = (node: AudioSceneNode | undefined) => {\n if (!node) return\n const k = node.kind\n if (k?.type === 'audio' && typeof k.src === 'string' && k.src.length > 0) {\n out.push({\n src: k.src,\n start: k.start ?? 0,\n startAt: k.start_at ?? 0,\n volume: k.volume ?? 1,\n })\n }\n for (const child of node.children ?? []) walk(child)\n }\n walk(root)\n return out\n}\n","//! In-browser image resolution.\n//!\n//! The wasm engine decodes `data:` URIs but can't fetch URL/path image sources\n//! (there's no filesystem or fetch inside the render call). So the Player resolves\n//! image `src` URLs to `data:` URIs in JS — the browser fetches + the engine's\n//! existing `data:` decode path handles them. Resolved URIs are cached and shared\n//! across players, so each image is fetched once.\n\n// Resolved `url -> data: URI`. Module-level so multiple <Player>s share it.\nconst cache = new Map<string, string>()\nconst inflight = new Map<string, Promise<void>>()\n// URLs whose fetch finished UNsuccessfully (404 / CORS / network). Tracked so the\n// on-demand resolver treats them as \"settled\" and never re-fetches in a loop — a\n// failed image just stays blank (same as before), it doesn't peg the engine.\nconst failed = new Set<string>()\n\n/** Fetch `url` and convert it to a `data:` URI, caching the result. Failures are\n * recorded (not retried) — the image stays unresolved and the renderer skips it. */\nexport function resolveImageUrl(url: string): Promise<void> {\n if (cache.has(url) || failed.has(url) || typeof fetch === 'undefined') return Promise.resolve()\n const existing = inflight.get(url)\n if (existing) return existing\n const p = (async () => {\n try {\n const res = await fetch(url)\n if (!res.ok) {\n failed.add(url)\n return\n }\n const blob = await res.blob()\n const dataUri = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(String(reader.result))\n reader.onerror = () => reject(reader.error)\n reader.readAsDataURL(blob)\n })\n cache.set(url, dataUri)\n } catch {\n // Network/CORS error — mark settled so we don't re-fetch it every repaint.\n failed.add(url)\n } finally {\n inflight.delete(url)\n }\n })()\n inflight.set(url, p)\n return p\n}\n\n/** True once `url` is decoded-ready: a `data:`/generated src needs no fetch, and a\n * resolved URL is in the cache. Lets the render loop skip already-handled images\n * and only kick off fetches for genuinely new ones (no repaint loop). */\nexport function imageResolved(url: string): boolean {\n return (\n url.startsWith('data:') || url.startsWith('onda-noise:') || cache.has(url) || failed.has(url)\n )\n}\n\n/** The minimal scene-node shape these walkers touch (a subset of `Scene`). */\ninterface ImageNode {\n kind?: { type?: string; src?: string }\n children?: ImageNode[]\n}\n\n/** Collect every non-`data:` image `src` URL in a scene tree. */\nexport function collectImageUrls(node: ImageNode | undefined, out: Set<string>): void {\n if (!node) return\n const src = node.kind?.type === 'image' ? node.kind.src : undefined\n // `data:` is already pixels; `onda-noise:` is generated by the engine's image\n // pass — neither needs fetching to a data: URI.\n if (\n typeof src === 'string' &&\n src.length > 0 &&\n !src.startsWith('data:') &&\n !src.startsWith('onda-noise:')\n ) {\n out.add(src)\n }\n for (const child of node.children ?? []) collectImageUrls(child, out)\n}\n\n/** Rewrite each resolved image `src` URL to its cached `data:` URI, in place. */\nexport function applyResolvedImages(node: ImageNode | undefined): void {\n if (!node) return\n if (node.kind?.type === 'image' && typeof node.kind.src === 'string') {\n const dataUri = cache.get(node.kind.src)\n if (dataUri) node.kind.src = dataUri\n }\n for (const child of node.children ?? []) applyResolvedImages(child)\n}\n","//! In-browser video-frame decoding for the Player.\n//!\n//! The wasm engine can't decode video, so the Player decodes the frame the scene\n//! asks for — an off-screen `<video>` seeked to the node's source `time`, drawn\n//! to a canvas — and hands it to the engine as that frame's pixels. Today the\n//! hand-off reuses the engine's image path (a `data:` URI); a raw-buffer path\n//! (no per-frame base64) layers on top of this same resolver later.\n//!\n//! Decoded frames are cached by `(src, time-bucket)` and shared across players,\n//! so a looping preview decodes each distinct source frame at most once — the\n//! first pass seeks, every pass after is a cache hit. Seeking is serialized per\n//! source (one `<video>` element can only be at one `currentTime`).\n\n/** Quantization of source time into cache buckets (frames per second). Two\n * requested times within the same 1/30s bucket share a decoded frame. */\nconst BUCKET_FPS = 30\n\n/** The minimal scene-node shape these walkers touch (a subset of `Scene`). */\ninterface VideoNode {\n transform?: { translate?: { x?: number; y?: number }; scale?: { x?: number; y?: number } }\n kind?: {\n type?: string\n src?: string\n time?: number\n width?: number\n height?: number\n fit?: 'fill' | 'cover' | 'contain'\n previewFallback?: 'skip' | 'element'\n }\n children?: VideoNode[]\n}\n\n/** A `previewFallback: 'element'` video to display via a DOM `<video>` overlay,\n * positioned in COMPOSITION coordinates (the player scales it to the canvas). */\nexport interface VideoOverlay {\n key: string\n src: string\n x: number\n y: number\n w: number\n h: number\n fit: 'fill' | 'cover' | 'contain'\n}\n\n// One <video> per source URL — heavy, so created lazily and shared module-level.\nconst elements = new Map<string, Promise<HTMLVideoElement>>()\n// Decoded frames: `${src}@${bucket}` -> data: URI. Shared across players.\nconst frameCache = new Map<string, string>()\n// In-flight decodes, so concurrent requests for the same frame share one decode.\nconst inflight = new Map<string, Promise<string | null>>()\n// Last successfully decoded frame per source. When a frame can't be decoded in\n// time (a slow seek mid-playback), we HOLD this instead of blanking the node —\n// blanking for one frame then recovering reads as a flicker/flash.\nconst lastGood = new Map<string, string>()\n// Per-source serialization: a <video> can only seek to one time at a time.\nconst seekChain = new Map<string, Promise<unknown>>()\n// Sources we've already warned about (so the console isn't spammed per frame).\nconst warned = new Set<string>()\n\n/** Warn once, with actionable guidance, when a video can't be decoded for preview\n * (almost always a cross-origin source the browser won't let us read pixels from). */\nfunction warnUnresolved(src: string): void {\n if (warned.has(src) || typeof console === 'undefined') return\n warned.add(src)\n let crossOrigin = false\n try {\n crossOrigin =\n typeof location !== 'undefined' && new URL(src, location.href).origin !== location.origin\n } catch {\n /* relative/odd src — treat as same-origin */\n }\n const reason = crossOrigin\n ? ' • Cross-origin: the browser only reads frames from a same-origin file or one served with CORS (Access-Control-Allow-Origin). Host it with CORS or copy it into your project. YouTube/Vimeo page links are not media files and never work. Or set previewFallback=\"element\" to play it in preview without compositing.'\n : ' • The source failed to load (wrong path / not a video file?).'\n console.warn(\n `[onda] couldn't decode video for PREVIEW: ${src}\\n${reason}\\n • This is a preview-only limit — \\`onda export\\` (ffmpeg) decodes any direct URL regardless of CORS.`,\n )\n}\n\nlet scratch: HTMLCanvasElement | null = null\n\nfunction bucketKey(src: string, time: number): string {\n return `${src}@${Math.round(Math.max(0, time) * BUCKET_FPS)}`\n}\n\n/** Lazily create (and load) one muted `<video>` per source, reused across frames. */\nfunction getVideo(src: string): Promise<HTMLVideoElement> {\n const existing = elements.get(src)\n if (existing) return existing\n const p = new Promise<HTMLVideoElement>((resolve, reject) => {\n const v = document.createElement('video')\n v.muted = true\n v.crossOrigin = 'anonymous'\n v.preload = 'auto'\n v.playsInline = true\n const cleanup = () => {\n v.removeEventListener('loadeddata', onReady)\n v.removeEventListener('error', onError)\n }\n const onReady = () => {\n cleanup()\n resolve(v)\n }\n const onError = () => {\n cleanup()\n reject(new Error(`video failed to load: ${src}`))\n }\n v.addEventListener('loadeddata', onReady)\n v.addEventListener('error', onError)\n v.src = src\n v.load()\n })\n elements.set(src, p)\n return p\n}\n\n/** Seek `v` to `t` seconds and resolve once the frame is ready. */\nfunction seek(v: HTMLVideoElement, t: number): Promise<void> {\n return new Promise((resolve) => {\n // Already on (close enough to) the target frame — no seek needed.\n if (v.readyState >= 2 && Math.abs(v.currentTime - t) < 1 / (BUCKET_FPS * 2)) {\n resolve()\n return\n }\n const onSeeked = () => {\n v.removeEventListener('seeked', onSeeked)\n resolve()\n }\n v.addEventListener('seeked', onSeeked)\n try {\n v.currentTime = t\n } catch {\n v.removeEventListener('seeked', onSeeked)\n resolve()\n }\n })\n}\n\n/** Decode one source frame to a `data:` URI, cached + per-source serialized.\n * Returns `null` if the frame can't be decoded (load/seek/CORS failure). */\nfunction decodeFrame(src: string, time: number): Promise<string | null> {\n const key = bucketKey(src, time)\n const cached = frameCache.get(key)\n if (cached) return Promise.resolve(cached)\n const pending = inflight.get(key)\n if (pending) return pending\n\n // Chain after any in-flight seek on this source so the <video> isn't seeked to\n // two times at once.\n const prior = seekChain.get(src) ?? Promise.resolve()\n const p = prior.then(async () => {\n const again = frameCache.get(key)\n if (again) return again\n try {\n const v = await getVideo(src)\n const dur = Number.isFinite(v.duration) ? v.duration : 0\n const t = dur > 0 ? Math.min(time, Math.max(0, dur - 1 / BUCKET_FPS)) : time\n await seek(v, t)\n const w = v.videoWidth\n const h = v.videoHeight\n if (!w || !h) return null\n if (!scratch) scratch = document.createElement('canvas')\n if (scratch.width !== w) scratch.width = w\n if (scratch.height !== h) scratch.height = h\n const ctx = scratch.getContext('2d')\n if (!ctx) return null\n ctx.drawImage(v, 0, 0, w, h)\n const uri = scratch.toDataURL('image/jpeg', 0.82)\n frameCache.set(key, uri)\n return uri\n } catch {\n // Unreadable: failed to load (bad URL / 404), or a cross-origin source\n // without CORS headers (the canvas is tainted, so toDataURL throws). The\n // node is left unresolved and the renderer skips it.\n return null\n } finally {\n inflight.delete(key)\n }\n })\n inflight.set(key, p)\n seekChain.set(src, p)\n return p\n}\n\n/** Whether the scene contains any video node. */\nexport function hasVideo(node: VideoNode | undefined): boolean {\n if (!node) return false\n if (node.kind?.type === 'video') return true\n return (node.children ?? []).some(hasVideo)\n}\n\n/** Decode + attach the current frame for every video node in `root`, in place:\n * rewrites each node's `src` to a `data:` URI of the requested source frame.\n * Awaits all decodes; an undecodable frame is left as-is (the engine skips an\n * unresolved src). No-op outside a browser. */\nexport async function resolveVideoFrames(root: VideoNode | undefined): Promise<void> {\n if (!root || typeof document === 'undefined') return\n const nodes: VideoNode[] = []\n const collect = (n: VideoNode | undefined) => {\n if (!n) return\n const src = n.kind?.type === 'video' ? n.kind.src : undefined\n // `previewFallback: 'element'` videos are shown via a DOM overlay instead of\n // composited — skip them here (don't decode, don't warn).\n if (\n typeof src === 'string' &&\n src.length > 0 &&\n !src.startsWith('data:') &&\n n.kind?.previewFallback !== 'element'\n ) {\n nodes.push(n)\n }\n for (const child of n.children ?? []) collect(child)\n }\n collect(root)\n // Sequential: video nodes commonly share one <video> element, which can only\n // hold one playhead — concurrent seeks would clobber each other.\n for (const n of nodes) {\n const src = n.kind?.src\n if (typeof src !== 'string') continue\n const time = typeof n.kind?.time === 'number' ? n.kind.time : 0\n const uri = await decodeFrame(src, time)\n if (uri && n.kind) {\n n.kind.src = uri\n lastGood.set(src, uri)\n } else if (!uri && n.kind) {\n // Couldn't decode THIS frame in time — hold the last good frame so the video\n // region doesn't blank-and-pop (a flash). Only warn (once) if we've never\n // managed to decode this source at all.\n const held = lastGood.get(src)\n if (held) n.kind.src = held\n else warnUnresolved(src)\n }\n }\n}\n\n/** Collect `previewFallback: 'element'` video nodes as positioned overlays (in\n * composition coordinates — translate + scale accumulated from the root). The\n * player renders a plain `<video>` at each box: a display-only preview for\n * sources it can't composite (cross-origin without CORS). Box/position only —\n * rotation, clip, and engine effects are not reflected (export still is). */\nexport function collectVideoOverlays(\n root: VideoNode | undefined,\n compWidth: number,\n compHeight: number,\n): VideoOverlay[] {\n const out: VideoOverlay[] = []\n if (!root) return out\n let idx = 0\n const walk = (node: VideoNode, ax: number, ay: number, asx: number, asy: number): void => {\n const t = node.transform?.translate\n const s = node.transform?.scale\n const nx = ax + asx * (t?.x ?? 0)\n const ny = ay + asy * (t?.y ?? 0)\n const nsx = asx * (s?.x ?? 1)\n const nsy = asy * (s?.y ?? 1)\n const k = node.kind\n if (\n k?.type === 'video' &&\n k.previewFallback === 'element' &&\n typeof k.src === 'string' &&\n k.src.length > 0\n ) {\n out.push({\n key: `${k.src}#${idx++}`,\n src: k.src,\n x: nx,\n y: ny,\n w: (typeof k.width === 'number' ? k.width : compWidth) * nsx,\n h: (typeof k.height === 'number' ? k.height : compHeight) * nsy,\n fit: k.fit ?? 'cover',\n })\n }\n for (const child of node.children ?? []) walk(child, nx, ny, nsx, nsy)\n }\n walk(root, 0, 0, 1, 1)\n return out\n}\n","//! `<Player>` — an interactive, accessible preview of an ONDA composition.\n//!\n//! Renders each visible frame from `@onda-engine/react`'s `renderFrame` (so what you\n//! scrub is the real per-frame scene graph) and paints it to a canvas. By\n//! default it paints with the **real ONDA engine** when one is supplied (the\n//! `@onda-engine/wasm` `OndaEngine`, pixel-identical to `onda export`), and otherwise\n//! falls back to the dependency-free Canvas2D preview.\n//!\n//! Controls are fully keyboard-accessible (Space = play/pause, ←/→ = step,\n//! Shift+←/→ = jump, Home/End = ends), ARIA-labelled, and styled with the ONDA\n//! brand tokens (see `assets/brand/BRAND.md`). All non-essential motion respects\n//! `prefers-reduced-motion`.\n\nimport { registeredFonts, renderFrame } from '@onda-engine/react'\nimport {\n type CSSProperties,\n type KeyboardEvent,\n type ReactElement,\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { PreviewAudio } from './audio-engine.js'\nimport { type AudioClip, collectAudioClips } from './audio.js'\nimport { type FrameDrawer, drawScene } from './canvas-renderer.js'\nimport { type RenderEngine, engineDrawer } from './engine-drawer.js'\nimport { applyResolvedImages, collectImageUrls, imageResolved, resolveImageUrl } from './images.js'\nimport { collectVideoOverlays, resolveVideoFrames } from './video.js'\n\n/** An async, GPU renderer — structurally `@onda-engine/wasm-vello`'s `VelloEngine`.\n * This is the pixel-exact, full-feature path (paths/gradients/clips/AA), so the\n * Player prefers it. Accepted structurally so `@onda-engine/player` needn't depend on\n * `@onda-engine/wasm-vello`. */\nexport interface GpuEngine {\n render(sceneJson: string): Promise<{ width: number; height: number; pixels: Uint8Array }>\n /** Optional: load a custom font (`.ttf`/`.otf` bytes) so the live preview draws\n * with the same fonts the export will. `@onda-engine/wasm-vello`'s `VelloEngine` exposes\n * `load_font`; `@onda-engine/wasm`'s `OndaEngine` exposes `loadFont` — the Player drains\n * the `@onda-engine/react` font registry into whichever exists. */\n loadFont?(data: Uint8Array): unknown\n load_font?(data: Uint8Array): unknown\n}\n\n// GPU engines currently mid-render. Keyed on the engine instance so multiple\n// <Player>s sharing one engine serialize their `&mut render()` calls (a wasm\n// engine panics on re-entrant use). Module-level on purpose — the guard must\n// outlive any single component instance.\nconst enginesRendering = new WeakSet<object>()\n\n// How many registered fonts have been loaded into each engine (keyed on the\n// engine instance). The `@onda-engine/react` font registry is append-only, so we load\n// only the newly-registered tail into an engine, once — never re-loading a font\n// or per frame. Module-level so it survives remounts that reuse an engine.\nconst engineFontCount = new WeakMap<object, number>()\n\n/** Drain any not-yet-loaded fonts from the `@onda-engine/react` registry into `engine`\n * (whichever of `loadFont`/`load_font` it exposes), so a composition's custom\n * fonts render in the live preview, matching export. Cheap to call before every\n * paint: a no-op once the engine is caught up. Safe inside the per-engine render\n * guard (synchronous, before `render()`), so it never races a `&mut render`. */\nfunction ensureFontsLoaded(engine: object): void {\n const e = engine as {\n loadFont?: (d: Uint8Array) => unknown\n load_font?: (d: Uint8Array) => unknown\n }\n const load = e.loadFont ?? e.load_font\n if (typeof load !== 'function') return\n const fonts = registeredFonts()\n const loaded = engineFontCount.get(engine) ?? 0\n for (let i = loaded; i < fonts.length; i++) {\n try {\n load.call(engine, fonts[i] as Uint8Array)\n } catch {\n // a bad font shouldn't break the preview; skip it\n }\n }\n engineFontCount.set(engine, fonts.length)\n}\n\nexport interface PlayerProps {\n /** A `<Composition>` element (from `@onda-engine/react`). */\n composition: ReactElement\n /** Start playing on mount. Default `true`. */\n autoPlay?: boolean\n /** Loop back to frame 0 at the end. Default `true`. Also toggleable in the UI. */\n loop?: boolean\n /**\n * The renderer. The Player auto-selects the best available, in order:\n * 1. an explicit {@link PlayerProps.draw},\n * 2. the GPU engine ({@link PlayerProps.gpuEngine}) — Vello/WebGPU,\n * pixel-identical to `onda export`,\n * 3. the CPU engine ({@link PlayerProps.engine}),\n * 4. the Canvas2D {@link drawScene} fallback.\n * It also falls back automatically if a renderer errors at runtime.\n */\n draw?: FrameDrawer\n /** The GPU (Vello/WebGPU) renderer — preferred when present (see {@link GpuEngine}). */\n gpuEngine?: GpuEngine\n /** The CPU renderer (`@onda-engine/wasm`'s `OndaEngine`) — fallback when there's no GPU. */\n engine?: RenderEngine\n /** Show a small backend indicator (WebGPU/CPU/Canvas2D). Default `true`. */\n showStatus?: boolean\n /** Control visibility. `'auto'` (default) reveals the controls on hover / focus\n * / when paused; `'always'` keeps them visible; `'none'` hides them entirely\n * (no overlay, no fullscreen button, no click-to-toggle) — a chrome-free\n * thumbnail (e.g. a gallery tile that plays on hover + clicks through to a link). */\n controls?: 'auto' | 'always' | 'none'\n /** Accessible label for the player region. Default `\"ONDA composition player\"`. */\n label?: string\n /** Optional className on the root for app-level layout/overrides. */\n className?: string\n /** Frame to start on. Default `0`. Clamped to the composition length. */\n initialFrame?: number\n /** Initial playback speed (preview only — does NOT change the exported video,\n * which always renders 1× at the composition fps). `1` = real-time. Forward\n * presets in the UI are 0.25×–2×; programmatic values clamp to 0.1×–4×.\n * Default `1`. */\n playbackRate?: number\n /** Called whenever the current frame changes (scrub or playback). */\n onFrameUpdate?: (frame: number) => void\n /** Called when playback starts. */\n onPlay?: () => void\n /** Called when playback pauses (or stops at the end of a non-looping clip). */\n onPause?: () => void\n}\n\n/**\n * Imperative handle for `<Player>` (via `ref`) — drive playback from a host app\n * such as an editor timeline.\n *\n * @example\n * ```tsx\n * const ref = useRef<PlayerHandle>(null)\n * <Player ref={ref} composition={…} />\n * ref.current?.seekTo(48)\n * ```\n */\n/** Player events (Remotion-`@remotion/player`-compatible) for a host editor to\n * sync against — e.g. a canvas overlay tracking the current frame. */\nexport type PlayerEventType = 'frameupdate' | 'play' | 'pause' | 'seeked' | 'ended' | 'ratechange'\n\n/** Event passed to a {@link PlayerEventListener}: `detail.frame` is the current\n * frame (mirrors Remotion's `CallbackListener` event shape). For `ratechange`,\n * `detail.playbackRate` carries the new preview speed. */\nexport interface PlayerEvent {\n type: PlayerEventType\n detail: { frame: number; playbackRate?: number }\n}\n\nexport type PlayerEventListener = (event: PlayerEvent) => void\n\nexport interface PlayerHandle {\n /** Seek to a frame (clamped). Does not change the play/pause state. */\n seekTo(frame: number): void\n /** Start playing (restarts from 0 if at the end of a non-looping clip). */\n play(): void\n /** Pause playback. */\n pause(): void\n /** Toggle play/pause. */\n toggle(): void\n /** The current frame. */\n getCurrentFrame(): number\n /** Total frames in the composition. */\n getTotalFrames(): number\n /** Whether playback is currently running. */\n isPlaying(): boolean\n /** The current preview playback speed (1 = real-time). */\n getPlaybackRate(): number\n /** Set the preview playback speed (clamped to 0.1×–4×). Preview only — does\n * not affect export. Emits a `ratechange` event. */\n setPlaybackRate(rate: number): void\n /** Subscribe to a player event\n * (`frameupdate`/`play`/`pause`/`seeked`/`ended`/`ratechange`).\n * Mirrors `@remotion/player`'s `addEventListener` so an editor built against\n * Remotion's Player ports without rewiring its frame-sync/overlay. */\n addEventListener(type: PlayerEventType, listener: PlayerEventListener): void\n /** Unsubscribe a listener previously passed to {@link addEventListener}. */\n removeEventListener(type: PlayerEventType, listener: PlayerEventListener): void\n}\n\n/**\n * Render an ONDA composition to a canvas with play/pause, a frame scrubber, a\n * loop toggle, and a frame/time readout.\n *\n * @example\n * ```tsx\n * import { Player } from '@onda-engine/player'\n * <Player composition={<Composition …>…</Composition>} engine={ondaEngine} />\n * ```\n */\nexport const Player = forwardRef<PlayerHandle, PlayerProps>(function Player(\n {\n composition,\n autoPlay = true,\n loop: initialLoop = true,\n draw,\n gpuEngine,\n engine,\n showStatus = true,\n controls = 'auto',\n label = 'ONDA composition player',\n className,\n initialFrame = 0,\n playbackRate = 1,\n onFrameUpdate,\n onPlay,\n onPause,\n }: PlayerProps,\n ref,\n): ReactElement {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const stageRef = useRef<HTMLDivElement>(null)\n const uid = useId()\n useInjectStyles()\n\n // If a renderer throws at runtime, drop it and fall back for the rest of the\n // session rather than blanking.\n const [gpuFailed, setGpuFailed] = useState(false)\n const [engineFailed, setEngineFailed] = useState(false)\n\n // Auto-select the renderer: explicit draw > GPU (Vello) > CPU engine > Canvas2D.\n const mode = useMemo<\n { kind: 'gpu'; engine: GpuEngine } | { kind: 'sync'; draw: FrameDrawer; label: string }\n >(() => {\n if (draw) return { kind: 'sync', draw, label: 'Custom' }\n if (gpuEngine && !gpuFailed) return { kind: 'gpu', engine: gpuEngine }\n if (engine && !engineFailed) {\n const real = engineDrawer(engine)\n const safe: FrameDrawer = (ctx, scene) => {\n try {\n real(ctx, scene)\n } catch {\n setEngineFailed(true)\n drawScene(ctx, scene)\n }\n }\n return { kind: 'sync', draw: safe, label: 'CPU' }\n }\n return { kind: 'sync', draw: drawScene, label: 'Canvas2D' }\n }, [draw, gpuEngine, gpuFailed, engine, engineFailed])\n\n const backend = mode.kind === 'gpu' ? 'WebGPU' : mode.label\n const isExact = mode.kind === 'gpu' || backend === 'CPU' || backend === 'Custom'\n\n // Resolution + timing come from rendering frame 0 once.\n const config = useMemo(() => renderFrame(composition, 0).composition, [composition])\n const totalFrames = Math.max(1, config.duration_in_frames)\n const lastFrame = totalFrames - 1\n\n // `previewFallback: 'element'` video nodes shown as DOM <video> overlays\n // (display-only preview for sources we can't composite, e.g. cross-origin\n // without CORS). Boxes are frame-independent, so derive once per composition.\n const videoOverlays = useMemo(\n () =>\n collectVideoOverlays(renderFrame(composition, 0).root as never, config.width, config.height),\n [composition, config.width, config.height],\n )\n const videoOverlayRef = useRef<HTMLDivElement>(null)\n\n // Non-visual <Audio> clips to play for preview (frame-independent, so derive\n // once per composition). Played via the Web Audio transport below (decoded\n // buffers on the audio thread — immune to the main-thread render jank that made\n // HTML <audio> glitch).\n const audioClips: AudioClip[] = useMemo(\n () => collectAudioClips(renderFrame(composition, 0).root as never),\n [composition],\n )\n // One Web Audio transport per player. Created lazily (browser-only) so SSR and\n // pre-gesture mounts never spin up an AudioContext.\n const audioRef = useRef<PreviewAudio | null>(null)\n if (audioRef.current === null && typeof window !== 'undefined') {\n audioRef.current = new PreviewAudio()\n }\n useEffect(\n () => () => {\n audioRef.current?.dispose()\n audioRef.current = null\n },\n [],\n )\n const [volume, setVolume] = useState(1)\n const [muted, setMuted] = useState(false)\n\n const [frame, setFrame] = useState(() =>\n Math.min(lastFrame, Math.max(0, Math.floor(initialFrame))),\n )\n\n // Resolve image src URLs to data: URIs (the wasm engine can't fetch). Sample a\n // few frames so srcs that only appear later are covered; bumping `imagesReady`\n // re-renders once they're cached so the now-decodable images appear.\n const [imagesReady, setImagesReady] = useState(0)\n useEffect(() => {\n const urls = new Set<string>()\n for (const f of new Set([0, Math.floor(lastFrame / 2), lastFrame])) {\n collectImageUrls(renderFrame(composition, f).root as never, urls)\n }\n if (urls.size === 0) return\n let cancelled = false\n Promise.all([...urls].map(resolveImageUrl)).then(() => {\n if (!cancelled) setImagesReady((v) => v + 1)\n })\n return () => {\n cancelled = true\n }\n }, [composition, lastFrame])\n\n const [playing, setPlaying] = useState(autoPlay)\n const [loop, setLoop] = useState(initialLoop)\n const [isFullscreen, setIsFullscreen] = useState(false)\n // Bumped by every explicit seek (scrubber/keyboard/host), so the audio\n // transport re-anchors only on a real seek — never on normal frame advance.\n const [seekNonce, setSeekNonce] = useState(0)\n // Preview playback speed (1 = real-time). Preview-only: the clock advances\n // `rate`× as fast; export is unaffected. `speedOpen` toggles the preset menu.\n const [rate, setRate] = useState(() => clampRate(playbackRate))\n const [speedOpen, setSpeedOpen] = useState(false)\n const speedRef = useRef<HTMLDivElement>(null)\n\n // The frame/composition the canvas should show. Updated synchronously each\n // render so the async GPU loop can always pull the latest target. `images` is\n // the resolved-image version so a fetch that lands mid-paint forces a repaint.\n const targetRef = useRef({ composition, frame, images: imagesReady })\n targetRef.current = { composition, frame, images: imagesReady }\n\n // Vsync-aligned canvas blit: stash the latest rendered pixels and paint them\n // inside ONE requestAnimationFrame, instead of the instant each async\n // `gpu.render` resolves. Aligning canvas writes to the display refresh stops a\n // playing video from tearing against the compositor while the mouse moves\n // (unsynced `putImageData` mid-composite reads as a subtle flash). Only the most\n // recent frame is painted — intermediate frames rendered before the rAF fires\n // are dropped, which is correct for smooth playback.\n const pendingPaintRef = useRef<{ width: number; height: number; pixels: Uint8Array } | null>(null)\n const blitRafRef = useRef<number | null>(null)\n const scheduleBlit = useCallback((out: { width: number; height: number; pixels: Uint8Array }) => {\n pendingPaintRef.current = out\n if (blitRafRef.current != null) return\n blitRafRef.current = requestAnimationFrame(() => {\n blitRafRef.current = null\n const p = pendingPaintRef.current\n const canvas = canvasRef.current\n const ctx = canvas?.getContext('2d')\n if (!p || !canvas || !ctx) return\n if (canvas.width !== p.width) canvas.width = p.width\n if (canvas.height !== p.height) canvas.height = p.height\n ctx.putImageData(new ImageData(new Uint8ClampedArray(p.pixels), p.width, p.height), 0, 0)\n })\n }, [])\n useEffect(\n () => () => {\n if (blitRafRef.current != null) cancelAnimationFrame(blitRafRef.current)\n },\n [],\n )\n\n // Latest values for the imperative handle + event callbacks, read from refs so\n // the handle/effects don't re-subscribe on every frame.\n const liveRef = useRef({ frame, playing, loop, lastFrame, totalFrames, rate })\n liveRef.current = { frame, playing, loop, lastFrame, totalFrames, rate }\n const onFrameUpdateRef = useRef(onFrameUpdate)\n onFrameUpdateRef.current = onFrameUpdate\n const onPlayRef = useRef(onPlay)\n onPlayRef.current = onPlay\n const onPauseRef = useRef(onPause)\n onPauseRef.current = onPause\n\n // Remotion-style event listeners (addEventListener on the handle). Held in a\n // ref so subscribing doesn't re-render; emitted from the same effects that\n // fire the callback props.\n const listenersRef = useRef<Map<PlayerEventType, Set<PlayerEventListener>>>(new Map())\n const emit = useCallback((type: PlayerEventType, atFrame: number, playbackRate?: number) => {\n const set = listenersRef.current.get(type)\n if (!set) return\n const detail =\n playbackRate === undefined ? { frame: atFrame } : { frame: atFrame, playbackRate }\n for (const listener of set) listener({ type, detail })\n }, [])\n\n // Change the preview speed (clamped), notifying listeners. Read by the rAF\n // clock + the audio sync via `liveRef.current.rate`, so changing speed never\n // tears down the playback loop.\n const changeRate = useCallback(\n (next: number) => {\n const clamped = clampRate(next)\n setRate(clamped)\n emit('ratechange', liveRef.current.frame, clamped)\n },\n [emit],\n )\n\n // Close the speed menu on an outside click or Escape.\n useEffect(() => {\n if (!speedOpen) return\n const onDown = (e: Event) => {\n if (!speedRef.current?.contains(e.target as Node)) setSpeedOpen(false)\n }\n const onKey = (e: globalThis.KeyboardEvent) => {\n if (e.key === 'Escape') setSpeedOpen(false)\n }\n document.addEventListener('pointerdown', onDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('pointerdown', onDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [speedOpen])\n\n // Single-flight async GPU paint: render the latest target, dropping any\n // intermediate frames (the readback can't always keep up at 60fps). The busy\n // flag is keyed on the ENGINE (module-level {@link enginesRendering}), not this\n // component — so multiple <Player>s sharing one engine (e.g. a gallery that\n // remounts on switch) never call its `&mut render()` re-entrantly (wasm:\n // \"recursive use of an object … unsafe aliasing in rust\").\n const paintGpu = useCallback(\n (gpu: GpuEngine) => {\n if (enginesRendering.has(gpu)) return\n enginesRendering.add(gpu)\n ;(async () => {\n try {\n let done: { c: ReactElement; f: number; v: number } | null = null\n while (true) {\n const { composition: c, frame: f, images: v } = targetRef.current\n // Caught up only if the frame/composition AND the resolved-image\n // version are unchanged — so an image that finishes fetching mid-paint\n // repaints even though the composition + frame are the same.\n if (done && done.c === c && done.f === f && done.v === v) break\n done = { c, f, v }\n const scene = renderFrame(c, f)\n // On-demand image resolution: the 3-frame pre-sample can miss srcs that\n // only appear BETWEEN samples (e.g. a template's time-staggered tiles),\n // so fetch any not-yet-resolved image in THIS frame's tree; the bump\n // repaints once they land (terminates — resolved srcs are skipped).\n const urls = new Set<string>()\n collectImageUrls(scene.root as never, urls)\n const pending = [...urls].filter((u) => !imageResolved(u))\n if (pending.length > 0) {\n void Promise.all(pending.map(resolveImageUrl)).then(() =>\n setImagesReady((n) => n + 1),\n )\n }\n applyResolvedImages(scene.root as never)\n // Decode the current frame of any <Video> node (browser-side) and\n // attach it before rendering — a video's pixels change every frame.\n await resolveVideoFrames(scene.root as never)\n // Load any custom fonts the composition registered (via `loadFont`) into\n // this engine before drawing, so preview matches export. No-op once warm.\n ensureFontsLoaded(gpu)\n const out = await gpu.render(JSON.stringify(scene))\n // Paint on the next animation frame (vsync-aligned), not inline — see\n // `scheduleBlit`. Keeps the video repaint from tearing under mouse-move.\n scheduleBlit(out)\n }\n } catch {\n setGpuFailed(true) // drop to the next renderer\n } finally {\n enginesRendering.delete(gpu)\n }\n })()\n },\n [scheduleBlit],\n )\n\n // Re-draw whenever the frame, composition, or renderer changes.\n // biome-ignore lint/correctness/useExhaustiveDependencies: paint fns are stable refs; deps list the real triggers\n useEffect(() => {\n if (mode.kind === 'gpu') {\n paintGpu(mode.engine)\n } else {\n const ctx = canvasRef.current?.getContext('2d')\n if (ctx) {\n const scene = renderFrame(composition, frame)\n // On-demand image resolution (see the GPU path) — fetch any image in this\n // frame the pre-sample missed, repainting via `imagesReady` when it lands.\n const urls = new Set<string>()\n collectImageUrls(scene.root as never, urls)\n const pending = [...urls].filter((u) => !imageResolved(u))\n if (pending.length > 0) {\n void Promise.all(pending.map(resolveImageUrl)).then(() => setImagesReady((n) => n + 1))\n }\n applyResolvedImages(scene.root as never)\n mode.draw(ctx, scene)\n }\n }\n // `imagesReady` is a dep so the frame repaints once images resolve.\n }, [composition, frame, mode, paintGpu, imagesReady])\n\n // Keep the `previewFallback: 'element'` overlay <video>s in lockstep with the\n // player's play/pause. (They aren't frame-locked to the timeline — a display-\n // only preview — but at least they pause when the composition pauses.)\n // biome-ignore lint/correctness/useExhaustiveDependencies: re-queries the DOM each run; playing is the only trigger\n useEffect(() => {\n const vids = videoOverlayRef.current?.querySelectorAll('video')\n if (!vids) return\n for (const v of vids) {\n if (playing) void v.play().catch(() => {})\n else v.pause()\n }\n }, [playing, videoOverlays])\n\n // ── Web Audio transport ──────────────────────────────────────────────────\n // The clips/period feed the transport; play/pause/seek/rate/volume drive it.\n // Note the conspicuous absence of a per-`frame` effect: the audio runs on the\n // AudioContext clock anchored at play-time, NOT chasing the visual frame each\n // tick — that's what keeps it gapless and jank-proof.\n const compSeconds = useCallback((f: number) => f / Math.max(1, config.fps), [config.fps])\n\n // Clip set + timeline period (one loop cycle, seconds).\n useEffect(() => {\n audioRef.current?.setClips(audioClips, totalFrames / Math.max(1, config.fps))\n }, [audioClips, totalFrames, config.fps])\n\n // Master volume / mute (click-free ramp inside the engine).\n useEffect(() => {\n audioRef.current?.setGain(volume, muted)\n }, [volume, muted])\n\n useEffect(() => {\n audioRef.current?.setLoop(loop)\n }, [loop])\n\n // Preview speed: the engine re-anchors and plays silent at ≠ 1× (raw rate would\n // pitch-shift), audible again at 1×.\n useEffect(() => {\n audioRef.current?.setRate(rate)\n }, [rate])\n\n // Play / pause — anchor at the current playhead on play, stop on pause. The\n // playhead is read live (not from the `frame` closure) so it's exact at the\n // moment play starts.\n useEffect(() => {\n const audio = audioRef.current\n if (!audio) return\n if (playing) audio.play(compSeconds(liveRef.current.frame))\n else audio.pause()\n }, [playing, compSeconds])\n\n // Re-anchor on an explicit seek (bumped by seekTo/goToFrame) — but only while\n // playing; a paused seek just records the position for the next play. Normal\n // playback advances `frame` without bumping this, so the audio is never yanked.\n // biome-ignore lint/correctness/useExhaustiveDependencies: seekNonce is the intentional trigger; refs carry live state\n useEffect(() => {\n if (liveRef.current.playing) audioRef.current?.seek(compSeconds(liveRef.current.frame))\n }, [seekNonce, compSeconds])\n\n // Playback paced to the composition's fps via requestAnimationFrame, scaled by\n // the preview `rate` (read live from the ref — `rate > 1` skips frames, `< 1`\n // holds them; the renderer just draws whatever frame the clock lands on).\n useEffect(() => {\n if (!playing) return\n const frameDuration = 1000 / config.fps\n let last: number | null = null\n let raf = 0\n const tick = (now: number) => {\n if (last === null) last = now\n const r = liveRef.current.rate\n const steps = Math.floor(((now - last) * r) / frameDuration)\n if (steps > 0) {\n // Advance `last` by exactly the time consumed (NOT to `now`), so the\n // sub-frame remainder carries over instead of being discarded. Discarding\n // it biased the clock slow under jank, letting the audio (real-time on the\n // AudioContext clock) drift ahead of the visual.\n last += (steps * frameDuration) / r\n setFrame((current) => {\n const next = current + steps\n if (next <= lastFrame) return next\n return loop ? next % totalFrames : lastFrame\n })\n }\n raf = requestAnimationFrame(tick)\n }\n raf = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(raf)\n }, [playing, config.fps, totalFrames, lastFrame, loop])\n\n // Stop at the end when not looping (and emit `ended`).\n useEffect(() => {\n if (!loop && frame >= lastFrame) {\n setPlaying(false)\n emit('ended', frame)\n }\n }, [frame, lastFrame, loop, emit])\n\n // Emit frame/play/pause events for host apps (e.g. an editor syncing an\n // overlay to the composition), both via the callback props and the\n // addEventListener API. Refs keep a changing callback from re-subscribing.\n useEffect(() => {\n onFrameUpdateRef.current?.(frame)\n emit('frameupdate', frame)\n }, [frame, emit])\n useEffect(() => {\n if (playing) onPlayRef.current?.()\n else onPauseRef.current?.()\n emit(playing ? 'play' : 'pause', liveRef.current.frame)\n }, [playing, emit])\n\n const togglePlay = useCallback(() => {\n setPlaying((p) => {\n // Restart from 0 if pressing play at the end of a non-looping clip. Read the LIVE\n // values (not the `frame`/`loop`/`lastFrame` deps) so this callback stays STABLE —\n // otherwise it re-creates on every frame, churning the imperative handle (and any\n // host effect keyed on it) every tick during playback.\n const { frame: f, loop: lp, lastFrame: lf } = liveRef.current\n if (!p && !lp && f >= lf) setFrame(0)\n return !p\n })\n }, [])\n\n const seekTo = useCallback(\n (next: number) => {\n setPlaying(false)\n setFrame(Math.min(lastFrame, Math.max(0, next)))\n setSeekNonce((n) => n + 1)\n },\n [lastFrame],\n )\n\n // Programmatic seek (imperative handle): clamp + set, WITHOUT pausing — a host\n // editor may scrub while playing. (The UI scrubber/keyboard use the pausing\n // `seekTo` above.)\n const goToFrame = useCallback(\n (next: number) => {\n const clamped = Math.min(lastFrame, Math.max(0, Math.floor(next)))\n setFrame(clamped)\n setSeekNonce((n) => n + 1)\n emit('seeked', clamped)\n },\n [lastFrame, emit],\n )\n\n // Imperative API for host apps driving playback (e.g. an editor timeline).\n useImperativeHandle(\n ref,\n () => ({\n seekTo: goToFrame,\n play: () => {\n const { frame: f, loop: lp, lastFrame: lf } = liveRef.current\n if (!lp && f >= lf) setFrame(0) // restart a finished non-looping clip\n setPlaying(true)\n },\n pause: () => setPlaying(false),\n toggle: togglePlay,\n getCurrentFrame: () => liveRef.current.frame,\n getTotalFrames: () => liveRef.current.totalFrames,\n isPlaying: () => liveRef.current.playing,\n getPlaybackRate: () => liveRef.current.rate,\n setPlaybackRate: changeRate,\n addEventListener: (type, listener) => {\n const map = listenersRef.current\n if (!map.has(type)) map.set(type, new Set())\n map.get(type)?.add(listener)\n },\n removeEventListener: (type, listener) => {\n listenersRef.current.get(type)?.delete(listener)\n },\n }),\n [goToFrame, togglePlay, changeRate],\n )\n\n // Fullscreen the stage (canvas + controls). Uses the standard API with a\n // WebKit fallback so it works in Safari too.\n const toggleFullscreen = useCallback(() => {\n const el = stageRef.current as\n | (HTMLDivElement & { webkitRequestFullscreen?: () => void })\n | null\n if (!el) return\n const doc = document as Document & {\n webkitFullscreenElement?: Element\n webkitExitFullscreen?: () => void\n }\n if (document.fullscreenElement ?? doc.webkitFullscreenElement) {\n ;(document.exitFullscreen ?? doc.webkitExitFullscreen)?.call(document)\n } else {\n ;(el.requestFullscreen ?? el.webkitRequestFullscreen)?.call(el)\n }\n }, [])\n\n // Track fullscreen state so the icon/label reflect it.\n useEffect(() => {\n const onChange = () => {\n const doc = document as Document & { webkitFullscreenElement?: Element }\n setIsFullscreen(Boolean(document.fullscreenElement ?? doc.webkitFullscreenElement))\n }\n document.addEventListener('fullscreenchange', onChange)\n document.addEventListener('webkitfullscreenchange', onChange)\n return () => {\n document.removeEventListener('fullscreenchange', onChange)\n document.removeEventListener('webkitfullscreenchange', onChange)\n }\n }, [])\n\n // Keyboard: Space = play/pause, arrows = step (Shift = jump 10), Home/End.\n // The handler lives on the focusable region so it works from anywhere in the\n // player. When a native <button> has focus, the browser already activates it\n // on Space/Enter — so we skip Space there to avoid a double toggle.\n const onKeyDown = useCallback(\n (event: KeyboardEvent) => {\n const onButton = (event.target as HTMLElement)?.tagName === 'BUTTON'\n const jump = event.shiftKey ? 10 : 1\n switch (event.key) {\n case ' ':\n case 'k':\n if (onButton && event.key === ' ') return // let the button handle it\n event.preventDefault()\n togglePlay()\n break\n case 'ArrowRight':\n event.preventDefault()\n seekTo(frame + jump)\n break\n case 'ArrowLeft':\n event.preventDefault()\n seekTo(frame - jump)\n break\n case 'Home':\n event.preventDefault()\n seekTo(0)\n break\n case 'End':\n event.preventDefault()\n seekTo(lastFrame)\n break\n case 'l':\n event.preventDefault()\n setLoop((v) => !v)\n break\n case 'f':\n event.preventDefault()\n toggleFullscreen()\n break\n }\n },\n [frame, lastFrame, togglePlay, seekTo, toggleFullscreen],\n )\n\n const seconds = frame / config.fps\n const totalSeconds = lastFrame / config.fps\n\n // Small corner badge: the active backend + a fuller description (tooltip).\n const statusLabel = backend\n const statusText =\n mode.kind === 'gpu'\n ? 'Rendered by Vello on WebGPU — pixel-identical to `onda export`, no Chromium.'\n : backend === 'CPU'\n ? 'Rendered by the ONDA CPU engine in WebAssembly — no DOM, no Chromium.'\n : backend === 'Canvas2D'\n ? 'Canvas2D fallback — WebGPU and the CPU engine are unavailable here.'\n : 'Custom renderer.'\n\n return (\n <div\n className={[\n 'onda-player',\n playing ? '' : 'is-paused',\n controls === 'always' ? 'is-controls' : '',\n controls === 'none' ? 'is-controls-none' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={styles.root}\n // biome-ignore lint/a11y/useSemanticElements: a media-player region; no semantic element exists for it\n role=\"group\"\n aria-label={label}\n aria-roledescription=\"media player\"\n // biome-ignore lint/a11y/noNoninteractiveTabindex: the player root IS the keyboard surface (Space/arrows/Home/End)\n tabIndex={0}\n onKeyDown={onKeyDown}\n >\n {/* The stage is the positioning context: canvas fills it, controls overlay\n on top (auto-hidden unless hovering / paused / keyboard-focused). */}\n <div\n ref={stageRef}\n className=\"onda-player__stage\"\n style={{ ...styles.stage, aspectRatio: `${config.width} / ${config.height}` }}\n >\n {/* biome-ignore lint/a11y/useKeyWithClickEvents: keyboard play/pause lives on the player root (Space) */}\n <canvas\n ref={canvasRef}\n width={config.width}\n height={config.height}\n className=\"onda-player__canvas\"\n style={styles.canvas}\n onClick={controls === 'none' ? undefined : togglePlay}\n aria-label={`composition preview, ${config.width}×${config.height} at ${config.fps}fps — click to ${playing ? 'pause' : 'play'}`}\n />\n\n {/* Display-only <video> overlay for `previewFallback: 'element'` sources\n (cross-origin without CORS). Above the canvas, click-through. */}\n {videoOverlays.length > 0 && (\n <div ref={videoOverlayRef} style={styles.videoOverlay} aria-hidden=\"true\">\n {videoOverlays.map((o) => (\n <video\n key={o.key}\n src={o.src}\n muted\n autoPlay\n loop\n playsInline\n style={{\n position: 'absolute',\n left: `${(o.x / config.width) * 100}%`,\n top: `${(o.y / config.height) * 100}%`,\n width: `${(o.w / config.width) * 100}%`,\n height: `${(o.h / config.height) * 100}%`,\n objectFit: o.fit,\n }}\n />\n ))}\n </div>\n )}\n\n {showStatus && (\n <div className=\"onda-player__badge\" title={statusText}>\n <span\n className={`onda-player__dot onda-player__dot--${isExact ? 'ok' : 'warn'}`}\n aria-hidden=\"true\"\n />\n <span>{statusLabel}</span>\n </div>\n )}\n\n <button\n type=\"button\"\n className=\"onda-player__fs\"\n onClick={toggleFullscreen}\n aria-label={isFullscreen ? 'Exit full screen' : 'Full screen'}\n aria-pressed={isFullscreen}\n title={isFullscreen ? 'Exit full screen (f)' : 'Full screen (f)'}\n >\n {isFullscreen ? <ExitFullscreenIcon /> : <FullscreenIcon />}\n </button>\n\n <div className=\"onda-player__overlay\">\n <input\n id={`${uid}-scrubber`}\n type=\"range\"\n className=\"onda-player__scrubber\"\n style={\n { '--progress': `${lastFrame ? (frame / lastFrame) * 100 : 0}%` } as CSSProperties\n }\n min={0}\n max={lastFrame}\n step={1}\n value={frame}\n onChange={(event) => seekTo(Number(event.target.value))}\n aria-label=\"Seek frame\"\n aria-valuemin={0}\n aria-valuemax={lastFrame}\n aria-valuenow={frame}\n aria-valuetext={`Frame ${frame} of ${lastFrame}, ${seconds.toFixed(2)} seconds`}\n />\n\n <div className=\"onda-player__row\">\n <button\n type=\"button\"\n className=\"onda-player__play\"\n onClick={togglePlay}\n aria-label={playing ? 'Pause' : 'Play'}\n aria-pressed={playing}\n >\n {playing ? <PauseIcon /> : <PlayIcon />}\n </button>\n\n <output\n className=\"onda-player__readout\"\n htmlFor={`${uid}-scrubber`}\n style={styles.readout}\n aria-live=\"off\"\n >\n <span className=\"onda-player__time\">{fmtTime(seconds)}</span>\n <span className=\"onda-player__sep\" aria-hidden=\"true\">\n /\n </span>\n <span className=\"onda-player__total\">{fmtTime(totalSeconds)}</span>\n </output>\n\n <span className=\"onda-player__spacer\" />\n\n {audioClips.length > 0 && (\n <div className=\"onda-player__volume\">\n <button\n type=\"button\"\n className=\"onda-player__icon\"\n onClick={() => setMuted((v) => !v)}\n aria-label={muted ? 'Unmute' : 'Mute'}\n aria-pressed={muted}\n title={muted ? 'Unmute' : 'Mute'}\n >\n {muted || volume === 0 ? <VolumeMuteIcon /> : <VolumeIcon />}\n </button>\n <input\n type=\"range\"\n className=\"onda-player__volume-slider\"\n min={0}\n max={1}\n step={0.01}\n value={muted ? 0 : volume}\n onChange={(event) => {\n const v = Number(event.target.value)\n setVolume(v)\n setMuted(v === 0)\n }}\n aria-label=\"Volume\"\n />\n </div>\n )}\n\n <div className=\"onda-player__speed\" ref={speedRef}>\n <button\n type=\"button\"\n className={`onda-player__icon onda-player__speed-btn${rate !== 1 ? ' is-active' : ''}`}\n onClick={() => setSpeedOpen((v) => !v)}\n aria-label={`Playback speed: ${formatRate(rate)}`}\n aria-haspopup=\"menu\"\n aria-expanded={speedOpen}\n title=\"Playback speed (preview only)\"\n >\n {formatRate(rate)}\n </button>\n {speedOpen && (\n <div className=\"onda-player__speed-menu\" role=\"menu\" aria-label=\"Playback speed\">\n {SPEED_PRESETS.map((r) => (\n <button\n key={r}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={r === rate}\n className={`onda-player__speed-item${r === rate ? ' is-active' : ''}`}\n onClick={() => {\n changeRate(r)\n setSpeedOpen(false)\n }}\n >\n {formatRate(r)}\n </button>\n ))}\n </div>\n )}\n </div>\n\n <button\n type=\"button\"\n className={`onda-player__icon${loop ? ' is-active' : ''}`}\n onClick={() => setLoop((v) => !v)}\n aria-label=\"Loop playback\"\n aria-pressed={loop}\n title=\"Loop\"\n >\n <LoopIcon />\n </button>\n </div>\n </div>\n {/* Audio is played via the Web Audio transport (see the effects above), not\n DOM <audio> elements — decoded buffers on the audio thread stay glitch-\n free under the main-thread render load. */}\n </div>\n </div>\n )\n})\n\n/** Preview-speed presets shown in the speed menu (forward only; 1 = real-time). */\nconst SPEED_PRESETS = [0.25, 0.5, 1, 1.5, 2] as const\n\n/** Clamp a programmatic playback rate to the supported preview range. */\nfunction clampRate(rate: number): number {\n if (!Number.isFinite(rate) || rate <= 0) return 1\n return Math.max(0.1, Math.min(4, rate))\n}\n\n/** Format a rate for the UI, e.g. `0.5×`, `1×`, `1.5×` (≤2 decimals). */\nfunction formatRate(rate: number): string {\n return `${Math.round(rate * 100) / 100}×`\n}\n\nfunction PlayIcon(): ReactElement {\n return (\n <svg width=\"15\" height=\"16\" viewBox=\"0 0 15 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M2 1.4v13.2a1 1 0 0 0 1.52.85l11-6.6a1 1 0 0 0 0-1.7l-11-6.6A1 1 0 0 0 2 1.4Z\" />\n </svg>\n )\n}\n\nfunction PauseIcon(): ReactElement {\n return (\n <svg width=\"14\" height=\"16\" viewBox=\"0 0 14 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <rect x=\"2\" y=\"1.5\" width=\"3.5\" height=\"13\" rx=\"1.2\" />\n <rect x=\"8.5\" y=\"1.5\" width=\"3.5\" height=\"13\" rx=\"1.2\" />\n </svg>\n )\n}\n\nfunction LoopIcon(): ReactElement {\n return (\n <svg\n width=\"17\"\n height=\"17\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M17 1.5 21 5.5 17 9.5\" />\n <path d=\"M3 11V9a4 4 0 0 1 4-4h14\" />\n <path d=\"M7 22.5 3 18.5 7 14.5\" />\n <path d=\"M21 13v2a4 4 0 0 1-4 4H3\" />\n </svg>\n )\n}\n\nfunction VolumeIcon(): ReactElement {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 9v6h4l5 4V5L8 9H4Z\" />\n <path d=\"M16.5 8.5a4 4 0 0 1 0 7\" />\n <path d=\"M19 6a7 7 0 0 1 0 12\" />\n </svg>\n )\n}\n\nfunction VolumeMuteIcon(): ReactElement {\n return (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 9v6h4l5 4V5L8 9H4Z\" />\n <path d=\"M22 9.5 16.5 15\" />\n <path d=\"M16.5 9.5 22 15\" />\n </svg>\n )\n}\n\nfunction FullscreenIcon(): ReactElement {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M3 8V4a1 1 0 0 1 1-1h4\" />\n <path d=\"M21 8V4a1 1 0 0 0-1-1h-4\" />\n <path d=\"M3 16v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M21 16v4a1 1 0 0 1-1 1h-4\" />\n </svg>\n )\n}\n\nfunction ExitFullscreenIcon(): ReactElement {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M8 3v4a1 1 0 0 1-1 1H3\" />\n <path d=\"M16 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M8 21v-4a1 1 0 0 0-1-1H3\" />\n <path d=\"M16 21v-4a1 1 0 0 1 1-1h4\" />\n </svg>\n )\n}\n\n/** Format seconds as `m:ss.cs` (tabular-friendly). */\nfunction fmtTime(s: number): string {\n const minutes = Math.floor(s / 60)\n const secs = Math.floor(s % 60)\n const centis = Math.floor((s * 100) % 100)\n return `${minutes}:${secs.toString().padStart(2, '0')}.${centis.toString().padStart(2, '0')}`\n}\n\n/** Inline-styled fallbacks (work even without the stylesheet). The stylesheet\n * below layers brand tokens, hover/focus, and reduced-motion on top. */\nconst styles: Record<string, CSSProperties> = {\n root: {\n display: 'block',\n width: '100%',\n color: 'var(--onda-text, #f2f2f4)',\n fontFamily: 'var(--onda-font-body, \"Space Grotesk\", ui-sans-serif, system-ui, sans-serif)',\n },\n stage: {\n position: 'relative',\n width: '100%',\n borderRadius: 14,\n overflow: 'hidden',\n background: 'var(--onda-bg-deep, #08080a)',\n border: '1px solid var(--onda-border, #26262c)',\n // Isolate the preview as its own compositing context + contain its paint, so\n // the heavy, per-frame-updating canvas layer doesn't force the browser to\n // recomposite the whole PAGE behind it. That recomposite is what flickers the\n // background on some GPUs (e.g. Arc/Metal) while a video plays and the cursor\n // moves — a compositor artifact, NOT a content change (the rendered frames are\n // byte-identical) and NOT present in exported video.\n isolation: 'isolate',\n contain: 'paint',\n // A query container (inline axis only, so aspect-ratio still drives height) so\n // the control bar can adapt to narrow widths (e.g. 9:16) — see the @container\n // rule in the stylesheet.\n containerType: 'inline-size',\n },\n // `translateZ(0)` promotes the canvas to its OWN GPU layer, so its per-frame\n // pixel updates don't invalidate / re-raster sibling layers (see `stage`).\n canvas: {\n width: '100%',\n height: '100%',\n display: 'block',\n cursor: 'pointer',\n transform: 'translateZ(0)',\n },\n videoOverlay: { position: 'absolute', inset: 0, overflow: 'hidden', pointerEvents: 'none' },\n readout: {\n display: 'flex',\n alignItems: 'baseline',\n gap: 4,\n fontVariantNumeric: 'tabular-nums',\n fontSize: 13,\n color: 'rgba(255,255,255,.75)',\n whiteSpace: 'nowrap',\n },\n}\n\n/** Inject the player's stylesheet once into `<head>`, persistently. A real\n * stylesheet (not inline styles) lets us style `:hover`, `:focus-visible`, the\n * range thumb/track, `:fullscreen`, and honor `prefers-reduced-motion`.\n *\n * It lives in `<head>` — NOT the component tree — so it survives the player\n * unmounting/remounting. (The gallery swaps compositions via `key`, which would\n * otherwise tear out an in-tree `<style>` and leave every player after the first\n * unstyled — no visible controls.) */\nfunction useInjectStyles(): void {\n useEffect(() => {\n const id = 'onda-player-styles'\n if (typeof document === 'undefined' || document.getElementById(id)) return\n const style = document.createElement('style')\n style.id = id\n style.textContent = PLAYER_CSS\n document.head.appendChild(style)\n }, [])\n}\n\nconst PLAYER_CSS = `\n.onda-player {\n /* Brand tokens (onda.video palette) with safe fallbacks. */\n --onda-bg: var(--bg, #0e0e12);\n --onda-bg-deep: var(--bg-deep, #08080a);\n --onda-surface: var(--surface, #121217);\n --onda-surface-2: var(--surface-2, #18181d);\n --onda-border: var(--border, #26262c);\n --onda-text: var(--text, #f2f2f4);\n --onda-text-muted: var(--text-muted, #8e8e98);\n /* Player-scoped (NOT the page's generic --accent, which a host app like ONDA\n Studio sets to its own color) so the controls stay the ONDA rose by default;\n a host can still theme them via --onda-player-accent. */\n --onda-accent: var(--onda-player-accent, #d96b82);\n --onda-accent-600: var(--onda-player-accent-600, #c8576f);\n --onda-on-accent: var(--on-accent, #0e0e12);\n --onda-ok: var(--ok, #6bbf8a);\n --onda-warn: var(--warn, #d9b06b);\n}\n/* Controls overlay the stage and auto-hide unless hovering / paused / focused. */\n.onda-player__overlay {\n position: absolute; left: 0; right: 0; bottom: 0;\n display: flex; flex-direction: column; gap: 10px;\n padding: 32px 14px 14px;\n background: linear-gradient(to top, rgba(0,0,0,.72), rgba(0,0,0,.32) 55%, transparent);\n opacity: 0; transform: translateY(8px);\n transition: opacity 200ms ease-out, transform 200ms ease-out;\n pointer-events: none;\n}\n.onda-player__stage:hover .onda-player__overlay,\n.onda-player__stage:focus-within .onda-player__overlay,\n.onda-player.is-paused .onda-player__overlay,\n.onda-player.is-controls .onda-player__overlay {\n opacity: 1; transform: none; pointer-events: auto;\n}\n/* controls:none — a chrome-free thumbnail: no overlay, no fullscreen button\n (overrides the hover/focus/paused reveal above). */\n.onda-player.is-controls-none .onda-player__overlay,\n.onda-player.is-controls-none .onda-player__fs {\n display: none;\n}\n.onda-player__row { display: flex; align-items: center; gap: 14px; }\n.onda-player__spacer { flex: 1 1 auto; }\n/* Responsive control bar — the overlay is an inline-size query container, so\n these adapt to the PLAYER width regardless of canvas aspect (9:16, 4:5, 1:1,\n 16:9 all just resolve to a width).\n\n KEY: the widest thing in the bar is the time readout (\"0:07.80 / 0:11.06\"),\n NOT the buttons — so the right move on a narrow player is to compact the TIME,\n which then lets every button (play · mute · speed · loop) stay in one row. We\n only start dropping controls at sizes far below any real editor preview.\n\n Tier 1 (≤440px — most 9:16 / smaller 4:5·1:1): readout → CURRENT time only\n (the scrubber already shows the end point), tighten gaps. All buttons stay.\n Tier 2 (≤340px — tight 9:16): collapse volume to a mute TOGGLE (its 56px\n hover-out slider is the only thing left that would overflow). Muting works.\n Tier 3 (≤280px — last resort, a very small player): drop the preview-only\n speed control. */\n@container (max-width: 440px) {\n .onda-player__overlay { padding-left: 12px; padding-right: 12px; }\n .onda-player__row { gap: 9px; }\n .onda-player__sep, .onda-player__total { display: none; }\n}\n@container (max-width: 340px) {\n .onda-player__overlay { padding-left: 9px; padding-right: 9px; }\n .onda-player__row { gap: 7px; }\n .onda-player__volume-slider { display: none; }\n}\n@container (max-width: 280px) {\n .onda-player__speed { display: none; }\n}\n/* Engine/preview badge (top-left), fades with the controls. */\n.onda-player__badge {\n position: absolute; top: 12px; left: 12px;\n display: inline-flex; align-items: center; gap: 7px;\n padding: 5px 10px; border-radius: 999px;\n background: rgba(8,8,10,.82);\n border: 1px solid rgba(255,255,255,.1);\n color: rgba(255,255,255,.85);\n font-size: 11.5px; font-weight: 500; letter-spacing: 0.02em;\n opacity: 0; transition: opacity 200ms ease-out; pointer-events: none;\n}\n.onda-player__stage:hover .onda-player__badge,\n.onda-player__stage:focus-within .onda-player__badge,\n.onda-player.is-paused .onda-player__badge,\n.onda-player.is-controls .onda-player__badge { opacity: 1; }\n/* Fullscreen toggle (top-right), fades in with the controls like the badge. */\n.onda-player__fs {\n position: absolute; top: 12px; right: 12px;\n width: 34px; height: 34px;\n display: grid; place-items: center;\n border-radius: 9px;\n background: rgba(8,8,10,.82);\n border: 1px solid rgba(255,255,255,.1);\n color: rgba(255,255,255,.85);\n cursor: pointer;\n opacity: 0; transform: translateY(-4px);\n transition: opacity 200ms ease-out, transform 200ms ease-out, background 160ms ease-out, color 160ms ease-out;\n pointer-events: none;\n}\n.onda-player__stage:hover .onda-player__fs,\n.onda-player__stage:focus-within .onda-player__fs,\n.onda-player.is-paused .onda-player__fs,\n.onda-player.is-controls .onda-player__fs { opacity: 1; transform: none; pointer-events: auto; }\n.onda-player__fs:hover { background: rgba(8,8,10,.85); color: #fff; }\n.onda-player__fs:focus-visible { outline: 2px solid var(--onda-accent); outline-offset: 2px; }\n.onda-player__fs svg { display: block; }\n/* In fullscreen: fill the screen and letterbox the canvas (preserve aspect). */\n.onda-player__stage:fullscreen,\n.onda-player__stage:-webkit-full-screen {\n width: 100vw; height: 100vh; border-radius: 0; aspect-ratio: auto; background: #000;\n}\n.onda-player__stage:fullscreen .onda-player__canvas,\n.onda-player__stage:-webkit-full-screen .onda-player__canvas {\n width: 100vw; height: 100vh; object-fit: contain;\n}\n/* Circular primary play/pause — the player's focal control. */\n.onda-player__play {\n flex: 0 0 auto;\n width: 42px; height: 42px;\n display: grid; place-items: center;\n border: 0; border-radius: 999px;\n background: var(--onda-accent);\n color: var(--onda-on-accent);\n cursor: pointer;\n transition: background 160ms ease-out, transform 120ms ease-out;\n}\n.onda-player__play:hover { background: var(--onda-accent-600); transform: scale(1.06); }\n.onda-player__play:active { transform: scale(0.96); }\n.onda-player__play svg { display: block; }\n/* Ghost icon toggle (loop), over the scrim. */\n.onda-player__icon {\n flex: 0 0 auto;\n width: 36px; height: 36px;\n display: grid; place-items: center;\n border: 1px solid rgba(255,255,255,.18); border-radius: 10px;\n background: transparent; color: rgba(255,255,255,.8);\n cursor: pointer;\n transition: background 160ms ease-out, color 160ms ease-out, border-color 160ms ease-out;\n}\n.onda-player__icon:hover { background: rgba(255,255,255,.1); color: #fff; }\n.onda-player__icon.is-active {\n color: var(--onda-accent);\n border-color: color-mix(in srgb, var(--onda-accent) 60%, transparent);\n background: color-mix(in srgb, var(--onda-accent) 16%, transparent);\n}\n.onda-player__icon svg { display: block; }\n/* Speed: a rate button (shows e.g. \"1×\") that opens a preset menu above it. */\n.onda-player__speed { position: relative; display: inline-flex; flex: 0 0 auto; }\n.onda-player__speed-btn {\n width: auto; min-width: 46px; padding: 0 10px;\n font: 600 13px/1 ui-monospace, \"SF Mono\", Menlo, monospace;\n font-variant-numeric: tabular-nums;\n}\n.onda-player__speed-menu {\n position: absolute; bottom: calc(100% + 8px); right: 0; z-index: 6;\n display: flex; flex-direction: column; gap: 2px;\n padding: 4px; border-radius: 10px;\n background: #16161c; border: 1px solid rgba(255,255,255,.14);\n box-shadow: 0 10px 30px rgba(0,0,0,.5);\n}\n.onda-player__speed-item {\n appearance: none; border: 0; background: transparent;\n color: rgba(255,255,255,.82); cursor: pointer;\n font: 600 13px/1 ui-monospace, \"SF Mono\", Menlo, monospace;\n font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap;\n padding: 7px 12px; border-radius: 7px; min-width: 60px;\n}\n.onda-player__speed-item:hover { background: rgba(255,255,255,.1); color: #fff; }\n.onda-player__speed-item.is-active { color: var(--onda-accent); }\n.onda-player__speed-btn:focus-visible,\n.onda-player__speed-item:focus-visible {\n outline: 2px solid var(--onda-accent); outline-offset: 2px;\n}\n/* Volume: a mute toggle + a slider that expands on hover/focus (compact). */\n.onda-player__volume { display: inline-flex; align-items: center; gap: 4px; }\n.onda-player__volume-slider {\n width: 0; opacity: 0; min-width: 0;\n height: 5px; cursor: pointer; margin: 0;\n -webkit-appearance: none; appearance: none; background: transparent;\n transition: width 160ms ease-out, opacity 160ms ease-out;\n}\n.onda-player__volume:hover .onda-player__volume-slider,\n.onda-player__volume:focus-within .onda-player__volume-slider { width: 56px; opacity: 1; }\n.onda-player__volume-slider::-webkit-slider-runnable-track {\n height: 4px; border-radius: 999px; background: rgba(255,255,255,.32);\n}\n.onda-player__volume-slider::-webkit-slider-thumb {\n -webkit-appearance: none; appearance: none; width: 11px; height: 11px; margin-top: -3.5px;\n border-radius: 999px; background: #fff;\n}\n.onda-player__volume-slider::-moz-range-track {\n height: 4px; border-radius: 999px; background: rgba(255,255,255,.32);\n}\n.onda-player__volume-slider::-moz-range-thumb {\n width: 11px; height: 11px; border: 0; border-radius: 999px; background: #fff;\n}\n/* Visible focus rings on every interactive control + the player region. */\n.onda-player:focus-visible,\n.onda-player__play:focus-visible,\n.onda-player__icon:focus-visible,\n.onda-player__scrubber:focus-visible {\n outline: 2px solid var(--onda-accent);\n outline-offset: 2px;\n}\n/* Progress-aware scrubber over the scrim: rose fill, translucent track. */\n.onda-player__scrubber {\n flex: 1 1 auto; min-width: 80px;\n height: 8px; cursor: pointer; margin: 0;\n -webkit-appearance: none; appearance: none;\n background: transparent;\n}\n.onda-player__scrubber::-webkit-slider-runnable-track {\n height: 6px; border-radius: 999px;\n background: linear-gradient(\n to right,\n var(--onda-accent) 0 var(--progress, 0%),\n rgba(255,255,255,.32) var(--progress, 0%) 100%\n );\n}\n.onda-player__scrubber::-moz-range-track {\n height: 6px; border-radius: 999px; background: rgba(255,255,255,.32);\n}\n.onda-player__scrubber::-moz-range-progress {\n height: 6px; border-radius: 999px; background: var(--onda-accent);\n}\n.onda-player__scrubber::-webkit-slider-thumb {\n -webkit-appearance: none; appearance: none;\n width: 14px; height: 14px; margin-top: -4px;\n border-radius: 999px; background: #fff;\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--onda-accent) 45%, transparent), 0 1px 3px rgba(0,0,0,.6);\n transition: box-shadow 140ms ease-out;\n}\n.onda-player__scrubber:hover::-webkit-slider-thumb {\n box-shadow: 0 0 0 6px color-mix(in srgb, var(--onda-accent) 50%, transparent), 0 1px 3px rgba(0,0,0,.6);\n}\n.onda-player__scrubber::-moz-range-thumb {\n width: 14px; height: 14px; border: 0;\n border-radius: 999px; background: #fff;\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--onda-accent) 45%, transparent), 0 1px 3px rgba(0,0,0,.6);\n}\n.onda-player__readout { flex: 0 0 auto; }\n.onda-player__time { font-weight: 600; color: #fff; }\n.onda-player__sep, .onda-player__total { color: rgba(255,255,255,.6); }\n.onda-player__dot {\n flex: 0 0 auto; width: 7px; height: 7px; border-radius: 999px; display: inline-block;\n}\n.onda-player__dot--ok {\n background: var(--onda-ok);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--onda-ok) 25%, transparent);\n}\n.onda-player__dot--warn {\n background: var(--onda-warn);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--onda-warn) 25%, transparent);\n}\n@media (prefers-reduced-motion: reduce) {\n .onda-player__overlay,\n .onda-player__badge,\n .onda-player__play,\n .onda-player__icon,\n .onda-player__scrubber::-webkit-slider-thumb { transition: none; }\n .onda-player__play:hover,\n .onda-player__play:active { transform: none; }\n}\n`\n"]}