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":["../../components/src/motion.ts","../../components/src/easing.ts","../../components/src/timing.ts","../../components/src/text-metrics.ts","../../components/src/divergence.ts","../../components/src/glyph-line.ts","../../components/src/bounds.ts","../../components/src/theme.ts","../../components/src/choreography.ts","../../components/src/hooks.ts","../../components/src/audio.ts","../../components/src/components/AudioClip.tsx","../../components/src/components/AudioVisualizer.tsx","../../components/src/components/BarChart.tsx","../../components/src/components/BentoGrid.tsx","../../components/src/components/BlurReveal.tsx","../../components/src/components/BoundingBox.tsx","../../components/src/components/BrowserFrame.tsx","../../components/src/components/Button.tsx","../../components/src/components/Callout.tsx","../../components/src/components/CameraShake.tsx","../../components/src/components/CardShowcase.tsx","../../components/src/components/Captions.tsx","../../components/src/components/FadeIn.tsx","../../components/src/components/ChapterCard.tsx","../../components/src/components/CodeBlock.tsx","../../components/src/components/CodeDiff.tsx","../../components/src/components/Confetti.tsx","../../components/src/components/CountUp.tsx","../../components/src/components/Cursor.tsx","../../components/src/components/DeviceFrame.tsx","../../components/src/components/DrawOn.tsx","../../components/src/components/DynamicGrid.tsx","../../components/src/components/EndCard.tsx","../../components/src/components/FadeOut.tsx","../../components/src/components/FilmGrade.tsx","../../components/src/components/GradientShift.tsx","../../components/src/components/GrainOverlay.tsx","../../components/src/components/Highlight.tsx","../../components/src/components/IconPop.tsx","../../components/src/components/ImageReveal.tsx","../../components/src/components/InputField.tsx","../../components/src/components/KanbanBoard.tsx","../../components/src/components/KenBurns.tsx","../../components/src/keyframes-sampler.ts","../../components/src/components/Keyframes.tsx","../../components/src/responsive.ts","../../components/src/components/TextAnimator.tsx","../../components/src/components/KineticText.tsx","../../components/src/components/LineChart.tsx","../../components/src/components/LogoReveal.tsx","../../components/src/path-length.ts","../../components/src/components/ScaleIn.tsx","../../components/src/components/Underline.tsx","../../components/src/components/LogoSting.tsx","../../components/src/components/LookbookShot.tsx","../../components/src/components/LowerThird.tsx","../../components/src/components/Marquee.tsx","../../components/src/components/MaskReveal.tsx","../../components/src/components/MatrixDecode.tsx","../../components/src/components/MeshGradient.tsx","../../components/src/components/Moodboard.tsx","../../components/src/components/NodeGraph.tsx","../../components/src/components/Parallax.tsx","../../components/src/components/PathMorph.tsx","../../components/src/components/PieReveal.tsx","../../components/src/components/PriceTag.tsx","../../components/src/components/PricingCard.tsx","../../components/src/components/ProductWall.tsx","../../components/src/components/ProgressBar.tsx","../../components/src/components/ProgressSteps.tsx","../../components/src/components/PulsingIndicator.tsx","../../components/src/components/WordStagger.tsx","../../components/src/components/QuoteCard.tsx","../../components/src/components/RgbGlitch.tsx","../../components/src/components/RotateIn.tsx","../../components/src/components/Scrim.tsx","../../components/src/components/SiteReveal.tsx","../../components/src/components/ShimmerSweep.tsx","../../components/src/components/SkeletonCard.tsx","../../components/src/components/SlideIn.tsx","../../components/src/components/SlideOut.tsx","../../components/src/components/SlotMachineRoll.tsx","../../components/src/components/SplitScreen.tsx","../../components/src/components/Spotlight.tsx","../../components/src/components/SpotlightCard.tsx","../../components/src/components/StaggerGroup.tsx","../../components/src/components/SplitLockup.tsx","../../components/src/components/StatCard.tsx","../../components/src/components/Terminal.tsx","../../components/src/components/TextFadeReplace.tsx","../../components/src/components/Timeline.tsx","../../components/src/components/TitleCard.tsx","../../components/src/components/TrackingIn.tsx","../../components/src/components/Typewriter.tsx","../../components/src/components/VideoClip.tsx","../../components/src/components/Vignette.tsx","../../components/src/components/WordRotate.tsx"],"names":["staggerFrames","mod","useVideoConfig","spring","interpolate","useState","useEffect","t","useCurrentFrame","jsx","Audio","jsxs","Group","Rect","r","linearGradient","Text","CLAMP","LINE_RATIO","Path","AVG_CHAR_W","Ellipse","variantSeed","AbsoluteFill","CHAR_WIDTH_FACTOR","Fragment","random","clipRect","Image","rgbHex","UNDERLINE_OFFSET","Flex","clamp","withAlpha","DEFAULT_DATA","lerp","TITLE_OFFSET","eb","DEFAULT_COLORS","radialGradient","lerpPathD","x0","y0","parseRgb","hx","toHexByte","DOT_GAP","toTransparent","mixHex","clamp01","easeOut","easeIn","alphaHex"],"mappings":"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","file":"components.js","sourcesContent":["//! Canonical motion tokens — durations, stagger, springs, overshoot.\n//!\n//! Ported verbatim from ondajs (`lib/motion.ts`). Every component references\n//! these tokens rather than embedding raw frame counts or spring configs: the\n//! motion signature comes from the closed system; raw values fragment it.\n//!\n//! Values are video-paced for a 30fps house composition. UI-animation\n//! literature quotes 200–500ms; Onda renders to video, where the eye has time\n//! to follow and there are no gestures to acknowledge, so durations run longer.\n\n/**\n * Duration scale in frames at 30fps. Reach for these before hardcoding a frame\n * count. At other framerates, scale via `Math.round(DURATION.x * fps / 30)`.\n *\n * - `instant` (6f / 0.20s) — micro shifts\n * - `fast` (10f / 0.33s) — exits, small moves\n * - `base` (22f / 0.73s) — default entrance\n * - `slow` (28f / 0.93s) — large entrances, hero moves\n * - `slower` (34f / 1.13s) — full scene transitions\n * - `hold` (48f / 1.60s) — minimum settled hold\n *\n * Pacing note: entrances run on the slower side and every reveal is meant to\n * *settle and hold* before the next move — confidence reads as stillness, not\n * constant motion. Keep one primary move per beat.\n */\nexport const DURATION = {\n instant: 6,\n fast: 10,\n base: 22,\n slow: 28,\n slower: 34,\n hold: 48,\n} as const\n\n/** Keys of {@link DURATION} — useful for typed props that pick a duration. */\nexport type DurationToken = keyof typeof DURATION\n\n/** Canonical stagger between sibling elements (lists, words, grouped reveals).\n * `5` frames @ 30fps ≈ 0.17s — a pronounced, orchestrated wave that choreographs\n * the eye. One value, used everywhere. */\nexport const STAGGER = 5\n\n/** Hero-landing overshoot magnitude — a 3% scale bump that settles back to 1.\n * Reserved for the two-phase landing pattern (see `heroReveal`). */\nexport const OVERSHOOT = 0.03\n\n/** The house spring — smooth, settled, no overshoot. The Onda fingerprint.\n * Heavily overdamped (damping ratio ≈ 10): a confident settle, never a bounce. */\nexport const SPRING_SMOOTH = {\n damping: 200,\n stiffness: 100,\n mass: 1,\n} as const\n\n/** Faster spring for decisive elements (counters, value swaps, cursor moves).\n * Still heavily overdamped — snappiness via higher stiffness, not less damping. */\nexport const SPRING_SNAPPY = {\n damping: 120,\n stiffness: 180,\n mass: 1,\n} as const\n\n/** Stagger offset in frames for the i-th sibling in a grouped reveal. The single\n * canonical helper — every cascade goes through here so stagger stays\n * consistent and greppable. */\nexport const staggerFrames = (index: number, increment: number = STAGGER): number => {\n return Math.max(0, index) * increment\n}\n","//! House easing curve.\n//!\n//! For physical motion (translate / scale / rotation) use the springs in\n//! `motion.ts` — SPRING_SMOOTH (default, no overshoot) and SPRING_SNAPPY. The\n//! HOUSE_EASE below is the canonical curve for opacity / color / non-physical\n//! transitions only. Never raw linear for tracked motion.\n\nimport { cubicBezier } from '@onda-engine/react'\n\n/** The house easing curve — a restrained ease-out (`cubic-bezier(0.16, 1, 0.3, 1)`).\n * Use for opacity / color fades and anything the eye tracks but that doesn't\n * move physically. (ondajs uses Remotion's `Easing.bezier`; `@onda-engine/react`\n * exposes the same curve as `cubicBezier`.) */\nexport const HOUSE_EASE = cubicBezier(0.16, 1, 0.3, 1)\n","//! Clip-aware timing — \"does this entrance land before the cut?\" as a NUMBER.\n//!\n//! Three pieces:\n//!\n//! - {@link settleTime} — the registry: per-component settle calculators\n//! (`(props, fps) → frames`) for every animated component whose entrance has\n//! a computable end. The same formulas the components run, so a director (or\n//! the Studio agent) can ask up front whether a 1.4s beat fits a slot-roll.\n//! - {@link staggeredSettle} — the shared formula most entrances reduce to\n//! (`delay + (n−1)×stagger + duration`), used by the registry AND the\n//! components so the two can't drift.\n//! - {@link useTimeScale} — the clamp: resolves `fitToClip`/`maxSettle` props\n//! into a ≤1 time-scale factor a component multiplies its delays/durations\n//! by, so the WHOLE envelope compresses to land inside `clip − hold`.\n//! `fitToClip` reads the clip length from `useVideoConfig().durationInFrames`\n//! (scoped to the enclosing `<Sequence>`; the cinema bridge wraps every entry\n//! in one, so clip length flows automatically).\n//!\n//! All registry inputs accept {@link TimeInput} (frames or '0.5s' strings),\n//! parsed with the same grammar the components use.\n\nimport { useVideoConfig } from '@onda-engine/react'\nimport { DURATION, STAGGER } from './motion.js'\nimport { type TimeInput, framesOf } from './time.js'\n\n/** `delay + (n−1)×stagger + duration` — the settle of a staggered entrance.\n * All values in FRAMES. */\nexport function staggeredSettle(\n count: number,\n staggerFrames: number,\n durationFrames: number,\n delayFrames = 0,\n): number {\n return delayFrames + Math.max(0, count - 1) * staggerFrames + durationFrames\n}\n\n/** Loose prop bag — the registry reads only the timing-relevant keys. */\ntype Props = Record<string, unknown>\n\n/** A per-component settle calculator: total frames from the component's local\n * frame 0 until its entrance has fully settled (defaults applied). */\nexport type SettleFn = (props: Props, fps: number) => number\n\nconst t = (props: Props, key: string, fps: number, fallback: number): number =>\n framesOf(props[key] as TimeInput | undefined, fps, fallback)\nconst str = (props: Props, key: string, fallback: string): string =>\n typeof props[key] === 'string' ? (props[key] as string) : fallback\nconst arr = (props: Props, key: string, fallback: number): number =>\n Array.isArray(props[key]) ? (props[key] as unknown[]).length : fallback\n\nconst glyphCount = (text: string): number =>\n Array.from(text).filter((ch) => ch.trim().length > 0).length\n\n/** Settle calculators, keyed by the PascalCase component name. Formulas mirror\n * the component implementations (see each component's source for the beats). */\nexport const COMPONENT_SETTLE: Record<string, SettleFn> = {\n // ── entrance / exit wrappers ────────────────────────────────────────────────\n FadeIn: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.base),\n FadeOut: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.fast),\n SlideIn: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.base),\n SlideOut: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.fast),\n ScaleIn: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.base),\n RotateIn: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.base),\n BlurReveal: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.base),\n MaskReveal: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'duration', fps, DURATION.base),\n\n // ── text family ─────────────────────────────────────────────────────────────\n Typewriter: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.slow),\n CountUp: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.slow),\n TextAnimator: (p, fps) => {\n const text = str(p, 'text', 'Animate')\n const units = str(p, 'units', 'glyph')\n const n =\n units === 'line'\n ? text.split('\\n').filter((l) => l.trim().length > 0).length\n : units === 'word'\n ? text.split(/\\s+/).filter(Boolean).length\n : glyphCount(text)\n return staggeredSettle(\n n,\n t(p, 'stagger', fps, STAGGER),\n t(p, 'durationInFrames', fps, DURATION.base),\n t(p, 'delay', fps, 0),\n )\n },\n KineticText: (p, fps) =>\n staggeredSettle(\n glyphCount(str(p, 'text', 'kinetic')),\n t(p, 'stagger', fps, STAGGER),\n t(p, 'durationInFrames', fps, DURATION.base),\n t(p, 'delay', fps, 0),\n ),\n MatrixDecode: (p, fps) =>\n staggeredSettle(\n Array.from(str(p, 'text', 'ONDA')).length,\n Math.max(0, t(p, 'charDelay', fps, 3)),\n Math.max(1, t(p, 'scrambleDuration', fps, 18)),\n t(p, 'delay', fps, 0),\n ),\n SlotMachineRoll: (p, fps) =>\n // Roll: delay + (n−1)×charDelay + duration; the accent glow then blooms\n // (DURATION.base − 8) frames past the last landing.\n staggeredSettle(\n Array.from(str(p, 'text', '2026')).length,\n t(p, 'charDelay', fps, STAGGER),\n t(p, 'durationInFrames', fps, DURATION.slower),\n t(p, 'delay', fps, 0),\n ) +\n (DURATION.base - 8),\n WordStagger: (p, fps) =>\n staggeredSettle(\n str(p, 'text', 'Make it move').split(/\\s+/).filter(Boolean).length,\n t(p, 'stagger', fps, STAGGER),\n DURATION.base,\n t(p, 'delay', fps, 0),\n ),\n\n // ── composites (sequenced cards) ───────────────────────────────────────────\n TitleCard: (p, fps) =>\n t(p, 'delay', fps, 0) + (p.subtitle ? 2 * STAGGER + DURATION.base : DURATION.slow), // subtitle trails by 2 stagger steps\n StatCard: (p, fps) => t(p, 'delay', fps, 0) + 4 * STAGGER + DURATION.base, // label lands last\n ChapterCard: (p, fps) => t(p, 'delay', fps, 0) + 34 + DURATION.fast, // underline (delay+34) draws over DURATION.fast\n EndCard: (p, fps) =>\n t(p, 'delay', fps, 0) +\n DURATION.base +\n 6 + // HANDLES_OFFSET\n Math.max(0, arr(p, 'handles', 2) - 1) * STAGGER +\n DURATION.base,\n LowerThird: (p, fps) => t(p, 'delay', fps, 0) + 8 + DURATION.base, // underline beat (delay+8) settles last\n InputField: (p, fps) => t(p, 'delay', fps, 0) + t(p, 'typeDuration', fps, 36),\n Terminal: (p, fps) =>\n t(p, 'delay', fps, 0) +\n t(p, 'typeSpeed', fps, 30) +\n t(p, 'outputDelay', fps, 8) +\n Math.max(0, arr(p, 'output', 2) - 1) * STAGGER +\n DURATION.base,\n Button: (p, fps) => {\n const enter = t(p, 'delay', fps, 0) + t(p, 'durationInFrames', fps, DURATION.base)\n const press = p.press === false ? 0 : t(p, 'pressFrame', fps, 30) + 7 // PRESS_OUT\n return Math.max(enter, press)\n },\n}\n\n/** Total settle time in FRAMES for `component` with `props` — `delay` included,\n * defaults applied — or `null` when the component isn't in the registry (not\n * animated, or its end isn't statically computable). \"Does it land before the\n * cut?\" is `settleTime(...) <= clipFrames`. */\nexport function settleTime(component: string, props: Props = {}, fps = 30): number | null {\n const fn = COMPONENT_SETTLE[component]\n if (!fn) return null\n return Math.ceil(fn(props, fps))\n}\n\n/** Clip-fit props shared by the animated components. */\nexport interface FitToClipOpts {\n /** Compress the WHOLE timing envelope (delay, stagger, durations) so the\n * entrance settles at least `hold` before the end of the enclosing clip\n * (`useVideoConfig().durationInFrames`, Sequence-scoped). Opt-in. */\n fitToClip?: boolean\n /** Hard cap on the settle time (frames or '0.5s' string). Wins over\n * `fitToClip` when both are given. */\n maxSettle?: TimeInput\n /** Breathing room before the cut for `fitToClip` (default `DURATION.instant`\n * = 6 frames). */\n hold?: TimeInput\n}\n\n/** Resolve {@link FitToClipOpts} against a natural settle time (frames) into a\n * time-scale factor ≤ 1. Multiply every delay/stagger/duration by it. Returns\n * 1 when no fit is requested or the entrance already lands. The compressed\n * settle never drops below 1 frame. */\nexport function useTimeScale(naturalSettleFrames: number, opts: FitToClipOpts): number {\n const { fps, durationInFrames } = useVideoConfig()\n let available: number | undefined\n if (opts.maxSettle !== undefined) {\n available = framesOf(opts.maxSettle, fps)\n } else if (opts.fitToClip) {\n available = durationInFrames - framesOf(opts.hold, fps, DURATION.instant)\n }\n if (available === undefined || naturalSettleFrames <= 0) return 1\n return Math.min(1, Math.max(1, available) / naturalSettleFrames)\n}\n","//! Real text measurement for components that must size to the *actual* text —\n//! Highlight's accent bar, Underline, Button padding, InputField's caret, etc.\n//!\n//! Backed by `@onda-engine/wasm`'s `OndaEngine.measureText` — the SAME cosmic-text\n//! shaping the engine draws with — so a bar/underline hugs the text exactly\n//! instead of the old glyph-count guess (`length * fontSize * 0.56`), which is\n//! wrong for proportional fonts.\n//!\n//! Two paths, mirroring `useAudioData`:\n//! - **Browser preview**: `useTextMetrics` lazily loads the wasm (async), falls\n//! back to the estimate until ready, and re-renders when it is.\n//! - **Node export**: `preloadTextMetrics()` warms the engine before the\n//! synchronous `renderFramesJSON`, so `measureText` returns real metrics\n//! during the bake (`@onda-engine/render` calls it; the CLI stays text-agnostic).\n//!\n//! `measureText` is always synchronous and never throws: real metrics when the\n//! engine is warm, the estimate otherwise — so a composition never blocks.\n\nimport { registerEngineWarmer, registerFont } from '@onda-engine/react'\nimport { useEffect, useState } from 'react'\n\nexport interface TextMetrics {\n /** Shaped advance width — the true rendered width of the string (px). */\n width: number\n /** Total laid-out height (px). */\n height: number\n /** Top of the line box to the baseline (px). */\n ascent: number\n /** Baseline to the bottom of the line box (px). */\n descent: number\n /** Baseline-to-baseline line height (px). */\n lineHeight: number\n}\n\n/** Resolve a CSS letter-spacing value to engine px. `'-0.02em'` → `-0.02 *\n * fontSize`; `'2px'` → `2`; a bare number passes through. Undefined → 0. */\nexport function letterSpacingPx(\n value: string | number | undefined | null,\n fontSize: number,\n): number {\n if (value == null) return 0\n if (typeof value === 'number') return value\n const v = value.trim()\n const n = Number.parseFloat(v)\n if (!Number.isFinite(n)) return 0\n return v.endsWith('em') ? n * fontSize : n\n}\n\nexport interface MeasureOpts {\n fontFamily?: string\n fontWeight?: number\n italic?: boolean\n /** Extra px between glyphs (CSS letter-spacing) — included in the width so a\n * component can center/size letter-spaced text faithfully. */\n letterSpacing?: number\n}\n\n/** Font-level vertical metrics returned by `fontMetrics()`. Derived by\n * rasterizing 'H' and 'x' — pixel-accurate for the actual rendered font.\n * Call once per (fontSize, family, weight) combo, not per frame. */\nexport interface FontMetrics {\n /** Distance from the Text node's `y` to the top of capital letters (px). */\n capTop: number\n /** Height of capital letters from their top to the baseline (px). */\n capHeight: number\n /** Distance from the Text node's `y` to the top of lowercase 'x' (px). */\n xTop: number\n /** x-height: height of lowercase letters from their top to the baseline (px). */\n xHeight: number\n /** Distance from node's `y` to the baseline (px). Same as `TextMetrics.ascent`. */\n ascent: number\n /** Baseline to bottom of the line box (px). */\n descent: number\n /** Baseline-to-baseline line height (px). */\n lineHeight: number\n}\n\n/** One kerning-aware character cluster from `glyphLayout()`. */\nexport interface GlyphInfo {\n /** Byte offset of this cluster's start in the original string. */\n start: number\n /** Byte offset of this cluster's end (exclusive). */\n end: number\n /** Pen x relative to the layout origin (includes letter-spacing). */\n x: number\n /** Advance width to the next cluster — includes kern pairs. */\n advance: number\n}\n\n/** Minimal shape of `@onda-engine/wasm` we use — kept local so this file doesn't\n * hard-depend on the generated wasm types at build time. */\ninterface OndaEngineLike {\n measureText(\n content: string,\n fontSize: number,\n family?: string,\n weight?: number,\n italic?: boolean,\n letterSpacing?: number,\n ): TextMetrics\n fontMetrics(fontSize: number, family?: string, weight?: number, italic?: boolean): FontMetrics\n glyphLayout(\n content: string,\n fontSize: number,\n family?: string,\n weight?: number,\n italic?: boolean,\n letterSpacing?: number,\n ): Float32Array\n /** Load `.ttf`/`.otf` bytes; returns the newline-joined family name(s). */\n loadFont(data: Uint8Array): string\n}\ninterface WasmModule {\n default: (opts?: unknown) => Promise<unknown>\n initSync: (opts: { module: BufferSource }) => unknown\n OndaEngine: new () => OndaEngineLike\n}\n\nlet engine: OndaEngineLike | null = null\nlet loadFailed = false\nlet loadPromise: Promise<void> | null = null\n\n/** The old glyph-count estimate — the fallback while the engine warms (or if it\n * fails to load). Intentionally matches the legacy `WIDTH_RATIO` so behavior is\n * unchanged until real metrics arrive. */\nconst WIDTH_RATIO = 0.56\nfunction estimate(content: string, fontSize: number, letterSpacing = 0): TextMetrics {\n const n = Math.max(0, content.length)\n return {\n width: n * fontSize * WIDTH_RATIO + letterSpacing * Math.max(0, n - 1),\n height: fontSize * 1.2,\n ascent: fontSize * 0.8,\n descent: fontSize * 0.2,\n lineHeight: fontSize * 1.2,\n }\n}\n\n/** Load + init `@onda-engine/wasm` once and build the shared engine. Idempotent. In the\n * browser the wasm auto-locates next to its JS; in Node we read the bytes and\n * `initSync` (the auto-locate is browser-only). */\nexport function preloadTextMetrics(): Promise<void> {\n if (engine || loadFailed) return Promise.resolve()\n if (!loadPromise) {\n loadPromise = (async () => {\n try {\n const mod = (await import('@onda-engine/wasm')) as unknown as WasmModule\n if (typeof window === 'undefined') {\n // Node: explicit bytes. `node:` imports are @vite-ignored so the\n // browser bundle never tries to include them.\n const { readFileSync } = await import(/* @vite-ignore */ 'node:fs')\n // `ONDA_WASM_PATH` overrides where the `.wasm` is read from — required\n // when a bundler INLINES the JS glue (e.g. the vendored ONDA Studio\n // bundle), where `import.meta.resolve` can't locate the adjacent file.\n // Falls back to auto-locating next to the resolved `@onda-engine/wasm` JS.\n const override = process.env.ONDA_WASM_PATH\n let wasmBytes: BufferSource\n if (override) {\n wasmBytes = readFileSync(override)\n } else {\n const { fileURLToPath } = await import(/* @vite-ignore */ 'node:url')\n const jsUrl = import.meta.resolve('@onda-engine/wasm')\n const wasmUrl = new URL('./onda_wasm_bg.wasm', jsUrl)\n wasmBytes = readFileSync(fileURLToPath(wasmUrl))\n }\n mod.initSync({ module: wasmBytes })\n } else {\n await mod.default()\n }\n engine = new mod.OndaEngine()\n } catch (e) {\n loadFailed = true\n if (typeof console !== 'undefined') {\n console.warn(`[onda] text metrics unavailable — using estimates.\\n ${String(e)}`)\n }\n }\n })()\n }\n return loadPromise\n}\n\n/** Measure `content` at `fontSize` synchronously: real shaped metrics if the\n * engine is warm (Node export, or browser after `useTextMetrics` loads it),\n * else the glyph-count estimate. Never throws. */\nexport function measureText(\n content: string,\n fontSize: number,\n opts: MeasureOpts = {},\n): TextMetrics {\n if (!engine || !content || fontSize <= 0) return estimate(content, fontSize, opts.letterSpacing)\n try {\n return engine.measureText(\n content,\n fontSize,\n opts.fontFamily,\n opts.fontWeight,\n opts.italic,\n opts.letterSpacing,\n )\n } catch {\n return estimate(content, fontSize, opts.letterSpacing)\n }\n}\n\n// ─── font-level vertical metrics ─────────────────────────────────────────────\n\nfunction estimateFontMetrics(fontSize: number): FontMetrics {\n return {\n capTop: fontSize * 0.1,\n capHeight: fontSize * 0.7,\n xTop: fontSize * 0.3,\n xHeight: fontSize * 0.52,\n ascent: fontSize * 0.8,\n descent: fontSize * 0.2,\n lineHeight: fontSize * 1.2,\n }\n}\n\n/** Font-level vertical metrics for `fontSize` + optional family/weight — derived\n * by rasterizing 'H' and 'x'. Call ONCE per (fontSize, family, weight) combo\n * (not per frame). Use `capTop`/`capHeight` to center text without guessing:\n * ```\n * const m = fontMetrics(SIZE, { fontFamily: SANS })\n * const y = height / 2 - m.capTop - m.capHeight / 2 // centers caps at height/2\n * const cursorY = y + m.capTop // cursor aligned to cap top\n * ```\n */\nexport function fontMetrics(fontSize: number, opts: MeasureOpts = {}): FontMetrics {\n if (!engine || fontSize <= 0) return estimateFontMetrics(fontSize)\n try {\n return engine.fontMetrics(fontSize, opts.fontFamily, opts.fontWeight, opts.italic)\n } catch {\n return estimateFontMetrics(fontSize)\n }\n}\n\n/** Like `fontMetrics` but loads the engine in the browser and re-renders when\n * ready. Returns estimates until the engine is warm. */\nexport function useFontMetrics(fontSize: number, opts: MeasureOpts = {}): FontMetrics {\n const [, bump] = useState(0)\n useEffect(() => {\n if (engine || loadFailed || typeof window === 'undefined') return\n let cancelled = false\n preloadTextMetrics().then(() => {\n if (!cancelled) bump((v) => v + 1)\n })\n return () => {\n cancelled = true\n }\n }, [])\n return fontMetrics(fontSize, opts)\n}\n\n// ─── kerning-aware glyph layout ───────────────────────────────────────────────\n\n/** Kerning-aware glyph layout for `content`: returns one [`GlyphInfo`] per\n * shaped cluster with the pen `x` and `advance` that already include kern\n * pairs + letter-spacing. Unlike calling `measureText` per character, this is\n * accurate for tightly-set display type where kerning is visible. */\nfunction estimateGlyphLayout(content: string, fontSize: number, opts: MeasureOpts): GlyphInfo[] {\n let x = 0\n let byteOffset = 0\n return Array.from(content).map((ch) => {\n const advance = measureText(ch, fontSize, opts).width\n const start = byteOffset\n byteOffset += new TextEncoder().encode(ch).length\n const info: GlyphInfo = { start, end: byteOffset, x, advance }\n x += advance\n return info\n })\n}\n\nexport function glyphLayout(\n content: string,\n fontSize: number,\n opts: MeasureOpts = {},\n): GlyphInfo[] {\n if (!engine || !content || fontSize <= 0) return estimateGlyphLayout(content, fontSize, opts)\n try {\n const raw = engine.glyphLayout(\n content,\n fontSize,\n opts.fontFamily,\n opts.fontWeight,\n opts.italic,\n opts.letterSpacing,\n )\n const out: GlyphInfo[] = []\n for (let i = 0; i < raw.length; i += 4) {\n // biome-ignore lint/style/noNonNullAssertion: stride-4 walk — i..i+3 in bounds by the loop condition\n out.push({ start: raw[i]!, end: raw[i + 1]!, x: raw[i + 2]!, advance: raw[i + 3]! })\n }\n return out\n } catch {\n return estimateGlyphLayout(content, fontSize, opts)\n }\n}\n\n/** Like `glyphLayout` but loads the engine in the browser and re-renders when\n * ready. Returns the no-kerning fallback until the engine is warm. */\nexport function useGlyphLayout(\n content: string,\n fontSize: number,\n opts: MeasureOpts = {},\n): GlyphInfo[] {\n const [, bump] = useState(0)\n useEffect(() => {\n if (engine || loadFailed || typeof window === 'undefined') return\n let cancelled = false\n preloadTextMetrics().then(() => {\n if (!cancelled) bump((v) => v + 1)\n })\n return () => {\n cancelled = true\n }\n }, [])\n return glyphLayout(content, fontSize, opts)\n}\n\n/** Measure `content`, loading the engine in the browser on first use and\n * re-rendering when it's ready. Returns the estimate until then. In Node it\n * returns whatever `measureText` has (real metrics when `preloadTextMetrics`\n * ran before the render; the estimate otherwise). */\nexport function useTextMetrics(\n content: string,\n fontSize: number,\n opts: MeasureOpts = {},\n): TextMetrics {\n const [, bump] = useState(0)\n useEffect(() => {\n if (engine || loadFailed || typeof window === 'undefined') return\n let cancelled = false\n preloadTextMetrics().then(() => {\n if (!cancelled) bump((v) => v + 1)\n })\n return () => {\n cancelled = true\n }\n }, [])\n return measureText(content, fontSize, opts)\n}\n\n/** Loader-only companion to {@link measureText} for components that measure a\n * VARIABLE number of strings (a `.map`/loop), where the {@link useTextMetrics}\n * hook can't be called per item without breaking the rules of hooks. Call this\n * ONCE at the top of the component, then `measureText(...)` synchronously in the\n * loop. It loads the engine in the browser and re-renders when ready; returns\n * `true` once measurements are real. In Node it reflects whether the engine is\n * warm (the export path warms it via `preloadTextMetrics`). */\nexport function useTextMetricsReady(): boolean {\n const [, bump] = useState(0)\n useEffect(() => {\n if (engine || loadFailed || typeof window === 'undefined') return\n let cancelled = false\n preloadTextMetrics().then(() => {\n if (!cancelled) bump((v) => v + 1)\n })\n return () => {\n cancelled = true\n }\n }, [])\n return engine !== null\n}\n\n// ─── custom font loading (author-time ↔ render parity) ───────────────────────\n\n/** Load a custom font (`.ttf`/`.otf` bytes) into the author-time measurement\n * engine so `measureText`/`glyphLayout`/`fontMetrics` — and therefore\n * `<TextAnimator>` / `KineticText` glyph placement — are kerning-accurate for\n * that family instead of silently falling back to the bundled default. Select\n * the font by a returned family name on `<Text fontFamily=…>` or `TextAnimator`'s\n * `fontFamily`. Resolves to the family name(s) the font provides.\n *\n * Parity: the RENDERER must be given the SAME bytes (CLI `--font <path>`, or the\n * wasm preview's own `loadFont`). Identical bytes + identical cosmic-text shaping\n * ⇒ the positions measured here match the glyphs the engine draws. Loading the\n * same family twice is harmless. Awaits engine init; never throws (logs + returns\n * `[]` if the engine is unavailable or the bytes don't parse). */\nexport async function loadFont(data: Uint8Array): Promise<string[]> {\n // Single source: retain the bytes so `@onda-engine/render` hands the SAME font to the\n // renderer (`--font`) — no separate flag. Synchronous + before the async engine\n // load, so the registration lands the instant `loadFont` is called.\n registerFont(data)\n await preloadTextMetrics()\n if (!engine) return []\n try {\n const families = engine.loadFont(data)\n return families ? families.split('\\n').filter(Boolean) : []\n } catch (e) {\n if (typeof console !== 'undefined') {\n console.warn(\n `[onda] loadFont failed — text will measure against the bundled font.\\n ${String(e)}`,\n )\n }\n return []\n }\n}\n\n// Register with @onda-engine/react so `@onda-engine/render` warms the engine before a (sync)\n// export render — components bake real metrics into exported frames, not the\n// estimate. Importing @onda-engine/components is enough; no caller setup.\nregisterEngineWarmer(preloadTextMetrics)\n","//! Backend divergence — \"what I SEE vs what SHIPS\", queryable.\n//!\n//! The reference render is the native Vello GPU export ('export'). Three other\n//! backends draw the same scene JSON with documented gaps:\n//!\n//! - `preview-webgpu` — `@onda-engine/wasm-vello` in the browser. Runs the SAME\n//! renderer (per-node effects AND the composition `finish` chain are applied\n//! — `LinearFinish` is a pure texture→texture compute chain that runs\n//! identically on native and web). Remaining gaps: `lightWrap` (export/\n//! native only — nodes draw un-wrapped), fBm gradients (degrade to a smooth\n//! gradient), the `linear` HDR pipeline (gamma fallback), and composition\n//! motion blur (export-time temporal supersampling — a live player renders\n//! single frames).\n//! - `preview-cpu` / `native-cpu` — the CPU reference (tiny-skia; `@onda-engine/wasm`\n//! in the browser, `--backend cpu` natively). Faithful for fills/strokes/\n//! gradients/paths/text, but: no rotation, no clip, blend modes composite\n//! normal, no video decode, per-run text colors collapse to the base style,\n//! `goo`/`lightWrap` skipped, fBm degrades, and the composition\n//! `finish`/`linear` chain is not applied.\n//!\n//! {@link divergenceReport} walks a rendered scene and returns every node/\n//! feature whose render on the target backend diverges from export — the\n//! Studio agent (and any author) can ask BEFORE judging a preview. Sources of\n//! truth: the scene-rs `Effect`/`Node`/`Transform` doc comments and\n//! `ENGINE_CAPABILITIES` in fidelity.ts; component-level capability lives in\n//! `COMPONENT_FIDELITY.backend` ('gpu_only').\n\nimport type { Scene } from '@onda-engine/react'\n\n/** The render backends a scene can be judged on. `'export'` is the reference. */\nexport type RenderBackend = 'export' | 'preview-webgpu' | 'preview-cpu' | 'native-cpu'\n\n/** One feature that renders differently on the target backend than on export. */\nexport interface Divergence {\n /** Slash path of node indices from the root (e.g. `root/0/2`); `composition`\n * for composition-level features. */\n path: string\n /** The node's `id`, when it has one. */\n nodeId?: string\n /** What diverges — `transform:rotation`, `node:clip`, `node:blend`,\n * `node:video`, `text:runs`, `effect:light_wrap`, `effect:goo`,\n * `gradient:fbm`, `composition:finish`, `composition:linear`,\n * `composition:motionBlur`. */\n feature: string\n /** `missing` = not drawn/applied at all; `degraded` = drawn approximately. */\n severity: 'missing' | 'degraded'\n /** Human note (mirrors the engine doc comments). */\n note: string\n}\n\ninterface SceneNode {\n id?: string\n transform?: { rotate?: number }\n clip?: unknown\n blend?: string\n effects?: { effect?: string }[]\n kind?: {\n type?: string\n runs?: unknown[]\n gradient?: { gradient?: string }\n }\n children?: SceneNode[]\n}\n\ninterface SceneShape {\n composition?: { finish?: unknown; linear?: boolean }\n root?: SceneNode\n}\n\n/** Options for composition-level features that do NOT survive into per-frame\n * scene JSON (and so can't be detected by walking it). */\nexport interface DivergenceOpts {\n /** The composition declares `<Composition motionBlur={…}>` (an export-time\n * frame expansion — pass it explicitly, the per-frame scene can't show it). */\n motionBlur?: boolean\n}\n\nconst CPU_BACKENDS: RenderBackend[] = ['preview-cpu', 'native-cpu']\n\n/** Every node/effect/composition feature in `scene` whose render on `backend`\n * diverges from the native export. Empty for `'export'` (modulo\n * `opts.motionBlur`, which only export applies). */\nexport function divergenceReport(\n scene: Scene,\n backend: RenderBackend,\n opts: DivergenceOpts = {},\n): Divergence[] {\n const out: Divergence[] = []\n const s = scene as unknown as SceneShape\n const isCpu = CPU_BACKENDS.includes(backend)\n const isPreview = backend !== 'export'\n\n // ── composition-level ───────────────────────────────────────────────────────\n if (opts.motionBlur && isPreview) {\n out.push({\n path: 'composition',\n feature: 'composition:motionBlur',\n severity: 'missing',\n note: 'Motion blur is export-time temporal supersampling (N sub-frames per frame); a live preview renders single frames sharp.',\n })\n }\n if (s.composition?.finish && isCpu) {\n out.push({\n path: 'composition',\n feature: 'composition:finish',\n severity: 'missing',\n note: 'The cinematic finish chain (bloom/halation/grade/vignette/grain + ACES) runs on the Vello GPU renderer (native AND WebGPU preview); the CPU reference renders un-finished.',\n })\n }\n if (s.composition?.linear) {\n if (isCpu) {\n out.push({\n path: 'composition',\n feature: 'composition:linear',\n severity: 'missing',\n note: 'Linear-light HDR pipeline — the CPU reference falls back to the gamma path.',\n })\n } else if (backend === 'preview-webgpu') {\n out.push({\n path: 'composition',\n feature: 'composition:linear',\n severity: 'degraded',\n note: 'Linear-light HDR pipeline — the WebGPU preview falls back to the gamma path (scene-rs Composition::linear); judge HDR roll-off on the native render.',\n })\n }\n }\n\n // ── per-node walk ───────────────────────────────────────────────────────────\n const visit = (node: SceneNode | undefined, path: string) => {\n if (!node) return\n const push = (feature: string, severity: Divergence['severity'], note: string) =>\n out.push({ path, ...(node.id ? { nodeId: node.id } : {}), feature, severity, note })\n\n if (isCpu) {\n if (node.transform?.rotate) {\n push(\n 'transform:rotation',\n 'missing',\n 'The CPU reference ignores rotation (Vello-only); the node draws un-rotated.',\n )\n }\n if (node.clip != null) {\n push('node:clip', 'missing', 'The CPU reference ignores clip regions (Vello-only).')\n }\n if (node.blend && node.blend !== 'normal') {\n push(\n 'node:blend',\n 'degraded',\n `Blend mode '${node.blend}' composites as normal (src-over) on the CPU reference.`,\n )\n }\n if (node.kind?.type === 'video') {\n push('node:video', 'missing', 'The CPU reference does not decode video.')\n }\n if (Array.isArray(node.kind?.runs) && node.kind.runs.length > 0) {\n push(\n 'text:runs',\n 'degraded',\n 'Per-run text styling draws on the GPU path; the CPU reference draws the concatenated text in the base style.',\n )\n }\n }\n\n for (const fx of node.effects ?? []) {\n const kind = fx?.effect\n if (kind === 'light_wrap' && isPreview) {\n push(\n 'effect:light_wrap',\n 'missing',\n 'Light-wrap is export/native only — previews draw the node un-wrapped (graceful degrade).',\n )\n }\n if (kind === 'goo' && isCpu) {\n push('effect:goo', 'missing', 'Goo/metaball is GPU-only; the CPU reference skips it.')\n }\n }\n\n const gradient = node.kind?.gradient?.gradient\n if (gradient === 'fbm' && (isCpu || backend === 'preview-webgpu')) {\n push(\n 'gradient:fbm',\n 'degraded',\n 'fBm fractal-noise gradients degrade to a smooth gradient off the native GPU — judge on the native render.',\n )\n }\n\n node.children?.forEach((child, i) => visit(child, `${path}/${i}`))\n }\n visit(s.root, 'root')\n\n return out\n}\n\n/** True when `scene` renders identically to export on `backend`. */\nexport function matchesExport(\n scene: Scene,\n backend: RenderBackend,\n opts: DivergenceOpts = {},\n): boolean {\n return divergenceReport(scene, backend, opts).length === 0\n}\n","//! Glyph line — the ONE per-glyph text-layout primitive.\n//!\n//! SlotMachineRoll, KineticText(+wave) and MatrixDecode each re-implemented\n//! glyph layout (cursor loops, byte decoding, alignment math, baseline nudges)\n//! — which is exactly why their centering/positioning used to diverge. This\n//! module is the single path:\n//!\n//! - {@link layoutGlyphLine} — one line → positioned cells. MEASURED advances\n//! by default (kerning-accurate `glyphLayout`, letter-spacing folded in), or\n//! a fixed {@link GlyphLineOpts.cellAdvance} for column-locked reels (the\n//! slot machine's monospace cell).\n//! - {@link lineStartX} — the alignment anchor → left-edge x (left/center/right).\n//! - {@link lineTopY} — the house vertical-centering nudge (anchor − 0.6×size,\n//! half the 1.2 line box) every single-line text component uses.\n//!\n//! Components built on this inherit the placement contract (#1), real\n//! measurement (#2) and clip-aware timing (#3) for free — layout is no longer\n//! something a text component re-invents.\n\nimport { type GlyphInfo, type MeasureOpts, glyphLayout } from './text-metrics.js'\n\n/** Engine line-box height as a multiple of font size (typography crate). */\nexport const LINE_RATIO = 1.2\n\n/** One laid-out character cluster. */\nexport interface GlyphCell {\n /** The cluster's text (one user-perceived character). */\n ch: string\n /** Pen x of the cluster's left edge, relative to the line's left edge. */\n x: number\n /** Advance width to the next cluster (kerning + letter-spacing included). */\n width: number\n /** Index among ALL cells (spaces included) — the historical stagger index. */\n index: number\n /** Index among RENDERED (non-space) cells, or -1 for whitespace. */\n renderIndex: number\n /** True for whitespace cells (advance only; usually not drawn). */\n space: boolean\n}\n\n/** A laid-out single line. */\nexport interface GlyphLine {\n /** Every cluster, spaces included, left-to-right. */\n cells: GlyphCell[]\n /** The non-space cells (what actually draws). */\n rendered: GlyphCell[]\n /** Total advance width of the line (px). */\n width: number\n /** Line-box height (`fontSize × 1.2`). */\n height: number\n}\n\nexport interface GlyphLineOpts extends MeasureOpts {\n /** Fixed per-character advance instead of measured shaping — for column-\n * locked layouts (e.g. the slot-roll's estimated monospace cell). Receives\n * the character; returns its advance in px. */\n cellAdvance?: (ch: string) => number\n}\n\n/** Lay out one line of text as positioned glyph cells. Measured, kerning-\n * accurate advances by default (one `glyphLayout` call; estimate fallback\n * until the wasm engine warms); fixed `cellAdvance` when supplied. */\nexport function layoutGlyphLine(\n text: string,\n fontSize: number,\n opts: GlyphLineOpts = {},\n): GlyphLine {\n const { cellAdvance, ...measure } = opts\n const cells: GlyphCell[] = []\n let rendered = 0\n\n if (cellAdvance) {\n // Fixed-cell path: a simple cursor over user-perceived characters.\n let x = 0\n for (const ch of text) {\n const width = cellAdvance(ch)\n const space = ch.trim().length === 0\n cells.push({ ch, x, width, index: cells.length, renderIndex: space ? -1 : rendered, space })\n if (!space) rendered++\n x += width\n }\n } else {\n // Measured path: one kerning-accurate glyphLayout call. Byte offsets are\n // UTF-8; decode each cluster's bytes by range (JS strings are UTF-16).\n const clusters: GlyphInfo[] = glyphLayout(text, fontSize, measure)\n const bytes = new TextEncoder().encode(text)\n const decoder = new TextDecoder()\n for (const g of clusters) {\n const ch = decoder.decode(bytes.subarray(g.start, g.end))\n const space = ch.trim().length === 0\n cells.push({\n ch,\n x: g.x,\n width: g.advance,\n index: cells.length,\n renderIndex: space ? -1 : rendered,\n space,\n })\n if (!space) rendered++\n }\n }\n\n const last = cells[cells.length - 1]\n return {\n cells,\n rendered: cells.filter((c) => !c.space),\n width: last ? last.x + last.width : 0,\n height: fontSize * LINE_RATIO,\n }\n}\n\n/** Left-edge x of a line of `lineWidth` aligned about `anchorX` — the single\n * alignment formula ('center' centers on the anchor, 'right' ends at it,\n * 'left' starts at it). */\nexport function lineStartX(\n align: 'left' | 'center' | 'right',\n anchorX: number,\n lineWidth: number,\n): number {\n return align === 'center'\n ? anchorX - lineWidth / 2\n : align === 'right'\n ? anchorX - lineWidth\n : anchorX\n}\n\n/** Top y of a single line whose VERTICAL CENTER should sit at `anchorY` — the\n * house nudge (`anchor − 0.6×fontSize`, half the 1.2 line box), rounded like\n * every text component historically did. */\nexport function lineTopY(anchorY: number, fontSize: number): number {\n return Math.round(anchorY - fontSize * 0.6)\n}\n","//! Layout queries + single-line auto-fit — keep type ON the frame.\n//!\n//! The engine knows every glyph's advance (`measureText`, cosmic-text via wasm),\n//! but nothing used to CONNECT that knowledge to the frame: \"WEEKS OF WORK\" at\n//! 140px happily overflowed 1920px. Two tools close the loop:\n//!\n//! - {@link useResolvedBounds} — the layout QUERY: the measured box of a line in\n//! px AND as a fraction of the frame, plus an `overflows` verdict against the\n//! safe band. Authors (and the Studio agent) can ask \"how big is this, really?\"\n//! - {@link fitFontSize} / {@link useFittedFontSize} — the auto-FIT: scale a\n//! font size DOWN (never up) so the measured line cannot exceed a width cap.\n//! Components expose it as `fit=\"frame\"` (cap = frame minus the safe margins)\n//! and/or `maxWidth` (explicit px cap). Letter-spacing is scaled with the font\n//! size, so tracked display type fits faithfully.\n//!\n//! Fallback honesty: before the wasm engine warms (browser first paint), widths\n//! come from the glyph-count estimate — the fit then re-resolves when real\n//! metrics arrive (the same contract as `useTextMetrics`).\n\nimport { useVideoConfig } from '@onda-engine/react'\nimport { SAFE_MARGIN } from './placement.js'\nimport { type MeasureOpts, measureText, useTextMetricsReady } from './text-metrics.js'\n\n/** The resolved box of a measured line, px and frame-relative. */\nexport interface ResolvedBounds {\n /** Shaped line width (px). */\n width: number\n /** Line-box height (px). */\n height: number\n /** Width as a fraction of the frame width. */\n widthFrac: number\n /** Height as a fraction of the frame height. */\n heightFrac: number\n /** True when the line is wider than the frame's safe band\n * (`frameWidth × (1 − 2×margin)`). */\n overflows: boolean\n}\n\n/** Measure `content` against the live frame: px box + %-of-frame + an overflow\n * verdict against the safe band (`margin` per side, default the shared\n * {@link SAFE_MARGIN} = 10%). Loads the metrics engine in the browser and\n * re-renders when real metrics arrive. */\nexport function useResolvedBounds(\n content: string,\n fontSize: number,\n opts: MeasureOpts & { margin?: number } = {},\n): ResolvedBounds {\n useTextMetricsReady()\n const { width: frameW, height: frameH } = useVideoConfig()\n const { margin = SAFE_MARGIN, ...measure } = opts\n const m = measureText(content, fontSize, measure)\n return {\n width: m.width,\n height: m.height,\n widthFrac: frameW > 0 ? m.width / frameW : 0,\n heightFrac: frameH > 0 ? m.height / frameH : 0,\n overflows: m.width > frameW * (1 - 2 * margin),\n }\n}\n\n/** The largest font size ≤ `fontSize` at which `content` measures ≤ `maxWidth`\n * px. Pure + synchronous (uses whatever metrics `measureText` has). The\n * caller's `letterSpacing` (given at the ORIGINAL `fontSize`) is scaled\n * proportionally, so tracked type fits exactly. Never scales UP. */\nexport function fitFontSize(\n content: string,\n fontSize: number,\n maxWidth: number,\n opts: MeasureOpts = {},\n): number {\n if (!content || fontSize <= 0 || !Number.isFinite(maxWidth) || maxWidth <= 0) return fontSize\n let size = fontSize\n // Advances are ~linear in font size, so one ratio step lands ~exactly; the\n // loop absorbs shaping non-linearities (hinting/rounding) in a few nudges.\n for (let i = 0; i < 4; i++) {\n const letterSpacing =\n opts.letterSpacing !== undefined ? opts.letterSpacing * (size / fontSize) : undefined\n const w = measureText(content, size, { ...opts, letterSpacing }).width\n if (w <= maxWidth || size <= 1) return size\n size = Math.max(1, size * (maxWidth / w) * 0.999)\n }\n return size\n}\n\n/** Auto-fit options shared by the text-bearing components. */\nexport interface FitOpts {\n /** `'frame'` caps the line to the frame width minus the safe margins\n * (10% per side). Opt-in; default `'none'` (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px. Combines with `fit` (the smaller cap wins). */\n maxWidth?: number\n /** Safe-margin fraction per side for `fit: 'frame'` (default 0.1). */\n fitMargin?: number\n}\n\n/** Resolve the effective width cap in px for {@link FitOpts} against a frame\n * width — `undefined` when no fit is requested. */\nexport function fitMaxWidth(opts: FitOpts, frameWidth: number): number | undefined {\n const caps: number[] = []\n if (opts.maxWidth !== undefined && opts.maxWidth > 0) caps.push(opts.maxWidth)\n if (opts.fit === 'frame') caps.push(frameWidth * (1 - 2 * (opts.fitMargin ?? SAFE_MARGIN)))\n return caps.length > 0 ? Math.min(...caps) : undefined\n}\n\n/** Hook form of {@link fitFontSize} driven by {@link FitOpts}: returns the\n * (possibly reduced) font size for `content` against the live frame. Returns\n * `fontSize` untouched when no fit is requested. Loads the metrics engine in\n * the browser and re-renders when real metrics arrive. */\nexport function useFittedFontSize(\n content: string,\n fontSize: number,\n opts: MeasureOpts & FitOpts = {},\n): number {\n useTextMetricsReady()\n const { width: frameW } = useVideoConfig()\n const { fit, maxWidth, fitMargin, ...measure } = opts\n const cap = fitMaxWidth({ fit, maxWidth, fitMargin }, frameW)\n if (cap === undefined) return fontSize\n return fitFontSize(content, fontSize, cap, measure)\n}\n","//! Theme — brand tokens shared across @onda-engine/components.\n//!\n//! Set once with `<ThemeProvider theme={…}>` and every themed component reads its\n//! color/font defaults from it; an explicit prop on a component always wins. This\n//! is the lever ONDA Studio uses: the agent supplies one brand kit (colors,\n//! fonts, logo) and a whole composition comes out on-brand, without threading\n//! styling into every component.\n//!\n//! Mechanism: React Context (the scene graph has no CSS cascade, so this is the\n//! analogue of ondajs's CSS variables). It flows through `renderFrame` just like\n//! the frame context. With no provider, components use {@link defaultTheme}, so\n//! existing compositions render identically.\n//!\n//! Font note: the engine renders a font *family name*; the font file must still\n//! be loaded into the engine (`--font` on the CLI, or registered in the wasm\n//! engine). The theme names the family — it does not ship fonts.\n\nimport { type ReactNode, createContext, createElement, useContext } from 'react'\n\nexport interface Theme {\n /** Primary brand color — the earned accent (bars, rules, highlights, glows). */\n accent: string\n /** A soft, translucent accent for fills/washes behind content. Must be an\n * engine color (`#rrggbbaa`), not a CSS `rgba()` string — it is used directly\n * as a scene fill. */\n accentSoft: string\n /** Primary text. */\n text: string\n /** Secondary / supporting text. */\n textMuted: string\n /** Canvas background. */\n background: string\n /** Cards / panels / surfaces. */\n surface: string\n /** Hairlines / borders. */\n border: string\n /** Extra series colors for multi-bar / multi-slice charts (after the accent). */\n palette: string[]\n /** Body font family (a *loaded* family name; `undefined` = the engine default). */\n fontFamily?: string\n /** Heading font family (falls back to `fontFamily`). */\n headingFamily?: string\n /** Monospace font family for code (falls back to a generic mono). */\n monoFamily?: string\n /** Base corner radius in px. */\n radius: number\n /** Brand logo, for `LogoSting` / watermarks / outros. */\n logo?: { src?: string; markup?: string }\n}\n\n/** The Onda house theme — the values components shipped with before theming. */\nexport const defaultTheme: Theme = {\n accent: '#e85494',\n accentSoft: '#e854942e',\n text: '#f2f2f4',\n textMuted: '#8e8e98',\n background: '#0a0d17',\n surface: '#121217',\n border: '#26262c',\n palette: ['#8e8e98', '#2974f2', '#e6b450', '#6bbf8a'],\n fontFamily: undefined,\n headingFamily: undefined,\n monoFamily: undefined,\n radius: 14,\n}\n\nconst ThemeContext = createContext<Theme>(defaultTheme)\n\n/** Read the active theme. Returns {@link defaultTheme} when there's no provider. */\nexport function useTheme(): Theme {\n return useContext(ThemeContext)\n}\n\nexport interface ThemeProviderProps {\n /** Partial overrides merged over the inherited (or default) theme. */\n theme?: Partial<Theme>\n children?: ReactNode\n}\n\n/** Provide a theme to descendant components. Merges over any parent theme, so\n * providers can nest (a section can tweak a few tokens). */\nexport function ThemeProvider({ theme, children }: ThemeProviderProps) {\n const parent = useContext(ThemeContext)\n const value = theme ? { ...parent, ...theme } : parent\n return createElement(ThemeContext.Provider, { value }, children)\n}\n","//! Named motion patterns — the Onda choreography vocabulary.\n//!\n//! Ported from ondajs (`lib/choreography.ts`). Each helper is a pure function of\n//! frame/fps. The one change for `@onda-engine/react`: where ondajs returns a CSS\n//! `{ opacity, transform }` to spread onto a `<div>`, these return a numeric\n//! {@link Motion} (`{ opacity, x, y, scaleX, scaleY }`) to spread onto a scene\n//! node (`<Group>`) — no string parsing, and it composes with the GPU transform.\n//!\n//! Atomic entries: entryFade · entrySlide · entryScale\n//! Named composite: entryFadeRise (the workhorse — opacity + rise)\n//! Exits (faster, on HOUSE_EASE — an exit doesn't settle):\n//! exitFade · exitSlide · exitScale · exitFadeFall\n//! Special: heroReveal (two-phase landing) · stateSwap (in-place crossfade)\n//!\n//! All patterns accept `delay` so callers can stagger via `staggerFrames(index)`.\n\nimport { interpolate, spring } from '@onda-engine/react'\nimport { HOUSE_EASE } from './easing.js'\nimport { DURATION, OVERSHOOT, SPRING_SMOOTH } from './motion.js'\nimport { type TimeInput, framesOf } from './time.js'\n\n/** Numeric motion for a scene node. Spread the relevant fields onto a `<Group>`:\n * `x`/`y` (px translate), `scaleX`/`scaleY` (1 = identity), `opacity` (0..1),\n * `rotation` (degrees; optional — only keyframe animation emits it). */\nexport type Motion = {\n opacity: number\n x: number\n y: number\n scaleX: number\n scaleY: number\n rotation?: number\n}\n\nconst REST: Motion = { opacity: 1, x: 0, y: 0, scaleX: 1, scaleY: 1, rotation: 0 }\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport type PatternInput = {\n frame: number\n fps: number\n /** Frames (number) or a time string ('0.5s', '500ms', '12f'). */\n delay?: TimeInput\n /** Frames (number) or a time string ('0.5s', '500ms', '12f'). */\n durationInFrames?: TimeInput\n travelPx?: number\n}\n\n/** Pure opacity 0 → 1 on {@link SPRING_SMOOTH}. No translate, no scale — the\n * simplest reveal, for elements where presence alone changes. */\nexport const entryFade = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n}: Omit<PatternInput, 'travelPx'>): Motion => {\n const delay = framesOf(delayIn, fps, 0)\n const durationInFrames = framesOf(durationIn, fps, DURATION.base)\n const progress = spring({ frame: frame - delay, fps, config: SPRING_SMOOTH, durationInFrames })\n const opacity = interpolate(progress, [0, 1], [0, 1], CLAMP)\n return { ...REST, opacity }\n}\n\n/** Direction-parameterized translate + fade on {@link SPRING_SMOOTH}. `direction`\n * names the *settling* direction — `'up'` rises into place (origin below),\n * `'left'` slides in from the right. Travel is the 12–24px Onda envelope. */\nexport const entrySlide = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n direction,\n distance = 12,\n}: Omit<PatternInput, 'travelPx'> & {\n direction: 'up' | 'down' | 'left' | 'right'\n distance?: number\n}): Motion => {\n const delay = framesOf(delayIn, fps, 0)\n const durationInFrames = framesOf(durationIn, fps, DURATION.base)\n const progress = spring({ frame: frame - delay, fps, config: SPRING_SMOOTH, durationInFrames })\n const opacity = interpolate(progress, [0, 1], [0, 1], CLAMP)\n // Positive offset at progress 0 for 'up'/'left' (starts below / right of rest).\n const isVertical = direction === 'up' || direction === 'down'\n const startSign = direction === 'up' || direction === 'left' ? 1 : -1\n const offset = interpolate(progress, [0, 1], [startSign * distance, 0], CLAMP)\n return {\n ...REST,\n opacity,\n x: isVertical ? 0 : offset,\n y: isVertical ? offset : 0,\n }\n}\n\n/** Opacity + scale from N → 1 on {@link SPRING_SMOOTH}. Restrained on purpose:\n * default `from` is `0.9`; below ~0.85 reads as dramatic zoom.\n *\n * Note: scene scale is about the node's local origin (0,0), not its center —\n * for centered growth, wrap a subtree whose origin sits where you want the\n * scale anchored. (Per-node transform-origin is a planned engine feature.) */\nexport const entryScale = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n from = 0.9,\n}: Omit<PatternInput, 'travelPx'> & { from?: number }): Motion => {\n const delay = framesOf(delayIn, fps, 0)\n const durationInFrames = framesOf(durationIn, fps, DURATION.base)\n const progress = spring({ frame: frame - delay, fps, config: SPRING_SMOOTH, durationInFrames })\n const opacity = interpolate(progress, [0, 1], [0, 1], CLAMP)\n const scale = interpolate(progress, [0, 1], [from, 1], CLAMP)\n return { ...REST, opacity, scaleX: scale, scaleY: scale }\n}\n\n/** The default entrance — translate up + fade in on {@link SPRING_SMOOTH} at\n * `DURATION.base`. Appropriate for ~80% of entering elements. */\nexport const entryFadeRise = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n travelPx = 12,\n}: PatternInput): Motion => {\n const delay = framesOf(delayIn, fps, 0)\n const durationInFrames = framesOf(durationIn, fps, DURATION.base)\n const progress = spring({ frame: frame - delay, fps, config: SPRING_SMOOTH, durationInFrames })\n const opacity = interpolate(progress, [0, 1], [0, 1], CLAMP)\n const y = interpolate(progress, [0, 1], [travelPx, 0], CLAMP)\n return { ...REST, opacity, y }\n}\n\n/** Plain fade OUT — opacity 1 → 0 on {@link HOUSE_EASE}, no transform. The exit\n * counterpart to {@link entryFade}. */\nexport const exitFade = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n}: Omit<PatternInput, 'travelPx' | 'fps'> & { fps?: number }): Motion => {\n const delay = framesOf(delayIn, fps ?? 30, 0)\n const durationInFrames = framesOf(durationIn, fps ?? 30, DURATION.fast)\n const progress = interpolate(frame - delay, [0, durationInFrames], [0, 1], {\n ...CLAMP,\n easing: HOUSE_EASE,\n })\n return { ...REST, opacity: 1 - progress }\n}\n\n/** The default exit — translate down + fade out at `DURATION.fast` on\n * {@link HOUSE_EASE}. Exits are ~30% faster than entries. */\nexport const exitFadeFall = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n travelPx = 8,\n}: Omit<PatternInput, 'fps'> & { fps?: number }): Motion => {\n const delay = framesOf(delayIn, fps ?? 30, 0)\n const durationInFrames = framesOf(durationIn, fps ?? 30, DURATION.fast)\n const progress = interpolate(frame - delay, [0, durationInFrames], [0, 1], {\n ...CLAMP,\n easing: HOUSE_EASE,\n })\n return { ...REST, opacity: 1 - progress, y: progress * travelPx }\n}\n\n/** Directional fade + translate OUT — the exit counterpart to {@link entrySlide}.\n * `direction` names where the element LEAVES toward. On {@link HOUSE_EASE}. */\nexport const exitSlide = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n direction,\n distance = 12,\n}: Omit<PatternInput, 'travelPx' | 'fps'> & {\n fps?: number\n direction: 'up' | 'down' | 'left' | 'right'\n distance?: number\n}): Motion => {\n const delay = framesOf(delayIn, fps ?? 30, 0)\n const durationInFrames = framesOf(durationIn, fps ?? 30, DURATION.fast)\n const progress = interpolate(frame - delay, [0, durationInFrames], [0, 1], {\n ...CLAMP,\n easing: HOUSE_EASE,\n })\n const isVertical = direction === 'up' || direction === 'down'\n const endSign = direction === 'down' || direction === 'right' ? 1 : -1\n const offset = interpolate(progress, [0, 1], [0, endSign * distance], CLAMP)\n return {\n ...REST,\n opacity: 1 - progress,\n x: isVertical ? 0 : offset,\n y: isVertical ? offset : 0,\n }\n}\n\n/** Fade + scale OUT — the exit counterpart to {@link entryScale}. Scales from 1\n * to `to` (default 0.9) while fading, on {@link HOUSE_EASE}. */\nexport const exitScale = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n to = 0.9,\n}: Omit<PatternInput, 'travelPx' | 'fps'> & { fps?: number; to?: number }): Motion => {\n const delay = framesOf(delayIn, fps ?? 30, 0)\n const durationInFrames = framesOf(durationIn, fps ?? 30, DURATION.fast)\n const progress = interpolate(frame - delay, [0, durationInFrames], [0, 1], {\n ...CLAMP,\n easing: HOUSE_EASE,\n })\n const scale = interpolate(progress, [0, 1], [1, to], CLAMP)\n return { ...REST, opacity: 1 - progress, scaleX: scale, scaleY: scale }\n}\n\n/** The two-phase hero landing — the Onda signature pattern. Phase 1: a\n * {@link SPRING_SMOOTH} translate + fade over the full duration. Phase 2: a 3%\n * scale overshoot ({@link OVERSHOOT}) near the end that settles back to 1.0. The\n * two read as one continuous landing. Reserve for ≤1 element per scene. */\nexport const heroReveal = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n travelPx = 16,\n}: PatternInput): Motion => {\n const delay = framesOf(delayIn, fps, 0)\n const durationInFrames = framesOf(durationIn, fps, DURATION.slow)\n const local = frame - delay\n const rise = spring({ frame: local, fps, config: SPRING_SMOOTH, durationInFrames })\n const opacity = interpolate(rise, [0, 1], [0, 1], CLAMP)\n const y = interpolate(rise, [0, 1], [travelPx, 0], CLAMP)\n // Triangle wave 0 → OVERSHOOT → 0 across ~10 frames, kicked off 4 frames\n // before phase 1 nominally completes so the landing reads as one motion.\n const landStart = durationInFrames - 4\n const scaleBump = interpolate(\n local,\n [landStart, landStart + 5, landStart + 10],\n [0, OVERSHOOT, 0],\n CLAMP,\n )\n const scale = 1 + scaleBump\n return { ...REST, opacity, y, scaleX: scale, scaleY: scale }\n}\n\n/** In-place state swap — for a value/label changing while its container stays\n * put. Crossfade on {@link HOUSE_EASE}. Returns `{ outOpacity, inOpacity }` —\n * apply to the old and new values (both rendered, layered, so it stays put). */\nexport const stateSwap = ({\n frame,\n fps,\n delay: delayIn,\n durationInFrames: durationIn,\n}: Omit<PatternInput, 'travelPx' | 'fps'> & { fps?: number }): {\n outOpacity: number\n inOpacity: number\n} => {\n const delay = framesOf(delayIn, fps ?? 30, 0)\n const durationInFrames = framesOf(durationIn, fps ?? 30, DURATION.fast)\n const local = frame - delay\n const half = durationInFrames / 2\n const outOpacity = interpolate(local, [0, half], [1, 0], { ...CLAMP, easing: HOUSE_EASE })\n const inOpacity = interpolate(local, [half, durationInFrames], [0, 1], {\n ...CLAMP,\n easing: HOUSE_EASE,\n })\n return { outOpacity, inOpacity }\n}\n","//! Deterministic React hooks for Onda components.\n//!\n//! Ported from ondajs (`lib/hooks.ts`). Every hook reads time via\n//! `useCurrentFrame()` and config via `useVideoConfig()`, then returns a pure\n//! function of the frame — no `useState`/`useEffect` to drive animation. They\n//! exist to remove the `const frame = useCurrentFrame()` + interpolate\n//! boilerplate every component otherwise repeats.\n\nimport { interpolate, spring, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { type Motion, entryFade, entryFadeRise, entryScale, entrySlide } from './choreography.js'\nimport { HOUSE_EASE } from './easing.js'\nimport { DURATION, SPRING_SMOOTH, SPRING_SNAPPY, STAGGER, staggerFrames } from './motion.js'\nimport { type TimeInput, framesOf } from './time.js'\n\n/** The entrance flavors {@link useEntrance} can produce. */\nexport type EntranceType = 'fade' | 'rise' | 'scale' | 'slide'\n\n/** Shared entrance options. `type` picks the choreography pattern. */\nexport type EntranceOptions = {\n type?: EntranceType\n delay?: TimeInput\n durationInFrames?: TimeInput\n /** For `type: 'slide'` — the settling direction. */\n direction?: 'up' | 'down' | 'left' | 'right'\n /** For `type: 'slide'` — travel distance in px (12–24 envelope). */\n distance?: number\n /** For `type: 'scale'` — starting scale (default 0.9). */\n from?: number\n}\n\n// Internal: compute an entrance Motion given an explicit frame/fps. Kept pure so\n// useStaggeredEntrance can call it per-index after reading the frame once.\nfunction computeEntrance(frame: number, fps: number, opts: EntranceOptions): Motion {\n const { type = 'rise', direction = 'up', distance = 12, from = 0.9 } = opts\n const delay = framesOf(opts.delay, fps, 0)\n const durationInFrames = framesOf(opts.durationInFrames, fps, DURATION.base)\n switch (type) {\n case 'fade':\n return entryFade({ frame, fps, delay, durationInFrames })\n case 'scale':\n return entryScale({ frame, fps, delay, durationInFrames, from })\n case 'slide':\n return entrySlide({ frame, fps, delay, durationInFrames, direction, distance })\n default:\n return entryFadeRise({ frame, fps, delay, durationInFrames })\n }\n}\n\n/** The workhorse entrance hook — returns the {@link Motion} for the current\n * frame. Dispatches to the choreography vocabulary so the fingerprint stays\n * consistent. Spread the relevant fields onto a `<Group>`. */\nexport function useEntrance(opts: EntranceOptions = {}): Motion {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n return computeEntrance(frame, fps, opts)\n}\n\n/** Call once, get a function that yields the entrance {@link Motion} for sibling\n * `i`, staggered by {@link STAGGER}. The clean way to animate a list/grid\n * without calling a hook in a loop. */\nexport function useStaggeredEntrance(\n opts: EntranceOptions & { increment?: TimeInput } = {},\n): (index: number) => Motion {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const { increment, delay, ...rest } = opts\n const incrementFrames = framesOf(increment, fps, STAGGER)\n const delayFrames = framesOf(delay, fps, 0)\n return (index: number) =>\n computeEntrance(frame, fps, {\n ...rest,\n delay: delayFrames + staggerFrames(index, incrementFrames),\n })\n}\n\n/** The house spring value (0→1) for the current frame — the one-liner most\n * components reach for to drive a custom interpolation. */\nexport function useSpringValue(\n opts: { delay?: TimeInput; durationInFrames?: TimeInput; snappy?: boolean } = {},\n): number {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const { snappy = false } = opts\n const delay = framesOf(opts.delay, fps, 0)\n const durationInFrames = framesOf(opts.durationInFrames, fps, DURATION.base)\n return spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: snappy ? SPRING_SNAPPY : SPRING_SMOOTH,\n durationInFrames,\n })\n}\n\n/** Normalized progress (0→1) across a window, eased with {@link HOUSE_EASE} by\n * default. For opacity/color ramps and anything that isn't physical motion\n * (use {@link useSpringValue} for position/scale). */\nexport function useSceneProgress(\n opts: { delay?: TimeInput; durationInFrames?: TimeInput; eased?: boolean } = {},\n): number {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const { eased = true } = opts\n const delay = framesOf(opts.delay, fps, 0)\n const durationInFrames = framesOf(opts.durationInFrames, fps, DURATION.base)\n return interpolate(frame - delay, [0, durationInFrames], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n ...(eased ? { easing: HOUSE_EASE } : {}),\n })\n}\n\n/** How many units (chars or words) of a reveal are visible at the current frame.\n * Drives typewriter / decode / slot-roll effects. Linear by default — a steady\n * cadence reads better than an eased one. Returns an integer in `[0, length]`. */\nexport function useTextReveal(opts: {\n length: number\n delay?: TimeInput\n durationInFrames?: TimeInput\n eased?: boolean\n}): number {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const { length, eased = false } = opts\n const delay = framesOf(opts.delay, fps, 0)\n const durationInFrames = framesOf(opts.durationInFrames, fps, DURATION.slower)\n const raw = interpolate(frame - delay, [0, durationInFrames], [0, length], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n ...(eased ? { easing: HOUSE_EASE } : {}),\n })\n return Math.floor(raw)\n}\n","//! Audio analysis for audio-reactive components (e.g. {@link AudioVisualizer}).\n//!\n//! Lazily loads `@onda-engine/wasm-audio` — the SAME decode + FFT the native `onda\n//! export` runs — decodes an audio file once, and exposes a per-frame spectrum.\n//! Async + cached + shared across components; callers fall back to procedural\n//! data until it's ready, so the composition never blocks. Browser only (the\n//! export path warms the cache separately before the synchronous frame render).\n\nimport { useVideoConfig } from '@onda-engine/react'\nimport { useEffect, useState } from 'react'\n\n/** `@onda-engine/wasm-audio`'s `Beats` handle — beat/onset/tempo analysis in frame units. */\nexport interface BeatsHandle {\n readonly tempo: number\n readonly beats: Uint32Array\n readonly onsets: Uint32Array\n readonly onsetEnv: Float32Array\n}\n\n/** Beat / onset / tempo analysis of a clip, in VIDEO-FRAME units — for syncing motion\n * to the music. Returned by {@link useAudioBeats}; pair with {@link beatPulse}. */\nexport interface Beats {\n /** Estimated tempo, beats per minute (0 if undetectable). */\n tempo: number\n /** Frame indices on the beat grid (ascending). */\n beats: number[]\n /** Frame indices of picked onsets — any transient (drum hit, note, accent). */\n onsets: number[]\n /** Per-frame onset strength `0..1` (one value per frame) — a continuous envelope. */\n onsetEnv: Float32Array\n}\n\n/** Minimal shape of `@onda-engine/wasm-audio`'s `AudioAnalyzer` — kept local so this\n * file doesn't hard-depend on the generated wasm types at build time. */\nexport interface AudioAnalyzer {\n /** Per-frame spectrum: flat, frame-major (`frames * bands`), each `0..1`,\n * low→high. Deterministic — identical to the native export. */\n spectrogram(fps: number, frames: number, bands: number): Float32Array\n /** Beat / onset / tempo analysis over `frames` frames at `fps`. Deterministic. */\n beats(fps: number, frames: number): BeatsHandle\n /** Clip duration in seconds. */\n duration_secs(): number\n /** Decoded sample rate (Hz). */\n sample_rate(): number\n}\n\ninterface WasmAudio {\n default: (opts?: unknown) => Promise<unknown>\n AudioAnalyzer: new (bytes: Uint8Array, extHint: string) => AudioAnalyzer\n}\n\n// Resolved analyzers by src (null = load failed → procedural fallback). Shared.\nconst analyzers = new Map<string, AudioAnalyzer | null>()\nconst inflight = new Map<string, Promise<void>>()\nlet modulePromise: Promise<WasmAudio> | null = null\n\n/** Load + init the wasm module once. `init()` with no arg auto-locates the\n * `.wasm` next to the JS module (handled by Vite/webpack/esbuild). */\nfunction loadModule(): Promise<WasmAudio> {\n if (!modulePromise) {\n modulePromise = (async () => {\n const mod = (await import('@onda-engine/wasm-audio')) as unknown as WasmAudio\n await mod.default()\n return mod\n })()\n }\n return modulePromise\n}\n\nfunction extOf(src: string): string {\n const path = src.split(/[?#]/)[0] ?? src\n const dot = path.lastIndexOf('.')\n return dot >= 0 ? path.slice(dot + 1).toLowerCase() : ''\n}\n\nasync function loadAnalyzer(src: string): Promise<void> {\n try {\n const mod = await loadModule()\n const res = await fetch(src)\n if (!res.ok) throw new Error(`audio fetch failed: ${res.status}`)\n const bytes = new Uint8Array(await res.arrayBuffer())\n analyzers.set(src, new mod.AudioAnalyzer(bytes, extOf(src)))\n } catch (e) {\n if (typeof console !== 'undefined') {\n console.warn(`[onda] couldn't load audio for the visualizer: ${src}\\n ${String(e)}`)\n }\n analyzers.set(src, null) // fall back to procedural\n } finally {\n inflight.delete(src)\n }\n}\n\n/** Load + decode `src` (cached + shared) and return its analyzer once ready, or\n * `null` while loading / on failure (the caller uses a procedural fallback). The\n * component re-renders when the analyzer becomes available. Browser only —\n * returns `null` outside a browser (export preloads the cache separately). */\nexport function useAudioData(src: string | undefined): AudioAnalyzer | null {\n const [, bump] = useState(0)\n useEffect(() => {\n if (!src || typeof window === 'undefined' || analyzers.has(src)) return\n let cancelled = false\n let p = inflight.get(src)\n if (!p) {\n p = loadAnalyzer(src)\n inflight.set(src, p)\n }\n p.then(() => {\n if (!cancelled) bump((v) => v + 1)\n })\n return () => {\n cancelled = true\n }\n }, [src])\n return src ? (analyzers.get(src) ?? null) : null\n}\n\n// Beat analysis is a whole-clip computation — memoize per (src, fps, frames).\nconst beatCache = new Map<string, Beats>()\n\n/** Analyze `src` for BEATS / onsets / tempo (frame units, from the composition's fps +\n * duration) so you can sync motion to the music. Returns `null` while the audio loads\n * or on failure (browser only — the export path preloads). Pair with {@link beatPulse}:\n * `scaleX={1 + 0.3 * beatPulse(frame, b.beats)}` punches an element on every beat.\n *\n * For deterministic export an agent can instead bake the `beats` array into the\n * composition as a constant and use the pure helpers directly. */\nexport function useAudioBeats(src: string | undefined): Beats | null {\n const analyzer = useAudioData(src)\n const { fps, durationInFrames } = useVideoConfig()\n if (!src || !analyzer) return null\n const key = `${src}@${fps}/${durationInFrames}`\n let cached = beatCache.get(key)\n if (!cached) {\n const raw = analyzer.beats(fps, durationInFrames)\n cached = {\n tempo: raw.tempo,\n beats: Array.from(raw.beats),\n onsets: Array.from(raw.onsets),\n onsetEnv: raw.onsetEnv,\n }\n beatCache.set(key, cached)\n }\n return cached\n}\n\n/** Frames since the most recent beat at or before `frame` (`Infinity` before the first).\n * `beats` must be ascending (as {@link useAudioBeats} returns it). */\nexport function framesSinceBeat(frame: number, beats: readonly number[]): number {\n let last = Number.NEGATIVE_INFINITY\n for (const b of beats) {\n if (b <= frame) last = b\n else break\n }\n return frame - last\n}\n\n/** A `1 → 0` PUNCH that fires on each beat and decays over `decay` frames — the core\n * audio-sync primitive. Drive a scale / opacity / glow with it so the element hits on\n * the beat: `scaleX={1 + amount * beatPulse(frame, beats)}`. */\nexport function beatPulse(frame: number, beats: readonly number[], decay = 6): number {\n const since = framesSinceBeat(frame, beats)\n if (!Number.isFinite(since) || since < 0) return 0\n return Math.max(0, 1 - since / Math.max(1, decay))\n}\n\n/** True when `frame` is on a beat (within `tolerance` frames) — for hard cuts/swaps. */\nexport function isBeat(frame: number, beats: readonly number[], tolerance = 0): boolean {\n return beats.some((b) => Math.abs(b - frame) <= tolerance)\n}\n","//! AudioClip — audio scheduling for a composition. Ported from ondajs.\n//!\n//! Emits a non-visual `<Audio>` node (`@onda-engine/react`): the player plays it during\n//! preview (synced to play/pause + scrub, with the player's volume), and it rides\n//! in the scene graph so export can mux it. v1 wires `src` + `startAt` (source\n//! trim) + `volume`/`gainDb`; the fade envelope, `loop`, `endAt`, and\n//! `playbackRate` are accepted for API parity but not yet applied to playback.\n\nimport { Audio, useVideoConfig } from '@onda-engine/react'\nimport type { TimeInput } from '../time.js'\n\n/** Time spec — seconds (number) or a string like `\"0:04\"`, `\"30s\"`, `\"500ms\"`, `\"90f\"`. */\nexport type TimeSpec = string | number\n\nexport interface AudioClipProps {\n /** URL or path to the audio file. AAC-in-MP4 or WAV preferred. */\n src?: string\n /**\n * Where to start in the source audio. Time spec — `\"0:04\"`, `\"30s\"`,\n * `\"500ms\"`, `\"90f\"`, or a raw number of seconds.\n */\n startAt?: TimeSpec\n /**\n * Where to stop in the source. Same time spec as `startAt`. When omitted,\n * plays to the source's end. Required for `loop`. (Not yet applied in preview.)\n */\n endAt?: TimeSpec\n /** Amplitude volume `0..1`. */\n volume?: number\n /**\n * Advanced gain in dB. When set, wins over `volume`. Converted via\n * `10 ** (dB / 20)`: `0` = unity, `-6` ≈ 0.5, `-12` ≈ 0.25, `-20` ≈ 0.1.\n */\n gainDb?: number\n /**\n * Apply an entry/exit volume envelope. Default `true`. (Not yet applied in\n * preview; accepted for API parity.)\n */\n fade?: boolean\n /** Frames the fade-in / fade-out takes. Default 2 (~67ms @ 30fps). */\n fadeDuration?: TimeInput\n /** Loop the trimmed clip. Requires `endAt`. (Not yet applied in preview.) */\n loop?: boolean\n /** Mute the clip. */\n muted?: boolean\n /** Playback speed. (Not yet applied in preview.) */\n playbackRate?: number\n /** Acceptable time-shift threshold before resync (seconds). */\n acceptableTimeShiftSeconds?: number\n}\n\n/** Resolve a {@link TimeSpec} to seconds (`90f` uses `fps`). */\nfunction toSeconds(t: TimeSpec | undefined, fps: number): number {\n if (t === undefined) return 0\n if (typeof t === 'number') return Math.max(0, t)\n const s = t.trim()\n const colon = s.match(/^(\\d+):(\\d+(?:\\.\\d+)?)$/) // \"M:SS\"\n if (colon) return Number.parseInt(colon[1] ?? '0', 10) * 60 + Number.parseFloat(colon[2] ?? '0')\n if (s.endsWith('ms')) return Number.parseFloat(s) / 1000\n if (s.endsWith('f')) return Number.parseFloat(s) / Math.max(1, fps)\n if (s.endsWith('s')) return Number.parseFloat(s)\n const n = Number.parseFloat(s)\n return Number.isFinite(n) ? Math.max(0, n) : 0\n}\n\n/**\n * Schedule an audio clip. Plays from the composition start (place inside a\n * `<Sequence>` to offset — Sequence-relative start is a follow-up), trimming the\n * source by `startAt`, at `volume` (or `gainDb`). Emits a `<Audio>` node, which\n * draws nothing; the player plays it for preview.\n */\nexport function AudioClip({\n src = 'https://www.w3schools.com/html/horse.mp3',\n startAt = 0,\n volume = 1,\n gainDb,\n muted = false,\n}: AudioClipProps = {}) {\n const { fps } = useVideoConfig()\n const startAtSecs = toSeconds(startAt, fps)\n const gain = gainDb !== undefined ? 10 ** (gainDb / 20) : volume\n return <Audio src={src} start={0} startAt={startAtSecs} volume={muted ? 0 : gain} />\n}\n","//! AudioVisualizer — an audio-spectrum visualizer with selectable styles.\n//! Ported from ondajs (`audio-visualizer`) and expanded with multiple render\n//! styles via the `type` prop: `bars`, `mirrored`, `waveform`, `radial`, `dots`.\n//!\n//! Pass `src` to drive the bars with REAL audio: `@onda-engine/wasm-audio` decodes the\n//! file and computes a per-frame FFT spectrum — the same analysis the native\n//! `onda export` runs, so preview and export match. Without `src` (or while the\n//! audio loads) it falls back to a deterministic PROCEDURAL spectrum: value noise\n//! (`noise2D`) plus sines with a low-bin tilt so it reads like music (bass-heavy\n//! left). Both paths feed the SAME amplitude array (`amps`), so all five styles\n//! render from one seam.\n//!\n//! Layout: the visualizer has FIXED dimensions and is centered by computing its\n//! top-left offset from the composition size — NOT a `<Flex>`. Each band animates\n//! every frame, so a layout container would reflow (jiggle) as the measured bbox\n//! grew; geometry is placed by explicit `x`/`y` inside one `<Group>` instead.\n//!\n//! Backend caveat: gradients, `<Path>`, and `rotation` render only on the\n//! Vello/GPU backend (the gallery's default). The CPU reference collapses a\n//! gradient to its FIRST stop, skips paths, and ignores rotation — so `bars`,\n//! `mirrored`, and `dots` degrade gracefully there, while `waveform` (a path) and\n//! `radial` (rotation) are GPU-only niceties.\n\nimport {\n Audio,\n Ellipse,\n Group,\n Path,\n Rect,\n linearGradient,\n noise2D,\n useCurrentFrame,\n useVideoConfig,\n variantSeed,\n} from '@onda-engine/react'\nimport { type ReactElement, useMemo } from 'react'\nimport { useAudioData } from '../audio.js'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\n/** Visualizer render style. Every style draws from the same amplitude array, so\n * switching `type` is purely a change of geometry. */\nexport type AudioVisualizerType = 'bars' | 'mirrored' | 'waveform' | 'radial' | 'dots'\n\nexport interface AudioVisualizerProps {\n /**\n * Render style (default `'bars'`):\n * - `bars` — classic vertical frequency bars.\n * - `mirrored` — bars mirrored around the centre line (symmetric EQ).\n * - `waveform` — a smooth filled ribbon around the centre line.\n * - `radial` — bars radiating from a centre ring (circular spectrum).\n * - `dots` — an LED dot-matrix meter with a brighter peak dot.\n */\n type?: AudioVisualizerType\n /**\n * Audio file URL to drive the bars with REAL frequency data (decoded + FFT'd by\n * `@onda-engine/wasm-audio` — identical spectra in preview and export). Omit for the\n * built-in procedural animation. For the browser preview the source must be\n * same-origin or CORS-enabled; `onda export` accepts any direct URL. When set,\n * the player also PLAYS the audio (use the volume/mute control to silence it).\n */\n src?: string\n /** Number of frequency bands. */\n barCount?: number\n /**\n * Bar color. Pass a single hex string for a one-tone visualizer, or a\n * two-entry array `[top, bottom]` for a vertical gradient ramp. The FIRST\n * entry is the meaningful color on the CPU backend (see header). (default:\n * theme `accent` for the top, theme `palette[1]` for the bottom)\n */\n color?: string | string[]\n /** Overall width of the visualizer, in px. */\n width?: number\n /** Overall height of the visualizer (the tallest a band can reach), in px. */\n height?: number\n /** Vertical placement of the bars within `height` (`bars` style only). */\n align?: 'top' | 'middle' | 'bottom'\n /** Pixel gap between adjacent bars. */\n gap?: number\n /** Bar corner radius in px (also the minimum bar height so idle bars read) (default: theme `radius`). */\n barRadius?: number\n /** Animation speed multiplier for the fake spectrum's drift. */\n speed?: number\n /** Deterministic seed for the fake spectrum. */\n seed?: number | string\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Frames before the visualizer fades/grows in. */\n delay?: TimeInput\n /** Frames for the entrance grow-in. */\n durationInFrames?: TimeInput\n}\n\n/** Two-entry [top, bottom] color ramp from the `color` prop (single string\n * becomes [color, color]; arrays are clamped to their first two entries with\n * defensive fallbacks). */\nfunction toColorRamp(color: string | string[]): [string, string] {\n if (Array.isArray(color)) {\n const top = color[0] ?? '#d96b82'\n const bottom = color[1] ?? top\n return [top, bottom]\n }\n return [color, color]\n}\n\nexport function AudioVisualizer({\n type = 'bars',\n src,\n barCount = 48,\n color: colorProp,\n width = 640,\n height = 160,\n align = 'middle',\n gap = 4,\n barRadius: barRadiusProp,\n speed = 1,\n seed: seedProp = 1,\n variant,\n delay = 0,\n durationInFrames = DURATION.slow,\n}: AudioVisualizerProps) {\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const frame = useCurrentFrame()\n const {\n width: compWidth,\n height: compHeight,\n fps,\n durationInFrames: compFrames,\n } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? [theme.accent, theme.palette[1] ?? '#7c5ce5']\n const barRadius = barRadiusProp ?? theme.radius\n\n const n = Math.max(1, Math.floor(barCount))\n\n // Bar slot = bar width + gap. Solve for a bar width that exactly fills the\n // row: n bars + (n - 1) gaps span `width`.\n const totalGap = gap * Math.max(0, n - 1)\n const barWidth = Math.max(1, (width - totalGap) / n)\n const slot = barWidth + gap\n\n // Center the fixed-size visualizer in the composition (no layout container, so\n // the per-frame size growth never triggers a reflow).\n const originX = Math.round((compWidth - width) / 2)\n const originY = Math.round((compHeight - height) / 2)\n\n // Entrance: a single house-spring 0→1 that grows the bands in and fades the\n // group in. opacity on the group is layout-safe; we only multiply per-band\n // sizes, so no Flex reflow concern (there's no Flex here).\n const entrance = useSpringValue({ delay, durationInFrames })\n\n // Animation phase. Dividing the frame by a constant sets the drift frequency;\n // `speed` scales it. Kept in noise-input units (noise2D fades between integer\n // lattice points, so a ~0.15/frame step gives smooth, lively motion).\n const t = frame * 0.15 * speed\n\n const [topColor, bottomColor] = toColorRamp(color)\n // Softer/transparent tail so single-color ramps still glow.\n const tailColor =\n Array.isArray(color) && color.length > 1 ? bottomColor : withAlpha(topColor, 0x4d)\n\n // The amplitudes (0..1, low→high) every style renders from. With `src`, these\n // are REAL FFT magnitudes (decoded + analyzed by @onda-engine/wasm-audio, cached for\n // the whole clip and indexed by frame); otherwise a deterministic procedural\n // spectrum. While the audio loads, the procedural fallback keeps it live.\n const audio = useAudioData(src)\n const spectrum = useMemo(\n () => (audio ? audio.spectrogram(fps, Math.max(1, compFrames), n) : null),\n [audio, fps, compFrames, n],\n )\n const amps = spectrum\n ? Array.from(\n spectrum.subarray(\n Math.min(Math.max(0, frame), Math.max(0, compFrames - 1)) * n,\n Math.min(Math.max(0, frame), Math.max(0, compFrames - 1)) * n + n,\n ),\n )\n : Array.from({ length: n }, (_, i) => barAmplitude(seed, i, n, t))\n\n const ctx: VizCtx = {\n amps,\n n,\n width,\n height,\n barWidth,\n slot,\n barRadius,\n topColor,\n bottomColor,\n tailColor,\n entrance,\n align,\n }\n\n const children =\n type === 'mirrored'\n ? renderMirrored(ctx)\n : type === 'waveform'\n ? renderWaveform(ctx)\n : type === 'radial'\n ? renderRadial(ctx)\n : type === 'dots'\n ? renderDots(ctx)\n : renderBars(ctx)\n\n return (\n <>\n <Group x={originX} y={originY} opacity={entrance}>\n {children}\n </Group>\n {/* Play the audio it's visualizing (the player's volume/mute controls it). */}\n {src ? <Audio src={src} /> : null}\n </>\n )\n}\n\n/** A 2D point in the visualizer's local space. */\ninterface Pt {\n x: number\n y: number\n}\n\n/** Everything a style renderer needs, derived once per frame. */\ninterface VizCtx {\n amps: number[]\n n: number\n width: number\n height: number\n barWidth: number\n slot: number\n barRadius: number\n topColor: string\n bottomColor: string\n tailColor: string\n entrance: number\n align: 'top' | 'middle' | 'bottom'\n}\n\n/** Round to 0.1px to keep generated path data compact. */\nfunction r(v: number): number {\n return Math.round(v * 10) / 10\n}\n\n// ── Styles ──────────────────────────────────────────────────────────────────\n\n/** `bars` — classic vertical frequency bars (the original look). Each bar's\n * x/y translate its whole local frame, so the geometry (and gradient) live in a\n * frame where the bar spans (0,0)..(barWidth, barH); the gradient runs top→bottom\n * in THAT local space — it must NOT be offset by the translate `y`. */\nfunction renderBars({\n amps,\n height,\n barWidth,\n slot,\n barRadius,\n topColor,\n tailColor,\n entrance,\n align,\n}: VizCtx): ReactElement[] {\n return amps.map((amp, i) => {\n const barH = Math.max(barRadius * 2, amp * height * Math.max(0, entrance))\n const x = i * slot\n const y = align === 'top' ? 0 : align === 'bottom' ? height - barH : (height - barH) / 2\n return (\n <Rect\n key={i}\n x={x}\n y={y}\n width={barWidth}\n height={barH}\n cornerRadius={barRadius}\n fill={topColor}\n gradient={linearGradient(\n [0, 0],\n [0, barH],\n [\n { offset: 0, color: topColor },\n { offset: 1, color: tailColor },\n ],\n )}\n />\n )\n })\n}\n\n/** `mirrored` — bars grown symmetrically from the centre line, with a\n * centre-bright gradient that fades to both ends (a reflected EQ). */\nfunction renderMirrored({\n amps,\n height,\n barWidth,\n slot,\n barRadius,\n topColor,\n tailColor,\n entrance,\n}: VizCtx): ReactElement[] {\n const mid = height / 2\n return amps.map((amp, i) => {\n const barH = Math.max(barRadius * 2, amp * height * Math.max(0, entrance))\n const x = i * slot\n const y = mid - barH / 2\n return (\n <Rect\n key={i}\n x={x}\n y={y}\n width={barWidth}\n height={barH}\n cornerRadius={barRadius}\n fill={topColor}\n gradient={linearGradient(\n [0, 0],\n [0, barH],\n [\n { offset: 0, color: tailColor },\n { offset: 0.5, color: topColor },\n { offset: 1, color: tailColor },\n ],\n )}\n />\n )\n })\n}\n\n/** Smooth open polyline through `pts` (quadratic curves to segment midpoints). */\nfunction smoothPath(pts: Pt[]): string {\n const head = pts[0]\n if (!head) return ''\n let d = `M ${r(head.x)} ${r(head.y)}`\n for (let i = 1; i < pts.length; i++) {\n const cur = pts[i]\n if (!cur) continue\n const nxt = pts[i + 1]\n if (nxt) {\n const mx = (cur.x + nxt.x) / 2\n const my = (cur.y + nxt.y) / 2\n d += ` Q ${r(cur.x)} ${r(cur.y)} ${r(mx)} ${r(my)}`\n } else {\n d += ` L ${r(cur.x)} ${r(cur.y)}`\n }\n }\n return d\n}\n\n/** Closed ribbon: smooth `top` contour, then the `bottom` contour back\n * (reversed), then close. */\nfunction ribbonPath(top: Pt[], bottom: Pt[]): string {\n const d1 = smoothPath(top)\n if (!d1) return ''\n const back = smoothPath([...bottom].reverse())\n if (!back) return d1\n // `back` starts with `M x y …`; re-enter it as a line from the top contour's\n // end (`L x y …`) so the two contours join into one closed shape.\n return `${d1} L${back.slice(1)} Z`\n}\n\n/** `waveform` — a smooth filled ribbon symmetric about the centre line. */\nfunction renderWaveform({\n amps,\n n,\n width,\n height,\n topColor,\n tailColor,\n entrance,\n}: VizCtx): ReactElement[] {\n const mid = height / 2\n const halfH = (height / 2) * 0.92 * Math.max(0, entrance)\n const xAt = (i: number) => (n > 1 ? (i / (n - 1)) * width : width / 2)\n const top: Pt[] = amps.map((a, i) => ({ x: xAt(i), y: mid - Math.max(a, 0.03) * halfH }))\n const bottom: Pt[] = amps.map((a, i) => ({ x: xAt(i), y: mid + Math.max(a, 0.03) * halfH }))\n return [\n <Path\n key=\"wave\"\n d={ribbonPath(top, bottom)}\n fill={topColor}\n stroke={topColor}\n strokeWidth={2}\n gradient={linearGradient(\n [0, mid - halfH],\n [0, mid + halfH],\n [\n { offset: 0, color: tailColor },\n { offset: 0.5, color: topColor },\n { offset: 1, color: tailColor },\n ],\n )}\n />,\n ]\n}\n\n/** `radial` — bars radiating outward from a centre ring (circular spectrum). */\nfunction renderRadial({\n amps,\n n,\n width,\n height,\n barRadius,\n topColor,\n tailColor,\n entrance,\n}: VizCtx): ReactElement[] {\n const cx = width / 2\n const cy = height / 2\n const outerR = (Math.min(width, height) / 2) * 0.94\n const innerR = outerR * 0.42\n const barW = Math.max(2, ((2 * Math.PI * innerR) / n) * 0.55)\n const ring = (\n <Ellipse\n key=\"ring\"\n x={cx - innerR}\n y={cy - innerR}\n width={innerR * 2}\n height={innerR * 2}\n stroke={tailColor}\n strokeWidth={1.5}\n />\n )\n const spokes = amps.map((amp, i) => {\n const barLen = Math.max(barRadius, amp * (outerR - innerR) * Math.max(0, entrance))\n const angle = (i / n) * 360\n return (\n // Rotate a Group about the centre, then draw the bar pointing \"up\" (−y)\n // from the inner ring outward. The rect's local (0,0) sits at the OUTER\n // tip, so the gradient runs faded-tip → bright-base.\n <Group key={i} x={cx} y={cy} rotation={angle}>\n <Rect\n x={-barW / 2}\n y={-(innerR + barLen)}\n width={barW}\n height={barLen}\n cornerRadius={Math.min(barW / 2, barRadius)}\n fill={topColor}\n gradient={linearGradient(\n [0, 0],\n [0, barLen],\n [\n { offset: 0, color: tailColor },\n { offset: 1, color: topColor },\n ],\n )}\n />\n </Group>\n )\n })\n return [ring, ...spokes]\n}\n\n/** `dots` — an LED dot-matrix meter; each column lights bottom-up to its\n * amplitude, with a brighter \"peak hold\" dot at the top of the lit run. */\nfunction renderDots({\n amps,\n height,\n barWidth,\n slot,\n topColor,\n bottomColor,\n entrance,\n}: VizCtx): ReactElement[] {\n const dotGap = 3\n const rows = Math.max(6, Math.round(height / 14))\n const dotH = (height - (rows - 1) * dotGap) / rows\n const dotW = Math.min(barWidth, dotH * 1.4)\n const dim = withAlpha(topColor, 0x22)\n const radius = Math.min(dotW, dotH) / 3\n const out: ReactElement[] = []\n amps.forEach((amp, i) => {\n const lit = Math.round(Math.max(0, amp) * rows * Math.max(0, entrance))\n const x = i * slot + (barWidth - dotW) / 2\n for (let row = 0; row < rows; row++) {\n const on = row < lit\n const peak = row === lit - 1\n const y = height - (row + 1) * dotH - row * dotGap\n out.push(\n <Rect\n key={`${i}-${row}`}\n x={x}\n y={y}\n width={dotW}\n height={dotH}\n cornerRadius={radius}\n fill={on ? (peak ? bottomColor : topColor) : dim}\n />,\n )\n }\n })\n return out\n}\n\n/** Fake per-band spectrum amplitude in `[0, 1]`.\n *\n * Combines smooth coherent noise (the slow \"envelope\" of each band), a faster\n * per-band flutter, and a global pulse so the whole row breathes together —\n * then tilts the result so low bins (left) sit louder than highs (right),\n * the way a real music spectrum reads. Deterministic: identical across frames\n * and renderers for a given `seed`. This is the ONE function real audio data\n * (FFT magnitudes) would replace; every style above reads its output. */\nfunction barAmplitude(seed: number | string, i: number, n: number, t: number): number {\n // Bin position 0..1 across the row (0 = bass/left, 1 = treble/right).\n const pos = n > 1 ? i / (n - 1) : 0\n\n // Slow band envelope: smooth noise drifting over time. Maps [-1,1] → [0,1].\n const slow = (noise2D(seed, i * 0.35, t) + 1) * 0.5\n\n // Faster per-band flutter, a different noise channel so it doesn't track slow.\n const fast = (noise2D(`${seed}-flutter`, i * 0.9, t * 2.3) + 1) * 0.5\n\n // Global pulse — a gentle sine the whole row shares, so peaks feel \"on beat\".\n const pulse = 0.5 + 0.5 * Math.sin(t * 1.7)\n\n // Weighted blend, then bias toward the bass end (real spectra fall off with\n // frequency). `tilt` goes 1 at the left to ~0.4 at the right.\n const tilt = 1 - 0.6 * pos\n const raw = (0.55 * slow + 0.3 * fast + 0.15 * pulse) * tilt\n\n // Light gamma so quiet bands don't all hug the floor; clamp to [0,1].\n const shaped = raw ** 0.8\n return Math.max(0, Math.min(1, shaped))\n}\n\n/** Return `color` with its alpha channel set to `alpha` (0..255), preserving\n * the RGB. Falls back to the input unchanged for non-`#rrggbb(aa)` strings. */\nfunction withAlpha(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(255, Math.round(alpha)))\n .toString(16)\n .padStart(2, '0')\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}${a}`\n }\n if (hex.length === 3) {\n const rr = hex[0] ?? '0'\n const gg = hex[1] ?? '0'\n const bb = hex[2] ?? '0'\n return `#${rr}${rr}${gg}${gg}${bb}${bb}${a}`\n }\n }\n return color\n}\n","//! BarChart — horizontal bars that grow from 0 to their value on the house\n//! spring, staggered. The largest bar earns the accent color; every other bar\n//! sits in the dim bar color. Ported from ondajs (`bar-chart`).\n//!\n//! The chart has FIXED dimensions. Each bar row is positioned by an EXPLICIT\n//! `y` (`rowHeight * i`) inside a single `<Group>` — NOT a `<Flex>` — because a\n//! bar's fill width animates every frame, and a layout container would reflow\n//! (jiggle) as the measured bbox grew. For the same reason the whole chart is\n//! centered by computing its top-left offset from the composition size rather\n//! than letting an `<AbsoluteFill>` measure (and chase) the animated subtree.\n//!\n//! Scene caveat: `<Rect>` paints from its local origin, so the fill grows\n//! left-to-right naturally (origin at the track's left edge).\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** One bar: a label and its numeric value. */\nexport interface BarChartDatum {\n label: string\n value: number\n}\n\nexport interface BarChartProps extends TextStyleProps {\n /** Bars to render. Order is preserved — top to bottom. */\n data?: BarChartDatum[]\n /** Value mapped to a full-width bar. Bars cap at 100% of the track. */\n max?: number\n /** Frames before the **first** bar starts. */\n delay?: TimeInput\n /** Per-bar grow duration. Bars want more time than text (default `slow`). */\n duration?: TimeInput\n /** Frames between consecutive bars (default canonical `STAGGER` = 4). */\n stagger?: TimeInput\n /** Bar (and track) height in px. */\n barHeight?: number\n /** Pixel gap between rows. */\n gap?: number\n /** Pixels reserved for the label column (left of the track). */\n labelWidth?: number\n /** Gap between the label column and the track, in px. */\n labelGap?: number\n /** Track length in px — the full-width target for a bar at `max`. */\n trackWidth?: number\n /** Color of the **largest** bar — the earned accent (Onda rose). */\n accentColor?: string\n /** Color of non-largest bars. */\n barColor?: string\n /** Bar track (background) color. */\n trackColor?: string\n /** Show the numeric value at the end of each bar. */\n showValues?: boolean\n /** Count each value up from 0 in sync with its bar's growth (lands exactly on\n * the true value). Only applies when `showValues` is on. Default `true`. */\n countUp?: boolean\n /** Optional headline above the chart — tells viewers what the numbers measure\n * (e.g. \"Frames per second\"). */\n title?: string\n /** Title font size in px. Default ~1.5× the label `fontSize`. */\n titleSize?: number\n /** Title color. Defaults to `color`. */\n titleColor?: string\n /** Label / value font size in px. */\n fontSize?: number\n}\n\nconst DEFAULT_DATA: BarChartDatum[] = [\n { label: 'Remotion', value: 92 },\n { label: 'After Effects', value: 64 },\n { label: 'Lottie', value: 38 },\n]\n\nexport function BarChart({\n data = DEFAULT_DATA,\n max = 100,\n delay: delayIn = 0,\n duration: durationIn = DURATION.slow,\n stagger: staggerIn = STAGGER,\n barHeight = 32,\n gap = 16,\n labelWidth = 220,\n labelGap = 24,\n trackWidth = 760,\n accentColor: accentColorProp,\n barColor: barColorProp,\n trackColor: trackColorProp,\n color: colorProp,\n showValues = false,\n countUp = true,\n title,\n titleSize,\n titleColor: titleColorProp,\n fontSize = 24,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n}: BarChartProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const stagger = framesOf(staggerIn, fps)\n // Colors/font default to the active theme; explicit props override.\n const theme = useTheme()\n const accentColor = accentColorProp ?? theme.accent\n const barColor = barColorProp ?? theme.palette[0] ?? theme.textMuted\n const trackColor = trackColorProp ?? theme.surface\n const color = colorProp ?? theme.text\n const titleColor = titleColorProp ?? color\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n const rowHeight = barHeight + gap\n // Total chart footprint (no trailing gap below the last row).\n const chartWidth = labelWidth + labelGap + trackWidth\n const barsHeight = data.length > 0 ? rowHeight * data.length - gap : 0\n // Optional headline above the bars. Reserve its line + a margin.\n const titleFont = titleSize ?? Math.round(fontSize * 1.5)\n const titleBlock = title ? Math.round(titleFont * 1.6) : 0\n const blockHeight = barsHeight + titleBlock\n\n // Center the fixed-size block (title + bars) by computing its top-left offset\n // directly — no layout container, so the per-frame width growth never\n // triggers a reflow.\n const originX = Math.round((width - chartWidth) / 2)\n const originY = Math.round((height - blockHeight) / 2)\n // Center the title over the chart width (estimated — the engine has no\n // author-time text metrics or text-align).\n const titleWidth = title ? title.length * titleFont * 0.55 : 0\n const titleX = Math.max(0, Math.round((chartWidth - titleWidth) / 2))\n\n // Largest value earns the accent. Ties go to the first occurrence; the reduce\n // seed handles an empty array without producing -Infinity downstream.\n const maxValue = data.reduce((m, d) => (d.value > m ? d.value : m), Number.NEGATIVE_INFINITY)\n\n const trackX = labelWidth + labelGap\n\n return (\n <Group x={originX} y={originY}>\n {title ? (\n <Text\n x={titleX}\n y={0}\n fontSize={titleFont}\n color={titleColor ?? color}\n fontFamily={fontFamily}\n fontWeight={600}\n letterSpacing={letterSpacing}\n >\n {applyTextCase(title, { uppercase })}\n </Text>\n ) : null}\n {data.map((d, i) => {\n const barDelay = delay + staggerFrames(i, stagger)\n const local = Math.max(0, frame - barDelay)\n\n // The house spring drives both the fill width and a calm fade-in.\n const progress = spring({\n frame: local,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: duration,\n })\n\n const opacity = interpolate(progress, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // A clamped growth fraction that reaches exactly 1 (the overdamped\n // spring settles at ~0.995). Drives BOTH the bar width and the count-up,\n // so the number and the bar land together on the true value.\n const grow = interpolate(progress, [0, 0.99], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // Target fill fraction of the track, clamped to [0, 1] so out-of-range\n // data never overflows (callers can raise `max`).\n const targetFrac = max > 0 ? Math.max(0, Math.min(1, d.value / max)) : 0\n const fillWidth = trackWidth * targetFrac * grow\n\n const isLargest = d.value === maxValue\n const fillColor = isLargest ? accentColor : barColor\n\n const rowY = titleBlock + rowHeight * i\n const radius = barHeight / 2\n\n return (\n // Row container: layout-positioned by explicit x/y, opacity-only motion\n // (safe — no translate that would grow the bbox).\n <Group key={`${i}-${d.label}`} y={rowY} opacity={opacity}>\n {/* Label column. The engine measures text from its own origin and\n has no right-align, so labels read left-aligned in the column\n (see approximations). Vertically centered against the bar. */}\n <Text\n x={0}\n y={Math.round((barHeight - fontSize) / 2)}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={500}\n >\n {d.label}\n </Text>\n\n {/* Track (full-width background pill). */}\n <Rect\n x={trackX}\n y={0}\n width={trackWidth}\n height={barHeight}\n cornerRadius={radius}\n fill={trackColor}\n />\n\n {/* Animated fill, grown left-to-right from the track's origin.\n Rendered only once it has positive width. */}\n {fillWidth > 0 ? (\n <Rect\n x={trackX}\n y={0}\n width={fillWidth}\n height={barHeight}\n cornerRadius={radius}\n fill={fillColor}\n />\n ) : null}\n\n {showValues ? (\n <Text\n x={trackX + trackWidth + labelGap}\n y={Math.round((barHeight - fontSize) / 2)}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={500}\n >\n {`${countUp ? Math.round(d.value * grow) : Math.round(d.value)}`}\n </Text>\n ) : null}\n </Group>\n )\n })}\n </Group>\n )\n}\n","//! BentoGrid — a data-driven bento layout: a grid of glass cards with varying\n//! column/row spans, each rising + fading in on the house spring, staggered\n//! left-to-right so the grid assembles as one calm cascade. Ported from ondajs\n//! (`bento-grid`).\n//!\n//! The engine has no CSS grid (and no auto-flow), so this reproduces CSS grid\n//! `grid-auto-flow: row` placement by hand: a fixed column-track width, a\n//! derived row-track height, and a left-to-right / top-to-bottom packer that\n//! finds the first free run of `colSpan` cells on each row (skipping cells\n//! occupied by an earlier `rowSpan>1` item). Every cell is then positioned by an\n//! EXPLICIT pixel x/y inside one self-centering `<Group>` (like `BarChart`) —\n//! NOT a `<Flex>` — so the per-frame entrance translate never triggers a layout\n//! reflow. Because the cards are absolutely placed (not Flex children), the\n//! entrance TRANSLATE is applied on a nested inner `<Group>` and is layout-safe.\n//!\n//! Glass: this card uses a translucent dark fill (`#0e0e128c` ≈\n//! rgba(14,14,18,0.55)) + a subtle 1px stroke + a faint top \"sheen\" gradient.\n//! NOTE: the engine now ships real frosted glass via the `backdropBlur` node\n//! prop (blurs what's BEHIND the node) — a follow-up can opt this Surface into it\n//! for true glass instead of the flat translucent approximation.\n//!\n//! Backend caveat: the sheen uses a `linearGradient`, which renders only on the\n//! Vello/GPU backend; the CPU reference collapses it to its first (transparent)\n//! stop, so the sheen simply vanishes there — the card still reads correctly.\n\nimport { Group, Rect, Text, linearGradient, useVideoConfig } from '@onda-engine/react'\nimport { useStaggeredEntrance } from '../hooks.js'\nimport { STAGGER } from '../motion.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\n/** A single bento cell. Spans default to 1×1; `accent` earns the rose tint. */\nexport interface BentoItem {\n /** Cell title (display font). */\n title: string\n /** Optional headline figure shown large above the title (e.g. `'98%'`). */\n value?: string\n /** Optional caption beneath the title. */\n caption?: string\n /** Columns this cell spans. Clamped to the grid's `columns` (default 1). */\n colSpan?: number\n /** Rows this cell spans (default 1). */\n rowSpan?: number\n /** Marks the one earned-accent cell — rose value + accent border. */\n accent?: boolean\n}\n\nexport interface BentoGridProps extends TextStyleProps {\n /** The cells, laid out left-to-right, top-to-bottom. Spans drive the rhythm. */\n items?: BentoItem[]\n /** Number of grid columns (default 3). */\n columns?: number\n /** Gap between cells in px (default 24). */\n gap?: number\n /** Overall grid width in px (default 960). */\n width?: number\n /** Row-track height in px. Defaults to the column-track width (≈ square cells). */\n rowHeight?: number\n /** Inner padding of each cell in px (default 34). */\n padding?: number\n /** Frames before the first cell enters (default 0). */\n delay?: TimeInput\n /** Frames between successive cells rising in. House stagger is 4. */\n stagger?: TimeInput\n /** Base title font size in px (default 30). */\n fontSize?: number\n /** Caption color (default: theme `textMuted`). */\n captionColor?: string\n /** Accent color for the earned `accent` cell (default: theme `accent`). */\n accentColor?: string\n /** Card fill — translucent dark, approximating glass (default: theme `surface`). */\n cardColor?: string\n /** Card border color (default: theme `border`). */\n borderColor?: string\n /** Body font family for captions (default: theme `fontFamily`). */\n captionFontFamily?: string\n}\n\nconst DEFAULT_ITEMS: BentoItem[] = [\n {\n title: 'Motion identity',\n caption: 'One consistent feel across every component.',\n colSpan: 2,\n rowSpan: 1,\n accent: false,\n },\n {\n title: 'Render',\n value: '4K',\n caption: 'Deterministic, frame-perfect.',\n colSpan: 1,\n rowSpan: 1,\n },\n {\n title: 'Components',\n value: '40+',\n caption: 'Copied into your project.',\n colSpan: 1,\n rowSpan: 1,\n },\n { title: 'Spring physics', caption: 'No overshoot. Calm by default.', colSpan: 2, rowSpan: 1 },\n]\n\n/** A placed cell: its item plus the resolved pixel rectangle and grid index. */\ntype PlacedCell = {\n item: BentoItem\n index: number\n x: number\n y: number\n w: number\n h: number\n}\n\n/** Approximate average glyph advance as a fraction of font size (proportional\n * display fonts). Used only to greedily word-wrap the caption — the engine\n * measures text at render, but a pure frame→scene function can't read those\n * measurements back, so this estimate stands in (matches the `Marquee` port). */\nconst AVG_CHAR_W = 0.55\n\n/** Greedy word-wrap into lines that each fit `maxWidth` at the given font size.\n * A single over-long word is kept on its own line rather than split. */\nfunction wrapText(text: string, maxWidth: number, fontSize: number): string[] {\n const words = text.split(/\\s+/).filter((w) => w.length > 0)\n if (words.length === 0) return []\n const charPx = fontSize * AVG_CHAR_W\n const maxChars = Math.max(1, Math.floor(maxWidth / charPx))\n const lines: string[] = []\n let current = ''\n for (const word of words) {\n const candidate = current.length === 0 ? word : `${current} ${word}`\n if (candidate.length <= maxChars || current.length === 0) {\n current = candidate\n } else {\n lines.push(current)\n current = word\n }\n }\n if (current.length > 0) lines.push(current)\n return lines\n}\n\n/**\n * Pack the items into pixel rectangles, replicating CSS `grid-auto-flow: row`:\n * scan rows top-to-bottom; within each row, find the first column where a run of\n * `colSpan` free cells fits; reserve `colSpan × rowSpan` cells. An occupancy map\n * (per row, per column) tracks cells claimed by earlier multi-row items.\n */\nfunction packCells(\n items: BentoItem[],\n columns: number,\n colWidth: number,\n rowHeight: number,\n gap: number,\n): { cells: PlacedCell[]; rows: number } {\n const occupied: boolean[][] = []\n const ensureRow = (r: number) => {\n while (occupied.length <= r) occupied.push(new Array<boolean>(columns).fill(false))\n }\n const cells: PlacedCell[] = []\n let cursorRow = 0\n let cursorCol = 0\n\n items.forEach((item, index) => {\n const colSpan = Math.max(1, Math.min(item.colSpan ?? 1, columns))\n const rowSpan = Math.max(1, item.rowSpan ?? 1)\n\n // Find the first (row, col) where a colSpan-wide, rowSpan-tall block is free,\n // scanning from the running cursor onward (auto-flow is monotonic).\n let placedRow = cursorRow\n let placedCol = cursorCol\n let found = false\n while (!found) {\n ensureRow(placedRow + rowSpan - 1)\n if (placedCol + colSpan <= columns) {\n let free = true\n for (let dr = 0; dr < rowSpan && free; dr++) {\n const row = occupied[placedRow + dr] ?? []\n for (let dc = 0; dc < colSpan; dc++) {\n if (row[placedCol + dc] === true) {\n free = false\n break\n }\n }\n }\n if (free) {\n found = true\n break\n }\n }\n placedCol += 1\n if (placedCol + colSpan > columns) {\n placedCol = 0\n placedRow += 1\n }\n }\n\n // Reserve the block.\n for (let dr = 0; dr < rowSpan; dr++) {\n ensureRow(placedRow + dr)\n const row = occupied[placedRow + dr]\n if (row) {\n for (let dc = 0; dc < colSpan; dc++) row[placedCol + dc] = true\n }\n }\n\n cells.push({\n item,\n index,\n x: placedCol * (colWidth + gap),\n y: placedRow * (rowHeight + gap),\n w: colSpan * colWidth + (colSpan - 1) * gap,\n h: rowSpan * rowHeight + (rowSpan - 1) * gap,\n })\n\n // Advance the cursor just past this block on its first row.\n cursorRow = placedRow\n cursorCol = placedCol + colSpan\n if (cursorCol >= columns) {\n cursorCol = 0\n cursorRow = placedRow + 1\n }\n })\n\n return { cells, rows: occupied.length }\n}\n\nexport function BentoGrid({\n items = DEFAULT_ITEMS,\n columns = 3,\n gap = 24,\n width = 960,\n rowHeight,\n padding = 34,\n delay = 0,\n stagger = STAGGER,\n fontSize = 30,\n color: colorProp,\n captionColor: captionColorProp,\n accentColor: accentColorProp,\n cardColor: cardColorProp,\n borderColor: borderColorProp,\n fontFamily: fontFamilyProp,\n captionFontFamily: captionFontFamilyProp,\n}: BentoGridProps) {\n const { width: canvasW, height: canvasH } = useVideoConfig()\n\n // One hook call, then a per-index entrance — never a hook in a loop.\n const at = useStaggeredEntrance({ type: 'rise', delay, increment: stagger })\n\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const captionColor = captionColorProp ?? theme.textMuted\n const accentColor = accentColorProp ?? theme.accent\n const cardColor = cardColorProp ?? theme.surface\n const borderColor = borderColorProp ?? theme.border\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n const captionFontFamily = captionFontFamilyProp ?? theme.fontFamily\n\n const cols = Math.max(1, Math.round(columns))\n // Column-track width from the overall grid width (CSS `repeat(cols, 1fr)`).\n const colWidth = (width - (cols - 1) * gap) / cols\n // Without intrinsic row sizing, default rows to the column width (≈ square\n // cells) — a balanced bento that reads the same at any aspect ratio.\n const trackHeight = rowHeight ?? colWidth\n\n const { cells, rows } = packCells(items, cols, colWidth, trackHeight, gap)\n\n // Actual packed footprint. The declared `width` is an upper bound: if the\n // last column ends up empty (the packer left a trailing track), the real\n // content is narrower, so center on the measured extent — not `width` — to\n // keep the margins symmetric. Height likewise has no trailing gap.\n const gridWidth = cells.length > 0 ? Math.max(...cells.map((c) => c.x + c.w)) : width\n const gridHeight = rows > 0 ? rows * trackHeight + (rows - 1) * gap : 0\n\n // Self-center the fixed-size grid by computing its top-left offset directly —\n // no layout container, so the per-frame entrance translate never reflows.\n const originX = Math.round((canvasW - gridWidth) / 2)\n const originY = Math.round((canvasH - gridHeight) / 2)\n\n const radius = theme.radius\n const valueSize = Math.round(fontSize * 1.8)\n const captionSize = Math.round(fontSize * 0.56)\n\n // Faint top sheen: white-alpha gradient over the top ~40% of a card, fading to\n // transparent (GPU-only; CPU collapses to the transparent first stop).\n const sheenTransparent = '#ffffff00'\n const sheenLit = '#ffffff10'\n\n return (\n <Group x={originX} y={originY}>\n {cells.map((cell) => {\n const entrance = at(cell.index)\n const isAccent = cell.item.accent === true\n const cardBorder = isAccent ? accentColor : borderColor\n const valueColor = isAccent ? accentColor : color\n\n // Inner content box (bottom-aligned column, like the ondajs Surface).\n const contentW = Math.max(0, cell.w - padding * 2)\n\n // Bottom-up layout: caption, then title, then value — measured up from the\n // card's bottom padding edge. Each block uses its font size as a line-box\n // proxy (the engine box can't be read back here).\n const captionLines = cell.item.caption\n ? wrapText(cell.item.caption, contentW, captionSize)\n : []\n const captionLineH = Math.round(captionSize * 1.45)\n const titleLineH = Math.round(fontSize * 1.1)\n const blockGap = 8\n\n // Compute baseline-top offsets from the card bottom, walking upward.\n let cursorBottom = cell.h - padding\n // Caption (lowest block).\n const captionTops: number[] = []\n for (let i = captionLines.length - 1; i >= 0; i--) {\n cursorBottom -= captionLineH\n captionTops[i] = cursorBottom\n }\n if (captionLines.length > 0) cursorBottom -= blockGap\n // Title.\n cursorBottom -= titleLineH\n const titleTop = cursorBottom\n // Value (highest block), if present.\n let valueTop = titleTop\n if (cell.item.value) {\n cursorBottom -= blockGap\n cursorBottom -= valueSize\n valueTop = cursorBottom\n }\n\n return (\n // Outer Group: fixed pixel placement (explicit x/y — not Flex).\n <Group key={`${cell.index}-${cell.item.title}`} x={cell.x} y={cell.y}>\n {/* Inner Group: entrance opacity + rise translate (layout-safe here\n because the parent is not a layout container). */}\n <Group y={entrance.y} opacity={entrance.opacity}>\n {/* Glass card: translucent fill + 1px stroke. (Could adopt the new\n `backdropBlur` prop for true frosted glass.) */}\n <Rect\n width={cell.w}\n height={cell.h}\n cornerRadius={radius}\n fill={cardColor}\n stroke={cardBorder}\n strokeWidth={1}\n />\n {/* Top sheen overlay (GPU-only). */}\n <Rect\n width={cell.w}\n height={Math.round(cell.h * 0.4)}\n cornerRadius={radius}\n gradient={linearGradient(\n [0, 0],\n [0, Math.round(cell.h * 0.4)],\n [\n { offset: 0, color: sheenTransparent },\n { offset: 0.01, color: sheenLit },\n { offset: 1, color: sheenTransparent },\n ],\n )}\n />\n\n {/* Value (large, accent on the earned cell). */}\n {cell.item.value ? (\n <Text\n x={padding}\n y={valueTop}\n fontSize={valueSize}\n color={valueColor}\n fontFamily={fontFamily}\n fontWeight={600}\n >\n {cell.item.value}\n </Text>\n ) : null}\n\n {/* Title. */}\n <Text\n x={padding}\n y={titleTop}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={600}\n >\n {cell.item.title}\n </Text>\n\n {/* Caption (wrapped to the content width). */}\n {captionLines.map((line, li) => (\n <Text\n key={li}\n x={padding}\n y={captionTops[li] ?? cell.h - padding}\n fontSize={captionSize}\n color={captionColor}\n fontFamily={captionFontFamily ?? fontFamily}\n fontWeight={400}\n >\n {line}\n </Text>\n ))}\n </Group>\n </Group>\n )\n })}\n </Group>\n )\n}\n","//! BlurReveal — the reference Onda reveal: opacity + a small rise + a real\n//! soft→sharp focus-pull, all on the house spring (no overshoot). Ported from\n//! ondajs.\n//!\n//! The blur is FIRST-CLASS: the engine's render-to-texture pass blurs the\n//! subtree and composites it back, so the literal ondajs `blur(10px → 0)` ramp\n//! is reproduced directly (a `blur` prop on the inner motion `<Group>`) — no\n//! scale-settle stand-in. The text resolves from soft to sharp as it rises and\n//! fades in, on both backends.\n//!\n//! Self-positioning: an `<AbsoluteFill>` centers the content, and the motion\n//! (opacity + rise + blur) lives on a NESTED inner `<Group>` — the layout pass\n//! owns the outer position, so a motion translate must not sit on a direct\n//! AbsoluteFill child.\n\nimport {\n AbsoluteFill,\n Group,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { type Placement, PlacementShift } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface BlurRevealProps extends TextStyleProps {\n /** What to reveal. Rendered as a single-line `<Text>` unless `children` is\n * provided. */\n text?: string\n /** Custom content to reveal instead of `text` (wins over `text` when both are\n * given). Lets BlurReveal wrap any subtree, not just a string. */\n children?: ReactNode\n /** Frames before the reveal starts. */\n delay?: TimeInput\n /** Frames until the reveal fully settles (default `DURATION.base` = 18). With\n * `SPRING_SMOOTH` the visible motion settles in roughly this range. */\n durationInFrames?: TimeInput\n /** Text size in px. Ignored when `children` is set. */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * measured line cannot exceed the frame minus the safe margins. Default\n * `'none'` (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the line; combines with `fit` (the smaller\n * cap wins). */\n maxWidth?: number // (Ignored when `children` is set.)\n /** Where the reveal sits. The legacy `'top'`/`'bottom'` keywords keep their\n * historical edge-flush meaning (layout `justify`); every other region\n * keyword and normalized `{x,y}` (0-1, content center) goes through the\n * shared placement contract. Default `'center'`. */\n placement?: Placement\n /** Rise distance in px (the original's 16px envelope; small on purpose). */\n travelPx?: number\n /** Starting blur in px (gaussian sigma) for the soft→sharp focus-pull; ramps\n * to 0 as the reveal settles (the ondajs original's `blur(10px → 0)`). */\n fromBlur?: number\n}\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport function BlurReveal({\n text: textProp = 'Onda',\n children,\n delay: delayIn = 0,\n durationInFrames: durationInFramesIn = DURATION.base,\n color: colorProp,\n fontSize: fontSizeProp = 96,\n fit,\n maxWidth,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n placement = 'center',\n travelPx = 16,\n fromBlur = 10,\n}: BlurRevealProps) {\n const text = applyTextCase(textProp, { uppercase })\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const durationInFrames = framesOf(durationInFramesIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Opt-in auto-fit for the single-line `text` form (children own their box).\n const fontSize = useFittedFontSize(text, fontSizeProp, { fontFamily, fontWeight, fit, maxWidth })\n\n // One house spring drives opacity, rise, and the focus-pull blur so they read\n // as a single motion — mirrors the ondajs original, where opacity, blur, and\n // the 16px rise all derive from one `SPRING_SMOOTH` progress.\n const progress = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames,\n })\n\n const opacity = interpolate(progress, [0, 1], [0, 1], CLAMP)\n const y = interpolate(progress, [0, 1], [travelPx, 0], CLAMP)\n // Real soft→sharp focus-pull: the engine's render-to-texture pass blurs the\n // subtree by `blur` px, ramping fromBlur → 0 as the reveal settles.\n const blur = interpolate(progress, [0, 1], [fromBlur, 0], CLAMP)\n\n // Legacy keywords keep their exact pre-contract behavior (edge-flush via the\n // layout pass); everything else resolves through the shared contract.\n const isLegacy = placement === 'center' || placement === 'top' || placement === 'bottom'\n const justify = placement === 'top' ? 'start' : placement === 'bottom' ? 'end' : 'center'\n\n const content: ReactNode = children ?? (\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {text}\n </Text>\n )\n\n return (\n <PlacementShift placement={isLegacy ? undefined : placement}>\n <AbsoluteFill justify={isLegacy ? justify : 'center'} align=\"center\">\n {/* Inner group carries the motion translate/blur/opacity; the outer\n AbsoluteFill owns positioning (don't translate a direct layout child). */}\n <Group y={y} blur={blur} opacity={opacity}>\n {content}\n </Group>\n </AbsoluteFill>\n </PlacementShift>\n )\n}\n","//! BoundingBox — a deliberate annotation that reveals around a region: four\n//! corner ticks draw on in a staggered wave, a calm outline settles between\n//! them, and a label tag pins to the top-left corner. The accent is earned\n//! here. Ported from ondajs, then redesigned to read as an intentional\n//! call-out (not a debug overlay).\n//!\n//! Choreography — corner-by-corner, one beat per element:\n//! 1. The four corner ticks draw on as L-marks, staggered clockwise from the\n//! top-left via `staggerFrames(i)`, each \"drawn\" by an animated stroke-dash\n//! on the house ease + a short fade. The eye is led around the box.\n//! 2. The outline `<Rect>` draws on underneath as a quiet base, its\n//! stroke-dash retreating over `drawDuration` so the perimeter fills in\n//! behind the ticks rather than snapping in.\n//! 3. Once the box has landed, the corner ticks settle into a soft, slow pulse\n//! (a low-amplitude opacity breathe that decelerates into rest — restraint,\n//! not a strobe), and the label tag fades + scales in.\n//!\n//! Depth: only the label tag carries a soft accent glow (the engine's `shadow`\n//! with a 0,0 offset reads as a centered halo around the rounded pill). Neither the\n//! outline nor the corner ticks glow: the engine's `shadow` is an analytic blurred\n//! rounded-rect of the shape's BOUNDING BOX, so a glow on the thin L-shaped ticks\n//! renders as a soft filled blob at each corner — it reads as a stray circle, not a\n//! halo. The ticks carry the accent with a crisp stroke instead.\n//!\n//! Geometry follows the ondajs schema: `x`/`y`/`width`/`height` are `0..1`\n//! fractions of the composition, resolved against `useVideoConfig()`. Corner\n//! ticks are `<Path>` L-marks (GPU/Vello backend only, like all paths). The\n//! label tag's width is MEASURED from the shaped glyphs via `useTextMetrics`\n//! (proportional — exact); it falls back to a glyph-count estimate until the\n//! wasm engine warms in the browser (the `Highlight`/`Underline` pattern).\n//!\n//! Corners are SHARP by default (`cornerRadius = 0`), matching ondajs's\n//! selection-marquee look — the L-shaped corner ticks pin to the sharp corners.\n//! `cornerRadius` is exposed as an optional rounding for the outline `<Rect>`.\n\nimport {\n Group,\n Path,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryFade, entryScale } from '../choreography.js'\nimport { HOUSE_EASE } from '../easing.js'\nimport { DURATION, SPRING_SMOOTH, staggerFrames } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Engine line-box height as a multiple of font size (matches typography crate). */\nconst LINE_RATIO = 1.2\n\nexport interface BoundingBoxProps extends TextStyleProps {\n /** Box left edge as a `0..1` fraction of the composition width. */\n x?: number\n /** Box top edge as a `0..1` fraction of the composition height. */\n y?: number\n /** Box width as a `0..1` fraction of the composition width. */\n width?: number\n /** Box height as a `0..1` fraction of the composition height. */\n height?: number\n /** Optional label tag pinned to the box's top-left corner. Empty hides it. */\n label?: string\n /** Frames before the outline starts revealing. */\n delay?: TimeInput\n /** Frames to reveal the full outline (default `DURATION.slow` = 28). */\n drawDuration?: number\n /** Outline stroke width in px. */\n strokeWidth?: number\n /** Reserved (kept for API compatibility). The perimeter draw-on traces sharp\n * corners (the selection-marquee look), so outline rounding is not applied. */\n cornerRadius?: number\n /** Label text color — a dark for contrast on the accent tag by default. */\n labelColor?: string\n /** Label font size in px. */\n fontSize?: number\n}\n\nexport function BoundingBox({\n x = 0.3,\n y = 0.3,\n width = 0.4,\n height = 0.4,\n label: labelProp = '',\n color: colorProp,\n delay: delayIn = 0,\n drawDuration = DURATION.slow,\n strokeWidth = 3,\n cornerRadius = 0,\n labelColor = '#08080a',\n fontSize = 16,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n}: BoundingBoxProps) {\n const frame = useCurrentFrame()\n const { fps, width: canvasW, height: canvasH } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.accent\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n\n // Apply the case transform up front so the measured width, the `showTag` gate,\n // and the rendered glyphs all agree on the same (possibly uppercased) string.\n const label = applyTextCase(labelProp, { uppercase })\n\n // Real shaped label width — the engine measures the glyphs (proportional —\n // exact); falls back to a glyph-count estimate until the wasm engine warms in\n // the browser.\n const measured = useTextMetrics(label, fontSize, { fontFamily })\n\n // Box geometry in pixel space.\n const bx = x * canvasW\n const by = y * canvasH\n const bw = width * canvasW\n const bh = height * canvasH\n\n // A soft, centered accent glow tinted toward the bg — the call-out has\n // presence without a hard black edge. `(0,0)` offset reads as a halo.\n const glow = { color, blur: Math.max(8, strokeWidth * 4), offsetX: 0, offsetY: 0 }\n\n // The outline draws on underneath the ticks as a quiet base. A smooth eased\n // ramp (not a spring) gives the pen an even pace across the whole perimeter\n // rather than snapping most edges in the first few frames.\n const drawDur = Math.max(1, drawDuration)\n const drawProgress = interpolate(frame, [delay, delay + drawDur], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n easing: HOUSE_EASE,\n })\n // Real draw-on via animated stroke-dash: one dash as long as the whole\n // perimeter, its offset retreating to 0 as `drawProgress` → 1, so the outline\n // is \"drawn\" clockwise from the top-left like a pen. Renders on both backends.\n const perim = 2 * (bw + bh)\n const dashOffset = perim * (1 - drawProgress)\n\n // Corner ticks — the lead element. Length scales with the box but stays inside\n // it; the tick is an L-mark drawn from its inner elbow out along both edges.\n // Each tick draws on (stroke-dash) staggered clockwise from the top-left.\n const tickLen = Math.min(28, bw * 0.25, bh * 0.25)\n const tickDash = tickLen * 2\n\n // The four corners, clockwise from top-left: elbow point + the two L arms as\n // an SVG path (`M arm1 → L elbow → L arm2`). Drawn in local box space.\n const corners = [\n { d: `M0 ${tickLen} L0 0 L${tickLen} 0` }, // top-left\n { d: `M${bw - tickLen} 0 L${bw} 0 L${bw} ${tickLen}` }, // top-right\n { d: `M${bw} ${bh - tickLen} L${bw} ${bh} L${bw - tickLen} ${bh}` }, // bottom-right\n { d: `M${tickLen} ${bh} L0 ${bh} L0 ${bh - tickLen}` }, // bottom-left\n ]\n\n // Once the box has essentially landed, the ticks settle into a soft, slow\n // pulse: a low-amplitude opacity breathe on a sine. Restraint — a 6% swing,\n // never a strobe.\n const settleFrom = delay + drawDur + DURATION.base\n const pulse = interpolate(\n Math.sin(((frame - settleFrom) / (fps * 1.6)) * Math.PI * 2),\n [-1, 1],\n [0.94, 1],\n { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' },\n )\n const pulseOpacity = frame > settleFrom ? pulse : 1\n\n // The label tag comes in last, once the outline has landed.\n const phaseTwoDelay = delay + drawDur\n const tagFade = entryFade({ frame, fps, delay: phaseTwoDelay, durationInFrames: DURATION.base })\n const tagScale = entryScale({ frame, fps, delay: phaseTwoDelay, durationInFrames: DURATION.base })\n\n // Label tag geometry — pinned just above the top-left corner. Width measured\n // from the shaped glyphs (see `useTextMetrics` above). The tag is a rounded\n // filled Rect with the label drawn on top.\n const showTag = label !== ''\n const tagPadX = 10\n const tagPadY = 4\n const tagGap = 6\n const tagWidth = measured.width + tagPadX * 2\n const tagHeight = fontSize * LINE_RATIO + tagPadY * 2\n const tagRadius = 6\n // Center the cap-height of the text within the tag box.\n const textY = (tagHeight - fontSize * LINE_RATIO) / 2\n\n return (\n <Group x={bx} y={by}>\n {/* The outline base, drawn on by an animated stroke-dash around the\n perimeter (clockwise from the top-left). It settles quietly behind the\n corner ticks; `cornerRadius` rounds the corners. */}\n {drawProgress > 0.001 ? (\n <Rect\n width={bw}\n height={bh}\n cornerRadius={cornerRadius}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeCap=\"round\"\n strokeJoin=\"round\"\n strokeDash={[perim, perim]}\n strokeDashOffset={dashOffset}\n opacity={0.7}\n />\n ) : null}\n {/* Corner ticks — draw on in a staggered clockwise wave, then breathe in a\n soft pulse. The earned accent reads strongest here, on the corners. */}\n {corners.map((corner, i) => {\n const tickDelay = delay + staggerFrames(i)\n const tickDraw = spring({\n frame: frame - tickDelay,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n if (tickDraw <= 0.001) return null\n return (\n <Path\n key={i}\n d={corner.d}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeCap=\"round\"\n strokeJoin=\"round\"\n strokeDash={[tickDash, tickDash]}\n strokeDashOffset={tickDash * (1 - tickDraw)}\n opacity={tickDraw * pulseOpacity}\n />\n )\n })}\n {/* Label tag pinned above the top-left corner. Fades + scales in once the\n outline lands. Scale pivots on the tag's bottom-left (its local origin\n sits there) so it grows up-and-out from the corner, matching ondajs's\n `transform-origin: bottom left`. */}\n {showTag ? (\n <Group y={-(tagHeight + tagGap)} opacity={tagFade.opacity}>\n <Group scaleX={tagScale.scaleX} scaleY={tagScale.scaleY}>\n <Rect\n width={tagWidth}\n height={tagHeight}\n cornerRadius={tagRadius}\n fill={color}\n shadow={glow}\n />\n <Text\n x={tagPadX}\n y={textY}\n fontSize={fontSize}\n color={labelColor}\n fontFamily={fontFamily}\n fontWeight={600}\n letterSpacing={letterSpacing}\n >\n {label}\n </Text>\n </Group>\n </Group>\n ) : null}\n </Group>\n )\n}\n","//! BrowserFrame — a browser-window chrome that wraps arbitrary content. A top\n//! bar with three \"traffic-light\" dots and an address pill, then a clipped\n//! content area below it. Ported from ondajs (`browser-frame`).\n//!\n//! This is a CONTAINER, not a leaf — the documented exception to the\n//! \"self-contained\" rule, since wrapping content is its whole job. Pass\n//! `children` (scene nodes), an image `src` (shown when there are no children),\n//! or neither (a neutral placeholder showing the URL). It scales-and-fades in on\n//! the house spring (`entryScale`, default `from` 0.96 — restrained), matching\n//! the ondajs entrance.\n//!\n//! Layout: the frame has FIXED dimensions, so it is centered by computing its\n//! position from the composition size directly (no `<AbsoluteFill>`) — a layout\n//! container would chase the animated subtree. The scale-in pivots on the\n//! frame's CENTER: scene scale is about a node's local origin (0,0), so the\n//! entrance `<Group>` sits at the frame's center and its body is drawn from\n//! `(-cardWidth/2, -cardHeight/2)`, so growth reads as centered, not corner-\n//! anchored.\n//!\n//! Children render at the content area's local origin (0,0) and are masked to it\n//! by `clipRect` (which is local-space, anchored at the parent `<Group>`'s\n//! origin — sized width×height, no offset).\n//!\n//! Approximations vs ondajs: the engine has no `object-fit: cover` for images,\n//! so a provided `src` is scaled to fill the content WIDTH (uniform scale) from\n//! the top-left; the clip hides any vertical overflow (it cannot fill a gap if\n//! the image is taller-cropped than the source — pass a landscape image). ondajs\n//! cover-crops both axes. The pill text and the placeholder are single-line (the\n//! engine doesn't auto-wrap) and left-aligned (no center/right text-align),\n//! clipped to the pill box. No drop shadow under the card (no box-shadow\n//! primitive) — a 1px border stands in for the card's edge, as in ondajs (which\n//! also paints a 1px border). No CSS letter-spacing on the pill text, and no top\n//! \"sheen\" overlay (a 1px highlight gradient ondajs draws on its Surface).\n\nimport {\n Ellipse,\n Group,\n Image,\n Rect,\n Text,\n clipRect,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { entryScale } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\n// Card geometry (matches ondajs: the chrome bar's 16/22px padding, 18px dots with\n// a 10px gap, a 40px-tall pill).\nconst CHROME_PAD_Y = 16\nconst CHROME_PAD_X = 22\nconst DOT_SIZE = 18\nconst DOT_GAP = 10\nconst PILL_HEIGHT = 40\n// Gap between the last dot and the pill. In ondajs the chrome row is a flex\n// container with `gap: 10` AND the pill carries `marginLeft: 16`, so the\n// last-dot → pill distance is the sum of both.\nconst PILL_GAP = DOT_GAP + 16 // = 26\nconst PILL_PAD_X = 20 // inner horizontal padding of the pill\nconst PILL_FONT = 22\nconst PLACEHOLDER_FONT = 32\n// Approx average glyph advance as a fraction of font size, for roughly centering\n// the single-line placeholder text (the engine measures at render time, but a\n// pure frame->scene function can't read those measurements back).\nconst AVG_CHAR_W = 0.55\n\n// The taller of the dots / pill — the run of content the chrome bar sizes to.\nconst CHROME_ROW = Math.max(DOT_SIZE, PILL_HEIGHT)\n// Chrome bar height: vertical padding around that row.\nconst CHROME_HEIGHT = CHROME_PAD_Y * 2 + CHROME_ROW\n\nexport interface BrowserFrameProps {\n /** URL shown in the address pill (and as the placeholder when empty). */\n url?: string\n /** Image to show inside the frame when no `children` are passed. Scaled to\n * fill the content width (see approximations). */\n src?: string\n /** Frames before the entrance. */\n delay?: TimeInput\n /** Scale-and-fade the frame in on the house spring. */\n animate?: boolean\n /** Frame (and content) width in px. */\n width?: number\n /** Content height in px (excludes the chrome bar). */\n height?: number\n /** Starting scale for the entrance (default 0.96 — restrained, like ondajs). */\n from?: number\n /** Card body fill (default: theme `surface`). */\n surface?: string\n /** 1px card border and chrome divider (default: theme `border`). */\n border?: string\n /** Traffic-light dot color (default: theme `border`). */\n borderLit?: string\n /** Address-pill fill (default: theme `surface`). */\n surface2?: string\n /** Content canvas background (default: theme `background`). */\n bg?: string\n /** Pill/URL text color (default: theme `textMuted`). */\n dim?: string\n /** Placeholder text color (default: theme `textMuted`). */\n faint?: string\n /** Card corner radius in px (default: theme `radius`). */\n cardRadius?: number\n /** Address-pill corner radius in px (default: theme `radius`). */\n pillRadius?: number\n /** Content to wrap; renders at the content area's local origin (0,0). */\n children?: ReactNode\n}\n\nexport function BrowserFrame({\n url = 'onda.video',\n src,\n delay = 0,\n animate = true,\n width = 1280,\n height = 720,\n from = 0.96,\n surface: surfaceProp,\n border: borderProp,\n borderLit: borderLitProp,\n surface2: surface2Prop,\n bg: bgProp,\n dim: dimProp,\n faint: faintProp,\n cardRadius: cardRadiusProp,\n pillRadius: pillRadiusProp,\n children,\n}: BrowserFrameProps) {\n const frame = useCurrentFrame()\n const { width: compWidth, height: compHeight, fps } = useVideoConfig()\n const theme = useTheme()\n const SURFACE = surfaceProp ?? theme.surface\n const BORDER = borderProp ?? theme.border\n const BORDER_LIT = borderLitProp ?? theme.border\n const SURFACE_2 = surface2Prop ?? theme.surface\n const BG = bgProp ?? theme.background\n const DIM = dimProp ?? theme.textMuted\n const FAINT = faintProp ?? theme.textMuted\n const CARD_RADIUS = cardRadiusProp ?? theme.radius\n const PILL_RADIUS = pillRadiusProp ?? theme.radius\n\n // Total card footprint: chrome bar on top, content area below.\n const cardWidth = width\n const cardHeight = CHROME_HEIGHT + height\n\n // Center the fixed-size card on the canvas.\n const centerX = compWidth / 2\n const centerY = compHeight / 2\n // Body drawn from the card's top-left, expressed relative to its center so the\n // entrance scale pivots on the center.\n const bodyX = -cardWidth / 2\n const bodyY = -cardHeight / 2\n\n // House spring scale + fade. Matches ondajs `useEntrance({ type: 'scale',\n // from: 0.96 })`, which uses the hook's default duration (DURATION.base).\n const motion = animate\n ? entryScale({ frame, fps, delay, durationInFrames: DURATION.base, from })\n : { opacity: 1, scaleX: 1, scaleY: 1 }\n\n // Dots: three traffic lights at the chrome bar's left, vertically centered.\n const dotY = CHROME_PAD_Y + (CHROME_ROW - DOT_SIZE) / 2\n const dotXs = [0, 1, 2].map((i) => CHROME_PAD_X + i * (DOT_SIZE + DOT_GAP))\n const lastDotRight = (dotXs[2] ?? CHROME_PAD_X) + DOT_SIZE\n\n // Pill: fills the remaining chrome width to the right of the dots.\n const pillX = lastDotRight + PILL_GAP\n const pillY = CHROME_PAD_Y + (CHROME_ROW - PILL_HEIGHT) / 2\n const pillWidth = Math.max(0, cardWidth - pillX - CHROME_PAD_X)\n // Inner box of the pill, where the url text is clipped/aligned.\n const pillInnerWidth = Math.max(0, pillWidth - PILL_PAD_X * 2)\n const pillTextX = pillX + PILL_PAD_X\n const pillTextY = pillY + (PILL_HEIGHT - PILL_FONT) / 2\n\n // Content area origin (just below the chrome bar), relative to the card body.\n const contentX = bodyX\n const contentY = bodyY + CHROME_HEIGHT\n\n // Placeholder text (when no children and no src): roughly centered.\n const placeholderTextWidth = url.length * PLACEHOLDER_FONT * AVG_CHAR_W\n const placeholderX = Math.round((cardWidth - placeholderTextWidth) / 2)\n const placeholderY = Math.round((height - PLACEHOLDER_FONT) / 2)\n\n return (\n <Group\n x={centerX}\n y={centerY}\n scaleX={motion.scaleX}\n scaleY={motion.scaleY}\n opacity={motion.opacity}\n >\n {/* Card body — opaque raised surface with a 1px border. */}\n <Rect\n x={bodyX}\n y={bodyY}\n width={cardWidth}\n height={cardHeight}\n cornerRadius={CARD_RADIUS}\n fill={SURFACE}\n stroke={BORDER}\n strokeWidth={1}\n />\n\n {/* Chrome bar contents, positioned relative to the card body top-left. */}\n <Group x={bodyX} y={bodyY}>\n {dotXs.map((dx, i) => (\n <Ellipse key={i} x={dx} y={dotY} width={DOT_SIZE} height={DOT_SIZE} fill={BORDER_LIT} />\n ))}\n\n {/* Address pill. */}\n {pillWidth > 0 ? (\n <Rect\n x={pillX}\n y={pillY}\n width={pillWidth}\n height={PILL_HEIGHT}\n cornerRadius={PILL_RADIUS}\n fill={SURFACE_2}\n stroke={BORDER}\n strokeWidth={1}\n />\n ) : null}\n\n {/* The 1px divider beneath the chrome bar. */}\n <Rect x={0} y={CHROME_HEIGHT - 1} width={cardWidth} height={1} fill={BORDER} />\n\n {/* URL text, masked to the pill's inner box (clip is local to its\n parent's origin, so this Group sits at the pill's inner top-left). */}\n {pillInnerWidth > 0 ? (\n <Group x={pillTextX} y={pillTextY} clip={clipRect(pillInnerWidth, PILL_FONT)}>\n <Text fontSize={PILL_FONT} color={DIM}>\n {url}\n </Text>\n </Group>\n ) : null}\n </Group>\n\n {/* Content area: dark canvas + clipped children / image / placeholder. */}\n <Group x={contentX} y={contentY}>\n {/* Background fill behind the content. */}\n <Rect x={0} y={0} width={cardWidth} height={height} fill={BG} />\n\n {/* Everything inside the content area is masked to it. */}\n <Group clip={clipRect(cardWidth, height)}>\n {children != null ? (\n // Re-center wrapped children on the INNER content rect, not the full\n // canvas. A self-centering child (e.g. one using <AbsoluteFill>) sizes\n // to the composition and centers its content at (compW/2, compH/2) in\n // its own local space; since that space is pinned to the content rect's\n // top-left, the content would land at compCenter — off-center inside\n // the chrome inset. Shift by (content − comp) / 2 so the child's center\n // coincides with the content rect's center instead.\n <Group x={(cardWidth - compWidth) / 2} y={(height - compHeight) / 2}>\n {children}\n </Group>\n ) : src ? (\n <Image src={src} width={cardWidth} height={height} fit=\"cover\" />\n ) : (\n <Text x={placeholderX} y={placeholderY} fontSize={PLACEHOLDER_FONT} color={FAINT}>\n {url}\n </Text>\n )}\n </Group>\n </Group>\n </Group>\n )\n}\n","//! Button — a styled CTA pill: a rounded filled `<Rect>` with a centered label.\n//! Fades + rises in on the house spring, then plays an optional press-dip at\n//! `pressFrame` (a quick scale to 0.94 and back on the house ease, reading as a\n//! physical click). Ported from ondajs.\n//!\n//! Two variants, matching ondajs: `'primary'` paints the pill with `color` and\n//! draws the label in `textColor`; `'ghost'` leaves the pill transparent with a\n//! `color` border and a `color`-tinted label.\n//!\n//! Self-positioning: like the ondajs original (which wraps the button in a\n//! `PlacementBox` that defaults to centered), this centers itself on the canvas\n//! by default. The whole assembly is drawn around its LOCAL ORIGIN (0,0) — the\n//! pill at `(-width/2, -height/2)`, the label offset by its own estimated extent\n//! — and that origin is then placed at the canvas center (or at the `x`/`y`\n//! canvas-fraction you pass). Centering the assembly on the origin also puts the\n//! pivot for the press dip at the button's visual center (HARD RULE 3), so it\n//! dips from the middle rather than the corner.\n//!\n//! Approximations vs the ondajs (CSS) original:\n//! - `box-shadow` (the soft accent glow on primary, the quiet inset lift) has no\n//! scene-graph equivalent — dropped. Depth is implied by the fill/border alone.\n//! - The primary variant keeps the ondajs subtle light border (`1px solid\n//! rgba(255,255,255,0.14)` → {@link PRIMARY_BORDER}), drawn as a thin stroke so\n//! the solid accent fill reads as a crisp, raised CTA against the dark canvas\n//! rather than a flat wash. The ghost's inset highlight is still dropped (no\n//! inset-shadow primitive); its `color` border carries the shape.\n//! - `letter-spacing: -0.01em` is unsupported by the text engine — dropped.\n//! - The label width/height are ESTIMATED from glyph count × font size (no\n//! author-time text metrics), so the centering is approximate; pass `width`\n//! sized to your label, or accept the small offset on very long labels.\n//! - The ghost transparent fill uses `'#00000000'` (the engine has no `none`).\n\nimport { Group, Rect, Text, interpolate, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { entryFadeRise } from '../choreography.js'\nimport { HOUSE_EASE } from '../easing.js'\nimport { DURATION } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Mean glyph advance as a fraction of the font size — a rough display-sans\n * heuristic, used only to center the label (the engine measures the real text\n * at render time). */\nconst CHAR_WIDTH_FACTOR = 0.54\n/** Engine line-box height as a multiple of font size (matches the typography\n * crate; the same ratio `Highlight`/`Underline` use). */\nconst LINE_RATIO = 1.2\n\n// Press-dip envelope, ported from ondajs: scale eases down to PRESS_SCALE over\n// PRESS_IN frames into `pressFrame`, then springs back to 1 over PRESS_OUT.\n// Short and tight so it reads as a click, not a bounce — no overshoot.\nconst PRESS_SCALE = 0.94\nconst PRESS_IN = 3\nconst PRESS_OUT = 7\n\n// Subtle top-light edge on the primary pill (ondajs's `1px solid\n// rgba(255,255,255,0.14)`, as `#ffffff24` — the engine takes hex, not CSS\n// `rgba()`), drawn as a thin stroke. It crisps the solid accent fill into a\n// deliberate, raised CTA instead of a flat, washed-out wash.\nconst PRIMARY_BORDER = '#ffffff24'\nconst PRIMARY_BORDER_WIDTH = 1\n\nexport interface ButtonProps extends TextStyleProps {\n /** The button label. */\n label?: string\n /** `'primary'` = filled with `color`; `'ghost'` = transparent with a `color`\n * border and `color`-tinted label. */\n variant?: 'primary' | 'ghost'\n /** Accent color — the primary fill and the ghost border/label tint\n * (default: theme `accent`). */\n color?: string\n /** Label color on the primary variant (default: theme `text`). Ignored\n * by `'ghost'`, which tints the label with `color`. */\n textColor?: string\n /** Pill width in px (default 280). */\n width?: number\n /** Pill height in px (default 72). */\n height?: number\n /** Corner radius in px (default: theme `radius`). */\n cornerRadius?: number\n /** Border thickness in px for the `'ghost'` variant (default 2). */\n borderWidth?: number\n /** Label font size in px (default 24). */\n fontSize?: number\n /** Loaded font family (e.g. a `--font` passed to `onda render`) (default: theme `fontFamily`). */\n fontFamily?: string\n /** Label font weight (display default 600). */\n fontWeight?: number\n /** Where the button sits: a region keyword (`'center'`, `'lower-third'`, …)\n * or normalized `{x,y}` (0–1, button center). The shared placement contract;\n * default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias for `placement={{ x }}` — horizontal center as a\n * 0–1 fraction of canvas width. */\n centerX?: number\n /** @deprecated Legacy alias for `placement={{ y }}` — vertical center as a\n * 0–1 fraction of canvas height. */\n centerY?: number\n /** Play the entrance (fade + rise on the house spring). */\n entrance?: boolean\n /** Frames before the entrance begins. */\n delay?: TimeInput\n /** Entrance duration in frames (default `DURATION.base` = 18). */\n durationInFrames?: TimeInput\n /** Play the click-dip press animation. */\n press?: boolean\n /** Frame the press dip lands on (relative to the local timeline). */\n pressFrame?: TimeInput\n}\n\nexport function Button({\n label = 'Get started',\n variant = 'primary',\n color: colorProp,\n textColor: textColorProp,\n width = 280,\n height = 72,\n cornerRadius: cornerRadiusProp,\n borderWidth = 2,\n fontSize = 24,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n placement,\n centerX,\n centerY,\n entrance = true,\n delay: delayIn = 0,\n durationInFrames: durationInFramesIn = DURATION.base,\n press = true,\n pressFrame: pressFrameIn = 30,\n}: ButtonProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const durationInFrames = framesOf(durationInFramesIn, fps)\n const pressFrame = framesOf(pressFrameIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.accent\n const textColor = textColorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Entrance: fade + rise on the house spring (ondajs's `useEntrance` rise).\n const enter = entrance\n ? entryFadeRise({ frame, fps, delay, durationInFrames })\n : { opacity: 1, y: 0 }\n const opacity = enter.opacity\n const riseY = enter.y\n\n // Press dip: down on the house ease into `pressFrame`, back out after it.\n // interpolate clamps outside the window, so scale rests at 1 until the dip\n // begins and returns to 1 once it settles.\n const pressScale = press\n ? interpolate(\n frame,\n [pressFrame - PRESS_IN, pressFrame, pressFrame + PRESS_OUT],\n [1, PRESS_SCALE, 1],\n {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n easing: HOUSE_EASE,\n },\n )\n : 1\n\n const isPrimary = variant === 'primary'\n const cornerRadius = cornerRadiusProp ?? theme.radius\n const radius = cornerRadius\n\n // Letter-spacing (ondajs `-0.01em`), in engine px. Added between glyphs, so it\n // widens the label by `tracking × (glyphs − 1)` — folded into the centering.\n const labelTracking = fontSize * -0.01\n // Estimated label extent, used to center it over the pill. No author-time\n // engine text metrics exist, so derive from glyph count × size.\n const labelWidth =\n Math.max(0, label.length) * fontSize * CHAR_WIDTH_FACTOR +\n labelTracking * Math.max(0, label.length - 1)\n const lineHeight = fontSize * LINE_RATIO\n // Text places its TOP-LEFT at (x, y); offset by half the estimated extent so\n // the label sits centered on the local origin (where the pill is also centered).\n const labelX = -labelWidth / 2\n const labelY = -lineHeight / 2\n\n const labelColor = isPrimary ? textColor : color\n\n // Canvas placement of the button's center (the local origin of the assembly)\n // via the shared placement contract. Defaults to centered, matching ondajs's\n // default `placement`; legacy `centerX`/`centerY` fractions alias 1:1.\n const resolved = usePlacement(placement ?? { x: centerX ?? 0.5, y: centerY ?? 0.5 }, {\n width,\n height,\n })\n const originX = resolved.x\n const originY = resolved.y\n\n return (\n // Canvas positioning: place the assembly's local origin at the canvas point.\n <Group x={originX} y={originY}>\n {/* Entrance fade — layout-safe, separate from the pivoted scale. */}\n <Group opacity={opacity}>\n {/* Rise translate (entrance). */}\n <Group y={riseY}>\n {/* Press scale — pivots on the local origin, the button's center,\n independent of the rise offset above. */}\n <Group scaleX={pressScale} scaleY={pressScale}>\n <Rect\n x={-width / 2}\n y={-height / 2}\n width={width}\n height={height}\n cornerRadius={radius}\n fill={isPrimary ? color : '#00000000'}\n stroke={isPrimary ? PRIMARY_BORDER : color}\n strokeWidth={isPrimary ? PRIMARY_BORDER_WIDTH : borderWidth}\n />\n <Text\n x={labelX}\n y={labelY}\n fontSize={fontSize}\n letterSpacing={letterSpacing ?? labelTracking}\n color={labelColor}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n >\n {applyTextCase(label, { uppercase })}\n </Text>\n </Group>\n </Group>\n </Group>\n </Group>\n )\n}\n","//! Callout — a speech bubble (rounded `<Rect>` body + pointer triangle `<Path>` +\n//! `<Text>` label) that lands on the house spring to annotate a spot on the\n//! canvas. Ported from ondajs.\n//!\n//! Two-phase reveal, matching the ondajs restraint signature (one move at a\n//! time): the bubble lands first (scale 0.9 → 1 + fade, `entryScale` + `entryFade`\n//! on SPRING_SMOOTH), then after a `lineDelay` beat the pointer triangle eases in\n//! toward the anchor (`entryFadeRise`). The eye is never asked to track two\n//! things at once.\n//!\n//! Divergence from the ondajs original: ondajs drew an anchor-relative arrow\n//! LINE that strokes on via `@remotion/paths` `evolvePath` (a stroke-dash\n//! reveal). The scene graph has NO stroke-dash animation, so the faithful\n//! scene-graph equivalent of \"an annotation that points\" is a classic speech\n//! bubble with a pointer triangle whose SIDE is chosen by `direction`. Prop\n//! names that carry over (label, x, y, delay, duration, lineDelay, color,\n//! bgColor, borderColor, fontSize, fontFamily) keep their ondajs meaning — in\n//! particular `x`/`y` stay 0..1 fractions of the canvas (default 0.5/0.5 =\n//! center), resolved to pixels via the composition size, exactly like ondajs.\n//!\n//! Scene-graph notes:\n//! - The bubble width is sized to the MEASURED text extent (`useTextMetrics`,\n//! proportional/exact; falls back to a glyph-count estimate until the wasm\n//! engine warms) plus horizontal padding. Pass `width` to override when the\n//! exact text extent is known.\n//! - Scene scale pivots on a node's LOCAL ORIGIN (0,0), not its center. To make\n//! the bubble grow about its own center, the scaling `<Group>` is placed at the\n//! bubble center and the body/label/pointer are drawn relative to that center.\n//! - The component anchors itself via the `x`/`y` props (canvas fractions), so it\n//! is NOT a layout child — drop it directly in a scene; do not place it inside a\n//! `<Flex>`/`<AbsoluteFill>` and also rely on its own x/y.\n\nimport { Group, Path, Rect, Text, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { entryFade, entryFadeRise, entryScale } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Default bubble surface. The theme `surface` (~`#121217`) sits barely above\n * the canvas (`#0a0d17`), so a speech bubble drawn with it vanishes. A callout\n * is an annotation that must POP off the canvas, so its default fill is an\n * elevated, lighter surface (a translucent white wash, `#rrggbbaa`, that lifts\n * whatever the background is). An explicit `bgColor` prop still wins. */\nconst ELEVATED_SURFACE = '#ffffff1a' // white @ ~10%\n\n/** Default bubble border — a brighter hairline than the theme `border`\n * (~`#26262c`) so the bubble + pointer read a clear edge on the dark canvas. */\nconst ELEVATED_BORDER = '#ffffff47' // white @ ~28%\n\n/** How far the pointer's base overlaps INTO the bubble body (px). The bubble is\n * drawn on top of this overlap, so the tail and body share one continuous fill\n * with no seam at the edge. A couple of px absorbs sub-pixel/anti-alias gaps. */\nconst POINTER_OVERLAP = 2\n\n/** Which side of the bubble the pointer triangle sticks out from (and thus the\n * rough direction the callout is aimed). */\nexport type CalloutDirection = 'top' | 'bottom' | 'left' | 'right'\n\nexport interface CalloutProps extends TextStyleProps {\n /** Bubble label. Single line — no auto-wrap. */\n label?: string\n /** Where the bubble sits: a region keyword (`'center'`, `'lower-third'`, …)\n * or normalized `{x,y}` (0–1, bubble center). The shared placement contract;\n * default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias for `placement={{ x }}` — bubble-center X as a\n * 0..1 fraction of canvas width. */\n x?: number\n /** @deprecated Legacy alias for `placement={{ y }}` — bubble-center Y as a\n * 0..1 fraction of canvas height. */\n y?: number\n /** Side the pointer triangle sticks out from (default `'bottom'`). */\n direction?: CalloutDirection\n /** Frames before the bubble starts revealing. */\n delay?: TimeInput\n /** Bubble scale-and-fade reveal duration in frames (default `DURATION.base`). */\n duration?: TimeInput\n /** Frames after the bubble starts before the pointer eases in (default 6). */\n lineDelay?: TimeInput\n /** Pointer reveal duration in frames (default `DURATION.base`). */\n lineDuration?: TimeInput\n /** Bubble background fill (default: an elevated translucent-white surface that\n * lifts the bubble off the dark canvas). */\n bgColor?: string\n /** Bubble border color (default: a bright translucent-white hairline). */\n borderColor?: string\n /** Bubble border width in px (default 1). */\n borderWidth?: number\n /** Label font size in px (default 20). */\n fontSize?: number\n /** Horizontal padding inside the bubble (default 14). */\n paddingX?: number\n /** Vertical padding inside the bubble (default 8). */\n paddingY?: number\n /** Bubble corner radius (default: theme `radius`). */\n cornerRadius?: number\n /** Pointer triangle base width in px (default 18). */\n pointerWidth?: number\n /** Pointer triangle length (how far it pokes out) in px (default 12). */\n pointerLength?: number\n /** Explicit bubble width in px. Overrides the measured text extent. */\n width?: number\n}\n\nexport function Callout({\n label = 'Look here',\n placement,\n x,\n y,\n direction = 'bottom',\n delay: delayIn = 0,\n duration: durationIn = DURATION.base,\n lineDelay: lineDelayIn = 6,\n lineDuration: lineDurationIn = DURATION.base,\n color: colorProp,\n bgColor: bgColorProp,\n borderColor: borderColorProp,\n borderWidth = 1,\n fontSize = 20,\n fontFamily: fontFamilyProp,\n fontWeight = 500,\n letterSpacing,\n uppercase,\n paddingX = 14,\n paddingY = 8,\n cornerRadius: cornerRadiusProp,\n pointerWidth = 18,\n pointerLength = 12,\n width,\n}: CalloutProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const lineDelay = framesOf(lineDelayIn, fps)\n const lineDuration = framesOf(lineDurationIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n // Default to an elevated surface/border (not the near-black theme tokens) so\n // the bubble + pointer separate from the dark canvas; explicit props win.\n const bgColor = bgColorProp ?? ELEVATED_SURFACE\n const borderColor = borderColorProp ?? ELEVATED_BORDER\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n const cornerRadius = cornerRadiusProp ?? theme.radius\n const labelText = applyTextCase(label, { uppercase })\n\n // Real shaped label width (overridable via `width`). The engine measures it\n // (proportional — exact); falls back to a glyph-count estimate until the wasm\n // engine warms in the browser, or if `width` is passed.\n const measured = useTextMetrics(labelText, fontSize, { fontFamily, fontWeight })\n\n // Bubble box, sized to the measured text extent unless `width` is given.\n const textWidth = measured.width\n const bubbleW = width ?? Math.round(textWidth + paddingX * 2)\n // Engine line box height ≈ fontSize * 1.2; add vertical padding.\n const bubbleH = Math.round(fontSize * 1.2 + paddingY * 2)\n\n // Bubble center via the shared placement contract. Legacy fractional `x`/`y`\n // were already bubble-center anchored (ondajs semantics), so they alias 1:1;\n // the default is centered, exactly as before.\n const resolved = usePlacement(placement ?? { x: x ?? 0.5, y: y ?? 0.5 }, {\n width: bubbleW,\n height: bubbleH,\n })\n const centerX = resolved.x\n const centerY = resolved.y\n\n // Bubble reveal — entryScale (0.9 → 1) for the transform, entryFade for the\n // matching opacity. Both on SPRING_SMOOTH so fade and scale stay locked.\n const fade = entryFade({ frame, fps, delay, durationInFrames: duration })\n const grow = entryScale({ frame, fps, delay, durationInFrames: duration })\n\n // Pointer eases in after the bubble lands — one-thing-at-a-time pacing. Rises\n // toward the bubble (replacing the ondajs arrow's draw-on beat).\n const pointerMotion = entryFadeRise({\n frame,\n fps,\n delay: delay + lineDelay,\n durationInFrames: lineDuration,\n travelPx: 6,\n })\n\n // Half-extents — everything is drawn relative to the bubble CENTER so the\n // scale (which pivots on the scaling group's local origin) grows about center.\n const halfW = bubbleW / 2\n const halfH = bubbleH / 2\n\n // Pointer triangle in bubble-center-relative coordinates. Apex points outward\n // along `direction`; the base OVERLAPS into the bubble body (by `POINTER_OVERLAP`)\n // so the bubble — drawn on top — covers the base seam and the tail fuses with\n // the body into one continuous surface. `fill` is the closed (overlapping)\n // triangle drawn UNDER the bubble; `outline` is just the two outer edges\n // (apex → each base corner, no base line), drawn OVER the bubble so the border\n // wraps the tail and meets the bubble's edge stroke flush.\n const pointer = buildPointer(direction, halfW, halfH, pointerWidth, pointerLength)\n\n // Text top-left, centered in the bubble (relative to center). The engine's\n // line box is ~fontSize * 1.2 tall, so center on that to sit on the optical\n // baseline band.\n const textX = -textWidth / 2\n const textY = -(fontSize * 1.2) / 2\n\n return (\n // Outer Group: place the bubble center at (centerX, centerY).\n <Group x={centerX} y={centerY}>\n {/* Scaling group: origin at bubble center, so entryScale grows about center. */}\n <Group scaleX={grow.scaleX} scaleY={grow.scaleY} opacity={fade.opacity}>\n {/* Tail fill — fades/rises in slightly after the bubble (one-thing-at-a-\n time pacing). Drawn FIRST, with its base overlapping up into the body,\n so the bubble (next) paints over the base and no seam shows. Same fill\n as the body, so the tail reads as the same lifted surface. */}\n <Group opacity={pointerMotion.opacity} x={pointerMotion.x} y={pointerMotion.y}>\n <Path d={pointer.fill} fill={bgColor} />\n </Group>\n\n {/* Bubble body, drawn over the tail base to hide the overlap seam. */}\n <Rect\n x={-halfW}\n y={-halfH}\n width={bubbleW}\n height={bubbleH}\n cornerRadius={cornerRadius}\n fill={bgColor}\n stroke={borderWidth > 0 ? borderColor : undefined}\n strokeWidth={borderWidth}\n />\n\n {/* Tail outer edges (apex → each base corner, no base line), drawn OVER\n the bubble — and on the same pointer motion as the fill — so the border\n wraps the tail and joins the bubble's bottom-edge stroke flush. */}\n {borderWidth > 0 ? (\n <Group opacity={pointerMotion.opacity} x={pointerMotion.x} y={pointerMotion.y}>\n <Path d={pointer.outline} stroke={borderColor} strokeWidth={borderWidth} />\n </Group>\n ) : null}\n\n {/* Label. */}\n <Text\n x={textX}\n y={textY}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n letterSpacing={letterSpacing}\n >\n {labelText}\n </Text>\n </Group>\n </Group>\n )\n}\n\n/** Pointer-triangle geometry in bubble-center-relative space, as two SVG paths:\n * - `fill`: a CLOSED triangle whose base sits `POINTER_OVERLAP` px INSIDE the\n * bubble edge, so the bubble (painted on top) covers the base and the tail\n * fuses with the body into one seamless surface.\n * - `outline`: an OPEN path of just the two outer edges (base corner → apex →\n * base corner, no base line), with the corners ON the bubble edge so the tail\n * border meets the bubble's edge stroke flush — no chevron, no seam.\n * The apex pokes out by `length` along `direction`. */\nfunction buildPointer(\n direction: CalloutDirection,\n halfW: number,\n halfH: number,\n base: number,\n length: number,\n): { fill: string; outline: string } {\n const h = base / 2\n const o = POINTER_OVERLAP\n switch (direction) {\n case 'top':\n // Apex above the top edge; base overlaps down into the body.\n return {\n fill: `M ${-h} ${-halfH + o} L ${h} ${-halfH + o} L 0 ${-halfH - length} Z`,\n outline: `M ${-h} ${-halfH} L 0 ${-halfH - length} L ${h} ${-halfH}`,\n }\n case 'left':\n // Apex left of the left edge; base overlaps right into the body.\n return {\n fill: `M ${-halfW + o} ${-h} L ${-halfW + o} ${h} L ${-halfW - length} 0 Z`,\n outline: `M ${-halfW} ${-h} L ${-halfW - length} 0 L ${-halfW} ${h}`,\n }\n case 'right':\n // Apex right of the right edge; base overlaps left into the body.\n return {\n fill: `M ${halfW - o} ${-h} L ${halfW - o} ${h} L ${halfW + length} 0 Z`,\n outline: `M ${halfW} ${-h} L ${halfW + length} 0 L ${halfW} ${h}`,\n }\n default:\n // 'bottom' — apex below the bottom edge; base overlaps up into the body.\n return {\n fill: `M ${-h} ${halfH - o} L ${h} ${halfH - o} L 0 ${halfH + length} Z`,\n outline: `M ${-h} ${halfH} L 0 ${halfH + length} L ${h} ${halfH}`,\n }\n }\n}\n","//! CameraShake — wraps children in a deterministic, decaying camera shake.\n//! Ported from ondajs.\n//!\n//! Jitters the x/y translate (and an optional slight rotation) of a wrapping\n//! `<Group>` using the engine's seeded `random()` — same `seed` + frame always\n//! yields the same offset, so the shake is identical across renders and threads.\n//! NEVER `Math.random()` in a render path.\n//!\n//! The shake is a contained event: it only fires inside `[delay, delay +\n//! duration]`. Before and after that window the offset is exactly 0, so wrapped\n//! content sits perfectly still. With `decay` (the default) the amplitude ramps\n//! linearly to 0 across the window, so the camera settles to rest by the end.\n//!\n//! Layout: the child is centered in the composition by an outer\n//! `<AbsoluteFill>` (justify/align center), and the shake is a SMALL ± offset\n//! applied by the inner motion `<Group>` ON TOP of that centered rest position —\n//! never a large absolute translate from the top-left origin. The motion\n//! `<Group>` is the AbsoluteFill's child, so the layout pass centers its box and\n//! the jitter rides on top (HARD RULE 2 holds: the box itself doesn't reflow).\n//! The `x`/`y` props nudge the rest position relative to that center.\n//!\n//! Engine note: `rotation` renders on the Vello/GPU backend; the CPU reference\n//! rasterizer ignores it (the x/y jitter still applies on both). Keep\n//! `rotationIntensity` small — a fraction of a degree reads as a hand-held\n//! wobble; more reads as a tumble.\n\nimport {\n AbsoluteFill,\n Group,\n random,\n useCurrentFrame,\n useVideoConfig,\n variantSeed,\n} from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { DURATION } from '../motion.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface CameraShakeProps {\n /** Frames before the shake starts. Outside the window, offset is 0. */\n delay?: TimeInput\n /** Frames the shake lasts. Before `delay` / after `delay + duration`, the\n * offset is exactly 0 and content is still. */\n duration?: TimeInput\n /** Maximum positional offset in px. Restrained by default — bump for impact\n * moments. */\n intensity?: number\n /** Maximum rotation amplitude in degrees (GPU/Vello only). A subtle wobble by\n * default; set `0` for pure translational shake. */\n rotationIntensity?: number\n /** PRNG seed — same seed always produces the same shake. */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Linearly decay intensity (and rotation) to 0 over `duration`, so the camera\n * settles to rest by the end. Default `true`. */\n decay?: boolean\n /** Rest x of the wrapper in px (the shake jitters around this). */\n x?: number\n /** Rest y of the wrapper in px (the shake jitters around this). */\n y?: number\n /** Content to shake. */\n children?: ReactNode\n}\n\nexport function CameraShake({\n delay: delayIn = 0,\n duration: durationIn = DURATION.slow,\n intensity = 4,\n rotationIntensity = 0.6,\n seed: seedProp = 0,\n variant,\n decay = true,\n x = 0,\n y = 0,\n children,\n}: CameraShakeProps) {\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const frame = useCurrentFrame()\n const local = frame - delay\n\n // Only shake inside [delay, delay + duration]; otherwise sit perfectly still.\n let offsetX = 0\n let offsetY = 0\n let rotation = 0\n\n if (local >= 0 && local <= duration) {\n const progress = duration > 0 ? local / duration : 1\n // Decay linearly so the shake settles by the end — restraint over time.\n const falloff = decay ? 1 - progress : 1\n const currentIntensity = intensity * falloff\n const currentRotation = rotationIntensity * falloff\n\n // Seeded, deterministic offsets in [-1, 1) per axis. Mirrors the ondajs seed\n // math (frame * 2 for x, +1 for y) and adds a third stream for rotation so\n // the three axes don't move in lockstep.\n offsetX = (random(seed + frame * 3) - 0.5) * 2 * currentIntensity\n offsetY = (random(seed + frame * 3 + 1) - 0.5) * 2 * currentIntensity\n rotation = (random(seed + frame * 3 + 2) - 0.5) * 2 * currentRotation\n }\n\n // Center the child in the composition, then jitter it with the SMALL shake\n // offset on top — the shake oscillates around the centered rest position\n // rather than displacing from the top-left origin.\n return (\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Group x={x + offsetX} y={y + offsetY} rotation={rotation}>\n {children}\n </Group>\n </AbsoluteFill>\n )\n}\n","//! CardShowcase — a premium card/product showcase (fintech / brand ads). Three\n//! tilted rows of cards slide as a seamless conveyor (top → right, middle → left,\n//! bottom → right; the tilt makes those read as diagonals). Near the end the whole\n//! grid ROTATES right to flat (un-tilts) while still sliding, the slide settles,\n//! then the middle row parts to open a center gap where a logo pops + fades in.\n//! All motion is a pure function of frame.\n\nimport { Group, Rect, Text, interpolate, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface CardShowcaseProps {\n brand?: string\n network?: string\n cardNumber?: string\n heroColor?: string\n heroTextColor?: string\n tierColors?: string[]\n background?: string\n tilt?: number\n /** Slide speed in px/sec (rightward magnitude; per-row direction is applied). */\n speed?: number\n /** Center logo text revealed at the end (e.g. a brand). Empty = no logo. */\n logo?: string\n logoColor?: string\n duration?: TimeInput\n}\n\nconst CARD_W = 520\nconst CARD_H = 326\nconst RADIUS = 30\nconst COLS = 8\nconst ROWH = 400\nconst ss = (t: number) => t * t * (3 - 2 * t)\nconst mod = (a: number, b: number) => ((a % b) + b) % b\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport function CardShowcase({\n brand = 'Lumen',\n network = 'VISA',\n cardNumber = '···· 3346',\n heroColor = '#3D2BE0',\n heroTextColor = '#EAEAFF',\n tierColors = ['#111114', '#F3F3F6', '#8E93A1'],\n background = '#ECECEF',\n tilt = -22,\n speed = 320,\n logo = '',\n logoColor,\n duration: durationIn = '10s',\n}: CardShowcaseProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n const theme = useTheme()\n const D = framesOf(durationIn, fps)\n const cx = width / 2\n const cy = height / 2\n const family = theme.fontFamily\n\n const palette = [heroColor, ...tierColors]\n const N = palette.length\n const COLW = 600\n const band = COLS * COLW\n const leftLimit = cx - band / 2\n\n // ── timeline ──────────────────────────────────────────────────────────────\n // slide (constant velocity, then a smooth decel to a stop), un-tilt, gap, logo.\n const tDecel = 0.6 * D\n const tStop = 0.82 * D\n const v = speed / fps\n let shift: number\n if (frame <= tDecel) shift = v * frame\n else {\n const u = Math.min((frame - tDecel) / (tStop - tDecel), 1)\n shift = v * tDecel + v * (tStop - tDecel) * (u - (u * u) / 2) // velocity → 0\n }\n // rotate the whole group right to flat (un-tilt) while it's still sliding\n const rotation = interpolate(frame, [0, 0.5 * D, 0.76 * D], [tilt, tilt, 0], {\n easing: ss,\n ...CLAMP,\n })\n const zoom = interpolate(frame, [0, 0.2 * D, D], [1.06, 1.1, 1.0], { easing: ss, ...CLAMP })\n // the middle row parts to open a center gap (after it's flat) — wide enough to\n // fully clear the logo (a centered card pushed by `gap` clears ~gap−CARD_W/2 each side)\n const gap = interpolate(frame, [0.83 * D, 0.95 * D], [0, 620], { easing: ss, ...CLAMP })\n // logo pop + fade into the gap\n const logoOp = interpolate(frame, [0.86 * D, 0.97 * D], [0, 1], CLAMP)\n const logoScale = interpolate(frame, [0.86 * D, 0.93 * D, D], [0.55, 1.08, 1.0], {\n easing: ss,\n ...CLAMP,\n })\n\n const rowDir = [1, -1, 1] // top → right, middle → left, bottom → right\n const cards: { x: number; y: number; ci: number; key: string }[] = []\n for (let r = 0; r < 3; r++) {\n const rowPhase = r * COLW * 0.5\n for (let j = 0; j < COLS; j++) {\n let x = leftLimit + mod(j * COLW + rowPhase + (rowDir[r] ?? 1) * shift, band)\n const y = cy + (r - 1) * ROWH\n if (r === 1) x += (x >= cx ? 1 : -1) * gap // middle row parts for the logo\n const ci = mod(j + r * 2, N)\n cards.push({ x, y, ci, key: `${r}:${j}` })\n }\n }\n\n const logoCol = logoColor ?? heroColor\n const LOGO = 190\n const logoX = cx - logo.length * 0.6 * LOGO * 0.5 // approx-center the wordmark\n\n return (\n <Group>\n <Group originX={cx} originY={cy} scaleX={zoom} scaleY={zoom} rotation={rotation}>\n <Rect x={-width} y={-height} width={width * 3} height={height * 3} fill={background} />\n {cards.map(({ x, y, ci, key }) => {\n const hero = ci === 0\n const col = palette[ci] ?? '#1B1C22'\n const isLight = !hero && /^#(f|e|d|c)/i.test(col)\n const inkBig = hero ? heroTextColor : isLight ? '#2A2A30' : '#FFFFFFEB'\n const inkMuted = hero ? heroTextColor : isLight ? '#7A7A85' : '#FFFFFF8C'\n return (\n <Group key={key} x={x} y={y}>\n <Rect\n x={-CARD_W / 2}\n y={-CARD_H / 2}\n width={CARD_W}\n height={CARD_H}\n cornerRadius={RADIUS}\n fill={col}\n />\n <Text\n x={CARD_W / 2 - 150}\n y={-CARD_H / 2 + 34}\n fontSize={38}\n fontWeight={800}\n fontFamily={family}\n color={inkBig}\n >\n {network}\n </Text>\n <Text\n x={-CARD_W / 2 + 42}\n y={-26}\n fontSize={26}\n fontWeight={600}\n fontFamily={family}\n color={inkMuted}\n >\n {cardNumber}\n </Text>\n <Text\n x={-CARD_W / 2 + 38}\n y={CARD_H / 2 - 132}\n fontSize={hero ? 112 : 96}\n fontWeight={800}\n fontFamily={family}\n color={inkBig}\n >\n {brand}\n </Text>\n </Group>\n )\n })}\n </Group>\n {logo && logoOp > 0.001 ? (\n <Group originX={cx} originY={cy} scaleX={logoScale} scaleY={logoScale} opacity={logoOp}>\n <Text\n x={logoX}\n y={cy - LOGO * 0.6}\n fontSize={LOGO}\n fontWeight={900}\n fontFamily={family}\n color={logoCol}\n >\n {logo}\n </Text>\n </Group>\n ) : null}\n </Group>\n )\n}\n","//! Captions — sequential captions driven by a timed transcript.\n//! Ported from ondajs (`captions`).\n//!\n//! Each entry is a caption (a word or short phrase) plus its `[startMs, endMs)`\n//! window — the shape every speech-to-text / transcript tool already speaks. The\n//! local frame (after `delay`) is converted to milliseconds via `fps`, so the\n//! timeline is authored in real-world ms and stays correct at any framerate.\n//!\n//! Only the ACTIVE caption — the one whose `[startMs, endMs)` window contains the\n//! current time — is on screen at any frame; captions replace one another in\n//! place rather than the whole transcript piling up. The active caption sits in\n//! the lower-third band by default (the broadcast subtitle position). Its words\n//! don't pop in: they lift the house move — a small `translateY` + opacity fade\n//! on `SPRING_SMOOTH`, cascaded word-by-word on the canonical `staggerFrames`\n//! wave so the line reads as a settled reveal, not a flash. The word the eye is\n//! landing on carries the one earned `accent`; words it has already passed settle\n//! back to near-white `text` — the karaoke contrast every premium captioner uses.\n//!\n//! Scene-graph notes vs the ondajs (CSS) original:\n//! - The centered origin is derived from the caption's MEASURED width (the\n//! engine shapes the text — proportional, exact; a glyph-count estimate is the\n//! fallback until the wasm engine warms in the browser). Each word is its own\n//! `<Text>`, laid out left-to-right by the cumulative measured advance of the\n//! words before it, so the line stays centered and the per-word colors/reveals\n//! never reflow it. Only one caption window shows at a time, so there is no row\n//! to stack.\n//! - Per-word reveal offsets the `<Text>` by its own `translateY`; the whole line\n//! is centered inside a `<Group>` placed at the band anchor, so the lift grows\n//! the words in place instead of drifting the block toward a corner.\n//! - `letterSpacing` / `lineHeight` are CSS-only knobs the scene `<Text>` does\n//! not expose; `letterSpacing` is folded into the measured width so centering\n//! stays exact; `lineHeight` is accepted for prop-shape parity with ondajs but\n//! not applied (see `approximations`). Line height comes from the engine's\n//! fixed text box instead.\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH, staggerFrames } from '../motion.js'\nimport { letterSpacingPx, measureText, useTextMetricsReady } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** One word inside a phrase, with its own spoken `[startMs, endMs)` window. */\nexport interface CaptionWord {\n text: string\n startMs: number\n endMs: number\n}\n\n/** One transcript entry: a word and its `[startMs, endMs)` activation window. */\nexport interface CaptionEntry {\n text: string\n startMs: number\n endMs: number\n /** Optional per-word timing. When present, the WHOLE phrase shows at once and\n * each word lights up the instant it is spoken (`currentMs` inside that word's\n * `[startMs, endMs)`) — true word-synced karaoke — instead of the default\n * cascade-timed reveal where words fade in on a fixed stagger and the accent\n * follows that wave. The shape `onda transcribe` emits per segment. */\n words?: CaptionWord[]\n}\n\nexport interface CaptionsProps extends TextStyleProps {\n /** The transcript timeline. Each entry is a word + its `[startMs, endMs)`\n * window — the format every STT / transcript tool already speaks. */\n captions?: CaptionEntry[]\n /** Frames before the timeline starts (shifts every `startMs` by this). */\n delay?: TimeInput\n /** Active word color — the one earned accent, carried by the word the eye is\n * currently landing on as the line cascades in (default: theme `accent`). */\n accentColor?: string\n /** Font size in px. */\n fontSize?: number\n /** Unitless line height. Accepted for prop-shape parity with ondajs; the scene\n * `<Text>` has a fixed text box, so it is NOT applied (see `approximations`). */\n lineHeight?: number\n /** Text alignment of the caption block within its line(s). */\n align?: 'left' | 'center' | 'right'\n /** Vertical placement band of the block. Captions sit in the lower third by\n * default; `'center'`/`'top'`/`'upper-third'`/`'bottom'` reposition it (the\n * historical band values). A normalized `{x,y}` point (0-1, line center) is\n * also accepted per the shared placement contract. */\n placement?:\n | 'center'\n | 'top'\n | 'bottom'\n | 'upper-third'\n | 'lower-third'\n | { x?: number; y?: number }\n /** Max line width as a 0–1 fraction of canvas width — the block wraps to more\n * lines within this (default 0.8) instead of overflowing the frame. */\n maxWidth?: number\n /** Legibility backing so captions read over any footage (Text has no native\n * stroke). `'shadow'` (default) drops a soft dark copy behind each word;\n * `'outline'` rings each word in dark — the classic black-border caption that\n * reads over ANYTHING; `'box'` lays a rounded translucent card behind the\n * whole block (the CapCut subtitle look); `'none'` for clean plates. */\n backdrop?: 'none' | 'shadow' | 'outline' | 'box'\n /** Backing color for `'shadow'`/`'outline'`/`'box'` (default near-black). */\n backdropColor?: string\n /** How the active word is emphasized. `'color'` (default) recolors it to the\n * accent; `'box'` seats it in a rounded accent pill with dark text (the\n * dominant short-form caption look). */\n highlight?: 'color' | 'box'\n}\n\nconst DEFAULT_CAPTIONS: CaptionEntry[] = [\n { text: 'Onda', startMs: 0, endMs: 1500 },\n { text: 'kinetic', startMs: 1500, endMs: 3000 },\n { text: 'captions', startMs: 3000, endMs: 4500 },\n]\n\n// Vertical placement → the caption baseline-band centre as a 0–1 fraction of\n// canvas height. `lower-third` (the broadcast subtitle position, ~0.78) is the\n// default; the others reposition the band toward an edge or centre.\nconst PLACEMENT_TO_BAND: Record<\n 'center' | 'top' | 'bottom' | 'upper-third' | 'lower-third',\n number\n> = {\n top: 0.12,\n 'upper-third': 0.22,\n center: 0.5,\n 'lower-third': 0.78,\n bottom: 0.88,\n}\n\nexport function Captions({\n captions = DEFAULT_CAPTIONS,\n delay: delayIn = 0,\n color: colorProp,\n accentColor: accentColorProp,\n fontSize = 96,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n letterSpacing,\n uppercase,\n align = 'center',\n placement = 'lower-third',\n maxWidth = 0.8,\n backdrop = 'shadow',\n backdropColor = '#000000',\n highlight = 'color',\n}: CaptionsProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n // The active word carries the one earned accent; words the eye has passed\n // settle back to near-white `text`.\n const accentColor = accentColorProp ?? theme.accent\n const restColor = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Convert the local frame (after `delay`) into milliseconds so the captions\n // array can be authored in real-world ms. Pure function of the current frame —\n // any frame renders correctly without prior state.\n const local = Math.max(0, frame - delay)\n const currentMs = (local / fps) * 1000\n\n // Only the ACTIVE caption shows — the one whose `[startMs, endMs)` window\n // contains the current time. Captions replace one another in place; nothing\n // renders in the gaps between windows. Pure function of the current frame.\n const active = captions.find((c) => currentMs >= c.startMs && currentMs < c.endMs)\n\n // Warm the metrics engine (browser) so the per-word `measureText` calls below\n // return real shaped advances; the hook must run every render. The fallback is\n // the glyph-count estimate until the wasm engine warms.\n useTextMetricsReady()\n\n if (!active) return null\n\n const lsPx = letterSpacingPx(letterSpacing, fontSize)\n const lineHeight = fontSize * 1.2\n\n // Word source: per-word-timed (the whole phrase is shown and each word lights\n // up at its OWN spoken time — true karaoke) when `active.words` is supplied,\n // else the phrase text split on spaces (the default cascade reveal).\n const wordTimed = !!(active.words && active.words.length > 0)\n const srcWords = (\n wordTimed\n ? // biome-ignore lint/style/noNonNullAssertion: guarded by wordTimed\n active.words!\n : active.text\n .split(/\\s+/)\n .filter(Boolean)\n .map((text) => ({ text, startMs: 0, endMs: 0 }))\n ).map((w) => ({ ...w, text: applyTextCase(w.text, { uppercase }) }))\n const spaceW = measureText(' ', fontSize, { fontFamily, fontWeight, letterSpacing: lsPx }).width\n const maxW = Math.max(0, Math.min(1, maxWidth))\n const maxWidthPx = width * maxW\n\n // Measure each word and pack them into LINES: a word that would push the\n // current line past `maxWidthPx` starts a new line (greedy wrap) instead of\n // running off-frame. `left` is the word's left edge within its own line;\n // `lineWidths[line]` is each line's shaped width (for per-line centering).\n const laid: { word: string; left: number; line: number; w: number; startMs: number }[] = []\n const lineWidths: number[] = []\n let line = 0\n let cursor = 0\n for (const sw of srcWords) {\n const ww = measureText(sw.text, fontSize, { fontFamily, fontWeight, letterSpacing: lsPx }).width\n if (cursor > 0 && cursor + ww > maxWidthPx) {\n lineWidths[line] = cursor - spaceW\n line += 1\n cursor = 0\n }\n laid.push({ word: sw.text, left: cursor, line, w: ww, startMs: sw.startMs })\n cursor += ww + spaceW\n }\n lineWidths[line] = Math.max(0, cursor - spaceW)\n const numLines = line + 1\n const widestLine = Math.max(...lineWidths)\n\n // Frames since this caption window opened — the clock its words cascade against.\n const activationLocalFrame = local - (active.startMs / 1000) * fps\n\n // The word currently carrying the accent. Word-timed: the latest word whose\n // spoken start has passed (so the glow rides the real voice and holds on the\n // last word through any gap). Default: the highest index whose stagger start\n // has passed (the freshest cascade reveal).\n let currentWord = 0\n laid.forEach((w, i) => {\n const reached = wordTimed ? currentMs >= w.startMs : activationLocalFrame >= staggerFrames(i)\n if (reached) currentWord = i\n })\n\n // Word-timed lines reveal as ONE block (a single settle on activation, words\n // stay put and only the accent moves); cascade lines lift word-by-word.\n const lineReveal = wordTimed\n ? spring({\n frame: activationLocalFrame,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n : 0\n\n // Horizontal anchor for the line's CENTRE, kept inside the `maxWidth` safe band\n // so left/right placements never kiss the frame edge.\n const margin = Math.round((width * (1 - Math.max(0, Math.min(1, maxWidth)))) / 2)\n const cx =\n typeof placement === 'object' && placement.x !== undefined\n ? placement.x * width\n : align === 'left'\n ? margin + widestLine / 2\n : align === 'right'\n ? width - margin - widestLine / 2\n : width / 2\n // Vertical anchor: the placement band centre (lower-third ≈ 0.78 by default,\n // the broadcast subtitle position), or a normalized point's y.\n const cy =\n typeof placement === 'object'\n ? (placement.y ?? 0.5) * height\n : height * PLACEMENT_TO_BAND[placement]\n\n // Each line's vertical centre, relative to the block centre (the Group origin):\n // line L sits at `(L - (numLines-1)/2) * lineHeight`, so the whole block stays\n // centred on the placement band whether it's one line or three.\n const lineCY = (l: number) => (l - (numLines - 1) / 2) * lineHeight\n // A word's left edge within the Group: its line is centred on cx.\n const wordX = (left: number, l: number) => left - (lineWidths[l] ?? 0) / 2\n\n // Drop-shadow offset for `backdrop: 'shadow'` — a soft dark copy down-right.\n const shOff = Math.max(1.5, fontSize * 0.05)\n\n return (\n // The Group sits at the band anchor; words are placed per line so the block\n // stays centred while each word reveals + the accent rides the voice.\n <Group x={cx} y={cy}>\n {/* `box` backdrop: one rounded card behind the whole (possibly multi-line)\n block, padded — the guaranteed-legible subtitle look. */}\n {backdrop === 'box' &&\n (() => {\n const padX = fontSize * 0.4\n const padY = fontSize * 0.22\n const boxW = widestLine + padX * 2\n const boxH = numLines * lineHeight + padY * 2\n return (\n <Rect\n x={-boxW / 2}\n y={-boxH / 2}\n width={boxW}\n height={boxH}\n cornerRadius={Math.min(boxH / 2, fontSize * 0.35)}\n // Translucent by default so the footage reads through the card; an\n // explicit `backdropColor` (incl. an 8-digit hex for alpha) wins.\n fill={backdropColor === '#000000' ? '#000000b3' : backdropColor}\n opacity={interpolate(lineReveal, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })}\n />\n )\n })()}\n {laid.map(({ word, left, line: l, w: ww }, i) => {\n // Reveal ramp. Word-timed: the WHOLE line shares one settle (already\n // there before the voice arrives, only the accent moves). Default: a\n // per-word SPRING_SMOOTH ramp delayed by the stagger wave (cascade).\n const reveal = wordTimed\n ? lineReveal\n : spring({\n frame: activationLocalFrame - staggerFrames(i),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n const opacity = interpolate(reveal, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n const ty = interpolate(reveal, [0, 1], [wordTimed ? 12 : 24, 0], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n // Karaoke accent: only the word the eye is landing on glows; the rest\n // settle to near-white (the last word stays accented once the line's in).\n const isCurrent = i === currentWord\n const x = wordX(left, l)\n const y = lineCY(l) - lineHeight / 2 + ty\n // Boxed active word: a rounded accent pill behind it, dark text on top.\n const boxed = highlight === 'box' && isCurrent\n const textColor = boxed ? '#0a0a0f' : isCurrent ? accentColor : restColor\n // Per-word legibility backing offsets `[dx, dy, alpha]`: `shadow` = one\n // soft copy down-right; `outline` = dark copies ringed around the word.\n const backing: [number, number, number][] = boxed\n ? []\n : backdrop === 'shadow'\n ? [[shOff, shOff, 0.55]]\n : backdrop === 'outline'\n ? [\n [shOff, 0, 1],\n [-shOff, 0, 1],\n [0, shOff, 1],\n [0, -shOff, 1],\n [shOff, shOff, 1],\n [-shOff, shOff, 1],\n [shOff, -shOff, 1],\n [-shOff, -shOff, 1],\n ]\n : []\n return (\n <Group key={i}>\n {boxed && (\n <Rect\n x={x - fontSize * 0.18}\n y={lineCY(l) - lineHeight * 0.42 + ty}\n width={ww + fontSize * 0.36}\n height={lineHeight * 0.84}\n cornerRadius={fontSize * 0.18}\n fill={accentColor}\n opacity={opacity}\n />\n )}\n {/* Per-word backing: `shadow` = one soft dark copy down-right;\n `outline` = dark copies ringed around the word (a real border\n that reads over anything). The `box` highlight already isolates\n the active word, so it skips the backing. */}\n {backing.map(([dx, dy, a], k) => (\n <Text\n key={k}\n x={x + dx}\n y={y + dy}\n fontSize={fontSize}\n color={backdropColor}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n letterSpacing={lsPx}\n opacity={opacity * a}\n >\n {word}\n </Text>\n ))}\n <Text\n x={x}\n y={y}\n fontSize={fontSize}\n color={textColor}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n letterSpacing={lsPx}\n opacity={opacity}\n >\n {word}\n </Text>\n </Group>\n )\n })}\n </Group>\n )\n}\n","//! FadeIn — pure opacity reveal (no motion). Layout-safe: applies only opacity,\n//! so it composes cleanly as a child of a `<Flex>`/`<AbsoluteFill>` layout.\n\nimport { Group, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { entryFade } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface FadeInProps {\n /** Frames to wait before starting. */\n delay?: TimeInput\n /** Frames the fade takes to settle (default `DURATION.base` = 18). */\n durationInFrames?: TimeInput\n children?: ReactNode\n}\n\nexport function FadeIn({ delay = 0, durationInFrames = DURATION.base, children }: FadeInProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const { opacity } = entryFade({ frame, fps, delay, durationInFrames })\n return <Group opacity={opacity}>{children}</Group>\n}\n","//! ChapterCard — a numbered eyebrow (\"01\") fades in above a large chapter title\n//! that rises into place; when `accent` is on, the number takes the rose and a\n//! quiet underline draws beneath the title. Centered via `<AbsoluteFill>` +\n//! `<Flex>` column so the engine's layout pass (taffy) handles stacking — no\n//! manual x/y math. Ported from ondajs.\n//!\n//! Approximations: ondajs sequences the title with `BlurReveal` (a SPRING_SMOOTH\n//! rise + CSS `blur()` falloff + fade). The engine has no blur filter, so the\n//! title uses the `entryFadeRise` choreography — the identical spring rise + fade,\n//! minus the blur ramp.\n//!\n//! The accent underline replicates ondajs's `Underline text=\"\"` (rule-only) mode:\n//! a rounded rule whose width grows 0 → full on the house spring. Its full width\n//! is ESTIMATED from `chapter.length × titleFontSize × 0.52` (no author-time\n//! engine text metrics), matching the sibling `Underline` port. The schema's CSS\n//! letter-spacing / line-height props and the semantic size-role / placement\n//! props are dropped (no engine equivalent): size roles collapse to explicit px\n//! and placement collapses to the centered `AbsoluteFill`.\n//!\n//! Layout-safety: a plain `<Group>`'s measured size is the bounding box of its\n//! children, so a per-frame motion TRANSLATE on a child of the Flex column would\n//! grow that box and reflow/jiggle the whole column (see the `WordStagger` port\n//! note). Both animated beats therefore live inside a FIXED-SIZE transparent\n//! spacer Rect: the title rises within a reserved-height row, and the rule grows\n//! within a reserved-width/height row. The spacer's constant box wins the Group\n//! bounding-box measurement, so the column never reflows as either beat animates.\n\nimport {\n AbsoluteFill,\n Flex,\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { entryFadeRise } from '../choreography.js'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { type Placement, PlacementShift } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { FadeIn } from './FadeIn.js'\n\nexport interface ChapterCardProps extends TextStyleProps {\n /** The chapter heading — the focal text on the card. */\n chapter: string\n /** Numbered index above the chapter. String so leading zeros (`\"01\"`) read as intended. */\n number?: string\n /** Frames before the number starts fading in. The whole card sequences off this. */\n delay?: TimeInput\n /** When `true`, the number takes `numberColor` (the rose) and an underline punctuates the title. */\n accent?: boolean\n /** Number color when `accent` is `true` (the Onda rose) (default: theme `accent`). */\n numberColor?: string\n /** Number color when `accent` is `false` — quiet metadata dim (default: theme `textMuted`). */\n subtitleColor?: string\n /** Number font size in px — smaller than the title, sitting above it. */\n numberFontSize?: number\n /** Number font weight. */\n numberFontWeight?: number\n /** Chapter title font size in px — the focal element. */\n titleFontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the TITLE size DOWN (never up) so the\n * title line cannot exceed the frame minus the safe margins. Default\n * `'none'` (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the title line; combines with `fit` (the\n * smaller cap wins). */\n maxWidth?: number\n /** Title font weight. */\n titleFontWeight?: number\n /** Where the card sits: a region keyword (`'center'`, `'lower-third'`, ...) or\n * normalized `{x,y}` (0-1, card center). The shared placement contract;\n * default `'center'` (the historical self-centering). */\n placement?: Placement\n}\n\n// Beat offsets — all derived from `delay` so the card is one composed sequence.\n// The number lands first as a quiet eyebrow; the title rises 10 frames later\n// (the canonical Onda follow-up cadence); the underline punctuates it as it\n// settles. Ported verbatim from the ondajs original.\nconst TITLE_OFFSET = 10\nconst UNDERLINE_OFFSET = TITLE_OFFSET + 24\n\n/** Mean glyph advance as a fraction of font size — a rough display-sans\n * heuristic, used only to size the accent rule (matches the `Underline` port). */\nconst CHAR_WIDTH_FACTOR = 0.52\n/** Engine line-box height as a multiple of font size (matches the typography\n * crate; the same ratio the `Underline`/`Highlight` ports use). Used only to\n * reserve the title slot so the rise never reflows the column. */\nconst LINE_RATIO = 1.2\n/** Title rise travel in px (the BlurReveal envelope). */\nconst TITLE_TRAVEL = 16\n\nexport function ChapterCard({\n chapter,\n number = '01',\n delay: delayIn = 0,\n accent = true,\n numberColor: numberColorProp,\n color: colorProp,\n subtitleColor: subtitleColorProp,\n numberFontSize = 32,\n numberFontWeight = 600,\n titleFontSize: titleFontSizeProp = 96,\n fit,\n maxWidth,\n titleFontWeight = 600,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n placement,\n}: ChapterCardProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const numberColor = numberColorProp ?? theme.accent\n const color = colorProp ?? theme.text\n const subtitleColor = subtitleColorProp ?? theme.textMuted\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n const chapterText = applyTextCase(chapter, { uppercase })\n\n // Opt-in auto-fit on the chapter title (the focal line).\n const titleFontSize = useFittedFontSize(chapter, titleFontSizeProp, {\n fontFamily,\n fontWeight: titleFontWeight,\n fit,\n maxWidth,\n })\n\n // Title rise — the focal beat. `entryFadeRise` is the spring rise + fade that\n // stands in for the ondajs `BlurReveal` (sans the unsupported blur).\n const title = entryFadeRise({\n frame,\n fps,\n delay: delay + TITLE_OFFSET,\n durationInFrames: DURATION.base,\n travelPx: TITLE_TRAVEL,\n })\n\n // Estimated title box, used only to reserve fixed-size spacer rows so neither\n // animated beat reflows the Flex column.\n const titleBoxWidth = chapter.length * titleFontSize * CHAR_WIDTH_FACTOR\n const titleBoxHeight = titleFontSize * LINE_RATIO\n // Reserve enough height for the text PLUS its rise travel, so the title row's\n // box stays constant while the inner text translates from +TITLE_TRAVEL → 0.\n const titleRowHeight = titleBoxHeight + TITLE_TRAVEL\n\n // Accent rule — grows 0 → full on the house spring, after the title settles.\n const ruleProgress = spring({\n frame: Math.max(0, frame - delay - UNDERLINE_OFFSET),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.fast,\n })\n const fullRuleWidth = chapter.length * titleFontSize * CHAR_WIDTH_FACTOR\n const ruleWidth = interpolate(ruleProgress, [0, 1], [0, fullRuleWidth], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n const ruleThickness = 3\n // Rule corner radius defaults to the theme `radius` token (for future override\n // capability), capped at half the rule's own thickness/width so a thin sliver\n // stays a clean rounded rule rather than bulging into a lens.\n const ruleRadius = Math.min(theme.radius, ruleThickness / 2, ruleWidth / 2)\n // Reserve a fixed-height row for the rule so the Flex column never reflows as\n // the rule width animates. Width is centered within the row by absolute x.\n const ruleRowHeight = ruleThickness + 4\n\n const gap = Math.round(numberFontSize * 0.75)\n\n return (\n // The flex column self-centers; PlacementShift moves the centered stack by\n // the center->placement delta (no-op for the default 'center').\n <PlacementShift placement={placement}>\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Flex direction=\"column\" align=\"center\" gap={gap}>\n {/* Numbered eyebrow — pure fade so the title owns the rise. Rose when\n accent is on; otherwise the dim metadata color. */}\n <FadeIn delay={delay} durationInFrames={DURATION.base}>\n <Text\n fontSize={numberFontSize}\n color={accent ? numberColor : subtitleColor}\n fontFamily={fontFamily}\n fontWeight={numberFontWeight}\n >\n {number}\n </Text>\n </FadeIn>\n\n {/* Chapter title — focal element. A fixed-size transparent spacer Rect\n reserves the row (text box + rise travel), so the rising text never\n grows the Group's bounding box and the column stays put. The text is\n laid out ABSOLUTELY inside the row (centered horizontally) and the\n inner Group carries the motion rise. */}\n <Group>\n <Rect width={titleBoxWidth} height={titleRowHeight} fill=\"#00000000\" />\n <Group y={title.y} opacity={title.opacity}>\n <Text\n fontSize={titleFontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={titleFontWeight}\n letterSpacing={letterSpacing}\n >\n {chapterText}\n </Text>\n </Group>\n </Group>\n\n {/* Accent underline — only when accent is on, so the rose stays earned.\n Rule drawn absolutely inside a fixed-height row (centered) so its\n per-frame width never reflows the column. */}\n {accent ? (\n <Group>\n <Rect width={fullRuleWidth} height={ruleRowHeight} fill=\"#00000000\" />\n {ruleWidth > 0 ? (\n <Rect\n x={(fullRuleWidth - ruleWidth) / 2}\n y={(ruleRowHeight - ruleThickness) / 2}\n width={ruleWidth}\n height={ruleThickness}\n cornerRadius={ruleRadius}\n fill={numberColor}\n />\n ) : null}\n </Group>\n ) : null}\n </Flex>\n </AbsoluteFill>\n </PlacementShift>\n )\n}\n","//! CodeBlock — syntax-highlighted source on a dark rounded panel, revealed\n//! line-by-line on a stagger. Ported from ondajs (`code-block`).\n//!\n//! ondajs renders DOM: a glass `<Surface>` with a `<pre>` whose lines are\n//! `<div>`s and tokens are `<span>`s colored by a deterministic regex\n//! tokenizer. Here the same structure becomes scene nodes — a self-positioned\n//! dark `<Rect>` panel (the \"glass\" surface), an optional macOS-style chrome\n//! bar (`<Ellipse>` dots + a title `<Text>`), and one `<Text runs={...}>` per\n//! source line. The tokenizer is ported verbatim: a single ordered regex →\n//! per-token `{text,type}` → a styled run with the type's color. Pure function\n//! of frame (§1) — no async, no Shiki, no state; frame N is reproducible.\n//!\n//! LAYOUT: the panel is centered by computing its top-left offset from the\n//! composition size (not a `<Flex>`), so the per-frame line reveals never\n//! trigger a reflow. Lines are positioned by EXPLICIT `y` inside the content\n//! `<Group>`; each line's rise+fade is a nested inner `<Group>` carrying the\n//! motion translate (HARD RULE 2 — translate lives on a child of the\n//! absolutely-positioned content group, never on a Flex child).\n//!\n//! APPROXIMATIONS:\n//! - The ondajs surface is a CSS frosted-glass panel. This renders a flat dark\n//! fill + 1px stroke; the engine now also ships a `backdropBlur` node prop\n//! (real frosted glass) this Surface could adopt in a follow-up.\n//! - Per-token colors render on the GPU (Vello) `runs` path. The CPU reference\n//! rasterizer draws a line's concatenated run text in the node style, so the\n//! syntax highlighting collapses to `textColor` there. GPU is the primary\n//! path, so this is an acceptable degradation.\n//! - Monospace column alignment relies on the engine gluing each run after the\n//! previous (it does), plus a real monospace `fontFamily` being loaded; with\n//! a proportional fallback, columns won't align (same as any code renderer).\n//! - The per-line rise uses the choreography `rise` pattern; the engine's rise\n//! travels its default 12px (ondajs requested 6px). The difference is\n//! visually negligible and the cascade reads identically.\n\nimport { Ellipse, Group, Rect, Text, useVideoConfig } from '@onda-engine/react'\nimport type { TextRunInput } from '@onda-engine/react'\nimport { useStaggeredEntrance } from '../hooks.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface CodeBlockProps extends TextStyleProps {\n /** The source to render. Newlines split into reveal-able lines. */\n code?: string\n /** Filename shown in the title bar. Empty hides the title (dots still show if `chrome`). */\n title?: string\n /** Show the macOS-style window chrome (three dots + title bar). */\n chrome?: boolean\n /** Reveal lines one-by-one instead of all at once. */\n revealLines?: boolean\n /** Frames before the first line appears. */\n delay?: TimeInput\n /** Frames between successive line reveals. */\n lineDelay?: TimeInput\n /** Code font size in px. Sized for a video canvas, not a screen UI. */\n fontSize?: number\n /** Panel width in px. */\n width?: number\n /** Default text color — identifiers, punctuation, operators (default: theme `text`). */\n textColor?: string\n /** Keyword color. A muted, dusty violet — reads as syntax, not the brand accent (default: theme `palette[1]`). */\n keywordColor?: string\n /** String literal color — dusty sage (default: theme `palette[3]`). */\n stringColor?: string\n /** Comment color (default: theme `textMuted`). */\n commentColor?: string\n /** Numeric literal color — dusty amber (default: theme `palette[2]`). */\n numberColor?: string\n /** JSX / HTML tag-name color — dusty cyan (default: theme `palette[1]`). */\n tagColor?: string\n /** Panel background fill (the \"glass\" surface) (default: theme `surface`). */\n panelColor?: string\n /** Panel border color (default: theme `border`). */\n borderColor?: string\n}\n\ntype TokenType = 'text' | 'keyword' | 'string' | 'comment' | 'number' | 'tag'\n\nconst KEYWORDS = new Set([\n 'const',\n 'let',\n 'var',\n 'function',\n 'return',\n 'if',\n 'else',\n 'for',\n 'while',\n 'import',\n 'export',\n 'from',\n 'default',\n 'class',\n 'extends',\n 'new',\n 'await',\n 'async',\n 'type',\n 'interface',\n 'of',\n 'in',\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'this',\n 'typeof',\n 'as',\n])\n\n// Deterministic, dependency-free tokenizer. A single ordered regex captures\n// comments / strings / numbers / identifiers / other; identifiers matching a\n// keyword are colored. Pure — no async, no state, safe for render (§1).\nconst TOKEN_RE =\n /(\\/\\/[^\\n]*|\\/\\*[\\s\\S]*?\\*\\/)|(`[^`]*`|\"[^\"]*\"|'[^']*')|(\\b\\d[\\d._]*\\b)|([A-Za-z_$][\\w$]*)|(\\s+|[^\\s])/g\n\nfunction tokenizeLine(line: string): Array<{ text: string; type: TokenType }> {\n const out: Array<{ text: string; type: TokenType }> = []\n // An identifier directly after `<` or `</` is a JSX/HTML tag name — color it\n // so markup reads with the variety a real editor theme has, not flat white.\n let expectTag = false\n for (const m of line.matchAll(TOKEN_RE)) {\n if (m[1]) {\n out.push({ text: m[1], type: 'comment' })\n expectTag = false\n } else if (m[2]) {\n out.push({ text: m[2], type: 'string' })\n expectTag = false\n } else if (m[3]) {\n out.push({ text: m[3], type: 'number' })\n expectTag = false\n } else if (m[4]) {\n if (expectTag) out.push({ text: m[4], type: 'tag' })\n else out.push({ text: m[4], type: KEYWORDS.has(m[4]) ? 'keyword' : 'text' })\n expectTag = false\n } else {\n const t = m[5] ?? ''\n out.push({ text: t, type: 'text' })\n // `<` opens a tag; a following `/` (closing tag) or whitespace keeps the\n // expectation alive; any other punctuation cancels it.\n if (t === '<') expectTag = true\n else if (t === '/' || /^\\s+$/.test(t)) {\n /* keep expectTag */\n } else expectTag = false\n }\n }\n return out\n}\n\nconst DEFAULT_CODE = \"const onda = motion('identity');\\nexport default onda;\"\n\nexport function CodeBlock({\n code = DEFAULT_CODE,\n title = 'onda.ts',\n chrome = true,\n revealLines = true,\n delay = 0,\n lineDelay = 3,\n fontFamily: fontFamilyProp,\n letterSpacing,\n fontSize = 48,\n width = 900,\n textColor: textColorProp,\n keywordColor: keywordColorProp,\n stringColor: stringColorProp,\n commentColor: commentColorProp,\n numberColor: numberColorProp,\n tagColor: tagColorProp,\n panelColor: panelColorProp,\n borderColor: borderColorProp,\n}: CodeBlockProps) {\n const { width: compWidth, height: compHeight } = useVideoConfig()\n const theme = useTheme()\n const fontFamily = fontFamilyProp ?? theme.monoFamily\n const textColor = textColorProp ?? theme.text\n const keywordColor = keywordColorProp ?? theme.palette[1] ?? '#B49DDD'\n const stringColor = stringColorProp ?? theme.palette[3] ?? '#9DBE9A'\n const commentColor = commentColorProp ?? theme.textMuted\n const numberColor = numberColorProp ?? theme.palette[2] ?? '#D6A87C'\n const tagColor = tagColorProp ?? theme.palette[1] ?? '#82B8C9'\n const panelColor = panelColorProp ?? theme.surface\n const borderColor = borderColorProp ?? theme.border\n\n const colorFor: Record<TokenType, string> = {\n text: textColor,\n keyword: keywordColor,\n string: stringColor,\n comment: commentColor,\n number: numberColor,\n tag: tagColor,\n }\n\n const lines = code.split('\\n')\n\n // One staggered rise per line (matches ondajs's\n // useStaggeredEntrance({ type: 'rise', ... })). When revealLines is off, all\n // lines show at once.\n const lineStyleAt = useStaggeredEntrance({\n type: 'rise',\n delay,\n increment: lineDelay,\n distance: 6,\n })\n\n // Vertical rhythm: a generous line-height for a video canvas (ondajs uses 1.6).\n const lineHeight = Math.round(fontSize * 1.6)\n // Inner padding around the code (ondajs: 28px vertical / 36px horizontal at a\n // 48px font — scaled to roughly track the font size).\n const padX = Math.round(fontSize * 0.75)\n const padY = Math.round(fontSize * 0.58)\n\n // Chrome bar geometry (only contributes height when shown).\n const dotSize = Math.round(fontSize * 0.38)\n const chromeHeight = chrome ? Math.round(fontSize * 1.5) : 0\n const titleSize = Math.round(fontSize * 0.6)\n\n // Panel size: width is fixed by the prop; height is derived from the line\n // count so the panel always wraps the code (no measurement / reflow risk).\n const codeHeight = lines.length > 0 ? lineHeight * lines.length : lineHeight\n const panelHeight = chromeHeight + padY * 2 + codeHeight\n\n // Center the fixed-size panel by computing its top-left offset directly.\n const originX = Math.round((compWidth - width) / 2)\n const originY = Math.round((compHeight - panelHeight) / 2)\n\n const cornerRadius = theme.radius ?? Math.round(fontSize * 0.4)\n\n return (\n <Group x={originX} y={originY}>\n {/* The \"glass\" panel — flat dark fill + faint border (see approximations). */}\n <Rect\n x={0}\n y={0}\n width={width}\n height={panelHeight}\n cornerRadius={cornerRadius}\n fill={panelColor}\n stroke={borderColor}\n strokeWidth={1}\n />\n\n {/* macOS-style window chrome: three dots + an optional filename. */}\n {chrome ? (\n <Group x={padX} y={0}>\n {[0, 1, 2].map((i) => (\n <Ellipse\n key={i}\n x={i * Math.round(dotSize * 1.55)}\n y={Math.round((chromeHeight - dotSize) / 2)}\n width={dotSize}\n height={dotSize}\n fill={borderColor}\n />\n ))}\n {title ? (\n <Text\n x={Math.round(dotSize * 1.55 * 3) + Math.round(fontSize * 0.5)}\n y={Math.round((chromeHeight - titleSize) / 2)}\n fontSize={titleSize}\n color={commentColor}\n fontFamily={fontFamily}\n >\n {title}\n </Text>\n ) : null}\n {/* Divider beneath the chrome bar. */}\n <Rect\n x={Math.round(-padX)}\n y={chromeHeight}\n width={width}\n height={1}\n fill={borderColor}\n />\n </Group>\n ) : null}\n\n {/* Code content. Each line is positioned by explicit y; the per-line\n rise+fade rides on a nested inner Group so the translate never sits on\n a layout child (HARD RULE 2). */}\n <Group x={padX} y={chromeHeight + padY}>\n {lines.map((line, i) => {\n const motion = revealLines ? lineStyleAt(i) : null\n const opacity = motion ? motion.opacity : 1\n const motionY = motion ? motion.y : 0\n\n const tokens = tokenizeLine(line)\n // Per-token styled runs (GPU path). A blank line still needs a Text so\n // its slot is reserved visually; render a single space run for it.\n const runs: TextRunInput[] =\n tokens.length > 0\n ? tokens.map((tok) => ({\n text: tok.text,\n color: colorFor[tok.type],\n fontSize,\n fontFamily,\n }))\n : [{ text: ' ', color: textColor, fontSize, fontFamily }]\n\n // Concatenated text is the CPU-backend fallback (single color).\n const flat = tokens.length > 0 ? line : ' '\n\n const lineY = i * lineHeight\n\n return (\n <Group key={i} y={lineY} opacity={opacity}>\n <Group y={motionY}>\n <Text\n x={0}\n y={0}\n fontSize={fontSize}\n color={textColor}\n fontFamily={fontFamily}\n letterSpacing={letterSpacing}\n runs={runs}\n >\n {flat}\n </Text>\n </Group>\n </Group>\n )\n })}\n </Group>\n </Group>\n )\n}\n","//! CodeDiff — a unified code diff panel, revealed line-by-line. Added / removed\n//! lines carry a colored left border + gutter symbol (`+`/`−`) and a tinted row\n//! backing; context lines stay neutral. Ported from ondajs (`code-diff`).\n//!\n//! Like `BarChart`, the panel has FIXED dimensions and is positioned by\n//! computing its top-left offset (centered) inside a single `<Group>` — NOT a\n//! `<Flex>` — because each line reveals with a translate (rise), and a layout\n//! container would reflow (jiggle) as the measured subtree grew. Every line\n//! sits at an EXPLICIT `y` (`rowHeight * i`); its tinted backing `<Rect>`,\n//! left-border accent `<Rect>`, gutter, and monospace `<Text>` all hang off\n//! that row's local origin.\n//!\n//! Approximations vs ondajs:\n//! - CSS `background: ${c}14` (≈8% alpha tint) → the backing `<Rect>` fill uses\n//! an `#rrggbbXX` alpha-hex string derived from the line color (suffix `14`).\n//! - The 4px CSS `border-left` is a thin accent `<Rect>` at the row's left edge.\n//! - The dimmed gutter (`opacity: 0.8` in ondajs) uses a `cc` alpha suffix\n//! (0xcc/0xff ≈ 0.8) on the line color.\n//! - Colors are normalized to 6-digit `rrggbb` before the alpha suffix is\n//! appended (via `rgbHex`), so any supported hex form is accepted without\n//! tripping the engine's strict color parser.\n//! - `letter-spacing` on the title is unsupported and dropped.\n//! - Monospace alignment relies on a monospace `fontFamily`; the engine measures\n//! each line, so columns line up if (and only if) the font is monospaced.\n//! - The window-chrome dots are `<Ellipse>` nodes; the `var(--onda-*)` CSS\n//! fallbacks are replaced with concrete hex colors.\n//! - Engine `<Text>` is single-line (no auto-wrap) — pre-split any line that\n//! would exceed the panel width.\n\nimport { Ellipse, Group, Rect, Text, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { entryFadeRise } from '../choreography.js'\nimport { DURATION, STAGGER, staggerFrames } from '../motion.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Line kind — drives gutter symbol, color, and row treatment. */\nexport type DiffLineType = 'add' | 'remove' | 'context'\n\n/** A single diff line. */\nexport interface DiffLine {\n /** The line text (no leading +/−; the gutter adds it). */\n text: string\n /** Line kind. Defaults to `'context'` when omitted. */\n type?: DiffLineType\n}\n\nexport interface CodeDiffProps extends TextStyleProps {\n /** The diff lines, top to bottom. */\n lines?: DiffLine[]\n /** Filename shown in the title bar. */\n title?: string\n /** Show window chrome (dots + title bar). */\n chrome?: boolean\n /** Reveal lines one-by-one (else all appear together). */\n revealLines?: boolean\n /** Frames before the first line appears. */\n delay?: TimeInput\n /** Frames between consecutive line reveals (default canonical `STAGGER` = 5). */\n lineDelay?: TimeInput\n /** Code font size in px. */\n fontSize?: number\n /** Panel width in px. */\n width?: number\n /** Default (context) text color (default: theme `textMuted`). */\n textColor?: string\n /** Added-line color — a restrained green (default: theme `palette[3]`). */\n addColor?: string\n /** Removed-line color — a restrained red tinted toward bg (default: `#cf6f7e`). */\n removeColor?: string\n /** Panel surface (glass) fill (default: theme `surface`). */\n surfaceColor?: string\n /** Panel border / chrome divider color (default: theme `border`). */\n borderColor?: string\n /** Panel corner radius in px (default: theme `radius`). */\n cornerRadius?: number\n /** Window-chrome traffic-light dot color (default: theme `border`). */\n chromeDotsColor?: string\n /** Window-chrome title (filename) color — the one earned accent: it names the\n * file under change (default: theme `accent`). */\n chromeTitleColor?: string\n}\n\nconst DEFAULT_LINES: DiffLine[] = [\n { text: \"const onda = motion('default');\", type: 'remove' },\n { text: \"const onda = motion('identity');\", type: 'add' },\n { text: 'export default onda;', type: 'context' },\n]\n\n// Two-hex alpha suffix (~8%) for the row backing tint — the scene equivalent of\n// ondajs's `${color}14` (0x14 / 0xff ≈ 0.078).\nconst TINT_ALPHA = '14'\n// Two-hex alpha suffix (~80%) for the dimmed gutter glyph — the scene\n// equivalent of ondajs's `opacity: 0.8` (0xcc / 0xff ≈ 0.8).\nconst GUTTER_ALPHA = 'cc'\n\n// Removed-line default — a restrained, desaturated red pulled toward the dark bg\n// (not a garish diff-tool neon), paired with the muted `palette[3]` green for\n// adds. The theme accent is freed for the ONE earned highlight (the filename).\nconst RESTRAINED_RED = '#cf6f7e'\n\n/** Strip a leading `#` and any trailing alpha, yielding a clean 6-digit\n * `rrggbb` so an alpha suffix can be appended without tripping the engine's\n * strict color parser. Mirrors the helper in `Vignette.tsx`. */\nfunction rgbHex(color: string): string {\n let hex = color.startsWith('#') ? color.slice(1) : color\n if (hex.length === 3 || hex.length === 4) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n hex = `${r}${r}${g}${g}${b}${b}`\n }\n return hex.slice(0, 6).padEnd(6, '0')\n}\n\nexport function CodeDiff({\n lines = DEFAULT_LINES,\n title = 'motion.ts',\n chrome = true,\n revealLines = true,\n delay: delayIn = 0,\n lineDelay: lineDelayIn = STAGGER,\n fontFamily: fontFamilyProp,\n letterSpacing,\n fontSize = 44,\n width = 760,\n textColor: textColorProp,\n addColor: addColorProp,\n removeColor: removeColorProp,\n surfaceColor: surfaceColorProp,\n borderColor: borderColorProp,\n cornerRadius: cornerRadiusProp,\n chromeDotsColor: chromeDotsColorProp,\n chromeTitleColor: chromeTitleColorProp,\n}: CodeDiffProps) {\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const lineDelay = framesOf(lineDelayIn, fps)\n const theme = useTheme()\n const fontFamily = fontFamilyProp ?? theme.monoFamily ?? theme.fontFamily\n const textColor = textColorProp ?? theme.textMuted\n const addColor = addColorProp ?? theme.palette[3] ?? '#7fb58c'\n const removeColor = removeColorProp ?? RESTRAINED_RED\n const surfaceColor = surfaceColorProp ?? theme.surface\n const borderColor = borderColorProp ?? theme.border\n const cornerRadius = cornerRadiusProp ?? theme.radius\n const chromeDotsColor = chromeDotsColorProp ?? theme.border\n // The one earned accent: the filename names the subject under change.\n const chromeTitleColor = chromeTitleColorProp ?? theme.accent\n\n // Monospace line box height (CSS line-height 1.6 in ondajs).\n const lineHeight = Math.round(fontSize * 1.6)\n // Left padding before the gutter; gutter is ~1.4em wide.\n const padLeft = 18\n const gutterWidth = Math.round(fontSize * 1.4)\n const accentBarWidth = 4\n\n // Vertical padding around the code block (CSS `24px 0`).\n const codePadY = 24\n const chromeHeight = chrome ? Math.round(fontSize * 1.2) + 36 : 0\n\n const codeBlockHeight = lines.length > 0 ? lines.length * lineHeight : 0\n const panelHeight = chromeHeight + codePadY * 2 + codeBlockHeight\n\n // Center the fixed-size panel by computing its top-left offset directly — no\n // layout container, so the per-frame line rise never triggers a reflow.\n const originX = Math.round((compWidth - width) / 2)\n const originY = Math.round((compHeight - panelHeight) / 2)\n\n const dotRadius = 9\n const dotGap = 10\n\n const colorFor = (t: DiffLineType): string =>\n t === 'add' ? addColor : t === 'remove' ? removeColor : textColor\n const gutterFor = (t: DiffLineType): string => (t === 'add' ? '+' : t === 'remove' ? '−' : '')\n\n return (\n <Group x={originX} y={originY}>\n {/* Glass surface. A soft, large-radius, low-opacity drop shadow tinted\n toward the dark bg (not hard black) lifts the panel off the canvas. */}\n <Rect\n x={0}\n y={0}\n width={width}\n height={panelHeight}\n cornerRadius={cornerRadius}\n fill={surfaceColor}\n stroke={borderColor}\n strokeWidth={1}\n shadow={{ color: `#${rgbHex(theme.background)}66`, blur: 36, offsetY: 18 }}\n />\n\n {chrome ? (\n <Group x={0} y={0}>\n {/* Three traffic-light dots, vertically centered in the chrome bar. */}\n {[0, 1, 2].map((d) => (\n <Ellipse\n key={`dot-${d}`}\n x={24 + d * (dotRadius * 2 + dotGap) + dotRadius}\n y={Math.round(chromeHeight / 2)}\n width={dotRadius * 2}\n height={dotRadius * 2}\n fill={chromeDotsColor}\n />\n ))}\n {/* Filename label, to the right of the dots — the earned accent. Tight\n negative tracking + a touch more weight give it a little authority. */}\n <Text\n x={24 + 3 * (dotRadius * 2 + dotGap) + 10}\n y={Math.round((chromeHeight - fontSize * 0.6) / 2)}\n fontSize={Math.round(fontSize * 0.6)}\n letterSpacing={Math.round(fontSize * 0.6) * -0.02}\n fontWeight={500}\n color={chromeTitleColor}\n fontFamily={fontFamily}\n >\n {title}\n </Text>\n {/* Divider under the chrome bar. */}\n <Rect x={0} y={chromeHeight} width={width} height={1} fill={borderColor} />\n </Group>\n ) : null}\n\n {/* Code block. Each line sits at an explicit y; reveal is a per-line rise. */}\n <Group x={0} y={chromeHeight + codePadY}>\n {lines.map((line, i) => {\n const type: DiffLineType = line.type ?? 'context'\n const c = colorFor(type)\n const tinted = type !== 'context'\n const gutter = gutterFor(type)\n const rgb = rgbHex(c)\n\n // Per-line staggered rise — a confident settled lift on the house\n // spring (`entryFadeRise` is SPRING_SMOOTH), one line per STAGGER beat.\n const motion = revealLines\n ? entryFadeRise({\n frame,\n fps,\n delay: delay + staggerFrames(i, lineDelay),\n durationInFrames: DURATION.base,\n travelPx: 10,\n })\n : { opacity: 1, y: 0 }\n\n const rowY = i * lineHeight\n // Center the glyph baseline-ish within the line box.\n const textY = rowY + Math.round((lineHeight - fontSize) / 2)\n\n return (\n <Group key={`line-${i}`} y={motion.y} opacity={motion.opacity}>\n {tinted ? (\n <>\n {/* Row backing tint (≈8% of the line color). */}\n <Rect\n x={0}\n y={rowY}\n width={width}\n height={lineHeight}\n fill={`#${rgb}${TINT_ALPHA}`}\n />\n {/* Left-border accent. */}\n <Rect x={0} y={rowY} width={accentBarWidth} height={lineHeight} fill={c} />\n </>\n ) : null}\n\n {/* Gutter symbol (+/−), dimmed slightly via alpha, weighted a touch\n heavier so the change reads at a glance against the code text. */}\n {gutter !== '' ? (\n <Text\n x={padLeft}\n y={textY}\n fontSize={fontSize}\n fontWeight={600}\n color={`#${rgb}${GUTTER_ALPHA}`}\n fontFamily={fontFamily}\n >\n {gutter}\n </Text>\n ) : null}\n\n {/* Line text. */}\n <Text\n x={padLeft + gutterWidth}\n y={textY}\n fontSize={fontSize}\n color={c}\n fontFamily={fontFamily}\n letterSpacing={letterSpacing}\n >\n {line.text}\n </Text>\n </Group>\n )\n })}\n </Group>\n </Group>\n )\n}\n","//! Confetti — a soft, slow particle BLOOM, not a party popper. Translucent motes\n//! rise and drift outward from an origin on an eased path that decelerates,\n//! gently growing and fading. Ported from ondajs, then premium-tuned.\n//!\n//! Deterministic: every per-piece value (angle, reach, opacity, size, sway,\n//! colour) is drawn from the pure `random(seed)` hash (§1), so the same seed\n//! renders the same bloom on every frame and every machine — no `Math.random`,\n//! no wall-clock.\n//!\n//! Each piece is a soft CIRCLE (`<Rect>` with `cornerRadius = r/2`) inside a\n//! per-piece `<Group>` translated to its centre and carrying the piece opacity.\n//! The whole field lives in one full-canvas `<Group>`; nothing uses `<Flex>`, so\n//! the per-frame position/size changes never trigger a layout reflow (§2).\n//!\n//! Premium notes: round translucent dots (not slim tumbling strips), a muted\n//! accent-led palette at low opacity, an eased outward drift (HOUSE_EASE — it\n//! decelerates rather than flying ballistically), a slow sway, and NO rotation —\n//! so it reads as ambient celebratory light, and renders identically on the CPU\n//! reference and the Vello/GPU backend (no GPU-only tumble).\n\nimport {\n Group,\n Rect,\n interpolate,\n random,\n useCurrentFrame,\n useVideoConfig,\n variantSeed,\n} from '@onda-engine/react'\nimport { HOUSE_EASE } from '../easing.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface ConfettiProps {\n /** Seed for every per-piece random (angle, reach, opacity, size, colour) — the\n * same seed always produces the same bloom (§1). */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Number of motes. ~80 reads full without thrashing the render. */\n count?: number\n /** Palette motes are picked from. Defaults to the theme accent plus a soft\n * accent tint and tasteful neutrals; all rendered translucent. */\n colors?: string[]\n /** Bloom origin X, as a fraction of canvas width (0 = left, 1 = right). */\n originX?: number\n /** Bloom origin Y, as a fraction of canvas height (0 = top, 1 = bottom). */\n originY?: number\n /** Frames before the bloom begins. */\n delay?: TimeInput\n /** Frames over which a mote drifts and fades out. */\n duration?: TimeInput\n /** Drift spread, in degrees, around straight up. Wider = more fan-out. */\n spread?: number\n /** Gentle downward bias added over the drift (0 = pure rise; 1 = a soft settle). */\n gravity?: number\n /** Base mote size in pixels — each varies around this (small motes .. soft bokeh). */\n pieceSize?: number\n}\n\n/** Onda accent + a soft tint + neutrals — resolved to hex (the scene graph has no\n * CSS custom properties). Used translucent, so they read as light, not paper. */\nconst DEFAULT_COLORS = ['#e85494', '#f2b8cf', '#f2f2f4', '#8e8e98']\n\nexport function Confetti({\n seed: seedProp = 7,\n variant,\n count = 80,\n colors: colorsProp,\n originX = 0.5,\n originY = 0.35,\n delay: delayIn = 0,\n duration: durationIn = 70,\n spread = 120,\n gravity = 1,\n pieceSize = 12,\n}: ConfettiProps) {\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const frame = useCurrentFrame()\n const { width, height, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const theme = useTheme()\n const colors = colorsProp ?? [\n theme.accent ?? '#e85494',\n '#f2b8cf',\n theme.text ?? '#f2f2f4',\n theme.textMuted ?? '#8e8e98',\n ]\n\n const local = frame - delay\n const ox = originX * width\n const oy = originY * height\n\n // Distances/speeds scaled to canvas + fps so the bloom looks the same at any\n // resolution and framerate.\n const speedScale = (Math.min(width, height) / 1080) * (30 / fps)\n const spreadRad = (spread * Math.PI) / 180\n\n // Nothing has begun yet — emit an empty field rather than null so the host node\n // is stable across frames.\n if (local < 0) {\n return <Group />\n }\n\n const palette = colors.length > 0 ? colors : DEFAULT_COLORS\n\n const pieces = Array.from({ length: count }, (_, i) => {\n // Each draw gets its OWN unique seed key (`random(seed)` here is a pure hash,\n // not a stateful generator), so piece order never shifts any value.\n const aJit = random(`${seed}-${i}-angle`)\n const reach = 90 + random(`${seed}-${i}-reach`) * 180 // px of outward travel @1080 baseline\n const peak = 0.22 + random(`${seed}-${i}-peak`) * 0.34 // max (translucent) opacity\n const sizeJit = 0.5 + random(`${seed}-${i}-size`) * 1.7 // small motes .. soft bokeh\n const lifeJit = 0.75 + random(`${seed}-${i}-life`) * 0.5 // per-piece duration variation\n const swayAmp = (random(`${seed}-${i}-sway`) - 0.5) * 26 // slow horizontal sway\n\n const color =\n palette[Math.floor(random(`${seed}-${i}-color`) * palette.length)] ?? palette[0] ?? '#f2f2f4'\n\n const life = duration * lifeJit\n if (local > life) {\n return null\n }\n\n const t = local // frames since launch (already >= 0)\n\n // Eased outward drift that decelerates — confident, not ballistic.\n const prog = interpolate(t, [0, life], [0, 1], {\n extrapolateRight: 'clamp',\n easing: HOUSE_EASE,\n })\n // Aim around straight up (-90deg), fanned by spread.\n const angle = -Math.PI / 2 + (aJit - 0.5) * spreadRad\n const dist = reach * speedScale * prog\n const sway = Math.sin(t * 0.06 + i) * swayAmp * speedScale * prog\n // A gentle downward bias that grows over the drift (soft settle, not a fall).\n const fall = 0.16 * gravity * speedScale * t * prog\n\n const x = ox + Math.cos(angle) * dist + sway\n const y = oy + Math.sin(angle) * dist + fall\n\n const opacity = interpolate(t, [0, life * 0.3, life * 0.6, life], [0, peak, peak, 0], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n easing: HOUSE_EASE,\n })\n\n // Soft round mote; grows slightly as it rises (a subtle bloom).\n const r = pieceSize * sizeJit * (0.85 + 0.3 * prog)\n\n return (\n <Group key={i} x={x} y={y} opacity={opacity}>\n <Rect x={-r / 2} y={-r / 2} width={r} height={r} cornerRadius={r / 2} fill={color} />\n </Group>\n )\n })\n\n return <Group>{pieces}</Group>\n}\n","//! CountUp — an animated number that counts from `from` to `to`. Ported from ondajs.\n//!\n//! Mirrors the ondajs component: opacity rides the house entrance (`entryFade`)\n//! while the numeric value is driven independently by a spring mapped onto\n//! `[from, to]`, so the fade-in and the counting curve settle together. The\n//! formatted value renders as a single `<Text>`.\n//!\n//! Engine notes (vs the ondajs/CSS original):\n//! - No `font-variant-numeric: tabular-nums`, no `letter-spacing`/`line-height`,\n//! no `text-align`, and no `placement` region system in the scene `<Text>`.\n//! We expose `x`/`y` for placement and let the engine measure the text.\n//! - en-US thousands grouping is implemented locally (deterministic across\n//! hosts) rather than via `Number.toLocaleString`, which is locale-data\n//! dependent. Toggle with `useGrouping`.\n\nimport { Text, interpolate, spring, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { entryFade } from '../choreography.js'\nimport { DURATION, SPRING_SMOOTH, SPRING_SNAPPY } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { useTimeScale } from '../timing.js'\n\nexport interface CountUpProps extends TextStyleProps {\n /** Starting value (default `0`). */\n from?: number\n /** Ending value (default `100`). */\n to?: number\n /** Time before the count starts (default `0`) — frames or '0.5s'. */\n delay?: TimeInput\n /** Time to count from `from` to `to`. Numbers want more time than text\n * (default `DURATION.slow` = 24 frames). */\n durationInFrames?: TimeInput\n /** Compress the whole timing envelope (delay, stagger, durations) so the\n * entrance settles at least `hold` before the end of the enclosing clip\n * (`useVideoConfig().durationInFrames`, Sequence-scoped). Opt-in. */\n fitToClip?: boolean\n /** Hard cap on the settle time (frames or '0.5s'). Wins over `fitToClip`. */\n maxSettle?: TimeInput\n /** Breathing room before the cut for `fitToClip` (default 6 frames). */\n hold?: TimeInput\n /** Fraction digits to render (default `0`). */\n decimals?: number\n /** Insert en-US thousands separators (default `true`). */\n useGrouping?: boolean\n /** Prepended to the number, e.g. `'$'` (default `''`). */\n prefix?: string\n /** Appended to the number, e.g. `'%'` (default `''`). */\n suffix?: string\n /** Font size in px. Counters are usually large (default `120`). */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * measured line cannot exceed the frame minus the safe margins. Default\n * `'none'` (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the line; combines with `fit` (the smaller\n * cap wins). */\n maxWidth?: number\n /** Use the snappier spring (`SPRING_SNAPPY`) for the count (default `false`,\n * i.e. `SPRING_SMOOTH` — matches ondajs). */\n snappy?: boolean\n /** Where the counter sits: a region keyword (`'center'`, `'lower-third'`, …)\n * or normalized `{x,y}` (0–1, anchored at the FINAL value's measured\n * center, so the line never slides as it counts). The shared placement\n * contract. Omitted → the legacy origin-relative `x`/`y` translate. */\n placement?: Placement\n /** @deprecated Legacy — pixel translate from the local origin. Prefer\n * `placement`. */\n x?: number\n /** @deprecated Legacy — pixel translate from the local origin. Prefer\n * `placement`. */\n y?: number\n}\n\n/** Format a number with a fixed number of decimals and optional en-US thousands\n * grouping. Deterministic — no locale data, no `toLocaleString`. */\nfunction formatNumber(value: number, decimals: number, useGrouping: boolean): string {\n const negative = value < 0\n // toFixed rounds half-away-from-zero on the absolute value, then we re-sign.\n const fixed = Math.abs(value).toFixed(Math.max(0, decimals))\n const dot = fixed.indexOf('.')\n const intPart = dot === -1 ? fixed : fixed.slice(0, dot)\n const fracPart = dot === -1 ? '' : fixed.slice(dot) // includes the leading '.'\n\n let grouped = intPart\n if (useGrouping && intPart.length > 3) {\n const out: string[] = []\n for (let i = intPart.length; i > 0; i -= 3) {\n out.unshift(intPart.slice(Math.max(0, i - 3), i))\n }\n grouped = out.join(',')\n }\n\n return `${negative ? '-' : ''}${grouped}${fracPart}`\n}\n\nexport function CountUp({\n from = 0,\n to = 100,\n delay: delayIn = 0,\n durationInFrames: durationIn = DURATION.slow,\n fitToClip,\n maxSettle,\n hold,\n decimals = 0,\n useGrouping = true,\n prefix = '',\n suffix = '',\n color: colorProp,\n fontSize: fontSizeProp = 120,\n fit,\n maxWidth,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n snappy = false,\n placement,\n x = 0,\n y = 0,\n}: CountUpProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Timing: parse + clip-fit (the count compresses to land inside the clip).\n const delayBase = framesOf(delayIn, fps)\n const durationBase = framesOf(durationIn, fps, DURATION.slow)\n const timeScale = useTimeScale(delayBase + durationBase, { fitToClip, maxSettle, hold })\n const delay = delayBase * timeScale\n const durationInFrames = Math.max(1, durationBase * timeScale)\n\n // Opt-in auto-fit, measured on the FINAL value (the widest the line gets).\n const finalText = `${prefix}${formatNumber(to, decimals, useGrouping)}${suffix}`\n const fontSize = useFittedFontSize(finalText, fontSizeProp, {\n fontFamily,\n fontWeight,\n fit,\n maxWidth,\n })\n\n // Opacity rides the shared house entrance so the fade-in and the counting\n // curve settle together rather than racing each other.\n const { opacity } = entryFade({ frame, fps, delay, durationInFrames })\n\n // The numeric progress on the same family of springs, computed independently\n // so we can map it onto the range [from, to]. The spring counts as \"settled\"\n // within a rest threshold of 1, so it asymptotes just shy of the target; once\n // the count duration has elapsed, snap progress to exactly 1 so the displayed\n // value lands on `to` precisely (otherwise it rests a hair short, e.g. 12,783\n // instead of 12,847).\n const elapsed = frame - delay\n const progress =\n elapsed >= durationInFrames\n ? 1\n : spring({\n frame: elapsed,\n fps,\n config: snappy ? SPRING_SNAPPY : SPRING_SMOOTH,\n durationInFrames,\n })\n\n const value = interpolate(progress, [0, 1], [from, to], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n const formatted = formatNumber(value, decimals, useGrouping)\n\n // Shared placement contract, anchored on the FINAL value's measured width so\n // the line never slides sideways as digits count up. Without `placement` the\n // legacy origin-relative `x`/`y` translate applies unchanged.\n const measured = useTextMetrics(finalText, fontSize, { fontFamily, fontWeight })\n const resolved = usePlacement(placement, { width: measured.width, height: fontSize * 1.2 })\n const px = placement !== undefined ? Math.round(resolved.originX) : x\n const py = placement !== undefined ? Math.round(resolved.y - fontSize * 0.6) : y\n\n return (\n <Text\n x={px}\n y={py}\n opacity={opacity}\n color={color}\n fontSize={fontSize}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {applyTextCase(`${prefix}${formatted}${suffix}`, { uppercase })}\n </Text>\n )\n}\n","//! Cursor — an animated mouse pointer that travels between two canvas points on\n//! the house spring and emits a single restrained click ripple on arrival.\n//! Ported from ondajs.\n//!\n//! A full-composition layer: position it with the `from*` / `to*` 0..1 fractions,\n//! not placement. The pointer is a scene `<Path>` (the classic arrow outline from\n//! ondajs's viewBox `0 0 40 64`), uniformly scaled to `size`. The click ripple is\n//! an `<Ellipse>` ring (stroke, no fill) that scales out and fades on arrival.\n//!\n//! Geometry / pivot notes:\n//! - The pointer travels via `useSpringValue` (the house spring, matching\n//! ondajs), with x/y linearly interpolated between the from/to fractions × the\n//! canvas size. The whole pointer hot-spot is placed with an outer `<Group x y>`.\n//! - The engine composes a node transform as `point * scale + translate` (scale\n//! about the local origin, then translate). To reproduce ondajs's\n//! `transformOrigin: '4px 2px'`, the pointer tip (viewBox `4,2`) is moved to\n//! the local origin so the click \"press\" (a brief dip to 0.86 and back) scales\n//! about the tip: outer `<Group x y>` (places the tip) > `<Group scale=press>`\n//! (pivots on the tip) > `<Group scale=size/VIEWBOX>` (px scale) >\n//! `<Group x=-TIP_X y=-TIP_Y>` (tip → origin, in viewBox units) > `<Path>`.\n//! - The ripple `<Ellipse>` is centered on the tip via a `-ring/2` offset inside\n//! a tip-origin group, mirroring the `PulsingIndicator` pattern. Everything\n//! uses explicit x/y (no `<Flex>`) so the per-frame scale changes can't trigger\n//! a layout reflow.\n//!\n//! Backend caveat: `<Path>` renders only on the Vello/GPU backend; the CPU\n//! reference rasterizer skips paths, so the pointer is a GPU-only visual.\n//!\n//! Approximation: ondajs draws the pointer with a CSS `drop-shadow` filter, which\n//! the engine has no equivalent for. The shadow is dropped; the pointer keeps its\n//! dark edge stroke (`#08080a`) for definition, which is the load-bearing part of\n//! the original look.\n\nimport {\n Ellipse,\n Group,\n Path,\n interpolate,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface CursorProps {\n /** Start X as a 0..1 fraction of canvas width. */\n fromX?: number\n /** Start Y as a 0..1 fraction of canvas height. */\n fromY?: number\n /** End X as a 0..1 fraction of canvas width. */\n toX?: number\n /** End Y as a 0..1 fraction of canvas height. */\n toY?: number\n /** Frames before the cursor starts moving. */\n delay?: TimeInput\n /** Frames to travel from start to end on the house spring. */\n travelDuration?: number\n /** Emit a click ripple on arrival. */\n click?: boolean\n /** Frames after arrival before the click fires. */\n clickDelay?: number\n /** Pointer + ripple color (hex `#rrggbb` / `#rrggbbaa`) (default: theme `text`). */\n color?: string\n /** Pointer height in px. */\n size?: number\n}\n\n// ondajs's pointer is authored in a 0..64 (height) viewBox. We scale the path by\n// `size / VIEWBOX_H` so the rendered pointer is `size` px tall (and ~0.62·size\n// wide, matching the original 40×64 box).\nconst VIEWBOX_H = 64\n// The arrow outline, verbatim from ondajs, in viewBox coordinates.\nconst POINTER_D = 'M4 2 L4 46 L15 36 L22 54 L30 50 L23 33 L38 33 Z'\n// The pointer hot-spot / tip in viewBox coordinates (ondajs's transform origin).\nconst TIP_X = 4\nconst TIP_Y = 2\n\nexport function Cursor({\n fromX = 0.28,\n fromY = 0.72,\n toX = 0.6,\n toY = 0.42,\n delay: delayIn = 6,\n travelDuration = DURATION.slow,\n click = true,\n clickDelay = 6,\n color: colorProp,\n size = 56,\n}: CursorProps) {\n const frame = useCurrentFrame()\n const { width, height, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n\n // House spring travel (SPRING_SMOOTH, no overshoot), matching ondajs's\n // `useSpringValue` default.\n const p = useSpringValue({ delay, durationInFrames: travelDuration })\n\n // Linear x/y between the from/to fractions, driven by the spring progress.\n const x = interpolate(p, [0, 1], [fromX, toX]) * width\n const y = interpolate(p, [0, 1], [fromY, toY]) * height\n\n // The click fires once the pointer has arrived plus a short beat.\n const clickFrame = delay + travelDuration + clickDelay\n const ripple = click\n ? interpolate(frame, [clickFrame, clickFrame + 14], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n : 0\n // A brief press-down on the pointer at the click moment.\n const press = click\n ? interpolate(frame, [clickFrame, clickFrame + 4, clickFrame + 9], [1, 0.86, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n : 1\n\n // Uniform scale from viewBox units to px so the pointer is `size` tall.\n const scale = size / VIEWBOX_H\n\n // The ripple ring sizing, mirroring ondajs (ring ≈ 1.4·size, scaling 0.2→1.4).\n const ringSize = size * 1.4\n const rippleScale = interpolate(ripple, [0, 1], [0.2, 1.4])\n const rippleOpacity = interpolate(ripple, [0, 1], [0.6, 0])\n // Match ondajs's small visual nudge of the ring relative to the tip.\n const ringOffsetX = 6\n const ringOffsetY = 4\n\n return (\n // Outer group places the pointer tip at the interpolated canvas point.\n <Group x={x} y={y}>\n {/* Click ripple — a stroked ring centered on the tip, scaling + fading.\n Drawn first so it reads beneath the pointer. (Scale pivots on the\n ellipse's local origin, the PulsingIndicator-blessed pattern.) */}\n {click && ripple > 0 && ripple < 1 ? (\n <Group x={ringOffsetX} y={ringOffsetY}>\n <Ellipse\n x={-ringSize / 2}\n y={-ringSize / 2}\n width={ringSize}\n height={ringSize}\n stroke={color}\n strokeWidth={2}\n scaleX={rippleScale}\n scaleY={rippleScale}\n opacity={rippleOpacity}\n />\n </Group>\n ) : null}\n\n {/* Pointer arrow. The press scales about this group's origin — which is\n the hot-spot / tip — so the dip pivots on the tip, matching ondajs's\n `transformOrigin: '4px 2px'`. The path is px-scaled, then offset back\n by the tip (in viewBox units) so viewBox (4,2) lands on the origin. */}\n <Group scaleX={press} scaleY={press}>\n <Group scaleX={scale} scaleY={scale}>\n <Group x={-TIP_X} y={-TIP_Y}>\n <Path d={POINTER_D} fill={color} stroke=\"#08080a\" strokeWidth={2} />\n </Group>\n </Group>\n </Group>\n </Group>\n )\n}\n","//! DeviceFrame — a phone or laptop bezel wrapping arbitrary content. Ported from ondajs.\n//!\n//! A container component (the documented exception to \"self-contained\"): pass\n//! `children` (scene nodes), an image `src`, or neither. ondajs renders nested\n//! CSS `<div>`s — a rounded bezel with padding, an `overflow:hidden` rounded\n//! screen, and a notch (phone) or hinge/base (laptop). Here that becomes scene\n//! primitives: an outer rounded `<Rect>` (bezel), an inner rounded `<Rect>`\n//! (screen background), a `<Group clip={clipRect(...)}>` masking the content to\n//! the rounded screen, and a small notch/hinge `<Rect>`.\n//!\n//! Self-positioning: the device is centered on the composition. The whole\n//! subtree is drawn around the device CENTER (offsets of `-w/2, -h/2`) so the\n//! scale-in entrance grows from the center — scene scale pivots on the local\n//! origin (0,0), not the node's box, so the origin is anchored at the center.\n//! (ondajs's `placement` prop is dropped: this always centers on the canvas.)\n//!\n//! Approximations vs ondajs:\n//! - CSS `box-shadow` has no engine primitive; the drop shadow is approximated\n//! by a soft, offset, semi-transparent `<Rect>` behind the bezel.\n//! - The screen content is masked with a ROUNDED `clipRect(w, h, screenRadius)`\n//! (cornerRadius = bezel-inset radius), standing in for the DOM's\n//! `overflow:hidden` on a rounded div. The rounded screen-background `<Rect>`\n//! shows through the same radius so the rounded-screen read holds.\n//! - When using `src` (no children), the `<Image>` is stretch-filled to the\n//! screen rect via independent scaleX/scaleY (from an assumed base raster\n//! size) and clipped to the rounded screen box. A frame→scene function can't\n//! read the image's intrinsic dimensions, so CSS `object-fit: cover` is not\n//! reproduced — pass children for precise (aspect-correct) framing.\n//! - The bezel carries a faint lighter stroke so the dark device reads against a\n//! dark canvas (there's no engine box-shadow rim).\n//! - The requested `width` is capped so the full device height stays within\n//! ~92% of the composition height; an oversized request is shrunk to fit.\n\nimport { Group, Image, Rect, clipRect, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { entryScale } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\n/** ondajs palette tokens (resolved from CSS vars there; literal hex here).\n * These are the fallbacks behind the theme tokens:\n * - bezel → theme `surface`\n * - hinge (BEZEL_LIT) → theme `border` (default: theme `border`)\n * - screen background (SCREEN_BG) → theme `background` (default: theme `background`)\n * - notch (NOTCH) → theme `background` (default: theme `background`) */\nconst BEZEL_LIT = '#26262e'\nconst SCREEN_BG = '#08080a'\nconst NOTCH = '#000000'\n/** A subtly lighter edge so the dark bezel reads against a dark canvas (no\n * engine box-shadow rim). Hairline stroke on the bezel body. */\nconst BEZEL_EDGE = '#3a3a44'\n/** Largest fraction of the composition height the device may occupy. The\n * requested `width` is shrunk to honour this when the device would overflow. */\nconst MAX_HEIGHT_FRACTION = 0.92\n/** Soft approximation of the ondajs `box-shadow` drop. Stays dark across themes\n * (a drop shadow isn't a theme color), so it's not theme-driven. */\nconst SHADOW = '#000000a6'\n\nexport interface DeviceFrameProps {\n /** Which device bezel to draw. */\n device?: 'phone' | 'laptop'\n /** Image src shown inside when no `children` are passed (use the literal\n * `\"DEMO_IMAGE\"` token in demos). Sized via the engine, not `object-fit`. */\n src?: string\n /** Frames before the entrance begins. */\n delay?: TimeInput\n /** Scale-and-fade the device in on the house spring. */\n animate?: boolean\n /** Device width in px (height is derived from the device aspect). */\n width?: number\n /** Bezel color (hex `#rrggbb` / `#rrggbbaa`) (default: theme `surface`). */\n color?: string\n /** Content to wrap (scene nodes). Takes precedence over `src`. */\n children?: ReactNode\n}\n\nexport function DeviceFrame({\n device = 'phone',\n src,\n delay = 0,\n animate = true,\n width = 420,\n color: colorProp,\n children,\n}: DeviceFrameProps) {\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.surface\n const screenBg = theme.background ?? SCREEN_BG\n const notch = theme.background ?? NOTCH\n const bezelLit = theme.border ?? BEZEL_LIT\n const shadow = SHADOW\n\n // House-spring scale-and-fade entrance (matches ondajs `useEntrance` scale).\n const entrance = entryScale({ frame, fps, delay, durationInFrames: DURATION.base, from: 0.96 })\n const opacity = animate ? entrance.opacity : 1\n const scale = animate ? entrance.scaleX : 1\n\n // Shrink the requested width so the full device fits within ~92% of the\n // composition height (the requested 2.05× phone would overflow a 720 canvas).\n const fitWidth = fitDeviceWidth(device, width, compHeight * MAX_HEIGHT_FRACTION)\n\n // The full device bounding box (so we can center it and pivot the scale).\n const box = deviceBox(device, fitWidth)\n\n // Center on the composition; draw the subtree around the device center so the\n // scale grows from the middle (scale pivots on this Group's local origin).\n const centerX = compWidth / 2\n const centerY = compHeight / 2\n\n return (\n <Group x={centerX} y={centerY} scaleX={scale} scaleY={scale} opacity={opacity}>\n <Group x={-box.width / 2} y={-box.height / 2}>\n {device === 'phone'\n ? renderPhone(fitWidth, color, src, children, { screenBg, notch, shadow })\n : renderLaptop(fitWidth, color, src, children, { screenBg, bezelLit, shadow })}\n </Group>\n </Group>\n )\n}\n\n/** The device's overall bounding box (for centering + pivot). */\nfunction deviceBox(device: 'phone' | 'laptop', width: number): { width: number; height: number } {\n if (device === 'phone') {\n return { width, height: width * 2.05 }\n }\n // Laptop: screen body + hinge base stacked, base is wider than the screen.\n const screenH = width * 0.62\n return { width: width * 1.16, height: screenH + 14 + 6 }\n}\n\n/** Shrink `width` so the device's overall HEIGHT fits within `maxHeight`. The\n * tall phone (2.05× width) overflows a 720 canvas at the default 420 width;\n * here we cap it and derive width back from the device aspect. Never enlarges. */\nfunction fitDeviceWidth(device: 'phone' | 'laptop', width: number, maxHeight: number): number {\n const height = deviceBox(device, width).height\n if (height <= maxHeight) {\n return width\n }\n // Height scales linearly with width, so scale width by the same factor.\n return (width * maxHeight) / height\n}\n\n/** Phone bezel: rounded body, inset rounded screen, clipped content, top notch. */\nfunction renderPhone(\n width: number,\n color: string,\n src: string | undefined,\n children: ReactNode,\n colors: { screenBg: string; notch: string; shadow: string },\n) {\n const { screenBg, notch, shadow } = colors\n const height = width * 2.05\n const radius = width * 0.15\n const bezel = Math.max(12, width * 0.035)\n const screenW = width - bezel * 2\n const screenH = height - bezel * 2\n const screenRadius = Math.max(0, radius - bezel)\n const notchW = width * 0.32\n const notchH = 10\n const notchX = (width - notchW) / 2\n const notchY = bezel + 6\n\n return (\n <Group>\n {/* Drop-shadow approximation (no engine box-shadow): offset, soft alpha. */}\n <Rect x={6} y={18} width={width} height={height} cornerRadius={radius} fill={shadow} />\n {/* Bezel body, with a subtly lighter edge so it reads on a dark canvas. */}\n <Rect\n width={width}\n height={height}\n cornerRadius={radius}\n fill={color}\n stroke={BEZEL_EDGE}\n strokeWidth={1.5}\n />\n {/* Screen background (rounded), inset by the bezel padding. */}\n <Rect\n x={bezel}\n y={bezel}\n width={screenW}\n height={screenH}\n cornerRadius={screenRadius}\n fill={screenBg}\n />\n {/* Content, masked to the rounded screen box. */}\n <Group x={bezel} y={bezel} clip={clipRect(screenW, screenH, screenRadius)}>\n {renderContent(src, children, screenW, screenH)}\n </Group>\n {/* Notch, drawn above the screen. */}\n <Rect\n x={notchX}\n y={notchY}\n width={notchW}\n height={notchH}\n cornerRadius={notchH / 2}\n fill={notch}\n />\n </Group>\n )\n}\n\n/** Laptop bezel: rounded screen body centered over a wider hinge + foot. */\nfunction renderLaptop(\n width: number,\n color: string,\n src: string | undefined,\n children: ReactNode,\n colors: { screenBg: string; bezelLit: string; shadow: string },\n) {\n const { screenBg, bezelLit, shadow } = colors\n const screenH = width * 0.62\n const bezel = Math.max(10, width * 0.02)\n const radius = 16\n const screenW = width - bezel * 2\n const screenInnerH = screenH - bezel * 2\n const screenRadius = Math.max(0, radius - bezel)\n\n // The body is centered horizontally within the (wider) base box.\n const baseW = width * 1.16\n const bodyX = (baseW - width) / 2\n\n const hingeW = baseW\n const hingeH = 14\n const hingeY = screenH\n\n const footW = width * 0.16\n const footH = 6\n const footX = (baseW - footW) / 2\n const footY = screenH + hingeH\n\n return (\n <Group>\n {/* Drop-shadow approximation under the screen body. */}\n <Rect\n x={bodyX + 6}\n y={18}\n width={width}\n height={screenH}\n cornerRadius={radius}\n fill={shadow}\n />\n {/* Screen body bezel, with a lighter edge so it reads on a dark canvas. */}\n <Rect\n x={bodyX}\n y={0}\n width={width}\n height={screenH}\n cornerRadius={radius}\n fill={color}\n stroke={BEZEL_EDGE}\n strokeWidth={1.5}\n />\n {/* Screen background (rounded), inset by the bezel padding. */}\n <Rect\n x={bodyX + bezel}\n y={bezel}\n width={screenW}\n height={screenInnerH}\n cornerRadius={screenRadius}\n fill={screenBg}\n />\n {/* Content, masked to the rounded screen box. */}\n <Group x={bodyX + bezel} y={bezel} clip={clipRect(screenW, screenInnerH, screenRadius)}>\n {renderContent(src, children, screenW, screenInnerH)}\n </Group>\n {/* Hinge base (wider, lit), then the small foot below it. */}\n <Rect\n x={0}\n y={hingeY}\n width={hingeW}\n height={hingeH}\n cornerRadius={hingeH / 2}\n fill={bezelLit}\n />\n <Rect\n x={footX}\n y={footY}\n width={footW}\n height={footH}\n cornerRadius={footH / 2}\n fill={color}\n />\n </Group>\n )\n}\n\n/** Screen contents: children take precedence, else an image src, else nothing.\n * The image is fitted to the screen rect with `fit=\"cover\"` — the renderer\n * measures the decoded image, so the photo fills the screen without distortion\n * for any source aspect. The parent clip keeps it inside the rounded screen. */\nfunction renderContent(\n src: string | undefined,\n children: ReactNode,\n screenW: number,\n screenH: number,\n): ReactNode {\n if (children != null) {\n return children\n }\n if (src) {\n return <Image src={src} width={screenW} height={screenH} fit=\"cover\" />\n }\n return null\n}\n","//! DrawOn — an SVG path that \"draws on\", the substrate for logos, icons, and\n//! signature flourishes. Ported from ondajs.\n//!\n//! ondajs strokes the path in with `@remotion/paths`' `evolvePath`, which turns a\n//! 0→1 spring progress into the `stroke-dasharray`/`stroke-dashoffset` pair that\n//! reveals the line from its start to its end. `@onda-engine/react` has no stroke-dash\n//! animation, so this is APPROXIMATED with a **clip wipe**: the fully-stroked\n//! `<Path>` is masked by a `clipRect` whose width grows 0 → full across the path's\n//! bounding box on the house spring (`SPRING_SMOOTH`, no overshoot — the same\n//! spring and timing ondajs uses). The line therefore reveals left-to-right (the\n//! natural read direction) rather than strictly following the path's arc-length\n//! parameterization; for a left-to-right path (logos, signatures, the default\n//! wave) the two are visually close. See `approximations`.\n//!\n//! Bounds: the engine exposes no author-time path metrics, so the clip rect is\n//! sized from a lightweight parse of the `d` string's coordinates, padded by half\n//! the stroke width so round caps/joins at the extremes are never clipped.\n//!\n//! Backend caveat: `<Path>` renders only on the Vello/GPU backend; the CPU\n//! reference rasterizer skips paths, so there is nothing to reveal there.\n//!\n//! Pivot: scale/rotation on a node pivot on its local origin (0,0); this\n//! component applies neither, so no centering caveat applies — the path renders in\n//! its own coordinate space exactly as authored.\n\nimport { Group, Path, clipRect } from '@onda-engine/react'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface DrawOnProps {\n /** SVG path `d` attribute (in the path's own coordinate space). The default is\n * a gentle wave — on-brand. */\n d?: string\n /** Stroke color (hex `#rrggbb` / `#rrggbbaa`) (default: theme `text`). */\n color?: string\n /** Stroke width in path coordinate units. */\n strokeWidth?: number\n /** Frames before the draw-on starts. */\n delay?: TimeInput\n /** Frames to fully draw the path in (default `DURATION.slow` = 24). */\n durationInFrames?: TimeInput\n}\n\n/** Parse the bounding box of an SVG path's `d` string from its coordinate pairs.\n *\n * This is a lightweight estimator, not a full path engine: it handles the common\n * absolute/relative move/line/curve commands (M/L/C/S/Q/T and their lowercase\n * forms) by tracking the running pen position over consecutive number pairs, and\n * the single-axis H/V commands. Arc (A/a) flag arguments would skew a strict\n * pair-walk, so arcs fall back to treating their numbers as a loose point cloud —\n * good enough to size a reveal wipe. Returns null when no numbers are found. */\nfunction pathBounds(d: string): { minX: number; minY: number; maxX: number; maxY: number } | null {\n const tokens = d.match(/[a-zA-Z]|-?\\d*\\.?\\d+(?:e[-+]?\\d+)?/gi)\n if (!tokens || tokens.length === 0) {\n return null\n }\n\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n let penX = 0\n let penY = 0\n let cmd = ''\n let found = false\n\n const acc = (x: number, y: number) => {\n if (x < minX) minX = x\n if (y < minY) minY = y\n if (x > maxX) maxX = x\n if (y > maxY) maxY = y\n found = true\n }\n\n let i = 0\n while (i < tokens.length) {\n const tok = tokens[i] ?? ''\n if (/^[a-zA-Z]$/.test(tok)) {\n cmd = tok\n i += 1\n // Z/z close the subpath and carry no coordinates.\n if (cmd === 'Z' || cmd === 'z') {\n // nothing to consume\n }\n continue\n }\n\n const lower = cmd.toLowerCase()\n const rel = cmd === lower && cmd !== ''\n\n if (lower === 'h') {\n const n = Number.parseFloat(tok)\n if (Number.isFinite(n)) {\n penX = rel ? penX + n : n\n acc(penX, penY)\n }\n i += 1\n continue\n }\n if (lower === 'v') {\n const n = Number.parseFloat(tok)\n if (Number.isFinite(n)) {\n penY = rel ? penY + n : n\n acc(penX, penY)\n }\n i += 1\n continue\n }\n\n // Everything else is consumed as x,y pairs. For curve commands the control\n // points are also pairs, so accounting for all of them only ever widens the\n // box conservatively — exactly what we want for a non-clipping reveal.\n const xs = tokens[i] ?? ''\n const ys = tokens[i + 1] ?? ''\n const xn = Number.parseFloat(xs)\n const yn = Number.parseFloat(ys)\n if (Number.isFinite(xn) && Number.isFinite(yn)) {\n const px = rel ? penX + xn : xn\n const py = rel ? penY + yn : yn\n acc(px, py)\n penX = px\n penY = py\n i += 2\n } else {\n // Stray/unparseable token — skip it rather than stall.\n i += 1\n }\n }\n\n if (!found) {\n return null\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport function DrawOn({\n d = 'M 10 50 Q 100 10 190 50',\n color: colorProp,\n strokeWidth = 3,\n delay = 0,\n durationInFrames = DURATION.slow,\n}: DrawOnProps) {\n // House spring (SPRING_SMOOTH, no overshoot) drives the reveal 0 → 1 — the same\n // spring/config/timing ondajs feeds to `evolvePath`. (useSpringValue reads\n // frame + fps internally.)\n const progress = useSpringValue({ delay, durationInFrames })\n const theme = useTheme()\n const color = colorProp ?? theme.text\n\n const bounds = pathBounds(d)\n\n // The stroke's round caps/joins extend half the stroke width beyond the path's\n // geometric bounds, so pad the wipe box by that much on every side; otherwise\n // the start/end caps would be sliced off at the edges of the clip.\n const pad = strokeWidth / 2 + 1\n\n // Without parseable bounds (degenerate `d`), still emit the stroked path — but\n // gate it on the spring so it stays invisible until the draw-on begins.\n if (!bounds) {\n if (progress <= 0) {\n return null\n }\n return <Path d={d} stroke={color} strokeWidth={strokeWidth} />\n }\n\n const boxX = bounds.minX - pad\n const boxY = bounds.minY - pad\n const boxWidth = bounds.maxX - bounds.minX + pad * 2\n const boxHeight = bounds.maxY - bounds.minY + pad * 2\n\n // The revealed slice of the box, left → right. Clamp ≥ 0 so a 0-progress frame\n // produces an empty (collapsed) clip rather than a negative one.\n const revealWidth = Math.max(0, boxWidth * progress)\n\n // Nothing revealed yet — render nothing (the line hasn't started drawing).\n if (revealWidth <= 0) {\n return null\n }\n\n // The clip is in the path's local space. We translate the clip Group's origin\n // to the box's top-left, clip to (revealWidth × boxHeight), then render the\n // path back at the negated offset so its coordinates are unchanged — the clip\n // window simply grows rightward across the stationary, fully-stroked path.\n return (\n <Group x={boxX} y={boxY} clip={clipRect(revealWidth, boxHeight)}>\n <Group x={-boxX} y={-boxY}>\n <Path d={d} stroke={color} strokeWidth={strokeWidth} />\n </Group>\n </Group>\n )\n}\n","//! DynamicGrid — a technical grid that drifts diagonally, an optional centered\n//! accent glow lifting the middle. A full-canvas atmosphere layer for\n//! dashboard / data / dev scenes. Ported from ondajs (`dynamic-grid`).\n//!\n//! ondajs draws the grid with a single CSS background-image (a repeating\n//! `linear-gradient` rule for `lines`, a `radial-gradient` dot lattice for\n//! `dots`) tiled by `background-size: cell`, then translates the whole tile by\n//! `-(frame * speed % cell)` on both axes so the drift loops by exactly one\n//! cell — seamless and deterministic. The engine has no tiled background-image,\n//! so the lattice is materialized as explicit scene primitives:\n//! - `lines` → thin vertical + horizontal `<Rect>` rulings, one per cell line.\n//! - `dots` → small round `<Ellipse>` dots at each lattice intersection\n//! (faithful to the CSS `radial-gradient circle`).\n//! The lattice is over-drawn one cell beyond every edge (origin at `-cell`) and\n//! the whole layer is `clip`ped to the canvas, reproducing ondajs's\n//! `inset: -cell` + `overflow: hidden`: the drift never exposes an unpainted\n//! edge and the off-canvas tail is masked. Layer transparency is applied via the\n//! enclosing `<Group opacity>` (the scene equivalent of CSS layer `opacity`),\n//! so `color` itself stays a flat hex.\n//!\n//! Pure function of frame: the only time input is `offset = (frame * speed) %\n//! cell`, so the output is identical every cycle and deterministic across\n//! renderers — no timers, no DOM measurement.\n//!\n//! Backend caveat: the `glow` is a scene `radialGradient`, which renders only on\n//! the Vello/GPU backend. The CPU reference rasterizer collapses a gradient to\n//! its first stop (the solid glow `color`), so the soft accent is a GPU-only\n//! effect; the grid + background render identically on both backends.\n\nimport {\n Ellipse,\n Group,\n Rect,\n clipRect,\n radialGradient,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useTheme } from '../theme.js'\n\nexport interface DynamicGridProps {\n /** Cell size in px (the lattice pitch). */\n cell?: number\n /** Ruled lines or a dot lattice. */\n variant?: 'lines' | 'dots'\n /** Grid color (hex `#rrggbb` / `#rrggbbaa`) (default: theme `border`). */\n color?: string\n /** Diagonal drift speed in px/frame. Negative drifts the other way. */\n speed?: number\n /** Grid opacity, 0..1 — a grid is scaffold, not subject. */\n opacity?: number\n /** Add a centered accent glow over the grid. */\n glow?: boolean\n /** Glow color (hex). The meaningful color on the CPU fallback (first stop) (default: theme `accent`). */\n glowColor?: string\n /** Canvas color painted behind the grid (default: theme `background`). */\n background?: string\n /** Stroke thickness (lines) / dot radius in px (dots). */\n thickness?: number\n}\n\n/** Hard ceiling on rulings/dots per axis, so a pathologically small `cell`\n * can't explode the node count. At 4k width and the schema-min cell (4px) this\n * caps a single axis well before then; normal cells stay far under it. */\nconst MAX_LINES_PER_AXIS = 600\n\n/** Clamp `n` into `[lo, hi]`. */\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, n))\n}\n\n/** Strip a leading `#` and any trailing alpha, yielding a 6-digit `rrggbb`. */\nfunction rgbHex(color: string): string {\n let hex = color.startsWith('#') ? color.slice(1) : color\n if (hex.length === 3 || hex.length === 4) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n hex = `${r}${r}${g}${g}${b}${b}`\n }\n return hex.slice(0, 6).padEnd(6, '0')\n}\n\nexport function DynamicGrid({\n cell = 48,\n variant = 'lines',\n color: colorProp,\n speed = 0.4,\n opacity = 0.6,\n glow = true,\n glowColor: glowColorProp,\n background: backgroundProp,\n thickness = 1,\n}: DynamicGridProps) {\n const frame = useCurrentFrame()\n const { width, height } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.border\n const glowColor = glowColorProp ?? theme.accent\n const background = backgroundProp ?? theme.background\n\n // Guard the pitch: the schema mins `cell` at 4, but clamp defensively so a\n // zero/negative value can't divide-by-zero or invert the lattice.\n const pitch = Math.max(1, cell)\n\n // Diagonal drift, looping by exactly one cell. JS `%` can go negative for a\n // negative `speed`, so normalize into [0, pitch) — the tile is over-drawn one\n // cell beyond the top-left, so a positive `offset` reveals the lead cell.\n const offset = (((frame * speed) % pitch) + pitch) % pitch\n\n // Lattice spans from one cell before the top-left to one cell past the\n // bottom-right, so the diagonal translate never exposes an unpainted edge.\n const cols = clamp(Math.ceil(width / pitch) + 2, 1, MAX_LINES_PER_AXIS)\n const rows = clamp(Math.ceil(height / pitch) + 2, 1, MAX_LINES_PER_AXIS)\n\n // Over-drawn extents (one cell of bleed on each side), measured in the grid\n // layer's local space (its origin is the top-left corner before the drift\n // translate; the layer itself is shifted by -offset on both axes).\n const fieldWidth = (cols + 1) * pitch\n const fieldHeight = (rows + 1) * pitch\n\n const stroke = Math.max(0.5, thickness)\n const gridColor = `#${rgbHex(color)}`\n\n const cols1 = Array.from({ length: cols + 1 }, (_, i) => i)\n const rows1 = Array.from({ length: rows + 1 }, (_, i) => i)\n\n // Center the glow on the canvas; size it to the smaller dimension so it reads\n // the same across aspect ratios. ondajs uses `size=1`, opacity 0.22 (a\n // radius of ~60% of the smaller axis fading to transparent at 70%).\n const minDimension = Math.min(width, height)\n const glowRadius = 0.6 * minDimension\n const transparentGlow = `#${rgbHex(glowColor)}00`\n\n return (\n <Group>\n {/* Canvas backdrop. */}\n <Rect width={width} height={height} fill={`#${rgbHex(background)}`} />\n\n {/* Drifting lattice, clipped to the canvas and dimmed via layer opacity.\n The clip region starts at the layer origin (0,0), so the -cell bleed\n and the off-canvas tail are masked — only the canvas band shows. */}\n <Group opacity={clamp(opacity, 0, 1)} clip={clipRect(width, height)}>\n <Group x={-pitch - offset} y={-pitch - offset}>\n {variant === 'dots'\n ? // Dot lattice — a round dot at every intersection.\n rows1.flatMap((ri) =>\n cols1.map((ci) => (\n <Ellipse\n key={`d-${ri}-${ci}`}\n x={ci * pitch - stroke}\n y={ri * pitch - stroke}\n width={stroke * 2}\n height={stroke * 2}\n fill={gridColor}\n />\n )),\n )\n : // Ruled grid — full-length vertical + horizontal rulings.\n [\n ...cols1.map((ci) => (\n <Rect\n key={`v-${ci}`}\n x={ci * pitch}\n y={0}\n width={stroke}\n height={fieldHeight}\n fill={gridColor}\n />\n )),\n ...rows1.map((ri) => (\n <Rect\n key={`h-${ri}`}\n x={0}\n y={ri * pitch}\n width={fieldWidth}\n height={stroke}\n fill={gridColor}\n />\n )),\n ]}\n </Group>\n </Group>\n\n {/* Centered accent glow (Vello-only; see header). First stop is the solid\n glow color so the CPU fallback still shows the accent. The transparent\n tail is the final stop so the canvas-sized Rect stays clear at the\n edges (the engine pads the last gradient stop outward). */}\n {glow ? (\n <Rect\n width={width}\n height={height}\n opacity={0.22}\n gradient={radialGradient([width / 2, height / 2], glowRadius, [\n { offset: 0, color: `#${rgbHex(glowColor)}` },\n { offset: 0.7, color: transparentGlow },\n { offset: 1, color: transparentGlow },\n ])}\n />\n ) : null}\n </Group>\n )\n}\n","//! EndCard — closing outro/credits block. A hero CTA reveals (with an optional\n//! accent underline drawing beneath it as it settles), then a faint, staggered\n//! row of social handles / URLs fades in last so the eye finishes on the\n//! contact strip. Ported from ondajs.\n//!\n//! Composition over invention: when `accent` is on the CTA reproduces the\n//! `Underline` motion inline (text fade + accent rule, two-phase) so the rule\n//! can be sized from the WHOLE title at the engine's per-glyph estimate (the\n//! `Underline` sibling's tighter factor under-spans a long hero CTA); when off\n//! it falls back to a bare blur-ramp `<Group>` + `Text`. The handles row reproduces the\n//! ondajs `StaggerGroup` directly — each handle is a `FadeIn`-wrapped `Text` on\n//! the canonical 4-frame stagger. No new motion is invented here; the card's\n//! job is sequencing, not animation.\n//!\n//! Layout: the whole card is centered and vertically stacked by the engine's\n//! layout pass (taffy) via `<AbsoluteFill>` + `<Flex direction=\"column\">`. Every\n//! child is OPACITY-ONLY (`FadeIn` / the CTA text fade) or animates inside a\n//! fixed-size reserved row (the accent rule), so nothing fights the layout pass\n//! (a motion translate on a direct Flex child would be clobbered; a per-frame\n//! size change would reflow the column). The\n//! handles sit in their own row `<Flex>`; each item is a `FadeIn`, so the row's\n//! measured size is stable and never jiggles as the cascade runs.\n//!\n//! Soft→sharp CTA: the ondajs CTA reveals via a blur-filter (BlurReveal) that\n//! resolves blurred -> sharp during the fade. With the engine's render-to-texture\n//! blur this is first-class — the CTA reveals through the opacity spring\n//! (entryFade) AND a real `blur` ramp (CTA_FROM_BLUR -> 0) on the same progress,\n//! so it resolves soft -> sharp exactly as the original. The blur lives on a\n//! `<Group>` wrapping the CTA text (both the accent and bare branches), inside\n//! the column's fixed-size rows so the layout pass is never disturbed.\n\nimport {\n AbsoluteFill,\n Flex,\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { type Placement, PlacementShift } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { FadeIn } from './FadeIn.js'\n\nexport interface EndCardProps extends TextStyleProps {\n /** Hero CTA / headline line. */\n cta?: string\n /** Social handles or URLs displayed in a row beneath the CTA. */\n handles?: string[]\n /** Time before the CTA starts (frames, or '0.5s'/'500ms'/'12f'). The whole card is sequenced relative to this. */\n delay?: TimeInput\n /** Where the card sits: a region keyword (`'center'`, `'lower-third'`, ...) or\n * normalized `{x,y}` (0-1, card center). The shared placement contract;\n * default `'center'` (the historical self-centering). */\n placement?: Placement\n /** Show the accent underline beneath the CTA (default `true`). */\n accent?: boolean\n /** CTA font size in px (default 96). */\n ctaFontSize?: number\n /** Font weight for the CTA (default 600). */\n ctaFontWeight?: number\n /** Handles row font size in px (default 24). */\n handlesFontSize?: number\n /** Font weight for the handles row (default 600). */\n handlesFontWeight?: number\n /** Handles color — defaults so the row reads quiet (default: theme `textMuted`). */\n handlesColor?: string\n /** Underline color — the earned rose (default: theme `accent`). */\n accentColor?: string\n}\n\n// Beat offsets — derived from delay so the whole card is one composed sequence.\n// The CTA lands first; the underline draws as it settles (handled inside the\n// `Underline` sibling via `lineDelay`); the handles row fades in last with a\n// small beat of breathing room so the eye finishes on the contact strip.\nconst HANDLES_OFFSET = DURATION.base + 6 // handles begin ~6 frames after the CTA finishes its rise\nconst UNDERLINE_OFFSET = DURATION.base - 4 // underline starts drawing just as the CTA settles\n\n/** Mean glyph advance as a fraction of the font size — the engine's documented\n * estimate (`text.length * fontSize * ~0.6`). The CTA delegated to the\n * `Underline` sibling, but that sibling sizes its rule with a tighter 0.52\n * factor tuned for shorter labels, which leaves a long hero CTA like the\n * default \"Made with Onda\" under-spanned (the rule stops before the last\n * word). The hero rule is laid inline here so it spans the FULL title at the\n * engine's own per-glyph estimate. */\nconst CHAR_WIDTH_FACTOR = 0.6\n/** Rule geometry — mirrors the values previously passed to `Underline`. */\nconst LINE_THICKNESS = 3\nconst LINE_OFFSET = 6\n/** Starting blur (px) for the CTA's soft→sharp focus-pull — the ondajs CTA's\n * `blur(… → 0)`, ramped to 0 on the same entry spring as the opacity. */\nconst CTA_FROM_BLUR = 10\n\nexport function EndCard({\n cta = 'Made with Onda',\n handles = ['@onda.video', 'onda.video/components'],\n delay: delayIn = 0,\n placement,\n accent = true,\n ctaFontSize = 96,\n ctaFontWeight = 600,\n handlesFontSize = 24,\n handlesFontWeight = 600,\n color: colorProp,\n handlesColor: handlesColorProp,\n accentColor: accentColorProp,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n}: EndCardProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const handlesColor = handlesColorProp ?? theme.textMuted\n const accentColor = accentColorProp ?? theme.accent\n // The CTA is the headline → it follows the theme's display face\n // (`headingFamily ?? fontFamily`); the handles strip is metadata → it stays on\n // the body `fontFamily`. An explicit `fontFamily` prop overrides both.\n const ctaFontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n const handlesFontFamily = fontFamilyProp ?? theme.fontFamily\n const ctaText = applyTextCase(cta, { uppercase })\n\n // Vertical gap between the CTA and the handles strip, scaled off the CTA size\n // so the rhythm holds at any headline size (~40px at the default 96px CTA).\n const stackGap = Math.round(ctaFontSize * 0.42)\n // Horizontal gap between handle items — the metadata strip reads as one row.\n const handlesGap = Math.round(handlesFontSize * 1.3)\n\n // CTA reveal + accent rule (only built when `accent` is on). The CTA resolves\n // soft→sharp: one house entry spring drives BOTH the opacity fade and a real\n // `blur` ramp (CTA_FROM_BLUR → 0) so they read as a single focus-pull (the\n // ondajs BlurReveal). The rule then draws beneath it. The rule's FULL width is\n // estimated from the WHOLE `cta` at the engine's per-glyph factor so it spans\n // every word of the title (not just the first).\n const ctaProgress = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n const ctaOpacity = interpolate(ctaProgress, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n const ctaBlur = interpolate(ctaProgress, [0, 1], [CTA_FROM_BLUR, 0], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n const fullRuleWidth = Math.max(0, cta.length) * ctaFontSize * CHAR_WIDTH_FACTOR\n const ruleProgress = spring({\n frame: Math.max(0, frame - delay - UNDERLINE_OFFSET),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.fast,\n })\n const ruleWidth = interpolate(ruleProgress, [0, 1], [0, fullRuleWidth], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n // A full-pill radius on a thin sliver would bulge; cap at half its own size.\n const ruleRadius = Math.min(LINE_THICKNESS / 2, ruleWidth / 2)\n // The rule is a flex sibling stacked directly BELOW the CTA text, so the\n // column already accounts for the title's line box. `ruleY` is therefore just\n // the small underline gap UNDER the text — a previous version added a whole\n // line box here (`ctaFontSize * 1.2 + …`), double-counting it and dropping the\n // rule ~1.2×fontSize too far below the title.\n const ruleY = LINE_OFFSET + Math.round(ctaFontSize * 0.12)\n // The row only needs to span the gap + the rule itself; the fixed-WIDTH\n // transparent spacer below is what keeps the animated rule from reflowing.\n const ruleRowHeight = ruleY + LINE_THICKNESS\n\n return (\n // The flex column self-centers; PlacementShift moves the centered stack by\n // the center->placement delta (no-op for the default 'center').\n <PlacementShift placement={placement}>\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Flex direction=\"column\" align=\"center\" gap={stackGap}>\n {/* CTA — the headline reveals soft→sharp (opacity + blur ramp). When\n accent is on, the accent rule then draws beneath it (two-phase, the\n `Underline` motion); the rule is laid out inline here so its FULL\n width tracks the WHOLE title (every word) at the engine's per-glyph\n estimate, and a fixed-height row (transparent spacer sized to the\n estimated title box) keeps the animated rule width from reflowing the\n centered column. When accent is off, the same blur-ramp CTA reveals\n without the rule. */}\n {accent ? (\n <Flex direction=\"column\" align=\"center\">\n {/* CTA text resolves soft→sharp: opacity + real blur ramp on one\n group (origin pinned, no translate, so the column never shifts). */}\n <Group opacity={ctaOpacity} blur={ctaBlur}>\n <Text\n fontSize={ctaFontSize}\n color={color}\n fontFamily={ctaFontFamily}\n fontWeight={ctaFontWeight}\n letterSpacing={letterSpacing}\n >\n {ctaText}\n </Text>\n </Group>\n <Group>\n <Rect width={fullRuleWidth} height={ruleRowHeight} fill=\"#00000000\" />\n {ruleWidth > 0 ? (\n <Rect\n x={(fullRuleWidth - ruleWidth) / 2}\n y={ruleY}\n width={ruleWidth}\n height={LINE_THICKNESS}\n cornerRadius={ruleRadius}\n fill={accentColor}\n />\n ) : null}\n </Group>\n </Flex>\n ) : (\n // No accent rule, but the CTA still resolves soft→sharp: same\n // opacity + blur ramp on the house entry spring (no rule beneath).\n <Group opacity={ctaOpacity} blur={ctaBlur}>\n <Text\n fontSize={ctaFontSize}\n color={color}\n fontFamily={ctaFontFamily}\n fontWeight={ctaFontWeight}\n letterSpacing={letterSpacing}\n >\n {ctaText}\n </Text>\n </Group>\n )}\n\n {/* Handles row — staggered, faint, the closing beat. Rendered as a\n horizontal strip so URLs / handles read as a single line of metadata,\n not a stack. Each handle is one beat on the canonical 4-frame stagger\n (reproducing ondajs's StaggerGroup). Opacity-only, so the row's\n measured size is stable and the cascade never reflows it. */}\n {handles.length > 0 ? (\n <Flex direction=\"row\" align=\"center\" gap={handlesGap}>\n {handles.map((handle, i) => (\n <FadeIn\n key={`${i}-${handle}`}\n delay={delay + HANDLES_OFFSET + staggerFrames(i, STAGGER)}\n durationInFrames={DURATION.base}\n >\n <Text\n fontSize={handlesFontSize}\n color={handlesColor}\n fontFamily={handlesFontFamily}\n fontWeight={handlesFontWeight}\n >\n {handle}\n </Text>\n </FadeIn>\n ))}\n </Flex>\n ) : null}\n </Flex>\n </AbsoluteFill>\n </PlacementShift>\n )\n}\n","//! FadeOut — opacity 1 → 0 on the house ease. The exit counterpart to FadeIn;\n//! `delay` is when the exit begins. Layout-safe (opacity only).\n\nimport { Group, useCurrentFrame } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { exitFade } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface FadeOutProps {\n /** Frame at which the exit begins. */\n delay?: TimeInput\n /** Frames the fade-out takes (default `DURATION.fast` = 10 — exits are quick). */\n durationInFrames?: TimeInput\n children?: ReactNode\n}\n\nexport function FadeOut({ delay = 0, durationInFrames = DURATION.fast, children }: FadeOutProps) {\n const frame = useCurrentFrame()\n const { opacity } = exitFade({ frame, delay, durationInFrames })\n return <Group opacity={opacity}>{children}</Group>\n}\n","//! FilmGrade — a one-prop cinematic LOOK over the engine's per-node `grade`\n//! effect (color_grade). The \"land AI media\" wedge: wrap a whole composition\n//! (especially mixed AI-generated clips with clashing white balance and\n//! saturation) in a single named film look so it reads as ONE graded film.\n//!\n//! Each `look` is a tasteful, restrained preset of grade params (exposure,\n//! contrast, saturation, temperature, tint). `intensity` lerps every param from\n//! the neutral identity (exposure 0, contrast 1, saturation 1, temperature 0,\n//! tint 0) toward the look, so `intensity={0}` is a no-op and `intensity={0.5}`\n//! is the look at half strength. Explicit overrides apply on top of the resolved\n//! look, for fine-tuning without abandoning the preset.\n//!\n//! Implementation: resolves to a single `<Group grade={…}>` wrapping the subtree\n//! — a TRANSPARENT passthrough (a Group does not re-layout its children, so their\n//! absolute positions are preserved; an AbsoluteFill would flex-reflow them), so\n//! the grade applies to the node's entire subtree. Honored by Vello AND the CPU\n//! reference (the\n//! grade is a per-pixel remap, no blur), so FilmGrade is `both`-backend and\n//! engine-native — not a CSS-filter approximation.\n\nimport { Group } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { useTheme } from '../theme.js'\n\n/** The named cinematic looks. */\nexport type FilmLook = 'warm' | 'cool' | 'noir' | 'teal-orange' | 'vibrant' | 'film' | 'faded'\n\n/** The five grade params (mirrors the engine's `color_grade` effect). */\ninterface GradeParams {\n exposure: number\n contrast: number\n saturation: number\n temperature: number\n tint: number\n}\n\n/** The neutral identity — `intensity={0}` lerps every look back to this (a\n * render no-op). */\nconst NEUTRAL: GradeParams = {\n exposure: 0,\n contrast: 1,\n saturation: 1,\n temperature: 0,\n tint: 0,\n}\n\n/** Look → grade params. Restrained on purpose: a grade is set-dressing, not a\n * party trick — these nudge white balance / contrast / saturation, they don't\n * blow the image out. */\nconst LOOKS: Record<FilmLook, GradeParams> = {\n // Gentle golden-hour warmth: a touch of exposure + warm temp, contrast held.\n warm: { exposure: 0.05, contrast: 1.05, saturation: 1.05, temperature: 0.22, tint: 0.04 },\n // Crisp, clean daylight pushed cold: cool temp, a faint magenta tint, slight\n // contrast for a clinical / tech look.\n cool: { exposure: 0, contrast: 1.08, saturation: 0.96, temperature: -0.25, tint: -0.05 },\n // Black-and-white drama: saturation to 0 (grayscale), contrast up, a hair of\n // exposure lift to keep the mids alive.\n noir: { exposure: 0.03, contrast: 1.25, saturation: 0, temperature: 0, tint: 0 },\n // The Hollywood blockbuster split-tone: warm skin against cool shadows —\n // warm temp + a slight desaturate + a contrast bump (the engine's grade is\n // global, so we evoke the look via warm balance + punch rather than a true\n // shadow/highlight split).\n 'teal-orange': {\n exposure: 0.02,\n contrast: 1.14,\n saturation: 0.92,\n temperature: 0.18,\n tint: -0.04,\n },\n // Punchy, saturated commercial pop: contrast + saturation up, exposure lifted\n // a touch, balance left neutral.\n vibrant: { exposure: 0.06, contrast: 1.12, saturation: 1.3, temperature: 0.03, tint: 0 },\n // The default — a subtle, all-purpose cinematic base: a whisper of warmth and\n // contrast, saturation eased back so it never looks digital. Unifies clips\n // without announcing itself.\n film: { exposure: 0.02, contrast: 1.06, saturation: 0.95, temperature: 0.08, tint: 0.01 },\n // Faded / washed indie look: lifted blacks via LOW contrast, a desaturated\n // pull, a faint cool cast. The \"matte film\" feel.\n faded: { exposure: 0.04, contrast: 0.85, saturation: 0.82, temperature: -0.06, tint: 0.02 },\n}\n\nexport interface FilmGradeProps {\n /** The named cinematic look applied to the whole subtree. Default `'film'`. */\n look?: FilmLook\n /**\n * Strength of the look, `0..1`. Lerps every grade param from the neutral\n * identity toward the look: `0` = no grade (pass-through), `1` = the full\n * look. Default `1`.\n */\n intensity?: number\n /** Explicit linear-exposure override (`2^exposure`; 0 = identity), applied on\n * top of the resolved look. */\n exposure?: number\n /** Explicit contrast override (1 = identity), applied on top of the look. */\n contrast?: number\n /** Explicit saturation override (1 = identity, 0 = grayscale), on top of the look. */\n saturation?: number\n /** Explicit warm/cool override (R up / B down for positive; 0 = neutral), on top. */\n temperature?: number\n /** Explicit green/magenta override (positive = green; 0 = neutral), on top. */\n tint?: number\n /** The graded subtree — typically the whole composition. */\n children?: ReactNode\n}\n\n/** Clamp `n` into `[lo, hi]`. */\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, n))\n}\n\n/** Linear interpolation. */\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t\n}\n\nexport function FilmGrade({\n look = 'film',\n intensity = 1,\n exposure,\n contrast,\n saturation,\n temperature,\n tint,\n children,\n}: FilmGradeProps) {\n // Touch the theme so the hook order stays stable with the other components.\n useTheme()\n\n const preset = LOOKS[look] ?? LOOKS.film\n const t = clamp(intensity, 0, 1)\n\n // Lerp each param from the neutral identity toward the look by `intensity`.\n const resolved: GradeParams = {\n exposure: lerp(NEUTRAL.exposure, preset.exposure, t),\n contrast: lerp(NEUTRAL.contrast, preset.contrast, t),\n saturation: lerp(NEUTRAL.saturation, preset.saturation, t),\n temperature: lerp(NEUTRAL.temperature, preset.temperature, t),\n tint: lerp(NEUTRAL.tint, preset.tint, t),\n }\n\n // Explicit overrides win over the resolved look (applied on top).\n if (typeof exposure === 'number') resolved.exposure = exposure\n if (typeof contrast === 'number') resolved.contrast = contrast\n if (typeof saturation === 'number') resolved.saturation = saturation\n if (typeof temperature === 'number') resolved.temperature = temperature\n if (typeof tint === 'number') resolved.tint = tint\n\n // A transparent Group wrapping the subtree (children keep their own positions;\n // a flex AbsoluteFill would reflow them). `grade` resolving to the neutral\n // identity is a render no-op, so `intensity={0}` with no overrides passes\n // through untouched.\n return <Group grade={resolved}>{children}</Group>\n}\n","//! GradientShift — a quiet, drifting two-color linear gradient background whose\n//! angle rotates at a constant degrees-per-frame. Ported from ondajs.\n//!\n//! Linear-by-design: the angle is a pure arithmetic function of (frame - delay),\n//! with no spring driver. A spring would settle and stop, killing the constant\n//! drift that is the whole point. GradientShift joins Typewriter / Marquee as a\n//! documented linear-by-design member of the catalog. Low-saturation defaults\n//! keep it atmospheric, never focal.\n//!\n//! Engine port: ondajs renders a CSS `linear-gradient(${angle}deg, from, to)` on\n//! an `AbsoluteFill`. Here the same shape is a scene `linearGradient` on a\n//! canvas-sized `<Rect>`. CSS gradient angles are direction-based (0deg points\n//! up, increasing clockwise) and the gradient line is sized so the two stops land\n//! exactly on the canvas's bounding edges; we reproduce that by projecting the\n//! gradient line's endpoints through the canvas center for the current angle. The\n//! `<Rect>` itself never changes size — only the two endpoint coordinates move —\n//! so no layout reflow occurs.\n//!\n//! Backend caveat: gradients render only on the Vello/GPU backend. The CPU\n//! reference rasterizer collapses a gradient to its first stop, so the drift is a\n//! GPU-only effect; the CPU output is a flat fill of `from` (the meaningful\n//! color, deliberately the first stop).\n\nimport { Rect, linearGradient, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface GradientShiftProps {\n /** Gradient start color (`#rrggbb` / `#rrggbbaa`). Default is the canvas tone\n * — near-identical to `to`, so the drift reads as a dark-on-dark breath\n * (default: theme `background`). */\n from?: string\n /** Gradient end color. Default is one step warmer than `from`, intentionally\n * near-identical so the shift is a whisper rather than a colored wash\n * (default: theme `surface`). */\n to?: string\n /** Starting gradient angle in degrees (CSS convention: `0deg` points up,\n * increasing clockwise). Default `135`. */\n angle?: number\n /** Rotation rate in degrees per frame. Keep low — atmospheric, not focal.\n * At 30fps the default `0.5` produces a 24-second full rotation. */\n speed?: number\n /** Frames before the drift starts. While `frame < delay` the gradient sits at\n * `angle`. Default `0`. */\n delay?: TimeInput\n}\n\nexport function GradientShift({\n from: fromProp,\n to: toProp,\n angle = 135,\n speed = 0.5,\n delay: delayIn = 0,\n}: GradientShiftProps) {\n const frame = useCurrentFrame()\n const { width, height, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const from = fromProp ?? theme.background\n const to = toProp ?? theme.surface\n\n // Linear-by-design: the angle is a pure function of (frame - delay), clamped so\n // nothing drifts before `delay`. No spring — a constant drift is the point.\n const local = Math.max(0, frame - delay)\n const currentAngle = angle + speed * local\n\n // Reproduce the CSS linear-gradient geometry. CSS angle 0deg points the\n // gradient \"up\" (toward bottom→top color travel) and increases clockwise, so\n // the direction unit vector is (sin θ, -cos θ) in screen space (y grows down).\n const rad = (currentAngle * Math.PI) / 180\n const dirX = Math.sin(rad)\n const dirY = -Math.cos(rad)\n\n // The CSS gradient line passes through the center; its half-length is the\n // projection of the box half-extents onto the line, so the two stops land on\n // the bounding edges for any angle: (|W·sinθ| + |H·cosθ|) / 2.\n const halfLen = (Math.abs(width * dirX) + Math.abs(height * dirY)) / 2\n\n const cx = width / 2\n const cy = height / 2\n\n // `from` sits at the start of the gradient line, `to` at the end (CSS: the\n // start is the side the gradient points away from). Keep `from` as the FIRST\n // stop so the CPU fallback collapses to the meaningful color.\n const startX = cx - dirX * halfLen\n const startY = cy - dirY * halfLen\n const endX = cx + dirX * halfLen\n const endY = cy + dirY * halfLen\n\n return (\n <Rect\n width={width}\n height={height}\n fill={from}\n gradient={linearGradient(\n [startX, startY],\n [endX, endY],\n [\n { offset: 0, color: from },\n { offset: 1, color: to },\n ],\n )}\n />\n )\n}\n","//! GrainOverlay — a film-grain texture layered over the whole canvas. Ported\n//! from ondajs.\n//!\n//! Real grain: a full-canvas procedural-noise `<Image>` (the engine's\n//! `onda-noise://` source — deterministic per-pixel gray noise centred on the\n//! neutral value) composited with a `mix-blend-mode: overlay`, so it MODULATES\n//! the luminance of everything beneath it — exactly what ondajs's SVG\n//! `feTurbulence` + overlay did. `baseFrequency` sets the grain's fineness (the\n//! noise resolution), `numOctaves` its contrast, `opacity` its strength, and\n//! `seed` the deterministic field; with `animate` on, the seed advances on a\n//! frame bucket so the grain shimmers without flickering every frame.\n//!\n//! Rendered on the GPU (Vello): the overlay blend is a vector-backend feature, so\n//! grain is `gpu_only` (the CPU reference composites the noise src-over).\n\nimport { Image, useCurrentFrame, useVideoConfig, variantSeed } from '@onda-engine/react'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface GrainOverlayProps {\n /** Grain strength (peak luminance deviation). Capped at `0.15` to match the\n * house 2–15% range (ondajs caps grain at ~2–4%). Default `0.05`. */\n opacity?: number\n /** Grain fineness: higher = finer, tighter speckle (noise nearer full\n * resolution); lower = coarser photo-grain (a lower-res field, upscaled).\n * Default `0.9`. */\n baseFrequency?: number\n /** Grain contrast: widens the deviation so the texture gains punch. Clamped to\n * `1..4` like ondajs. Default `1`. */\n numOctaves?: number\n /** Deterministic variation — the same seed always produces the same grain. Default `0`. */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** When `true`, the field re-seeds on a frame bucket so the grain shimmers. Off\n * by default — ondajs grain is intentionally static set-dressing. */\n animate?: boolean\n /** Frames per re-seed bucket when `animate` is on. Lower = busier. Default `2`. */\n animateEvery?: TimeInput\n /** @deprecated The grain is now a continuous per-pixel field, not scattered\n * dots — `count` no longer applies. Accepted for compat. */\n count?: number\n /** @deprecated Grain is monochrome luminance noise (overlay-blended), so a\n * colour no longer applies. Accepted for compat. */\n color?: string\n}\n\n/** Clamp `n` into `[lo, hi]`. */\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, n))\n}\n\nexport function GrainOverlay({\n opacity = 0.05,\n baseFrequency = 0.9,\n numOctaves = 1,\n seed: seedProp = 0,\n variant,\n animate = false,\n animateEvery: animateEveryIn = 2,\n}: GrainOverlayProps) {\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const { width, height, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const animateEvery = framesOf(animateEveryIn, fps)\n const frame = useCurrentFrame()\n // Touch the theme so the hook order stays stable with the other components.\n useTheme()\n\n const layerOpacity = clamp(opacity, 0, 0.15)\n const octaves = clamp(Math.round(numOctaves), 1, 4)\n // Strength = the capped opacity, lifted a little by contrast (octaves).\n const intensity = clamp(layerOpacity * (1 + (octaves - 1) * 0.35), 0, 0.6)\n\n // Frame bucket: constant when static (every frame identical), advancing in\n // steps when animating so the grain shimmers without flickering each frame.\n const bucket = animate ? Math.floor(frame / Math.max(1, animateEvery)) : 0\n const noiseSeed = seed * 1000 + bucket\n\n // Fineness → noise resolution. Higher frequency = closer to full res (finest\n // speckle); lower = a smaller field, upscaled (coarse photo-grain).\n const scale = clamp(0.4 + baseFrequency * 0.6, 0.3, 1)\n const nw = Math.max(2, Math.round(width * scale))\n const nh = Math.max(2, Math.round(height * scale))\n\n return (\n <Image\n src={`onda-noise://w=${nw}&h=${nh}&seed=${noiseSeed}&intensity=${intensity.toFixed(4)}&mono=1`}\n width={width}\n height={height}\n fit=\"fill\"\n blendMode=\"overlay\"\n />\n )\n}\n","//! Highlight — marker-style background reveal. Ported from ondajs.\n//!\n//! Two-phase emphasis: the text fades in (`entryFade` on the house spring),\n//! then an accent bar wipes in BEHIND it by growing its width on the house\n//! spring. The text draws on top of the bar so it stays legible throughout.\n//!\n//! Scene-graph notes vs the ondajs (CSS) original:\n//! - CSS sized the bar to the text via `display: inline-block`. The scene graph\n//! has no JS-side text measurement, so the bar width is ESTIMATED from the\n//! glyph count (`fontSize * text.length * WIDTH_RATIO`) plus `paddingX`. Pass\n//! `width` to override the estimate when you know the exact text extent.\n//! - `<Text>` places its TOP-LEFT at (x, y) with a line box of `fontSize * 1.2`\n//! (the engine's line height), so the bar is sized/positioned to that box.\n//! - The whole component anchors at its local origin (top-left). Position it via\n//! `x`/`y`, or wrap it in an `<AbsoluteFill justify align>` to center it.\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryFade } from '../choreography.js'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Engine line-box height as a multiple of font size (matches typography crate). */\nconst LINE_RATIO = 1.2\n\nexport interface HighlightProps extends TextStyleProps {\n /** Text to highlight. */\n text?: string\n /** Frames before the text starts revealing. */\n delay?: TimeInput\n /** Text reveal duration in frames (default `DURATION.base` = 18). */\n duration?: TimeInput\n /** Frames to wait after the text appears before the accent bar wipes in. */\n lineDelay?: TimeInput\n /** Accent-bar wipe duration. Fast on purpose — emphatic (default `DURATION.fast`). */\n lineDuration?: TimeInput\n /** Accent (highlight) bar color (default: theme `accent`). */\n accentColor?: string\n /** Font size in px (default 64). */\n fontSize?: number\n /** Pixels past the text edges that the accent bar extends (default 8). */\n paddingX?: number\n /** Explicit text width in px. Overrides the glyph-count estimate when known. */\n width?: number\n /** Local-space placement of the component's top-left. */\n x?: number\n /** Local-space placement of the component's top-left. */\n y?: number\n}\n\nexport function Highlight({\n text: textProp = 'highlight this',\n delay: delayIn = 0,\n duration: durationIn = DURATION.base,\n lineDelay: lineDelayIn = 8,\n lineDuration: lineDurationIn = DURATION.fast,\n color: colorProp,\n accentColor: accentColorProp,\n fontSize = 64,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n paddingX = 8,\n width,\n x = 0,\n y = 0,\n}: HighlightProps) {\n const text = applyTextCase(textProp, { uppercase })\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const lineDelay = framesOf(lineDelayIn, fps)\n const lineDuration = framesOf(lineDurationIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const accentColor = accentColorProp ?? theme.accent\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Phase 1: text fade — opacity 0 → 1 on the house spring.\n const { opacity } = entryFade({ frame, fps, delay, durationInFrames: duration })\n\n // Phase 2: accent bar wipes in after the text lands, offset by lineDelay.\n const barProgress = spring({\n frame: Math.max(0, frame - delay - lineDelay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: lineDuration,\n })\n\n // Real shaped text width (overridable via `width`). The engine measures it\n // (proportional — exact); falls back to a glyph-count estimate until the wasm\n // engine warms in the browser, or if `width` is passed.\n const measured = useTextMetrics(text, fontSize, { fontFamily, fontWeight })\n const textWidth = width ?? measured.width\n const fullBarWidth = textWidth + paddingX * 2\n const barWidth = interpolate(barProgress, [0, 1], [0, fullBarWidth], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n const lineHeight = fontSize * LINE_RATIO\n\n return (\n <Group x={x} y={y}>\n {/* Accent bar BEHIND the text. Starts paddingX left of the text, grows\n rightward by width. Covers the full line box vertically. */}\n <Rect x={-paddingX} y={0} width={barWidth} height={lineHeight} fill={accentColor} />\n {/* Text on top — fades in, always legible against the accent. */}\n <Group opacity={opacity}>\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {text}\n </Text>\n </Group>\n </Group>\n )\n}\n","//! IconPop — an icon (a glyph/emoji or a built-in shape) popping into place with\n//! an overshoot spring (scale 0 → peak past 1, then settle to 1).\n//! Ported from ondajs.\n//!\n//! ondajs renders one of four SVG icons (check/cross/dot/star) inside a 0–24\n//! viewBox and pops it in via `entryScale` (SPRING_SMOOTH — no overshoot). This\n//! port keeps the four built-in `shape` icons (drawn as `<Path>`, GPU-only) and\n//! adds a `glyph` mode (any character/emoji via `<Text>`) — except that common\n//! decorative star/sparkle symbols (e.g. \"✦\", which most render fonts have no\n//! glyph for and would draw blank) transparently fall back to the built-in\n//! `star` <Path>, so a star glyph always pops something visible. And — per the\n//! IconPop brief — uses an *overshoot* spring: a lightly-damped `spring` config\n//! whose value rises past 1.0 and rings down, giving the pop a little life (vs.\n//! the house spring's flat settle).\n//!\n//! Overshoot model: the underdamped `POP_SPRING` drives a normalized progress\n//! that goes 0 → ~1.19 → 1 (it overshoots past 1, then settles). We split that\n//! into a rise term (`min(progress, 1)`) and an overshoot bump (`progress - 1`\n//! when positive), then scale ONLY the bump to the `overshoot` prop. So the\n//! scale starts at exactly 0, peaks at ≈ `1 + overshoot`, and settles to ≈ 1 —\n//! one continuous pop, the bounce magnitude tunable, the start never clipped.\n//!\n//! Pivot caveat: scene scale pivots on the node's LOCAL ORIGIN (0,0), not the\n//! node's center. So the icon's geometry is drawn CENTERED on (0,0) — the outer\n//! `<Group x y>` marks that center on the canvas, and the inner `<Group>` does\n//! the scaling about it, so the pop grows from the middle rather than a corner.\n//!\n//! Backend caveats: `<Path>` (the four shapes) renders only on the Vello/GPU\n//! backend (the CPU reference skips paths). The outline shapes (check, cross)\n//! are stroked here; the engine's `<Path>` exposes no line-cap / line-join, so\n//! the SVG `round` caps/joins become the default butt/miter — a faithful-enough\n//! approximation for a quick pop. The `glyph` mode renders on either backend.\n\nimport {\n Group,\n Path,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION } from '../motion.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** The four built-in shape icons, matching ondajs (inside a 0–24 viewBox). */\nexport type IconShape = 'check' | 'cross' | 'dot' | 'star'\n\n/** Path data + paint mode for each built-in shape, in the 0–24 viewBox. */\nconst SHAPES: Record<IconShape, { d: string; filled: boolean }> = {\n check: { d: 'M5 13 L9 17 L19 7', filled: false },\n cross: { d: 'M6 6 L18 18 M6 18 L18 6', filled: false },\n dot: { d: 'M12 12 m-6 0 a6 6 0 1 0 12 0 a6 6 0 1 0 -12 0', filled: true },\n star: {\n d: 'M12 2 L14.9 8.9 L22.4 9.5 L16.7 14.4 L18.5 21.7 L12 17.8 L5.5 21.7 L7.3 14.4 L1.6 9.5 L9.1 8.9 Z',\n filled: true,\n },\n}\n\n/** Decorative star/sparkle symbol chars that fonts routinely lack a glyph for\n * (so `<Text>` would draw nothing — a blank frame). When a `glyph` is one of\n * these, we fall back to the guaranteed-renderable built-in `star` <Path>\n * instead, so the pop is never invisible. Other glyphs (real letters, common\n * emoji) still render via <Text>. */\nconst STAR_SYMBOLS = new Set([\n '✦', // U+2726 black four-pointed star\n '✧', // U+2727 white four-pointed star\n '★', // U+2605 black star\n '☆', // U+2606 white star\n '✪', // U+272A circled white star\n '✶', // U+2736 six-pointed black star\n '✷', // U+2737 eight-pointed rectilinear black star\n '✸', // U+2738 heavy eight-pointed rectilinear black star\n '✹', // U+2739 twelve-pointed black star\n '✺', // U+273A sixteen-pointed asterisk\n '⭐', // U+2B50 star\n '🌟', // U+1F31F glowing star\n '✨', // U+2728 sparkles\n '⭑', // U+2B51 black small star\n '⭒', // U+2B52 white small star\n])\n\nexport interface IconPopProps extends TextStyleProps {\n /** A character/emoji to pop in (e.g. \"✦\", \"★\", \"🎉\"). Takes precedence over\n * `shape` when set. Rendered via `<Text>` so it works on both backends. */\n glyph?: string\n /** One of the four built-in shapes (check/cross/dot/star). Used when `glyph`\n * is not set. Drawn as `<Path>` — GPU/Vello only. */\n shape?: IconShape\n /** Icon size in px (the icon is square-ish, centered on its placement point). */\n iconSize?: number\n /** Icon color (default: theme `accent`). */\n color?: string\n /** Stroke width for the outline shapes (check, cross). Ignored by glyph and by\n * the filled shapes (dot, star). */\n strokeWidth?: number\n /** Frames before the pop starts. */\n delay?: TimeInput\n /** Frames the pop takes to settle (default `DURATION.base` = 18). */\n durationInFrames?: TimeInput\n /** Overshoot amount — how far past 1.0 the scale peaks before settling, as a\n * fraction (default 0.18 ≈ an 18% bump). 0 disables the overshoot. */\n overshoot?: number\n /** Canvas x of the icon's CENTER (the pop grows from here). */\n x?: number\n /** Canvas y of the icon's CENTER. */\n y?: number\n}\n\n/** A lightly-damped spring config that overshoots before settling. Stiffer +\n * much less damped than the house spring, so its normalized value rises above\n * 1.0 and rings down — the source of the pop's bounce. */\nconst POP_SPRING = { mass: 1, stiffness: 200, damping: 12 } as const\n\n/** The natural peak EXCESS above 1.0 of the time-remapped `POP_SPRING` value\n * (measured against the engine's spring integrator: the first peak lands near\n * ~1.19, i.e. ~0.19 over 1.0, for `durationInFrames` in the 12–24 range). We\n * divide the raw overshoot ring by this so the `overshoot` prop maps directly\n * to the on-screen peak height (`peak scale ≈ 1 + overshoot`). */\nconst PEAK_EXCESS = 0.19\n\nexport function IconPop({\n glyph,\n shape = 'check',\n iconSize = 96,\n color: colorProp,\n strokeWidth = 3,\n delay: delayIn = 0,\n durationInFrames: durationInFramesIn = DURATION.base,\n overshoot = 0.18,\n letterSpacing,\n uppercase,\n x = 0,\n y = 0,\n}: IconPopProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const durationInFrames = framesOf(durationInFramesIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.accent\n const fontFamily = theme.fontFamily\n\n // Underdamped spring: progress 0 → ~1.19 (overshooting past 1) → 1, re-timed\n // to settle in `durationInFrames`.\n const progress = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: POP_SPRING,\n durationInFrames,\n })\n\n // Split progress into a rise term (capped at 1) plus the overshoot bump (the\n // part above 1), scaling ONLY the bump to the `overshoot` prop. This keeps the\n // start at exactly 0 and the settle at ~1, with a tunable peak ≈ 1 + overshoot.\n const rise = Math.min(progress, 1)\n const bump = Math.max(0, progress - 1) * (overshoot / PEAK_EXCESS)\n const scale = rise + bump\n\n // Opacity fades in over the first portion of the pop (clamped), independent of\n // the bounce so the icon never flickers as the spring rings.\n const opacity = interpolate(frame - delay, [0, durationInFrames * 0.5], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n return (\n // Outer group: places the icon's CENTER on the canvas.\n <Group x={x} y={y}>\n {/* Inner group: scales (with overshoot) about that center + fades. */}\n <Group scaleX={scale} scaleY={scale} opacity={opacity}>\n {glyph\n ? // A decorative star/sparkle char the font may lack a glyph for would\n // render blank via <Text>; draw the built-in `star` <Path> instead so\n // the pop is always visible. Other glyphs render as text.\n STAR_SYMBOLS.has(glyph)\n ? renderShape('star', iconSize, color, strokeWidth)\n : renderGlyph(glyph, iconSize, color, fontFamily, { letterSpacing, uppercase })\n : renderShape(shape, iconSize, color, strokeWidth)}\n </Group>\n </Group>\n )\n}\n\n/** Render a character/emoji centered on the local origin (0,0). The engine\n * measures text but we can't read measurements here, so the centering is an\n * approximation: width is estimated from `iconSize`, and the vertical nudge\n * assumes the glyph cap-box is ~0.7 of the font size. Wide/narrow glyphs will\n * sit slightly off-center. */\nfunction renderGlyph(\n glyph: string,\n iconSize: number,\n color: string,\n fontFamily?: string,\n style: Pick<TextStyleProps, 'letterSpacing' | 'uppercase'> = {},\n) {\n // Estimate the rendered glyph width (most emoji/symbols are ~square at this\n // font size; multi-codepoint strings will be wider and under-shifted).\n const estWidth = iconSize * 0.62\n return (\n <Text\n fontSize={iconSize}\n color={color}\n fontFamily={fontFamily}\n letterSpacing={style.letterSpacing}\n x={-estWidth / 2}\n y={-iconSize / 2}\n >\n {applyTextCase(glyph, style)}\n </Text>\n )\n}\n\n/** Render a built-in shape centered on the local origin (0,0). The 0–24 viewBox\n * is scaled to `iconSize` and shifted so the viewBox center (12,12) lands on the\n * pivot. Outlines are stroked; filled shapes are filled. */\nfunction renderShape(shape: IconShape, iconSize: number, color: string, strokeWidth: number) {\n const def = SHAPES[shape] ?? SHAPES.check\n const unit = iconSize / 24\n // Scale the path geometry from the 24-unit space and center it on (0,0).\n return (\n <Group scaleX={unit} scaleY={unit} x={-iconSize / 2} y={-iconSize / 2}>\n <Path\n d={def.d}\n fill={def.filled ? color : undefined}\n stroke={def.filled ? undefined : color}\n // Stroke width is in the 24-unit space (it scales with the group), so\n // divide by `unit` to keep the on-screen stroke ≈ `strokeWidth` px.\n strokeWidth={def.filled ? undefined : strokeWidth / unit}\n strokeCap=\"round\"\n strokeJoin=\"round\"\n />\n </Group>\n )\n}\n","//! ImageReveal — an image that enters with one of Onda's signature motion\n//! fingerprints (fade / scale / wipe). Ported from ondajs.\n//!\n//! ondajs wraps Remotion's `<Img>` with CSS `object-fit` and a CSS `filter:\n//! blur()` entrance. The engine's `<Image>` reproduces both with scene\n//! primitives — `fit` for `object-fit`, and a REAL gaussian (`Image.blur`,\n//! applied in the engine's image pass) for the soft→sharp focus pull:\n//!\n//! - Sizing / `fit`: the engine can't read the source's intrinsic dimensions\n//! back into a pure frame→scene function, so we take them as `srcWidth` /\n//! `srcHeight` props (defaulting to the box size = \"stretch to fill\"). With\n//! real source dimensions, `fit: 'cover'` scales so the box is fully covered\n//! (cropping the overflow via a clip) and `fit: 'contain'` scales so the\n//! whole image fits inside the box (letterboxing). Without them, both fits\n//! collapse to a plain box-fill — note this when the source aspect differs\n//! from the box.\n//! - Box: defaults to the full composition (the ondajs \"hero photo\" fill case).\n//! Pass `width`/`height` (and `x`/`y`) to place a sized sub-canvas image.\n//! - `motion`: `'blur'` (opacity + a real soft→sharp focus pull, the ondajs\n//! default, now backed by the engine's `Image.blur` gaussian), `'fade'`\n//! (opacity), `'scale'` (opacity + subtle 0.95→1, no overshoot — the ondajs\n//! `entryScale` fingerprint), and `'wipe'` (a left→right clip reveal).\n//!\n//! Pivot note: scene scale is about a node's local origin, so the `'scale'`\n//! variant nests an inner group at the box CENTER and draws the image offset by\n//! −w/2,−h/2, so it grows from the middle rather than the top-left corner.\n\nimport { Group, Image, clipRect, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { entryFade, entryScale } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\n/** Which entrance fingerprint the image uses. `'blur'` is the ondajs default —\n * a real soft→sharp focus pull via the engine's `Image.blur` gaussian.\n * `'none'` skips the entrance entirely: the image is placed and held still\n * (the bare `<Image>` primitive, but with this component's box / fit /\n * rounded-corner ergonomics) — for logos and precise product stills that\n * shouldn't drift or reveal. */\nexport type ImageRevealMotion = 'blur' | 'fade' | 'scale' | 'wipe' | 'none'\n\n/** How the image fills its box. Both require `srcWidth`/`srcHeight` to differ\n * from a plain stretch — see the file doc comment. */\nexport type ImageRevealFit = 'cover' | 'contain'\n\nexport interface ImageRevealProps {\n /** Image URL or path (resolved at render time). */\n src: string\n /** Which motion fingerprint the entrance uses (default `'blur'`). */\n motion?: ImageRevealMotion\n /** Peak blur for the `'blur'` motion — the sigma (source px) the image starts\n * at before resolving to sharp. Ignored by the other motions. Default `24`. */\n blurAmount?: number\n /** How the image fits its box (default `'cover'`). */\n fit?: ImageRevealFit\n /** Frames to fully reveal (default `DURATION.base` = 18). */\n durationInFrames?: TimeInput\n /** Frames before the reveal starts. */\n delay?: TimeInput\n /** Box top-left X in px (default 0). */\n x?: number\n /** Box top-left Y in px (default 0). */\n y?: number\n /** Box width in px. Defaults to the full composition width (fill mode). */\n width?: number\n /** Box height in px. Defaults to the full composition height (fill mode). */\n height?: number\n /** Corner radius of the box (clips the image to a rounded rect) (default: theme `radius`). */\n cornerRadius?: number\n}\n\nexport function ImageReveal({\n src,\n motion = 'blur',\n blurAmount = 24,\n fit = 'cover',\n durationInFrames = DURATION.base,\n delay = 0,\n x = 0,\n y = 0,\n width,\n height,\n cornerRadius: cornerRadiusProp,\n}: ImageRevealProps) {\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n const theme = useTheme()\n const cornerRadius = cornerRadiusProp ?? theme.radius\n\n // Box: defaults to the full composition (ondajs's hero-fill default).\n const boxW = width ?? compWidth\n const boxH = height ?? compHeight\n\n // Entrance motion (shared SPRING_SMOOTH fingerprints via the choreography\n // vocabulary). `wipe` drives a clip width; `fade`/`scale` drive the group.\n const fade = entryFade({ frame, fps, delay, durationInFrames })\n const scaleMotion = entryScale({ frame, fps, delay, durationInFrames, from: 0.95 })\n\n // For `wipe`, reveal width grows 0 → boxW on the house spring (reuse the\n // fade progress as a 0→1 ramp). A tiny opacity lead-in avoids a hard pop.\n const wipeWidth = Math.max(0, fade.opacity * boxW)\n\n // The image, fitted into the box by the renderer (it measures the decoded\n // pixels). The wrapping group's clip crops `cover`; `contain` letterboxes.\n const image = <Image src={src} width={boxW} height={boxH} fit={fit} />\n\n if (motion === 'none') {\n // No entrance — the image is simply placed and held (full opacity, no\n // keyframes). Still clipped to the box so `fit`/`cornerRadius` apply.\n return (\n <Group x={x} y={y} clip={clipRect(boxW, boxH, cornerRadius)}>\n {image}\n </Group>\n )\n }\n\n if (motion === 'blur') {\n // Soft→sharp focus pull: the decoded image carries a gaussian sigma that\n // retreats `blurAmount` → 0 as the spring fades it in — a REAL engine blur\n // (the ondajs `filter: blur()` entrance), identical on GPU/CPU/native.\n const sigma = Math.max(0, (1 - fade.opacity) * blurAmount)\n return (\n <Group x={x} y={y} opacity={fade.opacity} clip={clipRect(boxW, boxH, cornerRadius)}>\n <Image src={src} width={boxW} height={boxH} fit={fit} blur={sigma} />\n </Group>\n )\n }\n\n if (motion === 'fade') {\n return (\n <Group x={x} y={y} opacity={fade.opacity} clip={clipRect(boxW, boxH, cornerRadius)}>\n {image}\n </Group>\n )\n }\n\n if (motion === 'scale') {\n // Center-pivot scale: outer group at the box top-left clips to the box;\n // inner group sits at the box CENTER, scales there, and the image is drawn\n // offset by −w/2,−h/2 so it grows from the middle (scale pivots on origin).\n return (\n <Group x={x} y={y} clip={clipRect(boxW, boxH, cornerRadius)}>\n <Group\n x={boxW / 2}\n y={boxH / 2}\n scaleX={scaleMotion.scaleX}\n scaleY={scaleMotion.scaleY}\n opacity={scaleMotion.opacity}\n >\n <Image src={src} x={-boxW / 2} y={-boxH / 2} width={boxW} height={boxH} fit={fit} />\n </Group>\n </Group>\n )\n }\n\n // 'wipe' — left→right clip reveal. An outer rounded clip masks to the box; an\n // inner clip whose width grows wipes the image in. Slight opacity lead-in.\n return (\n <Group x={x} y={y} clip={clipRect(boxW, boxH, cornerRadius)}>\n <Group opacity={fade.opacity} clip={clipRect(wipeWidth, boxH)}>\n {image}\n </Group>\n </Group>\n )\n}\n","//! InputField — a UI text-input mockup. Ported from ondajs (`input-field`).\n//!\n//! A rounded \"glass\" field with an optional uppercase label above. With `typed`\n//! on, the `value` types itself in character-by-character (via `useTextReveal`,\n//! linear cadence) behind a thin blinking accent caret; once typing settles the\n//! caret keeps a slower idle blink. An accent focus ring lights the border once\n//! typing begins. Every animated quantity is a pure function of the current\n//! frame (caret blink is frame-parity, the reveal is `useTextReveal`), so the\n//! field is fully deterministic (CLAUDE.md §1).\n//!\n//! Layout notes vs the ondajs (CSS) original:\n//! - ondajs lays the field out with `display: flex` + `Surface` and lets the\n//! DOM measure the value text so the caret sits exactly after the last glyph.\n//! `@onda-engine/react` has no author-time text metrics, so the visible value width\n//! is ESTIMATED from `glyphCount * fontSize * AVG_CHAR_W` and the caret Rect\n//! is placed at that x. The estimate need only be roughly proportional — the\n//! caret reads as \"at the typing edge\". (See `approximations`.)\n//! - The value `<Text>` grows one glyph per frame while typing, so its measured\n//! box changes every frame. To avoid a `<Flex>` reflow/jiggle (HARD RULE 2)\n//! the whole field is positioned ABSOLUTELY: its top-left offset is computed\n//! from the composition size (the BarChart pattern) and every part is laid at\n//! an explicit x/y inside a fixed-size field `<Rect>` — no layout container.\n//! - CSS `letter-spacing` on the label and a `box-shadow` focus glow have no\n//! engine primitive; the label renders without extra tracking and the focus\n//! ring is approximated by a low-alpha accent stroke just outside the border.\n\nimport { Flex, Group, Rect, Text, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { useTextReveal } from '../hooks.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Engine line-box height as a multiple of font size (typography crate). */\nconst LINE_RATIO = 1.2\n\nexport interface InputFieldProps extends TextStyleProps {\n /** The field's value. With `typed` on, this is what types itself in. */\n value?: string\n /** Placeholder shown while the field is empty (before any glyph is revealed). */\n placeholder?: string\n /** Label above the field. Empty string hides it. */\n label?: string\n /** Animate `value` typing itself in character-by-character (`useTextReveal`). */\n typed?: boolean\n /** Frames before typing starts. */\n delay?: TimeInput\n /** Frames to type the whole value (linear pacing). */\n typeDuration?: TimeInput\n /** Show the accent focus ring around the field once typing begins. */\n focusRing?: boolean\n /** Field width in px. Sized for a 1080p+ video canvas, not a screen UI. */\n width?: number\n /** Text size in px. */\n fontSize?: number\n /** Value text color (default: theme `text`). */\n textColor?: string\n /** Placeholder text color (default: theme `textMuted`). */\n placeholderColor?: string\n /** Label text color (default: theme `textMuted`). */\n labelColor?: string\n /** Caret + focus-ring color — the one earned accent (the Onda rose) (default: theme `accent`). */\n accentColor?: string\n /** Resting (unfocused) field border color (default: theme `border`). */\n borderColor?: string\n /** Field background fill (the \"glass\" surface) (default: theme `surface`). */\n fieldColor?: string\n /** Where the field sits: a region keyword (`'center'`, `'lower-third'`, …)\n * or normalized `{x,y}` (0–1, field center). The shared placement contract;\n * default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias for `placement={{ x }}` — horizontal center of\n * the field as a 0–1 fraction of canvas width. */\n x?: number\n /** @deprecated Legacy alias for `placement={{ y }}` — vertical center of the\n * field as a 0–1 fraction of canvas height. */\n y?: number\n}\n\nexport function InputField({\n value = 'hello@onda.video',\n placeholder = 'Enter your email',\n label = 'Email',\n typed = true,\n delay: delayIn = 0,\n typeDuration: typeDurationIn = 36,\n focusRing = true,\n width = 640,\n fontSize = 36,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n textColor: textColorProp,\n placeholderColor: placeholderColorProp,\n labelColor: labelColorProp,\n accentColor: accentColorProp,\n borderColor: borderColorProp,\n fieldColor: fieldColorProp,\n placement,\n x,\n y,\n}: InputFieldProps) {\n const frame = useCurrentFrame()\n const { width: compWidth, height: compHeight, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const typeDuration = framesOf(typeDurationIn, fps)\n const theme = useTheme()\n const textColor = textColorProp ?? theme.text\n const placeholderColor = placeholderColorProp ?? theme.textMuted\n const labelColor = labelColorProp ?? theme.textMuted\n const accentColor = accentColorProp ?? theme.accent\n const borderColor = borderColorProp ?? theme.border\n const fieldColor = fieldColorProp ?? theme.surface\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // How much of the value is visible. With typing off, the whole value shows.\n const shown = useTextReveal({ length: value.length, delay, durationInFrames: typeDuration })\n const visible = typed ? value.slice(0, Math.max(0, shown)) : value\n const typing = typed && shown < value.length\n\n // Caret blinks while typing (faster, tracking each keystroke) and after it\n // settles (slower, an idle cursor). Pure frame math — no timer (CLAUDE.md §1).\n const blinkOn = typing ? Math.floor(frame / 8) % 2 === 0 : Math.floor(frame / 18) % 2 === 0\n // Caret only appears once typing has actually begun (frame >= delay); before\n // then the field rests on a steady placeholder with no blinking cursor.\n const showCaret = typed && frame >= delay && blinkOn\n\n // Focus ring only reads as \"focused\" once typing is underway / done.\n const focused = focusRing && (!typed || frame >= delay)\n const fieldBorder = focused ? accentColor : borderColor\n\n // Placeholder shows steadily while the field is empty and typing hasn't begun\n // (no caret to blink against). Once typing starts it gives way to the caret.\n const showPlaceholder = visible.length === 0 && (!typed || frame < delay)\n\n // Field geometry. Generous vertical padding so the line box breathes, matching\n // the ondajs `22px 28px` padding scaled to the video font size.\n const padX = Math.round(fontSize * 0.8)\n const padY = Math.round(fontSize * 0.6)\n const lineHeight = fontSize * LINE_RATIO\n const fieldHeight = lineHeight + padY * 2\n const cornerRadius = theme.radius ?? Math.round(fontSize * 0.4)\n\n // Label sits above the field, uppercased and dim (ondajs `textTransform` +\n // `letterSpacing`; the engine has no letter-spacing — see approximations).\n const hasLabel = label.length > 0\n const labelSize = Math.round(fontSize * 0.52)\n const labelGap = Math.round(fontSize * 0.4)\n const labelBlock = hasLabel ? labelSize * LINE_RATIO + labelGap : 0\n\n // Total assembly footprint, anchored by an explicit top-left offset (the\n // BarChart pattern) so the per-frame value-width changes never reflow a\n // layout. Legacy fractional `x`/`y` were already field-center anchored, so\n // they alias 1:1 onto the shared placement contract.\n const totalHeight = labelBlock + fieldHeight\n const resolved = usePlacement(placement ?? { x: x ?? 0.5, y: y ?? 0.5 }, {\n width,\n height: totalHeight,\n })\n const originX = Math.round(resolved.originX)\n const originY = Math.round(resolved.originY)\n\n // Top of the (vertically centered) value line box inside the field.\n const textY = labelBlock + padY\n const textX = padX\n\n // The caret sits right after the value via a Flex row (the engine measures the\n // text), so no glyph-width estimate is needed — a hair of gap separates it from\n // the last glyph.\n const caretWidth = Math.max(2, Math.round(fontSize * 0.06))\n const caretGap = Math.max(6, Math.round(fontSize * 0.22))\n\n // Focus-ring glow: a low-alpha accent stroke just outside the field border,\n // standing in for the ondajs CSS box-shadow (see approximations).\n const ringInset = 4\n const ringStroke = `${accentColor}40`\n\n return (\n <Group x={originX} y={originY}>\n {/* Label above the field (uppercased, dim). */}\n {hasLabel ? (\n <Text\n x={0}\n y={0}\n fontSize={labelSize}\n letterSpacing={labelSize * 0.08}\n color={labelColor}\n fontFamily={fontFamily}\n fontWeight={600}\n >\n {label.toUpperCase()}\n </Text>\n ) : null}\n\n {/* Focus ring — drawn behind the field as a soft accent outline. */}\n {focused ? (\n <Rect\n x={-ringInset}\n y={labelBlock - ringInset}\n width={width + ringInset * 2}\n height={fieldHeight + ringInset * 2}\n cornerRadius={cornerRadius + ringInset}\n fill=\"#00000000\"\n stroke={ringStroke}\n strokeWidth={6}\n />\n ) : null}\n\n {/* The glass field — rounded background with a (focus-aware) border. */}\n <Rect\n x={0}\n y={labelBlock}\n width={width}\n height={fieldHeight}\n cornerRadius={cornerRadius}\n fill={fieldColor}\n stroke={fieldBorder}\n strokeWidth={2}\n />\n\n {/* Placeholder while the field is empty (steady, before typing begins). */}\n {showPlaceholder ? (\n <Text\n x={textX}\n y={textY}\n fontSize={fontSize}\n color={placeholderColor}\n fontFamily={fontFamily}\n fontWeight={400}\n >\n {placeholder}\n </Text>\n ) : null}\n\n {/* Value + caret in a row so the ENGINE measures the typed text and the\n caret lands right after the last glyph (no width estimate). The row is\n left-pinned at the text origin and only grows rightward as it types — the\n fixed field Rect never reflows. */}\n {visible.length > 0 || showCaret ? (\n <Flex direction=\"row\" align=\"center\" gap={caretGap} x={textX} y={textY} height={lineHeight}>\n {visible.length > 0 ? (\n <Text\n fontSize={fontSize}\n color={textColor}\n fontFamily={fontFamily}\n fontWeight={400}\n letterSpacing={letterSpacing}\n >\n {applyTextCase(visible, { uppercase })}\n </Text>\n ) : null}\n {showCaret ? (\n <Rect width={caretWidth} height={fontSize} cornerRadius={1} fill={accentColor} />\n ) : null}\n </Flex>\n ) : null}\n </Group>\n )\n}\n","//! KanbanBoard — a data-driven board: a row of glass columns, each with a header\n//! (status dot, title, ticket count) and a vertical stack of small ticket cards.\n//! Every card rises + fades in on the house spring, staggered across the whole\n//! board on a single flat running index (left-to-right, top-to-bottom) so it\n//! assembles as one calm cascade. The board is static after the entrance.\n//! Ported from ondajs (`kanban-board`).\n//!\n//! Layout is computed manually with explicit x/y inside `<Group>`s — NOT a\n//! `<Flex>` — for two scene reasons: (1) each card's entrance is a per-frame\n//! TRANSLATE (rise), and a Flex both clobbers a direct child's x/y and reflows\n//! (jiggles) as the measured subtree grows; (2) `<Text>` is single-line, so card\n//! heights are fixed from the label font size rather than measured. Columns are\n//! equal-width, splitting `width` minus the inter-column gaps.\n//!\n//! Scene caveats: scale/rotation are unused here, so the local-origin pivot does\n//! not bite. Colors with alpha (`#rrggbbaa`) stand in for the original glass\n//! Surface (see approximations).\n\nimport {\n Ellipse,\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** A single Kanban column: a header, an optional accent, and its ticket cards. */\nexport interface KanbanColumn {\n /** Column header, e.g. `'In Progress'`. */\n title: string\n /** Status-dot + count color for this column. Defaults to a neutral faint token;\n * one column should earn the accent. */\n accent?: string\n /** Ticket labels — one small card per entry, top-to-bottom. Single-line each. */\n cards?: string[]\n}\n\nexport interface KanbanBoardProps extends TextStyleProps {\n /** The columns, laid out left-to-right. Each holds its own ticket cards. */\n columns?: KanbanColumn[]\n /** Overall board width in px. Split evenly across the columns. */\n width?: number\n /** Gap between columns (and between cards within a column) in px. */\n gap?: number\n /** Frames before the first card enters. */\n delay?: TimeInput\n /** Frames between successive cards rising in (house stagger = 4). */\n stagger?: TimeInput\n /** Base column-header font size in px. */\n fontSize?: number\n /** Default accent for the dot/count when a column omits its own (default: theme `accent`). */\n accent?: string\n /** Header / title text color (default: theme `text`). */\n textColor?: string\n /** Ticket-label text color (default: theme `textMuted`). */\n cardTextColor?: string\n /** Faint color for neutral dots, counts, and card accent stripes (default: theme `textMuted`). */\n faintColor?: string\n /** Glass column fill (translucent — see approximations) (default: theme `surface`). */\n columnFill?: string\n /** Glass column border color (default: theme `border`). */\n columnStroke?: string\n /** Ticket card fill (translucent — see approximations) (default: theme `surface`). */\n cardFill?: string\n}\n\nconst DEFAULT_COLUMNS: KanbanColumn[] = [\n {\n title: 'Todo',\n cards: ['Storyboard the intro', 'Source b-roll', 'Write VO script'],\n },\n {\n title: 'In Progress',\n accent: '#d96b82',\n cards: ['Animate the title card', 'Color-grade scene 2'],\n },\n {\n title: 'Done',\n cards: ['Lock the edit', 'Render preview', 'Sound pass', 'Export master'],\n },\n]\n\nexport function KanbanBoard({\n columns = DEFAULT_COLUMNS,\n width = 1040,\n gap = 20,\n delay: delayIn = 0,\n stagger: staggerIn = STAGGER,\n fontSize = 22,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n accent: accentProp,\n textColor: textColorProp,\n cardTextColor: cardTextColorProp,\n faintColor: faintColorProp,\n columnFill: columnFillProp,\n columnStroke: columnStrokeProp,\n cardFill: cardFillProp,\n}: KanbanBoardProps) {\n const frame = useCurrentFrame()\n const { fps, width: canvasW, height: canvasH } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const stagger = framesOf(staggerIn, fps)\n const theme = useTheme()\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n const accent = accentProp ?? theme.accent\n const textColor = textColorProp ?? theme.text\n const cardTextColor = cardTextColorProp ?? theme.textMuted\n const faintColor = faintColorProp ?? theme.textMuted\n const columnFill = columnFillProp ?? theme.surface\n const columnStroke = columnStrokeProp ?? theme.border\n const cardFill = cardFillProp ?? theme.surface\n\n // Soft elevation shadows: tinted toward the canvas bg (never hard black) so\n // cards read as panels floating above the near-surface column. The active\n // card swaps the neutral tint for a faint accent-tinted glow.\n const shadowTint = withAlpha(theme.background, 0.45)\n const shadowGlow = withAlpha(accent, 0.28)\n\n const headerSize = fontSize\n const cardSize = Math.round(headerSize * 0.82)\n\n // Inner padding of each column (ondajs: padding ≈ 0.9 * gap).\n const pad = Math.round(gap * 0.9)\n // Vertical gap between ticket cards (ondajs: 0.6 * gap).\n const cardGap = Math.round(gap * 0.6)\n // Inner padding inside each ticket card (ondajs: 0.7 * gap).\n const cardPad = Math.round(gap * 0.7)\n\n const dotSize = Math.round(cardSize * 0.42)\n const countSize = Math.round(cardSize * 0.78)\n // Header row height = the tallest of its inline parts.\n const headerH = Math.max(headerSize, dotSize, countSize)\n // Single-line label height + vertical padding on both sides.\n const cardH = cardSize + cardPad * 2\n // Accent stripe on the left edge of each card.\n const stripeW = 3\n const stripeGap = 8\n\n // Equal-width columns split `width` minus the (n-1) inter-column gaps.\n const n = Math.max(1, columns.length)\n const colWidth = Math.max(1, Math.floor((width - gap * (n - 1)) / n))\n\n // Board height = tallest column (header + its full card stack), so we can\n // center the fixed-size board by computing its top-left offset directly — no\n // layout container chasing the per-frame rise.\n const columnHeight = (col: KanbanColumn): number => {\n const cards = col.cards ?? []\n const stackH = cards.length > 0 ? cards.length * cardH + (cards.length - 1) * cardGap : 0\n const inner = headerH + (stackH > 0 ? gap + stackH : 0)\n return inner + pad * 2\n }\n const boardHeight = columns.reduce((m, col) => Math.max(m, columnHeight(col)), 0)\n\n const originX = Math.round((canvasW - width) / 2)\n const originY = Math.round((canvasH - boardHeight) / 2)\n\n // Flat running index across all cards keeps the cascade reading\n // left-to-right, top-to-bottom across the whole board.\n let cardIndex = 0\n\n return (\n <Group x={originX} y={originY}>\n {columns.map((col, ci) => {\n const colAccent = col.accent ?? accent\n const hasAccent = col.accent != null\n const dotColor = hasAccent ? colAccent : faintColor\n const countColor = hasAccent ? colAccent : faintColor\n const cards = col.cards ?? []\n const colX = ci * (colWidth + gap)\n\n return (\n <Group key={`${ci}-${col.title}`} x={colX} y={0}>\n {/* Glass column surface (translucent fill + faint border). */}\n <Rect\n x={0}\n y={0}\n width={colWidth}\n height={boardHeight}\n cornerRadius={16}\n fill={columnFill}\n stroke={columnStroke}\n strokeWidth={1}\n />\n\n {/* Column header: status dot · title · ticket count. */}\n <Group x={pad} y={pad}>\n <Ellipse\n x={0}\n y={Math.round((headerH - dotSize) / 2)}\n width={dotSize}\n height={dotSize}\n fill={dotColor}\n />\n <Text\n x={dotSize + 10}\n y={Math.round((headerH - headerSize) / 2)}\n fontSize={headerSize}\n color={textColor}\n fontFamily={fontFamily}\n fontWeight={600}\n letterSpacing={letterSpacing}\n >\n {applyTextCase(col.title, { uppercase })}\n </Text>\n {/* Count — right-aligned within the inner column width. The engine\n measures text from its own origin (no right-align), so we offset\n by an estimated glyph advance; close enough for a 1–2 digit\n count (see approximations). */}\n <Text\n x={colWidth - pad * 2 - countSize * (`${cards.length}`.length * 0.62)}\n y={Math.round((headerH - countSize) / 2)}\n fontSize={countSize}\n color={countColor}\n fontFamily={fontFamily}\n fontWeight={500}\n >\n {`${cards.length}`}\n </Text>\n </Group>\n\n {/* Ticket cards — each rises + fades in on the flat running stagger. */}\n <Group x={pad} y={pad + headerH + gap}>\n {cards.map((label, ti) => {\n // One earned accent: the active/priority card is the FIRST card\n // of the accented column. It alone gets the live accent stripe +\n // a soft accent glow; every other card stays calm and faint.\n const isActive = hasAccent && ti === 0\n const stripeColor = isActive ? colAccent : faintColor\n const stripeOpacity = isActive ? 1 : 0.35\n\n const cardDelay = delay + staggerFrames(cardIndex, stagger)\n cardIndex += 1\n\n const local = Math.max(0, frame - cardDelay)\n const progress = spring({\n frame: local,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n const opacity = interpolate(progress, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n const rise = interpolate(progress, [0, 1], [16, 0], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n const cardY = ti * (cardH + cardGap)\n const cardInnerW = colWidth - pad * 2\n\n return (\n // Outer Group: explicit layout position (x/y). Inner Group:\n // motion rise + opacity. Nesting keeps the translate off the\n // layout-positioned node.\n <Group key={`${ti}-${label}`} x={0} y={cardY}>\n <Group y={rise} opacity={opacity}>\n {/* Soft elevation shadow tinted toward the canvas bg (not\n hard black) so cards read as floating above the column.\n The active card earns a faint accent-tinted glow. */}\n <Rect\n x={0}\n y={0}\n width={cardInnerW}\n height={cardH}\n cornerRadius={8}\n fill={cardFill}\n stroke={columnStroke}\n strokeWidth={1}\n shadow={\n isActive\n ? { color: shadowGlow, blur: 26, offsetY: 8, spread: -2 }\n : { color: shadowTint, blur: 22, offsetY: 8, spread: -4 }\n }\n />\n {/* Left accent stripe — live accent only on the active card. */}\n <Rect\n x={cardPad}\n y={cardPad}\n width={stripeW}\n height={cardH - cardPad * 2}\n cornerRadius={2}\n fill={stripeColor}\n opacity={stripeOpacity}\n />\n <Text\n x={cardPad + stripeW + stripeGap}\n y={cardPad}\n fontSize={cardSize}\n color={isActive ? textColor : cardTextColor}\n fontFamily={fontFamily}\n fontWeight={isActive ? 500 : 400}\n >\n {label}\n </Text>\n </Group>\n </Group>\n )\n })}\n </Group>\n </Group>\n )\n })}\n </Group>\n )\n}\n\n/** Parse a 2-char hex byte to 0..255, defaulting to 0. */\nfunction hx(byte: string): number {\n const v = Number.parseInt(byte, 16)\n return Number.isNaN(v) ? 0 : v\n}\n\n/** Two-digit hex for a 0..255 channel. */\nfunction toHexByte(v: number): string {\n const c = Math.max(0, Math.min(255, Math.round(v)))\n return c.toString(16).padStart(2, '0')\n}\n\n/** Parse `#rgb` / `#rrggbb` / `#rrggbbaa` to an RGB triple. */\nfunction parseRgb(color: string): [number, number, number] {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return [hx(`${r}${r}`), hx(`${g}${g}`), hx(`${b}${b}`)]\n }\n if (hex.length === 6 || hex.length === 8) {\n return [hx(hex.slice(0, 2)), hx(hex.slice(2, 4)), hx(hex.slice(4, 6))]\n }\n }\n return [0, 0, 0]\n}\n\n/** Return `color`'s RGB with the given alpha (0..1) as `#rrggbbaa`. */\nfunction withAlpha(color: string, alpha: number): string {\n const [r, g, b] = parseRgb(color)\n const a = Math.max(0, Math.min(1, alpha)) * 255\n return `#${toHexByte(r)}${toHexByte(g)}${toHexByte(b)}${toHexByte(a)}`\n}\n","//! KenBurns — a slow cinematic zoom + pan over a photo (the iconic documentary\n//! motion). Ported from ondajs.\n//!\n//! Intentionally **linear** (no spring, no easing) for a constant slow-cinematic\n//! drift. Springs/eases at this multi-second scale read as \"the camera is\n//! accelerating\" — wrong for Ken Burns, which is steady throughout. So this is\n//! one of the few components that interpolates frame→progress directly rather\n//! than reaching for the choreography vocabulary.\n//!\n//! Engine model vs ondajs CSS. ondajs renders an `<Img>` with `objectFit: cover`,\n//! then `transform: scale(s)` about a `transformOrigin`. The engine's `<Image>`\n//! now takes a `width`/`height` box and `fit=\"cover\"`, so the renderer (which\n//! measures the decoded image) makes the photo fill the composition for ANY\n//! source aspect — no more guessing the image size. We layer the Ken Burns zoom\n//! on top, scaling about the pan origin (a fraction of the viewport). Engine\n//! scale pivots on a node's LOCAL origin (0,0), so the pivot is applied via\n//! translate-in / scale / translate-back. The outer `<Group clip>` masks the\n//! zoomed image to the composition (ondajs's `overflow: hidden`).\n//!\n//! Approximation: ondajs supports a `placement` box to sit the effect in a\n//! sub-region; the engine has no equivalent layout primitive here, so this port\n//! always fills the full composition (the ondajs default, `placement` omitted).\n\nimport { Group, Image, interpolate, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { type TimeInput, framesOf } from '../time.js'\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport interface KenBurnsProps {\n /** Image source (resolved at render time by `onda render`). */\n src: string\n /** Frames before the drift starts. */\n delay?: TimeInput\n /** Frames over which the zoom + pan completes. 150f ≈ 5s @ 30fps. */\n duration?: TimeInput\n /** Starting scale (atop the cover fit). Default 1.0. */\n fromScale?: number\n /** Ending scale — keep the delta restrained (1.0 → 1.1). Default 1.1. */\n toScale?: number\n /** Starting pan origin X. `0` = left, `1` = right. Default 0.5 (center). */\n fromX?: number\n /** Starting pan origin Y. `0` = top, `1` = bottom. Default 0.5 (center). */\n fromY?: number\n /** Ending pan origin X. Default 0.5. */\n toX?: number\n /** Ending pan origin Y. Default 0.5. */\n toY?: number\n}\n\nexport function KenBurns({\n src,\n delay: delayIn = 0,\n duration: durationIn = 150,\n fromScale = 1.0,\n toScale = 1.1,\n fromX = 0.5,\n fromY = 0.5,\n toX = 0.5,\n toY = 0.5,\n}: KenBurnsProps) {\n const frame = useCurrentFrame()\n const { width: compWidth, height: compHeight, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n\n // Linear progress 0 → 1 across [delay, delay + duration]. No spring, no easing\n // (see header) — the steady drift is the whole point. Guard duration ≥ 1.\n const span = duration > 0 ? duration : 1\n const progress = interpolate(frame - delay, [0, span], [0, 1], CLAMP)\n\n // Ken Burns zoom and the panning origin, all linear.\n const zoom = interpolate(progress, [0, 1], [fromScale, toScale], CLAMP)\n const originX = interpolate(progress, [0, 1], [fromX, toX], CLAMP)\n const originY = interpolate(progress, [0, 1], [fromY, toY], CLAMP)\n\n // Zoom pivot: the pan origin as a point in the viewport. Scaling about it keeps\n // that point fixed as the image zooms, so animating the origin pans the frame.\n const pivotX = originX * compWidth\n const pivotY = originY * compHeight\n\n // NB: KenBurns ALWAYS fills the full composition, so the over-scanned zoom is\n // already masked by the canvas — no wrapping `<Group clip>` is needed. (That\n // clip also tripped a renderer bug where a clip layer occludes LATER siblings,\n // so text/graphics placed over a KenBurns in the same scene vanished.)\n return (\n <Group x={pivotX} y={pivotY}>\n <Group scaleX={zoom} scaleY={zoom}>\n <Group x={-pivotX} y={-pivotY}>\n {/* The renderer covers the photo to the composition box for any source\n aspect (measures the decoded image — no intrinsic size needed). */}\n <Image src={src} width={compWidth} height={compHeight} fit=\"cover\" />\n </Group>\n </Group>\n </Group>\n )\n}\n","//! Keyframe sampling — the per-channel interpolation + cubic-bezier easing shared\n//! by the `Keyframes` component (this package), the cinema EXPORT choreography\n//! (@onda-engine/cinema), and the Studio live-preview renderer. ONE implementation, so\n//! preview == export by construction (no twin to drift). Pure math, no React.\n\nexport type Ease =\n | 'linear'\n | 'ease'\n | 'easeIn'\n | 'easeOut'\n | 'easeInOut'\n | [number, number, number, number]\n\n/** One position keyframe. `ease` is the TEMPORAL curve of the segment ENDING at this\n * key (speed). `ti`/`to` are SPATIAL bezier tangents — handle offsets RELATIVE to\n * this key's (x,y): `to` shapes the path LEAVING this key, `ti` the path ARRIVING.\n * Both absent ⇒ a straight segment (legacy behaviour, unchanged). */\nexport interface PosKey {\n at: number\n x: number\n y: number\n ease?: Ease\n ti?: [number, number]\n to?: [number, number]\n}\n/** One scalar keyframe (opacity 0–1, scale, rotation°). */\nexport interface ValKey {\n at: number\n v: number\n ease?: Ease\n}\n\nexport interface KeyframeTracks {\n position?: PosKey[]\n opacity?: ValKey[]\n scale?: ValKey[]\n /** Non-uniform horizontal scale — wins over `scale` when present. */\n scaleX?: ValKey[]\n /** Non-uniform vertical scale — wins over `scale` when present. */\n scaleY?: ValKey[]\n rotation?: ValKey[]\n}\n\nexport interface SampledKeyframes {\n x: number\n y: number\n opacity: number\n scale: number\n scaleX: number\n scaleY: number\n rotation: number\n}\n\nconst NAMED: Record<string, [number, number, number, number]> = {\n linear: [0, 0, 1, 1],\n ease: [0.25, 0.1, 0.25, 1],\n easeIn: [0.42, 0, 1, 1],\n easeOut: [0, 0, 0.58, 1],\n easeInOut: [0.42, 0, 0.58, 1],\n}\n\n/** Standard CSS cubic-bezier easing — solve y for x=t via Newton–Raphson. */\nfunction makeBezier([x1, y1, x2, y2]: [number, number, number, number]): (t: number) => number {\n const cx = 3 * x1\n const bx = 3 * (x2 - x1) - cx\n const ax = 1 - cx - bx\n const cy = 3 * y1\n const by = 3 * (y2 - y1) - cy\n const ay = 1 - cy - by\n const sampleX = (t: number) => ((ax * t + bx) * t + cx) * t\n const sampleY = (t: number) => ((ay * t + by) * t + cy) * t\n const dX = (t: number) => (3 * ax * t + 2 * bx) * t + cx\n const solveX = (x: number) => {\n let t = x\n for (let i = 0; i < 8; i++) {\n const dx = sampleX(t) - x\n const d = dX(t)\n if (Math.abs(dx) < 1e-5 || d === 0) break\n t -= dx / d\n // Clamp t to [0,1] — Newton can overshoot past the curve for certain handles,\n // and sampleY() then EXTRAPOLATES the cubic to a wild value (a 1-frame spike).\n t = t < 0 ? 0 : t > 1 ? 1 : t\n }\n return t\n }\n return (x: number) => sampleY(solveX(x < 0 ? 0 : x > 1 ? 1 : x))\n}\n\nconst FN_CACHE = new Map<string, (t: number) => number>()\nfunction easeFn(e?: Ease): (t: number) => number {\n const p: [number, number, number, number] = (Array.isArray(e) ? e : NAMED[e ?? 'linear']) ?? [\n 0, 0, 1, 1,\n ]\n const key = p.join(',')\n let f = FN_CACHE.get(key)\n if (!f) {\n f = makeBezier(p)\n FN_CACHE.set(key, f)\n }\n return f\n}\n\n/** Sample one channel of a track at `frame` — clamps to the end keys; between two\n * keys, eases `t` by the LATER key's `ease` (the segment's curve). */\nexport function sampleTrack<T extends { at: number; ease?: Ease }>(\n track: T[] | undefined,\n frame: number,\n get: (k: T) => number,\n dflt: number,\n): number {\n if (!track || track.length === 0) return dflt\n const first = track[0] as T\n const last = track[track.length - 1] as T\n if (frame <= first.at) return get(first)\n if (frame >= last.at) return get(last)\n for (let i = 0; i < track.length - 1; i++) {\n const a = track[i] as T\n const b = track[i + 1] as T\n if (frame >= a.at && frame < b.at) {\n const t = (frame - a.at) / (b.at - a.at)\n const e = easeFn(b.ease)(t)\n return get(a) + (get(b) - get(a)) * e\n }\n }\n return get(last)\n}\n\n/** Sample the position track at `frame` as a 2-D point. Straight (independent x/y\n * lerp) unless a segment carries a SPATIAL tangent (`a.to` or `b.ti`), in which case\n * the path follows a cubic bezier P0=a, P1=a+a.to, P2=b+b.ti, P3=b — evaluated at the\n * TEMPORALLY-eased parameter, so curve shape (tangents) and speed (ease) stay\n * independent, exactly like After Effects / Jitter / Lottie. */\nexport function samplePosition(\n track: PosKey[] | undefined,\n frame: number,\n): { x: number; y: number } {\n if (!track || track.length === 0) return { x: 0, y: 0 }\n const first = track[0] as PosKey\n const last = track[track.length - 1] as PosKey\n if (frame <= first.at) return { x: first.x, y: first.y }\n if (frame >= last.at) return { x: last.x, y: last.y }\n for (let i = 0; i < track.length - 1; i++) {\n const a = track[i] as PosKey\n const b = track[i + 1] as PosKey\n if (frame >= a.at && frame < b.at) {\n const e = easeFn(b.ease)((frame - a.at) / (b.at - a.at))\n if (a.to || b.ti) {\n const p1x = a.x + (a.to?.[0] ?? 0)\n const p1y = a.y + (a.to?.[1] ?? 0)\n const p2x = b.x + (b.ti?.[0] ?? 0)\n const p2y = b.y + (b.ti?.[1] ?? 0)\n const m = 1 - e\n const c0 = m * m * m\n const c1 = 3 * m * m * e\n const c2 = 3 * m * e * e\n const c3 = e * e * e\n return {\n x: c0 * a.x + c1 * p1x + c2 * p2x + c3 * b.x,\n y: c0 * a.y + c1 * p1y + c2 * p2y + c3 * b.y,\n }\n }\n return { x: a.x + (b.x - a.x) * e, y: a.y + (b.y - a.y) * e }\n }\n }\n return { x: last.x, y: last.y }\n}\n\n/** Sample every channel at `frame`. Absent channels return their neutral default\n * (position offset 0, opacity 1, scale 1, rotation 0). */\nexport function sampleKeyframes(tracks: KeyframeTracks, frame: number): SampledKeyframes {\n const pos = samplePosition(tracks.position, frame)\n const scale = sampleTrack(tracks.scale, frame, (k) => k.v, 1)\n return {\n x: pos.x,\n y: pos.y,\n opacity: sampleTrack(tracks.opacity, frame, (k) => k.v, 1),\n scale,\n // Non-uniform: a dedicated scaleX/scaleY track wins; else fall back to the\n // uniform `scale` (so existing uniform-scale tracks are unchanged).\n scaleX: tracks.scaleX ? sampleTrack(tracks.scaleX, frame, (k) => k.v, 1) : scale,\n scaleY: tracks.scaleY ? sampleTrack(tracks.scaleY, frame, (k) => k.v, 1) : scale,\n rotation: sampleTrack(tracks.rotation, frame, (k) => k.v, 0),\n }\n}\n\n/** True if `params` carries any keyframe track — lets a renderer/editor detect a\n * `pattern:\"keyframes\"` animation. */\nexport function hasKeyframeTracks(params: Record<string, unknown> | undefined): boolean {\n if (!params) return false\n return (['position', 'opacity', 'scale', 'scaleX', 'scaleY', 'rotation'] as const).some((k) => {\n const v = params[k]\n return Array.isArray(v) && v.length > 0\n })\n}\n","//! Keyframes — the engine's general declarative-keyframe primitive. Animate ANY\n//! element along explicit per-channel tracks (position / opacity / scale /\n//! rotation), each keyframe carrying its own easing (a named curve OR a raw\n//! cubic-bezier [x1,y1,x2,y2] — so a Lottie/AE curve transcribes 1:1). This is what\n//! lets a composition express ARBITRARY motion, not just the fixed entrance presets:\n//! \"this element is at A at frame 0, B at frame 18 on THIS ease, C at frame 54…\".\n//!\n//! It renders ONE content element (an image tile or a text line) so it slots into\n//! the flat composition-entry model; the content (src / text / color) stays an\n//! editable prop while the motion lives in the tracks (motion is never themed).\n\nimport {\n Ellipse,\n type GradientInput,\n Group,\n Image,\n Path,\n Rect,\n Text,\n clipRect,\n useCurrentFrame,\n} from '@onda-engine/react'\nimport { LINE_RATIO, layoutGlyphLine, lineStartX } from '../glyph-line.js'\nimport { type PosKey, type ValKey, sampleKeyframes } from '../keyframes-sampler.js'\nimport { type Theme, useTheme } from '../theme.js'\n\n// The track types + sampler now live in ../keyframes-sampler.js — ONE\n// implementation shared with the cinema export + the Studio preview. Re-exported\n// here so existing `import { PosKey } from './components/Keyframes'` keeps working.\nexport type { Ease, PosKey, ValKey } from '../keyframes-sampler.js'\n\n// ── Slot binding ──────────────────────────────────────────────────────────────\n// A fill can be SLOT-BOUND: an override handle (`slot`) carrying the original literal\n// (`default`, rendered when unset → byte-identical) and an optional `value` override\n// (wins). The renderer only needs `value ?? default`; `slot` is the id the studio/agent\n// targets, and multiple fills may share one. For a color T is a string — a brand token\n// OR a literal hex; the renderer never constrains a slot value to brand tokens.\nexport interface SlotRef<T> {\n slot: string\n default: T\n value?: T\n}\nexport type Slottable<T> = T | SlotRef<T>\nfunction isSlotRef<T>(v: Slottable<T> | undefined): v is SlotRef<T> {\n return typeof v === 'object' && v !== null && 'slot' in v && 'default' in v\n}\n/** The effective value of a slottable field: the override (`value`) if set, else `default`.\n * Overloaded so a REQUIRED field (e.g. `width`) resolves to `T`, an optional one to `T | undefined`. */\nexport function slotValue<T>(v: Slottable<T>): T\nexport function slotValue<T>(v: Slottable<T> | undefined): T | undefined\nexport function slotValue<T>(v: Slottable<T> | undefined): T | undefined {\n if (v === undefined) return undefined\n return isSlotRef(v) ? (v.value ?? v.default) : v\n}\n\nexport interface KeyframesImageContent {\n kind: 'image'\n /** Image source — a literal URL or a `{slot}` to swap. Omit for a `gradient`/`color` placeholder. */\n src?: Slottable<string>\n /** Gradient fill (linear/radial/fbm or a `{slot}`) used when `src` is absent — wins over `color`. */\n gradient?: Slottable<GradientInput>\n /** Solid fill — a hex, a brand-token name, or a `{slot}`; used when neither `src` nor `gradient` is set. Defaults to the theme surface. */\n color?: Slottable<string>\n /** Outline color (hex/token/`{slot}`) — for a stroked/outline rect. */\n stroke?: Slottable<string>\n /** Outline thickness (px) — a literal or a `{slot}`. */\n strokeWidth?: Slottable<number>\n /** Width (px) — a literal or a `{slot}` (resize). */\n width: Slottable<number>\n /** Height (px) — a literal or a `{slot}` (resize). */\n height: Slottable<number>\n /** Corner rounding (px) — a literal or a `{slot}`. */\n cornerRadius?: Slottable<number>\n /** Pivot in content space (defaults to the tile CENTER). */\n anchorX?: number\n anchorY?: number\n}\n/** An ellipse/ring leaf — fill via `color`/`gradient`, or `stroke` only for a ring. */\nexport interface KeyframesEllipseContent {\n kind: 'ellipse'\n width: Slottable<number>\n height: Slottable<number>\n color?: Slottable<string>\n gradient?: Slottable<GradientInput>\n stroke?: Slottable<string>\n strokeWidth?: Slottable<number>\n anchorX?: number\n anchorY?: number\n}\n/** An arbitrary vector path leaf (SVG `d`, local space). Native/GPU render. */\nexport interface KeyframesPathContent {\n kind: 'path'\n d: string\n color?: Slottable<string>\n gradient?: Slottable<GradientInput>\n stroke?: Slottable<string>\n strokeWidth?: Slottable<number>\n anchorX?: number\n anchorY?: number\n}\nexport interface KeyframesTextContent {\n kind: 'text'\n text: Slottable<string>\n /** Text size (px) — a literal or a `{slot}` (resize). */\n fontSize: Slottable<number>\n color?: Slottable<string>\n /** Typeface — a literal family name or a `{slot}` (the brand `font`). */\n fontFamily?: Slottable<string>\n /** Weight — a literal or a `{slot}`. */\n fontWeight?: Slottable<number>\n letterSpacing?: number\n /** Horizontal alignment of the text about its `position` x. `'left'` (default,\n * and the legacy behaviour) anchors the LEFT edge at the position; `'center'`\n * measures the rendered text and centres it on the position; `'right'` ends at\n * it. When set, it OVERRIDES `anchorX` (the engine computes the pivot). This is\n * what lets the agent \"centre this text\" on a raw-positioned Keyframes element. */\n align?: 'left' | 'center' | 'right'\n /** Vertical alignment of the text about its `position` y. `'top'` (default, the\n * legacy behaviour) anchors the TOP of the line box at the position; `'middle'`\n * centres it vertically; `'bottom'` anchors the bottom edge. When set, it\n * OVERRIDES `anchorY`. Combine with `align` for the full 9-point grid — e.g.\n * `align:'right' + vAlign:'top'` = top-right corner, `align:'center' +\n * vAlign:'middle'` = dead-centre on the position. */\n vAlign?: 'top' | 'middle' | 'bottom'\n /** Pivot in content space (defaults to top-left 0,0). `anchorX` ignored when\n * `align` is set; `anchorY` ignored when `vAlign` is set. */\n anchorX?: number\n anchorY?: number\n}\n\nexport type KeyframesContent =\n | KeyframesImageContent\n | KeyframesTextContent\n | KeyframesEllipseContent\n | KeyframesPathContent\n\n/** A keyframe on the path-`d` MORPH track: the `content.kind:\"path\"` `d` at frame `at`. */\nexport interface DMorphKey {\n at: number\n d: string\n}\n\nexport interface KeyframesProps {\n position?: PosKey[]\n opacity?: ValKey[]\n scale?: ValKey[]\n /** Non-uniform horizontal scale — wins over `scale` (e.g. a bar growing wide). */\n scaleX?: ValKey[]\n /** Non-uniform vertical scale — wins over `scale`. */\n scaleY?: ValKey[]\n rotation?: ValKey[]\n /** Path-`d` MORPH track — interpolates a `content.kind:\"path\"` element's `d` across\n * keyframes so the SHAPE itself transforms (a wave reforming, a logo morphing). The\n * forms must share segment structure (same command sequence) → numeric lerp with\n * ease-in-out, exactly like CSS `d:path()`. Ignored for non-path content. */\n morph?: DMorphKey[]\n content: KeyframesContent\n}\n\n// ── Path-`d` morph: interpolate two same-structure SVG `d` strings number-by-number\n// (keep command letters, lerp the coordinates). Mismatched structure → step (no crash).\nconst PATH_TOKENS = /[a-zA-Z]|-?\\d*\\.?\\d+/g\nfunction lerpPathD(a: string, b: string, t: number): string {\n const ta = a.match(PATH_TOKENS)\n const tb = b.match(PATH_TOKENS)\n if (!ta || !tb || ta.length !== tb.length) return t < 0.5 ? a : b\n return ta\n .map((tok, i) =>\n /[a-zA-Z]/.test(tok) ? tok : (Number(tok) + (Number(tb[i]) - Number(tok)) * t).toFixed(3),\n )\n .join(' ')\n}\nfunction easeInOut(t: number): number {\n return t < 0.5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2\n}\nfunction sampleMorph(keys: DMorphKey[], frame: number): string {\n const first = keys[0]\n if (!first) return ''\n const last = keys[keys.length - 1]\n if (keys.length === 1 || !last || frame <= first.at) return first.d\n if (frame >= last.at) return last.d\n let i = 0\n while (i < keys.length - 1) {\n const next = keys[i + 1]\n if (!next || next.at > frame) break\n i++\n }\n const a = keys[i]\n const b = keys[i + 1]\n if (!a || !b) return first.d\n return lerpPathD(a.d, b.d, easeInOut((frame - a.at) / (b.at - a.at)))\n}\n\n// Brand-token names a color/stroke can reference instead of a literal hex — they\n// resolve through the active theme, so a fill bound to \"accent\" recolors when the\n// brand changes (the cascade the editor's brand-binding relies on).\nconst THEME_TOKENS = [\n 'accent',\n 'accentSoft',\n 'text',\n 'textMuted',\n 'background',\n 'surface',\n 'border',\n] as const\nexport function resolveColor(c: Slottable<string> | undefined, theme: Theme): string | undefined {\n const s = slotValue(c)\n if (!s) return s\n return (THEME_TOKENS as readonly string[]).includes(s)\n ? (theme as unknown as Record<string, string>)[s]\n : s\n}\n\n/** Build paint props (fill/gradient/stroke) for a shape leaf. `stroke`-only (no\n * color/gradient) yields a ring; `fallbackFill` applies only when nothing else is set.\n * `color`/`stroke` may be a brand-token name (resolved via the theme). */\nfunction paint(\n c: {\n color?: Slottable<string>\n gradient?: Slottable<GradientInput>\n stroke?: Slottable<string>\n strokeWidth?: Slottable<number>\n },\n theme: Theme,\n fallbackFill?: string,\n): Record<string, unknown> {\n const p: Record<string, unknown> = {}\n const color = resolveColor(c.color, theme)\n const stroke = resolveColor(c.stroke, theme)\n const gradient = slotValue(c.gradient)\n if (gradient) p.gradient = gradient\n else if (color) p.fill = color\n else if (fallbackFill && !stroke) p.fill = fallbackFill\n if (stroke) {\n p.stroke = stroke\n p.strokeWidth = slotValue(c.strokeWidth) ?? 2\n }\n return p\n}\n\nexport function Keyframes({\n position,\n opacity,\n scale,\n scaleX,\n scaleY,\n rotation,\n morph,\n content,\n}: KeyframesProps) {\n const frame = useCurrentFrame()\n const theme = useTheme()\n const {\n x,\n y,\n opacity: op,\n scaleX: scX,\n scaleY: scY,\n rotation: rot,\n } = sampleKeyframes({ position, opacity, scale, scaleX, scaleY, rotation }, frame)\n if (op <= 0.002) return null\n\n let inner: React.ReactNode\n if (content.kind === 'image') {\n const width = slotValue(content.width)\n const height = slotValue(content.height)\n const cornerRadius = slotValue(content.cornerRadius) ?? 0\n const ax = content.anchorX ?? width / 2\n const ay = content.anchorY ?? height / 2\n const src = slotValue(content.src)\n inner = src ? (\n <Group x={-ax} y={-ay} clip={clipRect(width, height, cornerRadius)}>\n <Image src={src} width={width} height={height} fit=\"cover\" />\n </Group>\n ) : (\n // No image yet → a gradient/solid/outline placeholder card to swap an image into.\n <Group x={-ax} y={-ay}>\n <Rect\n width={width}\n height={height}\n cornerRadius={cornerRadius}\n {...paint(content, theme, theme.surface)}\n />\n </Group>\n )\n } else if (content.kind === 'ellipse') {\n const width = slotValue(content.width)\n const height = slotValue(content.height)\n const ax = content.anchorX ?? width / 2\n const ay = content.anchorY ?? height / 2\n inner = (\n <Group x={-ax} y={-ay}>\n <Ellipse width={width} height={height} {...paint(content, theme, theme.surface)} />\n </Group>\n )\n } else if (content.kind === 'path') {\n const pathD = morph && morph.length > 0 ? sampleMorph(morph, frame) : content.d\n inner = (\n <Group x={-(content.anchorX ?? 0)} y={-(content.anchorY ?? 0)}>\n <Path d={pathD} {...paint(content, theme, theme.surface)} />\n </Group>\n )\n } else {\n const fontFamily = slotValue(content.fontFamily) ?? theme.headingFamily ?? theme.fontFamily\n const fontWeight = slotValue(content.fontWeight) ?? 400\n const fontSize = slotValue(content.fontSize)\n const text = slotValue(content.text) ?? ''\n // Horizontal: `align` measures the rendered line and anchors left/centre/right\n // edge on the position (overriding anchorX); unset → legacy anchorX pivot.\n let textX = -(content.anchorX ?? 0)\n if (content.align) {\n const { width } = layoutGlyphLine(text, fontSize, {\n fontFamily,\n fontWeight,\n letterSpacing: content.letterSpacing,\n })\n textX = lineStartX(content.align, 0, width)\n }\n // Vertical: the Text node's y is the TOP of the line box (height = fontSize ×\n // LINE_RATIO), so anchoring mirrors the horizontal formula; unset → anchorY.\n let textY = -(content.anchorY ?? 0)\n if (content.vAlign) {\n const h = fontSize * LINE_RATIO\n textY = content.vAlign === 'middle' ? -h / 2 : content.vAlign === 'bottom' ? -h : 0\n }\n inner = (\n <Text\n x={textX}\n y={textY}\n fontSize={fontSize}\n color={resolveColor(content.color, theme) ?? theme.text}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n letterSpacing={content.letterSpacing}\n >\n {text}\n </Text>\n )\n }\n\n return (\n <Group x={x} y={y} opacity={op}>\n <Group scaleX={scX} scaleY={scY} rotation={rot}>\n {inner}\n </Group>\n </Group>\n )\n}\n","//! responsive.ts — \"Magic Resize\" layout. Re-frame an absolutely-positioned element\n//! from the canvas it was AUTHORED on (its \"design\" canvas) onto a DIFFERENT output\n//! canvas, the way Canva's Magic Resize / Figma constraints do: each element pins to\n//! the NEAR edge or tracks the CENTRE, per axis, and its SIZE scales uniformly so it\n//! never distorts. This generalises the single uniform `cover`/`contain` fit — which\n//! is just \"every element pinned to centre at one shared scale\" — to PER-ELEMENT\n//! anchors, so one master composition adapts to 16:9 / 4:3 / 1:1 / 9:16 with no\n//! hand-built per-format variants.\n//!\n//! Pure math, no React — shared by the @onda-engine/cinema EXPORT and the Studio live\n//! PREVIEW so the two can't drift (the same contract as ./keyframes-sampler).\n\nimport type { PosKey, ValKey } from './keyframes-sampler.js'\n\nexport interface Box {\n width: number\n height: number\n}\n\n/** The `<Group>` transform that re-frames a design-space element onto the output. */\nexport interface ResponsiveTransform {\n x: number\n y: number\n scale: number\n}\n\n/** How close (as a fraction of the canvas) an element's anchor must sit to an edge\n * to PIN to that edge instead of tracking the centre — the outer fifth each side. */\nconst EDGE = 0.2\n\nconst mean = (ns: number[]): number => (ns.length ? ns.reduce((a, b) => a + b, 0) / ns.length : 0)\n\n/** The representative design-space point an element \"lives at\" — the mean of its\n * position track, nudged to the visual CENTRE of image content (whose pivot defaults\n * to a corner). Returns `null` for elements with NO absolute position: those already\n * self-place against the output canvas (`placement`), so they must NOT be re-anchored. */\nexport function entryDesignAnchor(\n props: Record<string, unknown> | undefined,\n): { x: number; y: number } | null {\n const position = props?.position as PosKey[] | undefined\n if (!Array.isArray(position) || position.length === 0) return null\n let x = mean(position.map((k) => k.x))\n let y = mean(position.map((k) => k.y))\n // Image tiles pivot at a corner (anchorX/anchorY) and are scaled down — shift the\n // anchor to the tile's visual centre so it pins by where it READS, not its corner.\n const content = props?.content as\n | { kind?: string; width?: number; height?: number; anchorX?: number; anchorY?: number }\n | undefined\n if (content?.kind === 'image' && content.width && content.height) {\n const scaleTrack = props?.scale as ValKey[] | undefined\n const s = Array.isArray(scaleTrack) && scaleTrack.length ? mean(scaleTrack.map((k) => k.v)) : 1\n x += (content.width / 2 - (content.anchorX ?? content.width / 2)) * s\n y += (content.height / 2 - (content.anchorY ?? content.height / 2)) * s\n }\n return { x, y }\n}\n\n/** One axis of the pin: map a design anchor coordinate onto the output — pinned to the\n * near edge, the far edge, or the centre by where it sits — keeping the gap from the\n * reference proportional to the element's own scale `s`. */\nfunction pinAxis(a: number, design: number, out: number, s: number): number {\n const frac = a / design\n if (frac <= EDGE) return a * s // hug the start edge (left / top)\n if (frac >= 1 - EDGE) return out - (design - a) * s // hug the far edge (right / bottom)\n return out / 2 + (a - design / 2) * s // track the centre\n}\n\n/** The per-element Magic-Resize transform: anchor pinned per-axis, size scaled\n * uniformly by the smaller axis ratio so the element always fits the frame and never\n * distorts. A `null` anchor or a matching canvas ⇒ identity (the element self-places). */\nexport function responsiveEntryTransform(\n anchor: { x: number; y: number } | null,\n design: Box,\n out: Box,\n): ResponsiveTransform {\n if (!anchor || (design.width === out.width && design.height === out.height)) {\n return { x: 0, y: 0, scale: 1 }\n }\n const s = Math.min(out.width / design.width, out.height / design.height)\n const ax = pinAxis(anchor.x, design.width, out.width, s)\n const ay = pinAxis(anchor.y, design.height, out.height, s)\n // Place the element's design anchor at (ax, ay) with its content scaled by s.\n return { x: ax - anchor.x * s, y: ay - anchor.y * s, scale: s }\n}\n","//! TextAnimator — the general per-unit text choreography primitive (the AE \"text\n//! animator\" model). Where `KineticText` is opinionated presets, this is the open\n//! system: choose the UNIT granularity (`glyph` | `word` | `line`), a stagger\n//! ORDER (`forward` | `backward` | `center` | `edges`), and the set of channels to\n//! ANIMATE (`opacity`/`x`/`y`/`scale`/`rotate`/`blur`/`color`), each a `[from, to]`\n//! pair driven over a per-unit progress.\n//!\n//! Layout (HARD RULE 2 — the line never reflows): each unit's RESTING x is its\n//! true shaped pen position from a single kerning-accurate `glyphLayout()` call\n//! (one per line), and units are placed ABSOLUTELY. Per-frame motion lives on each\n//! unit's OWN transform/opacity/blur, so a growing/rotating unit never jiggles its\n//! neighbours. Multi-line text (`\\n`) stacks by line height and the block is\n//! centered on the canvas.\n//!\n//! Timing: unit `i` settles on the house spring (or a custom ease) over\n//! `durationInFrames`, staggered by `staggerFrames(order(i), stagger)` — so the\n//! animation wipes across the units. `order` is set by `direction`.\n//!\n//! Determinism: every value is a pure function of `frame` (springs are frame-keyed),\n//! so the same frame renders identically every run — in preview and in export.\n//! Custom fonts: until author-time font loading lands, positions are accurate only\n//! for the BUNDLED families; a custom `fontFamily`\n//! measures against the default and may drift from the render.\n\nimport {\n Group,\n type SpringConfig,\n Text,\n interpolate,\n interpolateColors,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { HOUSE_EASE } from '../easing.js'\nimport { LINE_RATIO, layoutGlyphLine, lineStartX, lineTopY } from '../glyph-line.js'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { measureText, useTextMetricsReady } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { staggeredSettle, useTimeScale } from '../timing.js'\n\n/** What a unit is: a single glyph, a whitespace-delimited word, or a `\\n` line. */\nexport type TextAnimatorUnit = 'glyph' | 'word' | 'line'\n\n/** Stagger order across the units — which one leads the wipe. */\nexport type TextAnimatorDirection = 'forward' | 'backward' | 'center' | 'edges'\n\n/** A `[from, to]` numeric pair animated over each unit's 0→1 progress. */\ntype Pair = readonly [number, number]\n\n/** The channels a TextAnimator can drive per unit. Omitted channels stay at rest;\n * a present channel eases from `from` (progress 0) to `to` (progress 1). */\nexport interface TextAnimate {\n /** Opacity `[from, to]` (e.g. `[0, 1]` to fade in). */\n opacity?: Pair\n /** translateX in px `[from, to]`. */\n x?: Pair\n /** translateY in px `[from, to]` (e.g. `[24, 0]` to rise). */\n y?: Pair\n /** Uniform scale `[from, to]`, pivoted about the unit's own center. */\n scale?: Pair\n /** Rotation in degrees `[from, to]`, pivoted about the unit's own center. */\n rotate?: Pair\n /** Blur sigma in px `[from, to]` (RTT focus-pull — judge on native/export). */\n blur?: Pair\n /** Color `[from, to]` (any ColorInput string). */\n color?: readonly [string, string]\n}\n\nexport interface TextAnimatorProps extends TextStyleProps {\n /** The text to choreograph. `\\n` starts a new line. */\n text?: string\n /** Unit granularity (default `'glyph'`). */\n units?: TextAnimatorUnit\n /** Channels to animate per unit (default `{ opacity: [0, 1], y: [24, 0] }`). */\n animate?: TextAnimate\n /** Time between consecutive units entering (default `STAGGER` = 5 frames). */\n stagger?: TimeInput\n /** Time each unit takes to settle (default `DURATION.base`). */\n durationInFrames?: TimeInput\n /** Time before the FIRST unit starts (default 0). */\n delay?: TimeInput\n /** Compress the whole timing envelope (delay, stagger, durations) so the\n * entrance settles at least `hold` before the end of the enclosing clip\n * (`useVideoConfig().durationInFrames`, Sequence-scoped). Opt-in. */\n fitToClip?: boolean\n /** Hard cap on the settle time (frames or '0.5s'). Wins over `fitToClip`. */\n maxSettle?: TimeInput\n /** Breathing room before the cut for `fitToClip` (default 6 frames). */\n hold?: TimeInput\n /** Stagger order across units (default `'forward'`). */\n direction?: TextAnimatorDirection\n /** Physical settle spring; pass `false` to use `ease` instead (default `SPRING_SMOOTH`). */\n spring?: SpringConfig | false\n /** Easing used when `spring` is `false` (default the house ease-out). */\n ease?: (t: number) => number\n /** Font size in px (default 96). */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * line cannot exceed the frame minus the safe margins. Default `'none'`\n * (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the line; combines with `fit` (the smaller\n * cap wins). */\n maxWidth?: number\n /** Horizontal alignment of each line about the placement anchor (default `'center'`). */\n align?: 'left' | 'center' | 'right'\n /** Where the text block sits: a region keyword (`'center'`, `'lower-third'`,\n * …) or normalized `{x,y}` (0–1, block center). The shared placement\n * contract; default `'center'` (the historical centering). */\n placement?: Placement\n}\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\n/** One absolutely-placed unit ready to animate. */\ninterface PlacedUnit {\n content: string\n /** Pen x within its line (from glyphLayout). */\n lineX: number\n /** 0-based line index (for vertical stacking + per-line alignment). */\n lineIndex: number\n /** Unit width in px — the pivot width for scale/rotate. */\n width: number\n}\n\n/** Stagger order for unit `i` of `n`, per `direction`. */\nfunction orderOf(i: number, n: number, direction: TextAnimatorDirection): number {\n const mid = (n - 1) / 2\n switch (direction) {\n case 'backward':\n return n - 1 - i\n case 'center': // center leads, edges trail\n return Math.round(Math.abs(i - mid))\n case 'edges': // edges lead, center trails\n return Math.round(mid - Math.abs(i - mid))\n default:\n return i\n }\n}\n\nexport function TextAnimator({\n text: textProp = 'Animate',\n units = 'glyph',\n animate,\n stagger: staggerIn = STAGGER,\n durationInFrames: durationIn = DURATION.base,\n delay: delayIn = 0,\n fitToClip,\n maxSettle,\n hold,\n direction = 'forward',\n spring: springConfig = SPRING_SMOOTH,\n ease = HOUSE_EASE,\n fontSize: fontSizeProp = 96,\n fit,\n maxWidth,\n color: colorProp,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n align = 'center',\n placement,\n}: TextAnimatorProps) {\n // Uppercase the SOURCE before it's split into lines/units, so the case\n // transform survives the per-unit layout (mirrors the shared contract).\n const text = applyTextCase(textProp, { uppercase })\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n const channels = animate ?? { opacity: [0, 1] as Pair, y: [24, 0] as Pair }\n\n // `useTextMetricsReady` warms the engine in the browser (re-renders when ready);\n // `glyphLayout` is the sync, kerning-accurate read used per line below.\n useTextMetricsReady()\n const measureOpts = { fontFamily, fontWeight }\n\n // Opt-in auto-fit against the WIDEST line (measured at the requested size);\n // every line then lays out at the fitted size.\n const lines = text.split('\\n')\n let widest = lines[0] ?? ''\n if (lines.length > 1) {\n let widestW = -1\n for (const line of lines) {\n const w = measureText(line, fontSizeProp, measureOpts).width\n if (w > widestW) {\n widestW = w\n widest = line\n }\n }\n }\n const fontSize = useFittedFontSize(widest, fontSizeProp, { ...measureOpts, fit, maxWidth })\n const lineHeight = fontSize * LINE_RATIO // engine default (Metrics line height)\n\n // Build absolutely-placed units, one pass per line, on the SHARED glyph-line\n // primitive (one kerning-accurate layout per line; spaces advance only).\n const placed: PlacedUnit[] = []\n const lineWidths: number[] = []\n lines.forEach((line, lineIndex) => {\n const laid = layoutGlyphLine(line, fontSize, measureOpts)\n lineWidths[lineIndex] = laid.width\n\n if (units === 'line') {\n if (line.trim().length > 0) {\n placed.push({ content: line, lineX: 0, lineIndex, width: laid.width })\n }\n return\n }\n\n if (units === 'word') {\n let startX: number | null = null\n let endX = 0\n let chars: string[] = []\n const flush = () => {\n if (chars.length > 0 && startX !== null) {\n placed.push({ content: chars.join(''), lineX: startX, lineIndex, width: endX - startX })\n }\n startX = null\n endX = 0\n chars = []\n }\n for (const cell of laid.cells) {\n if (cell.space) {\n flush() // whitespace ends a word\n continue\n }\n if (startX === null) startX = cell.x\n endX = cell.x + cell.width\n chars.push(cell.ch)\n }\n flush()\n return\n }\n\n // glyph — the rendered (non-space) cells, verbatim.\n for (const cell of laid.rendered) {\n placed.push({ content: cell.ch, lineX: cell.x, lineIndex, width: cell.width })\n }\n })\n\n const n = placed.length\n\n // Timing: parse the TimeInput props, then compress the envelope when the\n // last unit wouldn't settle inside the clip.\n const staggerBase = framesOf(staggerIn, fps, STAGGER)\n const durationBase = framesOf(durationIn, fps, DURATION.base)\n const delayBase = framesOf(delayIn, fps)\n const naturalSettle = staggeredSettle(n, staggerBase, durationBase, delayBase)\n const timeScale = useTimeScale(naturalSettle, { fitToClip, maxSettle, hold })\n const stagger = staggerBase * timeScale\n const durationInFrames = Math.max(1, durationBase * timeScale)\n const delay = delayBase * timeScale\n\n // Anchor the block on the shared placement contract (block CENTER at the\n // resolved point; corner regions sit flush on the safe margin). The default\n // `'center'` reproduces the historical canvas-centering exactly.\n const blockWidth = lineWidths.length > 0 ? Math.max(...lineWidths) : 0\n const blockHeight = (lines.length - 1) * lineHeight + fontSize * LINE_RATIO\n const resolved = usePlacement(placement, { width: blockWidth, height: blockHeight })\n const anchorX = Math.round(resolved.x)\n const startXOf = (lineIndex: number) => lineStartX(align, anchorX, lineWidths[lineIndex] ?? 0)\n // Center the whole block vertically about the anchor; one line reduces to\n // KineticText's baseline.\n const blockOffset = ((lines.length - 1) * lineHeight) / 2\n const baseYOf = (lineIndex: number) =>\n lineTopY(resolved.y, fontSize) + lineIndex * lineHeight - blockOffset\n\n return (\n <Group>\n {placed.map((unit, i) => {\n const order = orderOf(i, n, direction)\n const local = Math.max(0, frame - delay - staggerFrames(order, stagger))\n const progress = springConfig\n ? spring({ frame: local, fps, config: springConfig, durationInFrames })\n : interpolate(\n frame,\n [\n delay + staggerFrames(order, stagger),\n delay + staggerFrames(order, stagger) + durationInFrames,\n ],\n [0, 1],\n { ...CLAMP, easing: ease },\n )\n\n const at = (p: Pair | undefined, fallback: number) =>\n p ? interpolate(progress, [0, 1], p, CLAMP) : fallback\n\n const opacity = at(channels.opacity, 1)\n const dx = at(channels.x, 0)\n const dy = at(channels.y, 0)\n const scale = at(channels.scale, 1)\n const rot = at(channels.rotate, 0)\n const blur = at(channels.blur, 0)\n const unitColor = channels.color\n ? interpolateColors(progress, [0, 1], channels.color, CLAMP)\n : color\n\n // Pivot scale/rotate about the unit's own center so it transforms in place.\n const pivoted = scale !== 1 || rot !== 0\n const originX = pivoted ? unit.width / 2 : 0\n const originY = pivoted ? fontSize / 2 : 0\n\n return (\n <Text\n key={`${unit.lineIndex}:${i}:${unit.content}`}\n x={startXOf(unit.lineIndex) + unit.lineX + dx}\n y={baseYOf(unit.lineIndex) + dy}\n scaleX={scale}\n scaleY={scale}\n originX={originX}\n originY={originY}\n rotation={rot}\n blur={blur > 0.01 ? blur : undefined}\n opacity={opacity}\n fontSize={fontSize}\n color={unitColor}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {unit.content}\n </Text>\n )\n })}\n </Group>\n )\n}\n","//! KineticText — opinionated per-GLYPH entrance presets, now a thin facade over\n//! the general `<TextAnimator>` engine. The four from→to presets (rise/fade/scale/\n//! blur) are just preset `animate` channel maps routed through TextAnimator, so\n//! there is ONE kinetic-type engine, one layout path, one kerning-accurate\n//! placement. `wave` is the exception — a decaying sine ripple whose offset is a\n//! function of BOTH progress and glyph index, so it doesn't fit TextAnimator's\n//! `[from, to]` channel model and keeps its own small dedicated path.\n//!\n//! Presets:\n//! - `rise` — translateY 24 → 0 + fade (the house entrance, per glyph).\n//! - `fade` — opacity only (the layout-safe minimum).\n//! - `scale` — 0.6 → 1 + fade, scaled about the glyph's OWN center.\n//! - `blur` — blur 12 → 0 + fade: a per-glyph soft→sharp focus-pull through the\n//! engine's render-to-texture pass (CPU + GPU).\n//! - `wave` — a gentle sine translateY that ripples across glyphs + fade; the\n//! ripple phase is the glyph index, so the wave travels the line.\n\nimport {\n Group,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { LINE_RATIO, layoutGlyphLine, lineStartX, lineTopY } from '../glyph-line.js'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { useTextMetricsReady } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { staggeredSettle, useTimeScale } from '../timing.js'\nimport { type TextAnimate, TextAnimator } from './TextAnimator.js'\n\n/** The per-glyph entrance presets. */\nexport type KineticTextPreset = 'rise' | 'fade' | 'scale' | 'blur' | 'wave'\n\nexport interface KineticTextProps extends TextStyleProps {\n /** The line to choreograph. Laid out as one row of absolutely-placed glyphs. */\n text?: string\n /** Font size in px (default 96). */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * line cannot exceed the frame minus the safe margins. Default `'none'`\n * (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the line; combines with `fit` (the smaller\n * cap wins). */\n maxWidth?: number\n /** Per-glyph entrance flavor (default `'rise'`). */\n preset?: KineticTextPreset\n /** Time between consecutive glyphs entering (default `STAGGER` = 5 frames). */\n stagger?: TimeInput\n /** Time each glyph's entrance takes to settle (default `DURATION.base`). */\n durationInFrames?: TimeInput\n /** Time before the FIRST glyph starts (default 0). */\n delay?: TimeInput\n /** Compress the whole timing envelope (delay, stagger, durations) so the\n * entrance settles at least `hold` before the end of the enclosing clip\n * (`useVideoConfig().durationInFrames`, Sequence-scoped). Opt-in. */\n fitToClip?: boolean\n /** Hard cap on the settle time (frames or '0.5s'). Wins over `fitToClip`. */\n maxSettle?: TimeInput\n /** Breathing room before the cut for `fitToClip` (default 6 frames). */\n hold?: TimeInput\n /** Horizontal alignment of the line about its anchor (default `'center'`). */\n align?: 'left' | 'center' | 'right'\n /** Where the line sits: a region keyword (`'center'`, `'lower-third'`, …) or\n * normalized `{x,y}` (0–1, line center). The shared placement contract;\n * default `'center'` (the historical centering). */\n placement?: Placement\n}\n\n/** Starting rise distance in px for the `rise` preset (the house 24px envelope). */\nconst RISE_PX = 24\n/** Starting scale for the `scale` preset. */\nconst SCALE_FROM = 0.6\n/** Starting blur sigma in px for the `blur` preset's focus-pull. */\nconst BLUR_FROM = 12\n/** Peak amplitude in px of the `wave` preset's sine ripple. */\nconst WAVE_AMPLITUDE = 28\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\n/** The from→to presets as TextAnimator channel maps — the single source of truth\n * for what each preset animates. `wave` is procedural and handled separately. */\nconst PRESET_ANIMATE: Record<Exclude<KineticTextPreset, 'wave'>, TextAnimate> = {\n rise: { y: [RISE_PX, 0], opacity: [0, 1] },\n fade: { opacity: [0, 1] },\n scale: { scale: [SCALE_FROM, 1], opacity: [0, 1] },\n blur: { blur: [BLUR_FROM, 0], opacity: [0, 1] },\n}\n\nexport function KineticText({\n text: textProp = 'kinetic',\n fontSize = 96,\n fit,\n maxWidth,\n preset = 'rise',\n stagger = STAGGER,\n durationInFrames = DURATION.base,\n delay = 0,\n fitToClip,\n maxSettle,\n hold,\n align = 'center',\n color,\n fontFamily,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n placement,\n}: KineticTextProps) {\n // Uppercase the SOURCE once here, before it's handed to the per-glyph engine\n // (TextAnimator / KineticWave), so the transform survives the glyph layout.\n const text = applyTextCase(textProp, { uppercase })\n // KineticText is the engine's DISPLAY-statement component, so it follows the\n // theme's heading family by default (`headingFamily ?? fontFamily`) — set\n // `fontDisplay` on the brand and the kinetic lines pick up the title face,\n // while body components keep `fontFamily`. An explicit prop still wins.\n const theme = useTheme()\n const resolvedFamily = fontFamily ?? theme.headingFamily ?? theme.fontFamily\n\n // `wave` is a decaying sine ripple (a function of progress AND index), not a\n // from→to channel — it keeps its own small path. Everything else is the general\n // engine with a preset channel map.\n if (preset === 'wave') {\n return (\n <KineticWave\n text={text}\n fontSize={fontSize}\n fit={fit}\n maxWidth={maxWidth}\n stagger={stagger}\n durationInFrames={durationInFrames}\n delay={delay}\n fitToClip={fitToClip}\n maxSettle={maxSettle}\n hold={hold}\n align={align}\n color={color}\n fontFamily={resolvedFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n placement={placement}\n />\n )\n }\n\n return (\n <TextAnimator\n text={text}\n units=\"glyph\"\n animate={PRESET_ANIMATE[preset]}\n fit={fit}\n maxWidth={maxWidth}\n stagger={stagger}\n durationInFrames={durationInFrames}\n delay={delay}\n fitToClip={fitToClip}\n maxSettle={maxSettle}\n hold={hold}\n align={align}\n fontSize={fontSize}\n color={color}\n fontFamily={resolvedFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n placement={placement}\n />\n )\n}\n\ninterface KineticWaveProps {\n text: string\n fontSize: number\n fit?: 'none' | 'frame'\n maxWidth?: number\n stagger: TimeInput\n durationInFrames: TimeInput\n delay: TimeInput\n fitToClip?: boolean\n maxSettle?: TimeInput\n hold?: TimeInput\n align: 'left' | 'center' | 'right'\n color?: string\n fontFamily?: string\n fontWeight: number\n italic?: boolean\n letterSpacing?: number\n placement?: Placement\n}\n\n/** The `wave` preset: a gentle decaying sine ripple across glyphs. Placement\n * matches TextAnimator (one kerning-accurate `glyphLayout` call, absolute\n * left-to-right about the canvas center) so only the motion differs. */\nfunction KineticWave({\n text,\n fontSize: fontSizeProp,\n fit,\n maxWidth,\n stagger: staggerIn,\n durationInFrames: durationIn,\n delay: delayIn,\n fitToClip,\n maxSettle,\n hold,\n align,\n color: colorProp,\n fontFamily: fontFamilyProp,\n fontWeight,\n italic = false,\n letterSpacing,\n placement,\n}: KineticWaveProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n useTextMetricsReady()\n const measureOpts = { fontFamily, fontWeight }\n\n // Opt-in auto-fit (same contract as TextAnimator).\n const fontSize = useFittedFontSize(text, fontSizeProp, { ...measureOpts, fit, maxWidth })\n\n // Kerning-accurate resting positions via the SHARED glyph-line primitive\n // (matches TextAnimator exactly — one layout path for the whole family).\n const laid = layoutGlyphLine(text, fontSize, measureOpts)\n const placed = laid.rendered\n const lineWidth = laid.width\n\n // Timing: parse + clip-fit (same contract as TextAnimator).\n const staggerBase = framesOf(staggerIn, fps, STAGGER)\n const durationBase = framesOf(durationIn, fps, DURATION.base)\n const delayBase = framesOf(delayIn, fps)\n const naturalSettle = staggeredSettle(placed.length, staggerBase, durationBase, delayBase)\n const timeScale = useTimeScale(naturalSettle, { fitToClip, maxSettle, hold })\n const stagger = staggerBase * timeScale\n const durationInFrames = Math.max(1, durationBase * timeScale)\n const delay = delayBase * timeScale\n\n // Shared placement contract (matches TextAnimator's anchoring exactly).\n const resolved = usePlacement(placement, { width: lineWidth, height: fontSize * LINE_RATIO })\n const anchorX = Math.round(resolved.x)\n const startX = lineStartX(align, anchorX, lineWidth)\n const baseY = lineTopY(resolved.y, fontSize)\n\n return (\n <Group>\n {placed.map(({ ch, x, renderIndex: i }) => {\n const progress = spring({\n frame: Math.max(0, frame - delay - staggerFrames(i, stagger)),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames,\n })\n const opacity = interpolate(progress, [0, 1], [0, 1], CLAMP)\n // A gentle sine offset that fades out as the glyph settles, with the\n // ripple phase keyed to the glyph index so the wave travels the line.\n const ripple = Math.sin(progress * Math.PI + i * 0.6)\n const dy = ripple * WAVE_AMPLITUDE * (1 - progress)\n\n return (\n <Text\n key={`${i}-${ch}`}\n x={startX + x}\n y={baseY + dy}\n opacity={opacity}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {ch}\n </Text>\n )\n })}\n </Group>\n )\n}\n","//! LineChart — a polyline that draws on left-to-right on the house easing, with\n//! an optional soft area fill under it and per-point dots that pop as the line\n//! reaches them. Ported from ondajs (`line-chart`).\n//!\n//! Draw-on approximation: the engine has no stroke-dash animation, so the FULL\n//! polyline `<Path>` is built once and revealed by a growing clip rect —\n//! `clip={clipRect(chartWidth * progress, chartHeight)}` on a `<Group>` whose\n//! origin sits at the chart's top-left. The clip window opens left→right, so the\n//! line appears to draw on. This is geometrically a left-edge wipe, not a true\n//! pen stroke (a near-vertical segment reveals along a vertical seam rather than\n//! following the path's arc-length), but at chart proportions reads as a draw-on.\n//! The engine `<Path>` also has no linecap/linejoin controls, so ondajs's round\n//! caps/joins become the renderer default (miter) joins — a minor fidelity gap.\n//!\n//! The area fill fades in by opacity over the same progress (matching ondajs),\n//! rather than being clipped — so it can read slightly ahead of the line tip on\n//! the way in; this mirrors the original.\n//!\n//! Layout: the chart has FIXED dimensions and is centered by computing its\n//! top-left offset from the composition size inside a single static `<Group>` —\n//! NOT a `<Flex>`/`<AbsoluteFill>`. The clip window and dot opacities animate\n//! every frame; a layout container would be asked to re-measure an animated\n//! subtree, so we position absolutely instead (same rationale as `BarChart`).\n//!\n//! Backend caveats:\n//! - `<Path>` (line + area) renders only on the Vello/GPU backend; the CPU\n//! reference rasterizer skips paths, so the line/area are GPU-only. Dots are\n//! `<Ellipse>` and render on both.\n//! - The area gradient renders only on Vello; the CPU backend collapses it to\n//! the first stop, so the first stop is the meaningful (faint accent) color.\n\nimport {\n Ellipse,\n Group,\n Path,\n clipRect,\n interpolate,\n linearGradient,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useSceneProgress } from '../hooks.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface LineChartProps {\n /** The series values, left to right. */\n data?: number[]\n /** Frames before the line starts drawing. */\n delay?: TimeInput\n /** Frames for the line to fully draw on. */\n duration?: TimeInput\n /** Line + dot color — the earned accent (default: theme `accent`). */\n color?: string\n /** Stroke width in px. */\n strokeWidth?: number\n /** Chart width in px. */\n width?: number\n /** Chart height in px. */\n height?: number\n /** Fill a soft gradient area under the line. */\n fill?: boolean\n /** Show a dot at each data point as the line reaches it. */\n showDots?: boolean\n}\n\nconst DEFAULT_DATA = [12, 18, 15, 24, 22, 31, 28, 38]\n\n/** Append/replace a 2-hex alpha channel on a `#rrggbb`/`#rrggbbaa` color so the\n * area gradient fades from a faint tint to fully transparent. Falls back to the\n * input unchanged for unknown formats. */\nfunction withAlpha(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(255, Math.round(alpha * 255)))\n const hh = a.toString(16).padStart(2, '0')\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}${hh}`\n }\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}${hh}`\n }\n }\n return color\n}\n\nexport function LineChart({\n data = DEFAULT_DATA,\n delay = 0,\n duration = 40,\n color: colorProp,\n strokeWidth = 4,\n width = 900,\n height = 440,\n fill = true,\n showDots = true,\n}: LineChartProps) {\n const { width: compWidth, height: compHeight } = useVideoConfig()\n\n // House easing (non-physical reveal), matching ondajs `useSceneProgress`.\n const progress = useSceneProgress({ delay, durationInFrames: duration, eased: true })\n\n const theme = useTheme()\n const color = colorProp ?? theme.accent\n\n const n = data.length\n // Symmetric horizontal inset: the first point sits at `padLeft` and the last\n // at `width - padRight`, with padRight === padLeft so the polyline's terminal\n // point and the area fill keep equal breathing room from BOTH chart edges\n // (without it, the rising last point and the fill's vertical right wall jam\n // hard against x=width while the left stays inset — an asymmetric crop).\n const padLeft = 48\n const padRight = 48\n const padTop = 24\n const padBottom = 32\n const innerW = width - padLeft - padRight\n const innerH = height - padTop - padBottom\n\n // Defensive min/max: an empty series would make spread Math.min/max return\n // ±Infinity, so seed the reduce and guard the degenerate (flat) range below.\n const min = data.reduce((m, v) => (v < m ? v : m), Number.POSITIVE_INFINITY)\n const max = data.reduce((m, v) => (v > m ? v : m), Number.NEGATIVE_INFINITY)\n\n const xAt = (i: number) => padLeft + (n <= 1 ? 0 : (i / (n - 1)) * innerW)\n const yAt = (v: number) =>\n padTop + (max === min ? innerH / 2 : (1 - (v - min) / (max - min)) * innerH)\n\n const pts = data.map((v, i) => [xAt(i), yAt(v)] as const)\n const linePath = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p[0]} ${p[1]}`).join(' ')\n\n const baseline = padTop + innerH\n const firstX = xAt(0)\n const lastX = xAt(n - 1)\n const areaPath = `${linePath} L${lastX} ${baseline} L${firstX} ${baseline} Z`\n\n // Center the fixed-size chart by computing its top-left offset directly — no\n // layout container, so the per-frame clip/opacity animation never reflows.\n const originX = Math.round((compWidth - width) / 2)\n const originY = Math.round((compHeight - height) / 2)\n\n // The clip window width grows 0 → full chart width as the line draws on.\n const revealWidth = Math.max(0, width * progress)\n\n // Area fade-in, matching ondajs (opacity over progress).\n const areaOpacity = interpolate(progress, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // Soft vertical fill anchored to the LINE, not the chart box: the opaque stop\n // sits at the highest point the polyline reaches (its min y) and fades to\n // transparent at the baseline. Anchoring at `padTop` instead made the tint a\n // top-of-chart band that read as a detached rectangle — saturated under the\n // peaks, invisible under the valleys; anchoring to the line's extent keeps the\n // wash hugging just under the polyline everywhere. First stop is the\n // meaningful color for the CPU fallback.\n const topY = pts.reduce((m, p) => (p[1] < m ? p[1] : m), baseline)\n const areaGradient = linearGradient(\n [0, topY],\n [0, baseline],\n [\n { offset: 0, color: withAlpha(color, 0.28) },\n { offset: 1, color: withAlpha(color, 0) },\n ],\n )\n\n const dotRadius = strokeWidth + 2\n\n return (\n <Group x={originX} y={originY}>\n {/* Area fill — opacity-faded (no clip), matching ondajs. Path is GPU-only;\n its gradient collapses to the faint accent on the CPU backend. */}\n {fill && n >= 2 && areaOpacity > 0 ? (\n <Group opacity={areaOpacity}>\n <Path d={areaPath} gradient={areaGradient} />\n </Group>\n ) : null}\n\n {/* Line — full polyline, revealed left→right by the growing clip window.\n The clip is in this Group's local space (origin at the chart's\n top-left), so it opens from x=0 rightward. */}\n {n >= 2 && revealWidth > 0 ? (\n <Group clip={clipRect(revealWidth, height)}>\n <Path\n d={linePath}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeCap=\"round\"\n strokeJoin=\"round\"\n />\n </Group>\n ) : null}\n\n {/* Dots — each pops (opacity 0→1) as the draw progress crosses its point's\n normalized position along the series. Ellipse renders on both backends. */}\n {showDots\n ? pts.map((p, i) => {\n const threshold = n <= 1 ? 0 : i / (n - 1)\n const dotOpacity = interpolate(progress, [threshold - 0.02, threshold + 0.02], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n const cx = p[0]\n const cy = p[1]\n return dotOpacity > 0 ? (\n <Ellipse\n key={i}\n x={cx - dotRadius}\n y={cy - dotRadius}\n width={dotRadius * 2}\n height={dotRadius * 2}\n fill={color}\n opacity={dotOpacity}\n />\n ) : null\n })\n : null}\n </Group>\n )\n}\n","//! LogoReveal — a premium reveal for a RASTER (PNG/JPG) logo. The companion to\n//! `DrawOn` / `LogoSting`, which need SVG paths and are useless with a client's\n//! bitmap logo (the 95% case). The logo is drawn `fit=\"contain\"` so it never\n//! crops, CENTERED on the canvas, and animated in on the house spring.\n//!\n//! Three presets:\n//! - `focus` (default) — a soft→sharp FOCUS PULL: the engine's Image `blur` sigma\n//! animates 14→0 while opacity 0→1 and a slight 0.96→1 scale settles. The blur\n//! is a first-class image pass (identical on every backend), so this is the\n//! premium, reliable default.\n//! - `rise` — opacity 0→1 + a small upward translate.\n//! - `scale` — opacity 0→1 + a 0.8→1 scale.\n//!\n//! Scale pivots on the canvas CENTER via the translate-scale-translate pattern\n//! (engine scale pivots on a node's local origin), so the logo grows about its\n//! middle. NO clip — the Image is fit to its own box and the whole reveal is one\n//! unit, sidestepping the renderer's clip-occludes-later-siblings issue.\n\nimport {\n Group,\n Image,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport type LogoRevealPreset = 'focus' | 'rise' | 'scale'\n\nexport interface LogoRevealProps {\n /** Logo image source (resolved at render time by `onda render`). */\n src?: string\n /** Logo box width in px (the image is `fit=\"contain\"` inside it — never cropped). */\n width?: number\n /** Logo box height in px. */\n height?: number\n /** Frames before the reveal starts. */\n delay?: number\n /** Frames over which the reveal completes (the house-spring duration). */\n durationInFrames?: number\n /** Reveal style — `focus` (blur pull, default), `rise`, or `scale`. */\n preset?: LogoRevealPreset\n /** Starting blur sigma (px) for the `focus` pull. Default 14. */\n fromBlur?: number\n}\n\nexport function LogoReveal({\n src = '',\n width = 520,\n height = 260,\n delay = 0,\n durationInFrames = DURATION.slow,\n preset = 'focus',\n fromBlur = 14,\n}: LogoRevealProps) {\n const frame = useCurrentFrame()\n const { fps, width: W, height: H } = useVideoConfig()\n\n // House spring (0→1) — smooth, no overshoot.\n const enter = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames,\n })\n const opacity = interpolate(enter, [0, 1], [0, 1], CLAMP)\n\n // Per-preset motion.\n const scale =\n preset === 'scale'\n ? interpolate(enter, [0, 1], [0.8, 1], CLAMP)\n : preset === 'focus'\n ? interpolate(enter, [0, 1], [0.96, 1], CLAMP)\n : 1\n const riseY = preset === 'rise' ? interpolate(enter, [0, 1], [24, 0], CLAMP) : 0\n const blur = preset === 'focus' ? interpolate(enter, [0, 1], [fromBlur, 0], CLAMP) : 0\n\n // Center the logo box on the canvas; scale pivots about the center.\n const cx = W / 2\n const cy = H / 2\n const boxX = Math.round(cx - width / 2)\n const boxY = Math.round(cy - height / 2)\n\n return (\n <Group x={cx} y={cy + riseY} opacity={opacity}>\n <Group scaleX={scale} scaleY={scale}>\n <Group x={-cx} y={-cy}>\n <Image\n src={src}\n x={boxX}\n y={boxY}\n width={width}\n height={height}\n fit=\"contain\"\n blur={blur}\n />\n </Group>\n </Group>\n </Group>\n )\n}\n","//! Estimate the arc length of an SVG path `d` string, in its own coordinate\n//! space. This is just enough to drive a stroke-dash draw-on: the dash period\n//! must match the path length so the \"pen\" reaches the end exactly as the reveal\n//! progress hits 1 (a `[len, len]` dash with offset `len·(1−p)` uncovers the\n//! path from 0 to `len` as `p` goes 0→1 — see LogoSting / BoundingBox).\n//!\n//! Curves are flattened to short chords and summed — an approximation (good to\n//! ~1% for typical marks), NOT an exact perimeter. The renderer (kurbo) strokes\n//! the true geometry; this only times the reveal. Unsupported elliptical arcs\n//! (`A`) fall back to a straight chord to the segment endpoint.\n\n/** Curve flattening resolution (chords per cubic/quadratic segment). */\nconst STEPS = 24\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t\n}\n\n/** Point on a quadratic Bézier at parameter `t`. */\nfunction quadAt(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n t: number,\n): [number, number] {\n const ax = lerp(x0, x1, t)\n const ay = lerp(y0, y1, t)\n const bx = lerp(x1, x2, t)\n const by = lerp(y1, y2, t)\n return [lerp(ax, bx, t), lerp(ay, by, t)]\n}\n\n/** Point on a cubic Bézier at parameter `t`. */\nfunction cubicAt(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n x3: number,\n y3: number,\n t: number,\n): [number, number] {\n const [ax, ay] = quadAt(x0, y0, x1, y1, x2, y2, t)\n const [bx, by] = quadAt(x1, y1, x2, y2, x3, y3, t)\n return [lerp(ax, bx, t), lerp(ay, by, t)]\n}\n\n/** Tokenize a path `d` into command letters and numbers (handles exponents,\n * signed/decimal coords, and comma/space separators). */\nfunction tokenize(d: string): string[] {\n return d.match(/[MmLlHhVvCcSsQqTtAaZz]|-?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?/g) ?? []\n}\n\n/**\n * Estimate the total arc length of an SVG path, summing flattened segments.\n * Supports M/L/H/V/C/S/Q/T/Z (absolute + relative); `A` is approximated by its\n * chord. Returns `0` for an empty/degenerate path.\n */\nexport function estimatePathLength(d: string): number {\n const t = tokenize(d)\n let i = 0\n const num = (): number => Number.parseFloat(t[i++] ?? '0') || 0\n const isCmd = (s: string | undefined): boolean =>\n s !== undefined && /^[MmLlHhVvCcSsQqTtAaZz]$/.test(s)\n\n let total = 0\n // current point, subpath start, previous control point, previous command.\n let cx = 0\n let cy = 0\n let sx = 0\n let sy = 0\n let pcx = 0\n let pcy = 0\n let prev = ''\n\n const line = (nx: number, ny: number): void => {\n total += Math.hypot(nx - cx, ny - cy)\n cx = nx\n cy = ny\n }\n const flattenQuad = (x1: number, y1: number, x2: number, y2: number): void => {\n let px = cx\n let py = cy\n for (let s = 1; s <= STEPS; s++) {\n const [qx, qy] = quadAt(cx, cy, x1, y1, x2, y2, s / STEPS)\n total += Math.hypot(qx - px, qy - py)\n px = qx\n py = qy\n }\n cx = px\n cy = py\n }\n const flattenCubic = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n x3: number,\n y3: number,\n ): void => {\n let px = cx\n let py = cy\n for (let s = 1; s <= STEPS; s++) {\n const [qx, qy] = cubicAt(cx, cy, x1, y1, x2, y2, x3, y3, s / STEPS)\n total += Math.hypot(qx - px, qy - py)\n px = qx\n py = qy\n }\n cx = px\n cy = py\n }\n\n while (i < t.length) {\n const tok = t[i]\n let cmd: string\n if (isCmd(tok)) {\n cmd = tok as string\n i++\n } else {\n // Implicit repeat of the previous command (e.g. polyline after one `L`);\n // an implicit `M` repeat becomes `L` per the SVG spec.\n cmd = prev === 'M' ? 'L' : prev === 'm' ? 'l' : prev\n }\n if (cmd === '') return total // no command context yet — bail safely\n const rel = cmd === cmd.toLowerCase()\n const ox = rel ? cx : 0\n const oy = rel ? cy : 0\n\n switch (cmd.toUpperCase()) {\n case 'M': {\n cx = ox + num()\n cy = oy + num()\n sx = cx\n sy = cy\n break\n }\n case 'L': {\n line(ox + num(), oy + num())\n break\n }\n case 'H': {\n line(ox + num(), cy)\n break\n }\n case 'V': {\n line(cx, oy + num())\n break\n }\n case 'C': {\n const x1 = ox + num()\n const y1 = oy + num()\n const x2 = ox + num()\n const y2 = oy + num()\n const x = ox + num()\n const y = oy + num()\n flattenCubic(x1, y1, x2, y2, x, y)\n pcx = x2\n pcy = y2\n break\n }\n case 'S': {\n // Smooth cubic: first control is the reflection of the previous one.\n const smooth = prev.toUpperCase() === 'C' || prev.toUpperCase() === 'S'\n const x1 = smooth ? 2 * cx - pcx : cx\n const y1 = smooth ? 2 * cy - pcy : cy\n const x2 = ox + num()\n const y2 = oy + num()\n const x = ox + num()\n const y = oy + num()\n flattenCubic(x1, y1, x2, y2, x, y)\n pcx = x2\n pcy = y2\n break\n }\n case 'Q': {\n const x1 = ox + num()\n const y1 = oy + num()\n const x = ox + num()\n const y = oy + num()\n flattenQuad(x1, y1, x, y)\n pcx = x1\n pcy = y1\n break\n }\n case 'T': {\n // Smooth quad: control is the reflection of the previous one.\n const smooth = prev.toUpperCase() === 'Q' || prev.toUpperCase() === 'T'\n const x1 = smooth ? 2 * cx - pcx : cx\n const y1 = smooth ? 2 * cy - pcy : cy\n const x = ox + num()\n const y = oy + num()\n flattenQuad(x1, y1, x, y)\n pcx = x1\n pcy = y1\n break\n }\n case 'A': {\n // Elliptical arc — approximate by its chord (rare in logo marks). Skip\n // the rx/ry/rotation/flags, take the endpoint.\n num() // rx\n num() // ry\n num() // x-axis-rotation\n num() // large-arc-flag\n num() // sweep-flag\n line(ox + num(), oy + num())\n break\n }\n case 'Z': {\n total += Math.hypot(sx - cx, sy - cy)\n cx = sx\n cy = sy\n break\n }\n default:\n // Unknown token — bail to avoid an infinite loop.\n return total\n }\n prev = cmd\n }\n\n return total\n}\n","//! ScaleIn — opacity + scale from `from` → 1 on the house spring. Restrained by\n//! design (default 0.9).\n//!\n//! Scale pivots on the transform origin, set here to the composition center\n//! (matching ondajs's CSS `transform-origin: center` for centered content), so a\n//! centered element grows in place instead of drifting toward its top-left.\n\nimport { Group, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { entryScale } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface ScaleInProps {\n delay?: TimeInput\n durationInFrames?: TimeInput\n /** Starting scale (default 0.9; below ~0.85 reads as dramatic zoom). */\n from?: number\n children?: ReactNode\n}\n\nexport function ScaleIn({\n delay = 0,\n durationInFrames = DURATION.base,\n from = 0.9,\n children,\n}: ScaleInProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n const { opacity, scaleX, scaleY } = entryScale({ frame, fps, delay, durationInFrames, from })\n return (\n <Group\n scaleX={scaleX}\n scaleY={scaleY}\n opacity={opacity}\n originX={width / 2}\n originY={height / 2}\n >\n {children}\n </Group>\n )\n}\n","//! Underline — text fades in, then a rounded accent rule draws beneath it,\n//! its width growing 0 → full on the house spring. Two-phase reveal: text\n//! first, accent second (offset by `lineDelay`). One of the catalog's rare\n//! earned-color moments — reserved for emphasis. Ported from ondajs.\n//!\n//! Layout: ondajs renders a `position: relative` inline-block and sizes the\n//! rule as a `%` of the DOM-measured text width. `@onda-engine/react` has no\n//! author-time text metrics, so the assembly is hand-laid inside a centered\n//! `<Group>` (the ProgressBar pattern): the rule is positioned ABSOLUTELY at an\n//! explicit `y` below the text and its width animates every frame. An animated\n//! width inside a `<Flex>` would reflow/jiggle, so we avoid layout entirely for\n//! the rule. The full rule width is MEASURED from the shaped text via\n//! `useTextMetrics` (the engine's real metrics; estimate fallback until warm).\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryFade } from '../choreography.js'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface UnderlineProps extends TextStyleProps {\n /** Text to reveal. Pass `\"\"` to draw the rule alone. */\n text?: string\n /** Frames before the text starts revealing. */\n delay?: TimeInput\n /** Text reveal duration in frames (default `DURATION.base` = 18). */\n duration?: TimeInput\n /** Frames to wait after the text lands before the rule starts drawing. */\n lineDelay?: TimeInput\n /** Rule draw duration. Fast on purpose — emphatic (default `DURATION.fast`). */\n lineDuration?: TimeInput\n /** Rule color (default: theme `accent`). */\n accentColor?: string\n /** Rule thickness in px. */\n lineThickness?: number\n /** Pixel gap between the text box and the rule. */\n lineOffset?: number\n /** Text size in px (default 64). */\n fontSize?: number\n /** Horizontal alignment of the rule under the text. */\n align?: 'left' | 'center' | 'right'\n}\n\n/** Engine line-box height as a multiple of font size (matches the typography\n * crate; the same ratio `Highlight` uses to place its accent below the text). */\nconst LINE_RATIO = 1.2\n\nexport function Underline({\n text: textProp = 'underline this',\n delay: delayIn = 0,\n duration: durationIn = DURATION.base,\n lineDelay: lineDelayIn = 8,\n lineDuration: lineDurationIn = DURATION.fast,\n color: colorProp,\n accentColor: accentColorProp,\n lineThickness = 3,\n lineOffset = 6,\n fontSize = 64,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n align = 'left',\n}: UnderlineProps) {\n const text = applyTextCase(textProp, { uppercase })\n const frame = useCurrentFrame()\n const { fps, width: canvasWidth, height: canvasHeight } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const lineDelay = framesOf(lineDelayIn, fps)\n const lineDuration = framesOf(lineDurationIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const accentColor = accentColorProp ?? theme.accent\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Real shaped text width — the engine measures it (proportional, exact),\n // falling back to a glyph-count estimate until the wasm engine warms.\n const measured = useTextMetrics(text, fontSize, { fontFamily, fontWeight })\n\n // Phase 1: text fade — opacity 0 → 1 on the house spring (the `entryFade`\n // choreography, matching the ondajs original).\n const { opacity } = entryFade({ frame, fps, delay, durationInFrames: duration })\n\n // Phase 2: the rule draws after the text has landed, offset by `lineDelay`.\n const lineProgress = spring({\n frame: Math.max(0, frame - delay - lineDelay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: lineDuration,\n })\n\n // Full rule width = the measured text box width.\n const fullWidth = measured.width\n\n const lineWidth = interpolate(lineProgress, [0, 1], [0, fullWidth], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // The rule sits just below the text's line box (`fontSize * LINE_RATIO` tall,\n // the engine's line height) plus the gap — matching ondajs's `bottom` offset\n // relative to the text box, not the glyph baseline.\n const lineY = fontSize * LINE_RATIO + lineOffset\n // A full-pill radius on a thin sliver would bulge; cap at half its own size.\n const lineRadius = Math.min(lineThickness / 2, lineWidth / 2)\n // align: the rule grows from its left origin; shift it so it tracks the\n // chosen edge of the (measured) text box.\n const lineX =\n align === 'center' ? (fullWidth - lineWidth) / 2 : align === 'right' ? fullWidth - lineWidth : 0\n\n // Center the whole assembly. The rule's width animates every frame, so a\n // layout container would reflow/jiggle (ProgressBar pattern) — instead we\n // compute a static centered origin from the composition size and the block's\n // MEASURED extent: `fullWidth` wide; from the text's top to the rule's\n // bottom tall (`lineY + lineThickness`).\n const blockHeight = lineY + lineThickness\n const originX = (canvasWidth - fullWidth) / 2\n const originY = (canvasHeight - blockHeight) / 2\n\n return (\n <Group x={originX} y={originY}>\n <Text\n opacity={opacity}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {text}\n </Text>\n {lineWidth > 0 ? (\n <Rect\n x={lineX}\n y={lineY}\n width={lineWidth}\n height={lineThickness}\n cornerRadius={lineRadius}\n fill={accentColor}\n />\n ) : null}\n </Group>\n )\n}\n","//! LogoSting — a silent, restrained branded reveal: a logo mark wipes in, a title\n//! settles beneath it, and a single accent rule lands last. Ported from ondajs.\n//!\n//! Composition order (one earned beat per element, no overlap-noise):\n//! 1. Mark — the logo `<Path>` is revealed left→right by a clip-wipe.\n//! 2. Title — `ScaleIn` settles the wordmark in beneath the mark.\n//! 3. Underline — the accent rule draws last (only when `accent` is true).\n//! All three run on the house spring (`SPRING_SMOOTH`): no overshoot, no bounce —\n//! the mark lands and stays. Restraint IS the brand.\n//!\n//! ── Mark draw-on (faithful to ondajs) ───────────────────────────────────────\n//! ondajs's mark is a `DrawOn` primitive that strokes the path in via SVG\n//! `stroke-dasharray`/`stroke-dashoffset` (`@remotion/paths` `evolvePath`). The\n//! engine has the same primitive now: the mark `<Path>` carries a dash as long\n//! as the whole path with an offset that retreats to 0 on the house spring, so\n//! the stroke is literally drawn on from start to end like a pen. The dash\n//! period is the path's arc length, estimated from `d` (see `path-length.ts`) so\n//! the pen reaches the end exactly as the reveal completes. The `<Path>` renders\n//! only on the Vello/GPU backend (the CPU reference rasterizer skips paths), so\n//! the mark is GPU-only.\n//!\n//! ── Layout / pivots ─────────────────────────────────────────────────────────\n//! This is a self-positioning composite. Because the mark needs an animated clip\n//! WIDTH and the pieces must stack pixel-exactly, it does not use `<Flex>` (an\n//! animated clip/measure would reflow it); instead it centers everything on the\n//! canvas via `useVideoConfig()` width/height — the Spotlight/Marquee pattern.\n//! The title's `ScaleIn` group is anchored at the title's CENTER so the 0.9→1\n//! scale grows about the center (scene scale pivots on the local origin, so the\n//! glyphs are drawn offset by -halfWidth). Title/rule widths are ESTIMATED from\n//! glyph count × font size (no author-time text metrics) — see Underline.\n\nimport { Group, Path, Text, spring, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { estimatePathLength } from '../path-length.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { ScaleIn } from './ScaleIn.js'\nimport { Underline } from './Underline.js'\n\n/** Mean glyph advance as a fraction of font size — the same rough display-sans\n * heuristic `Underline` uses, so the centered title and its accent rule (which\n * `Underline` sizes with the same factor) stay aligned. */\nconst CHAR_WIDTH_FACTOR = 0.52\n/** Engine line-box height as a multiple of font size (matches the typography\n * crate; `Underline`/`Highlight` use the same ratio to place the accent). */\nconst LINE_RATIO = 1.2\n/** Pixel gap between the mark and the title (ondajs uses a 32px flex gap). */\nconst STACK_GAP = 32\n\n/** Choreography offsets — frames *after* the block's own `delay`. The title\n * begins before the mark is fully home so the two reveals feel linked; the\n * underline lands last so the eye reads mark → word → accent. (Verbatim from\n * ondajs.) */\nconst TITLE_OFFSET = 18\nconst UNDERLINE_OFFSET = 34\n\nexport interface LogoStingProps extends TextStyleProps {\n /** SVG path `d` for the logo mark, in `viewBox` coordinate space. */\n d?: string\n /** The brand / product title beneath the mark. */\n title?: string\n /** Frames before the sting starts. */\n delay?: TimeInput\n /** Draw the accent rule beneath the title (the single earned-color moment). */\n accent?: boolean\n /** SVG viewBox `\"minX minY width height\"` — must match the space of `d`. */\n viewBox?: string\n /** Rendered width of the mark in px. */\n pathWidth?: number\n /** Rendered height of the mark in px. */\n pathHeight?: number\n /** Stroke width, in px (after the viewBox→pixel scale; see note below). */\n strokeWidth?: number\n /** Logo stroke color (default: theme `text`). */\n stroke?: string\n /** Underline accent color — the signature dusty rose (default: theme `accent`). */\n accentColor?: string\n /** Title font size in px. */\n titleFontSize?: number\n}\n\n/** Parse an SVG `viewBox` string into `[minX, minY, width, height]`, defensively\n * — falls back to a unit box on malformed input so the mark never NaNs out. */\nfunction parseViewBox(vb: string): [number, number, number, number] {\n const parts = vb\n .trim()\n .split(/[\\s,]+/)\n .map((n) => Number.parseFloat(n))\n const minX = parts[0] ?? 0\n const minY = parts[1] ?? 0\n const w = parts[2] ?? 1\n const h = parts[3] ?? 1\n return [\n Number.isFinite(minX) ? minX : 0,\n Number.isFinite(minY) ? minY : 0,\n Number.isFinite(w) && w > 0 ? w : 1,\n Number.isFinite(h) && h > 0 ? h : 1,\n ]\n}\n\nexport function LogoSting({\n d = 'M 50 60 Q 100 20 150 60 T 250 60',\n title = 'Onda',\n delay: delayIn = 0,\n accent = true,\n viewBox = '0 0 300 120',\n pathWidth = 400,\n pathHeight = 160,\n strokeWidth = 3,\n stroke: strokeProp,\n accentColor: accentColorProp,\n titleFontSize = 96,\n color: colorProp,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n}: LogoStingProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const stroke = strokeProp ?? theme.text\n const accentColor = accentColorProp ?? theme.accent\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n\n // ── Mark reveal: ondajs's stroke draw-on via an animated dash. ─────────────\n // Progress 0→1 on the house spring over DURATION.slow (24f), the DrawOn default.\n const markProgress = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.slow,\n })\n // Dash period = the path's arc length (in viewBox units, the Path's local\n // space — strokeWidth is given there too). One dash + one gap, each as long as\n // the whole path; the offset retreats len→0 so the stroke uncovers from start\n // to end as progress → 1 (the BoundingBox draw-on, applied to a Path).\n const markLength = Math.max(1, estimatePathLength(d))\n const dashOffset = markLength * (1 - Math.max(0, Math.min(1, markProgress)))\n\n // viewBox → pixel scale for the path. The path `d` is authored in viewBox\n // units; map it onto pathWidth × pathHeight. (Non-uniform scale is fine for a\n // mark; strokeWidth is given in *post-scale* px and applied on the Path\n // directly, so it stays a consistent visual weight regardless of the scale.)\n const [vbMinX, vbMinY, vbW, vbH] = parseViewBox(viewBox)\n const scaleX = pathWidth / vbW\n const scaleY = pathHeight / vbH\n\n // ── Centered vertical stack geometry. ─────────────────────────────────────\n // Title line-box height + a centered estimate of the title's pixel width.\n const titleLineHeight = titleFontSize * LINE_RATIO\n const titleWidth = title.length * titleFontSize * CHAR_WIDTH_FACTOR\n // The accent rule occupies a sliver below the title's line box; include it in\n // the stack height so the whole composite stays vertically centered.\n const accentBand = accent ? 9 : 0 // ~ lineThickness (3) + small breathing room\n const stackHeight = pathHeight + STACK_GAP + titleLineHeight + accentBand\n const stackTop = (height - stackHeight) / 2\n const centerX = width / 2\n\n // Mark: centered horizontally, sitting at the top of the stack.\n const markX = centerX - pathWidth / 2\n const markY = stackTop\n\n // Title: its top-left origin (the wipe/baseline reference) below the mark.\n const titleTop = stackTop + pathHeight + STACK_GAP\n const titleLeft = centerX - titleWidth / 2\n\n return (\n <Group>\n {/* 1. Mark — the logo arrives, stroked on start→end by an animated dash\n (the ondajs DrawOn; GPU/Vello only — the CPU reference skips paths). */}\n <Group x={markX} y={markY}>\n <Group scaleX={scaleX} scaleY={scaleY} x={-vbMinX * scaleX} y={-vbMinY * scaleY}>\n {/* fill none ('#00000000') so only the stroke reads, like ondajs. The\n dash period is the path length; the offset retreats to 0 as the pen\n draws. Round caps/joins keep the moving pen-tip clean.\n Gate on progress > 0 (like BoundingBox): at exactly 0 the whole path\n sits in the dash gap, but the end-point lands on a dash boundary and\n the round cap would render a stray zero-length dot at the path END\n (the right side). Not drawing until the pen has actually started\n avoids that artifact and keeps frame 0 clean. */}\n {markProgress > 0.001 ? (\n <Path\n d={d}\n fill=\"#00000000\"\n stroke={stroke}\n strokeWidth={strokeWidth / scaleX}\n strokeCap=\"round\"\n strokeJoin=\"round\"\n strokeDash={[markLength, markLength]}\n strokeDashOffset={dashOffset}\n />\n ) : null}\n </Group>\n </Group>\n\n {/* 2. Title — settles in beneath the mark. The ScaleIn group is anchored at\n the title CENTER so the 0.9→1 scale grows about the center (scene scale\n pivots on the local origin), and the glyphs are drawn at -halfWidth. */}\n <Group x={centerX} y={titleTop}>\n <ScaleIn delay={delay + TITLE_OFFSET} durationInFrames={DURATION.base} from={0.9}>\n <Text\n x={-titleWidth / 2}\n fontSize={titleFontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {applyTextCase(title, { uppercase })}\n </Text>\n </ScaleIn>\n </Group>\n\n {/* 3. Accent rule — earned, single, last. Only when `accent` is true. We\n hand `Underline` the title (so the rule width tracks the wordmark) with\n a fully-transparent text color so the title glyphs DON'T double-render —\n only the rule reads (the engine analogue of ondajs's empty string). The\n rule is centered under the title; `Underline` places it below the line\n box, so we anchor this group at the title's top-left. */}\n {accent ? (\n <Group x={titleLeft} y={titleTop}>\n <Underline\n text={title}\n delay={delay + UNDERLINE_OFFSET}\n duration={1}\n lineDelay={0}\n lineDuration={DURATION.fast}\n color=\"#00000000\"\n accentColor={accentColor}\n fontSize={titleFontSize}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n lineThickness={3}\n lineOffset={0}\n align=\"center\"\n />\n </Group>\n ) : null}\n </Group>\n )\n}\n","//! LookbookShot — a single product presented like a page in a printed lookbook,\n//! NOT a full-bleed photo with a corner caption (which reads as a slide). The\n//! piece sits in a soft-shadowed mat (a framed print) inside the brand's space,\n//! with the name set in the DISPLAY face and real negative space beside it. Three\n//! layouts — `spread-right` / `spread-left` (asymmetric editorial: type one side,\n//! framed product the other) and `centered` (a gallery print with the label\n//! below). Alternating spread sides across successive shots gives a film the\n//! rhythm of turning lookbook pages.\n//!\n//! Motion: the card fades + settles in, then breathes on a slow linear scale\n//! (life without a Ken-Burns overscan — the photo is `fit=\"cover\"` to its exact\n//! box, so the card scales as ONE unit and never needs a clip, sidestepping the\n//! clip-occludes-later-siblings issue). The label lines stagger in after.\n//!\n//! Type: the name follows the theme DISPLAY face (`headingFamily ?? fontFamily`);\n//! the eyebrow + detail are the body face — the same two-font system as the rest\n//! of the library.\n\nimport {\n Group,\n Image,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useStaggeredEntrance } from '../hooks.js'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport type LookbookLayout = 'spread-right' | 'spread-left' | 'centered'\n\nexport interface LookbookShotProps extends TextStyleProps {\n /** Product photo source (resolved at render time by `onda render`). */\n src?: string\n /** Product name — the headline, set in the display face. */\n name?: string\n /** Small letterspaced eyebrow above the name (category), in the body face. */\n eyebrow?: string\n /** Quiet supporting line under the name (material / method), in the body face. */\n detail?: string\n /** Page composition (default `spread-right`). Alternate sides across shots. */\n layout?: LookbookLayout\n /** Frames before the card enters. */\n delay?: number\n /** Name font size in px (default 86 for spreads, auto-reduced for `centered`). */\n nameFontSize?: number\n /** The mat/frame color (the print border). Default a near-white off the bg. */\n matColor?: string\n /** Soft shadow color under the mat. Default a low-alpha warm dark. */\n shadowColor?: string\n /** Eyebrow + rule color (default: theme `accent`). */\n accentColor?: string\n /** Detail line color (default: theme `textMuted`). */\n detailColor?: string\n /** Body font for eyebrow + detail (default: theme `fontFamily`). */\n bodyFamily?: string\n /** Frames over which the card's slow \"breath\" scale completes (default 150). */\n lifeDurationInFrames?: number\n}\n\n/** Greedy word-wrap into lines that each fit `maxWidth` at the font size (the\n * engine measures at render, but a pure frame→scene function can't read that\n * back, so this estimate stands in — the display face is narrow, factor ~0.46). */\nfunction wrap(text: string, maxWidth: number, fontSize: number): string[] {\n const words = text.split(/\\s+/).filter((w) => w.length > 0)\n if (words.length === 0) return []\n const maxChars = Math.max(1, Math.floor(maxWidth / (fontSize * 0.46)))\n const lines: string[] = []\n let cur = ''\n for (const w of words) {\n const cand = cur.length === 0 ? w : `${cur} ${w}`\n if (cand.length <= maxChars || cur.length === 0) cur = cand\n else {\n lines.push(cur)\n cur = w\n }\n }\n if (cur.length > 0) lines.push(cur)\n return lines\n}\n\nexport function LookbookShot({\n src = '',\n name = 'Product',\n eyebrow = '',\n detail = '',\n layout = 'spread-right',\n delay = 0,\n nameFontSize,\n matColor,\n shadowColor = '#2b201824',\n color: colorProp,\n accentColor: accentColorProp,\n detailColor: detailColorProp,\n fontFamily: fontFamilyProp,\n bodyFamily: bodyFamilyProp,\n letterSpacing,\n uppercase,\n lifeDurationInFrames = 150,\n}: LookbookShotProps) {\n const frame = useCurrentFrame()\n const { width: W, height: H, fps } = useVideoConfig()\n const theme = useTheme()\n\n const color = colorProp ?? theme.text\n const accent = accentColorProp ?? theme.accent\n const detailColor = detailColorProp ?? theme.textMuted\n const nameFont = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n const bodyFont = bodyFamilyProp ?? theme.fontFamily\n const mat = matColor ?? '#fbf9f4'\n\n const centered = layout === 'centered'\n const margin = Math.round(W * 0.075)\n const pad = 18\n\n // ── Mat (framed print) geometry ──────────────────────────────────────────\n // Portrait canvases (9:16 / 4:5): size the centered print off HEIGHT and seat it\n // a touch above center — a width-based mat is tiny and stuck at the top in\n // portrait, leaving the lower frame empty. Landscape math is unchanged\n // (matW = matH * 0.806 ≡ the old W*0.32 with matH = W*0.32*1.24).\n const portrait = centered && H > W\n const matH = centered ? Math.round(portrait ? H * 0.44 : W * 0.32 * 1.24) : Math.round(H * 0.9)\n const matW = centered ? Math.round(matH * 0.806) : Math.round(matH * 0.76)\n const matX = centered\n ? Math.round((W - matW) / 2)\n : layout === 'spread-right'\n ? W - matW - margin\n : margin\n const matY = centered ? Math.round(portrait ? H * 0.17 : H * 0.075) : Math.round((H - matH) / 2)\n\n // ── Card motion: entrance settle + a slow \"breath\" scale (one unit, no clip).\n const enter = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n const enterOpacity = interpolate(enter, [0, 1], [0, 1], CLAMP)\n const enterY = interpolate(enter, [0, 1], [20, 0], CLAMP)\n const life = interpolate(frame - delay, [0, lifeDurationInFrames], [1, 1.03], CLAMP)\n const cardScale = interpolate(enter, [0, 1], [0.985, 1], CLAMP) * life\n const cx = matX + matW / 2\n const cy = matY + matH / 2\n\n // ── Label block ──────────────────────────────────────────────────────────\n const baseName = nameFontSize ?? (centered ? 58 : 86)\n const eyebrowSize = centered ? 20 : 22\n const detailSize = centered ? 22 : 24\n\n const at = useStaggeredEntrance({ type: 'rise', delay: delay + 8, increment: 5 })\n\n // The headline name with the shared text-case applied (so measurement,\n // wrapping, and rendering all agree on the same string).\n const displayName = applyTextCase(name, { uppercase })\n\n // Centering needs measured widths (the LowerThird pattern).\n const nameMetrics = useTextMetrics(displayName, baseName, {\n fontFamily: nameFont,\n fontWeight: 500,\n letterSpacing,\n })\n // Measure WITH the same letter-spacing the eyebrow renders with (4px) — else the\n // shaped width is ~4·(n-1)px too small and the centered eyebrow drifts right.\n const eyebrowMetrics = useTextMetrics(eyebrow, eyebrowSize, {\n fontFamily: bodyFont,\n fontWeight: 600,\n letterSpacing: 4,\n })\n\n if (centered) {\n const labelTop = matY + matH + Math.round(H * 0.05)\n const nameX = Math.round((W - nameMetrics.width) / 2)\n const eyebrowX = Math.round((W - eyebrowMetrics.width) / 2)\n const nm = at(0)\n const eb = at(1)\n return (\n <Group>\n <Group x={cx} y={cy}>\n <Group scaleX={cardScale} scaleY={cardScale}>\n <Group x={-cx} y={-cy} opacity={enterOpacity}>\n <Rect\n x={matX}\n y={matY}\n width={matW}\n height={matH}\n cornerRadius={2}\n fill={mat}\n shadow={{ color: shadowColor, blur: 50, offsetX: 0, offsetY: 22 }}\n />\n <Image\n src={src}\n x={matX + pad}\n y={matY + pad}\n width={matW - pad * 2}\n height={matH - pad * 2}\n fit=\"cover\"\n />\n </Group>\n </Group>\n </Group>\n <Group y={nm.y} opacity={nm.opacity}>\n <Text\n x={nameX}\n y={labelTop}\n fontSize={baseName}\n color={color}\n fontFamily={nameFont}\n fontWeight={500}\n letterSpacing={letterSpacing}\n >\n {displayName}\n </Text>\n </Group>\n {eyebrow ? (\n <Group y={eb.y} opacity={eb.opacity}>\n <Text\n x={eyebrowX}\n y={labelTop + Math.round(baseName * 1.25)}\n fontSize={eyebrowSize}\n color={accent}\n fontFamily={bodyFont}\n fontWeight={600}\n letterSpacing={4}\n >\n {eyebrow}\n </Text>\n </Group>\n ) : null}\n </Group>\n )\n }\n\n // ── Spread (asymmetric): type column on the side opposite the card. ────────\n const typeX = layout === 'spread-right' ? margin : matX + matW + Math.round(W * 0.03)\n const typeColW =\n layout === 'spread-right' ? matX - margin - Math.round(W * 0.03) : W - typeX - margin\n const nameLines = wrap(displayName, typeColW, baseName)\n const nameLineH = Math.round(baseName * 1.12)\n const eyebrowH = eyebrow ? Math.round(eyebrowSize * 1.6) : 0\n const ruleGap = 30\n const detailGap = 26\n const blockH =\n eyebrowH + nameLines.length * nameLineH + (detail ? ruleGap + 2 + detailGap + detailSize : 0)\n const startY = Math.round((H - blockH) / 2)\n\n const eb = at(0)\n return (\n <Group>\n {/* Framed product */}\n <Group x={cx} y={cy}>\n <Group scaleX={cardScale} scaleY={cardScale}>\n <Group x={-cx} y={-cy} opacity={enterOpacity}>\n <Rect\n x={matX}\n y={matY}\n width={matW}\n height={matH}\n cornerRadius={2}\n fill={mat}\n shadow={{ color: shadowColor, blur: 50, offsetX: 0, offsetY: 22 }}\n />\n <Image\n src={src}\n x={matX + pad}\n y={matY + pad}\n width={matW - pad * 2}\n height={matH - pad * 2}\n fit=\"cover\"\n />\n </Group>\n </Group>\n </Group>\n {/* Type column */}\n <Group y={enterY}>\n {eyebrow ? (\n <Group y={eb.y} opacity={eb.opacity}>\n <Text\n x={typeX}\n y={startY}\n fontSize={eyebrowSize}\n color={accent}\n fontFamily={bodyFont}\n fontWeight={600}\n letterSpacing={4}\n >\n {eyebrow}\n </Text>\n </Group>\n ) : null}\n {nameLines.map((line, i) => {\n const ln = at(1 + i)\n return (\n <Group key={`${i}-${line}`} y={ln.y} opacity={ln.opacity}>\n <Text\n x={typeX}\n y={startY + eyebrowH + i * nameLineH}\n fontSize={baseName}\n color={color}\n fontFamily={nameFont}\n fontWeight={500}\n letterSpacing={letterSpacing}\n >\n {line}\n </Text>\n </Group>\n )\n })}\n {detail\n ? (() => {\n const dl = at(1 + nameLines.length)\n const ruleY = startY + eyebrowH + nameLines.length * nameLineH + ruleGap\n return (\n <Group y={dl.y} opacity={dl.opacity}>\n <Rect x={typeX + 2} y={ruleY} width={70} height={2} fill={accent} />\n <Text\n x={typeX}\n y={ruleY + detailGap}\n fontSize={detailSize}\n color={detailColor}\n fontFamily={bodyFont}\n fontWeight={400}\n >\n {detail}\n </Text>\n </Group>\n )\n })()\n : null}\n </Group>\n </Group>\n )\n}\n","//! LowerThird — broadcast-style name + role bar that slides + fades into a corner\n//! with a single earned accent rule. Ported from ondajs.\n//!\n//! Choreography (matching ondajs): the name slides in from the bar's side on the\n//! house spring; the role fades in 4 frames later (the canonical stagger); the\n//! accent rule draws last (+8 frames), its width growing 0 → full so the eye\n//! reads name → role → accent.\n//!\n//! Layout: ondajs wraps the assembly in a `PlacementBox` (an `AbsoluteFill` that\n//! parks an absolutely-positioned box at a canvas anchor) and lays the three\n//! parts out in a flex column. Here the assembly is hand-laid as a BARE top-level\n//! `<Group x={originX} y={originY}>` (the `BarChart` pattern) — NOT inside an\n//! `<AbsoluteFill>`/`<Flex>` — for two reasons: (a) the engine layout pass would\n//! OVERWRITE the group's x/y (clobbering the corner anchor), and (b) the name\n//! carries a motion TRANSLATE and the accent rule's width animates per-frame,\n//! either of which would make a layout container reflow/jiggle. The origin is\n//! computed directly from the canvas size and `placement`; a left-half placement\n//! slides in from the left and aligns flush-left, a right-half one mirrors.\n//!\n//! Approximations: ondajs sizes the accent rule as a % of the DOM-measured name\n//! width and uses CSS letter-spacing / line-height. The rule width and the line\n//! stack are now sized from REAL shaped text metrics (`useTextMetrics`, which the\n//! engine measures exactly — falling back to a glyph-count estimate until the\n//! wasm engine warms). letter-spacing / line-height props are accepted but not\n//! applied.\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryFade, entrySlide } from '../choreography.js'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Broadcast lower-third placement regions — the corners (or centered edge) a\n * name bar lives in. The `*-center` variants center the block on the canvas\n * mid-line, for a single credit/URL line under a closing card. */\nexport type LowerThirdPlacement =\n | 'bottom-left'\n | 'bottom-right'\n | 'bottom-center'\n | 'top-left'\n | 'top-right'\n | 'top-center'\n\n/** Resolved canvas anchor for a placement: fractional x/y of the anchor point\n * plus which visual side the bar sits on (drives slide direction + alignment).\n * Margins match ondajs's `REGION_MAP` (10% safe inset on each axis); centered\n * variants anchor at x = 0.5 and align each line about the block center. */\nconst PLACEMENT_MAP: Record<\n LowerThirdPlacement,\n { x: number; y: number; side: 'left' | 'right' | 'center'; vertical: 'top' | 'bottom' }\n> = {\n 'bottom-left': { x: 0.1, y: 0.9, side: 'left', vertical: 'bottom' },\n 'bottom-right': { x: 0.9, y: 0.9, side: 'right', vertical: 'bottom' },\n 'bottom-center': { x: 0.5, y: 0.9, side: 'center', vertical: 'bottom' },\n 'top-left': { x: 0.1, y: 0.1, side: 'left', vertical: 'top' },\n 'top-right': { x: 0.9, y: 0.1, side: 'right', vertical: 'top' },\n 'top-center': { x: 0.5, y: 0.1, side: 'center', vertical: 'top' },\n}\n\n/** Engine line-box height as a multiple of font size (matches the typography\n * crate, the same ratio `Underline` uses). */\nconst LINE_RATIO = 1.2\n\n/** Choreography offsets — frames AFTER the name's delay (verbatim ondajs). */\nconst ROLE_OFFSET = 4\nconst UNDERLINE_OFFSET = 8\n\nexport interface LowerThirdProps extends TextStyleProps {\n /** The person's name (the primary line). */\n name?: string\n /** The person's role / title (the secondary line). */\n role?: string\n /** Which canvas corner the bar sits in (default `'bottom-left'`). Drives the\n * slide-in direction and flush alignment. */\n placement?: LowerThirdPlacement\n /** Frames before the name slides in. */\n delay?: TimeInput\n /** Show the accent rule beneath the name (default `true`). */\n accent?: boolean\n /** Role color (default: theme `textMuted`). */\n roleColor?: string\n /** Accent rule color (default: theme `accent`). */\n accentColor?: string\n /** Name font size in px (default 48). */\n fontSize?: number\n /** Name font weight (default 600). */\n nameFontWeight?: number\n /** Role font size in px (default 22). */\n roleFontSize?: number\n /** Role font weight (default 500). */\n roleFontWeight?: number\n /** Accent rule corner radius in px (capped so a thin sliver never bulges) (default: theme `radius`). */\n cornerRadius?: number\n}\n\nexport function LowerThird({\n name = 'Rodrigo',\n role = 'CEO, Onda',\n placement = 'bottom-left',\n delay: delayIn = 0,\n accent = true,\n color: colorProp,\n roleColor: roleColorProp,\n accentColor: accentColorProp,\n fontSize = 48,\n nameFontWeight = 600,\n roleFontSize = 22,\n roleFontWeight = 500,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n cornerRadius: cornerRadiusProp,\n}: LowerThirdProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const roleColor = roleColorProp ?? theme.textMuted\n const accentColor = accentColorProp ?? theme.accent\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n const cornerRadius = cornerRadiusProp ?? theme.radius\n const nameText = applyTextCase(name, { uppercase })\n\n // Real shaped line-box widths (the engine measures them exactly; falls back to\n // a glyph-count estimate until the wasm engine warms). One hook per fixed line.\n const nameMetrics = useTextMetrics(nameText, fontSize, { fontFamily, fontWeight: nameFontWeight })\n const roleMetrics = useTextMetrics(role, roleFontSize, { fontFamily, fontWeight: roleFontWeight })\n\n // A lower-third only lives in a corner; a caller (or the agent) may pass a\n // general placement like `center` — fall back to the house corner rather than\n // crashing on an unmapped key.\n const { x: ax, y: ay, side, vertical } = PLACEMENT_MAP[placement] ?? PLACEMENT_MAP['bottom-left']\n const isLeft = side === 'left'\n const isCenter = side === 'center'\n\n // Name slides in from the bar's side — subtle horizontal travel reinforces\n // which corner the bar belongs to (ondajs: 'left'/'right', distance 16). A\n // centered block has no \"side\", so it just fades up in place (distance 0).\n const slide = entrySlide({\n frame,\n fps,\n delay,\n durationInFrames: DURATION.base,\n direction: isLeft ? 'left' : 'right',\n distance: isCenter ? 0 : 16,\n })\n\n // Role fades in 4 frames after the name lands.\n const roleMotion = entryFade({\n frame,\n fps,\n delay: delay + ROLE_OFFSET,\n durationInFrames: DURATION.base,\n })\n\n // Accent rule draws last (+8 frames), its width growing 0 → full on the house\n // spring (fast — emphatic), matching ondajs's `Underline` second phase\n // (`lineDuration={10}` == DURATION.fast, `lineDelay={0}`).\n const accentProgress = spring({\n frame: Math.max(0, frame - delay - UNDERLINE_OFFSET),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.fast,\n })\n\n // Measured line-box widths (see header). The block width is the wider of the\n // two lines so the assembly anchors as one box.\n const nameWidth = nameMetrics.width\n const roleWidth = roleMetrics.width\n const blockWidth = Math.max(nameWidth, roleWidth)\n\n // Vertical stack: name line box, a 4px gap (ondajs), the role line box, an\n // 8px gap before the accent rule, then a 3px rule (ondajs `lineThickness`).\n const nameLineH = fontSize * LINE_RATIO\n const roleLineH = roleFontSize * LINE_RATIO\n const GAP = 4\n const ACCENT_GAP = 8\n const ACCENT_THICKNESS = 3\n const roleY = nameLineH + GAP\n const accentY = roleY + roleLineH + ACCENT_GAP\n\n // Accent rule grows 0 → the name's width (the name owns the typography above).\n const accentWidth = interpolate(accentProgress, [0, 1], [0, nameWidth], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n // A full-pill radius on a thin sliver would bulge; cap at half its own size.\n const accentRadius = Math.min(cornerRadius, ACCENT_THICKNESS / 2, accentWidth / 2)\n\n // Total assembled height — used to anchor a bottom-placed bar by its baseline.\n const blockHeight = accent ? accentY + ACCENT_THICKNESS : roleY + roleLineH\n\n // Anchor the assembly box at the canvas corner. The box's local origin (0,0)\n // is its top-left; shift so a right-side placement is flush-right (origin\n // moved left by the block width) and a bottom placement sits its baseline at\n // the anchor (origin moved up by the block height). Computed directly from the\n // canvas size — no layout container, so the anchor and the per-frame width\n // growth never trigger a reflow (the BarChart pattern).\n const anchorX = ax * width\n const anchorY = ay * height\n const originX = isCenter ? anchorX - blockWidth / 2 : isLeft ? anchorX : anchorX - blockWidth\n const originY = vertical === 'bottom' ? anchorY - blockHeight : anchorY\n\n // Per-line alignment within the block: left lines start at 0; right lines are\n // pushed flush-right; centered lines are centered about the block's mid-line.\n const lineX = (w: number) => (isCenter ? (blockWidth - w) / 2 : isLeft ? 0 : blockWidth - w)\n const nameX = lineX(nameWidth)\n const roleX = lineX(roleWidth)\n const accentX = lineX(accentWidth)\n\n return (\n <Group x={originX} y={originY}>\n {/* Name — slides + fades in from the bar's side. The inner Group carries\n the motion translate; the outer x positions the line within the\n block (flush-left or flush-right). */}\n <Group x={nameX}>\n <Group x={slide.x} y={slide.y} opacity={slide.opacity}>\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={nameFontWeight}\n letterSpacing={letterSpacing}\n >\n {nameText}\n </Text>\n </Group>\n </Group>\n\n {/* Role — fades in 4 frames after the name. */}\n <Text\n x={roleX}\n y={roleY}\n opacity={roleMotion.opacity}\n fontSize={roleFontSize}\n color={roleColor}\n fontFamily={fontFamily}\n fontWeight={roleFontWeight}\n >\n {role}\n </Text>\n\n {/* Accent rule — draws last, width 0 → full, only when `accent`. */}\n {accent && accentWidth > 0 ? (\n <Rect\n x={accentX}\n y={accentY}\n width={accentWidth}\n height={ACCENT_THICKNESS}\n cornerRadius={accentRadius}\n fill={accentColor}\n />\n ) : null}\n </Group>\n )\n}\n","//! Marquee — a seamless looping horizontal scroll (logo strips, ticker tape,\n//! \"as featured in\" rows). Ported from ondajs.\n//!\n//! Intentionally **linear**: a marquee with spring acceleration feels broken.\n//! Content is laid out absolutely (not via `<Flex>`) and translated each frame,\n//! then the item set is repeated enough times to blanket the viewport from a\n//! one-content-width head start, so the wrap is seamless. An outer `<Group clip>`\n//! masks everything to the viewport, hiding the seam and the off-screen tail.\n//!\n//! Item widths (and thus `contentWidth`, which sets the repeat count for a\n//! seamless wrap) are the REAL shaped text widths via `measureText` — exact and\n//! proportional — falling back to a glyph-count estimate only until the engine\n//! warms in the browser.\n\nimport { Group, Text, clipRect, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { measureText, useTextMetricsReady } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\n\nexport interface MarqueeProps extends TextStyleProps {\n /** Items to scroll. The list is repeated as needed for a seamless wrap. */\n items?: string[]\n /** Scroll speed in pixels per second. Keep low for restraint (default 30). */\n speed?: number\n /** Scroll direction (default `'left'`). */\n direction?: 'left' | 'right'\n /** Pixels between items (default 64). */\n gap?: number\n /** Font size in px (default 32). */\n fontSize?: number\n /** Viewport width to scroll within. Defaults to the full composition width. */\n width?: number\n /** Viewport height (the clip band). Defaults to the full composition height. */\n height?: number\n}\n\nexport function Marquee({\n items: itemsProp = ['ONDA', 'TYPESCRIPT', 'REACT'],\n speed = 30,\n direction = 'left',\n gap = 64,\n color: colorProp,\n fontSize = 32,\n fontFamily: fontFamilyProp,\n fontWeight = 500,\n italic = false,\n letterSpacing,\n uppercase,\n width,\n height,\n}: MarqueeProps) {\n const items = itemsProp.map((item) => applyTextCase(item, { uppercase }))\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.textMuted\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n const viewportWidth = width ?? compWidth\n const viewportHeight = height ?? compHeight\n\n // Real shaped x-advance for each item, plus the trailing gap (proportional +\n // exact). `useTextMetricsReady` loads the engine in the browser and re-renders\n // when warm; `measureText` is the sync per-item read (a hook can't run in a map).\n useTextMetricsReady()\n const itemWidths = items.map(\n (item) => measureText(item, fontSize, { fontFamily, fontWeight }).width + gap,\n )\n const contentWidth = itemWidths.reduce((sum, w) => sum + w, 0)\n\n // Linear translation by design (see header). Pixels travelled so far.\n const speedPxPerFrame = speed / fps\n const rawOffset = frame * speedPxPerFrame\n\n // Modulo by one content width so the wrap is seamless. JS `%` can return a\n // negative result for negative operands, so normalize into [0, contentWidth).\n const wrapped = contentWidth > 0 ? ((rawOffset % contentWidth) + contentWidth) % contentWidth : 0\n\n // 'left' moves content leftward (negative x); 'right' flips the direction by\n // starting one content width back so the second copy is on screen.\n const offset = direction === 'left' ? -wrapped : wrapped - contentWidth\n\n // Vertically center the text band within the clip (fontSize is the line-height\n // proxy, since we can't read the engine's measured box back here).\n const textY = Math.round((viewportHeight - fontSize) / 2)\n\n // Center the whole clip band within the composition. When `height` is a short\n // ticker strip, the band would otherwise pin to the top (y=0) and leave the\n // rest of the frame empty; offsetting by half the slack reads as deliberate.\n const bandY = Math.round((compHeight - viewportHeight) / 2)\n const bandX = Math.round((compWidth - viewportWidth) / 2)\n\n // Precompute each item's local x within a single set (running sum of widths).\n let cursor = 0\n const placed = items.map((item, i) => {\n const x = cursor\n cursor += itemWidths[i] ?? 0\n return { item, x }\n })\n\n // Repeat the set enough times to blanket the viewport. The content is shifted\n // by at most one content width (`wrapped < contentWidth`), so we need one lead\n // copy plus enough copies to span `viewportWidth` — i.e. ceil(vw/cw) + 1.\n // Always at least 2 so the wrap point is never visible. Each copy's local x\n // origin is `copyIndex * contentWidth`.\n const copyCount = contentWidth > 0 ? Math.max(2, Math.ceil(viewportWidth / contentWidth) + 1) : 1\n const copies = Array.from({ length: copyCount }, (_, copyIndex) => copyIndex * contentWidth)\n\n return (\n <Group x={bandX} y={bandY} clip={clipRect(viewportWidth, viewportHeight)}>\n <Group x={offset}>\n {copies.map((copyOffset, copyIndex) =>\n placed.map(({ item, x }, i) => (\n <Text\n key={`${copyIndex}-${i}`}\n x={copyOffset + x}\n y={textY}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {item}\n </Text>\n )),\n )}\n </Group>\n </Group>\n )\n}\n","//! MaskReveal — a hard-edge mask reveal: content uncovered by a clip region that\n//! retreats from `direction` on the house spring. Pixel-sharp edge by design — no\n//! opacity fade. The moving edge IS the fingerprint. Ported from ondajs.\n//!\n//! In ondajs the text is fully painted from frame 0 and a CSS `clip-path` inset\n//! shrinks from 100% → 0% along the chosen side. `@onda-engine/react` expresses the same\n//! shape with a `<Group clip={clipRect(w, h)}>` whose clip RECTANGLE grows from 0\n//! → full. `clipRect` is anchored at the node's LOCAL ORIGIN (0,0) and takes no\n//! offset, so:\n//! - `left`/`top` (reveal grows away from the origin) clip directly;\n//! - `right`/`bottom` (reveal grows toward the origin) need the shift-clip-\n//! shift-back trick (outer Group offsets, inner Group clips at the origin and\n//! offsets back) — the same approach `@onda-engine/react`'s `wipe` transition uses.\n//!\n//! `direction` names the side the content appears to come IN from (mirrors\n//! `SlideIn`): the mask sits on the OPPOSITE side and retreats toward `direction`,\n//! so the reveal edge sweeps in from that side.\n//!\n//! Sizing caveat: the clip box must cover the content. With a `text` prop the box\n//! width comes from the engine's MEASURED glyph run (`useTextMetrics`, with a\n//! glyph-count fallback until the wasm engine warms) and its height from\n//! `LINE_RATIO`, padded so the sweep clears glyph edges and descenders. To reveal\n//! arbitrary `children`, pass explicit `width`/`height` for the clip box. The assembly is\n//! origin-relative (like `SlideIn`/`Underline`): position it via a parent `x`/`y`\n//! or an `<AbsoluteFill>` rather than as a measured `<Flex>` child.\n\nimport { Group, Text, clipRect, useVideoConfig } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { fitFontSize, fitMaxWidth } from '../bounds.js'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\n/** Engine line-box height as a multiple of font size (matches the typography\n * crate / the ratio `Underline` and `Highlight` use). */\nconst LINE_RATIO = 1.2\n/** Extra px around the estimated text box so the hard reveal edge sweeps cleanly\n * past the glyphs and descenders are never trimmed. */\nconst BOX_PAD = 8\n/** Extra px added to each end of the reveal axis (on top of `BOX_PAD`) so the\n * last glyph clears the right/leading edge of the clip even at rest (p = 1) and\n * is never trimmed by the estimate. */\nconst AXIS_PAD = 12\n\nexport interface MaskRevealProps extends TextStyleProps {\n /** What to reveal (single line). Ignored when `children` is supplied. */\n text?: string\n /** Frames before the reveal starts. */\n delay?: TimeInput\n /** Frames for the mask to fully retreat. */\n duration?: TimeInput\n /** The side the content appears to come IN from (mirrors `SlideIn`). The mask\n * retreats toward this side. */\n direction?: 'left' | 'right' | 'top' | 'bottom'\n /** Text size in px (default 96). */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * padded clip box cannot exceed the frame minus the safe margins. Default\n * `'none'` (the historical behavior). Text mode only. */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the padded clip box; combines with `fit`\n * (the smaller cap wins). Text mode only. */\n maxWidth?: number\n /** Clip-box width in px. Required for `children`; otherwise estimated from `text`. */\n width?: number\n /** Clip-box height in px. Required for `children`; otherwise `fontSize × 1.2`. */\n height?: number\n /** Where the clip box sits: a region keyword (`'center'`, `'lower-third'`, …)\n * or normalized `{x,y}` (0–1, box center). The shared placement contract;\n * default `'center'` (the historical behavior). */\n placement?: Placement\n /** Arbitrary subtree to reveal instead of `text`. Supply `width`/`height`. */\n children?: ReactNode\n}\n\nexport function MaskReveal({\n text: textProp = 'Onda',\n delay = 0,\n duration = DURATION.base,\n direction = 'left',\n color: colorProp,\n fontSize: fontSizeProp = 96,\n fit,\n maxWidth,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n width,\n height,\n placement,\n children,\n}: MaskRevealProps) {\n const text = applyTextCase(textProp, { uppercase })\n // House spring (SPRING_SMOOTH, no overshoot), matching ondajs. `useSpringValue`\n // clamps the pre-delay frames to 0 internally, so it reads 0 before `delay`.\n const progress = useSpringValue({ delay, durationInFrames: duration })\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n\n // Opt-in auto-fit (text mode): the cap applies to the PADDED clip box, so\n // the text must fit cap minus the sweep padding.\n const { width: frameW } = useVideoConfig()\n const cap = fitMaxWidth({ fit, maxWidth }, frameW)\n const textPad = width != null ? 0 : (BOX_PAD + AXIS_PAD) * 2\n const fontSize =\n cap !== undefined && children == null\n ? fitFontSize(text, fontSizeProp, Math.max(1, cap - textPad), { fontFamily, fontWeight })\n : fontSizeProp\n\n // Real shaped text width — the engine measures the glyphs (proportional, exact;\n // tracking-aware so the clip box still covers the line); falls back to a\n // glyph-count estimate until the wasm engine warms in the browser.\n const measured = useTextMetrics(text, fontSize, { fontFamily, fontWeight, letterSpacing })\n // Revealed fraction 0 → 1 (ondajs animates `cover` 100 → 0; this is `1 - cover`).\n const p = Math.min(1, Math.max(0, progress))\n\n // Clip box. With explicit children the caller owns the box; for `text` it's\n // sized from the measured glyph run, padded so the sweep clears the glyphs.\n const boxW = width ?? Math.max(1, measured.width + (BOX_PAD + AXIS_PAD) * 2)\n const boxH = height ?? Math.round(fontSize * LINE_RATIO + BOX_PAD * 2)\n\n // The content rendered beneath the mask — fully painted from frame 0.\n const content: ReactNode = children ?? (\n <Text\n x={width != null ? 0 : BOX_PAD + AXIS_PAD}\n y={height != null ? 0 : BOX_PAD}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {text}\n </Text>\n )\n\n // Grow the clip along the reveal axis. `clipRect` is origin-anchored, so for a\n // reveal that grows AWAY from the origin (left/top) the clip dimension simply\n // scales with `p`. For one that grows TOWARD the origin (right/bottom) we offset\n // the whole box by the not-yet-revealed amount, clip at the origin, and offset\n // the content back so it stays put — the moving edge then sweeps from that side.\n let inner: ReactNode\n switch (direction) {\n case 'top': {\n // Content comes in from the top → mask covers the bottom, retreats downward.\n const h = boxH * p\n inner = <Group clip={clipRect(boxW, h)}>{content}</Group>\n break\n }\n case 'right': {\n // Content comes in from the right → mask covers the left, retreats leftward.\n const w = boxW * p\n const dx = boxW - w\n inner = (\n <Group x={dx}>\n <Group x={-dx} clip={clipRect(w, boxH)}>\n {content}\n </Group>\n </Group>\n )\n break\n }\n case 'bottom': {\n // Content comes in from the bottom → mask covers the top, retreats upward.\n const h = boxH * p\n const dy = boxH - h\n inner = (\n <Group y={dy}>\n <Group y={-dy} clip={clipRect(boxW, h)}>\n {content}\n </Group>\n </Group>\n )\n break\n }\n default: {\n // 'left' — content comes in from the left → mask covers the right, retreats rightward.\n const w = boxW * p\n inner = <Group clip={clipRect(w, boxH)}>{content}</Group>\n }\n }\n\n // Anchor the (origin-relative) clip box on the shared placement contract —\n // the assembly is laid out from its top-left, so without this it would sit in\n // the corner (the Underline/BarChart pattern). Default `'center'` is the\n // historical centering; corner regions sit flush on the safe margin. A static\n // origin avoids any per-frame reflow as the clip edge sweeps. Explicit\n // children that overflow the estimated box still anchor to this top-left.\n const resolved = usePlacement(placement, { width: boxW, height: boxH })\n const originX = Math.round(resolved.originX)\n const originY = Math.round(resolved.originY)\n return (\n <Group x={originX} y={originY}>\n {inner}\n </Group>\n )\n}\n","//! MatrixDecode — glyphs flicker through random chars then settle left-to-right,\n//! a \"decode\" reveal. Ported from ondajs.\n//!\n//! Per character position: before its settle frame we show a random glyph from\n//! the charset; after its settle frame we show the target char. Settling marches\n//! left-to-right (each char settles `charDelay` frames after the previous), and\n//! every char scrambles for `scrambleDuration` frames before it lands.\n//!\n//! Determinism (HARD RULE 1): the flicker is a pure function of frame. Each\n//! scramble glyph is picked with `random(seed)` from '@onda-engine/react' (no\n//! `Math.random`, no wall clock), keyed by char index + a frame BUCKET\n//! (`floor(local / scrambleSpeed)`) so the glyph swaps every `scrambleSpeed`\n//! frames rather than every frame — same flicker cadence as ondajs.\n//!\n//! Rendering: ondajs renders one `<span>` per char with per-char color. Here the\n//! whole line is a single engine-measured `<Text>` carrying a per-char `runs`\n//! array, so still-scrambling glyphs take `scrambleColor` (the earned accent) and\n//! settled glyphs take `color` — without manual per-glyph x math.\n//!\n//! Layout note (HARD RULE 2): a monospace family keeps the advance steady as\n//! glyphs flicker, but the measured line width can still shift frame-to-frame\n//! (and the charset can include wider glyphs). A changing-width `<Text>` inside a\n//! `<Flex>`/`<AbsoluteFill>` would make the layout pass reflow/jiggle, so the\n//! line is positioned ABSOLUTELY at an explicit `x`/`y` (defaulting to the canvas\n//! center) — like `Typewriter`/`CountUp`.\n//!\n//! Approximations (engine vs the ondajs/CSS original):\n//! - No CSS `letter-spacing` in scene `<Text>`; the `--onda-*` CSS-var color\n//! defaults are resolved to their literal hex fallbacks.\n//! - No `text-align`/`placement` region system: `align` is approximated by\n//! anchoring the (single) line — `'left'` puts the left edge at `x`,\n//! `'center'`/`'right'` shift left by the MEASURED text width (via\n//! `useTextMetrics`; falls back to a glyph-count estimate until the wasm\n//! engine warms). Pass explicit `x`/`y` for exact placement.\n//! - Per-run colors render on the GPU (Vello) path; the CPU reference draws the\n//! concatenated text in the node's base `color`, so there the scramble accent\n//! is lost. GPU is the primary path.\n\nimport { Text, random, useCurrentFrame, useVideoConfig, variantSeed } from '@onda-engine/react'\nimport type { TextRunInput } from '@onda-engine/react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { LINE_RATIO, layoutGlyphLine } from '../glyph-line.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { useTextMetricsReady } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { staggeredSettle, useTimeScale } from '../timing.js'\n\nexport interface MatrixDecodeProps extends TextStyleProps {\n /** The text that decodes into place. */\n text?: string\n /** Time before decoding starts — frames or '0.5s'. */\n delay?: TimeInput\n /** Time between successive characters settling (left-to-right). */\n charDelay?: TimeInput\n /** Time each character scrambles before it settles (min 1 frame). */\n scrambleDuration?: TimeInput\n /** Time between glyph swaps while scrambling. Lower = faster flicker (min 1 frame). */\n scrambleSpeed?: TimeInput\n /** Compress the whole timing envelope (delay, stagger, durations) so the\n * entrance settles at least `hold` before the end of the enclosing clip\n * (`useVideoConfig().durationInFrames`, Sequence-scoped). Opt-in. */\n fitToClip?: boolean\n /** Hard cap on the settle time (frames or '0.5s'). Wins over `fitToClip`. */\n maxSettle?: TimeInput\n /** Breathing room before the cut for `fitToClip` (default 6 frames). */\n hold?: TimeInput\n /** Seed for the (deterministic) glyph picks. */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Glyph pool drawn from while scrambling. */\n charset?: string\n /** Color of still-scrambling glyphs — the earned accent (default: theme `accent`). */\n scrambleColor?: string\n /** Font size in px (default 120). */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * measured line cannot exceed the frame minus the safe margins. Default\n * `'none'` (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the line; combines with `fit` (the smaller\n * cap wins). */\n maxWidth?: number\n /** Horizontal anchoring of the single line (approximate — see file notes).\n * Only applies to the legacy default/`x` anchoring — `placement` anchors the\n * line's measured center. */\n align?: 'left' | 'center' | 'right'\n /** Where the line sits: a region keyword (`'center'`, `'lower-third'`, …) or\n * normalized `{x,y}` (0–1, line center). The shared placement contract;\n * default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias — absolute x of the line's left edge in px.\n * Prefer `placement`. */\n x?: number\n /** @deprecated Legacy alias — absolute y (top-ish) of the line in px. Prefer\n * `placement`. */\n y?: number\n}\n\nexport function MatrixDecode({\n text: textProp = 'ONDA',\n delay: delayIn = 0,\n charDelay: charDelayIn = 3,\n scrambleDuration: scrambleDurationIn = 18,\n scrambleSpeed: scrambleSpeedIn = 2,\n fitToClip,\n maxSettle,\n hold,\n seed: seedProp = 7,\n variant,\n charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#$%&*+=<>/',\n color: colorProp,\n scrambleColor: scrambleColorProp,\n fontSize: fontSizeProp = 120,\n fit,\n maxWidth,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n align = 'center',\n placement,\n x,\n y,\n}: MatrixDecodeProps) {\n const text = applyTextCase(textProp, { uppercase })\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const frame = useCurrentFrame()\n const { width, height, fps } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const scrambleColor = scrambleColorProp ?? theme.accent\n const fontFamily = fontFamilyProp ?? theme.monoFamily\n\n // Opt-in auto-fit, measured on the TARGET text (the settled line). A wider\n // scramble glyph can exceed it by a glyph-width transiently; the settled\n // line cannot.\n const fontSize = useFittedFontSize(text, fontSizeProp, { fontFamily, fontWeight, fit, maxWidth })\n\n const chars = [...text]\n\n // Timing: parse the TimeInput props, then compress the envelope when the\n // decode wouldn't settle inside the clip. Guard degenerate values (the\n // schema clamps these to >= 1).\n const delayBase = framesOf(delayIn, fps)\n const stepBase = Math.max(0, framesOf(charDelayIn, fps, 3))\n const scrambleBase = Math.max(1, framesOf(scrambleDurationIn, fps, 18))\n const naturalSettle = staggeredSettle(chars.length, stepBase, scrambleBase, delayBase)\n const timeScale = useTimeScale(naturalSettle, { fitToClip, maxSettle, hold })\n const delay = delayBase * timeScale\n const stepDelay = stepBase * timeScale\n const scrambleFrames = Math.max(1, scrambleBase * timeScale)\n const swapEvery = Math.max(1, framesOf(scrambleSpeedIn, fps, 2))\n const pool = charset.length > 0 ? charset : ' '\n\n const local = frame - delay\n\n // Build a per-char run: settled chars get `color`, scrambling chars get a\n // deterministic glyph in `scrambleColor`. Spaces pass through untouched so the\n // word shape stays legible while the rest decodes.\n const runs: TextRunInput[] = chars.map((ch, i) => {\n if (ch === ' ') {\n return { text: ' ', color, fontSize, fontFamily, fontWeight, italic }\n }\n const settleAt = i * stepDelay + scrambleFrames\n const settled = local >= settleAt\n if (settled) {\n return { text: ch, color, fontSize, fontFamily, fontWeight, italic }\n }\n // Scramble: pick a glyph deterministically from (index, frame bucket). The\n // bucket changes every `swapEvery` frames, so the flicker swaps at that rate.\n const bucket = Math.floor(Math.max(0, local) / swapEvery)\n const r = random(seed + i * 9301 + bucket * 49297)\n const idx = Math.min(pool.length - 1, Math.floor(r * pool.length))\n const glyph = pool[idx] ?? ch\n return { text: glyph, color: scrambleColor, fontSize, fontFamily, fontWeight, italic }\n })\n\n // The plain concatenated string — used as the base child (CPU-reference draw)\n // and to measure width for `align` anchoring.\n const plain = runs.map((run) => run.text).join('')\n\n // Real shaped line width via the SHARED glyph-line primitive (kerning-exact;\n // glyph-count estimate until the wasm engine warms in the browser).\n useTextMetricsReady()\n const measured = layoutGlyphLine(plain, fontSize, { fontFamily, fontWeight })\n\n // Absolute placement so the (potentially width-varying) line never triggers a\n // Flex reflow. The shared placement contract anchors the line's MEASURED\n // center (corner regions sit flush on the safe margin); legacy `x`/`y` px and\n // the `align`-anchored default keep their exact pre-placement behavior.\n const estWidth = measured.width\n const resolved = usePlacement(placement, { width: estWidth, height: fontSize * LINE_RATIO })\n // `placement` is authoritative when set; legacy pixel `x`/`y` only anchor in\n // the pre-placement path, so a stray `x`/`y` can't override an explicit\n // placement (a 0.5 meant as a fraction reads as 0.5 px → top-left).\n let px: number\n if (placement !== undefined) {\n px = Math.round(resolved.originX)\n } else if (x !== undefined) {\n px = x\n } else if (align === 'left') {\n px = Math.round(width * 0.08)\n } else if (align === 'right') {\n px = Math.round(width * 0.92 - estWidth)\n } else {\n px = Math.round((width - estWidth) / 2)\n }\n const py =\n placement !== undefined\n ? Math.round(resolved.originY)\n : (y ?? Math.round(height / 2 - fontSize * 0.6))\n\n return (\n <Text\n x={px}\n y={py}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n runs={runs}\n >\n {plain}\n </Text>\n )\n}\n","//! MeshGradient — a drifting mesh-gradient backdrop. Ported from ondajs.\n//!\n//! Atmosphere, not subject: several large, soft radial blobs in palette colors\n//! drift slowly over a near-black canvas. Each blob's center is a pure function\n//! of the frame (sine/cosine drift keyed off a *seeded* phase), so it loops and\n//! renders deterministically (§1) — no `useState`/`useEffect`, no global PRNG.\n//! Overlapping soft radials read as a single mesh gradient.\n//!\n//! Engine notes / approximations:\n//! - No blur primitive. ondajs draws hard-ish radial blobs and applies a CSS\n//! `blur(8px)` over the whole layer to melt them together. Here the softness\n//! is baked into each blob's gradient instead: a wide color→transparent tail\n//! (the gradient *is* the blur), so overlapping blobs still blend smoothly.\n//! - Each blob is a full-composition `<Rect>` filled with a `radialGradient`\n//! (solid `color` at the moving center → transparent at the blob radius). The\n//! Rect size never changes, only the gradient center moves, so there is no\n//! layout reflow. The blobs are absolutely positioned at the origin, not in a\n//! `<Flex>`, so animated centers can't make a layout jiggle (§2).\n//! - Overall `opacity` is applied as a wrapping `<Group opacity>` (the scene\n//! equivalent of ondajs's layer opacity over the background).\n//! - Overlapping soft radial blobs ARE the mesh gradient (the standard\n//! radials-as-mesh technique). Both backends render radial gradients + the\n//! transparent-tail alpha compositing, so the soft mesh blend holds on the CPU\n//! reference too.\n\nimport {\n Group,\n Rect,\n radialGradient,\n random,\n useCurrentFrame,\n useVideoConfig,\n variantSeed,\n} from '@onda-engine/react'\nimport { useTheme } from '../theme.js'\n\n/** Default palette — drifts over the near-black canvas (matches ondajs). */\nconst DEFAULT_COLORS = ['#d96b82', '#e89aab', '#26262e']\n\n/** Default canvas color behind the blobs (matches ondajs `--onda-bg`). */\nconst DEFAULT_BACKGROUND = '#08080a'\n\nexport interface MeshGradientProps {\n /** Blob colors. 2–4 reads best; they drift over the `background` canvas (default: theme `palette[0]`). */\n colors?: string[]\n /** Base canvas color behind the blobs (default: theme `background`). */\n background?: string\n /** Drift speed multiplier. Keep low — this is atmosphere, not motion. */\n speed?: number\n /** Seed for the blob phase/amplitude offsets (deterministic). */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Overall blob opacity over the canvas (0..1). */\n opacity?: number\n}\n\n/** Clamp `n` into `[lo, hi]`. */\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, n))\n}\n\n/** Return `color` with its alpha channel forced to `00` (fully transparent),\n * preserving the RGB so the blob fades OUT rather than toward black. */\nfunction toTransparent(color: string): string {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}00`\n }\n if (hex.length === 3 || hex.length === 4) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}00`\n }\n }\n // Unknown format — fall back to a known-transparent value.\n return '#00000000'\n}\n\nexport function MeshGradient({\n colors: colorsProp,\n background: backgroundProp,\n speed = 1,\n seed: seedProp = 7,\n variant,\n opacity = 0.5,\n}: MeshGradientProps) {\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const frame = useCurrentFrame()\n const { width, height } = useVideoConfig()\n const theme = useTheme()\n const colors = colorsProp ?? (theme.palette[0] ? [theme.palette[0]] : DEFAULT_COLORS)\n const background = backgroundProp ?? theme.background ?? DEFAULT_BACKGROUND\n\n // Shared drift clock — slow, since this is atmosphere (ondajs: frame * 0.012).\n const w = frame * 0.012 * speed\n\n // Blob radius scales with the canvas so the softness reads the same at any\n // aspect. ondajs's CSS tail ends at 45% of the gradient box; the half-diagonal\n // gives a generous, soft overlap that melts the blobs together (the \"blur\").\n const blobRadius = Math.hypot(width, height) * 0.5\n\n return (\n <Group opacity={clamp(opacity, 0, 1)}>\n {/* Base canvas behind the blobs. */}\n <Rect width={width} height={height} fill={background} />\n\n {colors.map((color, i) => {\n // Per-blob deterministic phase/amplitude offsets. The engine's `random`\n // is single-shot, so derive an independent value per axis by salting the\n // seed with the blob index (matches the *intent* of ondajs's seeded\n // `rand()` sequence: stable, decorrelated offsets per blob).\n const phase = random(`${seed}-${i}-phase`) * Math.PI * 2\n const ampX = (16 + random(`${seed}-${i}-ampx`) * 14) / 100\n const ampY = (14 + random(`${seed}-${i}-ampy`) * 14) / 100\n const baseX = (25 + random(`${seed}-${i}-basex`) * 50) / 100\n const baseY = (25 + random(`${seed}-${i}-basey`) * 50) / 100\n\n // Drift the center as a fraction of the canvas, then to px. Cosine runs\n // at 0.8× the sine rate so x/y trace a slow Lissajous, not a circle.\n const fx = baseX + Math.sin(w + phase) * ampX\n const fy = baseY + Math.cos(w * 0.8 + phase) * ampY\n const cx = fx * width\n const cy = fy * height\n\n const transparent = toTransparent(color)\n\n // Two stops: solid `color` at the center fading to transparent at the\n // blob edge. The transparent tail is the LAST stop so the engine's\n // `Extend::Pad` doesn't fill the canvas-sized Rect opaque beyond the blob\n // (same reasoning as Spotlight). On CPU this collapses to the solid first\n // stop — hence the meaningful color leads.\n return (\n <Rect\n key={i}\n width={width}\n height={height}\n gradient={radialGradient([cx, cy], blobRadius, [\n { offset: 0, color },\n { offset: 1, color: transparent },\n ])}\n />\n )\n })}\n </Group>\n )\n}\n","//! Moodboard — a seeded scatter-grid of image tiles arranged AROUND a central\n//! exclusion zone (where a title lockup sits). Given N images it auto-distributes\n//! them on a coarse grid, skips the cells over the center, and jitters each tile's\n//! position/size/aspect deterministically (seeded → same layout every render). Each\n//! tile CASCADES in — fade + upward drift + slight scale-up — on a VISIBLE stagger,\n//! holds, then exits on the mirrored stagger. The portfolio/moodboard spread.\n//!\n//! The two craft rules baked in: the stagger is visible (tiles never land at once),\n//! and the exit is the entrance reversed (same curve). Pair it with a centered\n//! title (e.g. <SplitLockup>) sitting in the exclusion zone.\n\nimport { Group, Image, clipRect, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface MoodboardProps {\n /** Tile image sources (resolved at render). Distributed around the center. */\n images?: string[]\n /** Layout seed — same seed → same scatter (deterministic). */\n seed?: number\n /** Coarse grid the tiles snap to (before jitter). */\n columns?: number\n rows?: number\n /** Central exclusion rect (no tiles), as fractions of the canvas — sized to the\n * title that sits there. */\n exclusionWidth?: number\n exclusionHeight?: number\n /** Frames between successive tiles ENTERING — keep it visible (default 3). */\n stagger?: TimeInput\n /** Per-tile entrance duration (default '0.5s'). */\n tileEnter?: TimeInput\n /** Frames between successive tiles EXITING (default 2). */\n exitStagger?: TimeInput\n /** Per-tile exit duration (default '0.4s'). */\n tileExit?: TimeInput\n /** Total clip length; defaults to the enclosing Sequence duration. */\n durationInFrames?: TimeInput\n /** Entrance start scale (default 1 — the look is fade + slide, no scale). */\n scaleFrom?: number\n /** Entrance drift distance in px (tiles rise into place). */\n driftPx?: number\n /** Rounded-corner radius for each tile in px (default 16). */\n cornerRadius?: number\n /** Position jitter as a fraction of the cell (default 0.12). */\n jitter?: number\n /** Tile aspect-ratio pool (w/h) the scatter draws from (default landscape + square). */\n aspects?: number[]\n}\n\nconst clamp01 = (t: number): number => (t < 0 ? 0 : t > 1 ? 1 : t)\nconst easeOut = (t: number): number => 1 - (1 - clamp01(t)) ** 3\nconst easeIn = (t: number): number => clamp01(t) ** 3\nconst lerp = (a: number, b: number, t: number): number => a + (b - a) * t\n// Default tile aspect pool — landscape + square (no portraits), matching the\n// moodboard/portfolio look. Override with the `aspects` prop.\nconst ASPECTS = [1.37, 1.6, 1.0, 1.83, 1.37, 1.0]\n\ninterface Tile {\n cx: number\n cy: number\n w: number\n h: number\n src: string\n}\n\nexport function Moodboard({\n images = [],\n seed = 7,\n columns = 5,\n rows = 4,\n exclusionWidth = 0.46,\n exclusionHeight = 0.4,\n stagger,\n tileEnter,\n exitStagger,\n tileExit,\n durationInFrames,\n scaleFrom = 1,\n driftPx = 44,\n cornerRadius = 16,\n jitter = 0.12,\n aspects = ASPECTS,\n}: MoodboardProps) {\n const frame = useCurrentFrame()\n const { fps, width, height, durationInFrames: clipFrames } = useVideoConfig()\n if (images.length === 0) return null\n\n const total = durationInFrames != null ? framesOf(durationInFrames, fps) : clipFrames\n const stag = Math.max(1, framesOf(stagger ?? 3, fps))\n const enterDur = Math.max(1, framesOf(tileEnter ?? '0.5s', fps))\n const exitStag = Math.max(1, framesOf(exitStagger ?? 2, fps))\n const exitDur = Math.max(1, framesOf(tileExit ?? '0.4s', fps))\n\n // Seeded PRNG (mulberry32) — deterministic scatter.\n let s = seed >>> 0 || 1\n const rnd = (): number => {\n s = (s + 0x6d2b79f5) | 0\n let t = Math.imul(s ^ (s >>> 15), 1 | s)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n const cellW = width / columns\n const cellH = height / rows\n const exLeft = width / 2 - (width * exclusionWidth) / 2\n const exRight = width / 2 + (width * exclusionWidth) / 2\n const exTop = height / 2 - (height * exclusionHeight) / 2\n const exBottom = height / 2 + (height * exclusionHeight) / 2\n\n // Collect non-excluded cells, shuffle deterministically, then place exactly ONE\n // tile per image — so the moodboard has N tiles scattered around the title, not a\n // packed grid.\n const cells: Array<{ cx: number; cy: number }> = []\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < columns; c++) {\n const ccx = (c + 0.5) * cellW\n const ccy = (r + 0.5) * cellH\n if (ccx > exLeft && ccx < exRight && ccy > exTop && ccy < exBottom) continue\n cells.push({ cx: ccx, cy: ccy })\n }\n }\n for (let i = cells.length - 1; i > 0; i--) {\n const j = Math.floor(rnd() * (i + 1))\n const tmp = cells[i] as { cx: number; cy: number }\n cells[i] = cells[j] as { cx: number; cy: number }\n cells[j] = tmp\n }\n const tiles: Tile[] = []\n for (let i = 0; i < images.length && i < cells.length; i++) {\n const cell = cells[i] as { cx: number; cy: number }\n const sizeF = 0.66 + rnd() * 0.26\n const aspect = aspects[Math.floor(rnd() * aspects.length)] ?? 1\n const base = Math.min(cellW, cellH) * sizeF\n tiles.push({\n cx: cell.cx + (rnd() - 0.5) * cellW * jitter,\n cy: cell.cy + (rnd() - 0.5) * cellH * jitter,\n w: base * Math.sqrt(aspect),\n h: base / Math.sqrt(aspect),\n src: images[i] as string,\n })\n }\n\n const n = tiles.length\n // Exit window sits at the end; the LAST tile finishes exactly at `total`.\n const exitStart = total - (exitDur + (n - 1) * exitStag)\n\n return (\n <Group>\n {tiles.map((t, i) => {\n const enterP = easeOut((frame - i * stag) / enterDur)\n const exitTileStart = exitStart + i * exitStag\n const exitP = easeIn((frame - exitTileStart) / exitDur)\n const inO = clamp01(enterP)\n const outO = clamp01(exitP)\n const opacity = inO * (1 - outO)\n if (opacity <= 0.002) return null\n const scale = lerp(scaleFrom, 1, inO) * lerp(1, 0.96, outO)\n const dy = (1 - inO) * driftPx - outO * driftPx * 0.5\n return (\n <Group key={`${i}-${t.src}`} x={t.cx} y={t.cy + dy} opacity={opacity}>\n <Group scaleX={scale} scaleY={scale}>\n <Group x={-t.w / 2} y={-t.h / 2} clip={clipRect(t.w, t.h, cornerRadius)}>\n <Image src={t.src} width={t.w} height={t.h} fit=\"cover\" />\n </Group>\n </Group>\n </Group>\n )\n })}\n </Group>\n )\n}\n","//! NodeGraph — a hub-and-spoke constellation: a labeled central hub with\n//! satellite nodes that fly in from off-frame, settle into elliptical orbits,\n//! and connect to the hub by lines that periodically light up. Ported from\n//! ondajs (`node-graph`).\n//!\n//! Everything is a pure function of `useCurrentFrame()` and a seed (§1). The\n//! seeded fly-in directions and connection-pulse phases are reproduced with\n//! `random('${seed}-...')` sub-seeds — `@onda-engine/react`'s `random` returns one\n//! value per seed (not a stateful generator like ondajs's `seededRandom`), so\n//! each draw gets a distinct, stable sub-seed in the same fixed order.\n//!\n//! Layout: the constellation is centered on a single anchor Group (no `<Flex>`)\n//! — node positions drift every frame, and a layout container would reflow as\n//! the measured bbox moved. Connection lines, the glow, the satellites, and the\n//! hub are all placed by explicit x/y in that anchor's local space, with the\n//! hub at the origin (0,0).\n//!\n//! Pivot caveat (§3): the hub's scale-rise scales about the node's LOCAL\n//! origin, so the hub disc is offset by -radius and wrapped in a Group that\n//! marks its center, making the growth read as centered.\n//!\n//! Approximations (engine has no CSS): the hub's `box-shadow`/`border` glow and\n//! the soft accent `Glow` become a radial-gradient `<Ellipse>` halo behind the\n//! hub; satellite pill `box-shadow` and `letter-spacing` are dropped (no engine\n//! equivalent). ondajs's `placement` region + `hubSize` semantic-size tokens\n//! collapse to plain `centerX`/`centerY` canvas fractions and a px `hubFontSize`.\n//! Connection lines are `<Path>` strokes — Path and gradients render on the\n//! Vello/GPU backend only; the CPU reference skips paths and collapses gradients\n//! to their first stop (so the hub reads as a solid accent disc on CPU).\n\nimport {\n Ellipse,\n Flex,\n Group,\n Path,\n Rect,\n Text,\n interpolate,\n radialGradient,\n random,\n spring,\n useCurrentFrame,\n useVideoConfig,\n variantSeed,\n} from '@onda-engine/react'\nimport { HOUSE_EASE } from '../easing.js'\nimport { DURATION, SPRING_SMOOTH, staggerFrames } from '../motion.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** One orbiting satellite node in the constellation. */\nexport interface Satellite {\n /** Short label inside the node — a word or single character reads best. */\n label: string\n /** Orbit radius in px (distance from the hub). Varying radii read as depth. */\n radius: number\n /** Angular speed in radians per frame; signed for either direction. */\n speed: number\n /** Starting angle in radians — where the satellite sits at frame 0. */\n startAngle: number\n}\n\nexport interface NodeGraphProps extends TextStyleProps {\n /** Label inside the central hub node — a single character or short word. */\n hubLabel?: string\n /** The orbiting satellites. Each flies in from off-frame, then settles into\n * its elliptical orbit. ~5 reads as a believable constellation. */\n satellites?: Satellite[]\n /** The earned accent — hub fill tint, the connection lines, and the glow (default: theme `accent`). */\n accent?: string\n /** Vertical squash of every orbit (1 = circular, <1 = elliptical). A strong\n * squash makes the even-angled spokes *read* as lopsided (nodes bunch toward\n * the 3/9-o'clock sides and gaps open top/bottom), so the default keeps the\n * ring near-circular. */\n ellipse?: number\n /** Seed for the deterministic fly-in directions and connection-pulse phases. */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Frames before the constellation begins assembling. */\n delay?: TimeInput\n /** Show the soft accent glow behind the hub. */\n glow?: boolean\n /** Hub node diameter in px. */\n hubDiameter?: number\n /** Hub label size in px. */\n hubFontSize?: number\n /** Background canvas color behind the constellation (default: theme `background`). */\n background?: string\n /** Surface (fill) color of the satellite pills (default: theme `surface`). */\n surface?: string\n /** Border color of the satellite pills (default: theme `border`). */\n borderColor?: string\n /** Text color of every label (default: theme `text`). */\n textColor?: string\n /** Satellite label font size in px. */\n satelliteFontSize?: number\n /** Horizontal center of the constellation as a 0–1 fraction of canvas width. */\n centerX?: number\n /** Vertical center of the constellation as a 0–1 fraction of canvas height. */\n centerY?: number\n}\n\n// Five satellites on evenly-spaced spokes (`i * 2π/5`) at a uniform radius so\n// the constellation reads as a balanced, centered ring rather than a lopsided\n// cluster. The ring is rotated by half a step (`SPOKE_GAP/2`) off straight-up so\n// two spokes *straddle* the top symmetrically instead of one pointing dead-center\n// up — which otherwise leaves a wide empty wedge on either side of the top. The\n// slow signed drift keeps the orbit alive without letting spokes bunch up.\nconst SPOKE_GAP = (2 * Math.PI) / 5\nconst SPOKE_BASE = -Math.PI / 2 - SPOKE_GAP / 2\nconst DEFAULT_SATELLITES: Satellite[] = [\n { label: 'data', radius: 300, speed: 0.006, startAngle: SPOKE_BASE },\n {\n label: 'model',\n radius: 300,\n speed: 0.006,\n startAngle: SPOKE_BASE + SPOKE_GAP,\n },\n {\n label: 'render',\n radius: 300,\n speed: 0.006,\n startAngle: SPOKE_BASE + 2 * SPOKE_GAP,\n },\n {\n label: 'audio',\n radius: 300,\n speed: 0.006,\n startAngle: SPOKE_BASE + 3 * SPOKE_GAP,\n },\n {\n label: 'scene',\n radius: 300,\n speed: 0.006,\n startAngle: SPOKE_BASE + 4 * SPOKE_GAP,\n },\n]\n\n// How far off-frame a satellite starts before it flies into orbit.\nconst FLY_IN_DISTANCE = 1400\n// Approximate average glyph advance as a fraction of font size (for sizing the\n// satellite pill, which the engine measures but a pure frame→scene fn can't\n// read back). Matches the estimate used by the Marquee port.\nconst AVG_CHAR_W = 0.6\n\nexport function NodeGraph({\n hubLabel = 'AI',\n satellites = DEFAULT_SATELLITES,\n accent: accentProp,\n ellipse = 0.92,\n seed: seedProp = 7,\n variant,\n delay: delayIn = 0,\n glow = true,\n hubDiameter = 120,\n hubFontSize = 34,\n background: backgroundProp,\n surface: surfaceProp,\n borderColor: borderColorProp,\n textColor: textColorProp,\n satelliteFontSize = 20,\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n centerX = 0.5,\n centerY = 0.5,\n}: NodeGraphProps) {\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const accent = accentProp ?? theme.accent\n const background = backgroundProp ?? theme.background\n const surface = surfaceProp ?? theme.surface\n const borderColor = borderColorProp ?? theme.border\n const textColor = textColorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n const anchorX = centerX * width\n const anchorY = centerY * height\n\n // Hub entrance — a single calm scale-rise on the house spring, settled on the\n // `slow` token (hero move).\n const hubP = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.slow,\n })\n const hubScale = interpolate(hubP, [0, 1], [0.7, 1])\n const hubOpacity = interpolate(frame - delay, [0, DURATION.base], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n easing: HOUSE_EASE,\n })\n\n const hubRadius = hubDiameter / 2\n\n // Per-satellite deterministic motion. Each draw uses a distinct sub-seed so\n // the sequence is stable every render and across renderers (§1).\n const nodes = satellites.map((sat, i) => {\n // Off-frame fly-in origin: a seeded direction, pushed beyond the frame.\n const flyAngle = random(`${seed}-fly-${i}`) * Math.PI * 2\n const startX = Math.cos(flyAngle) * FLY_IN_DISTANCE\n const startY = Math.sin(flyAngle) * FLY_IN_DISTANCE\n // Connection-line pulse phase — seeded so siblings don't blink in unison.\n const pulsePhase = random(`${seed}-pulse-${i}`) * Math.PI * 2\n\n const localDelay = delay + staggerFrames(i)\n const t = frame - localDelay\n\n // Settled orbital position (elliptical: y squashed by `ellipse`).\n const angle = sat.startAngle + sat.speed * Math.max(0, t)\n const orbitX = Math.cos(angle) * sat.radius\n const orbitY = Math.sin(angle) * sat.radius * ellipse\n\n // Fly-in blends start → orbit on the house spring (no overshoot), settled on\n // the `slower` token so each satellite decelerates calmly into its orbit.\n const p = spring({\n frame: Math.max(0, t),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.slower,\n })\n const x = interpolate(p, [0, 1], [startX, orbitX])\n const y = interpolate(p, [0, 1], [startY, orbitY])\n\n const opacity = interpolate(t, [0, DURATION.base], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n easing: HOUSE_EASE,\n })\n\n // Deterministic line \"light-up\": a slow sine raised to a power so the line\n // sits dim most of the time and briefly flares. Gated by `p` so it stays\n // dark until the satellite has arrived.\n const wave = (Math.sin(t * 0.06 + pulsePhase) + 1) / 2 // 0..1\n const flare = wave ** 4 // mostly low, brief peaks\n const lineLit = flare * p\n\n // Pill geometry (label width can't be measured back, so it's estimated).\n const padX = 18\n const labelW = sat.label.length * satelliteFontSize * AVG_CHAR_W\n const pillW = labelW + padX * 2\n const pillH = satelliteFontSize + 20\n\n // Edge endpoint: stop at the pill's near edge (toward the hub), not its\n // center, so the connection line meets the pill cleanly. Treat the pill as\n // a rounded box and shrink the (x, y) target by the half-extent the\n // hub→pill ray crosses on entry, plus the hub radius at the near end.\n const dist = Math.hypot(x, y)\n let edgeStartX = 0\n let edgeStartY = 0\n let edgeEndX = x\n let edgeEndY = y\n if (dist > 0.001) {\n const ux = x / dist\n const uy = y / dist\n // Half-extent of the axis-aligned pill in the ray's direction.\n const half =\n Math.abs(ux) < 1e-6\n ? pillH / 2\n : Math.min(pillW / 2 / Math.abs(ux), pillH / 2 / Math.abs(uy))\n const endTrim = Math.min(half, dist)\n edgeEndX = x - ux * endTrim\n edgeEndY = y - uy * endTrim\n edgeStartX = ux * Math.min(hubRadius, dist)\n edgeStartY = uy * Math.min(hubRadius, dist)\n }\n\n return {\n sat,\n x,\n y,\n opacity,\n lineLit,\n pillW,\n pillH,\n labelW,\n edgeStartX,\n edgeStartY,\n edgeEndX,\n edgeEndY,\n }\n })\n\n // The ONE earned accent among the satellites: the node whose connection is\n // currently most lit reads as \"active\" this frame — it gets an accent rim and\n // a faint accent glow while every other node stays on the restrained surface\n // palette. Deterministic (a pure function of frame), so it's stable across\n // renderers; -1 until at least one satellite has flown in.\n let activeIndex = -1\n let activeLit = 0.04\n nodes.forEach((n, i) => {\n if (n.opacity > 0.5 && n.lineLit > activeLit) {\n activeLit = n.lineLit\n activeIndex = i\n }\n })\n\n // Soft halo behind the hub, approximating ondajs's blur/box-shadow glow.\n const glowRadius = Math.min(width, height) * 0.35\n const glowColor = `${rgbHex(accent)}59` // ~0.22 alpha at center\n const glowClear = `${rgbHex(accent)}00`\n const transparent = `${rgbHex(accent)}00`\n\n return (\n <Group>\n {/* Full-canvas background. */}\n <Rect width={width} height={height} fill={background} />\n\n {/* Anchor: the hub center. Everything below is in this local space. */}\n <Group x={anchorX} y={anchorY}>\n {/* Soft accent glow behind the hub (radial-gradient halo). */}\n {glow && glowRadius >= 1 ? (\n <Ellipse\n x={-glowRadius}\n y={-glowRadius}\n width={glowRadius * 2}\n height={glowRadius * 2}\n opacity={hubOpacity}\n gradient={radialGradient([glowRadius, glowRadius], glowRadius, [\n { offset: 0, color: glowColor },\n { offset: 1, color: glowClear },\n ])}\n />\n ) : null}\n\n {/* Connection lines (behind the nodes), hub rim → each satellite's near\n (hub-facing) pill edge — so the line meets the pill cleanly instead\n of running through it. Path/stroke is GPU-only; CPU skips it. Each\n edge is drawn twice: a wide, low-opacity accent underlay that reads\n as a soft glow, then the crisp stroke on top. */}\n {nodes.map(({ opacity, lineLit, edgeStartX, edgeStartY, edgeEndX, edgeEndY }, i) => {\n // Every edge shares one accent stroke at a consistent opacity/width —\n // the pulse only *adds* a brief brighten/thicken on top of that floor,\n // so no edge ever drops to a near-invisible gray hairline regardless\n // of its per-edge pulse phase at this frame. Gated by `opacity` so a\n // line stays hidden until its satellite has flown in.\n const lineOpacity = opacity * interpolate(lineLit, [0, 1], [0.6, 0.9])\n const lineWidth = interpolate(lineLit, [0, 1], [1.6, 2.4])\n if (lineOpacity <= 0.001) return null\n const d = `M${edgeStartX.toFixed(2)} ${edgeStartY.toFixed(2)} L${edgeEndX.toFixed(2)} ${edgeEndY.toFixed(2)}`\n // Soft glow underlay: much wider, low-opacity accent that swells with\n // the pulse — a halo around the live line without a CSS blur.\n const glowOpacity = opacity * interpolate(lineLit, [0, 1], [0.1, 0.22])\n const glowWidth = interpolate(lineLit, [0, 1], [5, 9])\n return (\n <Group key={`edge-${i}`}>\n <Path d={d} stroke={accent} strokeWidth={glowWidth} opacity={glowOpacity} />\n <Path d={d} stroke={accent} strokeWidth={lineWidth} opacity={lineOpacity} />\n </Group>\n )\n })}\n\n {/* Satellite nodes — rounded pills with a centered label. The pill is\n sized from an estimated label width (engine measurement can't be\n read back here). Positioned so the pill's center sits on (x, y). */}\n {nodes.map(({ sat, x, y, opacity, pillW, pillH, labelW }, i) => {\n // The one active node (§ accent above) earns the accent rim + a faint\n // accent halo behind its pill; the rest stay on the surface palette.\n const isActive = i === activeIndex\n const haloW = pillW + 36\n const haloH = pillH + 36\n return (\n <Group key={`node-${i}`} x={x} y={y} opacity={opacity}>\n {/* Faint accent halo behind the active node only. */}\n {isActive ? (\n <Ellipse\n x={-haloW / 2}\n y={-haloH / 2}\n width={haloW}\n height={haloH}\n opacity={interpolate(activeLit, [0, 1], [0.12, 0.3])}\n gradient={radialGradient([haloW / 2, haloH / 2], haloW / 2, [\n { offset: 0, color: `${rgbHex(accent)}66` },\n { offset: 1, color: transparent },\n ])}\n />\n ) : null}\n {/* Center the pill on the orbit point. The active node takes the\n accent rim; every other node stays on the hairline border. */}\n <Rect\n x={-pillW / 2}\n y={-pillH / 2}\n width={pillW}\n height={pillH}\n cornerRadius={pillH / 2}\n fill={surface}\n stroke={isActive ? accent : borderColor}\n strokeWidth={isActive ? 1.5 : 1}\n />\n <Text\n x={-labelW / 2}\n y={-satelliteFontSize / 2}\n fontSize={satelliteFontSize}\n color={textColor}\n fontFamily={fontFamily}\n fontWeight={600}\n letterSpacing={letterSpacing}\n >\n {applyTextCase(sat.label, { uppercase })}\n </Text>\n </Group>\n )\n })}\n\n {/* Central hub — a radial-gradient disc with an accent ring. Scales\n about its center: the Group marks the center, the Ellipse is offset\n by -radius so the local-origin scale reads centered (§3). */}\n <Group scaleX={hubScale} scaleY={hubScale} opacity={hubOpacity}>\n {/* Radial fill CONCENTRIC with the ellipse (and its stroke ring): the\n gradient is centred on the disc and its radius equals the disc\n radius, so the orb fills the ring symmetrically and fades at the rim\n exactly where the stroke sits. (A previous up-offset centre with too\n small a radius left the bottom of the disc transparent, so the orb\n bunched up-top and the ring hung below it.) A faint specular\n highlight just above centre keeps a hint of 3-D without breaking the\n concentric read. */}\n <Ellipse\n x={-hubRadius}\n y={-hubRadius}\n width={hubDiameter}\n height={hubDiameter}\n stroke={accent}\n strokeWidth={1}\n gradient={radialGradient([hubRadius, hubRadius], hubRadius, [\n { offset: 0, color: rgbHex(accent) },\n { offset: 0.72, color: surface },\n { offset: 1, color: transparent },\n ])}\n />\n <Ellipse\n x={-hubRadius * 0.62}\n y={-hubRadius * 0.78}\n width={hubRadius * 1.24}\n height={hubRadius * 1.0}\n opacity={0.5}\n gradient={radialGradient([hubRadius * 0.62, hubRadius * 0.5], hubRadius * 0.62, [\n { offset: 0, color: `${rgbHex(accent)}cc` },\n { offset: 1, color: transparent },\n ])}\n />\n {/* Center the hub label with a fixed-size Flex box over the disc so\n the ENGINE measures the glyphs and centers both axes (the explicit\n x/y estimate over/under-shoots narrow letters like \"I\" and ignores\n the text baseline, drifting the label off the orb). The box is a\n fixed hubDiameter square, so it never reflows as the hub scales. */}\n <Group x={-hubRadius} y={-hubRadius}>\n <Flex width={hubDiameter} height={hubDiameter} justify=\"center\" align=\"center\">\n <Text\n fontSize={hubFontSize}\n color={textColor}\n fontFamily={fontFamily}\n fontWeight={600}\n >\n {hubLabel}\n </Text>\n </Flex>\n </Group>\n </Group>\n </Group>\n </Group>\n )\n}\n\n/** Normalize a color to a 6-digit `#rrggbb` (drops any trailing alpha, expands\n * shorthand) so alpha suffixes can be appended deterministically. Unknown\n * formats fall through unchanged. */\nfunction rgbHex(color: string): string {\n if (!color.startsWith('#')) return color\n const hex = color.slice(1)\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}`\n }\n if (hex.length === 4) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}`\n }\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}`\n }\n return color\n}\n","//! Parallax — slow, linear drift of one or more image layers at different rates.\n//! Ported from ondajs.\n//!\n//! Backgrounds / b-roll that should feel alive without pulling focus. A lighter,\n//! no-zoom complement to KenBurns. Intentionally **linear** (no spring/ease): at\n//! a multi-second scale, acceleration would read as the camera moving — wrong for\n//! parallax, which is steady throughout.\n//!\n//! Multi-layer parallax: each layer drifts the shared `distance` scaled by its own\n//! `speed` multiplier, so backgrounds (low speed) trail foregrounds (high speed)\n//! and the scene gains depth. A single `src` is the degenerate one-layer case and\n//! matches the ondajs original.\n//!\n//! Approximations vs ondajs:\n//! - The engine's `<Image>` has no `width`/`height`/`object-fit`; it renders at\n//! the source's natural size. ondajs stretched the image to `100% cover`. Here\n//! each layer rides a `scale` (default 1.05, matching ondajs's oversize) applied\n//! about the LOCAL ORIGIN (0,0) — supply a source already roughly canvas-sized.\n//! Because scale pivots on (0,0), the layer is placed at (0,0) and the modest\n//! 1.05 oversize hides the drifting edges, as in the original.\n//! - ondajs's `overflow: hidden` becomes an outer `<Group clip={clipRect(...)}>`\n//! masking everything to the composition bounds, so the oversized/translated\n//! layers never bleed past the canvas.\n//! - ondajs's `placement` (canvas-fraction sub-region) is not modeled; this port\n//! always fills the composition, which is the original's default behavior.\n\nimport {\n Group,\n Image,\n clipRect,\n interpolate,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** One drifting image layer. */\nexport interface ParallaxLayer {\n /** Image URL/path (resolved at render time). */\n src: string\n /** Drift-rate multiplier vs the base `distance` (1 = full distance over the\n * duration). Lower = slower/further-back layer; higher = faster/closer. */\n speed?: number\n /** Per-layer oversize so the drift never exposes a canvas edge (default 1.05). */\n scale?: number\n /** Per-layer opacity, 0..1 (default 1). */\n opacity?: number\n}\n\nexport interface ParallaxProps {\n /** Single image layer. Use `src` OR `layers`; `layers` wins when both are set. */\n src?: string\n /** Multiple layers, drawn back-to-front, each drifting at its own `speed`. */\n layers?: ParallaxLayer[]\n /** Frames before the drift starts. */\n delay?: TimeInput\n /** Frames over which the drift completes (180f ≈ 6s @ 30fps — parallax wants time). */\n duration?: TimeInput\n /** The edge the layers drift *toward* as time advances. */\n direction?: 'left' | 'right' | 'up' | 'down'\n /** Base drift in pixels across `duration` (per-layer scaled by `speed`). Keep\n * restrained — past ~120px it reads as a pan, not parallax. */\n distance?: number\n /** Default oversize applied to layers that don't set their own `scale` (1.05). */\n scale?: number\n}\n\nexport function Parallax({\n src,\n layers,\n delay: delayIn = 0,\n duration: durationIn = 180,\n direction = 'left',\n distance = 40,\n scale = 1.05,\n}: ParallaxProps) {\n const frame = useCurrentFrame()\n const { width, height, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n\n // Resolve the layer list. `layers` takes precedence; otherwise fall back to the\n // single `src` (the ondajs one-layer case). An empty/absent config renders\n // nothing rather than throwing.\n const resolved: ParallaxLayer[] =\n layers && layers.length > 0 ? layers : src != null ? [{ src }] : []\n\n // Linear by design — constant drift, no acceleration. Clamp on both sides so\n // the component is correct on frame 0 and rests at the final offset afterward.\n const progress = interpolate(frame - delay, [0, duration], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // Axis + sign per direction. Left/up are negative translations; right/down\n // positive. Vertical/horizontal selected once for all layers.\n const isHorizontal = direction === 'left' || direction === 'right'\n const sign = direction === 'left' || direction === 'up' ? -1 : 1\n\n return (\n <Group clip={clipRect(width, height)}>\n {resolved.map((layer, i) => {\n const layerSpeed = layer.speed ?? 1\n const layerScale = layer.scale ?? scale\n const layerOpacity = layer.opacity ?? 1\n const offset = sign * progress * distance * layerSpeed\n const tx = isHorizontal ? offset : 0\n const ty = isHorizontal ? 0 : offset\n\n // Each layer is its own translated/scaled Group. The Image sits at the\n // group origin; scale pivots on (0,0), and the modest oversize hides the\n // edges the linear drift would otherwise reveal.\n return (\n <Group\n key={i}\n x={tx}\n y={ty}\n scaleX={layerScale}\n scaleY={layerScale}\n opacity={layerOpacity}\n >\n <Image src={layer.src} width={width} height={height} fit=\"cover\" />\n </Group>\n )\n })}\n </Group>\n )\n}\n","//! PathMorph — the \"magic move\": one SVG shape continuously morphing into another.\n//! CLOSED shapes (an emblem → a filled mark) are FILLED; OPEN paths (a line/curve\n//! motif → another) are STROKED. This matters: an open path that is FILLED\n//! auto-closes into a solid blob over your content (the #1 PathMorph misuse — a\n//! \"line motif\" rendered as a white lens), so a line is NEVER filled. For a line\n//! that simply DRAWS ON (no shape change) prefer `<DrawOn>`; reach for PathMorph\n//! when the line/shape itself MORPHS.\n//!\n//! Closed shapes morph via `@onda-engine/react`'s `morphPath` (flubber — point\n//! CORRESPONDENCE so the fill never tears). Open paths use a per-number lerp so the\n//! stroke stays OPEN (flubber re-closes its output into a ring). Feed two `d`\n//! strings in the SAME coordinate space; it animates the in-between over\n//! `durationInFrames` after `delay`, positioned/scaled by `x`/`y`/`scale`.\n//!\n//! Backend caveat: like `<Path>`, this renders on the Vello/GPU backend; the CPU\n//! reference degrades (no path fills).\nimport { Group, Path, interpolate, morphPath, useCurrentFrame } from '@onda-engine/react'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\n\n/** A path is CLOSED if it explicitly closes (`Z`/`z`); open paths are lines/curves. */\nfunction isClosedPath(d: string): boolean {\n return /[zZ]/.test(d)\n}\n\n/** Lerp two structurally-identical path `d` strings number-by-number (same command\n * letters in the same order) → a clean in-between that stays OPEN. Returns null\n * when the structures differ (the caller then falls back to flubber). */\nfunction lerpPathD(from: string, to: string, t: number): string | null {\n const tok = (d: string): string[] => d.match(/[a-zA-Z]|-?\\d*\\.?\\d+(?:e[-+]?\\d+)?/gi) ?? []\n const a = tok(from)\n const b = tok(to)\n if (a.length === 0 || a.length !== b.length) return null\n const out: string[] = []\n for (let i = 0; i < a.length; i++) {\n const ca = a[i] as string\n const cb = b[i] as string\n const na = Number(ca)\n const nb = Number(cb)\n if (Number.isNaN(na) || Number.isNaN(nb)) {\n if (ca !== cb) return null // command letters must line up\n out.push(ca)\n } else {\n out.push(String(na + (nb - na) * t))\n }\n }\n return out.join(' ')\n}\n\nexport interface PathMorphProps {\n /** SVG path `d` to morph FROM (e.g. a logo emblem, or a line), in its own space. */\n from: string\n /** SVG path `d` to morph TO (e.g. a divider, or another line), in the SAME space. */\n to: string\n /** Ink color (hex). FILL for closed shapes, STROKE for open lines. Defaults theme `text`. */\n color?: string\n /** Force STROKE (line) rendering. Auto-true when BOTH paths are OPEN (no `Z`). */\n stroke?: boolean\n /** Stroke width in path-coordinate units (when stroked). Default 4. */\n strokeWidth?: number\n /** Frames before the `from` shape appears. */\n delay?: number\n /** Frames to HOLD the `from` shape (recognizable) before the morph begins. */\n holdFrames?: number\n /** Frames the morph itself takes (default `DURATION.slow` = 24). */\n durationInFrames?: number\n /** Composition position of the morph's local origin. */\n x?: number\n y?: number\n /** Uniform scale of the path's coordinate space. */\n scale?: number\n /** Fade the shape in over the first 8 frames (default true). */\n fadeIn?: boolean\n}\n\nexport function PathMorph({\n from,\n to,\n color,\n stroke,\n strokeWidth = 4,\n delay = 0,\n durationInFrames,\n x = 0,\n y = 0,\n scale = 1,\n fadeIn = true,\n}: PathMorphProps) {\n const frame = useCurrentFrame()\n const theme = useTheme()\n const dur = durationInFrames ?? DURATION.slow\n const t = interpolate(frame, [delay, delay + dur], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n // A LINE motif (both paths open) STROKES; a SHAPE morph (closed) FILLS. Filling an\n // open path auto-closes it into a blob over the content — so we never do that.\n const asLine = stroke ?? (!isClosedPath(from) && !isClosedPath(to))\n // Open paths: a per-number lerp keeps the line OPEN (flubber would re-close its\n // output into a lens ring). Fall back to flubber when the structures differ.\n const d = asLine ? (lerpPathD(from, to, t) ?? morphPath(from, to, t)) : morphPath(from, to, t)\n const ink = color ?? theme.text\n const opacity = fadeIn\n ? interpolate(frame, [delay, delay + 8], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n : 1\n return (\n <Group x={x} y={y} opacity={opacity}>\n <Group scaleX={scale} scaleY={scale}>\n {asLine ? (\n <Path d={d} stroke={ink} strokeWidth={strokeWidth} strokeCap=\"round\" />\n ) : (\n <Path d={d} fill={ink} />\n )}\n </Group>\n </Group>\n )\n}\n","//! PieReveal — a pie/donut chart whose slices grow from 0. Each slice is a\n//! `<Path>` arc whose end angle sweeps from its start to its full extent on the\n//! house spring, staggered slice-to-slice. A donut hole is a center `<Ellipse>`\n//! filled with the background color. Ported from ondajs (`pie-reveal`).\n//!\n//! ondajs renders a single-arc ring by animating an SVG `stroke-dashoffset`. The\n//! engine has no stroke-dash draw-on, so this port expresses the reveal as the\n//! closest faithful primitive: a filled wedge `<Path>` per slice\n//! (\"M cx cy L x0 y0 A r r 0 largeArc 1 x1 y1 Z\") whose terminal angle animates.\n//! Arcs start at 12 o'clock and sweep clockwise; in the engine's y-down space a\n//! clockwise sweep is the SVG `sweep-flag=1`. The full 360° edge case (a single\n//! 100% slice) can't be one arc, so it is drawn as two half-sweeps.\n//!\n//! Layout: the chart has a FIXED footprint and the wedge geometry changes every\n//! frame, so nothing is laid out by `<Flex>` (which would reflow/jiggle). The\n//! disc is centered by computing its center from the composition size and all\n//! parts are placed with explicit x/y inside one `<Group>`.\n//!\n//! Backend caveat: `<Path>` (and gradients) render only on the Vello/GPU backend;\n//! the CPU reference rasterizer skips paths, so the wedges are a GPU-only effect.\n//! The donut hole `<Ellipse>` and center label do render on both backends.\n\nimport {\n Ellipse,\n Group,\n Path,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** One pie slice: a numeric weight and its color. */\nexport interface PieRevealSlice {\n /** Relative weight of the slice. The full circle is split proportionally. */\n value: number\n /** Slice fill color (hex `#rrggbb` / `#rrggbbaa`). */\n color: string\n /** Optional label, drawn just outside the ring at the slice's mid-angle when\n * {@link PieRevealProps.showLabel} is set. Also used for React keying. */\n label?: string\n}\n\nexport interface PieRevealProps extends TextStyleProps {\n /** Slices to render, drawn clockwise from 12 o'clock in array order. */\n data?: PieRevealSlice[]\n /** Outer radius of the pie, in px. */\n radius?: number\n /** Inner radius (donut hole) in px. `0` is a solid pie. The hole is filled\n * with {@link holeColor}, so set that to match the background. */\n innerRadius?: number\n /** Color filling the donut hole — match the composition background (default: theme `background`). */\n holeColor?: string\n /** Frames before the **first** slice starts sweeping. */\n delay?: TimeInput\n /** Per-slice sweep duration on the house spring. */\n duration?: TimeInput\n /** Frames between consecutive slices starting (default canonical `STAGGER`). */\n stagger?: TimeInput\n /** Horizontal center as a 0–1 fraction of canvas width. */\n x?: number\n /** Vertical center as a 0–1 fraction of canvas height. */\n y?: number\n /** Show labels: the center total (donut only) plus each slice's `label`\n * drawn just outside the ring. */\n showLabel?: boolean\n /** Center label text. Defaults to the slice count. */\n label?: string\n /** Center label color (default: theme `text`). */\n labelColor?: string\n /** Center label font size in px. */\n fontSize?: number\n}\n\nconst DEFAULT_DATA: PieRevealSlice[] = [\n { value: 64, color: '#d96b82', label: 'A' },\n { value: 22, color: '#8e8e98', label: 'B' },\n { value: 14, color: '#3a3a44', label: 'C' },\n]\n\n/** Build a filled-wedge SVG path from `cx,cy` sweeping clockwise between two\n * angles (radians, measured clockwise from 12 o'clock). Returns `''` for a\n * zero/negative sweep so the caller can skip rendering it. */\nfunction wedgePath(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n): string {\n const sweep = endAngle - startAngle\n if (sweep <= 0) return ''\n\n // 12 o'clock = angle 0. x = cx + r*sin(a), y = cy - r*cos(a): increasing the\n // angle rotates the point clockwise on screen (y-down), so SVG sweep-flag=1.\n const point = (a: number): [number, number] => [cx + r * Math.sin(a), cy - r * Math.cos(a)]\n\n // A single arc can't span a full circle (start would equal end). For a near-\n // full sweep, split into two arcs through an intermediate angle.\n if (sweep >= Math.PI * 2 - 1e-4) {\n const mid = startAngle + Math.PI\n const [x0, y0] = point(startAngle)\n const [xm, ym] = point(mid)\n return (\n `M ${cx} ${cy} L ${x0} ${y0} ` +\n `A ${r} ${r} 0 0 1 ${xm} ${ym} ` +\n `A ${r} ${r} 0 0 1 ${x0} ${y0} Z`\n )\n }\n\n const [x0, y0] = point(startAngle)\n const [x1, y1] = point(endAngle)\n const largeArc = sweep > Math.PI ? 1 : 0\n return `M ${cx} ${cy} L ${x0} ${y0} A ${r} ${r} 0 ${largeArc} 1 ${x1} ${y1} Z`\n}\n\nexport function PieReveal({\n data = DEFAULT_DATA,\n radius = 180,\n innerRadius = 0,\n holeColor: holeColorProp,\n delay: delayIn = 0,\n duration: durationIn = DURATION.slow,\n stagger: staggerIn = STAGGER,\n x = 0.5,\n y = 0.5,\n showLabel = false,\n label,\n labelColor: labelColorProp,\n fontSize = 56,\n fontFamily: fontFamilyProp,\n}: PieRevealProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const stagger = framesOf(staggerIn, fps)\n const theme = useTheme()\n const holeColor = holeColorProp ?? theme.background\n const labelColor = labelColorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n\n // Center the fixed-size disc by mapping the 0–1 fractions onto the canvas.\n const cx = x * width\n const cy = y * height\n\n // Total weight; guard against an empty/zero array so angles stay finite.\n const total = data.reduce((s, d) => s + Math.max(0, d.value), 0)\n\n // Precompute each slice's [startAngle, fullEndAngle] (radians, clockwise from\n // 12 o'clock) so the per-frame work is just the spring + path string.\n let cursor = 0\n const slices = data.map((d) => {\n const frac = total > 0 ? Math.max(0, d.value) / total : 0\n const startAngle = cursor\n const fullSweep = frac * Math.PI * 2\n cursor += fullSweep\n return {\n ...d,\n startAngle,\n fullEndAngle: startAngle + fullSweep,\n midAngle: startAngle + fullSweep / 2,\n }\n })\n\n // Clamp the donut hole to the disc; only draw it when it has area.\n const holeRadius = Math.max(0, Math.min(innerRadius, radius - 1))\n\n const centerText = label ?? `${data.length}`\n\n // Real shaped width of the center label, used to center it on the disc (the\n // engine draws from the text origin and has no centering). Falls back to a\n // glyph-count estimate until the wasm engine warms in the browser.\n const centerMetrics = useTextMetrics(centerText, fontSize, { fontFamily })\n\n // Per-slice labels sit just outside the ring, sized relative to the center\n // label. The engine has no text metrics, so width ≈ len * fontSize * 0.6.\n const sliceFontSize = Math.max(12, Math.round(fontSize * 0.32))\n const labelRadius = radius + sliceFontSize * 0.9\n\n return (\n <Group>\n {slices.map((s, i) => {\n const sliceDelay = delay + staggerFrames(i, stagger)\n const local = Math.max(0, frame - sliceDelay)\n\n // House spring (SPRING_SMOOTH, no overshoot) drives the sweep 0 → full.\n const progress = spring({\n frame: local,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: duration,\n })\n const clamped = Math.max(0, Math.min(1, progress))\n\n const endAngle = interpolate(clamped, [0, 1], [s.startAngle, s.fullEndAngle], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n const d = wedgePath(cx, cy, radius, s.startAngle, endAngle)\n if (!d) return null\n\n return <Path key={`${i}-${s.label ?? ''}`} d={d} fill={s.color} />\n })}\n\n {/* Donut hole — punched after the wedges, filled with the background. */}\n {holeRadius > 0 ? (\n <Ellipse\n x={cx - holeRadius}\n y={cy - holeRadius}\n width={holeRadius * 2}\n height={holeRadius * 2}\n fill={holeColor}\n />\n ) : null}\n\n {/* Center label (donut). Single-line; the engine draws from the text\n origin and has no centering, so offset by half the measured width. */}\n {showLabel && holeRadius > 0 ? (\n <Text\n x={cx - centerMetrics.width / 2}\n y={cy - fontSize / 2}\n fontSize={fontSize}\n color={labelColor}\n fontFamily={fontFamily}\n fontWeight={600}\n >\n {centerText}\n </Text>\n ) : null}\n\n {/* Per-slice labels, just outside the ring at each slice's mid-angle.\n Mid-angle is measured clockwise from 12 o'clock (same convention as\n the wedges): x = cx + r*sin(mid), y = cy - r*cos(mid). Each fades in\n with its slice's sweep. Centered by half the estimated text extent. */}\n {showLabel\n ? slices.map((s, i) => {\n if (!s.label) return null\n\n const sliceDelay = delay + staggerFrames(i, stagger)\n const local = Math.max(0, frame - sliceDelay)\n const progress = spring({\n frame: local,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: duration,\n })\n if (progress <= 0.01) return null\n\n const lx = cx + labelRadius * Math.sin(s.midAngle)\n const ly = cy - labelRadius * Math.cos(s.midAngle)\n return (\n <Text\n key={`label-${i}-${s.label}`}\n x={lx - s.label.length * sliceFontSize * 0.3}\n y={ly - sliceFontSize / 2}\n fontSize={sliceFontSize}\n color={labelColor}\n fontFamily={fontFamily}\n fontWeight={600}\n >\n {s.label}\n </Text>\n )\n })\n : null}\n </Group>\n )\n}\n","//! PriceTag — a compact, premium PRODUCT price chip for e-commerce shots: the\n//! product name set in the display face with the price emphasized beside it, in a\n//! rounded surface chip (hairline border + a soft shadow). DISTINCT from\n//! `PricingCard` (subscription tiers) — this is a small label/tag you drop next to\n//! or beneath a product photo, the single most-requested e-comm block.\n//!\n//! Layout: one tasteful row — the name on the left, a thin divider, the accent\n//! price on the right — sized to the measured text so the chip hugs its content\n//! (the engine measures the shaped widths; a glyph-count estimate stands in until\n//! the wasm engine warms). When `sold`, a small muted SOLD pill sits after the\n//! price and the price is dimmed + struck through.\n//!\n//! Motion: the chip fades + rises in on the house spring (no overshoot — restrained,\n//! premium). The whole chip is ONE unit (no clip — sidesteps the renderer's\n//! clip-occludes-later-siblings issue). Centered on the canvas by default; pass\n//! `x`/`y` for the chip's top-left to place it explicitly.\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\n/** Engine line-box height as a multiple of font size (matches typography crate). */\nconst LINE_RATIO = 1.2\n\nexport interface PriceTagProps extends TextStyleProps {\n /** Product name — the label, set in the display face. */\n name?: string\n /** Price as a string so any currency works (e.g. `'$70'`, `'€19'`, `'£12.50'`). */\n price?: string\n /** Show the SOLD state — dims + strikes the price and appends a muted pill. */\n sold?: boolean\n /** The SOLD pill label. */\n soldLabel?: string\n /** Frames before the chip enters. */\n delay?: number\n /** Base scale for the chip (1 = the default size). Scales type + padding together. */\n size?: number\n /** Price text color (default: theme `accent`). */\n priceColor?: string\n /** Divider + SOLD-pill accent color (default: theme `accent`). */\n accentColor?: string\n /** Chip fill color (default: theme `surface`). */\n surface?: string\n /** Chip hairline border color (default: theme `border`). */\n border?: string\n /** Body font for the price + SOLD pill (default: theme `fontFamily`). */\n bodyFamily?: string\n /** Local-space x of the chip's top-left. Omit to center on the composition. */\n x?: number\n /** Local-space y of the chip's top-left. Omit to center on the composition. */\n y?: number\n}\n\nexport function PriceTag({\n name = 'Product',\n price = '$0',\n sold = false,\n soldLabel = 'SOLD',\n delay = 0,\n size = 1,\n color: colorProp,\n priceColor: priceColorProp,\n accentColor: accentColorProp,\n surface: surfaceProp,\n border: borderProp,\n fontFamily: fontFamilyProp,\n bodyFamily: bodyFamilyProp,\n letterSpacing,\n uppercase,\n x,\n y,\n}: PriceTagProps) {\n const frame = useCurrentFrame()\n const { fps, width: W, height: H } = useVideoConfig()\n const theme = useTheme()\n\n const color = colorProp ?? theme.text\n const priceColor = priceColorProp ?? theme.accent\n const accent = accentColorProp ?? theme.accent\n const surface = surfaceProp ?? theme.surface\n const border = borderProp ?? theme.border\n const nameFont = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n const bodyFont = bodyFamilyProp ?? theme.fontFamily\n const nameText = applyTextCase(name, { uppercase })\n\n // ── Sizing (scaled by `size`) ──────────────────────────────────────────────\n const nameSize = Math.round(36 * size)\n const priceSize = Math.round(34 * size)\n const soldSize = Math.round(15 * size)\n const padX = Math.round(28 * size)\n const padY = Math.round(20 * size)\n const gap = Math.round(20 * size) // between name and divider/price\n const dividerW = Math.max(1, Math.round(1 * size))\n const soldGap = Math.round(14 * size)\n\n // ── Measured text widths (the chip hugs its content) ───────────────────────\n const nameMetrics = useTextMetrics(nameText, nameSize, { fontFamily: nameFont, fontWeight: 500 })\n const priceMetrics = useTextMetrics(price, priceSize, { fontFamily: bodyFont, fontWeight: 600 })\n const soldMetrics = useTextMetrics(soldLabel, soldSize, {\n fontFamily: bodyFont,\n fontWeight: 600,\n letterSpacing: soldSize * 0.12,\n })\n\n // SOLD pill geometry (letterspaced caps run wide — pad generously).\n const soldPadX = Math.round(12 * size)\n const soldTracking = soldSize * 0.12\n const soldTextW = soldMetrics.width + soldTracking\n const soldPillW = sold ? Math.round(soldTextW + soldPadX * 2) : 0\n const soldPillH = Math.round(soldSize * LINE_RATIO + 8 * size)\n\n // ── Chip geometry ──────────────────────────────────────────────────────────\n const contentW =\n nameMetrics.width + gap + dividerW + gap + priceMetrics.width + (sold ? soldGap + soldPillW : 0)\n const rowH = Math.max(nameSize, priceSize) * LINE_RATIO\n const chipW = Math.round(contentW + padX * 2)\n const chipH = Math.round(rowH + padY * 2)\n const radius = Math.min(theme.radius + 6, Math.round(chipH / 2))\n\n const originX = x ?? Math.round((W - chipW) / 2)\n const originY = y ?? Math.round((H - chipH) / 2)\n\n // ── Entrance: fade + small rise on the house spring ────────────────────────\n const enter = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n const opacity = interpolate(enter, [0, 1], [0, 1], CLAMP)\n const riseY = interpolate(enter, [0, 1], [16, 0], CLAMP)\n\n // ── Row cursor (within the padded content box) ─────────────────────────────\n const nameX = padX\n const dividerX = nameX + nameMetrics.width + gap\n const priceX = dividerX + dividerW + gap\n const soldX = priceX + priceMetrics.width + soldGap\n // Vertical centering of each text's line box inside the row.\n const nameY = padY + Math.round((rowH - nameSize * LINE_RATIO) / 2)\n const priceY = padY + Math.round((rowH - priceSize * LINE_RATIO) / 2)\n const dividerY = padY + Math.round((rowH - rowH * 0.62) / 2)\n const dividerH = Math.round(rowH * 0.62)\n const soldPillY = padY + Math.round((rowH - soldPillH) / 2)\n\n const soldColor = theme.textMuted\n const struckPrice = sold ? soldColor : priceColor\n\n return (\n <Group x={originX} y={originY + riseY} opacity={opacity}>\n {/* Chip surface — soft shadow, hairline border. */}\n <Rect\n width={chipW}\n height={chipH}\n cornerRadius={radius}\n fill={surface}\n stroke={border}\n strokeWidth={1}\n shadow={{ color: '#00000040', blur: 28, offsetX: 0, offsetY: 12 }}\n />\n\n {/* Product name (display face). */}\n <Text\n x={nameX}\n y={nameY}\n fontSize={nameSize}\n color={color}\n fontFamily={nameFont}\n fontWeight={500}\n letterSpacing={letterSpacing}\n >\n {nameText}\n </Text>\n\n {/* Thin accent divider between name and price. */}\n <Rect x={dividerX} y={dividerY} width={dividerW} height={dividerH} fill={accent} />\n\n {/* Price (body face, accent / bolder). Dimmed + struck when sold. */}\n <Text\n x={priceX}\n y={priceY}\n fontSize={priceSize}\n color={struckPrice}\n fontFamily={bodyFont}\n fontWeight={600}\n >\n {price}\n </Text>\n {sold ? (\n <Rect\n x={priceX}\n y={priceY + Math.round(priceSize * 0.52)}\n width={priceMetrics.width}\n height={Math.max(1, Math.round(2 * size))}\n fill={soldColor}\n />\n ) : null}\n\n {/* SOLD pill — muted outline after the price. */}\n {sold ? (\n <Group x={soldX} y={soldPillY}>\n <Rect\n width={soldPillW}\n height={soldPillH}\n cornerRadius={soldPillH / 2}\n fill=\"#00000000\"\n stroke={soldColor}\n strokeWidth={1}\n />\n <Text\n x={soldPadX}\n y={Math.round((soldPillH - soldSize * LINE_RATIO) / 2)}\n fontSize={soldSize}\n letterSpacing={soldTracking}\n color={soldColor}\n fontFamily={bodyFont}\n fontWeight={600}\n >\n {soldLabel}\n </Text>\n </Group>\n ) : null}\n </Group>\n )\n}\n","//! PricingCard — a single pricing tier: a rounded glass panel with the tier\n//! name, a large price + billing period, an accent-checkmark feature list that\n//! reveals on a stagger, and a CTA button. The whole card rises in on the house\n//! spring. `recommended` lifts + scales the card, shows an accent badge, and\n//! floats a soft accent glow behind it. Ported from ondajs (`pricing-card`).\n//!\n//! Scene-graph notes vs the ondajs (CSS) original:\n//! - ondajs is a CSS flex column inside a glass `Surface`; the scene graph has no\n//! JS-side text measurement, so the card is laid out by EXPLICIT pixel y-offsets\n//! inside a fixed-size `<Group>` (panel `width` × computed height) rather than a\n//! `<Flex>` — feature rows fade in per-frame, and a layout container would\n//! reflow/jiggle as each row's measured bbox appeared. The card is centered on\n//! the composition by computing its top-left offset (see `x`/`y` to override).\n//! - The entrance lift+scale for `recommended` is composed as a STATIC scale on\n//! the panel's own subtree. Scene scale pivots on the LOCAL ORIGIN, so the\n//! recommended scale is anchored to the card's top-left (a subtle top-anchored\n//! grow), not its center — close enough to the ondajs `scale(1.04)` for a\n//! single highlighted card; document if you nest differently.\n//! - Approximations: CSS `letter-spacing` + `text-transform: uppercase` on the\n//! tier label and badge — the engine has no letter-spacing, so the tier name is\n//! uppercased in JS and tracking is dropped. The recommended GLOW is a scene\n//! `radialGradient` (ondajs blurs a `Glow`); gradients render only on the\n//! Vello/GPU backend (CPU reference collapses to the first stop). The CTA label\n//! and the billing-period offset are centered/placed via real shaped text\n//! measurement (`useTextMetrics`); only the recommended badge pill still uses a\n//! glyph-count width estimate. The checkmark is a `<Path>`\n//! (GPU only) — on the CPU reference it simply won't paint.\n\nimport {\n Group,\n Path,\n Rect,\n Text,\n radialGradient,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryFade, entryFadeRise } from '../choreography.js'\nimport { DURATION, staggerFrames } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Engine line-box height as a multiple of font size (matches typography crate). */\nconst LINE_RATIO = 1.2\n\nexport interface PricingCardProps extends TextStyleProps {\n /** Tier name above the price (e.g. `'Pro'`). Rendered uppercase. */\n tier?: string\n /** The headline price, rendered large. Free-form: `'$29'`, `'€19'`, `'Free'`. */\n price?: string\n /** Billing period beneath the price (e.g. `'/month'`). Empty hides it. */\n period?: string\n /** Feature checklist — each item gets an accent checkmark, revealed on a stagger. */\n features?: string[]\n /** Call-to-action button label. */\n cta?: string\n /** Lifts + scales the card and shows an accent badge — the highlighted tier. */\n recommended?: boolean\n /** The earned accent — checkmarks, badge, CTA, recommended border + glow (default: theme `accent`). */\n accent?: string\n /** Frames before the card enters. */\n delay?: TimeInput\n /** Card width in px. */\n width?: number\n /** Price font size in px (the large display number). */\n priceSize?: number\n /** Panel fill color (default: theme `surface`). */\n background?: string\n /** Panel border color (when not `recommended`) (default: theme `border`). */\n borderColor?: string\n /** Dim color for the tier label (default: theme `textMuted`). */\n dimColor?: string\n /** Faint color for the billing period (default: theme `textMuted`). */\n faintColor?: string\n /** Body font for tier / features / CTA (default: theme `fontFamily`). */\n bodyFontFamily?: string\n /** Where the card sits: a region keyword (`'center'`, `'lower-third'`, …) or\n * normalized `{x,y}` (0–1, card center). The shared placement contract;\n * default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias — x of the card's top-left in px. Prefer\n * `placement`. */\n x?: number\n /** @deprecated Legacy alias — y of the card's top-left in px. Prefer\n * `placement`. */\n y?: number\n}\n\nconst DEFAULT_FEATURES = [\n 'Unlimited renders',\n 'Signature motion identity',\n 'Source you own, copied in',\n 'Priority support',\n]\n\nexport function PricingCard({\n tier = 'Pro',\n price = '$29',\n period = '/month',\n features = DEFAULT_FEATURES,\n cta = 'Get started',\n recommended = false,\n accent: accentProp,\n delay: delayIn = 0,\n width = 380,\n priceSize = 64,\n background: backgroundProp,\n borderColor: borderColorProp,\n color: colorProp,\n dimColor: dimColorProp,\n faintColor: faintColorProp,\n fontFamily: fontFamilyProp,\n bodyFontFamily: bodyFontFamilyProp,\n letterSpacing,\n uppercase,\n placement,\n x,\n y,\n}: PricingCardProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const accent = accentProp ?? theme.accent\n const background = backgroundProp ?? theme.surface\n const borderColor = borderColorProp ?? theme.border\n const color = colorProp ?? theme.text\n const dimColor = dimColorProp ?? theme.textMuted\n const faintColor = faintColorProp ?? theme.textMuted\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n const bodyFontFamily = bodyFontFamilyProp ?? theme.fontFamily\n const priceText = applyTextCase(price, { uppercase })\n\n // --- Layout constants (px) — the explicit column the engine layout pass\n // would otherwise produce, kept fixed so per-frame row fades don't reflow. ---\n const padding = 40\n const tierSize = 15\n const periodSize = 18\n const featureSize = 18\n const ctaSize = 17\n const checkBox = 18\n const checkGap = 12\n const sectionGap = 24\n const featureGap = 14\n const ctaHeight = 48\n const contentWidth = width - padding * 2\n\n // Real shaped text widths (proportional — exact) used to center the CTA label\n // and to offset the billing period after the price. The engine measures these;\n // they fall back to a glyph-count estimate until the wasm engine warms.\n const ctaMetrics = useTextMetrics(cta, ctaSize, { fontFamily: bodyFontFamily, fontWeight: 600 })\n const priceMetrics = useTextMetrics(priceText, priceSize, {\n fontFamily,\n fontWeight: 600,\n letterSpacing: letterSpacing ?? priceSize * -0.03,\n })\n\n // Vertical cursor through the card body, accumulating each section's height.\n const tierY = padding\n const priceY = tierY + tierSize * LINE_RATIO + sectionGap\n const featuresY = priceY + priceSize * LINE_RATIO + sectionGap\n const featureRow = featureSize * LINE_RATIO + featureGap\n const featuresHeight = features.length > 0 ? featureRow * features.length - featureGap : 0\n const ctaY = featuresY + featuresHeight + sectionGap\n const cardHeight = ctaY + ctaHeight + padding\n\n // The recommended tier sits a touch higher + larger — a STATIC lift composed\n // with the entrance, not an animation (matches ondajs `translateY(-16px) scale(1.04)`).\n const liftY = recommended ? -16 : 0\n const liftScale = recommended ? 1.04 : 1\n\n // Anchor the fixed-size card on the shared placement contract (card CENTER at\n // the resolved point; corner regions sit flush on the safe margin).\n // `placement` is authoritative when set; legacy px `x`/`y` only anchor in the\n // pre-placement path (else a stray `x:0.5` reads as 0.5 px → top-left).\n // Default: centered. (No layout container: per-frame feature fades never reflow.)\n const resolved = usePlacement(placement, { width, height: cardHeight })\n const useLegacy = placement === undefined\n const originX = useLegacy && x !== undefined ? x : Math.round(resolved.originX)\n const originY = useLegacy && y !== undefined ? y : Math.round(resolved.originY)\n\n // Entrance — opacity + rise on the house spring (ondajs `useEntrance('rise')`).\n const enter = entryFadeRise({ frame, fps, delay })\n\n const panelBorder = recommended ? accent : borderColor\n\n // CTA label centered via real shaped text measurement.\n const ctaTextWidth = ctaMetrics.width\n const ctaTextX = Math.round((contentWidth - ctaTextWidth) / 2)\n const ctaTextY = Math.round((ctaHeight - ctaSize * LINE_RATIO) / 2)\n\n // Recommended badge box (top-right) — estimated label width + horizontal padding.\n // Uppercase caps run noticeably wider than the body advance, so size the pill\n // with a deliberately wide glyph ratio and generous side padding to keep the\n // label clear of the rounded border (the trailing cap mustn't crowd the edge).\n const badgeLabel = 'RECOMMENDED'\n const badgeFontSize = 12\n const badgePadX = 16\n const badgeWidthRatio = 0.72\n // ondajs tracks the badge at 0.12em — widens it by tracking × (glyphs − 1).\n const badgeTracking = badgeFontSize * 0.12\n const badgeTextWidth =\n badgeLabel.length * badgeFontSize * badgeWidthRatio +\n badgeTracking * Math.max(0, badgeLabel.length - 1)\n const badgeWidth = Math.round(badgeTextWidth + badgePadX * 2)\n const badgeHeight = Math.round(badgeFontSize * LINE_RATIO + 8)\n\n return (\n <Group x={originX} y={originY} opacity={enter.opacity}>\n {/* Entrance rise + static recommended lift. Scale pivots on the local\n origin (top-left) — top-anchored grow for the highlighted card. */}\n <Group y={enter.y + liftY} scaleX={liftScale} scaleY={liftScale}>\n {/* Soft accent glow behind the recommended card (GPU only). Painted\n first so it sits beneath the panel; a canvas-local radial fading to\n transparent, centered near the card's top edge. */}\n {recommended ? (\n <Rect\n x={-width * 0.15}\n y={-cardHeight * 0.12}\n width={width * 1.3}\n height={cardHeight * 0.7}\n gradient={radialGradient([width / 2, cardHeight * 0.1], width * 0.65, [\n { offset: 0, color: withAlpha(accent, 0x38) },\n { offset: 1, color: withAlpha(accent, 0x00) },\n ])}\n />\n ) : null}\n\n {/* Glass panel. */}\n <Rect\n width={width}\n height={cardHeight}\n cornerRadius={theme.radius}\n fill={background}\n stroke={panelBorder}\n strokeWidth={recommended ? 2 : 1}\n />\n\n {/* --- Card body, inset by `padding`. --- */}\n <Group x={padding} y={0}>\n {/* Tier name (uppercased, ondajs `0.16em` tracking; left-aligned). */}\n <Text\n x={0}\n y={tierY}\n fontSize={tierSize}\n letterSpacing={tierSize * 0.16}\n color={dimColor}\n fontFamily={bodyFontFamily}\n fontWeight={600}\n >\n {tier.toUpperCase()}\n </Text>\n\n {/* Recommended badge — outlined pill in the top-right. */}\n {recommended ? (\n <Group x={contentWidth - badgeWidth} y={tierY - 6}>\n <Rect\n width={badgeWidth}\n height={badgeHeight}\n cornerRadius={badgeHeight / 2}\n fill=\"#00000000\"\n stroke={accent}\n strokeWidth={1}\n />\n <Text\n x={badgePadX}\n y={Math.round((badgeHeight - badgeFontSize * LINE_RATIO) / 2)}\n fontSize={badgeFontSize}\n letterSpacing={badgeTracking}\n color={accent}\n fontFamily={bodyFontFamily}\n fontWeight={600}\n >\n {badgeLabel}\n </Text>\n </Group>\n ) : null}\n\n {/* Price (large display, ondajs `-0.03em`) + billing period; left-aligned,\n billing offset uses priceMetrics which now folds in the tracking. */}\n <Text\n x={0}\n y={priceY}\n fontSize={priceSize}\n letterSpacing={letterSpacing ?? priceSize * -0.03}\n color={color}\n fontFamily={fontFamily}\n fontWeight={600}\n >\n {priceText}\n </Text>\n {period ? (\n <Text\n x={Math.round(priceMetrics.width + 8)}\n y={Math.round(priceY + (priceSize - periodSize) * 0.9)}\n fontSize={periodSize}\n color={faintColor}\n fontFamily={bodyFontFamily}\n fontWeight={500}\n >\n {period}\n </Text>\n ) : null}\n\n {/* Feature checklist — accent checkmarks, each row fades in on a stagger.\n Opacity-only motion (layout-safe; rows are explicitly y-positioned). */}\n {features.map((feature, i) => {\n const rowDelay = delay + staggerFrames(i + 2)\n const { opacity } = entryFade({\n frame,\n fps,\n delay: rowDelay,\n durationInFrames: DURATION.base,\n })\n const rowY = featuresY + featureRow * i\n return (\n <Group key={`${i}-${feature}`} y={rowY} opacity={opacity}>\n {/* Accent checkmark (GPU-only Path). Drawn within an 18×18 box,\n nudged down to sit on the text's optical center. */}\n <Group y={3}>\n <Path\n d={`M ${checkBox * 0.22} ${checkBox * 0.53} L ${checkBox * 0.4} ${\n checkBox * 0.69\n } L ${checkBox * 0.78} ${checkBox * 0.31}`}\n fill=\"#00000000\"\n stroke={accent}\n strokeWidth={2}\n strokeCap=\"round\"\n strokeJoin=\"round\"\n />\n </Group>\n <Text\n x={checkBox + checkGap}\n y={0}\n fontSize={featureSize}\n letterSpacing={featureSize * 0.01}\n color={color}\n fontFamily={bodyFontFamily}\n fontWeight={400}\n >\n {feature}\n </Text>\n </Group>\n )\n })}\n\n {/* CTA button — filled accent when recommended, else an outline. */}\n <Group y={ctaY}>\n <Rect\n width={contentWidth}\n height={ctaHeight}\n cornerRadius={theme.radius}\n fill={recommended ? accent : '#00000000'}\n stroke={recommended ? accent : borderColor}\n strokeWidth={1}\n />\n <Text\n x={ctaTextX}\n y={ctaTextY}\n fontSize={ctaSize}\n color={recommended ? '#08080a' : color}\n fontFamily={bodyFontFamily}\n fontWeight={600}\n >\n {cta}\n </Text>\n </Group>\n </Group>\n </Group>\n </Group>\n )\n}\n\n/** Return `color` (`#rrggbb` / `#rrggbbaa` / `#rgb`) with its alpha channel set to\n * the given byte (0..255), preserving RGB so a gradient fades the accent rather\n * than toward black. Falls back to the input unchanged on an unknown format. */\nfunction withAlpha(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(255, Math.round(alpha)))\n .toString(16)\n .padStart(2, '0')\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}${a}`\n }\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}${a}`\n }\n }\n return color\n}\n","//! ProductWall — a bento grid of product photos under a slow camera move: the\n//! \"behold the whole collection\" beat. It reuses the BentoGrid auto-flow packer\n//! (colSpan/rowSpan → centered pixel rects) but fills each cell with an\n//! `<Image fit=\"cover\">`, which crops to its OWN box — so NO per-tile clip Group\n//! is needed, sidestepping the renderer's clip-occludes-later-siblings issue that\n//! KenBurns documents. Tiles stagger in (rise + fade) like BentoGrid, then the\n//! whole wall is pushed + drifted by a KenBurns-style center-pivot camera so it\n//! reads as a gentle dolly across the products, not a static contact sheet.\n//!\n//! Backend: `<Image>` renders on both backends and the camera/entrance are plain\n//! transforms — no GPU-only features, so it degrades cleanly.\n\nimport {\n Group,\n Image,\n Rect,\n interpolate,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useStaggeredEntrance } from '../hooks.js'\nimport { STAGGER } from '../motion.js'\nimport { useTheme } from '../theme.js'\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport interface ProductWallProps {\n /** Product photo sources (resolved at render time by `onda render`). */\n images?: string[]\n /** Per-image `[colSpan, rowSpan]` for the bento rhythm; cycled if shorter than\n * `images`. Omit for a uniform 1×1 grid. */\n spans?: Array<[number, number]>\n /** Grid columns (default 4). */\n columns?: number\n /** Gap between tiles in px (default 16). */\n gap?: number\n /** Overall grid width in px (default 1680). */\n width?: number\n /** Row-track height in px. Defaults to the column-track width (≈ square tiles). */\n rowHeight?: number\n /** Frames before the first tile enters (default 0). */\n delay?: number\n /** Frames between successive tiles rising in (default `STAGGER` = 4). */\n stagger?: number\n /** Tile hairline border color (default: theme `border`). */\n borderColor?: string\n /** Tile hairline border width in px (default 0 = no border). */\n borderWidth?: number\n /** Optional dark veil over every tile, 0..1, to unify a mixed set (default 0). */\n scrim?: number\n /** Camera scale at the start of the move (default 1.06). */\n cameraFrom?: number\n /** Camera scale at the end — keep the delta gentle (default 1.18). */\n cameraTo?: number\n /** Horizontal camera drift in px across the move (default -44). */\n cameraDriftX?: number\n /** Vertical camera drift in px across the move (default 26). */\n cameraDriftY?: number\n /** Frames over which the camera completes its push + drift (default 150). */\n cameraDurationInFrames?: number\n}\n\ntype Cell = { x: number; y: number; w: number; h: number; index: number }\n\n/** Slim CSS `grid-auto-flow: row` packer: place each item at the first free\n * colSpan-wide, rowSpan-tall run, scanning rows top-to-bottom. (See BentoGrid\n * for the fully-commented version — this is the same algorithm, geometry-only.) */\nfunction pack(\n spans: Array<[number, number]>,\n columns: number,\n colW: number,\n rowH: number,\n gap: number,\n): { cells: Cell[]; rows: number } {\n const occ: boolean[][] = []\n const ensure = (r: number) => {\n while (occ.length <= r) occ.push(new Array<boolean>(columns).fill(false))\n }\n const cells: Cell[] = []\n let cr = 0\n let cc = 0\n spans.forEach(([csRaw, rsRaw], index) => {\n const cs = Math.max(1, Math.min(csRaw, columns))\n const rs = Math.max(1, rsRaw)\n let pr = cr\n let pc = cc\n let found = false\n while (!found) {\n ensure(pr + rs - 1)\n if (pc + cs <= columns) {\n let free = true\n for (let dr = 0; dr < rs && free; dr++) {\n const row = occ[pr + dr] ?? []\n for (let dc = 0; dc < cs; dc++) {\n if (row[pc + dc]) {\n free = false\n break\n }\n }\n }\n if (free) {\n found = true\n break\n }\n }\n pc += 1\n if (pc + cs > columns) {\n pc = 0\n pr += 1\n }\n }\n for (let dr = 0; dr < rs; dr++) {\n ensure(pr + dr)\n const row = occ[pr + dr]\n if (row) for (let dc = 0; dc < cs; dc++) row[pc + dc] = true\n }\n cells.push({\n index,\n x: pc * (colW + gap),\n y: pr * (rowH + gap),\n w: cs * colW + (cs - 1) * gap,\n h: rs * rowH + (rs - 1) * gap,\n })\n cr = pr\n cc = pc + cs\n if (cc >= columns) {\n cc = 0\n cr = pr + 1\n }\n })\n return { cells, rows: occ.length }\n}\n\nexport function ProductWall({\n images = [],\n spans,\n columns = 4,\n gap = 16,\n width = 1680,\n rowHeight,\n delay = 0,\n stagger = STAGGER,\n borderColor,\n borderWidth = 0,\n scrim = 0,\n cameraFrom = 1.06,\n cameraTo = 1.18,\n cameraDriftX = -44,\n cameraDriftY = 26,\n cameraDurationInFrames = 150,\n}: ProductWallProps) {\n const frame = useCurrentFrame()\n const { width: canvasW, height: canvasH } = useVideoConfig()\n const theme = useTheme()\n const at = useStaggeredEntrance({ type: 'rise', delay, increment: stagger })\n\n const cols = Math.max(1, Math.round(columns))\n const colW = (width - (cols - 1) * gap) / cols\n const rowH = rowHeight ?? colW\n\n // One [colSpan, rowSpan] per image (cycled), default uniform 1×1.\n const spanList: Array<[number, number]> = images.map((_, i) =>\n spans && spans.length > 0 ? (spans[i % spans.length] as [number, number]) : [1, 1],\n )\n const { cells, rows } = pack(spanList, cols, colW, rowH, gap)\n\n const gridW = cells.length > 0 ? Math.max(...cells.map((c) => c.x + c.w)) : width\n const gridH = rows > 0 ? rows * rowH + (rows - 1) * gap : 0\n const originX = Math.round((canvasW - gridW) / 2)\n const originY = Math.round((canvasH - gridH) / 2)\n\n // KenBurns-style camera: linear push + diagonal drift, scaled about the canvas\n // center (engine scale pivots on local origin → translate-in / scale / back).\n const span = cameraDurationInFrames > 0 ? cameraDurationInFrames : 1\n const p = interpolate(frame - delay, [0, span], [0, 1], CLAMP)\n const scale = interpolate(p, [0, 1], [cameraFrom, cameraTo], CLAMP)\n const driftX = interpolate(p, [0, 1], [0, cameraDriftX], CLAMP)\n const driftY = interpolate(p, [0, 1], [0, cameraDriftY], CLAMP)\n const cx = canvasW / 2\n const cy = canvasH / 2\n\n const border = borderColor ?? theme.border\n\n return (\n <Group x={cx + driftX} y={cy + driftY}>\n <Group scaleX={scale} scaleY={scale}>\n <Group x={-cx} y={-cy}>\n <Group x={originX} y={originY}>\n {cells.map((cell) => {\n const e = at(cell.index)\n const src = images[cell.index]\n if (!src) return null\n return (\n <Group key={cell.index} x={cell.x} y={cell.y}>\n {/* Inner Group carries the entrance (opacity + rise) — safe over\n siblings (opacity, not clip; the BentoGrid pattern). */}\n <Group y={e.y} opacity={e.opacity}>\n {/* `fit=\"cover\"` crops the photo to this w×h box, so the tile\n never bleeds into its neighbors — no clip Group required. */}\n <Image src={src} width={cell.w} height={cell.h} fit=\"cover\" />\n {scrim > 0 ? (\n <Rect width={cell.w} height={cell.h} fill=\"#000000\" opacity={scrim} />\n ) : null}\n {borderWidth > 0 ? (\n <Rect\n width={cell.w}\n height={cell.h}\n fill=\"#00000000\"\n stroke={border}\n strokeWidth={borderWidth}\n />\n ) : null}\n </Group>\n </Group>\n )\n })}\n </Group>\n </Group>\n </Group>\n </Group>\n )\n}\n","//! ProgressBar — a horizontal bar that fills from 0 to `value`% on the house\n//! spring. A muted rounded track <Rect> with an accent fill <Rect> on top whose\n//! width grows with the spring. Optional `${value}%` label sits to the right.\n//! Ported from ondajs.\n//!\n//! The track + fill + label are laid out by hand inside ONE `<Group>` (NOT a\n//! `<Flex>`/`<AbsoluteFill>`): the fill's width animates every frame, and the\n//! engine layout pass overwrites a direct child's x/y — so a layout container\n//! cannot hold a hand-positioned animated subtree (and would also clobber any\n//! offset translate on it). The assembly is centered by computing its top-left\n//! origin directly from the composition size (same approach as `BarChart`).\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface ProgressBarProps extends TextStyleProps {\n /** Target fill, 0–100. The bar grows from 0 to this value. */\n value?: number\n /** Frames before the animation starts. */\n delay?: TimeInput\n /** Frames to reach the full target value (default `DURATION.slow` = 24). */\n duration?: TimeInput\n /** Track width in px — the full 0%→100% travel. */\n width?: number\n /** Bar thickness in px. */\n height?: number\n /** Corner radius in px. Defaults to a full pill. */\n radius?: number\n /** Track color — the unfilled portion (default: theme `surface`). */\n trackColor?: string\n /** Fill color (default: theme `accent`). */\n accentColor?: string\n /** Whether to render the `${value}%` label beside the bar. */\n showValue?: boolean\n /** Label font size in px. */\n fontSize?: number\n}\n\nexport function ProgressBar({\n value = 64,\n delay: delayIn = 0,\n duration: durationIn = DURATION.slow,\n width = 640,\n height = 12,\n radius = 999,\n trackColor: trackColorProp,\n accentColor: accentColorProp,\n showValue = true,\n color: colorProp,\n fontSize = 28,\n fontFamily: fontFamilyProp,\n}: ProgressBarProps) {\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const theme = useTheme()\n const trackColor = trackColorProp ?? theme.surface\n const accentColor = accentColorProp ?? theme.accent\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n const progress = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: duration,\n })\n\n // Clamp the target so an out-of-range `value` never overflows the track.\n const targetPct = Math.max(0, Math.min(100, value))\n const fillPct = interpolate(progress, [0, 1], [0, targetPct], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n const fillWidth = (width * fillPct) / 100\n // Engine shapes have no overflow-clip, so a full-pill radius on a thin sliver\n // of fill would bulge into a lens. Cap the fill's radius at half its own\n // width (and half its height) so it stays a clean rounded sliver as it grows.\n const trackRadius = Math.min(radius, height / 2)\n const fillRadius = Math.min(radius, height / 2, fillWidth / 2)\n\n // Gap between the track's right edge and the label.\n const labelGap = 24\n // Settled label text (does not count up — matches ondajs).\n const labelText = `${Math.round(targetPct)}%`\n // Real shaped label width so the whole assembly centers. The engine measures\n // it (proportional — exact); this only positions the centered origin, not the\n // glyphs. Hook is called unconditionally; `showValue` only gates inclusion.\n const measuredLabel = useTextMetrics(labelText, fontSize, { fontFamily, fontWeight: 500 })\n const labelWidth = showValue ? labelGap + measuredLabel.width : 0\n\n // Center the fixed-size assembly by computing its top-left offset directly —\n // no layout container, so the per-frame fill-width growth never reflows and\n // no offset translate gets clobbered by the layout pass (see BarChart).\n //\n // The track is the dominant visual mass; the `${value}%` label is a light\n // accent reserved only on the right. Centering the full bounding box (track +\n // label) would over-weight that one-sided label and shove the heavy track\n // left of frame-center. Instead center the *visual center-of-mass*: reserve\n // only half the label width on the right so the track reads centered while the\n // label is still accounted for and never runs off-frame.\n const centeringWidth = width + labelWidth / 2\n // The label (font box height ≈ fontSize) can be taller than the track and is\n // vertically centered on it; the assembly's visual height is the taller one.\n const assemblyHeight = Math.max(height, fontSize)\n const originX = Math.round((compWidth - centeringWidth) / 2)\n const originY = Math.round((compHeight - assemblyHeight) / 2)\n // Track's own top within the assembly (centered against the taller label box).\n const trackY = Math.round((assemblyHeight - height) / 2)\n\n return (\n <Group x={originX} y={originY}>\n <Rect\n x={0}\n y={trackY}\n width={width}\n height={height}\n cornerRadius={trackRadius}\n fill={trackColor}\n />\n {fillWidth > 0 ? (\n <Rect\n x={0}\n y={trackY}\n width={fillWidth}\n height={height}\n cornerRadius={fillRadius}\n fill={accentColor}\n />\n ) : null}\n {showValue ? (\n <Text\n x={width + labelGap}\n y={Math.round((assemblyHeight - fontSize) / 2)}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={500}\n >\n {labelText}\n </Text>\n ) : null}\n </Group>\n )\n}\n","//! ProgressSteps — a horizontal stepper whose fill travels to the `current` step\n//! on the house spring. Completed dots and the connecting track earn the accent;\n//! pending steps stay neutral. The active step gets a soft glow ring. Ported from\n//! ondajs (`progress-steps`).\n//!\n//! Geometry is FIXED and laid out by explicit x/y inside a single centered\n//! `<Group>` — NOT a `<Flex>`. The connector \"fill\" grows left-to-right every\n//! frame (an animated width), so a layout container would reflow/jiggle as the\n//! measured bbox changed (same reasoning as BarChart). Dots are equal-spaced\n//! across `width`; each connector is the gap between adjacent dots.\n//!\n//! Scene caveats / approximations vs ondajs:\n//! - color-mix: ondajs blends the dot color with CSS `color-mix(in srgb, accent\n//! on%, dim)`. The engine has no color-mix, so the dot color is computed by a\n//! straight sRGB hex lerp between `dimColor` and `accentColor` by `on` — a\n//! close visual match (gamma differences aside).\n//! - box-shadow glow: ondajs draws the active-step glow with a CSS `box-shadow`\n//! blur, which the engine can't do. It is approximated by a larger, low-alpha\n//! accent `<Ellipse>` drawn UNDER the active dot (a hard-edged halo, not a\n//! blurred one). It scales about its own center via a scaled `<Group>` placed\n//! AT the dot center (scene scale pivots on the Group's local origin), with the\n//! ellipse offset by -r so it stays concentric with the dot at every scale.\n\nimport { Ellipse, Group, Rect, Text, interpolate, useVideoConfig } from '@onda-engine/react'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface ProgressStepsProps extends TextStyleProps {\n /** Step labels, left to right. */\n steps?: string[]\n /** How many steps are complete — the fill animates to this index (0-based count). */\n current?: number\n /** Frames before the fill animates. */\n delay?: TimeInput\n /** Frames for the fill to travel to `current`. */\n duration?: TimeInput\n /** Completed / active color — the earned accent (Onda rose) (default: theme `accent`). */\n accentColor?: string\n /** Pending color (dots + connector track) (default: theme `border`). */\n dimColor?: string\n /** Label color (default: theme `textMuted`). */\n labelColor?: string\n /** Label font size in px. */\n fontSize?: number\n /** Overall width in px (dots are spaced across this). */\n width?: number\n /** Dot diameter in px. */\n dotSize?: number\n /** Connector track thickness in px. */\n trackThickness?: number\n}\n\nconst DEFAULT_STEPS = ['Plan', 'Build', 'Render', 'Ship']\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport function ProgressSteps({\n steps = DEFAULT_STEPS,\n current = 2,\n delay = 0,\n duration = DURATION.slower,\n accentColor: accentColorProp,\n dimColor: dimColorProp,\n labelColor: labelColorProp,\n fontFamily: fontFamilyProp,\n fontSize = 34,\n width = 1280,\n dotSize = 30,\n trackThickness = 3,\n}: ProgressStepsProps) {\n const { width: compWidth, height: compHeight } = useVideoConfig()\n const theme = useTheme()\n const accentColor = accentColorProp ?? theme.accent\n const dimColor = dimColorProp ?? theme.border\n const labelColor = labelColorProp ?? theme.textMuted\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // House spring (SPRING_SMOOTH, no overshoot), matching ondajs's useSpringValue.\n const p = useSpringValue({ delay, durationInFrames: duration })\n const filled = p * current // 0..current, animated\n\n const n = steps.length\n const radius = dotSize / 2\n\n // Equal-spaced dot centers across `width`: first dot center at radius, last at\n // width - radius. With a single step the dot sits at the left (matches a row).\n const stepX = (i: number): number => {\n if (n <= 1) return radius\n return radius + (i * (width - dotSize)) / (n - 1)\n }\n\n // Label band sits below the dots; reserve room for one text line plus the\n // active-step halo, which scales out to ~2.4× the dot radius (see `glowScale`),\n // so the label clears the glow rather than colliding with it.\n const labelTop = dotSize + radius * 1.4 + 18\n const rowHeight = labelTop + fontSize\n\n // Center the fixed-size stepper on the composition by computing its top-left\n // directly — no layout container, so the per-frame connector growth never\n // triggers a reflow.\n const originX = Math.round((compWidth - width) / 2)\n const originY = Math.round((compHeight - rowHeight) / 2)\n\n return (\n <Group x={originX} y={originY}>\n {/* Connectors first, so the dots paint over their ends. */}\n {steps.map((_, i) => {\n if (i >= n - 1) return null\n const x0 = stepX(i) + radius // right edge of dot i\n const x1 = stepX(i + 1) - radius // left edge of dot i+1\n const segWidth = Math.max(0, x1 - x0)\n if (segWidth <= 0) return null\n\n const connector = interpolate(filled, [i, i + 1], [0, 1], CLAMP)\n const fillWidth = segWidth * Math.max(0, Math.min(1, connector))\n const trackY = radius - trackThickness / 2\n\n return (\n <Group key={`seg-${i}`} y={trackY}>\n {/* Dim track. */}\n <Rect x={x0} y={0} width={segWidth} height={trackThickness} fill={dimColor} />\n {/* Accent fill grown left-to-right from the track's left end. */}\n {fillWidth > 0 ? (\n <Rect x={x0} y={0} width={fillWidth} height={trackThickness} fill={accentColor} />\n ) : null}\n </Group>\n )\n })}\n\n {/* Dots + labels. */}\n {steps.map((label, i) => {\n const on = interpolate(filled, [i - 0.5, i], [0, 1], CLAMP)\n const cx = stepX(i)\n const cy = radius\n const dotColor = mixHex(dimColor, accentColor, on)\n\n // Glow approximation: a low-alpha accent halo under the active dot,\n // appearing past 60% activation and scaling up as `on` climbs. Centered\n // on the dot via a nested origin at the dot center (scale pivots on the\n // local origin).\n const glow = Math.max(0, (on - 0.6) / 0.4) // 0..1 once on > 0.6\n const glowScale = 1 + glow * 1.4\n const glowAlpha = glow * 0.35\n const glowColor = withAlpha(accentColor, glowAlpha)\n\n // Label opacity: 0.5 → 1.0 as the step activates (ondajs `0.5 + on*0.5`).\n const labelOpacity = 0.5 + on * 0.5\n\n return (\n <Group key={`step-${i}`}>\n {/* Dot center as the local origin so the halo scales about its middle. */}\n <Group x={cx} y={cy}>\n {/* Halo: a scaled Group sits AT the dot center so the scale pivots\n on (0,0) = the center; the ellipse inside is offset to -r,-r so\n it stays concentric with the dot at every scale. Scaling the\n Ellipse directly would pivot on its top-left and drift the halo\n down-right. */}\n {glowAlpha > 0.001 ? (\n <Group scaleX={glowScale} scaleY={glowScale}>\n <Ellipse\n x={-radius}\n y={-radius}\n width={dotSize}\n height={dotSize}\n fill={glowColor}\n />\n </Group>\n ) : null}\n <Ellipse x={-radius} y={-radius} width={dotSize} height={dotSize} fill={dotColor} />\n </Group>\n\n {/* Label beneath the dot. The engine measures text from its own\n left origin (no center-align), so labels read left-aligned at\n each dot's left edge — see approximations. */}\n <Text\n x={cx - radius}\n y={labelTop}\n fontSize={fontSize}\n color={labelColor}\n fontFamily={fontFamily}\n opacity={labelOpacity}\n >\n {label}\n </Text>\n </Group>\n )\n })}\n </Group>\n )\n}\n\n/** Parse a `#rgb` / `#rrggbb` / `#rrggbbaa` hex into [r, g, b] (0..255). Alpha is\n * dropped. Returns black for unrecognized input. */\nfunction parseRgb(color: string): [number, number, number] {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return [hx(`${r}${r}`), hx(`${g}${g}`), hx(`${b}${b}`)]\n }\n if (hex.length === 6 || hex.length === 8) {\n return [hx(hex.slice(0, 2)), hx(hex.slice(2, 4)), hx(hex.slice(4, 6))]\n }\n }\n return [0, 0, 0]\n}\n\n/** Parse a 2-char hex byte to 0..255, defaulting to 0. */\nfunction hx(byte: string): number {\n const v = Number.parseInt(byte, 16)\n return Number.isNaN(v) ? 0 : v\n}\n\n/** Two-digit hex for a 0..255 channel. */\nfunction toHexByte(v: number): string {\n const c = Math.max(0, Math.min(255, Math.round(v)))\n return c.toString(16).padStart(2, '0')\n}\n\n/** Straight sRGB lerp between two hex colors by `t` (0 = `a`, 1 = `b`). The\n * engine has no `color-mix`; this is the closest faithful approximation. */\nfunction mixHex(a: string, b: string, t: number): string {\n const k = Math.max(0, Math.min(1, t))\n const [ar, ag, ab] = parseRgb(a)\n const [br, bg, bb] = parseRgb(b)\n const r = ar + (br - ar) * k\n const g = ag + (bg - ag) * k\n const bl = ab + (bb - ab) * k\n return `#${toHexByte(r)}${toHexByte(g)}${toHexByte(bl)}`\n}\n\n/** Return `color`'s RGB with the given alpha (0..1) as `#rrggbbaa`. */\nfunction withAlpha(color: string, alpha: number): string {\n const [r, g, b] = parseRgb(color)\n const a = Math.max(0, Math.min(1, alpha)) * 255\n return `#${toHexByte(r)}${toHexByte(g)}${toHexByte(b)}${toHexByte(a)}`\n}\n","//! PulsingIndicator — a live status dot with a calm expanding-ring pulse, plus an\n//! optional label. Ported from ondajs.\n//!\n//! The pulse is keyed off `frame % period`, so it loops seamlessly and is a pure\n//! function of frame (no timers): the halo ring scales 1 → 2.6 while fading\n//! 0.5 → 0, over a solid core dot.\n//!\n//! Layout note: the ring's *scale* animates each frame. Scene scale pivots on\n//! the node's local origin (0,0), so the scale lives on a `<Group>` placed at\n//! the dot's center, with the ring `<Ellipse>` offset by `-size/2` inside it —\n//! that way the halo grows symmetrically and stays concentric with the core\n//! dot. With no explicit x/y, the dot + label assembly is centered on the\n//! composition. Everything is positioned with explicit x/y (not `<Flex>`) so the\n//! per-frame size change of the ring can't make a layout container reflow/jiggle.\n\nimport {\n Ellipse,\n Group,\n Text,\n interpolate,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { useTextMetrics } from '../text-metrics.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\n\nexport interface PulsingIndicatorProps extends TextStyleProps {\n /** Dot + ring color (default: theme `accent`). Note: this is the dot/ring fill,\n * not the label text color — set the label color via `labelColor`. */\n color?: string\n /** Dot diameter in px. */\n size?: number\n /** Optional label to the right of the dot. Empty hides it. */\n label?: string\n /** Label color (default: theme `textMuted`). */\n labelColor?: string\n /** Label font size in px. */\n fontSize?: number\n /** Frames per pulse cycle. */\n period?: number\n /**\n * Placement of the indicator's top-left (the dot's bounding box). When\n * omitted, the dot + label assembly is centered on the composition.\n */\n x?: number\n y?: number\n}\n\nexport function PulsingIndicator({\n color: colorProp,\n size = 20,\n label = 'LIVE',\n labelColor: labelColorProp,\n fontFamily: fontFamilyProp,\n letterSpacing,\n fontSize = 28,\n period = 45,\n x: xProp,\n y: yProp,\n}: PulsingIndicatorProps) {\n const frame = useCurrentFrame()\n const theme = useTheme()\n const { width, height } = useVideoConfig()\n const color = colorProp ?? theme.accent\n const labelColor = labelColorProp ?? theme.textMuted\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n const safePeriod = Math.max(1, period)\n // Normalized 0..1 phase within the cycle; the modulo keeps it seamless and\n // handles negative frames (e.g. inside a delayed Sequence).\n const t = (((frame % safePeriod) + safePeriod) % safePeriod) / safePeriod\n const ringScale = interpolate(t, [0, 1], [1, 2.6])\n const ringOpacity = interpolate(t, [0, 1], [0.5, 0])\n\n const radius = size / 2\n // Gap between the dot and the label, mirroring ondajs (size * 0.7).\n const labelGap = size * 0.7\n // ondajs uppercases the label via CSS `text-transform`; the engine has no\n // text-transform, so uppercase here.\n const labelText = label ? label.toUpperCase() : ''\n\n // Real shaped label width (the engine measures it — proportional, exact;\n // falls back to a glyph-count estimate until the wasm engine warms in the\n // browser). The width sizes the whole assembly (dot + gap + label) so we can\n // center it when no explicit x/y is given. The default = centered on the\n // composition.\n const measuredLabel = useTextMetrics(labelText, fontSize, { fontFamily })\n const labelWidth = labelText ? measuredLabel.width : 0\n const assemblyWidth = size + (labelText ? labelGap + labelWidth : 0)\n const x = xProp ?? (width - assemblyWidth) / 2\n const y = yProp ?? (height - size) / 2\n\n return (\n <Group x={x} y={y}>\n {/* Origin at the dot's center, so the ring scales about its middle. */}\n <Group x={radius} y={radius}>\n {/* Expanding halo ring — scales + fades about the dot center. The scale\n lives on this Group (pivoting on its local origin, the dot center),\n with the ellipse offset by -radius so the ellipse's own bbox is\n centered on the pivot; this keeps the halo concentric with the dot. */}\n <Group scaleX={ringScale} scaleY={ringScale} opacity={ringOpacity}>\n <Ellipse x={-radius} y={-radius} width={size} height={size} fill={color} />\n </Group>\n {/* Solid core dot. */}\n <Ellipse x={-radius} y={-radius} width={size} height={size} fill={color} />\n </Group>\n {labelText ? (\n // Vertically center the cap-height roughly on the dot: nudge the text\n // baseline so it reads centered next to the dot.\n <Text\n x={size + labelGap}\n y={radius - fontSize / 2}\n fontSize={fontSize}\n color={labelColor}\n fontFamily={fontFamily}\n letterSpacing={letterSpacing}\n >\n {labelText}\n </Text>\n ) : null}\n </Group>\n )\n}\n","//! WordStagger — split a phrase into words and reveal them left-to-right with a\n//! per-word stagger. Ported from ondajs.\n//!\n//! Words are laid out by the engine's layout pass (taffy) via a wrapping\n//! `<Flex direction=\"row\" wrap>` with a fixed `width`, so long phrases wrap onto\n//! multiple lines. Each word is wrapped in `FadeIn` — OPACITY-ONLY on purpose:\n//! a per-word translate would be clobbered by the layout pass and, worse, a\n//! per-frame translate would grow each word's bbox and make the whole line\n//! reflow/jiggle as the cascade runs. ondajs uses `entryFadeRise` (a small rise)\n//! because it animates CSS `transform` on inline-blocks that don't reflow the\n//! flow; here a pure fade is the faithful, layout-safe equivalent. See\n//! `approximations` in the port notes.\n\nimport { AbsoluteFill, Flex, Text, useVideoConfig } from '@onda-engine/react'\nimport { STAGGER, staggerFrames } from '../motion.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { FadeIn } from './FadeIn.js'\n\nexport interface WordStaggerProps extends TextStyleProps {\n /** The phrase. Split on whitespace into one reveal per word. */\n text?: string\n /** Font size in px (default 64). */\n fontSize?: number\n /** Container width in px — the line wraps within this (default 1080). */\n width?: number\n /** Horizontal alignment of words within each line (default `'start'`). */\n justify?: 'start' | 'center' | 'end'\n /** Frames before the FIRST word starts (default 0). */\n delay?: TimeInput\n /** Frames between consecutive words (default `STAGGER` = 4). */\n stagger?: TimeInput\n}\n\nexport function WordStagger({\n text: textProp = 'motion that moves you',\n fontSize = 64,\n color: colorProp,\n width = 1080,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n justify = 'start',\n delay: delayIn = 0,\n stagger: staggerIn,\n}: WordStaggerProps) {\n const text = applyTextCase(textProp, { uppercase })\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const stagger = framesOf(staggerIn, fps, STAGGER)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Split on any run of whitespace; drop empties so leading/trailing spaces in\n // the prop don't create ghost words that delay the cascade.\n const words = text.split(/\\s+/).filter(Boolean)\n\n return (\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Flex direction=\"row\" wrap justify={justify} gap={Math.round(fontSize * 0.3)} width={width}>\n {words.map((word, i) => (\n <FadeIn key={`${i}-${word}`} delay={delay + staggerFrames(i, stagger)}>\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {word}\n </Text>\n </FadeIn>\n ))}\n </Flex>\n </AbsoluteFill>\n )\n}\n","//! QuoteCard — a centered pull-quote: a large word-staggered quote, an accent\n//! divider that draws in from the left, and an attribution (author + role) that\n//! fades in last. A slow, readable stagger — the quote reads, it doesn't\n//! cascade. Ported from ondajs.\n//!\n//! Layout: an `<AbsoluteFill justify align center>` centers a\n//! `<Flex direction=\"column\" align=\"center\">` that stacks the three beats with a\n//! fixed gap, so the engine's layout pass (taffy) handles centering and vertical\n//! stacking — no manual y math (which the wrapped quote would make\n//! un-computable at author time anyway).\n//!\n//! Sequencing (verbatim from ondajs — no two things move together):\n//! t=delay quote words begin staggering in\n//! t=delay + quoteRevealEnd + 8 divider draws in (only if `accent`)\n//! t=dividerDelay + DURATION.base + 4 author + role fade in together\n//! `quoteRevealEnd = (wordCount - 1) * QUOTE_STAGGER + DURATION.base`.\n//!\n//! Divider draw-on: ondajs composes `MaskReveal` (a clip-path retreat over a\n//! unicode block) to \"draw\" the rule from the left. Here the rule is a\n//! fixed-size `<Rect>` revealed by an animated `clipRect(width * progress, …)`\n//! on its wrapping `<Group>` — same left-to-right reveal, and layout-safe: the\n//! clip does not change the node's measured bbox, so the column never reflows\n//! (an animated Rect `width` as a Flex child would jiggle).\n\nimport {\n AbsoluteFill,\n Flex,\n Group,\n Rect,\n Text,\n clipRect,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH, STAGGER } from '../motion.js'\nimport { type Placement, PlacementShift } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { FadeIn } from './FadeIn.js'\nimport { WordStagger } from './WordStagger.js'\n\n/** Slower stagger between quote words than the canonical `STAGGER` (4f) — a\n * quote needs to read, not cascade. 6f @ 30fps ≈ 0.20s: quiet, readable. This\n * longer beat is the entire reason this scene-block exists over a bare\n * `WordStagger`. */\nconst QUOTE_STAGGER = STAGGER + 2\n\n/** Divider geometry — a thin horizontal accent rule, never a full underline. */\nconst DIVIDER_WIDTH = 48\nconst DIVIDER_HEIGHT = 2\n\nexport interface QuoteCardProps extends TextStyleProps {\n /** The pull-quote body. Revealed word-by-word on a slower-than-canonical\n * stagger. */\n quote?: string\n /** Attribution name. */\n author?: string\n /** Attribution role / title. */\n role?: string\n /** Frames before the quote starts. */\n delay?: TimeInput\n /** Show the accent divider between quote and attribution. */\n accent?: boolean\n /** Quote font size in px. */\n quoteFontSize?: number\n /** Quote font weight (display default 600). */\n quoteFontWeight?: number\n /** Author / role font size in px. */\n authorFontSize?: number\n /** Author / role font weight. */\n authorFontWeight?: number\n /** Author / role color (default: theme `textMuted`). */\n authorColor?: string\n /** Divider color (default: theme `accent`). */\n accentColor?: string\n /** Wrap width for the quote in px. Defaults to ~44% of the composition width\n * (the ondajs `40vw` pull-quote feel), so long quotes wrap onto multiple\n * lines. */\n quoteWidth?: number\n /** Where the card sits: a region keyword (`'center'`, `'lower-third'`, ...) or\n * normalized `{x,y}` (0-1, card center). The shared placement contract;\n * default `'center'` (the historical self-centering). */\n placement?: Placement\n}\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport function QuoteCard({\n quote = 'Motion is the difference between art and craft.',\n author = 'Saul Bass',\n role = 'Graphic Designer',\n delay: delayIn = 0,\n accent = true,\n quoteFontSize = 56,\n quoteFontWeight = 600,\n authorFontSize = 22,\n authorFontWeight = 500,\n color: colorProp,\n authorColor: authorColorProp,\n accentColor: accentColorProp,\n fontFamily: fontFamilyProp,\n uppercase,\n quoteWidth,\n placement,\n}: QuoteCardProps) {\n const frame = useCurrentFrame()\n const { fps, width } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const authorColor = authorColorProp ?? theme.textMuted\n const accentColor = accentColorProp ?? theme.accent\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n const quoteText = applyTextCase(quote, { uppercase })\n\n // ~40vw pull-quote feel when no explicit width is given.\n const resolvedQuoteWidth = quoteWidth ?? Math.round(width * 0.44)\n\n // The word count drives how long the quote takes to finish revealing — the\n // last word lands at (wordCount - 1) * QUOTE_STAGGER + DURATION.base.\n const words = quoteText.split(/\\s+/).filter(Boolean)\n const wordCount = Math.max(1, words.length)\n const quoteRevealEnd = (wordCount - 1) * QUOTE_STAGGER + DURATION.base\n\n // A small breathing beat after the quote settles before the divider draws.\n const dividerDelay = delay + quoteRevealEnd + 8\n const dividerDuration = DURATION.base\n\n // Author + role fade in together after the divider lands.\n const attributionDelay = dividerDelay + dividerDuration + 4\n\n // Divider draw-on — width grows 0 → full from the left on the house spring,\n // expressed as a clip so the Rect's measured bbox (and the column layout)\n // never changes.\n const dividerProgress = spring({\n frame: Math.max(0, frame - dividerDelay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: dividerDuration,\n })\n const dividerRevealed = interpolate(dividerProgress, [0, 1], [0, DIVIDER_WIDTH], CLAMP)\n\n return (\n // The flex column self-centers; PlacementShift moves the centered stack by\n // the center->placement delta (no-op for the default 'center').\n <PlacementShift placement={placement}>\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Flex direction=\"column\" align=\"center\" gap={32}>\n {/* Quote — words stagger in slowly so the line reads. WordStagger's\n wrapping Flex wraps long quotes within `quoteWidth`. */}\n <WordStagger\n text={quoteText}\n delay={delay}\n stagger={QUOTE_STAGGER}\n justify=\"center\"\n color={color}\n fontSize={quoteFontSize}\n fontFamily={fontFamily}\n fontWeight={quoteFontWeight}\n width={resolvedQuoteWidth}\n />\n\n {/* Divider — accent rule that draws in from the left. Skipped entirely\n when `accent` is false; the column gap still keeps the layout\n breathing. The full-size Rect reserves the slot; the clip reveals\n it. */}\n {accent ? (\n <Group clip={clipRect(dividerRevealed, DIVIDER_HEIGHT)}>\n <Rect width={DIVIDER_WIDTH} height={DIVIDER_HEIGHT} fill={accentColor} />\n </Group>\n ) : null}\n\n {/* Attribution — author + role fade in together after the divider; the\n role sits dim beneath the author in the same centered column. */}\n <Flex direction=\"column\" align=\"center\" gap={4}>\n <FadeIn delay={attributionDelay}>\n <Text\n fontSize={authorFontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={authorFontWeight}\n >\n {author}\n </Text>\n </FadeIn>\n <FadeIn delay={attributionDelay}>\n <Text\n fontSize={authorFontSize}\n color={authorColor}\n fontFamily={fontFamily}\n fontWeight={authorFontWeight}\n >\n {role}\n </Text>\n </FadeIn>\n </Flex>\n </Flex>\n </AbsoluteFill>\n </PlacementShift>\n )\n}\n","//! RgbGlitch — RGB channel-split glitch text. Ported from ondajs (rgb-glitch-text).\n//!\n//! Renders the text three times — a red copy and a cyan copy offset just off a\n//! white center copy — to fake the chromatic-aberration look. A constant\n//! `baseSplit` gives the always-on coloured edge; periodic glitch bursts kick the\n//! split wider and add vertical jitter. All randomness is a pure function of\n//! `random(seed + bucket)` (deterministic per §1) keyed by a 2-frame bucket, so\n//! it renders identically every time.\n//!\n//! DETERMINISM NOTE: ondajs uses a *stateful* `seededRandom(...)` generator and\n//! calls it twice per bucket (x-burst, then y-jitter). Onda's `random(seed)` is a\n//! single-step pure function, so we draw two independent values from two distinct\n//! seeds (`base` and `base + 104729`). Not bit-identical to ondajs, but the same\n//! behaviour: two independent jitter draws per 2-frame bucket, fully deterministic.\n//!\n//! BLEND-MODE APPROXIMATION: ondajs composites the coloured copies with CSS\n//! `mix-blend-mode: screen` over the dark canvas, so the overlaps brighten toward\n//! white. The scene graph has NO blend modes — nodes alpha-composite (source-\n//! over) only. We approximate by drawing the two coloured copies at reduced\n//! opacity UNDER the solid white center copy: on the intended dark background the\n//! offset coloured fringes read as the red/cyan split, and the center stays clean\n//! white. It is not a true additive screen (overlapping fringes won't lighten),\n//! but on the dark Onda canvas the chromatic-edge read is faithful.\n//!\n//! LAYOUT: self-positioning. `<Text>` is single-line and LEFT-anchored, so to\n//! centre/right-align the line we measure its width (via `useTextMetrics`) and\n//! offset x accordingly. The three copies share that base x/y so they stack, and\n//! the whole effect is wrapped in a single `<Group>` so it composes as one node.\n//!\n//! Tracking: the shared `letterSpacing` knob now rides the scene `<Text>` (the\n//! ondajs original tightened by `-0.02em`); the measured width is tracking-aware\n//! so the three copies stay aligned.\n\nimport {\n Group,\n Text,\n random,\n useCurrentFrame,\n useVideoConfig,\n variantSeed,\n} from '@onda-engine/react'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface RgbGlitchProps extends TextStyleProps {\n /** The text to glitch. */\n text?: string\n /** Frames before the effect starts. */\n delay?: TimeInput\n /** Constant baseline channel split in px (the always-on chromatic edge). */\n baseSplit?: number\n /** Peak extra split in px during a glitch burst. */\n intensity?: number\n /** Frames between glitch bursts. */\n glitchPeriod?: number\n /** Frames a glitch burst lasts. */\n glitchDuration?: number\n /** Seed for the (deterministic) burst jitter. */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Red-channel copy color (default: theme `accent`). */\n redColor?: string\n /** Cyan-channel copy color (default: theme `palette[1]`). */\n cyanColor?: string\n /** Opacity of the coloured channel copies (the screen-blend approximation —\n * lower keeps the center read as clean white). Default 0.85. */\n channelOpacity?: number\n /** Font size in px. */\n fontSize?: number\n /** Line alignment relative to the placement point. Default `'center'`. */\n align?: 'left' | 'center' | 'right'\n /** Absolute x of the alignment anchor. Defaults to canvas horizontal center. */\n x?: number\n /** Absolute y (top-ish) of the line. Defaults to vertical center. */\n y?: number\n}\n\nexport function RgbGlitch({\n text: textProp = 'GLITCH',\n delay: delayIn = 0,\n baseSplit = 2,\n intensity = 10,\n glitchPeriod = 48,\n glitchDuration = 8,\n seed: seedProp = 7,\n variant,\n color: colorProp,\n redColor: redColorProp,\n cyanColor: cyanColorProp,\n channelOpacity = 0.85,\n fontSize = 120,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n align = 'center',\n x,\n y,\n}: RgbGlitchProps) {\n const text = applyTextCase(textProp, { uppercase })\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const frame = useCurrentFrame()\n const { width, height, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const redColor = redColorProp ?? theme.accent\n const cyanColor = cyanColorProp ?? theme.palette[1] ?? '#4de2ff'\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n const measured = useTextMetrics(text, fontSize, { fontFamily, fontWeight, letterSpacing })\n\n const local = Math.max(0, frame - delay)\n\n // Burst window + 2-frame bucket, matching the ondajs PRNG keying so the jitter\n // is deterministic and steps every other frame (a chunky, digital cadence).\n const inBurst = local % glitchPeriod < glitchDuration\n const bucket = Math.floor(local / 2)\n // Two independent draws per bucket (x-burst, y-jitter), offset so they differ.\n const rx = random(seed + bucket * 7919)\n const ry = random(seed + bucket * 7919 + 104729)\n const burst = inBurst ? rx * 2 - 1 : 0\n const dx = baseSplit + burst * intensity\n const dy = inBurst ? (ry * 2 - 1) * intensity * 0.4 : 0\n\n // Measured single-line width for centre/right alignment (shifts the anchor point).\n const lineWidth = measured.width\n const anchorX = x ?? Math.round(width / 2)\n const anchorY = y ?? Math.round(height / 2 - fontSize * 0.6)\n const baseX =\n align === 'center' ? anchorX - lineWidth / 2 : align === 'right' ? anchorX - lineWidth : anchorX\n\n const common = { fontSize, fontFamily, fontWeight, italic, letterSpacing } as const\n\n // The coloured copies composite with a real `screen` blend (ondajs's\n // mix-blend-mode: screen) so overlaps brighten toward white; the white center\n // draws last, on top, normal-composited, so it stays clean.\n return (\n <Group>\n <Text\n x={baseX - dx}\n y={anchorY - dy}\n color={redColor}\n opacity={channelOpacity}\n blendMode=\"screen\"\n {...common}\n >\n {text}\n </Text>\n <Text\n x={baseX + dx}\n y={anchorY + dy}\n color={cyanColor}\n opacity={channelOpacity}\n blendMode=\"screen\"\n {...common}\n >\n {text}\n </Text>\n <Text x={baseX} y={anchorY} color={color} {...common}>\n {text}\n </Text>\n </Group>\n )\n}\n","//! RotateIn — opacity + rotation from `fromDegrees` → 0° on the house spring.\n//! Ported from ondajs. The calm landing of the original: no overshoot, a small\n//! starting angle (safe zone [-12°, +12°]), one spring driving both fade and\n//! settle.\n//!\n//! Rotation pivots on the transform origin, set here to the composition center\n//! (matching ondajs's CSS `transform-origin: center` for centered content), so a\n//! centered element settles in place rather than swinging about its top-left.\n\nimport { Group, interpolate, spring, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface RotateInProps {\n /** Frames to wait before starting. */\n delay?: TimeInput\n /** Frames to settle to 0° (default `DURATION.base` = 18). */\n durationInFrames?: TimeInput\n /** Starting angle in degrees (clockwise). Safe zone: `[-12, +12]`. Default -8. */\n fromDegrees?: number\n children?: ReactNode\n}\n\nexport function RotateIn({\n delay: delayIn = 0,\n durationInFrames: durationInFramesIn = DURATION.base,\n fromDegrees = -8,\n children,\n}: RotateInProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const durationInFrames = framesOf(durationInFramesIn, fps)\n\n // One spring drives both the fade and the angle settle, so they read as a\n // single motion — mirrors the ondajs source (no overshoot, calm landing).\n const progress = spring({\n frame: frame - delay,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames,\n })\n\n const clamp = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n const opacity = interpolate(progress, [0, 1], [0, 1], clamp)\n const rotation = interpolate(progress, [0, 1], [fromDegrees, 0], clamp)\n\n return (\n <Group rotation={rotation} opacity={opacity} originX={width / 2} originY={height / 2}>\n {children}\n </Group>\n )\n}\n","//! Scrim — a flat, full-frame, semi-transparent color veil. Drop it OVER a busy\n//! photo/video (and UNDER the text) to mute the image just enough that overlaid\n//! type reads — \"not too white, not too dark.\" A light scrim lifts a dark photo;\n//! a dark scrim deepens a bright one. The point isn't to show the picture\n//! perfectly — it's legibility.\nimport { Rect, interpolate, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\n\nexport interface ScrimProps {\n /** Veil color (hex). Default white — lifts a busy photo so dark text reads. */\n color?: string\n /** Veil strength 0..1 (default 0.3). */\n opacity?: number\n /** Frames before it appears. */\n delay?: number\n /** Fade the veil in over the first 8 frames (default true). */\n fadeIn?: boolean\n}\n\nexport function Scrim({ color = '#ffffff', opacity = 0.3, delay = 0, fadeIn = true }: ScrimProps) {\n const frame = useCurrentFrame()\n const { width, height } = useVideoConfig()\n const o = fadeIn\n ? interpolate(frame, [delay, delay + 8], [0, opacity], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n : opacity\n return <Rect x={0} y={0} width={width} height={height} fill={color} opacity={o} />\n}\n","//! SiteReveal — the \"it's live\" payoff for a launch film: a soft-shadowed browser\n//! card that scale-fades in and then slowly SCROLLS a full-page screenshot of the\n//! homepage (a gentle auto-scroll, not a fast flick), so the whole site reads as\n//! real and live. Pairs with a headline beat (\"Now live.\") placed as an EARLIER\n//! scene sibling — list the headline before this so the internal content clip\n//! never occludes it.\n//!\n//! The page is a tall full-page capture (e.g. 1400×6274). Pass its `pageAspect`\n//! (height/width) so the component scales it to the card width and scrolls\n//! through `scrollStart`→`scrollEnd` of the page over the beat. The scrolling\n//! image is masked to the viewport with `clipRect` — the clip is the LAST node in\n//! the card and the chrome is drawn first, so the frame chrome is never clipped.\n//!\n//! Premium chrome: a clean centered address pill (not macOS traffic lights) over\n//! a near-white bar, a soft drop shadow under the rounded card (the same framed-\n//! print depth as LookbookShot) — consistent with an editorial brand film.\n\nimport {\n Ellipse,\n Group,\n Image,\n Rect,\n Text,\n clipRect,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport { useTheme } from '../theme.js'\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport interface SiteRevealProps {\n /** Full-page screenshot (tall) — the homepage to scroll. */\n src?: string\n /** Address-bar text. */\n url?: string\n /** Page height / width of `src` (drives the scroll extent). Default ~4.48. */\n pageAspect?: number\n /** Card content width in px (default 1360). */\n width?: number\n /** Viewport height in px below the chrome bar (default 770). */\n height?: number\n /** Vertical nudge of the whole card from center (default 56, slightly low to\n * leave room for a headline above). */\n offsetY?: number\n /** Frames before the card enters. */\n delay?: number\n /** Type the URL into the address bar (with a blinking cursor) before scrolling\n * — the \"navigate to the site\" beat. Default true. */\n typeUrl?: boolean\n /** Frames the URL takes to type in (default 26). */\n typeDurationInFrames?: number\n /** Page fraction (0..1) shown at the start of the scroll (default 0 = top). */\n scrollStart?: number\n /** Page fraction (0..1) reached at the end (default 0.62 — stop before footer). */\n scrollEnd?: number\n /** Frames over which the scroll completes (default 150). */\n scrollDurationInFrames?: number\n /** Card body fill (default near-white). */\n surface?: string\n /** Chrome bar fill (default a light warm gray). */\n barColor?: string\n /** 1px card border + chrome divider (default: theme `border`). */\n border?: string\n /** Address pill text color (default: theme `textMuted`). */\n dim?: string\n /** Soft shadow color under the card (default a low-alpha warm dark). */\n shadowColor?: string\n /** Card corner radius in px (default 16). */\n cardRadius?: number\n}\n\nconst CHROME_H = 58\nconst DOT = 12\nconst DOT_GAP = 9\n\nexport function SiteReveal({\n src = '',\n url = '',\n pageAspect = 4.48,\n width = 1360,\n height = 770,\n offsetY = 56,\n delay = 0,\n typeUrl = true,\n typeDurationInFrames = 26,\n scrollStart = 0,\n scrollEnd = 0.62,\n scrollDurationInFrames = 150,\n surface = '#fdfcf9',\n barColor = '#f1ece1',\n border: borderProp,\n dim: dimProp,\n shadowColor = '#2b201826',\n cardRadius = 16,\n}: SiteRevealProps) {\n const frame = useCurrentFrame()\n const { width: W, height: H, fps } = useVideoConfig()\n const theme = useTheme()\n const border = borderProp ?? theme.border\n const dim = dimProp ?? theme.textMuted\n\n const cardW = width\n const cardH = CHROME_H + height\n const cx = W / 2\n const cy = H / 2 + offsetY\n\n // Entrance: house scale-fade about the card center.\n const enter = spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n const opacity = interpolate(enter, [0, 1], [0, 1], CLAMP)\n const scale = interpolate(enter, [0, 1], [0.965, 1], CLAMP)\n\n // URL types into the address bar after the card lands (a blinking cursor while\n // typing), then the scroll waits until the URL is finished — the \"navigate to\n // the site, then browse it\" beat.\n const typeStart = delay + 14\n const typeP = typeUrl\n ? interpolate(frame - typeStart, [0, typeDurationInFrames], [0, 1], CLAMP)\n : 1\n const typedUrl = url.slice(0, Math.round(url.length * typeP))\n const typing = typeUrl && frame >= typeStart && frame < typeStart + typeDurationInFrames\n const cursorOn = typing && Math.floor((frame - typeStart) / 6) % 2 === 0\n const urlText = typeUrl ? typedUrl + (cursorOn ? '|' : '') : url\n const scrollBegin = typeUrl ? typeStart + typeDurationInFrames + 8 : delay + 10\n\n // Auto-scroll: the page is scaled to the card width, then panned through\n // scrollStart→scrollEnd of its height over the beat (linear — a steady scroll).\n const scaledPageH = cardW * pageAspect\n const scrollRange = Math.max(0, scaledPageH - height)\n const p = interpolate(frame - scrollBegin, [0, scrollDurationInFrames], [0, 1], CLAMP)\n const frac = scrollStart + (scrollEnd - scrollStart) * p\n const scrollY = -scrollRange * frac\n\n const bodyX = -cardW / 2\n const bodyY = -cardH / 2\n\n // Centered address pill geometry.\n const pillW = Math.min(560, Math.round(cardW * 0.42))\n const pillH = 34\n const pillX = Math.round(-pillW / 2)\n const pillY = bodyY + Math.round((CHROME_H - pillH) / 2)\n const dotY = bodyY + Math.round((CHROME_H - DOT) / 2)\n\n return (\n <Group x={cx} y={cy} scaleX={scale} scaleY={scale} opacity={opacity}>\n {/* Card body — soft drop shadow, near-white, hairline border. */}\n <Rect\n x={bodyX}\n y={bodyY}\n width={cardW}\n height={cardH}\n cornerRadius={cardRadius}\n fill={surface}\n stroke={border}\n strokeWidth={1}\n shadow={{ color: shadowColor, blur: 60, offsetX: 0, offsetY: 26 }}\n />\n {/* Chrome bar. */}\n <Rect\n x={bodyX}\n y={bodyY}\n width={cardW}\n height={CHROME_H}\n cornerRadius={cardRadius}\n fill={barColor}\n />\n {/* square off the bar's bottom corners so only the top is rounded */}\n <Rect\n x={bodyX}\n y={bodyY + CHROME_H - cardRadius}\n width={cardW}\n height={cardRadius}\n fill={barColor}\n />\n {[0, 1, 2].map((i) => (\n <Ellipse\n key={i}\n x={bodyX + 26 + i * (DOT + DOT_GAP)}\n y={dotY}\n width={DOT}\n height={DOT}\n fill={border}\n />\n ))}\n {/* Address pill (centered). */}\n <Rect\n x={pillX}\n y={pillY}\n width={pillW}\n height={pillH}\n cornerRadius={pillH / 2}\n fill={surface}\n stroke={border}\n strokeWidth={1}\n />\n <Group\n x={pillX + 18}\n y={pillY + Math.round((pillH - 20) / 2)}\n clip={clipRect(pillW - 36, 22)}\n >\n <Text fontSize={20} color={dim}>\n {urlText}\n </Text>\n </Group>\n {/* 1px divider under the chrome. */}\n <Rect x={bodyX} y={bodyY + CHROME_H - 1} width={cardW} height={1} fill={border} />\n\n {/* Content viewport — the scrolling page, masked to the viewport. The clip\n is the LAST node (chrome already drawn), so the chrome is never cut. */}\n <Group x={bodyX} y={bodyY + CHROME_H} clip={clipRect(cardW, height)}>\n <Image src={src} x={0} y={scrollY} width={cardW} height={scaledPageH} fit=\"cover\" />\n </Group>\n </Group>\n )\n}\n","//! ShimmerSweep — a single bright band of light sweeps across text. Ported from ondajs.\n//!\n//! Restrained emphasis, not a disco: the base text sits in a dim `color`; a\n//! brighter band travels through once (or loops on an interval), drawing the eye\n//! without moving the layout. Linear motion by design — a sweep with spring\n//! acceleration reads as broken.\n//!\n//! Scene-graph rendition of the ondajs (CSS) original:\n//! - ondajs paints the shine with a `linear-gradient` clipped to the glyphs via\n//! `background-clip: text` and animates `backgroundPositionX`. We reproduce that\n//! faithfully: a translating `<Rect>` filled with a soft `linearGradient`\n//! (transparent → `shimmerColor` → transparent) is masked to the TEXT GLYPHS via\n//! an **alpha matte** (`matte={<Text/>}`) — the scene-graph equivalent of\n//! `background-clip: text`. The bright band rides OVER the dim base text and is\n//! revealed only where the letterforms are, so the shine shows ON the glyphs and\n//! never in the gaps around them. (Earlier versions clipped to a rectangular text\n//! BOX, which leaked the shine into the empty space between/around letters.)\n//! - The sweep extent uses the REAL shaped width (`measureText`, warm in the\n//! browser preview and the Node export bake); pass `width` to override.\n//! - `<Text>` is single-line (no wrap); pass a single line of `text`.\n//! - `angle` is approximated by tilting the gradient's start/end points; the band\n//! itself translates horizontally (the dominant axis of the original sweep).\n//! - `letterSpacing` and `lineHeight` from ondajs have no scene equivalent and\n//! are dropped (the engine owns line-box metrics).\n//!\n//! Backend caveat: the shine (gradient + matte) is a Vello/GPU effect. The CPU\n//! reference collapses a gradient to its first stop (here fully transparent), so on\n//! CPU the band is invisible and only the dim base text shows. On the WebGPU preview\n//! the matte resolves via the async pre-pass — judge the look on a native render.\n//! The base text is always legible on every backend.\n\nimport {\n Group,\n Rect,\n Text,\n interpolate,\n linearGradient,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { HOUSE_EASE } from '../easing.js'\nimport { DURATION } from '../motion.js'\nimport { measureText, useTextMetricsReady } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Engine line-box height as a multiple of font size (typography crate). */\nconst LINE_RATIO = 1.2\n/** Band width as a fraction of the text box — a soft, generous shine. */\nconst BAND_RATIO = 0.5\n\nexport interface ShimmerSweepProps extends TextStyleProps {\n /** The single line of text to sweep light across. */\n text?: string\n /** Frames before the sweep starts. */\n delay?: TimeInput\n /** Frames for one sweep pass (default `DURATION.slower` = 30). */\n duration?: TimeInput\n /** Loop the sweep instead of a single pass. */\n loop?: boolean\n /** Frames between sweeps when looping. */\n interval?: TimeInput\n /** The sweeping highlight color (default: theme `text`). */\n shimmerColor?: string\n /** Sweep angle in degrees (approximated by tilting the gradient band). */\n angle?: number\n /** Font size in px (default 96). */\n fontSize?: number\n /** Explicit text-box width in px. Overrides the measured width. */\n width?: number\n /** Top-left x in px. Defaults to centering the word on the canvas. */\n x?: number\n /** Top-left y in px. Defaults to centering the word on the canvas. */\n y?: number\n}\n\nexport function ShimmerSweep({\n text: textProp = 'Onda',\n delay: delayIn = 0,\n duration: durationIn = DURATION.slower,\n loop = false,\n interval: intervalIn = 60,\n color: colorProp,\n shimmerColor: shimmerColorProp,\n angle = 110,\n fontSize = 96,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n width,\n x,\n y,\n}: ShimmerSweepProps) {\n const text = applyTextCase(textProp, { uppercase })\n const frame = useCurrentFrame()\n const { width: canvasW, height: canvasH, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const duration = framesOf(durationIn, fps)\n const interval = framesOf(intervalIn, fps)\n const theme = useTheme()\n useTextMetricsReady()\n const color = colorProp ?? theme.textMuted\n const shimmerColor = shimmerColorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n const local = frame - delay\n\n // Progress 0 → 1 across one pass. Loop wraps on `interval` (linear); a single\n // pass eases on HOUSE_EASE and clamps, matching the ondajs timing.\n const safeInterval = Math.max(1, interval)\n const t = loop\n ? (((local % safeInterval) + safeInterval) % safeInterval) / safeInterval\n : interpolate(local, [0, Math.max(1, duration)], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n easing: HOUSE_EASE,\n })\n\n // Real shaped text width drives the sweep extent (overridable via `width`); the\n // alpha matte below masks the shine to the actual glyphs regardless.\n const boxWidth = width ?? measureText(text, fontSize, { fontFamily, fontWeight }).width\n const boxHeight = fontSize * LINE_RATIO\n\n // Center the word on the canvas by default; `x`/`y` override the top-left.\n const groupX = x ?? Math.round(canvasW / 2 - boxWidth / 2)\n const groupY = y ?? Math.round(canvasH / 2 - boxHeight / 2)\n\n // The bright band is wider than the visible window so its soft edges live\n // off-box at the extremes of the pass. It travels from fully off the right to\n // fully off the left across `t` (linear within the pass).\n const bandWidth = Math.max(1, boxWidth * BAND_RATIO)\n const startX = boxWidth // band's left edge starts just off the right edge\n const endX = -bandWidth // band's left edge ends just off the left edge\n const bandX = interpolate(t, [0, 1], [startX, endX], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // Transparent ends, bright middle. The FIRST stop is transparent so the CPU\n // reference (which collapses to the first stop) shows nothing rather than a\n // hard block — leaving the base text clean.\n const transparent = toTransparent(shimmerColor)\n\n // Approximate `angle` by tilting the gradient axis. 90° is a vertical band\n // (a clean horizontal sweep); deviation from 90° leans the band. Local space.\n const rad = (angle * Math.PI) / 180\n const tilt = Math.cos(rad) // 0 at 90°, ±1 at 0/180°\n const gx0 = 0\n const gy0 = 0\n const gx1 = bandWidth\n const gy1 = boxHeight * tilt\n\n return (\n <Group x={groupX} y={groupY}>\n {/* Base text — dim, always legible, never moves. */}\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {text}\n </Text>\n {/* Bright shine band, masked to the TEXT GLYPHS via an alpha matte — the\n scene-graph `background-clip: text`. The matte Text sits at this Group's\n local origin (0,0), exactly over the base text, so the shine is revealed\n only on the letterforms (not the box around them). The band rides over the\n dim base text, brightening each glyph as it passes. */}\n <Group\n matte={\n <Text\n fontSize={fontSize}\n color={shimmerColor}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {text}\n </Text>\n }\n matteMode=\"alpha\"\n >\n <Group x={bandX}>\n <Rect\n width={bandWidth}\n height={boxHeight}\n gradient={linearGradient(\n [gx0, gy0],\n [gx1, gy1],\n [\n { offset: 0, color: transparent },\n { offset: 0.5, color: shimmerColor },\n { offset: 1, color: transparent },\n ],\n )}\n />\n </Group>\n </Group>\n </Group>\n )\n}\n\n/** Return `color` with its alpha channel forced to `00` (fully transparent),\n * preserving the RGB so the band fades out rather than toward black. */\nfunction toTransparent(color: string): string {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}00`\n }\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}00`\n }\n }\n return '#00000000'\n}\n","//! SkeletonCard — a loading-placeholder card: an optional thumbnail block plus a\n//! stack of rounded bars, with a highlight band sweeping across them on a\n//! frame-driven loop. The card rises in on the house spring. Ported from ondajs.\n//!\n//! The card has FIXED dimensions and is centered by computing its top-left origin\n//! directly from the composition size — NOT via `<Flex>`/`<AbsoluteFill>`. The\n//! shimmer band translates every frame and the card carries an entrance translate,\n//! and the layout pass would both reflow on the moving band and clobber the rise\n//! translate on a direct layout child. So every part is positioned by explicit\n//! x/y inside one outer `<Group>` (which carries the rise + fade Motion), and the\n//! placeholder bars/thumbnail sit at hand-computed y offsets.\n//!\n//! Shimmer: a card-sized `<Rect>` filled with a horizontal `linearGradient`\n//! (transparent → `shimmerColor` → transparent) whose stop offsets slide\n//! left→right on a `frame % shimmerSpeed` loop, clipped to the card's rounded\n//! rect via `clipRect`. The bars also breathe with a gentle sine opacity pulse so\n//! the placeholder reads \"live\" even on the CPU reference (see caveats).\n//!\n//! Approximations vs ondajs:\n//! - The glass `Surface` uses CSS `backdrop-filter: blur` + a drop shadow + a 1px\n//! top sheen. This card renders a flat translucent panel (the dark glass fill\n//! `#0e0e12` + a 1px border) with no top-sheen overlay. NOTE: the engine now\n//! ships both a real `backdropBlur` node prop AND `shadow`, so a follow-up could\n//! upgrade this Surface to true frosted glass with elevation.\n//! - The moving-gradient sheen renders only on the Vello/GPU backend; the CPU\n//! reference collapses a gradient to its first stop (here transparent), so on\n//! CPU the sweep is invisible — the sine opacity pulse on the bars carries the\n//! \"loading\" liveliness there.\n\nimport {\n Group,\n Rect,\n clipRect,\n linearGradient,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryFadeRise } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** Default frames for one shimmer pass — a slow, settled sweep. Two `hold`\n * beats (≈3.2s @30fps) so the highlight glides rather than races; a fast sweep\n * reads cheap/anxious, a slow one reads premium and calm. */\nconst SHIMMER_PASS = DURATION.hold * 2\n\n/** Deterministic bar widths as a fraction of the inner content width — a fixed\n * repeating pattern keyed off the bar index (no PRNG; pure function of i). Reads\n * as \"real\" placeholder copy: a full line, then progressively shorter, then\n * back. Mirrors the ondajs `BAR_WIDTHS` percentages. */\nconst BAR_WIDTHS = [1, 0.92, 0.74, 0.85, 0.6]\nconst barWidthFrac = (i: number): number => BAR_WIDTHS[i % BAR_WIDTHS.length] ?? 1\n\nexport interface SkeletonCardProps {\n /** Number of placeholder text bars below the (optional) thumbnail. */\n lines?: number\n /** Show the leading thumbnail block above the bars. */\n thumbnail?: boolean\n /** Frames for one shimmer pass across the card. Lower = faster sweep. The\n * default runs slow on purpose — a settled, premium loading state. */\n shimmerSpeed?: number\n /** The travelling highlight color — a soft sheen over the bars (default: theme `border`). */\n shimmerColor?: string\n /** Resting fill of the placeholder bars / thumbnail (default: theme `surface`). */\n barColor?: string\n /** Card (panel) background — the translucent glass fill (default: theme `background`). */\n cardColor?: string\n /** Card border color (the 1px-equivalent stroke) (default: theme `border`). */\n borderColor?: string\n /** Frames before the card enters. */\n delay?: TimeInput\n /** Card width in px. */\n width?: number\n /** Card height in px. `undefined` sizes the card to its content. */\n height?: number\n /** Base bar height in px. */\n barHeight?: number\n /** Inner padding of the card in px. */\n padding?: number\n}\n\nexport function SkeletonCard({\n lines = 3,\n thumbnail = true,\n shimmerSpeed = SHIMMER_PASS,\n shimmerColor: shimmerColorProp,\n barColor: barColorProp,\n cardColor: cardColorProp,\n borderColor: borderColorProp,\n delay: delayIn = 0,\n width = 480,\n height,\n barHeight = 18,\n padding = 32,\n}: SkeletonCardProps) {\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n // Resting bar fill. The theme `surface` (`#121217`) sits barely above the\n // canvas `background` (`#0a0d17`), so raw surface bars vanish on a dark scene.\n // Lift the *default* placeholder toward `text` so the card reads as a\n // skeleton — but only a near-surface lift, so the bars sit quiet and premium\n // rather than glaring; an explicit `barColor` is always honored as-is.\n const barColor = barColorProp ?? mixHex(theme.surface, theme.text, 0.16)\n // The travelling sheen — a soft highlight just a touch above the resting bar\n // tone (not the flat `border`), so the pass reads as a gentle wash of light\n // over the skeleton rather than a hard edge sweeping through.\n const shimmerColor = shimmerColorProp ?? mixHex(barColor, theme.text, 0.28)\n // The glass panel is the canvas background at ~80% alpha. Force `cc` onto a\n // 6-digit hex background; otherwise take the theme value as-is.\n const cardColor = cardColorProp ?? withGlassAlpha(theme.background)\n const borderColor = borderColorProp ?? theme.border\n // Shared corner radius for the card panel, thumbnail block, and clip mask.\n const cornerRadius = theme.radius\n // Elevation shadow tinted toward the canvas background (not hard black) at a\n // low alpha — a soft, large-radius pool under the panel reads as quiet depth,\n // where pure black at high alpha would read as a harsh cutout.\n const shadowColor = `${mixHex(theme.background, '#000000', 0.4)}40`\n\n const safeLines = Math.max(1, Math.floor(lines))\n const safeBarHeight = Math.max(1, barHeight)\n // Gap between bars, mirroring ondajs (`round(barHeight * 0.9)`).\n const gap = Math.round(safeBarHeight * 0.9)\n const thumbHeight = safeBarHeight * 6\n\n // Inner content box (card minus padding on both sides).\n const innerWidth = Math.max(0, width - padding * 2)\n\n // Total content height: optional thumbnail (+ its trailing gap) then the bar\n // stack (no trailing gap after the last bar).\n const barsHeight = safeBarHeight * safeLines + gap * Math.max(0, safeLines - 1)\n const contentHeight = thumbnail ? thumbHeight + gap + barsHeight : barsHeight\n\n // Card height: explicit, else sized to content + padding.\n const cardHeight = height ?? contentHeight + padding * 2\n\n // Entrance: rise + fade on the house spring (ondajs `useEntrance({type:'rise'})`).\n const motion = entryFadeRise({ frame, fps, delay })\n const local = frame - delay\n\n // Center the fixed-size card by computing its top-left directly — no layout\n // container (the moving band + rise translate would otherwise be clobbered /\n // cause reflow). The rise `y` is added on top of the centered origin.\n const originX = Math.round((compWidth - width) / 2)\n const originY = Math.round((compHeight - cardHeight) / 2)\n\n // The highlight band travels left → right on a continuous, seamless loop. Pure\n // function of the frame: normalize `local % shimmerSpeed` into [0, 1) (handles\n // negative frames inside a delayed Sequence), then slide the gradient's bright\n // center across [-0.5, 1.5] so it fully enters and exits the card each pass.\n const safeSpeed = Math.max(1, Math.floor(shimmerSpeed))\n const t = (((local % safeSpeed) + safeSpeed) % safeSpeed) / safeSpeed\n const center = -0.5 + t * 2 // ondajs: posX from -50% → 150%\n // Half-width of the bright zone in gradient-offset units. A *wide*, gentle\n // band so the sheen fades in and out across a third of the card — broad and\n // diffuse reads soft/premium; a narrow band would sweep as a hard edge.\n const band = 0.32\n const lo = Math.max(0, Math.min(1, center - band))\n const mid = Math.max(0, Math.min(1, center))\n const hi = Math.max(0, Math.min(1, center + band))\n const transparent = toTransparent(shimmerColor)\n\n // A gentle sine opacity breath on the bars so the placeholder reads \"loading\"\n // even on the CPU backend (where the gradient sheen collapses away). Oscillates\n // ~0.82 → 1.0 over the same (now slow) loop period — a quiet, settled breath,\n // tight amplitude and high floor so it never throbs or strobes.\n const pulse = 0.91 + 0.09 * Math.sin(t * Math.PI * 2 - Math.PI / 2)\n\n // Sheen offsets must be strictly increasing and within [0, 1] for a valid\n // gradient; if the band is fully off one edge the three clamp together — nudge\n // them apart by a hair, then clamp the ceiling back to 1.\n const o1 = lo\n const o2 = Math.min(1, Math.max(o1 + 0.0001, mid))\n const o3 = Math.min(1, Math.max(o2 + 0.0001, hi))\n\n return (\n <Group x={originX} y={originY + motion.y} opacity={motion.opacity}>\n {/* Glass panel: translucent fill + 1px border + a soft drop-shadow for\n elevation (ondajs's box-shadow; backdrop-blur stays a non-goal). */}\n <Rect\n x={0}\n y={0}\n width={width}\n height={cardHeight}\n cornerRadius={cornerRadius}\n fill={cardColor}\n stroke={borderColor}\n strokeWidth={1}\n shadow={{ color: shadowColor, blur: 40, offsetY: 16 }}\n />\n\n {/* Placeholder content, inset by the padding. */}\n <Group x={padding} y={padding}>\n {thumbnail ? (\n <Rect\n x={0}\n y={0}\n width={innerWidth}\n height={thumbHeight}\n cornerRadius={cornerRadius}\n fill={barColor}\n opacity={pulse}\n />\n ) : null}\n\n {Array.from({ length: safeLines }, (_, i) => {\n const barY = (thumbnail ? thumbHeight + gap : 0) + i * (safeBarHeight + gap)\n const w = Math.max(0, innerWidth * barWidthFrac(i))\n return (\n <Rect\n key={i}\n x={0}\n y={barY}\n width={w}\n height={safeBarHeight}\n cornerRadius={safeBarHeight / 2}\n fill={barColor}\n opacity={pulse}\n />\n )\n })}\n </Group>\n\n {/* Travelling sheen — a card-sized gradient band clipped to the rounded\n card, sliding left → right. GPU/Vello-only (CPU collapses to the first,\n transparent stop). Drawn last so it reads as a highlight over the bars. */}\n <Group clip={clipRect(width, cardHeight, cornerRadius)}>\n <Rect\n x={0}\n y={0}\n width={width}\n height={cardHeight}\n gradient={linearGradient(\n [0, cardHeight / 2],\n [width, cardHeight / 2],\n [\n { offset: o1, color: transparent },\n { offset: o2, color: shimmerColor },\n { offset: o3, color: transparent },\n ],\n )}\n opacity={0.32}\n />\n </Group>\n </Group>\n )\n}\n\n/** Return `color` with its alpha forced to `cc` (~80%) so the theme's opaque\n * `background` reads as the translucent glass panel (the original `#0e0e12cc`).\n * Only rewrites 6/3-digit hex; any other form (already-alpha hex, rgba, …) is\n * returned untouched so an author-set translucent background is respected. */\nfunction withGlassAlpha(color: string): string {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6) {\n return `#${hex}cc`\n }\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}cc`\n }\n }\n return color\n}\n\n/** Parse a hex color to an `[r, g, b]` triple (0..255); non-hex → black. */\nfunction parseRgb(color: string): [number, number, number] {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return [hx(`${r}${r}`), hx(`${g}${g}`), hx(`${b}${b}`)]\n }\n if (hex.length === 6 || hex.length === 8) {\n return [hx(hex.slice(0, 2)), hx(hex.slice(2, 4)), hx(hex.slice(4, 6))]\n }\n }\n return [0, 0, 0]\n}\n\n/** Parse a 2-char hex byte to 0..255, defaulting to 0. */\nfunction hx(byte: string): number {\n const v = Number.parseInt(byte, 16)\n return Number.isNaN(v) ? 0 : v\n}\n\n/** Two-digit hex for a 0..255 channel. */\nfunction toHexByte(v: number): string {\n const c = Math.max(0, Math.min(255, Math.round(v)))\n return c.toString(16).padStart(2, '0')\n}\n\n/** Straight sRGB lerp between two hex colors by `t` (0 = `a`, 1 = `b`). The\n * engine has no `color-mix`; this is the closest faithful approximation. */\nfunction mixHex(a: string, b: string, t: number): string {\n const k = Math.max(0, Math.min(1, t))\n const [ar, ag, ab] = parseRgb(a)\n const [br, bg, bb] = parseRgb(b)\n const r = ar + (br - ar) * k\n const g = ag + (bg - ag) * k\n const bl = ab + (bb - ab) * k\n return `#${toHexByte(r)}${toHexByte(g)}${toHexByte(bl)}`\n}\n\n/** Return `color` with its alpha forced to `00` (fully transparent), preserving\n * the RGB so the band fades to transparent rather than toward black. Mirrors the\n * `Spotlight` helper. */\nfunction toTransparent(color: string): string {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}00`\n }\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}00`\n }\n }\n return '#00000000'\n}\n","//! SlideIn — directional translate + fade on the house spring. `direction` names\n//! the settling direction (`'up'` rises into place from below).\n//!\n//! Applies a translate, so place it in an absolute context (via `x`/`y` on a\n//! parent, or inside an `<AbsoluteFill>`) rather than as a measured `<Flex>`\n//! child, where the layout pass owns translation.\n\nimport { Group, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { entrySlide } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface SlideInProps {\n delay?: TimeInput\n durationInFrames?: TimeInput\n /** Settling direction (default `'up'`). */\n direction?: 'up' | 'down' | 'left' | 'right'\n /** Travel distance in px (12–24 Onda envelope; default 12). */\n distance?: number\n children?: ReactNode\n}\n\nexport function SlideIn({\n delay = 0,\n durationInFrames = DURATION.base,\n direction = 'up',\n distance = 12,\n children,\n}: SlideInProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const { opacity, x, y } = entrySlide({ frame, fps, delay, durationInFrames, direction, distance })\n return (\n <Group x={x} y={y} opacity={opacity}>\n {children}\n </Group>\n )\n}\n","//! SlideOut — directional translate + fade out on the house ease. `direction`\n//! names where the element leaves toward (`'down'` drops it). Place absolutely\n//! (it applies a translate the layout pass would otherwise own).\n\nimport { Group, useCurrentFrame } from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { exitSlide } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface SlideOutProps {\n delay?: TimeInput\n durationInFrames?: TimeInput\n /** Direction the element leaves toward (default `'down'`). */\n direction?: 'up' | 'down' | 'left' | 'right'\n distance?: number\n children?: ReactNode\n}\n\nexport function SlideOut({\n delay = 0,\n durationInFrames = DURATION.fast,\n direction = 'down',\n distance = 12,\n children,\n}: SlideOutProps) {\n const frame = useCurrentFrame()\n const { opacity, x, y } = exitSlide({ frame, delay, durationInFrames, direction, distance })\n return (\n <Group x={x} y={y} opacity={opacity}>\n {children}\n </Group>\n )\n}\n","//! SlotMachineRoll — each character spins down a reel of glyphs and lands cleanly\n//! on its target: the reel decelerates hard into place on the house spring,\n//! staggered left-to-right on the house cadence. Ported from ondajs, retuned\n//! premium.\n//!\n//! Premium notes (vs the original linear roll): the reel rides `SPRING_SMOOTH`\n//! over `DURATION.slower` for a slow, settled deceleration (no constant-velocity\n//! spin) that lands square on the target — the glyph drops in and stops, with no\n//! past-target kick (an over-roll that flashes a wrong glyph reads as a glitch, not\n//! a premium settle). Columns sit on the house stagger; the cell advance is a touch\n//! airier so the digits breathe. An opt-in accent (`glow`, default OFF): a soft\n//! radial bloom behind the landed row as the reels settle — a TRUE falloff to\n//! transparent (not a solid wash with a fake shadow), the digits stay near-white.\n//!\n//! Engine port notes (vs the ondajs/CSS original):\n//! - ondajs nests `overflow:hidden` spans and translates an inner block. Here\n//! each character is its own column: a `<Group clip={clipRect(cell, cell)}>`\n//! window (one glyph tall) with the reel — a vertical stack of `<Text>`s —\n//! translated upward inside it. The window masks every glyph except the one\n//! currently aligned to row 0.\n//! - The columns are positioned ABSOLUTELY at explicit `x` (an estimated\n//! monospace cell advance) rather than via `<Flex>`. The reel translates and\n//! glyphs change every frame, so a Flex would reflow/jiggle (HARD RULE 2);\n//! explicit x keeps the reels rock-steady and column-aligned. The engine\n//! measures text at render time but a pure frame→scene function can't read\n//! those measurements back, so cell width is estimated like `Marquee`\n//! (`fontSize * CELL_W`). A monospace stack keeps the estimate honest.\n//! - Filler glyphs are seeded with `random(seed + …)` from `@onda-engine/react`\n//! (deterministic, §1) so the spin is identical every render. ondajs uses a\n//! `seededRandom(seed)` *generator* pulled `reelLength` times; here each\n//! filler gets a distinct composite seed — same spirit, same determinism.\n//! - Reel direction: ondajs maps the spring to `ty ∈ [-reelLength*cell, 0]`,\n//! which settles on the FIRST filler rather than the target. This port maps\n//! `ty ∈ [0, -reelLength*cell]` so it actually lands on the target glyph (the\n//! component's documented purpose). See `approximations`.\n//! - No CSS `letter-spacing` / `line-height` / `text-align`: spacing is folded\n//! into the cell advance, vertical centering into a per-glyph nudge, and\n//! `align` into the block's horizontal anchor.\n//!\n//! Pivot caveat: the whole reel block is anchored from its top-left local origin\n//! and offset into place via `x`/`y`; there is no centered scale/rotate here, so\n//! the local-origin pivot rule doesn't bite.\n\nimport {\n Ellipse,\n Flex,\n Group,\n Text,\n clipRect,\n interpolate,\n parseColor,\n radialGradient,\n random,\n spring,\n useCurrentFrame,\n useVideoConfig,\n variantSeed,\n} from '@onda-engine/react'\nimport { fitMaxWidth } from '../bounds.js'\nimport { layoutGlyphLine } from '../glyph-line.js'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { staggeredSettle, useTimeScale } from '../timing.js'\n\n/** Estimated cell advance as a fraction of font size — the per-character column\n * width. Tuned for a monospace/display stack (matches the spirit of `Marquee`'s\n * `AVG_CHAR_W`); only needs to be roughly proportional to keep reels aligned.\n * Bumped a touch over the original `0.62` so the landed digits breathe — premium\n * display type wants air between columns, not a cramped odometer. */\nconst CELL_W = 0.7\n\nexport interface SlotMachineRollProps extends TextStyleProps {\n /** The text that rolls into place. Best on short strings (years, counts). */\n text?: string\n /** Time before rolling starts — frames or '0.5s'. */\n delay?: TimeInput\n /** Time between successive characters starting their roll (default the house\n * `STAGGER` = 5 frames — a settled, orchestrated wave left-to-right). */\n charDelay?: TimeInput\n /** Time for each character's reel to settle (default `DURATION.slower` = 34\n * frames — a slow, hard-decelerating odometer drop, not a constant-velocity\n * spin). */\n durationInFrames?: TimeInput\n /** Compress the whole timing envelope (delay, stagger, durations) so the\n * entrance settles at least `hold` before the end of the enclosing clip\n * (`useVideoConfig().durationInFrames`, Sequence-scoped). Opt-in. */\n fitToClip?: boolean\n /** Hard cap on the settle time (frames or '0.5s'). Wins over `fitToClip`. */\n maxSettle?: TimeInput\n /** Breathing room before the cut for `fitToClip` (default 6 frames). */\n hold?: TimeInput\n /** How many filler glyphs spin past before the target lands. */\n reelLength?: number\n /** Seed for the (deterministic) filler glyphs. */\n seed?: number\n /** Integer \"take\" selector: derives a new deterministic seed from (seed,\n * variant), so alternates never require hand-edited magic seeds. 0/omitted\n * = the default take (identical to today's output). */\n variant?: number\n /** Glyph pool the reel spins through. */\n charset?: string\n /** Font size in px (default 140). The cell height equals this. */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * line cannot exceed the frame minus the safe margins. Default `'none'`\n * (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the line; combines with `fit` (the smaller\n * cap wins). */\n maxWidth?: number\n /** Render a soft accent bloom behind the landed row. Default `false` — OFF.\n * It was a filled ellipse at half opacity faking a glow, so it read as a\n * muddy lozenge (a shape, not light), not a real radial falloff. Opt in with\n * `true` only if you know a theme's accent wants it. */\n glow?: boolean\n /** Horizontal anchoring of the whole block (default `'center'`). Only applies\n * to the legacy `x` anchor — `placement` always anchors the block's center. */\n align?: 'left' | 'center' | 'right'\n /** Where the row sits: a region keyword (`'center'`, `'lower-third'`,\n * `'top-left'`, …) or normalized `{x,y}` (0–1, block center). The shared\n * placement contract; default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias — absolute x of the block's anchor in px\n * (respecting `align`). Prefer `placement`. */\n x?: number\n /** @deprecated Legacy alias — absolute y of the block's top in px. Prefer\n * `placement`. */\n y?: number\n}\n\nexport function SlotMachineRoll({\n text: textProp = '2026',\n delay: delayIn = 0,\n charDelay: charDelayIn = STAGGER,\n durationInFrames: durationIn = DURATION.slower,\n fitToClip,\n maxSettle,\n hold,\n reelLength = 12,\n seed: seedProp = 7,\n variant,\n charset = '0123456789',\n color: colorProp,\n fontSize: fontSizeProp = 140,\n fit,\n maxWidth,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n glow = false,\n align = 'center',\n placement,\n x,\n y,\n}: SlotMachineRollProps) {\n const text = applyTextCase(textProp, { uppercase })\n // The variant knob derives an alternate deterministic seed (identity at 0).\n const seed = variantSeed(seedProp, variant)\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n const chars = [...text]\n\n // Timing: parse the TimeInput props, then compress the WHOLE envelope when\n // the entrance (incl. the glow payoff) wouldn't land inside the clip.\n const delayBase = framesOf(delayIn, fps)\n const charDelayBase = framesOf(charDelayIn, fps, STAGGER)\n const durationBase = framesOf(durationIn, fps, DURATION.slower)\n const naturalSettle =\n staggeredSettle(chars.length, charDelayBase, durationBase, delayBase) + (DURATION.base - 8)\n const timeScale = useTimeScale(naturalSettle, { fitToClip, maxSettle, hold })\n const delay = delayBase * timeScale\n const charDelay = charDelayBase * timeScale\n const durationInFrames = Math.max(1, durationBase * timeScale)\n\n // Opt-in auto-fit: the row's estimated width is proportional to the font\n // size (fixed cell advances), so the cap resolves in closed form.\n const unitsW = chars.reduce((sum, ch) => sum + (ch === ' ' ? CELL_W * 0.65 : CELL_W), 0)\n const cap = fitMaxWidth({ fit, maxWidth }, width)\n const fontSize =\n cap !== undefined && unitsW > 0 && fontSizeProp * unitsW > cap\n ? Math.max(1, cap / unitsW)\n : fontSizeProp\n\n const cell = fontSize\n\n // Per-character cell advance. Spaces are a narrower gap (matches ondajs's\n // `cell * 0.4`); everything else gets a full estimated cell.\n const advance = (ch: string): number => (ch === ' ' ? cell * CELL_W * 0.65 : cell * CELL_W)\n\n // Lay out columns on the SHARED glyph-line primitive — fixed cell advances\n // (column-locked reels), so the family shares ONE layout/alignment path.\n const laid = layoutGlyphLine(text, fontSize, { cellAdvance: advance })\n const totalWidth = laid.width\n\n // Anchor the block on the shared placement contract (block CENTER at the\n // resolved point; corner regions sit flush on the safe margin). Legacy px\n // `x`/`y` win per-axis when given: `align` decides which edge `x` pins, `y`\n // pins the block's top — exactly the pre-placement behavior.\n const resolved = usePlacement(placement, { width: totalWidth, height: cell })\n // `placement` is authoritative when set; the legacy pixel `x`/`y` apply ONLY\n // in the pre-placement path (no `placement`). Otherwise a stray `x`/`y` would\n // silently override an explicit placement (a 0.5 meant as a fraction reads as\n // 0.5 px → top-left).\n const useLegacy = placement === undefined\n const originX =\n useLegacy && x !== undefined\n ? align === 'left'\n ? x\n : align === 'right'\n ? x - totalWidth\n : x - totalWidth / 2\n : resolved.originX\n const originY = useLegacy && y !== undefined ? y : Math.round(resolved.originY)\n\n const local = frame - delay\n\n // One earned accent: a soft, low-opacity glow that blooms behind the landed row\n // as the reels settle — the only color in the piece (the digits stay near-white).\n // It eases in on the house spring once the LAST column has nominally landed, so\n // the bloom reads as the payoff of the roll, not a competing entrance.\n const lastStart = staggerFrames(Math.max(0, laid.cells.length - 1), charDelay)\n const glowP = spring({\n frame: local - lastStart - durationInFrames + 8,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n const glowOpacity = interpolate(glowP, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n // A REAL bloom (not a solid ellipse): a circular accent falloff to FULLY\n // TRANSPARENT — so you read light, not a lozenge — stretched wide to hug the\n // row. The shape edge sits where the gradient is already transparent, so it's\n // invisible; the spring drives the reveal, the stop alphas set the softness.\n const glowCx = totalWidth / 2\n const glowCy = cell / 2\n const glowR = cell * 1.1\n const glowScaleX = Math.max(1, (totalWidth / 2 + cell * 0.45) / glowR)\n const accentRGB = parseColor(theme.accent)\n\n return (\n <Group x={originX} y={originY}>\n {/* One earned accent (opt-in via `glow`): a soft radial bloom behind the\n landed row. A circular accent falloff to FULLY TRANSPARENT — light, not\n a shape — stretched wide to hug the row. No hard body, no drop-shadow\n (those made it a muddy lozenge). Drawn first; digits read on top. */}\n {glow && (\n <Group originX={glowCx} originY={glowCy} scaleX={glowScaleX} scaleY={0.92}>\n <Ellipse\n x={glowCx - glowR * 1.1}\n y={glowCy - glowR * 1.1}\n width={glowR * 2.2}\n height={glowR * 2.2}\n opacity={glowOpacity}\n gradient={radialGradient([glowR * 1.1, glowR * 1.1], glowR, [\n { offset: 0, color: { ...accentRGB, a: 0.42 } },\n { offset: 0.45, color: { ...accentRGB, a: 0.14 } },\n { offset: 1, color: { ...accentRGB, a: 0 } },\n ])}\n />\n </Group>\n )}\n {laid.cells.map(({ ch, index: i, x: localX, space }) => {\n // Spaces occupy advance but render nothing — no reel, no window.\n if (space) return null\n\n // Build this column's reel: `reelLength` deterministic fillers from the\n // charset, then the target glyph the reel lands on. Each filler gets a\n // distinct composite seed (stable per render).\n const pool = [...charset]\n const reel: string[] = []\n for (let k = 0; k < reelLength; k++) {\n const r = random(seed + i * 7919 + k * 31 + 1)\n const idx = Math.min(pool.length - 1, Math.floor(r * pool.length))\n reel.push(pool[idx] ?? ch)\n }\n reel.push(ch)\n\n // House spring, staggered per character on the house cadence. The reel\n // translates from the top filler (ty = 0) down to landing on the target\n // (ty = -reelLength*cell). The spring decelerates HARD into rest — a slow\n // odometer drop, never constant-velocity — so the digit settles, not spins.\n const charStart = staggerFrames(i, charDelay)\n const localChar = local - charStart\n const p = spring({\n frame: localChar,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames,\n })\n // The reel lands cleanly on the target: the spring's hard deceleration is\n // the whole settle — the digit drops in and stops, no past-target kick.\n const ty = interpolate(p, [0, 1], [0, -reelLength * cell], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // Window is EXACTLY one cell tall, anchored at the column origin, so the\n // block stays vertically centered via `originY`. The reel translates\n // inside it; each glyph sits in its own `cell`-tall <Flex> cell that the\n // ENGINE centers (no font-metric estimate), so the landed row is centered\n // in the band and its neighbours — a full `cell` away — are fully masked.\n return (\n <Group key={`${i}-${ch}`} x={localX} clip={clipRect(advance(ch), cell)}>\n <Group y={ty}>\n {reel.map((g, k) => (\n <Flex\n key={k}\n y={k * cell}\n width={advance(ch)}\n height={cell}\n justify=\"center\"\n align=\"center\"\n >\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {g}\n </Text>\n </Flex>\n ))}\n </Group>\n </Group>\n )\n })}\n </Group>\n )\n}\n","//! SplitScreen — two side-by-side (or stacked) content panes divided by a thin\n//! token line. Ported from ondajs (`split-screen`).\n//!\n//! A container — the documented exception to the \"self-contained\" rule, since\n//! wrapping arbitrary `left`/`right` content (any scene subtree) is its whole\n//! job. The two panes are positioned ABSOLUTELY with explicit x/y (not `<Flex>`):\n//! when `animate`, each pane translates a few px every frame, and a layout\n//! container would reflow as the measured bbox shifted. Pane sizes are derived\n//! from the overall `width`/`height`, `ratio`, `gap`, and `divider` so the math\n//! is deterministic and frame-pure.\n//!\n//! Entrance: matching ondajs, the panes start pulled IN toward the center seam\n//! and SPREAD APART to settle — the left/top pane starts displaced toward the\n//! center and slides out to the left/top, the right/bottom pane starts toward\n//! the center and slides out to the right/bottom — a 16px travel on the house\n//! spring. (ondajs drives this via `useEntrance({type:'slide', direction:'left'})`\n//! for the first pane and `'right'` for the second; in its `entrySlide` the sign\n//! convention has `'up'`/`'left'` start at `+distance`, so both panes begin near\n//! the seam.) Each pane is clipped to its own rect so animated/overflowing\n//! content stays inside its panel.\n//!\n//! Approximations vs ondajs (CSS):\n//! - The empty-pane placeholder label uses `letterSpacing` in ondajs; the\n//! engine has no letter-spacing, so the placeholder is drawn without it, and\n//! its horizontal centering is estimated from glyph advance (a pure\n//! frame→scene function can't read the engine's measured text box back).\n//! - ondajs honors a `placement` prop via `PlacementBox`; like the other ports\n//! (Spotlight, Marquee) this centers the box in the composition instead.\n\nimport {\n Group,\n Rect,\n Text,\n clipRect,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport type { ReactNode } from 'react'\nimport { DURATION, SPRING_SMOOTH } from '../motion.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface SplitScreenProps extends TextStyleProps {\n /** Content for the left (or top) pane — any scene subtree. */\n left?: ReactNode\n /** Content for the right (or bottom) pane — any scene subtree. */\n right?: ReactNode\n /** Pane axis: `horizontal` = side-by-side, `vertical` = stacked. */\n orientation?: 'horizontal' | 'vertical'\n /** Fraction (0..1) of the main axis given to the `left` (or top) pane. */\n ratio?: number\n /** Gap between the two panes in px. */\n gap?: number\n /** Draw a thin token divider in the gap between the panes. */\n divider?: boolean\n /** Slide the two panes apart from the center seam on the house spring. */\n animate?: boolean\n /** Frames before the entrance. */\n delay?: TimeInput\n /** Overall width in px. Defaults to the full composition width. */\n width?: number\n /** Overall height in px. Defaults to the full composition height. */\n height?: number\n /** Pane background fill (default: theme `surface`). */\n paneBackground?: string\n /** Outer (gutter) background fill, seen in the gap behind the divider (default: theme `background`). */\n background?: string\n /** Divider color (thin token line) (default: theme `border`). */\n dividerColor?: string\n /** Placeholder label color for an empty pane (default: theme `textMuted`). */\n placeholderColor?: string\n}\n\n/** House-spring travel for the pane entrance, in px (matches ondajs). */\nconst TRAVEL = 16\n\n/** Default pane fill — a lifted surface that reads against the dark canvas\n * (the theme `surface` token sits too close to `background` when used bare). */\nconst PANE_FILL = '#1b1e2a'\n/** Default divider/pane-edge color — a brighter hairline than `border` so the\n * seam and panel edges register on the dark canvas. */\nconst PANE_EDGE = '#3a4055'\n\nexport function SplitScreen({\n left,\n right,\n orientation = 'horizontal',\n ratio = 0.5,\n gap = 0,\n divider = true,\n animate = true,\n delay: delayIn = 0,\n width,\n height,\n paneBackground: paneBackgroundProp,\n background: backgroundProp,\n dividerColor: dividerColorProp,\n placeholderColor: placeholderColorProp,\n fontFamily: fontFamilyProp,\n}: SplitScreenProps) {\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n // The house `surface`/`border` tokens are tuned to sit *on* a card; alone on\n // the bare canvas they're nearly invisible (surface ≈ background, and the\n // hairline border vanishes), so the two-pane structure reads as flat dark.\n // Lift the pane fill a notch above `surface` and brighten the divider/edge so\n // the split reads clearly against the dark canvas. Explicit props still win.\n const paneBackground = paneBackgroundProp ?? PANE_FILL\n const background = backgroundProp ?? theme.background\n const dividerColor = dividerColorProp ?? PANE_EDGE\n const placeholderColor = placeholderColorProp ?? theme.textMuted\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n // Outer container corner radius in px (matches ondajs `borderRadius`). The\n // engine's `clipRect` takes an optional corner radius, so the rounded\n // container is reproduced faithfully.\n const OUTER_RADIUS = theme.radius ?? 20\n\n const boxWidth = width ?? compWidth\n const boxHeight = height ?? compHeight\n\n const horizontal = orientation === 'horizontal'\n\n // Clamp ratio defensively so a bad value never produces a negative pane.\n const r = Math.max(0, Math.min(1, ratio))\n\n // Thickness of the divider band (only when shown), measured on the main axis.\n // A 2px seam reads as a deliberate token line on the dark canvas (a 1px line\n // washes out at this contrast).\n const dividerThickness = divider ? 2 : 0\n\n // Main-axis length to split between the two panes, after removing the gap and\n // the divider band. The full gap holds both the gutter and the divider line.\n const mainAxis = horizontal ? boxWidth : boxHeight\n const crossAxis = horizontal ? boxHeight : boxWidth\n const splittable = Math.max(0, mainAxis - gap - dividerThickness)\n const firstLen = splittable * r\n const secondLen = splittable - firstLen\n\n // The first pane starts at 0; the second pane sits past the first + gap +\n // divider band. The divider line is centered in the gutter, on the boundary.\n const firstOffset = 0\n const secondOffset = firstLen + gap + dividerThickness\n const dividerOffset = firstLen + gap / 2\n\n // Center the whole box in the composition (ondajs uses PlacementBox; the ports\n // center — see header). Rounded to whole px so edges stay crisp.\n const boxX = Math.round((compWidth - boxWidth) / 2)\n const boxY = Math.round((compHeight - boxHeight) / 2)\n\n // Entrance progress on the house spring (no overshoot), shared by both panes.\n const progress = animate\n ? spring({\n frame: Math.max(0, frame - delay),\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: DURATION.base,\n })\n : 1\n const opacity = interpolate(progress, [0, 1], [0, 1], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n // Panes start pulled IN toward the center seam and SPREAD APART to settle\n // (matching ondajs's `entrySlide` sign convention: `'left'`/`'up'` start at\n // `+distance`, `'right'`/`'down'` at `-distance`). So the first (left/top)\n // pane starts toward the center (positive) and eases out to its rest position,\n // and the second (right/bottom) pane starts toward the center (negative) and\n // eases out the other way; both ease to 0.\n const firstTravel = interpolate(progress, [0, 1], [TRAVEL, 0], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n const secondTravel = interpolate(progress, [0, 1], [-TRAVEL, 0], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n return (\n <Group x={boxX} y={boxY} clip={clipRect(boxWidth, boxHeight, OUTER_RADIUS)}>\n {/* Gutter background — seen in the gap behind the divider. */}\n <Rect width={boxWidth} height={boxHeight} cornerRadius={OUTER_RADIUS} fill={background} />\n\n {/* First pane (left when horizontal, top when vertical). */}\n <Pane\n x={horizontal ? firstOffset : 0}\n y={horizontal ? 0 : firstOffset}\n width={horizontal ? firstLen : crossAxis}\n height={horizontal ? crossAxis : firstLen}\n content={left}\n label={horizontal ? 'Left' : 'Top'}\n opacity={opacity}\n translateX={horizontal ? firstTravel : 0}\n translateY={horizontal ? 0 : firstTravel}\n background={paneBackground}\n edge={dividerColor}\n placeholderColor={placeholderColor}\n fontFamily={fontFamily}\n />\n\n {/* Divider line, centered on the boundary and stretched across the cross\n axis. Drawn over the panes so the seam reads as a thin token line. */}\n {divider ? (\n <Rect\n x={horizontal ? dividerOffset : 0}\n y={horizontal ? 0 : dividerOffset}\n width={horizontal ? dividerThickness : crossAxis}\n height={horizontal ? crossAxis : dividerThickness}\n fill={dividerColor}\n />\n ) : null}\n\n {/* Second pane (right when horizontal, bottom when vertical). */}\n <Pane\n x={horizontal ? secondOffset : 0}\n y={horizontal ? 0 : secondOffset}\n width={horizontal ? secondLen : crossAxis}\n height={horizontal ? crossAxis : secondLen}\n content={right}\n label={horizontal ? 'Right' : 'Bottom'}\n opacity={opacity}\n translateX={horizontal ? secondTravel : 0}\n translateY={horizontal ? 0 : secondTravel}\n background={paneBackground}\n edge={dividerColor}\n placeholderColor={placeholderColor}\n fontFamily={fontFamily}\n />\n </Group>\n )\n}\n\n/** A single pane: a background rect + its content (or a centered placeholder\n * label), clipped to its own rect so content can't bleed past the panel. The\n * entrance translate is applied on an inner `<Group>` while the outer `<Group>`\n * holds the layout position — so the clip stays put as the content slides. */\nfunction Pane({\n x,\n y,\n width,\n height,\n content,\n label,\n opacity,\n translateX,\n translateY,\n background,\n edge,\n placeholderColor,\n fontFamily,\n}: {\n x: number\n y: number\n width: number\n height: number\n content?: ReactNode\n label: string\n opacity: number\n translateX: number\n translateY: number\n background: string\n edge: string\n placeholderColor: string\n fontFamily?: string\n}) {\n // Below ~1px on either axis the pane is degenerate (e.g. ratio at an extreme);\n // skip it so a zero-size clip never produces artefacts.\n if (width < 1 || height < 1) return null\n\n // Placeholder label sizing/position when the pane has no content.\n const placeholderSize = 28\n // Letter-spacing (ondajs `0.04em`); widens the line by `tracking × (glyphs−1)`,\n // folded into the centering so the placeholder stays centered.\n const placeholderTracking = placeholderSize * 0.04\n const labelX = Math.round(\n (width -\n (label.length * placeholderSize * 0.6 +\n placeholderTracking * Math.max(0, label.length - 1))) /\n 2,\n )\n const labelY = Math.round((height - placeholderSize) / 2)\n\n return (\n <Group x={x} y={y} clip={clipRect(width, height)}>\n {/* Pane fill + a faint edge stroke so the panel reads against the canvas\n (the house \"surface + 1px border\" pattern). */}\n <Rect width={width} height={height} fill={background} stroke={edge} strokeWidth={1} />\n <Group x={translateX} y={translateY} opacity={opacity}>\n {content ?? (\n <Text\n x={labelX}\n y={labelY}\n fontSize={placeholderSize}\n letterSpacing={placeholderTracking}\n color={placeholderColor}\n fontFamily={fontFamily}\n fontWeight={500}\n >\n {label}\n </Text>\n )}\n </Group>\n </Group>\n )\n}\n","//! Spotlight — a soft radial light that grows from radius 0 to its target on the\n//! house spring. Ported from ondajs.\n//!\n//! A full-composition `<Rect>` filled with a radial gradient that is alpha-aware:\n//! solid `color` at the center, fading to transparent at the lit edge. This is a\n//! reveal, not a fill — anything rendered beneath stays visible outside the disc.\n//!\n//! ondajs renders this as a CSS `radial-gradient` on an `AbsoluteFill`. Here the\n//! same shape is expressed as a scene `radialGradient` on a canvas-sized `Rect`,\n//! with the gradient's `radius` (not the Rect) animating — so the node's measured\n//! size never changes and no layout reflow occurs.\n//!\n//! Backend caveat: gradients render only on the Vello/GPU backend. The CPU\n//! reference rasterizer collapses a gradient to its first stop (the solid light\n//! color), so the soft reveal is a GPU-only effect.\n\nimport { Rect, radialGradient, useVideoConfig } from '@onda-engine/react'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface SpotlightProps {\n /** Horizontal center of the spotlight as a 0–1 fraction of canvas width. */\n x?: number\n /** Vertical center of the spotlight as a 0–1 fraction of canvas height. */\n y?: number\n /** Final radius as a percentage of the canvas's smaller dimension. */\n radius?: number\n /** Frames before the reveal starts. */\n delay?: TimeInput\n /** Frames until the spotlight reaches its full radius. */\n durationInFrames?: TimeInput\n /** Light color (default: theme `text`). Hex `#rrggbb` / `#rrggbbaa`. */\n color?: string\n /** Gradient softness — % of the radius given over to the fade-to-transparent\n * tail. `0` is a hard disc; `100` fades from the very center. */\n softness?: number\n}\n\nexport function Spotlight({\n x = 0.5,\n y = 0.5,\n radius = 40,\n delay = 0,\n durationInFrames = DURATION.slow,\n color: colorProp,\n softness = 60,\n}: SpotlightProps) {\n const { width, height } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n\n // House spring (SPRING_SMOOTH, no overshoot), matching ondajs.\n const progress = useSpringValue({ delay, durationInFrames })\n\n // Map the % radius onto the smaller canvas dimension so the spotlight reads\n // the same regardless of aspect ratio, then grow it 0 → target.\n const minDimension = Math.min(width, height)\n const radiusPx = progress * (radius / 100) * minDimension\n\n // Center in the Rect's local space (the Rect is the full canvas at origin).\n const cx = x * width\n const cy = y * height\n\n // The inner solid stop holds `color` for the first (100 - softness)% of the\n // radius, then fades to transparent across the last `softness`%.\n const innerOffset = Math.min(1, Math.max(0, 1 - softness / 100))\n\n // A transparent version of `color`: same RGB, zero alpha. Append/replace the\n // 2-hex alpha channel so the fade is to fully transparent (not to black).\n const transparent = toTransparent(color)\n\n // Below ~1px the gradient is degenerate; render a fully-transparent fill until\n // the disc opens (visually identical to \"no light yet\").\n if (radiusPx < 1) {\n return <Rect width={width} height={height} fill={transparent} />\n }\n\n // Three stops, always ending transparent: solid `color` from the center out to\n // `innerOffset`, then fading to transparent at offset 1. The engine pads a\n // gradient's LAST stop beyond `radius` (peniko `Extend::Pad`), so the\n // transparent tail must be the final stop — otherwise the canvas-sized Rect\n // would fill opaque beyond the disc and the reveal would become a fill. At\n // `softness=0` the solid stop sits at offset 1 alongside the transparent one\n // (a hard disc edge), matching ondajs's CSS `color radiusPx, transparent\n // radiusPx`.\n return (\n <Rect\n width={width}\n height={height}\n gradient={radialGradient([cx, cy], radiusPx, [\n { offset: 0, color },\n { offset: innerOffset, color },\n { offset: 1, color: transparent },\n ])}\n />\n )\n}\n\n/** Return `color` with its alpha channel forced to `00` (fully transparent),\n * preserving the RGB so the gradient fades out rather than toward black. */\nfunction toTransparent(color: string): string {\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}00`\n }\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}00`\n }\n }\n // Unknown format — fall back to a known-transparent value.\n return '#00000000'\n}\n","//! SpotlightCard — a glass card with a spotlight drifting behind the content,\n//! the card rising in on the house spring while the title/body fade in on top.\n//! Ported from ondajs.\n//!\n//! Composes the ported `<Spotlight>` (a soft radial reveal) as the card's\n//! living background and `<FadeIn>` for the content, matching the ondajs\n//! `Surface variant=\"glass\"` + drifting `Glow` recipe.\n//!\n//! Self-positioning: the card is centered on the composition (ondajs's default\n//! center placement). The whole card rises + fades in on the house spring\n//! (`SPRING_SMOOTH`, via `useSpringValue`); the spotlight keeps drifting\n//! (sin/cos of the frame) so the surface feels alive without competing for\n//! attention, exactly as in the original.\n//!\n//! Layout: the card is positioned absolutely with explicit x/y (not a Flex) so\n//! its measured size never drives a reflow, and so the card's local origin can\n//! sit at its top-left for the rounded-rect clip. The content inside is stacked\n//! with manual y offsets (the engine `<Text>` is single-line and not auto-laid\n//! out here) so eyebrow/title/body keep a stable rhythm every frame.\n//!\n//! Scale/clip caveat: scale & clip anchor on the node's LOCAL ORIGIN (0,0). The\n//! card Group's origin is its top-left, so the rise (a translate) is origin-safe;\n//! no centered scale is applied to the card itself.\n//!\n//! Engine approximations vs the ondajs (CSS) original:\n//! - The \"glass\" frost: this card is a translucent rounded `Rect` fill plus a\n//! 1px border `stroke` (it doesn't blur what's behind it). The engine now ships\n//! a `backdropBlur` node prop (real frosted glass) it could adopt for the frost.\n//! - The CSS `box-shadow` elevation and the 1px top `SHEEN` highlight are\n//! omitted (no box-shadow / inset-gradient primitive); the border stroke\n//! carries the surface edge.\n//! - `letter-spacing` (the uppercase eyebrow tracking) is unsupported; the\n//! eyebrow is rendered without extra tracking.\n//! - The drifting glow is a GPU-only soft reveal (the CPU reference collapses a\n//! gradient to its first stop — see `<Spotlight>`).\n\nimport { Group, Rect, Text, clipRect, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION, staggerFrames } from '../motion.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { FadeIn } from './FadeIn.js'\nimport { Spotlight } from './Spotlight.js'\n\n/** Engine line-box height as a multiple of font size (matches typography crate). */\nconst LINE_RATIO = 1.2\n\nexport interface SpotlightCardProps extends TextStyleProps {\n /** Small uppercase kicker above the title. Empty hides it. */\n eyebrow?: string\n /** Card headline (display font). */\n title?: string\n /** Supporting body copy. Empty hides it. Single line (engine `<Text>` is\n * single-line; pass a short string). */\n body?: string\n /** Frames before the card enters. */\n delay?: TimeInput\n /** The drifting spotlight color — the earned accent (default: theme `accent`). */\n glowColor?: string\n /** Card width in px. */\n width?: number\n /** Card height in px. If omitted, sized from the content + padding. */\n height?: number\n /** Inner padding in px. */\n padding?: number\n /** Text alignment within the card. */\n align?: 'left' | 'center'\n /** Font family for the eyebrow + body copy (default: theme `fontFamily`). */\n bodyFontFamily?: string\n /** Title font size in px (default 44). */\n titleSize?: number\n /** Body font size in px (default 20). */\n bodySize?: number\n /** Eyebrow font size in px (default 15). */\n eyebrowSize?: number\n /** Title color (default: theme `text`). */\n titleColor?: string\n /** Body color (default: theme `textMuted`). */\n bodyColor?: string\n /** Eyebrow color (default: theme `textMuted`). */\n eyebrowColor?: string\n /** Card glass fill (translucent dark by default) (default: theme `surface`). */\n background?: string\n /** Card border (stroke) color (default: theme `border`). */\n borderColor?: string\n /** Corner radius in px (default: theme `radius`). */\n cornerRadius?: number\n}\n\nexport function SpotlightCard({\n eyebrow = 'FEATURE',\n title = 'Motion identity',\n body = 'One consistent feel across every component.',\n delay: delayIn = 0,\n glowColor: glowColorProp,\n width = 560,\n height,\n padding = 48,\n align = 'left',\n fontFamily: fontFamilyProp,\n letterSpacing,\n uppercase,\n bodyFontFamily: bodyFontFamilyProp,\n titleSize = 44,\n bodySize = 20,\n eyebrowSize = 15,\n titleColor: titleColorProp,\n bodyColor: bodyColorProp,\n eyebrowColor: eyebrowColorProp,\n background: backgroundProp,\n borderColor: borderColorProp,\n cornerRadius: cornerRadiusProp,\n}: SpotlightCardProps) {\n const frame = useCurrentFrame()\n const { width: compWidth, height: compHeight, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const glowColor = glowColorProp ?? theme.accent\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n const bodyFontFamily = bodyFontFamilyProp ?? theme.fontFamily\n const titleColor = titleColorProp ?? theme.text\n const bodyColor = bodyColorProp ?? theme.textMuted\n const eyebrowColor = eyebrowColorProp ?? theme.textMuted\n const background = backgroundProp ?? theme.surface\n const borderColor = borderColorProp ?? theme.border\n const cornerRadius = cornerRadiusProp ?? theme.radius\n\n // ── Content layout (manual stacking; engine <Text> is single-line) ─────────\n const hasEyebrow = eyebrow.length > 0\n const hasBody = body.length > 0\n const eyebrowGap = 14 // marginBottom under the eyebrow (matches ondajs)\n const bodyGap = 16 // marginTop above the body (matches ondajs)\n\n const eyebrowLine = eyebrowSize * LINE_RATIO\n const titleLine = titleSize * LINE_RATIO\n const bodyLine = bodySize * LINE_RATIO\n\n // Running vertical cursor for each content line, top of the padding box down.\n let cursor = 0\n const eyebrowY = cursor\n if (hasEyebrow) cursor += eyebrowLine + eyebrowGap\n const titleY = cursor\n cursor += titleLine\n if (hasBody) cursor += bodyGap\n const bodyY = cursor\n if (hasBody) cursor += bodyLine\n const contentHeight = cursor\n\n // Card dimensions: explicit, or content + padding. Absolute layout, so an\n // animated size would NOT reflow anything — but the card size is static here.\n const cardWidth = width\n const cardHeight = height ?? contentHeight + padding * 2\n\n // Centered on the composition (ondajs's default center placement).\n const baseX = Math.round((compWidth - cardWidth) / 2)\n const baseY = Math.round((compHeight - cardHeight) / 2)\n\n // ── Card entrance: rise + fade on the house spring (ondajs `useEntrance` rise).\n const entrance = useSpringValue({ delay, durationInFrames: DURATION.slow })\n const cardOpacity = entrance\n const riseY = (1 - entrance) * 16 // translate up into place (16px envelope)\n\n // ── Drifting spotlight center, in composition fractions, centered on the card.\n // Reproduces ondajs's `0.5 + sin(f*0.02)*0.22`, `0.4 + cos(f*0.016)*0.16`\n // but anchored to the card's center rather than the whole canvas.\n const cardCenterFracX = (baseX + cardWidth / 2) / compWidth\n const cardCenterFracY = (baseY + cardHeight / 2) / compHeight\n // Drift amplitude in fractions of the SMALLER card axis, mapped to comp space.\n const driftX = (Math.sin(frame * 0.02) * 0.22 * cardWidth) / compWidth\n const driftY = (Math.cos(frame * 0.016) * 0.16 * cardHeight) / compHeight\n const glowX = cardCenterFracX + driftX\n const glowY = cardCenterFracY + driftY\n // Spotlight radius as a % of the smaller comp dimension that roughly matches\n // ondajs's `size={0.9}` glow (~0.9 of the card's smaller axis).\n const minCard = Math.min(cardWidth, cardHeight)\n const minComp = Math.min(compWidth, compHeight)\n const glowRadiusPct = ((0.9 * minCard) / minComp) * 100\n\n // Text x within the padding box (left-aligned vs centered).\n const innerWidth = cardWidth - padding * 2\n const textX = align === 'center' ? Math.round(innerWidth / 2) : 0\n\n return (\n <Group x={baseX} y={baseY} opacity={cardOpacity}>\n {/* Rise translate nested inside the layout-positioned group (translate-safe:\n this group is positioned by explicit x/y above, not by a Flex). */}\n <Group y={riseY}>\n {/* Glass surface: translucent fill + 1px border + a soft drop-shadow for\n elevation (ondajs's box-shadow; backdrop-blur stays a non-goal). */}\n <Rect\n width={cardWidth}\n height={cardHeight}\n cornerRadius={cornerRadius}\n fill={background}\n stroke={borderColor}\n strokeWidth={1}\n shadow={{ color: '#00000059', blur: 28, offsetY: 12 }}\n />\n\n {/* Drifting spotlight behind the content, clipped to the card's rounded\n rect. The spotlight renders at composition scale (its Rect + gradient\n are sized to the comp via useVideoConfig); counter-translate it back\n to the composition origin so it aligns, while the clip — anchored to\n this group's local origin (the card top-left) — masks it to the card. */}\n <Group clip={clipRect(cardWidth, cardHeight, cornerRadius)}>\n <Group x={-baseX} y={-(baseY + riseY)} opacity={0.28}>\n <Spotlight\n x={glowX}\n y={glowY}\n radius={glowRadiusPct}\n delay={delay}\n durationInFrames={DURATION.slow}\n color={glowColor}\n softness={70}\n />\n </Group>\n </Group>\n\n {/* Content on top, fading in just after the card lands. Manual stacking;\n each <Text> is single-line. */}\n <Group x={padding} y={padding}>\n {hasEyebrow ? (\n <FadeIn delay={delay + staggerFrames(1)} durationInFrames={DURATION.base}>\n <Text\n x={textX}\n y={eyebrowY}\n fontSize={eyebrowSize}\n color={eyebrowColor}\n fontFamily={bodyFontFamily ?? fontFamily}\n fontWeight={500}\n >\n {eyebrow}\n </Text>\n </FadeIn>\n ) : null}\n\n <FadeIn delay={delay + staggerFrames(2)} durationInFrames={DURATION.base}>\n <Text\n x={textX}\n y={titleY}\n fontSize={titleSize}\n color={titleColor}\n fontFamily={fontFamily}\n fontWeight={600}\n letterSpacing={letterSpacing}\n >\n {applyTextCase(title, { uppercase })}\n </Text>\n </FadeIn>\n\n {hasBody ? (\n <FadeIn delay={delay + staggerFrames(3)} durationInFrames={DURATION.base}>\n <Text\n x={textX}\n y={bodyY}\n fontSize={bodySize}\n color={bodyColor}\n fontFamily={bodyFontFamily ?? fontFamily}\n fontWeight={400}\n >\n {body}\n </Text>\n </FadeIn>\n ) : null}\n </Group>\n </Group>\n </Group>\n )\n}\n","//! StaggerGroup — reveals a list of items in sequence on the canonical Onda\n//! stagger (`STAGGER` = 4 frames between siblings). Ported from ondajs.\n//!\n//! The composition primitive behind animated lists and sequenced reveals. Items\n//! are a `string[]`, rendered as styled `<Text>` and laid out by the engine's\n//! layout pass (taffy) via a single `<Flex>` (row or column). Each item enters\n//! with the workhorse Onda entrance — `entryFadeRise` (opacity + a ~12px upward\n//! rise on `SPRING_SMOOTH`) — offset by `staggerFrames(i, stagger)` so the eye\n//! reads the cascade as one continuous beat. The same stagger rhythm as\n//! `WordStagger`; keeping one cascade across the library is what makes the\n//! fingerprint readable.\n//!\n//! Layout-safe rise: the per-item motion is applied on an INNER `<Group y>` that\n//! is nested inside the direct `<Flex>` child. The layout pass only overwrites a\n//! direct child's x/y, so the inner group's translate survives; and because a\n//! translate is applied after layout, it does NOT change the item's measured box\n//! and so does NOT make the row/column reflow as the cascade runs. The opacity\n//! sits on the outer (layout-positioned) group, where it is always safe.\n//!\n//! This is NOT a `<Sequence>`-based component: every item renders on every frame\n//! and per-item visibility is driven by the staggered local frame fed into\n//! `entryFadeRise`, so frame N is correct with zero knowledge of frame N-1.\n\nimport {\n AbsoluteFill,\n Flex,\n Group,\n Text,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryFadeRise } from '../choreography.js'\nimport { DURATION, STAGGER, staggerFrames } from '../motion.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface StaggerGroupProps extends TextStyleProps {\n /** The items to reveal, in source order (default: four short lines). */\n items?: string[]\n /** Frames before the FIRST item starts (default 0). */\n delay?: TimeInput\n /** Frames between consecutive items. Canonical Onda stagger is `4`. */\n stagger?: TimeInput\n /** Per-item reveal duration (default `DURATION.base` = 18). */\n duration?: TimeInput\n /** Layout direction for the items (default `'column'`). */\n direction?: 'row' | 'column'\n /** Pixels between items (default 16). */\n gap?: number\n /** Cross-axis alignment of items (default `'center'`). */\n align?: 'start' | 'center' | 'end'\n /** Font size in px (default 48). */\n fontSize?: number\n}\n\nexport function StaggerGroup({\n items = ['Less is more', 'Calm is power', 'Motion has a feel', 'Made to be edited'],\n delay: delayIn = 0,\n stagger: staggerIn = STAGGER,\n duration: durationIn = DURATION.base,\n direction = 'column',\n gap = 16,\n align = 'center',\n color: colorProp,\n fontSize = 48,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n}: StaggerGroupProps) {\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const stagger = framesOf(staggerIn, fps)\n const duration = framesOf(durationIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n return (\n // Center the whole cascade in the composition. `AbsoluteFill` is a\n // full-size flex container; its center alignment positions the inner\n // `Flex` block. The inner `Flex` keeps `align` to control how the items\n // align relative to one another.\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Flex direction={direction} align={align} gap={gap}>\n {items.map((item, i) => {\n // Per-item entrance, staggered. `entryFadeRise` clamps at both ends, so\n // the item is correct before it starts and after it has settled.\n const { opacity, y } = entryFadeRise({\n frame,\n fps,\n delay: delay + staggerFrames(i, stagger),\n durationInFrames: duration,\n })\n return (\n // Outer group: positioned by the layout pass; carries opacity (safe).\n // Inner group: carries the rise translate (survives layout; no reflow).\n <Group key={i} opacity={opacity}>\n <Group y={y}>\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n >\n {item}\n </Text>\n </Group>\n </Group>\n )\n })}\n </Flex>\n </AbsoluteFill>\n )\n}\n","//! SplitLockup — two lines that START split to opposite corners, CONVERGE into a\n//! centered, stacked, left-aligned lockup (ease-out, no overshoot), HOLD for the\n//! body, then DISASSEMBLE back to the corners (the entrance reversed). The\n//! signature \"title that splits open and reassembles\" move — a motion BEHAVIOUR\n//! authored declaratively: feed it two words, the split distance, and the phase\n//! timings. Default `line1` sits upper-left, `line2` lower-right; they meet stacked\n//! and left-aligned in the center.\n//!\n//! Two things make or break it (the craft layer): the assemble eases OUT (no\n//! overshoot) and the disassemble is the SAME curve reversed (ease-in), so the\n//! exit reads as the entrance run backwards, not a different move.\n\nimport { Group, Text, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { layoutGlyphLine, lineStartX, lineTopY } from '../glyph-line.js'\nimport { useTextMetricsReady } from '../text-metrics.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface SplitLockupProps {\n /** Top line of the lockup (default 'NEW'). */\n line1?: string\n /** Bottom line of the lockup (default 'PROJECT'). */\n line2?: string\n /** Font size in px (default 200). */\n fontSize?: number\n /** Ink color (defaults to theme `text`). */\n color?: string\n fontFamily?: string\n fontWeight?: number\n /** Tracking in px — the look wants it generous (default fontSize × 0.04). */\n letterSpacing?: number\n /** How far each line pulls HORIZONTALLY to its corner, px from center\n * (default 26% of the frame width). */\n splitX?: number\n /** How far each line pulls VERTICALLY to its corner, px from center\n * (default 28% of the frame height). */\n splitY?: number\n /** Vertical gap between the two stacked lines in the lockup (default fontSize × 0.12). */\n lineGap?: number\n /** Time of the assemble (split → center) move (default '0.7s'). */\n assembleFrames?: TimeInput\n /** Time of the disassemble (center → split) move (default '0.5s'). */\n disassembleFrames?: TimeInput\n /** Total clip length; defaults to the enclosing Sequence duration. */\n durationInFrames?: TimeInput\n}\n\nconst clamp01 = (t: number): number => (t < 0 ? 0 : t > 1 ? 1 : t)\nconst easeOut = (t: number): number => 1 - (1 - clamp01(t)) ** 3\nconst easeIn = (t: number): number => clamp01(t) ** 3\nconst lerp = (a: number, b: number, t: number): number => a + (b - a) * t\n\ninterface Pt {\n x: number\n y: number\n}\n\nexport function SplitLockup({\n line1 = 'NEW',\n line2 = 'PROJECT',\n fontSize = 200,\n color,\n fontFamily,\n fontWeight = 500,\n letterSpacing,\n splitX,\n splitY,\n lineGap,\n assembleFrames,\n disassembleFrames,\n durationInFrames,\n}: SplitLockupProps) {\n const frame = useCurrentFrame()\n const { fps, width, height, durationInFrames: clipFrames } = useVideoConfig()\n const theme = useTheme()\n const ink = color ?? theme.text\n const family = fontFamily ?? theme.headingFamily ?? theme.fontFamily\n const tracking = letterSpacing ?? fontSize * 0.04\n\n useTextMetricsReady()\n const measure = { fontFamily: family, fontWeight }\n const widthOf = (s: string): number =>\n layoutGlyphLine(s, fontSize, measure).width + tracking * Math.max(0, s.length - 1)\n const w1 = widthOf(line1)\n const w2 = widthOf(line2)\n\n const total = durationInFrames != null ? framesOf(durationInFrames, fps) : clipFrames\n const assemble = Math.max(1, framesOf(assembleFrames ?? '0.7s', fps))\n const disassemble = Math.max(1, framesOf(disassembleFrames ?? '0.5s', fps))\n\n const cx = width / 2\n const cy = height / 2\n const gap = lineGap ?? fontSize * 0.12\n const step = fontSize + gap // vertical distance between the two line CENTERS\n\n // Lockup: left-aligned block, centered. Each line's CENTER position.\n const blockW = Math.max(w1, w2)\n const leftX = cx - blockW / 2\n const lock1: Pt = { x: leftX + w1 / 2, y: cy - step / 2 }\n const lock2: Pt = { x: leftX + w2 / 2, y: cy + step / 2 }\n\n // Split: line1 → upper-left, line2 → lower-right (line CENTERS).\n const sx = splitX ?? width * 0.26\n const sy = splitY ?? height * 0.28\n const split1: Pt = { x: cx - sx, y: cy - sy }\n const split2: Pt = { x: cx + sx, y: cy + sy }\n\n const positionOf = (split: Pt, lock: Pt): Pt => {\n if (frame <= assemble) {\n const e = easeOut(frame / assemble)\n return { x: lerp(split.x, lock.x, e), y: lerp(split.y, lock.y, e) }\n }\n const exitStart = total - disassemble\n if (frame >= exitStart) {\n const e = easeIn((frame - exitStart) / disassemble)\n return { x: lerp(lock.x, split.x, e), y: lerp(lock.y, split.y, e) }\n }\n return lock\n }\n\n const p1 = positionOf(split1, lock1)\n const p2 = positionOf(split2, lock2)\n\n const lineProps = {\n fontSize,\n color: ink,\n fontFamily: family,\n fontWeight,\n letterSpacing: tracking,\n }\n\n return (\n <Group>\n <Text x={lineStartX('center', p1.x, w1)} y={lineTopY(p1.y, fontSize)} {...lineProps}>\n {line1}\n </Text>\n <Text x={lineStartX('center', p2.x, w2)} y={lineTopY(p2.y, fontSize)} {...lineProps}>\n {line2}\n </Text>\n </Group>\n )\n}\n","//! StatCard — a single metric: a big value, a label beneath it, and a short\n//! accent bar. Stacked and centered by the engine's layout pass (taffy) via an\n//! `<AbsoluteFill>` + `<Flex>` column; each part fades in on a stagger.\n\nimport { AbsoluteFill, Flex, Rect, Text, useVideoConfig } from '@onda-engine/react'\nimport { DURATION, staggerFrames } from '../motion.js'\nimport { type Placement, PlacementShift } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { FadeIn } from './FadeIn.js'\n\nexport interface StatCardProps extends TextStyleProps {\n /** The headline metric, e.g. \"26.8 fps\" or \"100×\" (number is stringified).\n * Defaults to \"—\" so an under-specified card renders a placeholder, not nothing. */\n value?: string | number\n /** The label beneath, e.g. \"faster than Remotion\". */\n label?: string\n valueSize?: number\n labelSize?: number\n /** Value color (default: theme `text`). */\n valueColor?: string\n /** Label color (default: theme `textMuted`). */\n labelColor?: string\n /** Show the accent rule beneath the value. `true`/undefined → show (theme\n * accent); `false` → hide; a string → show in that color. Matches the\n * ondajs/Studio `accent: boolean` contract (a color goes via `accentColor`). */\n accent?: boolean | string\n /** Accent rule color (default: theme `accent`). */\n accentColor?: string\n delay?: TimeInput\n /** Where the stat sits: a region keyword (`'center'`, `'lower-third'`, …) or\n * normalized `{x,y}` (0–1, stat center). The shared placement contract;\n * default `'center'` (the historical self-centering). */\n placement?: Placement\n}\n\nexport function StatCard({\n value = '—',\n label = '',\n valueSize = 180,\n labelSize = 34,\n valueColor,\n labelColor,\n accent = true,\n accentColor,\n fontFamily,\n letterSpacing,\n uppercase,\n delay: delayIn = 0,\n placement,\n}: StatCardProps) {\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const valueCol = valueColor ?? theme.text\n const labelCol = labelColor ?? theme.textMuted\n // `accent` is a boolean flag in the Studio contract; a string is accepted as\n // a color shorthand. `accentColor` (explicit color) wins.\n const showAccent = accent !== false\n const accentCol = accentColor ?? (typeof accent === 'string' ? accent : theme.accent)\n const family = fontFamily ?? theme.fontFamily\n\n return (\n // The flex column self-centers; PlacementShift moves the centered stack by\n // the center→placement delta (no-op for the default 'center').\n <PlacementShift placement={placement}>\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Flex direction=\"column\" align=\"center\" gap={Math.round(labelSize * 0.7)}>\n <FadeIn delay={delay} durationInFrames={DURATION.slow}>\n <Text\n fontSize={valueSize}\n color={valueCol}\n fontFamily={family}\n fontWeight={700}\n letterSpacing={letterSpacing ?? Math.round(valueSize * -0.02)}\n >\n {applyTextCase(String(value), { uppercase })}\n </Text>\n </FadeIn>\n {showAccent ? (\n <FadeIn delay={delay + staggerFrames(2)}>\n <Rect\n width={Math.round(valueSize * 0.6)}\n height={6}\n cornerRadius={3}\n fill={accentCol}\n />\n </FadeIn>\n ) : null}\n <FadeIn delay={delay + staggerFrames(4)}>\n <Text fontSize={labelSize} color={labelCol} fontFamily={family}>\n {label}\n </Text>\n </FadeIn>\n </Flex>\n </AbsoluteFill>\n </PlacementShift>\n )\n}\n","//! Terminal — a terminal session window. Ported from ondajs.\n//!\n//! A dark rounded window (`<Rect>`) with an optional title bar (three dot\n//! `<Ellipse>`s + a label). After an optional delay the command types itself\n//! out one glyph per frame after the prompt, a block cursor blinks while typing\n//! (keyed off the frame, never a timer — so the result is deterministic), then\n//! the output lines appear one-by-one on a fade stagger once typing finishes.\n//!\n//! Layout note: the visible command grows one glyph per step, so its measured\n//! width changes every frame; output lines fade their opacity per-frame too. A\n//! Flex/AbsoluteFill column would reflow/jiggle on those changes (HARD RULE 2),\n//! so every line is positioned at an explicit `x`/`y` inside the window\n//! `<Group>` instead of being laid out by Flex — the window frame stays rock\n//! steady while the command types into it.\n//!\n//! Self-positioning: ondajs uses a `PlacementBox` (CSS) to place the window on\n//! the canvas. The engine has no CSS placement, so the window is centered on the\n//! composition by default; pass explicit `x`/`y` (top-left of the window) to\n//! place it elsewhere.\n//!\n//! Cursor caveat: like `Typewriter`, the blinking block cursor is appended as a\n//! second styled `runs` entry so the engine measures the command and positions\n//! the cursor right after the last revealed glyph — no manual text-width math.\n//! Per-run colors render on the GPU (Vello) path; the CPU reference draws the\n//! concatenated runs in the node's base style, so there the cursor inherits the\n//! command's `textColor`. GPU is the primary path, so this is acceptable.\n//!\n//! Color defaults: ondajs ships `var(--onda-…, #hex)` CSS-token defaults. The\n//! engine has no CSS variables, so the literal hex fallbacks are used directly.\n\nimport {\n Ellipse,\n Group,\n Path,\n Rect,\n Text,\n radialGradient,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport type { TextRunInput } from '@onda-engine/react'\nimport { useStaggeredEntrance, useTextReveal } from '../hooks.js'\nimport { STAGGER } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface TerminalProps extends TextStyleProps {\n /** The command that types itself out after the prompt. */\n command?: string\n /** Output lines that appear, staggered, once the command finishes typing. */\n output?: string[]\n /** The shell prompt glyph. */\n prompt?: string\n /** Title-bar label. Empty hides it (dots still show if `chrome` is on). */\n title?: string\n /** Show window chrome (dots + title bar). */\n chrome?: boolean\n /** Frames before typing starts. */\n delay?: TimeInput\n /** Frames to type the whole command (linear cadence). */\n typeSpeed?: TimeInput\n /** Frames after the command finishes before output begins. */\n outputDelay?: TimeInput\n /** Font size in px. Sized for a 1080p+ video canvas, not a screen UI. */\n fontSize?: number\n /** Width of the window in px. Fixed so the frame is stable while the command\n * types into it — a terminal has a defined size, it doesn't grow char by char. */\n width?: number\n /** Command text color (default: theme `text`). */\n textColor?: string\n /** Prompt glyph color — the earned accent (default: theme `accent`). */\n promptColor?: string\n /** Output line color (default: theme `textMuted`). */\n outputColor?: string\n /** Window background color (default: theme `background`). */\n background?: string\n /** Window corner radius in px (default: theme `radius`). */\n cornerRadius?: number\n /** Where the window sits: a region keyword (`'center'`, `'lower-third'`, …)\n * or normalized `{x,y}` (0–1, window center). The shared placement contract;\n * default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias — absolute x of the window's top-left in px.\n * Prefer `placement`. */\n x?: number\n /** @deprecated Legacy alias — absolute y of the window's top-left in px.\n * Prefer `placement`. */\n y?: number\n}\n\n// Monospace glyph advance as a fraction of font size — for the prompt offset\n// only (the command/cursor are glued by the engine's own measurement via runs).\nconst MONO_CHAR_W = 0.6\n// Line box as a fraction of font size (ondajs uses CSS line-height 1.6).\nconst LINE_HEIGHT = 1.6\n\n// Output check mark. The mono font lacks U+2713 (it falls back to \"√\"), so a\n// leading \"✓\"/\"✔\" on an output line is stripped from the text and drawn as a\n// small <Path> tick instead. The \"M…L…L…\" coords are in a unit (0..1) box,\n// scaled by `checkBox` at the call site.\nconst CHECK_GLYPHS = /^[✓✔]\\s?/u\nconst CHECK_PATH = 'M 0.18 0.55 L 0.42 0.78 L 0.84 0.26'\n\nexport function Terminal({\n command = 'npx ondajs add code-block',\n output = ['✓ added code-block', '✓ wrote 4 files'],\n prompt = '$',\n title = 'zsh',\n chrome = true,\n delay: delayIn = 0,\n typeSpeed: typeSpeedIn = 30,\n outputDelay: outputDelayIn = 8,\n fontFamily: fontFamilyProp,\n letterSpacing: letterSpacingProp,\n fontSize = 48,\n width = 1100,\n textColor: textColorProp,\n promptColor: promptColorProp,\n outputColor: outputColorProp,\n background: backgroundProp,\n cornerRadius: cornerRadiusProp,\n placement,\n x,\n y,\n}: TerminalProps) {\n const frame = useCurrentFrame()\n const { width: compWidth, height: compHeight, fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const typeSpeed = framesOf(typeSpeedIn, fps)\n const outputDelay = framesOf(outputDelayIn, fps)\n const theme = useTheme()\n const textColor = textColorProp ?? theme.text\n const promptColor = promptColorProp ?? theme.accent\n const outputColor = outputColorProp ?? theme.textMuted\n // The window must read as a SURFACE sitting on the canvas, so it defaults to\n // the theme's surface token, not the page background (which would be invisible\n // against an identically-colored composition background).\n const background = backgroundProp ?? theme.surface\n const fontFamily =\n fontFamilyProp ??\n theme.monoFamily ??\n theme.fontFamily ??\n 'ui-monospace, \"SF Mono\", Menlo, monospace'\n\n // Linear char count for the command — constant cadence (the intentional\n // non-spring case; matches ondajs `useTextReveal`).\n const shown = useTextReveal({ length: command.length, delay, durationInFrames: typeSpeed })\n const revealed = command.slice(0, Math.max(0, shown))\n const typing = shown < command.length\n\n // Deterministic blink keyed purely off the frame — a calm, steady cadence:\n // a ~0.62s period where the cursor rests visible for most of it and winks off\n // only briefly, so it reads settled and confident rather than strobing.\n const period = Math.max(2, Math.round(fps * 0.62))\n const blinkOn = frame % period < Math.round(period * 0.66)\n const showCursor = typing && blinkOn\n\n // Output lines settle in on the house stagger after the command finishes\n // typing — a small rise + fade (opacity + a few px of translateY) on the\n // smooth spring, so each line decelerates into place instead of popping.\n const outputAt = useStaggeredEntrance({\n type: 'rise',\n delay: delay + typeSpeed + outputDelay,\n increment: STAGGER,\n })\n\n // Window geometry. Title bar holds the dots + label; the body holds the\n // command line plus one row per output line. Everything is sized in px from\n // the font size so the box is stable regardless of how much has typed.\n const lineBox = Math.round(fontSize * LINE_HEIGHT)\n const titleBarHeight = chrome ? Math.round(fontSize * 1.5) : 0\n const bodyPadX = Math.round(fontSize * 0.75)\n const bodyPadY = Math.round(fontSize * 0.6)\n const lineCount = 1 + output.length\n const bodyHeight = bodyPadY * 2 + lineCount * lineBox\n const windowHeight = titleBarHeight + bodyHeight\n const cornerRadius = cornerRadiusProp ?? theme.radius\n\n // Anchor on the shared placement contract (window CENTER at the resolved\n // point; corner regions sit flush on the safe margin). `placement` is\n // authoritative when set; legacy px `x`/`y` only anchor in the pre-placement\n // path (else a stray `x:0.5` reads as 0.5 px → top-left). Default: centered.\n const resolved = usePlacement(placement, { width, height: windowHeight })\n const useLegacy = placement === undefined\n const winX = useLegacy && x !== undefined ? x : Math.round(resolved.originX)\n const winY = useLegacy && y !== undefined ? y : Math.round(resolved.originY)\n\n // Title-bar dots: three neutral-grey circles, matching ondajs's chrome dots\n // (it draws `--onda-border-lit, #26262E`; here a touch lighter so they read).\n const dotR = Math.round(fontSize * 0.19)\n const dotGap = Math.round(fontSize * 0.42)\n const dotY = Math.round(titleBarHeight / 2 - dotR)\n const dotColor = '#3a3a42'\n const dotStartX = bodyPadX\n\n // Prompt + command share the first body line. The command is offset past the\n // prompt glyph plus one space (estimated for a monospace stack).\n const bodyTop = titleBarHeight + bodyPadY\n const promptX = bodyPadX\n const commandX = promptX + Math.round((prompt.length + 1) * fontSize * MONO_CHAR_W)\n\n // Drawn check mark for output lines: a unit <Path> scaled into a glyph-sized\n // box that occupies the same horizontal slot as the stripped \"✓ \" prefix, so\n // the remaining text aligns exactly where it would after the glyph.\n const checkBox = Math.round(fontSize * 0.62)\n const checkGap = Math.round(fontSize * MONO_CHAR_W * 2 - checkBox)\n\n // Cursor as a second styled run so the engine glues the block glyph right\n // after the last revealed command glyph (no manual text-width math).\n const commandRuns: TextRunInput[] | undefined = showCursor\n ? [\n { text: revealed, color: textColor, fontSize, fontFamily, fontWeight: 500 },\n { text: '▍', color: textColor, fontSize, fontFamily, fontWeight: 500 },\n ]\n : undefined\n\n return (\n <Group x={winX} y={winY}>\n {/* Depth: a soft, large-radius drop shadow tinted toward the page\n background (never hard black) — painted first so the window reads as a\n surface lifted off the canvas. GPU-only (a canvas-local radial fading\n to transparent), centered just below the panel. */}\n <Rect\n x={-width * 0.12}\n y={windowHeight * 0.04}\n width={width * 1.24}\n height={windowHeight * 1.24}\n gradient={radialGradient(\n // Center in the Rect's local space so it sits beneath the panel mid.\n [width * 0.62, windowHeight * 0.5],\n width * 0.6,\n [\n { offset: 0, color: withAlpha(theme.background, 0x66) },\n { offset: 1, color: withAlpha(theme.background, 0x00) },\n ],\n )}\n />\n\n {/* A subtle accent glow bleeding from the window's top edge — the one\n earned flourish, kept faint so it warms the panel without shouting. */}\n <Rect\n x={-width * 0.1}\n y={-windowHeight * 0.14}\n width={width * 1.2}\n height={windowHeight * 0.6}\n gradient={radialGradient(\n // Centered on the panel's top edge, in the Rect's local space.\n [width * 0.6, windowHeight * 0.14],\n width * 0.5,\n [\n { offset: 0, color: withAlpha(promptColor, 0x1c) },\n { offset: 1, color: withAlpha(promptColor, 0x00) },\n ],\n )}\n />\n\n {/* Window panel — a near-black surface with a hairline border so its edge\n reads crisply against the canvas. */}\n <Rect\n width={width}\n height={windowHeight}\n cornerRadius={cornerRadius}\n fill={background}\n stroke={theme.border}\n strokeWidth={1}\n />\n\n {/* Title bar: dots + optional label + a hairline separator that divides the\n bar from the body, so the chrome reads as a real terminal window. */}\n {chrome ? (\n <>\n <Rect x={0} y={titleBarHeight - 1} width={width} height={1} fill={theme.border} />\n <Ellipse x={dotStartX} y={dotY} width={dotR * 2} height={dotR * 2} fill={dotColor} />\n <Ellipse\n x={dotStartX + dotGap}\n y={dotY}\n width={dotR * 2}\n height={dotR * 2}\n fill={dotColor}\n />\n <Ellipse\n x={dotStartX + dotGap * 2}\n y={dotY}\n width={dotR * 2}\n height={dotR * 2}\n fill={dotColor}\n />\n {title ? (\n <Text\n x={dotStartX + dotGap * 2 + dotR * 2 + Math.round(fontSize * 0.6)}\n y={Math.round(titleBarHeight / 2 - fontSize * 0.62 * 0.62)}\n fontSize={Math.round(fontSize * 0.62)}\n color=\"#56565f\"\n fontFamily={fontFamily}\n >\n {title}\n </Text>\n ) : null}\n </>\n ) : null}\n\n {/* Prompt glyph + the command typing itself out (with cursor run). */}\n <Text x={promptX} y={bodyTop} fontSize={fontSize} color={promptColor} fontFamily={fontFamily}>\n {prompt}\n </Text>\n <Text\n x={commandX}\n y={bodyTop}\n fontSize={fontSize}\n letterSpacing={letterSpacingProp ?? fontSize * 0.04}\n color={textColor}\n fontFamily={fontFamily}\n fontWeight={500}\n runs={commandRuns}\n >\n {revealed}\n </Text>\n\n {/* Output lines — staggered fade once the command finishes typing. A line\n prefixed with a check glyph gets a drawn <Path> tick (the mono font has\n no U+2713) and the prefix is stripped from its text. */}\n {output.map((line, i) => {\n const hasCheck = CHECK_GLYPHS.test(line)\n const text = hasCheck ? line.replace(CHECK_GLYPHS, '') : line\n const rowY = bodyTop + (i + 1) * lineBox\n const textX = hasCheck ? bodyPadX + checkBox + checkGap : bodyPadX\n const { opacity, y: riseY } = outputAt(i)\n return (\n <Group key={i} y={riseY} opacity={opacity}>\n {hasCheck ? (\n <Group\n x={bodyPadX}\n y={rowY + Math.round((fontSize - checkBox) / 2)}\n scaleX={checkBox}\n scaleY={checkBox}\n >\n <Path d={CHECK_PATH} stroke={theme.accent} strokeWidth={2.2 / checkBox} />\n </Group>\n ) : null}\n <Text\n x={textX}\n y={rowY}\n fontSize={fontSize}\n color={outputColor}\n fontFamily={fontFamily}\n >\n {text}\n </Text>\n </Group>\n )\n })}\n </Group>\n )\n}\n\n/** Return `color` (`#rrggbb` / `#rrggbbaa` / `#rgb`) with its alpha channel set\n * to the given byte (0..255), preserving RGB so a glow fades the tone itself\n * rather than toward black. Falls back to the input unchanged on an unknown\n * format. */\nfunction withAlpha(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(255, Math.round(alpha)))\n .toString(16)\n .padStart(2, '0')\n if (color.startsWith('#')) {\n const hex = color.slice(1)\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}${a}`\n }\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}${a}`\n }\n }\n return color\n}\n","//! TextFadeReplace — crossfade between an old and a new phrase in place. Ported from ondajs.\n//!\n//! ondajs cycles through a list of phrases, crossfading one into the next so the\n//! layout never shifts. This port takes the simplified two-phrase shape the\n//! engine batch asked for: a single `from` -> `to` swap. Both phrases are\n//! rendered (layered in the same slot) so the swap stays put — `from` rides\n//! `outOpacity`, `to` rides `inOpacity`, both from the ported `stateSwap`\n//! choreography (a HOUSE_EASE crossfade: old fades out over the first half of\n//! the window, new fades in over the second).\n//!\n//! Layout: the two `<Text>` nodes are layered at the SAME local origin (0,0)\n//! inside one `<Group>`, and that single Group is the only child of an\n//! `<AbsoluteFill justify=\"center\" align=\"center\">`, so the engine layout pass\n//! (taffy) centers the whole block. Only opacity animates per phrase and both\n//! phrases are present every frame, so the Group's measured size never changes —\n//! this is layout-safe (no per-frame size change, no reflow). Sharing the origin\n//! keeps the swap perfectly in place vertically (no negative-translate guess,\n//! which would be off by the engine's 1.2x line-box height).\n//!\n//! Engine notes (vs the ondajs/CSS original):\n//! - The two phrases are anchored at a shared TOP-LEFT origin (block-centered by\n//! the layout pass), not per-phrase center-aligned: the scene `<Text>` has no\n//! measurement-free `text-align`, so phrases of different widths share a left\n//! edge rather than a center. ondajs used CSS `justify-content` for this.\n//! - No `letter-spacing` / `line-height` / `placement` region system on the\n//! scene `<Text>`; centering is handled by the layout pass.\n//! - `<Text>` is single-line (no wrap) — `from`/`to` are expected to be short\n//! phrases (taglines / value props), matching the ondajs use case.\n\nimport { AbsoluteFill, Group, Text, useCurrentFrame } from '@onda-engine/react'\nimport { stateSwap } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface TextFadeReplaceProps extends TextStyleProps {\n /** The outgoing phrase (shown first, fades out). */\n from: string\n /** The incoming phrase (fades in over `from`). */\n to: string\n /** Frames before the crossfade begins. Until then only `from` is shown\n * (default `DURATION.hold` = 45, a settled beat before the swap). */\n delay?: TimeInput\n /** Frames the crossfade takes — old out over the first half, new in over the\n * second (default `DURATION.base` = 18). */\n durationInFrames?: TimeInput\n /** Font size in px (default `96`, matching the ondajs display default). */\n fontSize?: number\n}\n\nexport function TextFadeReplace({\n from: fromProp,\n to: toProp,\n delay = DURATION.hold,\n durationInFrames = DURATION.base,\n fontSize = 96,\n color: colorProp,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n}: TextFadeReplaceProps) {\n // Both phrases are primary text — uppercase each before render.\n const from = applyTextCase(fromProp, { uppercase })\n const to = applyTextCase(toProp, { uppercase })\n const frame = useCurrentFrame()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n\n // In-place crossfade on HOUSE_EASE: old fades out over the first half of the\n // window, new fades in over the second. Both are rendered (layered, same\n // origin) so the container never shifts.\n const { outOpacity, inOpacity } = stateSwap({ frame, delay, durationInFrames })\n\n return (\n <AbsoluteFill justify=\"center\" align=\"center\">\n {/* One layout child (block-centered by taffy). Both phrases live at the\n same local origin so the swap stays put — only opacity animates. */}\n <Group>\n <Group opacity={outOpacity}>\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {from}\n </Text>\n </Group>\n <Group opacity={inOpacity}>\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {to}\n </Text>\n </Group>\n </Group>\n </AbsoluteFill>\n )\n}\n","//! Timeline — a vertical event timeline. Ported from ondajs (`timeline`).\n//!\n//! A vertical line (`<Rect>`) draws on top-to-bottom first, then event markers\n//! (`<Ellipse>`) cascade in down the line with the canonical stagger, then each\n//! label (`<Text>`) rises in beside its marker. The final marker is the playhead:\n//! it earns the dusty-rose accent and a soft accent glow — one focal moment, the\n//! rest neutral. Every marker sits on a soft, bg-tinted drop-shadow so the column\n//! reads with quiet depth above the line. This mirrors the ondajs choreography\n//! (line → markers → labels); ondajs lays the line out horizontally, this port\n//! runs it vertically (per the engine component spec) with an explicit `y` per\n//! event.\n//!\n//! Layout / scene caveats:\n//! - FIXED dimensions, centered by computing a top-left offset from the\n//! composition size (the BarChart pattern) rather than a `<Flex>`/\n//! `<AbsoluteFill>` — the line-reveal clip animates per frame, and a layout\n//! container would chase the growing bbox and jiggle. Dots/labels are placed by\n//! explicit `x`/`y` inside one `<Group>`, never as Flex children.\n//! - The line \"draws on\" via a `clipRect` (engine signature\n//! `clipRect(width, height)`, anchored at the clip Group's local origin) whose\n//! height grows top→bottom. The engine has no stroke-dash draw-on, so a clip\n//! reveal is the faithful substitute (the ondajs original used `evolvePath`\n//! stroke-dash).\n//! - `entryScale` pivots on a node's LOCAL origin (0,0), so each dot's subtree\n//! origin is translated to the dot CENTER first; the dot then scales from its\n//! own center, not its top-left corner.\n\nimport {\n Ellipse,\n Group,\n Rect,\n Text,\n clipRect,\n interpolate,\n radialGradient,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { entryScale, entrySlide } from '../choreography.js'\nimport { DURATION, SPRING_SMOOTH, STAGGER, staggerFrames } from '../motion.js'\nimport { measureText, useTextMetricsReady } from '../text-metrics.js'\nimport type { TextStyleProps } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\n/** One anchor on the timeline. */\nexport interface TimelineEvent {\n label: string\n}\n\nexport interface TimelineProps extends TextStyleProps {\n /** Anchor points down the timeline. Order is preserved — top to bottom. */\n events?: TimelineEvent[]\n /** Frames before the line begins to draw. */\n delay?: TimeInput\n /** Frames over which the vertical line reveals itself top→bottom. */\n lineDuration?: TimeInput\n /** Frames between the line completing and the first dot appearing. */\n dotDelay?: number\n /** Frames between consecutive dot entrances (canonical Onda stagger = 4). */\n dotStagger?: number\n /** Per-dot entrance duration. */\n dotDuration?: number\n /** Dot diameter in px. */\n dotSize?: number\n /** Vertical distance between consecutive events, in px. */\n spacing?: number\n /** Line thickness in px. */\n lineWidth?: number\n /** Line color (default: theme `border`). */\n lineColor?: string\n /** Non-final dot color (default: theme `text`). */\n dotColor?: string\n /** Final dot color — the earned accent (Onda rose) (default: theme `accent`). */\n accentColor?: string\n /** Label color (default: theme `textMuted`). */\n labelColor?: string\n /** Label font size in px. */\n fontSize?: number\n}\n\nconst DEFAULT_EVENTS: TimelineEvent[] = [\n { label: 'Concept' },\n { label: 'Build' },\n { label: 'Ship' },\n { label: 'Iterate' },\n]\n\nexport function Timeline({\n events = DEFAULT_EVENTS,\n delay: delayIn = 0,\n lineDuration: lineDurationIn = DURATION.slow,\n dotDelay = 8,\n dotStagger = STAGGER,\n dotDuration = DURATION.base,\n dotSize = 18,\n spacing = 110,\n lineWidth = 4,\n lineColor: lineColorProp,\n dotColor: dotColorProp,\n accentColor: accentColorProp,\n labelColor: labelColorProp,\n fontSize = 28,\n fontFamily: fontFamilyProp,\n}: TimelineProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const lineDuration = framesOf(lineDurationIn, fps)\n const theme = useTheme()\n const lineColor = lineColorProp ?? theme.border\n const dotColor = dotColorProp ?? theme.text\n const accentColor = accentColorProp ?? theme.accent\n const labelColor = labelColorProp ?? theme.textMuted\n const fontFamily = fontFamilyProp ?? theme.headingFamily ?? theme.fontFamily\n\n const count = events.length\n const lastIndex = count - 1\n\n // Depth tones. Markers sit on a soft, large-radius drop-shadow tinted toward\n // the canvas (not hard black) so the column reads with quiet elevation above\n // the line. The playhead (final marker) earns a soft accent glow — one focal\n // halo, drawn behind the dot. `alphaHex` appends an 8-bit alpha to a #rrggbb\n // tone; the accent is a known hex, so the glow stops are derived from it.\n const markerShadow = { color: alphaHex(theme.background, 0x66), blur: 22, offsetY: 8 }\n const glowCore = alphaHex(accentColor, 0x4d) // ~0.30 alpha at center\n const glowEdge = alphaHex(accentColor, 0x00) // fade to transparent\n // Glow radius scales with the dot — a soft bloom roughly 2.4× the diameter.\n const glowRadius = dotSize * 1.2\n\n // Vertical extent the dots span: first dot at y=0, last at spacing*lastIndex.\n const dotsSpan = count > 1 ? spacing * lastIndex : 0\n // Pixels reserved between a dot's right edge and its label.\n const labelGap = Math.round(dotSize * 0.9) + 16\n\n // Local x where labels start (just past the dot + gap).\n const labelX = dotSize + labelGap\n\n // Footprint of the whole subtree. Content runs from the dot column's left edge\n // (local x=0) to the right end of the WIDEST label — measured exactly (real\n // shaped width) and reserved from `labelX` outward, so the timeline centers on\n // true canvas center. `useTextMetricsReady` warms the engine in the browser;\n // `measureText` is the per-label sync read (a hook can't run in a reduce).\n useTextMetricsReady()\n const maxLabelWidth = events.reduce(\n (max, e) =>\n Math.max(\n max,\n Math.ceil(measureText(e.label, fontSize, { fontFamily, fontWeight: 500 }).width),\n ),\n 0,\n )\n const subtreeWidth = labelX + maxLabelWidth\n const subtreeHeight = dotsSpan\n\n // Center by an explicit offset — no layout container chasing the animated clip.\n const originX = Math.round((width - subtreeWidth) / 2)\n const originY = Math.round((height - subtreeHeight) / 2)\n\n // The line sits along the dot column (dots centered on it). Local x of the\n // line's left edge so the line is centered under the dots.\n const lineX = Math.round((dotSize - lineWidth) / 2)\n\n // Line-draw reveal: a top→bottom clip that grows with the house spring. The\n // line spans from the first dot center to the last dot center.\n const lineLocal = Math.max(0, frame - delay)\n const lineProgress =\n count > 1\n ? spring({ frame: lineLocal, fps, config: SPRING_SMOOTH, durationInFrames: lineDuration })\n : 0\n const revealHeight = interpolate(lineProgress, [0, 1], [0, dotsSpan], {\n extrapolateLeft: 'clamp',\n extrapolateRight: 'clamp',\n })\n\n return (\n <Group x={originX} y={originY}>\n {/* The vertical line. Drawn from the first dot center down to the last.\n Revealed top→bottom by a clip whose height animates. The engine's\n `clipRect(width, height)` is anchored at this Group's local origin\n (0,0), so it clips the column [0, lineX+lineWidth] × [0, revealHeight];\n the line Rect (at x=lineX) is fully covered horizontally and revealed\n down to `revealHeight`. The Rect's own measured size never changes, so\n nothing reflows. Rendered only with ≥2 events — a single event has no\n line. */}\n {count > 1 && revealHeight > 0 ? (\n <Group clip={clipRect(lineX + lineWidth, revealHeight)}>\n <Rect\n x={lineX}\n y={0}\n width={lineWidth}\n height={dotsSpan}\n cornerRadius={lineWidth / 2}\n fill={lineColor}\n />\n </Group>\n ) : null}\n\n {events.map((event, i) => {\n const thisDotDelay = delay + lineDuration + dotDelay + staggerFrames(i, dotStagger)\n\n // Marker entrance — scale + fade from the canonical vocabulary, settling\n // on the house spring (no bounce; decelerates into rest).\n const dotMotion = entryScale({\n frame,\n fps,\n delay: thisDotDelay,\n durationInFrames: dotDuration,\n })\n\n // Label trails its marker by 2 frames — the marker leads, the label is\n // its consequence — and RISES in (opacity + a small translateY) rather\n // than flat-fading, so the cascade reads as an orchestrated wave.\n const labelMotion = entrySlide({\n frame,\n fps,\n delay: thisDotDelay + 2,\n durationInFrames: dotDuration,\n direction: 'up',\n distance: 10,\n })\n\n const isLast = i === lastIndex\n const fillColor = isLast ? accentColor : dotColor\n\n // Dot center: column centered on the line, stepping down by `spacing`.\n const dotCenterX = dotSize / 2\n const dotCenterY = spacing * i\n\n return (\n <Group key={`${i}-${event.label}`}>\n {/* Marker. The subtree origin is moved to the dot CENTER so entryScale\n grows from the center (scale pivots on the local origin). The whole\n group carries the entrance opacity/scale, so the playhead glow\n below blooms in as one unit with its dot. */}\n <Group\n x={dotCenterX}\n y={dotCenterY}\n scaleX={dotMotion.scaleX}\n scaleY={dotMotion.scaleY}\n opacity={dotMotion.opacity}\n >\n {/* Playhead glow — the one earned accent halo, behind the final\n marker only (radial-gradient bloom). Drawn first so the dot\n sits on top. */}\n {isLast ? (\n <Ellipse\n x={-glowRadius}\n y={-glowRadius}\n width={glowRadius * 2}\n height={glowRadius * 2}\n gradient={radialGradient([glowRadius, glowRadius], glowRadius, [\n { offset: 0, color: glowCore },\n { offset: 1, color: glowEdge },\n ])}\n />\n ) : null}\n\n <Ellipse\n x={-dotSize / 2}\n y={-dotSize / 2}\n width={dotSize}\n height={dotSize}\n fill={fillColor}\n shadow={markerShadow}\n />\n </Group>\n\n {/* Label — opacity + small rise, placed by explicit x/y (the rise is\n nested inside this positioned group, layout-safe). Vertically\n centered against the dot (text is measured from its own origin,\n so nudge up by half the font size). */}\n <Group opacity={labelMotion.opacity} y={labelMotion.y}>\n <Text\n x={dotSize + labelGap}\n y={dotCenterY - Math.round(fontSize / 2)}\n fontSize={fontSize}\n color={isLast ? accentColor : labelColor}\n fontFamily={fontFamily}\n fontWeight={500}\n >\n {event.label}\n </Text>\n </Group>\n </Group>\n )\n })}\n </Group>\n )\n}\n\n/** Append an 8-bit `alpha` (0–255) to a `#rgb`/`#rrggbb` tone, yielding a\n * `#rrggbbaa`. Used for the bg-tinted marker shadow and the accent glow stops —\n * derived from theme tones rather than hardcoded black/transparent. Non-hex\n * inputs fall through unchanged (the renderer still gets a valid color). */\nfunction alphaHex(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(255, Math.round(alpha)))\n .toString(16)\n .padStart(2, '0')\n if (!color.startsWith('#')) return color\n const hex = color.slice(1)\n if (hex.length === 3) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n return `#${r}${r}${g}${g}${b}${b}${a}`\n }\n if (hex.length === 6 || hex.length === 8) {\n return `#${hex.slice(0, 6)}${a}`\n }\n return color\n}\n","//! TitleCard — a centered title with an optional subtitle, each fading in with a\n//! short stagger. Composes `FadeIn` (layout-safe) inside an `<AbsoluteFill>` +\n//! `<Flex>` column, so the engine's layout pass (taffy) handles the centering\n//! and vertical stacking — no manual x/y math.\n//!\n//! Colors and font default to the active {@link useTheme} (text / textMuted /\n//! heading family); pass explicit props to override.\n\nimport { AbsoluteFill, Flex, Text, useVideoConfig } from '@onda-engine/react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { DURATION, staggerFrames } from '../motion.js'\nimport { type Placement, PlacementShift } from '../placement.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { FadeIn } from './FadeIn.js'\n\nexport interface TitleCardProps extends TextStyleProps {\n title: string\n subtitle?: string\n /** Title font size in px (default 120). */\n titleSize?: number\n /** Opt-in auto-fit: `'frame'` scales the TITLE size DOWN (never up) so the\n * title line cannot exceed the frame minus the safe margins. Default\n * `'none'` (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the title line; combines with `fit` (the\n * smaller cap wins). */\n maxWidth?: number\n /** Subtitle font size in px (default 36). */\n subtitleSize?: number\n /** Title color (default: theme `text`). */\n titleColor?: string\n /** Subtitle color (default: theme `textMuted`). */\n subtitleColor?: string\n /** Frame the title begins fading in (subtitle follows by one stagger step). */\n delay?: TimeInput\n /** Where the card sits: a region keyword (`'center'`, `'lower-third'`, …) or\n * normalized `{x,y}` (0–1, card center). The shared placement contract;\n * default `'center'` (the historical self-centering). */\n placement?: Placement\n}\n\nexport function TitleCard({\n title,\n subtitle,\n titleSize: titleSizeProp = 120,\n fit,\n maxWidth,\n subtitleSize = 36,\n titleColor,\n subtitleColor,\n fontFamily,\n letterSpacing,\n uppercase,\n delay: delayIn = 0,\n placement,\n}: TitleCardProps) {\n const { fps } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const theme = useTheme()\n const titleCol = titleColor ?? theme.text\n const subtitleCol = subtitleColor ?? theme.textMuted\n const family = fontFamily ?? theme.headingFamily ?? theme.fontFamily\n const titleText = applyTextCase(title, { uppercase })\n\n // Opt-in auto-fit on the title line (tracking scales with the size).\n const titleSize = useFittedFontSize(title, titleSizeProp, {\n fontFamily: family,\n fontWeight: 700,\n letterSpacing: Math.round(titleSizeProp * -0.02),\n fit,\n maxWidth,\n })\n\n return (\n <PlacementShift placement={placement}>\n <AbsoluteFill justify=\"center\" align=\"center\">\n <Flex direction=\"column\" align=\"center\" gap={Math.round(subtitleSize * 0.8)}>\n <FadeIn delay={delay} durationInFrames={DURATION.slow}>\n <Text\n fontSize={titleSize}\n color={titleCol}\n fontFamily={family}\n fontWeight={700}\n letterSpacing={letterSpacing ?? Math.round(titleSize * -0.02)}\n >\n {titleText}\n </Text>\n </FadeIn>\n {subtitle ? (\n <FadeIn delay={delay + staggerFrames(2)} durationInFrames={DURATION.base}>\n <Text fontSize={subtitleSize} color={subtitleCol} fontFamily={family}>\n {subtitle}\n </Text>\n </FadeIn>\n ) : null}\n </Flex>\n </AbsoluteFill>\n </PlacementShift>\n )\n}\n","//! TrackingIn — letter-spacing tighten + fade. Ported from ondajs.\n//!\n//! The text begins spread wide and contracts to its resting tracking on the\n//! house spring (SPRING_SMOOTH, no overshoot), fading as it settles — a\n//! confident, cinematic title entrance.\n//!\n//! The whole line is ONE engine `<Text>` with real **letter-spacing** (the scene\n//! `<Text>` carries a `letterSpacing` prop; `tracking * fontSize` px between\n//! glyphs = the CSS `letter-spacing: Xem` semantics of the original) — exact\n//! shaping, no per-glyph estimate.\n//!\n//! Layout note: the line's width changes every frame as the tracking tightens,\n//! so it is MEASURED (letter-spacing-aware `useTextMetrics`) and positioned\n//! ABSOLUTELY at an explicit `x`/`y`, not as a `<Flex>`/`<AbsoluteFill>` child,\n//! where a per-frame width change would make the layout pass reflow (HARD RULE 2).\n//!\n//! Approximation — blur: ondajs starts the text soft (CSS `blur(8px)`) and\n//! sharpens as it settles; the engine has no content-blur primitive. When `blur`\n//! is enabled this is a nod — a faint, wider-tracked ghost of the line layered\n//! behind the crisp text, fading out as it settles — not a true Gaussian blur.\n\nimport { Group, Text, useVideoConfig } from '@onda-engine/react'\nimport { useSpringValue } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport type { TimeInput } from '../time.js'\n\nexport interface TrackingInProps extends TextStyleProps {\n /** The text to settle in. */\n text?: string\n /** Frames before the entrance starts. */\n delay?: TimeInput\n /** Frames until the text settles (default `DURATION.slow` = 24). */\n durationInFrames?: TimeInput\n /** Starting letter-spacing in em — the text begins spread wide and contracts. */\n fromTracking?: number\n /** Resting letter-spacing in em. */\n tracking?: number\n /** Start the text soft and sharpen as it settles (approximated; see doc). */\n blur?: boolean\n /** Font size in px. */\n fontSize?: number\n /** Horizontal alignment of the line about `x`. Default `'center'`. */\n align?: 'left' | 'center' | 'right'\n /** @deprecated No longer used — the line now uses real shaped letter-spacing\n * metrics, so no per-glyph advance estimate is needed. Accepted for compat. */\n advanceFactor?: number\n /** Absolute x anchor of the line (default canvas center). */\n x?: number\n /** Absolute y of the line's top (default vertical center). */\n y?: number\n}\n\nexport function TrackingIn({\n text: textProp = 'Onda',\n delay = 0,\n durationInFrames = DURATION.slow,\n color: colorProp,\n fromTracking = 0.5,\n tracking = -0.02,\n blur = true,\n fontSize = 96,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n align = 'center',\n x,\n y,\n}: TrackingInProps) {\n const text = applyTextCase(textProp, { uppercase })\n const { width, height } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // House spring (SPRING_SMOOTH, no overshoot), matching ondajs.\n const progress = useSpringValue({ delay, durationInFrames })\n\n // Opacity fades 0 → 1 across the settle.\n const opacity = progress\n\n // Current tracking, contracting from spread → rest: em → engine px. The\n // shared `letterSpacing` (px) is an additive RESTING offset on top of the\n // animated em track, so it lands the line at extra tracking once settled\n // (undefined → 0, i.e. identical to the historical behavior).\n const ls = fromTracking + (tracking - fromTracking) * progress\n const trackPx = ls * fontSize + (letterSpacing ?? 0)\n\n // ONE engine <Text> with real letter-spacing (exact shaping + tracking, no\n // per-glyph estimate). The line's width changes every frame as it contracts;\n // we MEASURE it (letter-spacing-aware) to keep it centered. Positioned at an\n // explicit x/y, NOT a flex child, so the per-frame width change can't reflow.\n const measured = useTextMetrics(text, fontSize, {\n fontFamily,\n fontWeight,\n letterSpacing: trackPx,\n })\n const lineWidth = measured.width\n\n const anchorX = x ?? Math.round(width / 2)\n const startX =\n align === 'center' ? anchorX - lineWidth / 2 : align === 'right' ? anchorX - lineWidth : anchorX\n // Vertical: roughly center the single line by offsetting the top by ~half the\n // cap height (matches Typewriter's convention).\n const py = y ?? Math.round(height / 2 - fontSize * 0.6)\n\n // Optional soft-edge \"nod to blur\" (the engine has no content blur): a faint,\n // wider-tracked ghost of the line behind the crisp text, fading as it settles.\n const ghostOn = blur && progress < 1\n const ghostOpacity = ghostOn ? (1 - progress) * 0.45 * opacity : 0\n const ghostTrack = trackPx + (1 - progress) * fontSize * 0.06\n\n return (\n <Group opacity={opacity}>\n {ghostOpacity > 0.001 ? (\n <Text\n x={startX}\n y={py}\n fontSize={fontSize}\n letterSpacing={ghostTrack}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n opacity={ghostOpacity}\n >\n {text}\n </Text>\n ) : null}\n <Text\n x={startX}\n y={py}\n fontSize={fontSize}\n letterSpacing={trackPx}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n >\n {text}\n </Text>\n </Group>\n )\n}\n","//! Typewriter — reveal text character-by-character with an optional blinking\n//! cursor. Ported from ondajs.\n//!\n//! Linear cadence is deliberate (the one documented exception to the house\n//! spring rule): typing has to feel constant-rate, so it uses\n//! `useTextReveal` (linear interpolation) rather than a spring.\n//!\n//! Layout note: the visible string grows one glyph per step, so its measured\n//! width changes every frame. A growing-width `<Text>` inside a `<Flex>`/\n//! `<AbsoluteFill>` makes the layout pass reflow/jiggle each frame (HARD RULE\n//! 2). To keep the reveal rock-steady the text is positioned absolutely at an\n//! explicit `x`/`y` (left-anchored, vertically centered by default) instead of\n//! being laid out by Flex. The cursor is appended as a second styled `runs`\n//! entry so the engine measures and glues it right after the last revealed\n//! glyph — no manual text-width math.\n//!\n//! Backend caveat: per-run colors render on the GPU (Vello) path; the CPU\n//! reference rasterizer draws the concatenated run text in the node's style, so\n//! there the cursor inherits `color` rather than `cursorColor`. GPU is the\n//! primary path, so this is an acceptable degradation.\n\nimport { Text, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { useFittedFontSize } from '../bounds.js'\nimport { useTextReveal } from '../hooks.js'\nimport { DURATION } from '../motion.js'\nimport { type Placement, usePlacement } from '../placement.js'\nimport { useTextMetrics } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\nimport { useTimeScale } from '../timing.js'\n\nexport interface TypewriterProps extends TextStyleProps {\n /** What to type out. */\n text?: string\n /** Time before typing starts — frames or '0.5s'. */\n delay?: TimeInput\n /** Time to type the full string. Linear pacing — chars-per-frame is\n * constant. Default `DURATION.slow` (24 frames). */\n durationInFrames?: TimeInput\n /** Compress the whole timing envelope (delay, stagger, durations) so the\n * entrance settles at least `hold` before the end of the enclosing clip\n * (`useVideoConfig().durationInFrames`, Sequence-scoped). Opt-in. */\n fitToClip?: boolean\n /** Hard cap on the settle time (frames or '0.5s'). Wins over `fitToClip`. */\n maxSettle?: TimeInput\n /** Breathing room before the cut for `fitToClip` (default 6 frames). */\n hold?: TimeInput\n /** Show a blinking cursor at the leading edge while typing. Default `true`. */\n cursor?: boolean\n /** Cursor color (default: theme `accent`). */\n cursorColor?: string\n /** Font size in px (default 64). */\n fontSize?: number\n /** Opt-in auto-fit: `'frame'` scales the font size DOWN (never up) so the\n * measured line cannot exceed the frame minus the safe margins. Default\n * `'none'` (the historical behavior). */\n fit?: 'none' | 'frame'\n /** Explicit width cap in px for the line; combines with `fit` (the smaller\n * cap wins). */\n maxWidth?: number\n /** Where the line sits: a region keyword (`'center'`, `'lower-third'`, …) or\n * normalized `{x,y}` (0–1, anchored at the FULL line's measured center). The\n * shared placement contract; default `'center'`. */\n placement?: Placement\n /** @deprecated Legacy alias — absolute x of the text's left edge in px.\n * Prefer `placement`. */\n x?: number\n /** @deprecated Legacy alias — absolute y (baseline-ish top) in px. Prefer\n * `placement`. */\n y?: number\n}\n\nexport function Typewriter({\n text: textProp = 'motion graphics',\n delay: delayIn = 0,\n durationInFrames: durationIn = DURATION.slow,\n fitToClip,\n maxSettle,\n hold,\n cursor = true,\n cursorColor: cursorColorProp,\n color: colorProp,\n fontSize: fontSizeProp = 64,\n fit,\n maxWidth,\n fontFamily: fontFamilyProp,\n fontWeight = 500,\n italic = false,\n letterSpacing,\n uppercase,\n placement,\n x,\n y,\n}: TypewriterProps) {\n const text = applyTextCase(textProp, { uppercase })\n const frame = useCurrentFrame()\n const { fps } = useVideoConfig()\n const theme = useTheme()\n const cursorColor = cursorColorProp ?? theme.accent\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n\n // Timing: parse + clip-fit (typing compresses to land inside the clip).\n const delayBase = framesOf(delayIn, fps)\n const durationBase = framesOf(durationIn, fps, DURATION.slow)\n const timeScale = useTimeScale(delayBase + durationBase, { fitToClip, maxSettle, hold })\n const delay = delayBase * timeScale\n const durationInFrames = Math.max(1, durationBase * timeScale)\n\n // Opt-in auto-fit: scale the size down so the FULL line fits the cap.\n const fontSize = useFittedFontSize(text, fontSizeProp, { fontFamily, fontWeight, fit, maxWidth })\n\n // Real shaped width of the FULL string (proportional — exact); falls back to\n // a glyph-count estimate until the wasm engine warms in the browser.\n const measured = useTextMetrics(text, fontSize, { fontFamily, fontWeight })\n\n // Linear char count — constant cadence (the intentional non-spring case).\n const shown = useTextReveal({ length: text.length, delay, durationInFrames })\n const revealed = text.slice(0, Math.max(0, shown))\n\n const done = shown >= text.length\n\n // Deterministic blink derived purely from the current frame: toggles every\n // half second (fps/2 frames). Hidden once typing completes.\n const half = Math.max(1, Math.round(fps / 2))\n const cursorVisible = Math.floor(frame / half) % 2 === 0\n const showCursor = cursor && !done && cursorVisible\n\n // Absolute placement so the growing string never triggers a Flex reflow.\n // The anchor is derived from the MEASURED width of the FULL string via the\n // shared placement contract. Anchoring on the full width — not the growing\n // substring — keeps the origin rock-steady (the line would slide sideways\n // otherwise) while the completed line reads placed as asked. `placement` is\n // authoritative when set; legacy px `x`/`y` only anchor in the pre-placement\n // path (else a stray `x:0.5` reads as 0.5 px → top-left). Default: centered.\n const resolved = usePlacement(placement, { width: measured.width, height: fontSize * 1.2 })\n const useLegacy = placement === undefined\n const px = useLegacy && x !== undefined ? x : Math.round(resolved.originX)\n const py = useLegacy && y !== undefined ? y : Math.round(resolved.y - fontSize * 0.6)\n\n // Append the cursor as a separate styled run so the engine measures the text\n // and positions the \"|\" right after the last revealed glyph.\n const runs = showCursor\n ? [\n { text: revealed, color, fontSize, fontFamily, fontWeight, italic },\n { text: '|', color: cursorColor, fontSize, fontFamily, fontWeight, italic },\n ]\n : undefined\n\n return (\n <Text\n x={px}\n y={py}\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n runs={runs}\n >\n {revealed}\n </Text>\n )\n}\n","//! VideoClip — a trimmed video clip with the Onda fade envelope. Ported from ondajs.\n//!\n//! Real playback: a `<Video>` node draws the source frame at the current time\n//! (decoded by the player in-browser via `<video>`/WebCodecs, or by `onda export`\n//! via ffmpeg), wrapped in the same fade-in/out envelope ondajs gives\n//! `<OffthreadVideo>`. `startAt` trims the head; `playbackRate` re-times it.\n//!\n//! Sizing: the frame is fitted into the box per `fit` ('cover' crops, 'contain'\n//! letterboxes) by the renderer, centered over a black backing `<Rect>`, with the\n//! whole thing clipped to the box (rounded corners supported). Optional cinematic\n//! `letterbox` bars overlay top & bottom.\n//!\n//! Backend caveat: video decode + scale/opacity render on the Vello/GPU backend\n//! (the player's default); the CPU reference rasterizer skips video frames.\n\nimport { Group, Rect, Video, clipRect, useCurrentFrame, useVideoConfig } from '@onda-engine/react'\nimport { entryFade, exitFade } from '../choreography.js'\nimport { DURATION } from '../motion.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nexport interface VideoClipProps {\n /** URL or path to the video. The current frame is decoded per composition\n * frame by the player (browser) or `onda export` (native ffmpeg). */\n src: string\n /** Seconds into the source shown at the clip's frame 0 (trim the head). Default 0. */\n startAt?: number\n /** Source seconds advanced per composition second (1 = realtime). Default 1. */\n playbackRate?: number\n /** Seconds into the source to stop at (trim the tail). Past it the clip holds\n * its last frame unless `loop` is set. Omit to play to the source's end. */\n endAt?: number\n /** Loop the trimmed span `[startAt, endAt)` (requires `endAt`) for as long as\n * the clip is visible. */\n loop?: boolean\n /** Preview-only: how the player previews a source it can't composite (a\n * cross-origin URL without CORS). `'skip'` (default) blanks it + warns;\n * `'element'` overlays a plain `<video>` so it still plays in preview. Never\n * affects `onda export`. See {@link VideoProps.previewFallback}. */\n previewFallback?: 'skip' | 'element'\n /** Frames the clip waits before its fade-in begins (default 0). */\n delay?: TimeInput\n /** Frames the fade-in takes (default `DURATION.base` = 18). `0` = hard cut in. */\n fadeIn?: number\n /** Frames the fade-out takes (default `DURATION.base` = 18). `0` = hard cut out. */\n fadeOut?: number\n /** Visible hold of the clip in frames, used to time the fade-out (the fade-out\n * lands on the last `fadeOut` frames). When omitted, the clip never fades out —\n * mirrors ondajs skipping the fade-out when `endAt` is unset. */\n durationInFrames?: TimeInput\n /** How the poster fits its box. `'cover'` crops to fill (default); `'contain'`\n * letterboxes against black. */\n fit?: 'cover' | 'contain'\n /** Box width in px the clip occupies (default = full composition width). */\n width?: number\n /** Box height in px the clip occupies (default = full composition height). */\n height?: number\n /** Top-left x of the box in px (default 0 — canvas-filling). */\n x?: number\n /** Top-left y of the box in px (default 0 — canvas-filling). */\n y?: number\n /** Rounded corner radius of the box in px (default: theme `radius`). */\n borderRadius?: number\n /** Draw cinematic black letterbox bars top & bottom, each this many px tall\n * (default 0 = none). Drawn over the poster, inside the box. */\n letterbox?: number\n /** Backing color shown behind/around the poster (default: theme `background`). */\n backgroundColor?: string\n}\n\nexport function VideoClip({\n src,\n startAt = 0,\n playbackRate = 1,\n endAt,\n loop,\n previewFallback,\n delay: delayIn = 0,\n fadeIn = DURATION.base,\n fadeOut = DURATION.base,\n durationInFrames: durationInFramesIn,\n fit = 'cover',\n width,\n height,\n x = 0,\n y = 0,\n borderRadius: borderRadiusProp,\n letterbox = 0,\n backgroundColor: backgroundColorProp,\n}: VideoClipProps) {\n const frame = useCurrentFrame()\n const { fps, width: compWidth, height: compHeight } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n // `undefined` keeps its meaning (never fade out) — only parse when given.\n const durationInFrames =\n durationInFramesIn === undefined ? undefined : framesOf(durationInFramesIn, fps)\n const theme = useTheme()\n const borderRadius = borderRadiusProp ?? theme.radius\n const backgroundColor = backgroundColorProp ?? theme.background\n\n // Box the clip fills — default is the whole composition (ondajs's fill default).\n const boxW = width ?? compWidth\n const boxH = height ?? compHeight\n\n // Fade envelope: fade-in via entryFade, fade-out via exitFade landing on the\n // last `fadeOut` frames of the visible hold. Skipping fade-out when the hold is\n // unknown matches ondajs (no `endAt` → no fade-out timing).\n const fadeInOpacity =\n fadeIn > 0\n ? entryFade({ frame, fps, delay, durationInFrames: fadeIn }).opacity\n : frame >= delay\n ? 1\n : 0\n let opacity = fadeInOpacity\n if (durationInFrames !== undefined && fadeOut > 0) {\n const fadeOutStart = delay + Math.max(0, durationInFrames - fadeOut)\n const fadeOutOpacity = exitFade({\n frame,\n delay: fadeOutStart,\n durationInFrames: fadeOut,\n }).opacity\n opacity = Math.min(opacity, fadeOutOpacity)\n }\n\n return (\n // Outer Group positions + fades the whole clip; clip masks to the box so\n // 'cover' crops and 'contain' letterboxes cleanly within rounded corners.\n <Group x={x} y={y} opacity={opacity} clip={clipRect(boxW, boxH, borderRadius)}>\n {/* Black backing so any uncovered area (contain) reads as letterbox. */}\n <Rect width={boxW} height={boxH} cornerRadius={borderRadius} fill={backgroundColor} />\n {/* The current video frame, fitted to the box by the renderer (cover\n crops, contain letterboxes against the backing). */}\n <Video\n src={src}\n startFrom={startAt}\n playbackRate={playbackRate}\n endAt={endAt}\n loop={loop}\n previewFallback={previewFallback}\n width={boxW}\n height={boxH}\n fit={fit}\n />\n {/* Optional cinematic letterbox bars, top & bottom, inside the box. */}\n {letterbox > 0 ? (\n <Group>\n <Rect width={boxW} height={letterbox} fill=\"#000000\" />\n <Rect width={boxW} height={letterbox} y={boxH - letterbox} fill=\"#000000\" />\n </Group>\n ) : null}\n </Group>\n )\n}\n","//! Vignette — a static cinematic darkening at the canvas edges that pulls the\n//! eye toward the center. Ported from ondajs.\n//!\n//! Atmospheric layer, no motion: the output is identical on every frame, so the\n//! component never reads `useCurrentFrame` and is deterministic by construction.\n//!\n//! Engine note: ondajs renders a CSS `radial-gradient(ellipse at center, …)` —\n//! an *ellipse* matched to the (non-square) canvas, where all four corners reach\n//! full darkness together (CSS `farthest-corner`). The scene `radialGradient` is\n//! *circular* (one radius), so we size it to the half-diagonal\n//! (`hypot(W, H) / 2`) so the corners still land exactly at offset 1; on a\n//! non-square canvas the edge *midpoints* therefore stay a little lighter than\n//! CSS's aspect-matched ellipse would draw them. Intensity is baked into the\n//! edge stop's alpha rather than applied as a layer opacity (the engine\n//! equivalent, since scene nodes have no separate compositing-layer opacity).\n\nimport { Rect, radialGradient, useVideoConfig } from '@onda-engine/react'\nimport { useTheme } from '../theme.js'\n\nexport interface VignetteProps {\n /** Edge darkness. `0` = no vignette, `1` = fully dark edges. Default `0.5`. */\n intensity?: number\n /**\n * Percent (0..100) from center where the darkening begins. Larger = bigger\n * clean middle. Default `40`.\n */\n innerRadius?: number\n /** Edge color. Defaults to pure black for the classic cinematic frame (default: theme `background`). */\n color?: string\n}\n\n/** Clamp `n` into `[lo, hi]`. */\nfunction clamp(n: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, n))\n}\n\n/** Strip a leading `#` and any trailing alpha, yielding a 6-digit `rrggbb`. */\nfunction rgbHex(color: string): string {\n let hex = color.startsWith('#') ? color.slice(1) : color\n if (hex.length === 3) {\n // Expand `rgb` → `rrggbb`.\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n hex = `${r}${r}${g}${g}${b}${b}`\n } else if (hex.length === 4) {\n const r = hex[0] ?? '0'\n const g = hex[1] ?? '0'\n const b = hex[2] ?? '0'\n hex = `${r}${r}${g}${g}${b}${b}`\n }\n return hex.slice(0, 6).padEnd(6, '0')\n}\n\n/** A 0..1 alpha as a 2-digit hex channel. */\nfunction alphaHex(a: number): string {\n return clamp(Math.round(a * 255), 0, 255)\n .toString(16)\n .padStart(2, '0')\n}\n\nexport function Vignette({ intensity = 0.5, innerRadius = 40, color: colorProp }: VignetteProps) {\n const { width, height } = useVideoConfig()\n const theme = useTheme()\n const color = colorProp ?? theme.background\n\n // The clean center ends where the gradient starts darkening.\n const innerOffset = clamp(innerRadius, 0, 100) / 100\n // Half-diagonal: a circular radius that reaches the canvas corners exactly at\n // offset 1, matching CSS `radial-gradient(ellipse at center, … farthest-corner)`.\n const radius = Math.hypot(width, height) / 2\n\n const edge = `#${rgbHex(color)}${alphaHex(clamp(intensity, 0, 1))}`\n const clear = `#${rgbHex(color)}00`\n\n return (\n <Rect\n width={width}\n height={height}\n gradient={radialGradient([width / 2, height / 2], radius, [\n { offset: 0, color: clear },\n { offset: innerOffset, color: clear },\n { offset: 1, color: edge },\n ])}\n />\n )\n}\n","//! WordRotate — cycle a list of phrases in place, one at a time. Ported from ondajs.\n//!\n//! Faithful to the ondajs original: phrases are stacked at the SAME point and\n//! only one is visible at a time. Each phrase rises in on `SPRING_SMOOTH`\n//! (translateY 12 → 0), holds at full opacity, then fades down as the next\n//! arrives — the outgoing fade and incoming fade share frames so the swap reads\n//! as one motion. The opacity envelope is a 4-point keyframe on `HOUSE_EASE`,\n//! matching ondajs exactly. Slot timing: `slot = holdDuration + transitionDuration`\n//! and phrase `i` starts at `delay + i * slot`. After the last phrase has held,\n//! everything is faded out (no wrap-around — same as ondajs).\n//!\n//! Layout / placement notes (vs the ondajs/CSS original):\n//! - ondajs stacks the phrases with an `inline-grid` (`gridArea: 'phrase'`) and\n//! aligns them with CSS `justifySelf`/`text-align`. The engine has no CSS grid\n//! and `<Text>` is single-line + engine-measured, but the measured width is\n//! not available synchronously at author time. So the phrases are positioned\n//! ABSOLUTELY at an explicit `x`/`y` on a `<Group>` (NOT inside a `<Flex>`/\n//! `<AbsoluteFill>` — overlapping siblings would otherwise be stacked into a\n//! column by the layout pass, and a per-frame translate on a layout child is\n//! clobbered, HARD RULE 2). Each phrase nests an inner `<Group y={...}>` for\n//! the rise so the absolute placement (outer) and the motion translate (inner)\n//! don't fight.\n//! - Horizontal alignment (`align`) uses the REAL shaped phrase width\n//! (`measureText`) to shift the anchor left/center/right — exact, falling back\n//! to a glyph-count estimate only until the engine warms in the browser.\n//! - `letterSpacing` and `lineHeight` from the ondajs schema are dropped: the\n//! scene `<Text>` exposes neither. Phrases are single words/short phrases, so\n//! line-height is moot; letter-spacing has no engine primitive.\n//! - `size` (semantic typography role) and the `placement` region system are\n//! dropped in favor of explicit `fontSize` and `x`/`y` (defaulting to the\n//! composition center), matching how the other ported components place\n//! themselves.\n\nimport {\n Group,\n Text,\n interpolate,\n spring,\n useCurrentFrame,\n useVideoConfig,\n} from '@onda-engine/react'\nimport { HOUSE_EASE } from '../easing.js'\nimport { SPRING_SMOOTH } from '../motion.js'\nimport { measureText, useTextMetricsReady } from '../text-metrics.js'\nimport { type TextStyleProps, applyTextCase } from '../text-style.js'\nimport { useTheme } from '../theme.js'\nimport { type TimeInput, framesOf } from '../time.js'\n\nconst CLAMP = { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } as const\n\nexport interface WordRotateProps extends TextStyleProps {\n /** Phrases cycled in place, in order. One is visible at a time. */\n phrases?: string[]\n /** Frames before the first phrase begins to enter (default `0`). */\n delay?: TimeInput\n /** Frames each phrase holds at full opacity before the next arrives\n * (default `30`). */\n holdDuration?: TimeInput\n /** Frames for a single phrase to fade in (and, separately, fade out)\n * (default `12`). */\n transitionDuration?: number\n /** Font size in px. Phrases are usually large (default `96`). */\n fontSize?: number\n /** Horizontal anchor of each phrase relative to `x` (default `'left'`).\n * `'center'`/`'right'` use an estimated text width (see doc comment). */\n align?: 'left' | 'center' | 'right'\n /** Absolute x of the anchor point. Defaults to the composition center. */\n x?: number\n /** Absolute y (top-ish) of the text. Defaults to vertical center. */\n y?: number\n}\n\nexport function WordRotate({\n phrases: phrasesProp = ['fast', 'beautiful', 'restrained'],\n delay: delayIn = 0,\n holdDuration: holdDurationIn = 30,\n transitionDuration = 12,\n color: colorProp,\n fontSize = 96,\n fontFamily: fontFamilyProp,\n fontWeight = 600,\n italic = false,\n letterSpacing,\n uppercase,\n align = 'left',\n x,\n y,\n}: WordRotateProps) {\n const frame = useCurrentFrame()\n const { fps, width, height } = useVideoConfig()\n // TimeInput props -> frames (accepts numbers or '0.5s'/'500ms'/'12f').\n const delay = framesOf(delayIn, fps)\n const holdDuration = framesOf(holdDurationIn, fps)\n const theme = useTheme()\n const color = colorProp ?? theme.text\n const fontFamily = fontFamilyProp ?? theme.fontFamily\n // Uppercase each phrase (the primary text) before measure + render.\n const phrases = uppercase ? phrasesProp.map((p) => applyTextCase(p, { uppercase })) : phrasesProp\n // Warm real text measurement (browser re-renders when ready); per-phrase widths\n // are read with the sync `measureText` inside the map below.\n useTextMetricsReady()\n\n // Each phrase's slot overlaps its neighbor's by `transitionDuration` — the\n // outgoing fade and the incoming fade share frames, so the swap reads as one\n // motion rather than two. (Verbatim ondajs timing.)\n const slot = holdDuration + transitionDuration\n\n // Default the anchor to the composition center; roughly center the single\n // line vertically by lifting the top by ~0.6 of the cap height.\n const ax = x ?? Math.round(width / 2)\n const py = y ?? Math.round(height / 2 - fontSize * 0.6)\n\n return (\n <Group x={ax} y={py}>\n {phrases.map((phrase, i) => {\n const phraseStart = delay + i * slot\n const local = frame - phraseStart\n\n const rise = spring({\n frame: local,\n fps,\n config: SPRING_SMOOTH,\n durationInFrames: transitionDuration,\n })\n const translateY = interpolate(rise, [0, 1], [12, 0], CLAMP)\n\n const opacity = interpolate(\n local,\n [0, transitionDuration, transitionDuration + holdDuration, slot + transitionDuration],\n [0, 1, 1, 0],\n { ...CLAMP, easing: HOUSE_EASE },\n )\n\n // Anchor offset: 'left' is exact; 'center'/'right' use the real shaped\n // width (measured, tracking-aware) so alignment hugs the actual phrase.\n const estWidth = measureText(phrase, fontSize, {\n fontFamily,\n fontWeight,\n letterSpacing,\n }).width\n const offsetX = align === 'center' ? -estWidth / 2 : align === 'right' ? -estWidth : 0\n\n return (\n <Group key={`${i}-${phrase}`} x={offsetX} y={translateY} opacity={opacity}>\n <Text\n fontSize={fontSize}\n color={color}\n fontFamily={fontFamily}\n fontWeight={fontWeight}\n italic={italic}\n letterSpacing={letterSpacing}\n >\n {phrase}\n </Text>\n </Group>\n )\n })}\n </Group>\n )\n}\n"]}