{"version":3,"sources":["../src/events.ts","../src/history.ts","../src/ids.ts","../src/keyframes/types.ts","../src/keyframes/interpolate.ts","../src/model.ts","../src/timeline/layout.ts","../src/playback/html-video.ts","../src/playback/canvas-compositor.ts","../src/theme.ts","../src/i18n.ts","../src/ui/thumbnails.ts","../src/ui/format.ts","../src/timeline/draw.ts","../src/timeline/hit.ts","../src/timeline/index.ts","../src/ui/keyframe-overlay.ts","../src/ui/keyframe-panel.ts","../src/ui/icons.ts","../src/ui/preview-controls.ts","../src/ui/aspect-picker.ts","../src/ui/toolbar.ts","../src/ui/index.ts","../src/editor.ts"],"names":["TRACK_HEIGHT","RULER_HEIGHT","c","ti","track","snapTargets","parseAspect","SNAP_PX","clampScale","opts","evenPx"],"mappings":"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","file":"index.cjs","sourcesContent":["type Handler<T> = (payload: T) => void;\n\n/**\n * Minimal typed event bus. Returns an unsubscribe function from `on` so\n * callers don't have to retain the handler reference. No once/wildcard\n * by design — keep the surface small until something needs them.\n *\n * EventMap is intentionally unconstrained — its keys are the event\n * names and values are payload types. An explicit `Record` constraint\n * would force consumers to add an index signature, which would in turn\n * mask typos in `emit` / `on`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class EventBus<EventMap extends Record<string, any>> {\n  private listeners = new Map<keyof EventMap, Set<Handler<any>>>();\n\n  on<K extends keyof EventMap>(\n    event: K,\n    handler: Handler<EventMap[K]>,\n  ): () => void {\n    let set = this.listeners.get(event);\n    if (!set) {\n      set = new Set();\n      this.listeners.set(event, set);\n    }\n    set.add(handler);\n    return () => this.off(event, handler);\n  }\n\n  off<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): void {\n    this.listeners.get(event)?.delete(handler);\n  }\n\n  emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void {\n    const set = this.listeners.get(event);\n    if (!set) return;\n    for (const h of set) {\n      try {\n        h(payload);\n      } catch (err) {\n        // Swallow handler errors so one broken listener can't kill the editor.\n        // eslint-disable-next-line no-console\n        console.error(\"[aicut] event handler threw\", event, err);\n      }\n    }\n  }\n\n  clear(): void {\n    this.listeners.clear();\n  }\n}\n","import type { Project } from \"./types.js\";\n\n/**\n * Snapshot-based undo/redo. Each mutation pushes the *previous*\n * project onto the undo stack and clears redo. Cheap enough for\n * v1: deep cloning a project JSON of a few dozen clips is O(<1ms).\n *\n * Capped to prevent unbounded memory growth on long sessions.\n */\nexport class HistoryStack {\n  private undoStack: Project[] = [];\n  private redoStack: Project[] = [];\n  private readonly limit: number;\n\n  constructor(limit = 50) {\n    this.limit = limit;\n  }\n\n  /** Call BEFORE applying a mutation. */\n  push(previous: Project): void {\n    this.undoStack.push(clone(previous));\n    if (this.undoStack.length > this.limit) this.undoStack.shift();\n    this.redoStack.length = 0;\n  }\n\n  canUndo(): boolean {\n    return this.undoStack.length > 0;\n  }\n\n  canRedo(): boolean {\n    return this.redoStack.length > 0;\n  }\n\n  /** Returns the project to restore, or null if nothing to undo. */\n  undo(current: Project): Project | null {\n    const prev = this.undoStack.pop();\n    if (!prev) return null;\n    this.redoStack.push(clone(current));\n    return prev;\n  }\n\n  redo(current: Project): Project | null {\n    const next = this.redoStack.pop();\n    if (!next) return null;\n    this.undoStack.push(clone(current));\n    return next;\n  }\n\n  clear(): void {\n    this.undoStack.length = 0;\n    this.redoStack.length = 0;\n  }\n}\n\nfunction clone(p: Project): Project {\n  return JSON.parse(JSON.stringify(p)) as Project;\n}\n","/**\n * Short, stable, URL-safe ID. Not cryptographic — fine for client IDs\n * that get persisted in the project JSON.\n */\nexport function createId(prefix = \"id\"): string {\n  const rand = Math.random().toString(36).slice(2, 8);\n  const t = Date.now().toString(36).slice(-4);\n  return `${prefix}_${t}${rand}`;\n}\n","/**\n * The transform a clip's content is rendered with at a given moment.\n * Engines apply this INSIDE a fixed output frame: `panX` / `panY`\n * translate the content (in CSS px), `scale` resizes it around the\n * output frame's center. Anything pushed outside the frame is\n * clipped. Identity = `{ panX: 0, panY: 0, scale: 1 }`.\n */\nexport interface EffectiveTransform {\n  panX: number;\n  panY: number;\n  scale: number;\n}\n\n/** Identity transform — no pan, no scaling (content fills the output frame). */\nexport const IDENTITY_TRANSFORM: EffectiveTransform = {\n  panX: 0,\n  panY: 0,\n  scale: 1,\n};\n\n/** True when a transform is effectively identity (within FP slop). */\nexport function isIdentityTransform(t: EffectiveTransform): boolean {\n  return (\n    Math.abs(t.panX) < 0.001 &&\n    Math.abs(t.panY) < 0.001 &&\n    Math.abs(t.scale - 1) < 0.0001\n  );\n}\n","import type { Clip, EasingKind, Keyframe, KeyframeProp, Ms } from \"../types.js\";\nimport {\n  IDENTITY_TRANSFORM,\n  type EffectiveTransform,\n} from \"./types.js\";\n\n/**\n * Map normalized time t∈[0,1] to eased t' via cubic easing. Cubic was\n * picked over quadratic because the start / end \"stickiness\" is more\n * pronounced — when the user picks `easeIn` they typically want the\n * motion to clearly hold at the start, not just barely slow down.\n *\n * `easing` is the leaving keyframe's outgoing curve — matches AE /\n * Premiere / CapCut convention so the user only sets it once per kf,\n * not once per segment.\n */\nexport function applyEasing(t: number, easing: EasingKind): number {\n  switch (easing) {\n    case \"linear\":\n      return t;\n    case \"easeIn\":\n      return t * t * t;\n    case \"easeOut\": {\n      const u = 1 - t;\n      return 1 - u * u * u;\n    }\n    case \"easeInOut\":\n      return t < 0.5\n        ? 4 * t * t * t\n        : 1 - Math.pow(-2 * t + 2, 3) / 2;\n  }\n}\n\n/** Default value when a property has neither static base nor keyframes. */\nfunction defaultFor(prop: KeyframeProp): number {\n  return prop === \"scale\" ? 1 : 0;\n}\n\n/** Static fallback for `prop` on a clip. */\nfunction staticValue(clip: Clip, prop: KeyframeProp): number {\n  const v = clip[prop];\n  return v ?? defaultFor(prop);\n}\n\n/**\n * Sub-keyframes for a single property in time order. Cheap on small\n * arrays (a few keyframes per clip in practice) — no caching needed.\n */\nexport function keyframesForProp(\n  kfs: Keyframe[],\n  prop: KeyframeProp,\n): Keyframe[] {\n  const out: Keyframe[] = [];\n  for (const k of kfs) if (k.prop === prop) out.push(k);\n  out.sort((a, b) => a.time - b.time);\n  return out;\n}\n\n/** True when the clip has any keyframes pinning this property. */\nexport function hasKeyframesForProp(clip: Clip, prop: KeyframeProp): boolean {\n  return clip.keyframes?.some((k) => k.prop === prop) ?? false;\n}\n\n/**\n * Interpolate one property at the given clip-local time.\n *\n * Rules per property:\n *   - No keyframes for this prop → static base (or 0 / 1).\n *   - Before first keyframe → first keyframe's value (held).\n *   - After last keyframe   → last keyframe's value (held).\n *   - Between two           → linear interpolation.\n */\nexport function interpolateProp(\n  clip: Clip,\n  prop: KeyframeProp,\n  localMs: Ms,\n): number {\n  if (!clip.keyframes || clip.keyframes.length === 0) {\n    return staticValue(clip, prop);\n  }\n  const arr = keyframesForProp(clip.keyframes, prop);\n  if (arr.length === 0) return staticValue(clip, prop);\n  if (arr.length === 1) return arr[0]!.value;\n  const first = arr[0]!;\n  const last = arr[arr.length - 1]!;\n  if (localMs <= first.time) return first.value;\n  if (localMs >= last.time) return last.value;\n  for (let i = 0; i < arr.length - 1; i += 1) {\n    const a = arr[i]!;\n    const b = arr[i + 1]!;\n    if (localMs >= a.time && localMs <= b.time) {\n      if (b.time === a.time) return a.value;\n      const rawT = (localMs - a.time) / (b.time - a.time);\n      // Easing belongs to the LEAVING keyframe (a) — the curve from\n      // a→b is shaped by a.easing. Undefined / missing field\n      // gracefully degrades to \"linear\" so old projects look the same.\n      const eased = applyEasing(rawT, a.easing ?? \"linear\");\n      return a.value + (b.value - a.value) * eased;\n    }\n  }\n  return last.value;\n}\n\n/**\n * Effective transform = all three properties evaluated together. The\n * engine applies this to the content inside the fixed output frame:\n * scale around frame center, then translate by (panX, panY).\n */\nexport function getEffectiveTransform(\n  clip: Clip,\n  localMs: Ms,\n): EffectiveTransform {\n  if (\n    (!clip.keyframes || clip.keyframes.length === 0) &&\n    clip.panX === undefined &&\n    clip.panY === undefined &&\n    clip.scale === undefined\n  ) {\n    return IDENTITY_TRANSFORM;\n  }\n  return {\n    panX: interpolateProp(clip, \"panX\", localMs),\n    panY: interpolateProp(clip, \"panY\", localMs),\n    scale: interpolateProp(clip, \"scale\", localMs),\n  };\n}\n\n/** Same as `getEffectiveTransform` but takes timeline-absolute time. */\nexport function getTransformAtTimelineTime(\n  clip: Clip,\n  timelineMs: Ms,\n): EffectiveTransform {\n  return getEffectiveTransform(clip, timelineMs - clip.start);\n}\n\n/**\n * Insert a keyframe for `prop` at `time`, or update value if one\n * already exists at the same (rounded) time. Returns the next array.\n *\n * The 16ms tolerance handles \"click button while seeking\" — two\n * keyframes 1 frame apart get coalesced. Reference behavior.\n */\nexport function upsertKeyframe(\n  kfs: Keyframe[] | undefined,\n  prop: KeyframeProp,\n  time: Ms,\n  value: number,\n  idFactory: () => string,\n): Keyframe[] {\n  const existing = kfs ?? [];\n  const idx = existing.findIndex(\n    (k) => k.prop === prop && Math.abs(k.time - time) < 16,\n  );\n  if (idx >= 0) {\n    const next = existing.slice();\n    next[idx] = { ...next[idx]!, value };\n    return next;\n  }\n  return [...existing, { id: idFactory(), prop, time, value }];\n}\n\n/** Drop every keyframe for one prop on a clip. */\nexport function removeKeyframesForProp(\n  kfs: Keyframe[] | undefined,\n  prop: KeyframeProp,\n): Keyframe[] {\n  return (kfs ?? []).filter((k) => k.prop !== prop);\n}\n","import { createId } from \"./ids.js\";\nimport { interpolateProp } from \"./keyframes/interpolate.js\";\nimport type {\n  AspectRatio,\n  Clip,\n  Keyframe,\n  KeyframeProp,\n  Ms,\n  Project,\n  ProjectOutput,\n  Track,\n} from \"./types.js\";\n\n/**\n * Default 1080p-tier output dimensions per aspect ratio — the canvas\n * the editor renders into when the user picks an aspect from the\n * built-in chip. 1080p is the lowest-common-denominator distribution\n * target (web, mobile, most SaaS encoders) and matches CapCut's\n * \"Standard 1080p\" default. Hosts can override by writing directly\n * into `project.output` via `editor.setOutput(...)`.\n */\nexport const DEFAULT_OUTPUT_DIMS: Record<\n  AspectRatio,\n  { width: number; height: number }\n> = {\n  \"16:9\": { width: 1920, height: 1080 },\n  \"9:16\": { width: 1080, height: 1920 },\n  \"1:1\": { width: 1080, height: 1080 },\n  \"4:3\": { width: 1440, height: 1080 },\n  \"3:4\": { width: 1080, height: 1440 },\n  \"4:5\": { width: 1080, height: 1350 },\n  \"21:9\": { width: 2560, height: 1080 },\n};\n\n/** Pick canvas dims for a chosen aspect, snapping to even pixels. */\nexport function defaultOutputForAspect(\n  aspect: AspectRatio,\n): { width: number; height: number } {\n  const d = DEFAULT_OUTPUT_DIMS[aspect];\n  return { width: evenPx(d.width), height: evenPx(d.height) };\n}\n\nfunction evenPx(n: number): number {\n  const r = Math.max(2, Math.round(n));\n  return r % 2 === 0 ? r : r - 1;\n}\n\nconst KEYFRAME_PROPS: KeyframeProp[] = [\"panX\", \"panY\", \"scale\"];\n\n/**\n * Default frame rate when a project has no `fps`. 30 matches CapCut /\n * Premiere \"new project\" defaults. Changing this is a project-wide\n * UX shift — the user should opt in via `Project.fps`.\n */\nexport const DEFAULT_FPS = 30;\n/** Shift + arrow nudges this many frames at once. */\nexport const BIG_FRAME_STEP = 10;\n\n/**\n * Project's effective fps. Resolution order: `output.fps` (new) →\n * top-level `fps` (legacy back-compat) → `DEFAULT_FPS`. The two\n * fields coexist so existing projects keep working without a manual\n * migration; `setOutput` writes to `output.fps` going forward.\n */\nexport function projectFps(project: Project): number {\n  const fromOutput = project.output?.fps;\n  if (fromOutput != null && fromOutput > 0) return fromOutput;\n  const f = project.fps;\n  return f != null && f > 0 ? f : DEFAULT_FPS;\n}\n\n/** Milliseconds per frame at the project's fps. Rounded to integer ms\n *  because the playhead is integer-ms and we don't want sub-ms drift. */\nexport function frameStepMs(project: Project): number {\n  return Math.max(1, Math.round(1000 / projectFps(project)));\n}\n\n/** Milliseconds for a shift+arrow nudge (one \"big step\" = N frames). */\nexport function bigFrameStepMs(project: Project): number {\n  return Math.max(1, Math.round((BIG_FRAME_STEP * 1000) / projectFps(project)));\n}\n\nexport function createEmptyProject(): Project {\n  return {\n    version: 1,\n    sources: [],\n    tracks: [{ id: createId(\"track\"), kind: \"video\", clips: [] }],\n  };\n}\n\nexport function clipDuration(c: Clip): Ms {\n  return c.out - c.in;\n}\n\n/** End of a clip on the timeline (start + duration). */\nexport function clipEnd(c: Clip): Ms {\n  return c.start + clipDuration(c);\n}\n\nexport function trackEnd(track: Track): Ms {\n  let max = 0;\n  for (const c of track.clips) {\n    const end = clipEnd(c);\n    if (end > max) max = end;\n  }\n  return max;\n}\n\n/**\n * Find which clip on the track contains `timeMs`. Edges:\n *   - start inclusive\n *   - end exclusive (a clip ending at T does not contain T)\n */\nexport function findClipContaining(track: Track, timeMs: Ms): Clip | null {\n  for (const c of track.clips) {\n    if (timeMs >= c.start && timeMs < clipEnd(c)) return c;\n  }\n  return null;\n}\n\nexport function findTrackOfClip(\n  project: Project,\n  clipId: string,\n): Track | null {\n  for (const t of project.tracks) {\n    if (t.clips.some((c) => c.id === clipId)) return t;\n  }\n  return null;\n}\n\n/**\n * Defensive normalization — ensures clips on each track are sorted by\n * `start`, IDs exist, and trivially-empty clips (out <= in) are dropped.\n * Called from `Editor.setProject` so consumers can hand us loosely-formed\n * JSON without risking inconsistent internal state.\n */\nexport function normalizeProject(project: Project): Project {\n  const sources = project.sources.map((s) => ({ ...s }));\n  const tracks = project.tracks.map<Track>((t) => {\n    const clips = t.clips\n      .filter((c) => c.out > c.in)\n      .map<Clip>((c) => {\n        const out: Clip = { ...c, id: c.id || createId(\"clip\") };\n        if (c.keyframes && c.keyframes.length > 0) {\n          // Sort by (prop, time) + assign ids to any keyframe missing\n          // one. Drop empties / out-of-range keyframes (defensive — a\n          // host restoring a stale snapshot might have them).\n          //\n          // Also: migrate the v0.5 tuple-keyframe format\n          //   { time, x?, y?, scale? }\n          // into per-property keyframes if we see any. Old projects\n          // round-trip cleanly into the new model without the host\n          // having to know.\n          const duration = c.out - c.in;\n          out.keyframes = migrateKeyframes(c.keyframes)\n            .filter((kf) => kf.time >= 0 && kf.time <= duration)\n            .map<Keyframe>((kf) => ({ ...kf, id: kf.id || createId(\"kf\") }))\n            .sort((a, b) => {\n              if (a.prop !== b.prop) return a.prop.localeCompare(b.prop);\n              return a.time - b.time;\n            });\n        }\n        return out;\n      })\n      .sort((a, b) => a.start - b.start);\n    return { ...t, id: t.id || createId(\"track\"), clips };\n  });\n  // Preserve top-level project fields beyond version/sources/tracks.\n  // `aspect`, `fps`, and `output` are authored state that must survive\n  // a setProject round-trip — without this, picking 9:16 in the toolbar\n  // and then adding a clip (which routes through setProject) used to\n  // silently reset the canvas back to the first-clip fallback.\n  const norm: Project = { version: 1, sources, tracks };\n  if (project.aspect != null) norm.aspect = project.aspect;\n  if (project.fps != null && project.fps > 0) norm.fps = project.fps;\n  // Fill in `output` for projects that don't have it yet — `aspect`\n  // → DEFAULT_OUTPUT_DIMS, falling back to a sane 1080p when neither\n  // is set. Hosts that need a different size can call `setOutput`\n  // anytime; once persisted in the project JSON the migration is\n  // a no-op.\n  const explicit = normalizeOutput(project.output);\n  if (explicit) {\n    norm.output = explicit;\n  } else if (project.aspect) {\n    const dims = defaultOutputForAspect(project.aspect);\n    norm.output = { width: dims.width, height: dims.height };\n    if (project.fps != null && project.fps > 0) norm.output.fps = project.fps;\n  }\n  return norm;\n}\n\nfunction normalizeOutput(\n  output: ProjectOutput | undefined,\n): ProjectOutput | null {\n  if (!output) return null;\n  const w = evenPx(output.width);\n  const h = evenPx(output.height);\n  if (w <= 0 || h <= 0) return null;\n  const norm: ProjectOutput = { width: w, height: h };\n  if (output.fps != null && output.fps > 0) norm.fps = output.fps;\n  return norm;\n}\n\n/**\n * Back-compat: the v0.5 keyframe shape was a single object with\n * `{ time, x?, y?, scale? }` — all three values together. v0.6 splits\n * them into per-property entries `{ prop, time, value }`. If we see\n * the old shape, fan out into N per-property keyframes; otherwise\n * pass through unchanged.\n */\nfunction migrateKeyframes(\n  raw: Array<\n    | Keyframe\n    | { id?: string; time: number; x?: number; y?: number; scale?: number }\n  >,\n): Keyframe[] {\n  const out: Keyframe[] = [];\n  for (const kf of raw) {\n    if (\"prop\" in kf && \"value\" in kf) {\n      out.push(kf as Keyframe);\n      continue;\n    }\n    // Old tuple shape — fan out.\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const tuple = kf as any;\n    const id = tuple.id;\n    const t = tuple.time;\n    if (typeof tuple.x === \"number\") {\n      out.push({\n        id: id ? `${id}-px` : createId(\"kf\"),\n        prop: \"panX\",\n        time: t,\n        value: tuple.x,\n      });\n    }\n    if (typeof tuple.y === \"number\") {\n      out.push({\n        id: id ? `${id}-py` : createId(\"kf\"),\n        prop: \"panY\",\n        time: t,\n        value: tuple.y,\n      });\n    }\n    if (typeof tuple.scale === \"number\") {\n      out.push({\n        id: id ? `${id}-s` : createId(\"kf\"),\n        prop: \"scale\",\n        time: t,\n        value: tuple.scale,\n      });\n    }\n  }\n  return out;\n}\n\n/** Splits a clip at `localOffset` ms (measured from clip.start on the timeline). */\nexport function splitClipAt(clip: Clip, localOffset: Ms): [Clip, Clip] | null {\n  const sourceLen = clip.out - clip.in;\n  if (localOffset <= 0 || localOffset >= sourceLen) return null;\n  const left: Clip = { ...clip, out: clip.in + localOffset };\n  const right: Clip = {\n    ...clip,\n    id: createId(\"clip\"),\n    in: clip.in + localOffset,\n    start: clip.start + localOffset,\n  };\n  // Partition keyframes across the cut, AND insert interpolated\n  // boundary keyframes at the seam so playing the two halves back-to-\n  // back is visually identical to the un-cut clip. Without the\n  // boundary insertion, a cut mid-ramp would snap to the prior kf's\n  // value on the left half (because \"after last kf = hold\") and to\n  // the next kf's value on the right half — instant value jump at\n  // the seam. Done per-property because only the props that actually\n  // have keyframes need a boundary; props that ride the static base\n  // are inherited unchanged.\n  //\n  // Static base values (panX / panY / scale) are inherited unchanged\n  // by both halves — they were per-clip defaults.\n  if (clip.keyframes && clip.keyframes.length > 0) {\n    const leftKf: Keyframe[] = [];\n    const rightKf: Keyframe[] = [];\n    for (const prop of KEYFRAME_PROPS) {\n      const propKfs = clip.keyframes.filter((k) => k.prop === prop);\n      if (propKfs.length === 0) continue;\n      const boundaryValue = interpolateProp(clip, prop, localOffset);\n      let leftSeamPresent = false;\n      let rightSeamPresent = false;\n      for (const kf of propKfs) {\n        if (kf.time < localOffset) {\n          leftKf.push(kf);\n        } else if (kf.time > localOffset) {\n          // Re-id the shifted ones — the original kf belongs to the\n          // left half conceptually; the right half is a brand-new clip.\n          rightKf.push({ ...kf, id: createId(\"kf\"), time: kf.time - localOffset });\n        } else {\n          // kf sits exactly on the cut. It IS the seam — keep on the\n          // left at its current time, and clone to the right at t=0.\n          leftKf.push(kf);\n          leftSeamPresent = true;\n          rightKf.push({ ...kf, id: createId(\"kf\"), time: 0 });\n          rightSeamPresent = true;\n        }\n      }\n      if (!leftSeamPresent) {\n        leftKf.push({\n          id: createId(\"kf\"),\n          prop,\n          time: localOffset,\n          value: boundaryValue,\n        });\n      }\n      if (!rightSeamPresent) {\n        rightKf.push({\n          id: createId(\"kf\"),\n          prop,\n          time: 0,\n          value: boundaryValue,\n        });\n      }\n    }\n    left.keyframes = leftKf.length > 0 ? leftKf : undefined;\n    right.keyframes = rightKf.length > 0 ? rightKf : undefined;\n  }\n  return [left, right];\n}\n\n/** Alias retained for back-compat with existing call sites. */\nexport function findClipAt(track: Track, timeMs: Ms): Clip | null {\n  return findClipContaining(track, timeMs);\n}\n\nexport function projectDuration(project: Project): Ms {\n  let max = 0;\n  for (const t of project.tracks) {\n    const e = trackEnd(t);\n    if (e > max) max = e;\n  }\n  return max;\n}\n","import type { Clip, Ms, Project, Track } from \"../types.js\";\n\n/** Visual constants — kept here so draw + hit-test share one source of truth.\n *  The two row-height values are `let` rather than `const` so hosts can\n *  shrink the timeline footprint for small screens via\n *  `setTimelineMetrics(...)`. ES module live bindings mean every importer\n *  sees the updated value automatically. */\nexport let TRACK_HEIGHT = 56;\nexport let RULER_HEIGHT = 24;\nexport const HEADER_WIDTH = 96;\nexport const HANDLE_PX = 8;\nexport const CLIP_INSET = 6;\nexport const SCALE_MIN = 10;\n/** Tuned so the user can zoom down to \"1 frame per major tick\" at\n *  30 fps with the default `rulerMinTickPx` (80px). 80px × 30 fps =\n *  2400 px/sec. Higher fps projects can still hit 1-frame granularity\n *  visually by lowering `rulerMinTickPx`. */\nexport const SCALE_MAX = 2400;\n\n/**\n * Left / right padding inside the timeline canvas, between the header\n * column (or canvas edge when the header is hidden) and where actual\n * content (clips + ruler ticks + playhead) is drawn. Without this the\n * t=0 playhead has its left half clipped, the first clip touches the\n * canvas edge, and the visual rhythm with the rest of the editor\n * chrome is off.\n */\nexport const TIMELINE_PAD_LEFT = 12;\nexport const TIMELINE_PAD_RIGHT = 12;\n\n/**\n * Where on the canvas does the timeline CONTENT area start (in CSS\n * pixels)? Combines the optional header column with the left padding.\n * Use this instead of `showHeader ? HEADER_WIDTH : 0` everywhere —\n * one place to change if the padding ever becomes configurable.\n */\nexport function contentLeftX(showHeader: boolean): number {\n  return (showHeader ? HEADER_WIDTH : 0) + TIMELINE_PAD_LEFT;\n}\n\n/**\n * Override the default timeline row + ruler heights. Process-wide — call\n * before / during editor construction. Useful when the editor is mounted\n * in a small viewport (e.g. side-by-side panel on a laptop) and the\n * default 56px tracks crowd out the preview.\n *\n * Reasonable ranges: trackHeight ∈ [28, 96], rulerHeight ∈ [18, 36].\n * Anything smaller leaves no room for the clip label or the time ticks.\n *\n * Multi-editor mounts share these values. If you have two editors with\n * different needs, agree on the smaller one or remount on switch.\n */\nexport function setTimelineMetrics(opts: {\n  trackHeight?: number;\n  rulerHeight?: number;\n}): void {\n  if (opts.trackHeight != null && opts.trackHeight > 0) {\n    TRACK_HEIGHT = Math.round(opts.trackHeight);\n  }\n  if (opts.rulerHeight != null && opts.rulerHeight > 0) {\n    RULER_HEIGHT = Math.round(opts.rulerHeight);\n  }\n}\n\n/** Scrollbar geometry. */\nexport const SCROLLBAR_THICKNESS = 10;\n/** Minimum thumb length so it stays grabbable at large content sizes. */\nexport const SCROLLBAR_MIN_THUMB = 24;\n/** Gutter inset from the canvas edges so the bar doesn't clip. */\nexport const SCROLLBAR_INSET = 2;\n\n/** Total height = ruler + sum of tracks. Caller decides if it wants more. */\nexport function totalHeight(tracks: Track[]): number {\n  return RULER_HEIGHT + tracks.length * TRACK_HEIGHT;\n}\n\n/**\n * Track-stack content height — what the scrollbars compare against\n * the visible track region. Includes one extra TRACK_HEIGHT when a\n * drag is in flight so the \"+ 新轨道\" phantom row is reachable.\n */\nexport function contentHeight(tracks: Track[], isDragging: boolean): number {\n  return tracks.length * TRACK_HEIGHT + (isDragging ? TRACK_HEIGHT : 0);\n}\n\n/** Pixels of timeline content along the X axis at the given zoom. */\nexport function contentWidth(project: Project, pxPerSec: number): number {\n  let max = 0;\n  for (const t of project.tracks) {\n    for (const c of t.clips) {\n      const end = c.start + (c.out - c.in);\n      if (end > max) max = end;\n    }\n  }\n  return (max / 1000) * pxPerSec;\n}\n\n/** Top-edge y for a track at `index`. */\nexport function trackY(index: number): number {\n  return RULER_HEIGHT + index * TRACK_HEIGHT;\n}\n\n/** Inverse of trackY — which track index (or -1) does a given y fall in.\n *  `scrollTop` shifts the visible window down; pass 0 if not scrolling. */\nexport function trackIndexAt(\n  y: number,\n  trackCount: number,\n  scrollTop = 0,\n): number {\n  if (y < RULER_HEIGHT) return -1;\n  const contentY = y - RULER_HEIGHT + scrollTop;\n  const idx = Math.floor(contentY / TRACK_HEIGHT);\n  if (idx < 0 || idx >= trackCount) return -1;\n  return idx;\n}\n\n/** Convert timeline ms → x pixel coordinate, accounting for header,\n *  the left padding, and scroll. */\nexport function msToX(\n  timeMs: Ms,\n  pxPerSec: number,\n  scrollLeft: number,\n  showHeader: boolean,\n): number {\n  return contentLeftX(showHeader) + (timeMs / 1000) * pxPerSec - scrollLeft;\n}\n\n/** Convert x pixel coordinate back → timeline ms. */\nexport function xToMs(\n  x: number,\n  pxPerSec: number,\n  scrollLeft: number,\n  showHeader: boolean,\n): Ms {\n  return Math.max(\n    0,\n    ((x - contentLeftX(showHeader) + scrollLeft) / pxPerSec) * 1000,\n  );\n}\n\n/**\n * Choose a \"nice\" major-tick interval covering at least `targetSec`.\n * Drives the ruler so it never shows ugly intervals like every 3.7s.\n */\nexport function niceTickSeconds(targetSec: number): number {\n  if (targetSec <= 0) return 1;\n  const exp = Math.floor(Math.log10(targetSec));\n  const base = targetSec / Math.pow(10, exp);\n  let nice: number;\n  if (base < 1.5) nice = 1;\n  else if (base < 3) nice = 2;\n  else if (base < 7) nice = 5;\n  else nice = 10;\n  return nice * Math.pow(10, exp);\n}\n\n/**\n * Pick the ruler's major + sub tick interval for the given zoom + fps.\n *\n * Behavior matches CapCut-desktop: major ticks ALWAYS land on whole\n * seconds (1s, 2s, 5s, …) so the labels stay readable at every zoom.\n * Sub-ticks switch to frame-aligned spacing (1 per frame) once the\n * zoom is high enough to render a frame as ≥ `FRAME_SUB_MIN_PX` —\n * that's how seconds + 30 frames-per-second both stay visible at the\n * same time. At lower zoom we keep the classic 5-subs-per-major.\n */\nconst FRAME_SUB_MIN_PX = 10;\n\nexport interface RulerTicks {\n  /** Major (labeled) tick interval in seconds. Always ≥ 1s. */\n  majorSec: number;\n  /** Unlabeled sub-tick interval in seconds. Smaller than majorSec. */\n  subSec: number;\n}\n\nexport function pickRulerTicks(\n  targetSec: number,\n  fps: number,\n  pxPerSec: number,\n): RulerTicks {\n  const frameSec = 1 / Math.max(1, fps);\n  // Major: pick the smallest nice interval ≥ 1s that's at least the\n  // requested target. `niceTickSeconds` may return 0.2s / 0.5s at high\n  // zoom — clamp those up to 1s so the labels stay \"Ns\" no matter how\n  // far the user zooms in.\n  const majorSec = Math.max(1, niceTickSeconds(targetSec));\n  // Sub: drop to 1-frame ticks once frames are visually distinct.\n  // Otherwise 5 subs per major (0.2s, 0.4s, …).\n  const framePx = pxPerSec * frameSec;\n  const subSec =\n    framePx >= FRAME_SUB_MIN_PX ? frameSec : majorSec / 5;\n  return { majorSec, subSec };\n}\n\nexport function formatRulerLabel(sec: number): string {\n  if (sec < 60) return `${Math.round(sec * 10) / 10}s`;\n  const m = Math.floor(sec / 60);\n  const s = Math.round(sec - m * 60);\n  return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n\nexport function clampScale(s: number): number {\n  return Math.max(SCALE_MIN, Math.min(SCALE_MAX, s));\n}\n\n/**\n * Snap targets aggregated from all clips in the project plus the\n * playhead and origin. Excludes the dragged clip (caller passes its id).\n */\nexport function snapTargets(\n  project: Project,\n  playheadMs: Ms,\n  ignoreClipId: string | null,\n): Ms[] {\n  const arr: Ms[] = [0, playheadMs];\n  for (const t of project.tracks) {\n    for (const c of t.clips) {\n      if (c.id === ignoreClipId) continue;\n      arr.push(c.start, c.start + (c.out - c.in));\n      // Each keyframe is a timeline-absolute snap target. Without this\n      // keyframes can't snap to each other (or to clip drags hitting\n      // a keyframe's time). Note: a keyframe's own time is also a\n      // legit target during its own drag — same-time check in the\n      // snap distance loop handles \"snap to self\" as a zero-cost no-op.\n      if (c.keyframes) {\n        for (const kf of c.keyframes) arr.push(c.start + kf.time);\n      }\n    }\n  }\n  return arr;\n}\n\n/**\n * Return whether placing `clip` at `start..end` on `track` would\n * collide with any *other* clip already on that track.\n */\nexport function wouldOverlap(\n  track: Track,\n  clipId: string,\n  start: Ms,\n  end: Ms,\n): boolean {\n  for (const c of track.clips) {\n    if (c.id === clipId) continue;\n    const cEnd = c.start + (c.out - c.in);\n    if (start < cEnd && end > c.start) return true;\n  }\n  return false;\n}\n\n/** Look up `(track, clip)` for `clipId` across the project. */\nexport function findClip(\n  project: Project,\n  clipId: string,\n): { track: Track; clip: Clip; trackIndex: number } | null {\n  for (let i = 0; i < project.tracks.length; i++) {\n    const t = project.tracks[i]!;\n    const c = t.clips.find((c) => c.id === clipId);\n    if (c) return { track: t, clip: c, trackIndex: i };\n  }\n  return null;\n}\n\n/**\n * Uncovered intervals across the whole video timeline, in ms — i.e.\n * spans where no clip on any video track plays. Returned in time\n * order, half-open `[start, end)`. Used by the drawer to highlight\n * gaps in warning color so the user notices accidentally orphaned\n * regions.\n */\nexport function uncoveredIntervals(project: Project): Array<[Ms, Ms]> {\n  const intervals: Array<[Ms, Ms]> = [];\n  for (const t of project.tracks) {\n    if (t.kind !== \"video\") continue;\n    for (const c of t.clips) {\n      const end = c.start + (c.out - c.in);\n      if (end > c.start) intervals.push([c.start, end]);\n    }\n  }\n  if (intervals.length === 0) return [];\n  intervals.sort((a, b) => a[0] - b[0]);\n  const merged: Array<[Ms, Ms]> = [];\n  for (const [s, e] of intervals) {\n    const last = merged[merged.length - 1];\n    if (last && s <= last[1]) last[1] = Math.max(last[1], e);\n    else merged.push([s, e]);\n  }\n  const gaps: Array<[Ms, Ms]> = [];\n  let cursor = 0;\n  for (const [s, e] of merged) {\n    if (s > cursor) gaps.push([cursor, s]);\n    cursor = e;\n  }\n  // Trailing gap (after last clip) is intentionally NOT reported —\n  // that's \"the end of the timeline\", not a coverage hole.\n  return gaps;\n}\n","import { getEffectiveTransform } from \"../keyframes/index.js\";\nimport type { Clip, Ms, Project } from \"../types.js\";\nimport type {\n  PlaybackEngine,\n  PlaybackEngineFactory,\n  PlaybackEngineOptions,\n} from \"./types.js\";\n\n/**\n * Default preview engine — one wrapper + `<video>` pair per\n * `MediaSource`. The wrapper is sized to the OUTPUT frame (the base\n * contain-letterbox rect) with `overflow: hidden` so any keyframe\n * transform applied to the inner video gets clipped to the output\n * bounds. That's what makes pan / zoom / picture-in-picture work:\n * translating the video reveals the wrapper's letterbox color, not\n * the rest of the editor chrome.\n *\n * Multi-track / PiP: when `setPictureInPictureEnabled(true)` flips\n * on, every video track's currently-active clip stays visible, with\n * track `0` on top (highest z-index). Audio policy: only the top\n * track stays unmuted so stacked playbacks don't double-pitch. When\n * the flag is off (default) behaviour matches the historical single-\n * clip preview — only track `0`'s active clip paints.\n *\n * Strengths: zero deps, browser-native decode (GPU when available),\n * works in every browser today.\n *\n * Limits: a clip dropped on two tracks that share the same\n * `MediaSource.id` will only one currentTime at a time (one decoder\n * per source) — the second one wins. Workaround: upload the file\n * twice for separate ids. Seek snaps to keyframes (browser controls\n * the decode pipeline), no transitions / shaders / filters. See\n * `WebCodecsEngine` for the frame-accurate path.\n */\ninterface SourceState {\n  /** Clipping container — positioned + sized to the OUTPUT frame each\n   *  frame so any video transform clips against the output bounds. */\n  wrapper: HTMLDivElement;\n  video: HTMLVideoElement;\n}\n\nexport class HtmlVideoEngine implements PlaybackEngine {\n  private host: HTMLElement;\n  private mount: HTMLDivElement;\n  private sources = new Map<string, SourceState>();\n  private project: Project;\n  /** trackId → currently-active clipId on that track. PiP off keeps\n   *  only the first entry; PiP on holds one per video track. */\n  private activeByTrack = new Map<string, string>();\n  private playing = false;\n  private timeMs: Ms = 0;\n  private rafHandle: number | null = null;\n  private lastFrameTs = 0;\n  /** Permanent rAF that positions the active wrappers at the output\n   *  rect + pushes keyframe transforms onto the inner videos via CSS. */\n  private transformRaf: number | null = null;\n  private pictureInPictureEnabled = false;\n\n  /** Public event hooks — set by Editor. */\n  onTimeUpdate?: (ms: Ms) => void;\n  onEnded?: () => void;\n  onError?: (err: Error) => void;\n  onReady?: () => void;\n  onSourceMetadata?: (sourceId: string, durationMs: Ms) => void;\n\n  constructor(opts: PlaybackEngineOptions) {\n    this.host = opts.host;\n    this.project = opts.project;\n    this.mount = document.createElement(\"div\");\n    this.mount.className = \"aicut-preview\";\n    Object.assign(this.mount.style, {\n      position: \"absolute\",\n      inset: \"0\",\n      width: \"100%\",\n      height: \"100%\",\n    } satisfies Partial<CSSStyleDeclaration>);\n    this.host.appendChild(this.mount);\n    this.syncSources();\n    this.startTransformLoop();\n  }\n\n  setProject(next: Project): void {\n    this.project = next;\n    this.syncSources();\n    this.refreshActive();\n  }\n\n  setPictureInPictureEnabled(enabled: boolean): void {\n    if (this.pictureInPictureEnabled === enabled) return;\n    this.pictureInPictureEnabled = enabled;\n    // Re-resolve active clips with the new policy. Wrappers that\n    // were visible for non-primary tracks get hidden; new tracks may\n    // come online.\n    this.refreshActive();\n  }\n\n  play(): void {\n    if (this.playing) return;\n    if (this.totalDuration() <= 0) return;\n    // If no clip currently overlaps the playhead, snap forward to the\n    // next clip's start so the user gets immediate playback.\n    if (this.activeByTrack.size === 0) {\n      const next = this.nextClipAfterTime(this.timeMs);\n      if (!next) return;\n      this.timeMs = next.start;\n      this.refreshActive();\n    }\n    this.playAllActive();\n    this.playing = true;\n    this.startTickLoop();\n  }\n\n  pause(): void {\n    if (!this.playing) return;\n    this.playing = false;\n    this.stopTickLoop();\n    this.pauseAllActive();\n  }\n\n  isPlaying(): boolean {\n    return this.playing;\n  }\n\n  getTime(): Ms {\n    return this.timeMs;\n  }\n\n  seek(timeMs: Ms): void {\n    const total = this.totalDuration();\n    if (total <= 0) {\n      this.timeMs = 0;\n      return;\n    }\n    const clamped = Math.max(0, Math.min(timeMs, total));\n    this.timeMs = clamped;\n    this.refreshActive();\n    this.onTimeUpdate?.(clamped);\n  }\n\n  /**\n   * The OUTPUT frame — the fixed stage the rendered video is clipped\n   * to. Independent of the keyframe transform. Used by the overlay to\n   * draw the dashed border at a stable position.\n   */\n  getOutputFrameRect(\n    _clipId?: string,\n  ): { x: number; y: number; w: number; h: number } | null {\n    // Output canvas is shared across all clips on the same paint —\n    // `_clipId` is for API symmetry with `getFrameRect`.\n    return this.baseFrameRect();\n  }\n\n  /**\n   * The CONTENT frame — where the transformed video pixels actually\n   * land. Equal to the output frame when transform is identity; may\n   * extend outside (zoom in) or fit inside (zoom out) when not.\n   *\n   * `clipId` (PiP): the overlay passes the selected clip so the\n   * dashed border + corner handles latch onto a picture-in-picture\n   * overlay instead of always tracking the primary. When omitted,\n   * defaults to the primary (= bottom track) clip.\n   */\n  getFrameRect(\n    clipId?: string,\n  ): { x: number; y: number; w: number; h: number } | null {\n    const base = this.baseFrameRect();\n    if (!base) return null;\n    let clip: Clip | null = null;\n    if (clipId) {\n      // Only honor the request when the clip is currently active\n      // (selecting a non-active clip falls back to the primary so\n      // the overlay doesn't ghost over an empty wrapper).\n      for (const cId of this.activeByTrack.values()) {\n        if (cId === clipId) {\n          clip = this.clipById(cId);\n          break;\n        }\n      }\n    }\n    if (!clip) clip = this.primaryActiveClip();\n    if (!clip) return base;\n    const t = getEffectiveTransform(clip, this.timeMs - clip.start);\n    // panX/panY are CANVAS pixels — convert to CSS px via the same\n    // canvas-to-CSS ratio that sized `base.w`/`base.h`.\n    const ref = this.canvasReferenceDims();\n    const cssPerCanvasX = ref ? base.w / ref[0] : 1;\n    const cssPerCanvasY = ref ? base.h / ref[1] : 1;\n    const cx = base.x + base.w / 2 + t.panX * cssPerCanvasX;\n    const cy = base.y + base.h / 2 + t.panY * cssPerCanvasY;\n    const w = base.w * t.scale;\n    const h = base.h * t.scale;\n    return { x: cx - w / 2, y: cy - h / 2, w, h };\n  }\n\n  /**\n   * Untransformed output-canvas rect.\n   *\n   * Source of truth: `Project.aspect` when the user picked a ratio\n   * via the built-in picker. When it's null we fall back to a\n   * STABLE reference — the first clip in the first video track,\n   * regardless of playhead — so the canvas stays anchored as\n   * playback crosses clip boundaries. Picks up the active primary\n   * clip's dims as a last resort when the reference video hasn't\n   * loaded metadata yet.\n   *\n   * Mirrors CapCut: \"Original\" means \"lock to the first clip's\n   * aspect\", not \"follow whatever's playing right now\". Without\n   * this, the canvas would visibly jump every time the playhead\n   * crossed from track-0's clip 1 to clip 2.\n   */\n  private baseFrameRect():\n    | { x: number; y: number; w: number; h: number }\n    | null {\n    const hostRect = this.host.getBoundingClientRect();\n    const cw = hostRect.width;\n    const ch = hostRect.height;\n    if (cw === 0 || ch === 0) return null;\n\n    let aw: number | null = null;\n    let ah: number | null = null;\n    const aspect = parseAspect(this.project.aspect);\n    if (aspect) {\n      [aw, ah] = aspect;\n    } else {\n      const ref = this.canvasReferenceDims();\n      if (ref) [aw, ah] = ref;\n    }\n    if (aw == null || ah == null) {\n      // Last resort — use whatever clip is currently primary so we\n      // still produce a rect during the brief window before any\n      // metadata has resolved.\n      const clip = this.primaryActiveClip();\n      if (!clip) return null;\n      const v = this.sources.get(clip.sourceId)?.video;\n      if (!v || v.videoWidth === 0 || v.videoHeight === 0) return null;\n      aw = v.videoWidth;\n      ah = v.videoHeight;\n    }\n    const scale = Math.min(cw / aw, ch / ah);\n    const w = aw * scale;\n    const h = ah * scale;\n    return { x: (cw - w) / 2, y: (ch - h) / 2, w, h };\n  }\n\n  /**\n   * Dims of the canvas-anchor clip — the first clip (by start time)\n   * on the first video track. Stable across playback so the canvas\n   * doesn't resize at clip boundaries. Returns null when nothing's\n   * decoded yet.\n   */\n  getCanvasReferenceDims(): [number, number] | null {\n    const out = this.project.output;\n    if (out && out.width > 0 && out.height > 0) return [out.width, out.height];\n    for (const track of this.project.tracks) {\n      if (track.kind !== \"video\") continue;\n      let earliest: { c: { sourceId: string; start: number } } | null = null;\n      for (const c of track.clips) {\n        if (!earliest || c.start < earliest.c.start) earliest = { c };\n      }\n      if (!earliest) continue;\n      const v = this.sources.get(earliest.c.sourceId)?.video;\n      if (!v || v.videoWidth === 0 || v.videoHeight === 0) continue;\n      return [v.videoWidth, v.videoHeight];\n    }\n    return null;\n  }\n  private canvasReferenceDims(): [number, number] | null {\n    return this.getCanvasReferenceDims();\n  }\n\n  /**\n   * Permanent rAF that (a) sizes + positions every active wrapper to\n   * the output frame, and (b) writes the keyframe transform onto each\n   * inner video. Negligible cost — a handful of style writes per\n   * frame even with PiP on.\n   */\n  private startTransformLoop(): void {\n    const tick = (): void => {\n      this.applyTransforms();\n      this.transformRaf = requestAnimationFrame(tick);\n    };\n    this.transformRaf = requestAnimationFrame(tick);\n  }\n\n  private applyTransforms(): void {\n    const outRect = this.baseFrameRect();\n    if (!outRect) {\n      // No primary clip → no positioning to do; visibility was already\n      // toggled in `refreshActive`.\n      return;\n    }\n    // Build a sourceId → (trackIndex, clip) map for the active set so\n    // we know which wrapper to z-order and animate.\n    const activeBySource = new Map<\n      string,\n      { trackIndex: number; clip: Clip }\n    >();\n    let i = 0;\n    for (const track of this.project.tracks) {\n      if (track.kind !== \"video\") {\n        i++;\n        continue;\n      }\n      const clipId = this.activeByTrack.get(track.id);\n      if (clipId) {\n        const clip = track.clips.find((c) => c.id === clipId);\n        if (clip) activeBySource.set(clip.sourceId, { trackIndex: i, clip });\n      }\n      i++;\n    }\n\n    for (const [sourceId, src] of this.sources) {\n      const entry = activeBySource.get(sourceId);\n      if (entry) {\n        const { trackIndex, clip } = entry;\n        // Wrapper covers the full output canvas; overflow: hidden\n        // clips any transform-overflow at the output bounds.\n        // Z-order convention: higher track index = higher z. That's\n        // the Premiere / After Effects model and what users expect\n        // when they upload PiP overlays onto track 1 / 2 / etc.\n        Object.assign(src.wrapper.style, {\n          left: `${outRect.x}px`,\n          top: `${outRect.y}px`,\n          width: `${outRect.w}px`,\n          height: `${outRect.h}px`,\n          zIndex: String(trackIndex + 1),\n        });\n        const t = getEffectiveTransform(clip, this.timeMs - clip.start);\n        // panX/panY are CANVAS pixels — convert to CSS px via the\n        // wrapper's `outRect.w/h` vs the canvas reference dims so a\n        // 1 px pan in canvas-units shows the same relative motion as\n        // the canvas-compositor + the backend export.\n        const ref = this.canvasReferenceDims();\n        const cssPerCanvasX = ref ? outRect.w / ref[0] : 1;\n        const cssPerCanvasY = ref ? outRect.h / ref[1] : 1;\n        const cssPanX = t.panX * cssPerCanvasX;\n        const cssPanY = t.panY * cssPerCanvasY;\n        src.video.style.transform = `translate(${cssPanX.toFixed(2)}px, ${cssPanY.toFixed(2)}px) scale(${t.scale.toFixed(4)})`;\n      } else if (src.video.style.transform) {\n        // Inactive — reset transform so stale state doesn't ghost when\n        // we swap back.\n        src.video.style.transform = \"\";\n      }\n    }\n  }\n\n  destroy(): void {\n    this.stopTickLoop();\n    if (this.transformRaf != null) {\n      cancelAnimationFrame(this.transformRaf);\n      this.transformRaf = null;\n    }\n    for (const s of this.sources.values()) {\n      s.video.pause();\n      s.video.removeAttribute(\"src\");\n      s.video.load();\n      s.wrapper.remove();\n    }\n    this.sources.clear();\n    this.mount.remove();\n  }\n\n  // --- internals -------------------------------------------------------\n\n  private syncSources(): void {\n    const wanted = new Set(this.project.sources.map((s) => s.id));\n    for (const [id, s] of this.sources) {\n      if (!wanted.has(id)) {\n        s.video.pause();\n        s.wrapper.remove();\n        this.sources.delete(id);\n      }\n    }\n    for (const src of this.project.sources) {\n      if (src.kind !== \"video\") continue;\n      if (this.sources.has(src.id)) continue;\n      const wrapper = document.createElement(\"div\");\n      wrapper.className = \"aicut-preview-clip\";\n      Object.assign(wrapper.style, {\n        position: \"absolute\",\n        overflow: \"hidden\",\n        visibility: \"hidden\",\n        // Initial bounds — applyTransforms overrides each frame.\n        left: \"0\",\n        top: \"0\",\n        width: \"0\",\n        height: \"0\",\n      } satisfies Partial<CSSStyleDeclaration>);\n\n      const v = document.createElement(\"video\");\n      v.preload = \"auto\";\n      // No `crossOrigin` — would force CORS preflight that most CDNs\n      // don't serve. Pure <video> playback works cross-origin without.\n      v.playsInline = true;\n      v.muted = false;\n      v.src = src.url;\n      Object.assign(v.style, {\n        position: \"absolute\",\n        inset: \"0\",\n        width: \"100%\",\n        height: \"100%\",\n        // contain (not fill) so the video letterboxes inside the\n        // output canvas when the canvas aspect (driven by\n        // `Project.aspect`) differs from the video's intrinsic aspect.\n        // When they match (Original / matching ratio), contain\n        // produces the same pixel-perfect result as fill.\n        objectFit: \"contain\",\n        // Transform origin at center so scale() scales around the\n        // video's centroid, not its top-left corner.\n        transformOrigin: \"50% 50%\",\n      } satisfies Partial<CSSStyleDeclaration>);\n      const sourceId = src.id;\n      v.addEventListener(\"error\", () =>\n        this.onError?.(new Error(`Failed to load ${src.url}`)),\n      );\n      v.addEventListener(\"loadedmetadata\", () => {\n        this.onReady?.();\n        const durMs = Math.round(v.duration * 1000);\n        if (Number.isFinite(durMs) && durMs > 0) {\n          this.onSourceMetadata?.(sourceId, durMs);\n        }\n      });\n      wrapper.appendChild(v);\n      this.mount.appendChild(wrapper);\n      this.sources.set(src.id, { wrapper, video: v });\n    }\n  }\n\n  /**\n   * Resolve the active clip per track for the current playhead and\n   * reconcile wrapper visibility, audio policy, and per-source\n   * playback state. Called on `seek` / `setProject` / `setPiP` and\n   * whenever a tick advances past a clip boundary.\n   */\n  private refreshActive(): void {\n    const next = this.computeActiveClips();\n    const prev = this.activeByTrack;\n    this.activeByTrack = next;\n\n    // Figure out which sources need to be visible after the swap and\n    // which need to be hidden / paused.\n    const visibleSources = new Set<string>();\n    for (const clipId of next.values()) {\n      const clip = this.clipById(clipId);\n      if (clip) visibleSources.add(clip.sourceId);\n    }\n\n    // Hide + pause sources that lost activation.\n    for (const [sourceId, src] of this.sources) {\n      if (visibleSources.has(sourceId)) continue;\n      if (src.wrapper.style.visibility !== \"hidden\") {\n        src.wrapper.style.visibility = \"hidden\";\n      }\n      if (!src.video.paused) src.video.pause();\n    }\n\n    // For each newly-active clip, seek the underlying video and play\n    // (if the engine is in playing state). Iterate in track order so\n    // the primary (track 0) clip is the LAST one seeked — same-source\n    // tie-break: primary wins the currentTime.\n    const orderedEntries: Array<[string, string]> = [];\n    for (let i = this.project.tracks.length - 1; i >= 0; i--) {\n      const tid = this.project.tracks[i]!.id;\n      const cid = next.get(tid);\n      if (cid) orderedEntries.push([tid, cid]);\n    }\n    // Track 0 last so its seek/play wins for same-source ties.\n    for (const [, clipId] of orderedEntries) {\n      const clip = this.clipById(clipId);\n      if (!clip) continue;\n      const src = this.sources.get(clip.sourceId);\n      if (!src) continue;\n      src.wrapper.style.visibility = \"visible\";\n      this.seekVideoToClipOffset(clip, this.timeMs - clip.start);\n      if (this.playing) {\n        void src.video.play().catch((err) => this.onError?.(err as Error));\n      }\n    }\n\n    // Audio policy: only the FIRST (top, track 0) active video stays\n    // unmuted; lower-track sources mute to avoid stacking playback.\n    // When PiP is off there's only one active source anyway, so this\n    // is a no-op there.\n    const primaryClip = this.primaryActiveClip();\n    const primarySourceId = primaryClip?.sourceId ?? null;\n    for (const [sourceId, src] of this.sources) {\n      src.video.muted = sourceId !== primarySourceId;\n    }\n\n    // Surface a \"selection-equivalent\" ready event (Editor wires this\n    // into UI updates) so anything keying off `activeClipChanged`\n    // gets a chance to re-render. The old code only fired this when\n    // the SINGLE current clip swapped; we fire it whenever the primary\n    // changes.\n    void prev; // reserved if we ever need a diff\n  }\n\n  private computeActiveClips(): Map<string, string> {\n    const result = new Map<string, string>();\n    for (const track of this.project.tracks) {\n      if (track.kind !== \"video\") continue;\n      for (const c of track.clips) {\n        if (\n          this.timeMs >= c.start &&\n          this.timeMs < c.start + (c.out - c.in)\n        ) {\n          result.set(track.id, c.id);\n          break;\n        }\n      }\n      // PiP off: stop AFTER we've found one active clip — but keep\n      // walking if the first track was empty so the user still sees\n      // a lower-track clip even with PiP disabled.\n      if (!this.pictureInPictureEnabled && result.size > 0) break;\n    }\n    return result;\n  }\n\n  /** First track-in-order with an active clip — the \"primary\" =\n   *  canvas reference + audio source. Track `0` wins when it has\n   *  content; otherwise the next video track with a clip. */\n  private primaryActiveClip(): Clip | null {\n    for (const track of this.project.tracks) {\n      if (track.kind !== \"video\") continue;\n      const cid = this.activeByTrack.get(track.id);\n      if (cid) return this.clipById(cid);\n    }\n    return null;\n  }\n\n  private playAllActive(): void {\n    for (const clipId of this.activeByTrack.values()) {\n      const clip = this.clipById(clipId);\n      if (!clip) continue;\n      const src = this.sources.get(clip.sourceId);\n      if (!src) continue;\n      void src.video.play().catch((err) => this.onError?.(err as Error));\n    }\n  }\n\n  private pauseAllActive(): void {\n    for (const clipId of this.activeByTrack.values()) {\n      const clip = this.clipById(clipId);\n      if (!clip) continue;\n      const src = this.sources.get(clip.sourceId);\n      if (src && !src.video.paused) src.video.pause();\n    }\n  }\n\n  private seekVideoToClipOffset(clip: Clip, offsetMs: Ms): void {\n    const s = this.sources.get(clip.sourceId);\n    if (!s) return;\n    const target = (clip.in + Math.max(0, offsetMs)) / 1000;\n    if (Math.abs(s.video.currentTime - target) > 0.05) {\n      s.video.currentTime = target;\n    }\n  }\n\n  private clipById(id: string): Clip | null {\n    for (const t of this.project.tracks) {\n      for (const c of t.clips) if (c.id === id) return c;\n    }\n    return null;\n  }\n\n  /** Earliest clip starting at-or-after `timeMs` across all video tracks. */\n  private nextClipAfterTime(timeMs: Ms): Clip | null {\n    let best: Clip | null = null;\n    for (const t of this.project.tracks) {\n      if (t.kind !== \"video\") continue;\n      for (const c of t.clips) {\n        if (c.start >= timeMs && (!best || c.start < best.start)) best = c;\n      }\n    }\n    return best;\n  }\n\n  /** Max clip end across all video tracks. */\n  private totalDuration(): Ms {\n    let max = 0;\n    for (const t of this.project.tracks) {\n      if (t.kind !== \"video\") continue;\n      for (const c of t.clips) {\n        const e = c.start + (c.out - c.in);\n        if (e > max) max = e;\n      }\n    }\n    return max;\n  }\n\n  private startTickLoop(): void {\n    this.lastFrameTs = performance.now();\n    const tick = (now: number) => {\n      if (!this.playing) return;\n      const dtMs = now - this.lastFrameTs;\n      this.lastFrameTs = now;\n      this.advance(dtMs);\n      this.rafHandle = requestAnimationFrame(tick);\n    };\n    this.rafHandle = requestAnimationFrame(tick);\n  }\n\n  private stopTickLoop(): void {\n    if (this.rafHandle != null) {\n      cancelAnimationFrame(this.rafHandle);\n      this.rafHandle = null;\n    }\n  }\n\n  private advance(dtMs: number): void {\n    if (this.project.tracks.length === 0) return;\n    this.timeMs += dtMs;\n    const totalDur = this.totalDuration();\n    if (this.timeMs >= totalDur) {\n      this.timeMs = totalDur;\n      this.onTimeUpdate?.(this.timeMs);\n      this.pause();\n      this.onEnded?.();\n      return;\n    }\n    // Detect whether the active clip set changed across this tick —\n    // if so, re-resolve + seek/play any new entrants. We compare by\n    // length AND by entries since a track could swap clips mid-tick.\n    const next = this.computeActiveClips();\n    let changed = next.size !== this.activeByTrack.size;\n    if (!changed) {\n      for (const [tid, cid] of next) {\n        if (this.activeByTrack.get(tid) !== cid) {\n          changed = true;\n          break;\n        }\n      }\n    }\n    if (changed) {\n      this.refreshActive();\n    }\n    // If there's no primary clip after re-resolution, the project has\n    // run out of footage — bail.\n    if (this.activeByTrack.size === 0) {\n      const nextStart = this.nextClipAfterTime(this.timeMs);\n      if (nextStart) {\n        this.timeMs = nextStart.start;\n        this.refreshActive();\n      } else {\n        this.pause();\n        this.onEnded?.();\n        return;\n      }\n    }\n    this.onTimeUpdate?.(this.timeMs);\n  }\n}\n\n/** Factory shorthand for `Editor.create({ playbackEngine })`. */\nexport const htmlVideoEngineFactory: PlaybackEngineFactory = (opts) =>\n  new HtmlVideoEngine(opts);\n\n/**\n * Parse a `Project.aspect` string like \"16:9\" into a `[w, h]` tuple.\n * Returns null for missing / malformed input so callers can fall\n * back to the source video's intrinsic aspect (today's behaviour).\n */\nfunction parseAspect(value: string | undefined | null): [number, number] | null {\n  if (!value) return null;\n  const m = value.match(/^\\s*(\\d+(?:\\.\\d+)?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*$/);\n  if (!m) return null;\n  const w = Number(m[1]);\n  const h = Number(m[2]);\n  if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) {\n    return null;\n  }\n  return [w, h];\n}\n","import { getEffectiveTransform } from \"../keyframes/index.js\";\nimport type { Clip, Ms, Project } from \"../types.js\";\nimport type {\n  PlaybackEngine,\n  PlaybackEngineFactory,\n  PlaybackEngineOptions,\n} from \"./types.js\";\n\nexport interface CanvasCompositorEngineOptions extends PlaybackEngineOptions {\n  /**\n   * Show the corner HUD (\"engine: canvas compositor • t=… • frames\n   * painted: …\"). Off by default — production hosts get a clean canvas\n   * with no chrome painted on top. Turn on in development / demos to\n   * see who's drawing and what the current state is.\n   */\n  debug?: boolean;\n}\n\n/**\n * Reference second engine — demonstrates that the `PlaybackEngine`\n * surface really is engine-agnostic. Same `<video>`-based decode as\n * `HtmlVideoEngine` (so it works in every browser, no WebCodecs gate),\n * but rendering happens via `ctx.drawImage(video, …)` on a single\n * canvas instead of the browser painting the video element itself.\n *\n * Why ship it: it's tangible proof that a host can swap the rendering\n * surface for compositing / shaders / overlays / capture-to-canvas\n * without touching Editor internals. It's also the natural stepping\n * stone toward a WebGL or WebCodecs path (those replace the decoder\n * but keep the canvas-blit pattern).\n *\n * Multi-track / PiP: `setPictureInPictureEnabled(true)` flips the\n * paint loop into multi-clip composite mode — every video track's\n * currently-active clip draws in reverse track order so track 0 ends\n * up on top. Audio: track 0 stays unmuted, lower tracks mute.\n *\n * Limits: same-source same-time tie still goes to a single decoder\n * (one `<video>` per source). Seek snaps to the browser's keyframe\n * pipeline. No transitions / shaders / filters — the canvas blit\n * pattern is the foundation those would build on, not the feature.\n */\nexport class CanvasCompositorEngine implements PlaybackEngine {\n  private host: HTMLElement;\n  private mount: HTMLDivElement;\n  private canvas: HTMLCanvasElement;\n  private ctx: CanvasRenderingContext2D;\n  /** Only created when constructed with `debug: true`. */\n  private badge: HTMLDivElement | null = null;\n  private videos = new Map<string, HTMLVideoElement>();\n  private project: Project;\n  /** trackId → active clipId on that track. Top track's clip is the\n   *  \"primary\" — drives output canvas + audio + overlay rects. */\n  private activeByTrack = new Map<string, string>();\n  private playing = false;\n  private timeMs: Ms = 0;\n  private rafHandle: number | null = null;\n  private lastFrameTs = 0;\n  private paintedFrames = 0;\n  private pictureInPictureEnabled = false;\n  /** Output canvas rect (no transform) — same for every clip on\n   *  the same paint pass. */\n  private lastOutputRect: {\n    x: number;\n    y: number;\n    w: number;\n    h: number;\n  } | null = null;\n  /** Post-transform content rect, keyed by clipId. With PiP on a\n   *  paint pass records one entry per painted clip; the overlay can\n   *  ask for any specific one (the SELECTED clip when PiP is on,\n   *  the primary clip otherwise). */\n  private frameRectsByClip = new Map<\n    string,\n    { x: number; y: number; w: number; h: number }\n  >();\n  /** Primary (top-track) clip id from the last paint — used as the\n   *  fallback for `getFrameRect()` when no clipId is passed. */\n  private primaryClipIdLastPaint: string | null = null;\n\n  onTimeUpdate?: (ms: Ms) => void;\n  onEnded?: () => void;\n  onError?: (err: Error) => void;\n  onReady?: () => void;\n  onSourceMetadata?: (sourceId: string, durationMs: Ms) => void;\n\n  constructor(opts: CanvasCompositorEngineOptions) {\n    this.host = opts.host;\n    this.project = opts.project;\n\n    this.mount = document.createElement(\"div\");\n    this.mount.className = \"aicut-preview aicut-preview--canvas\";\n    Object.assign(this.mount.style, {\n      position: \"absolute\",\n      inset: \"0\",\n      width: \"100%\",\n      height: \"100%\",\n    } satisfies Partial<CSSStyleDeclaration>);\n\n    this.canvas = document.createElement(\"canvas\");\n    Object.assign(this.canvas.style, {\n      position: \"absolute\",\n      inset: \"0\",\n      width: \"100%\",\n      height: \"100%\",\n      // Stretch with letterboxing handled by the draw loop.\n      objectFit: \"contain\",\n      // Same var the preview-host + demo slots use, so a light-theme\n      // host doesn't end up with a hard black plate around a\n      // letterboxed frame while the surrounding chrome is off-white.\n      // Falls back to black to preserve today's default when no theme\n      // sets the var.\n      background: \"var(--aicut-preview-bg, #000)\",\n    } satisfies Partial<CSSStyleDeclaration>);\n    this.mount.appendChild(this.canvas);\n\n    const ctx = this.canvas.getContext(\"2d\");\n    if (!ctx) throw new Error(\"CanvasCompositorEngine: 2d context unavailable\");\n    this.ctx = ctx;\n\n    if (opts.debug) {\n      const badge = document.createElement(\"div\");\n      badge.className = \"aicut-preview__badge\";\n      Object.assign(badge.style, {\n        position: \"absolute\",\n        top: \"8px\",\n        left: \"8px\",\n        padding: \"4px 8px\",\n        borderRadius: \"6px\",\n        background: \"rgba(0, 0, 0, 0.55)\",\n        color: \"rgba(255, 255, 255, 0.92)\",\n        font: \"11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace\",\n        pointerEvents: \"none\",\n        zIndex: \"2\",\n        letterSpacing: \"0.02em\",\n      } satisfies Partial<CSSStyleDeclaration>);\n      badge.textContent = \"engine: canvas compositor\";\n      this.mount.appendChild(badge);\n      this.badge = badge;\n    }\n\n    this.host.appendChild(this.mount);\n    this.syncSources();\n    this.resizeCanvas();\n    this.startTickLoop(); // always painting so HUD reflects state when paused\n  }\n\n  setProject(next: Project): void {\n    this.project = next;\n    this.syncSources();\n    this.refreshActive();\n  }\n\n  setPictureInPictureEnabled(enabled: boolean): void {\n    if (this.pictureInPictureEnabled === enabled) return;\n    this.pictureInPictureEnabled = enabled;\n    this.refreshActive();\n  }\n\n  play(): void {\n    if (this.playing) return;\n    if (this.totalDuration() <= 0) return;\n    if (this.activeByTrack.size === 0) {\n      const next = this.nextClipAfterTime(this.timeMs);\n      if (!next) return;\n      this.timeMs = next.start;\n      this.refreshActive();\n    }\n    this.playAllActive();\n    this.playing = true;\n    this.lastFrameTs = performance.now();\n  }\n\n  pause(): void {\n    if (!this.playing) return;\n    this.playing = false;\n    this.pauseAllActive();\n  }\n\n  isPlaying(): boolean {\n    return this.playing;\n  }\n\n  getTime(): Ms {\n    return this.timeMs;\n  }\n\n  seek(timeMs: Ms): void {\n    const total = this.totalDuration();\n    if (total <= 0) {\n      this.timeMs = 0;\n      return;\n    }\n    const clamped = Math.max(0, Math.min(timeMs, total));\n    this.timeMs = clamped;\n    this.refreshActive();\n    this.onTimeUpdate?.(clamped);\n  }\n\n  destroy(): void {\n    this.stopTickLoop();\n    for (const v of this.videos.values()) {\n      v.pause();\n      v.removeAttribute(\"src\");\n      v.load();\n    }\n    this.videos.clear();\n    this.mount.remove();\n  }\n\n  // --- internals -------------------------------------------------------\n\n  private syncSources(): void {\n    const wanted = new Set(this.project.sources.map((s) => s.id));\n    for (const [id, v] of this.videos) {\n      if (!wanted.has(id)) {\n        v.pause();\n        this.videos.delete(id);\n      }\n    }\n    for (const src of this.project.sources) {\n      if (src.kind !== \"video\") continue;\n      if (this.videos.has(src.id)) continue;\n      const v = document.createElement(\"video\");\n      v.preload = \"auto\";\n      v.playsInline = true;\n      v.muted = false;\n      v.src = src.url;\n      // Detached from the DOM — videos decode fine when not mounted,\n      // they just need a current `src` and `play()` called on them.\n      // Keeping them off-tree avoids any chance of the raw <video>\n      // showing through the canvas (which would defeat the demo).\n      const sourceId = src.id;\n      v.addEventListener(\"error\", () =>\n        this.onError?.(new Error(`Failed to load ${src.url}`)),\n      );\n      v.addEventListener(\"loadedmetadata\", () => {\n        this.onReady?.();\n        const durMs = Math.round(v.duration * 1000);\n        if (Number.isFinite(durMs) && durMs > 0) {\n          this.onSourceMetadata?.(sourceId, durMs);\n        }\n      });\n      this.videos.set(src.id, v);\n    }\n  }\n\n  /**\n   * Resolve the active clip per track for the current playhead and\n   * reconcile per-source playback / audio policy. PiP off = only the\n   * top track contributes; PiP on = every video track.\n   */\n  private refreshActive(): void {\n    const next = this.computeActiveClips();\n    this.activeByTrack = next;\n\n    const visibleSources = new Set<string>();\n    for (const clipId of next.values()) {\n      const clip = this.clipById(clipId);\n      if (clip) visibleSources.add(clip.sourceId);\n    }\n\n    // Pause sources that lost activation.\n    for (const [sourceId, v] of this.videos) {\n      if (visibleSources.has(sourceId)) continue;\n      if (!v.paused) v.pause();\n    }\n\n    // Seek (+ play if running) every newly-active source. Iterate\n    // bottom-up so track 0 ends up last — same-source tie wins for\n    // the primary clip's currentTime.\n    for (let i = this.project.tracks.length - 1; i >= 0; i--) {\n      const tid = this.project.tracks[i]!.id;\n      const cid = next.get(tid);\n      if (!cid) continue;\n      const clip = this.clipById(cid);\n      if (!clip) continue;\n      this.seekVideoToClipOffset(clip, this.timeMs - clip.start);\n      if (this.playing) {\n        const v = this.videos.get(clip.sourceId);\n        if (v) void v.play().catch((err) => this.onError?.(err as Error));\n      }\n    }\n\n    // Audio policy: only the top track's source unmuted.\n    const primaryClip = this.primaryActiveClip();\n    const primarySourceId = primaryClip?.sourceId ?? null;\n    for (const [sourceId, v] of this.videos) {\n      v.muted = sourceId !== primarySourceId;\n    }\n  }\n\n  private computeActiveClips(): Map<string, string> {\n    const result = new Map<string, string>();\n    for (const track of this.project.tracks) {\n      if (track.kind !== \"video\") continue;\n      for (const c of track.clips) {\n        if (\n          this.timeMs >= c.start &&\n          this.timeMs < c.start + (c.out - c.in)\n        ) {\n          result.set(track.id, c.id);\n          break;\n        }\n      }\n      // PiP off: stop AFTER we've found one active clip — but keep\n      // walking if the first track was empty so the user still sees\n      // a lower-track clip even with PiP disabled. Without this, a\n      // gap on track 0 would black the preview while track 1 had\n      // content.\n      if (!this.pictureInPictureEnabled && result.size > 0) break;\n    }\n    return result;\n  }\n\n  /**\n   * The \"primary\" clip = the bottom-most active clip = the main\n   * canvas reference + audio source. It's track `0` when track `0`\n   * has content; if that track is empty at the playhead, fall\n   * through to the next video track with a clip. (Without that\n   * fall-through, dragging the only track-0 clip out of the\n   * playhead range blanked the preview even though a lower-track\n   * clip was still active.)\n   */\n  /**\n   * Dims of the canvas-anchor clip — the first clip (by start time)\n   * on the first video track. Stable across playback so the canvas\n   * doesn't resize at clip boundaries. Returns null when nothing's\n   * decoded yet.\n   */\n  getCanvasReferenceDims(): [number, number] | null {\n    // `Project.output` is the authoritative reference frame when set.\n    // Falls through to the anchor-clip dims so legacy projects with\n    // neither aspect nor output still resolve to a stable canvas.\n    const out = this.project.output;\n    if (out && out.width > 0 && out.height > 0) return [out.width, out.height];\n    for (const track of this.project.tracks) {\n      if (track.kind !== \"video\") continue;\n      let earliest: { c: { sourceId: string; start: number } } | null = null;\n      for (const c of track.clips) {\n        if (!earliest || c.start < earliest.c.start) earliest = { c };\n      }\n      if (!earliest) continue;\n      const v = this.videos.get(earliest.c.sourceId);\n      if (!v || v.videoWidth === 0 || v.videoHeight === 0) continue;\n      return [v.videoWidth, v.videoHeight];\n    }\n    return null;\n  }\n  private canvasReferenceDims(): [number, number] | null {\n    return this.getCanvasReferenceDims();\n  }\n\n  private primaryActiveClip(): Clip | null {\n    for (const track of this.project.tracks) {\n      if (track.kind !== \"video\") continue;\n      const cid = this.activeByTrack.get(track.id);\n      if (cid) return this.clipById(cid);\n    }\n    return null;\n  }\n\n  private playAllActive(): void {\n    for (const clipId of this.activeByTrack.values()) {\n      const clip = this.clipById(clipId);\n      if (!clip) continue;\n      const v = this.videos.get(clip.sourceId);\n      if (v) void v.play().catch((err) => this.onError?.(err as Error));\n    }\n  }\n\n  private pauseAllActive(): void {\n    for (const clipId of this.activeByTrack.values()) {\n      const clip = this.clipById(clipId);\n      if (!clip) continue;\n      const v = this.videos.get(clip.sourceId);\n      if (v && !v.paused) v.pause();\n    }\n  }\n\n  private seekVideoToClipOffset(clip: Clip, offsetMs: Ms): void {\n    const v = this.videos.get(clip.sourceId);\n    if (!v) return;\n    const target = (clip.in + Math.max(0, offsetMs)) / 1000;\n    if (Math.abs(v.currentTime - target) > 0.05) {\n      v.currentTime = target;\n    }\n  }\n\n  private clipById(id: string): Clip | null {\n    for (const t of this.project.tracks) {\n      for (const c of t.clips) if (c.id === id) return c;\n    }\n    return null;\n  }\n\n  private clipAtTime(timeMs: Ms): Clip | null {\n    for (const t of this.project.tracks) {\n      if (t.kind !== \"video\") continue;\n      for (const c of t.clips) {\n        if (timeMs >= c.start && timeMs < c.start + (c.out - c.in)) return c;\n      }\n    }\n    return null;\n  }\n\n  private nextClipAfterTime(timeMs: Ms): Clip | null {\n    let best: Clip | null = null;\n    for (const t of this.project.tracks) {\n      if (t.kind !== \"video\") continue;\n      for (const c of t.clips) {\n        if (c.start >= timeMs && (!best || c.start < best.start)) best = c;\n      }\n    }\n    return best;\n  }\n\n  private totalDuration(): Ms {\n    let max = 0;\n    for (const t of this.project.tracks) {\n      if (t.kind !== \"video\") continue;\n      for (const c of t.clips) {\n        const e = c.start + (c.out - c.in);\n        if (e > max) max = e;\n      }\n    }\n    return max;\n  }\n\n  private resizeCanvas(): void {\n    const rect = this.mount.getBoundingClientRect();\n    const dpr = window.devicePixelRatio || 1;\n    const w = Math.max(1, Math.floor(rect.width * dpr));\n    const h = Math.max(1, Math.floor(rect.height * dpr));\n    if (this.canvas.width !== w || this.canvas.height !== h) {\n      this.canvas.width = w;\n      this.canvas.height = h;\n    }\n  }\n\n  private startTickLoop(): void {\n    this.lastFrameTs = performance.now();\n    const tick = (now: number): void => {\n      this.resizeCanvas();\n      if (this.playing) {\n        const dtMs = now - this.lastFrameTs;\n        this.lastFrameTs = now;\n        this.advance(dtMs);\n      }\n      this.paint();\n      this.rafHandle = requestAnimationFrame(tick);\n    };\n    this.rafHandle = requestAnimationFrame(tick);\n  }\n\n  private stopTickLoop(): void {\n    if (this.rafHandle != null) {\n      cancelAnimationFrame(this.rafHandle);\n      this.rafHandle = null;\n    }\n  }\n\n  private advance(dtMs: number): void {\n    if (this.project.tracks.length === 0) return;\n    this.timeMs += dtMs;\n    const totalDur = this.totalDuration();\n    if (this.timeMs >= totalDur) {\n      this.timeMs = totalDur;\n      this.onTimeUpdate?.(this.timeMs);\n      this.pause();\n      this.onEnded?.();\n      return;\n    }\n    // Detect clip-set changes across this tick.\n    const next = this.computeActiveClips();\n    let changed = next.size !== this.activeByTrack.size;\n    if (!changed) {\n      for (const [tid, cid] of next) {\n        if (this.activeByTrack.get(tid) !== cid) {\n          changed = true;\n          break;\n        }\n      }\n    }\n    if (changed) this.refreshActive();\n    // Out of footage on every track? Skip ahead to the next clip\n    // start or end playback.\n    if (this.activeByTrack.size === 0) {\n      const nextStart = this.nextClipAfterTime(this.timeMs);\n      if (nextStart) {\n        this.timeMs = nextStart.start;\n        this.refreshActive();\n      } else {\n        this.pause();\n        this.onEnded?.();\n        return;\n      }\n    }\n    this.onTimeUpdate?.(this.timeMs);\n  }\n\n  /**\n   * One paint per rAF — clears the canvas, composites every active\n   * track's clip in reverse track order (so track 0 ends up on top),\n   * then refreshes the HUD. Done unconditionally (not just on\n   * `playing`) so the HUD frame counter and the seek preview both\n   * update when paused.\n   *\n   * Canvas dims (`dw, dh`) are computed once from the PRIMARY clip's\n   * source video — every lower-track clip then letterboxes inside\n   * the same canvas via its own contain-fit math. The output rect +\n   * content rect for the overlay both reflect the primary clip too\n   * (keyframe handles on PiP-overlaid clips are a v2 concern).\n   */\n  private paint(): void {\n    const cw = this.canvas.width;\n    const ch = this.canvas.height;\n    this.ctx.clearRect(0, 0, cw, ch);\n\n    const primaryClip = this.primaryActiveClip();\n    const primaryVideo = primaryClip\n      ? this.videos.get(primaryClip.sourceId)\n      : null;\n    if (\n      !primaryClip ||\n      !primaryVideo ||\n      primaryVideo.videoWidth === 0 ||\n      primaryVideo.videoHeight === 0\n    ) {\n      this.frameRectsByClip.clear();\n      this.lastOutputRect = null;\n      this.primaryClipIdLastPaint = null;\n      this.updateBadge();\n      return;\n    }\n\n    // Canvas dims come from `getCanvasReferenceDims` — which prefers\n    // `project.output` (the authoritative authoring canvas, e.g.\n    // 1080×1920 for a 9:16 project) and falls back to the first clip\n    // on track 0 for legacy projects without `output`. NEVER use\n    // `parseAspect(project.aspect)` here — that returns the bare\n    // ratio numbers (9, 16) which would make `canvasScale = cw/9`\n    // huge, and any pan multiplied by that scale flings the content\n    // out of frame on the first cursor wiggle.\n    let aw: number;\n    let ah: number;\n    const ref = this.canvasReferenceDims();\n    if (ref) {\n      [aw, ah] = ref;\n    } else {\n      aw = primaryVideo.videoWidth;\n      ah = primaryVideo.videoHeight;\n    }\n    const canvasScale = Math.min(cw / aw, ch / ah);\n    const dw = aw * canvasScale;\n    const dh = ah * canvasScale;\n    const dpr = window.devicePixelRatio || 1;\n    const outX = (cw - dw) / 2;\n    const outY = (ch - dh) / 2;\n    const ccx = cw / 2;\n    const ccy = ch / 2;\n\n    // Z-order convention: tracks[0] paints FIRST (bottom) and the\n    // last track paints LAST (top). This matches Premiere / After\n    // Effects — uploads land on the first empty track, so the second\n    // upload (track 1) naturally becomes the PiP overlay sitting on\n    // top of the track-0 background. While painting, also cache each\n    // clip's post-transform content rect so the overlay can latch\n    // onto whichever clip the user selects.\n    this.frameRectsByClip.clear();\n    for (let i = 0; i < this.project.tracks.length; i++) {\n      const track = this.project.tracks[i]!;\n      if (track.kind !== \"video\") continue;\n      const clipId = this.activeByTrack.get(track.id);\n      if (!clipId) continue;\n      const clip = track.clips.find((c) => c.id === clipId);\n      if (!clip) continue;\n      const v = this.videos.get(clip.sourceId);\n      if (!v || v.videoWidth === 0 || v.videoHeight === 0) continue;\n\n      const vw = v.videoWidth;\n      const vh = v.videoHeight;\n      const vidContain = Math.min(dw / vw, dh / vh);\n      const vidW = vw * vidContain;\n      const vidH = vh * vidContain;\n      const t = getEffectiveTransform(clip, this.timeMs - clip.start);\n\n      // pan values are in CANVAS pixels (= units of `aw`/`ah`).\n      // Convert into preview-canvas backbuffer pixels by multiplying\n      // by `canvasScale` — that's the ratio of preview-canvas space\n      // per project-canvas unit.\n      this.ctx.save();\n      this.ctx.beginPath();\n      this.ctx.rect(outX, outY, dw, dh);\n      this.ctx.clip();\n      this.ctx.translate(\n        ccx + t.panX * canvasScale,\n        ccy + t.panY * canvasScale,\n      );\n      this.ctx.scale(t.scale, t.scale);\n      this.ctx.drawImage(v, -vidW / 2, -vidH / 2, vidW, vidH);\n      this.ctx.restore();\n\n      // Cache this clip's content rect in CSS px for the overlay.\n      // CSS-px conversion: backbuffer / dpr; pan in canvas-px → CSS\n      // px = panX * canvasScale / dpr.\n      const cssCx = cw / (2 * dpr) + (t.panX * canvasScale) / dpr;\n      const cssCy = ch / (2 * dpr) + (t.panY * canvasScale) / dpr;\n      const cssW = (vidW * t.scale) / dpr;\n      const cssH = (vidH * t.scale) / dpr;\n      this.frameRectsByClip.set(clip.id, {\n        x: cssCx - cssW / 2,\n        y: cssCy - cssH / 2,\n        w: cssW,\n        h: cssH,\n      });\n    }\n    this.paintedFrames += 1;\n    this.primaryClipIdLastPaint = primaryClip.id;\n\n    this.lastOutputRect = {\n      x: outX / dpr,\n      y: outY / dpr,\n      w: dw / dpr,\n      h: dh / dpr,\n    };\n    this.updateBadge();\n  }\n\n  getOutputFrameRect(\n    _clipId?: string,\n  ): { x: number; y: number; w: number; h: number } | null {\n    // The output canvas is the same for every clip on the same paint\n    // pass, so `_clipId` is just for API symmetry.\n    return this.lastOutputRect;\n  }\n\n  getFrameRect(\n    clipId?: string,\n  ): { x: number; y: number; w: number; h: number } | null {\n    const id = clipId ?? this.primaryClipIdLastPaint;\n    if (id == null) return null;\n    // Compute on demand from the LIVE project state instead of\n    // returning the paint-cache value. Paint runs in its own rAF\n    // tick, so the overlay was reading a frame rect that lagged the\n    // actual project by one tick — which manifested as a brief\n    // \"jump\" of the dashed selection border when a drag updated\n    // scale + panX in the same tick. Recomputing here keeps the\n    // overlay in lockstep with the keyframe model.\n    const live = this.computeFrameRect(id);\n    return live ?? this.frameRectsByClip.get(id) ?? null;\n  }\n\n  /**\n   * Compute a clip's content rect (CSS px in host coords) from the\n   * LIVE project state — no paint cache involvement. Mirrors the\n   * math in `paint()` so visible canvas pixels and overlay handles\n   * agree to within float precision.\n   */\n  private computeFrameRect(\n    clipId: string,\n  ): { x: number; y: number; w: number; h: number } | null {\n    let clip: Clip | null = null;\n    for (const track of this.project.tracks) {\n      const c = track.clips.find((cc) => cc.id === clipId);\n      if (c) {\n        clip = c;\n        break;\n      }\n    }\n    if (!clip) return null;\n    const v = this.videos.get(clip.sourceId);\n    if (!v || v.videoWidth === 0 || v.videoHeight === 0) return null;\n    const cw = this.canvas.width;\n    const ch = this.canvas.height;\n    if (cw === 0 || ch === 0) return null;\n    // Same canonical canvas dims as paint() — see the note there.\n    let aw: number;\n    let ah: number;\n    const ref = this.canvasReferenceDims();\n    if (ref) {\n      [aw, ah] = ref;\n    } else {\n      aw = v.videoWidth;\n      ah = v.videoHeight;\n    }\n    const canvasScale = Math.min(cw / aw, ch / ah);\n    const dw = aw * canvasScale;\n    const dh = ah * canvasScale;\n    const dpr = window.devicePixelRatio || 1;\n    const vidContain = Math.min(dw / v.videoWidth, dh / v.videoHeight);\n    const vidW = v.videoWidth * vidContain;\n    const vidH = v.videoHeight * vidContain;\n    const t = getEffectiveTransform(clip, this.timeMs - clip.start);\n    // panX/panY are in CANVAS pixels — convert to CSS px via\n    // `canvasScale / dpr` to match the paint() math.\n    const cssCx = cw / (2 * dpr) + (t.panX * canvasScale) / dpr;\n    const cssCy = ch / (2 * dpr) + (t.panY * canvasScale) / dpr;\n    const cssW = (vidW * t.scale) / dpr;\n    const cssH = (vidH * t.scale) / dpr;\n    return {\n      x: cssCx - cssW / 2,\n      y: cssCy - cssH / 2,\n      w: cssW,\n      h: cssH,\n    };\n  }\n\n  private updateBadge(): void {\n    if (!this.badge) return;\n    const sec = (this.timeMs / 1000).toFixed(2);\n    this.badge.textContent =\n      `engine: canvas compositor • t=${sec}s • frames painted: ${this.paintedFrames}`;\n  }\n}\n\n/** Factory shorthand for `Editor.create({ playbackEngine })`. */\nexport const canvasCompositorEngineFactory: PlaybackEngineFactory = (opts) =>\n  new CanvasCompositorEngine(opts);\n\n/**\n * Parse a `Project.aspect` string like \"16:9\" into a `[w, h]` tuple.\n * Returns null for missing / malformed input so callers can fall\n * back to the source video's intrinsic aspect.\n */\nfunction parseAspect(value: string | undefined | null): [number, number] | null {\n  if (!value) return null;\n  const m = value.match(/^\\s*(\\d+(?:\\.\\d+)?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*$/);\n  if (!m) return null;\n  const w = Number(m[1]);\n  const h = Number(m[2]);\n  if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) {\n    return null;\n  }\n  return [w, h];\n}\n","import type { Theme } from \"./types.js\";\n\n/**\n * Map `Theme` keys to the CSS custom property they write.\n *\n * Brand/palette keys share names with iqvise's globals.css so hosts\n * that already define `--color-brand` etc. at the page level get the\n * editor in their palette for free — `theme` props ONLY needed when\n * scoping to this editor instance.\n *\n * Chrome keys keep the `--aicut-controls-*` prefix because they have\n * no analogue in the host palette.\n */\nconst THEME_VARS: Record<keyof Theme, string> = {\n  brand: \"--color-brand\",\n  secondary: \"--color-secondary\",\n  surface: \"--color-surface\",\n  dark: \"--color-dark\",\n  muted: \"--color-muted\",\n  card: \"--color-card\",\n  success: \"--color-success\",\n  warning: \"--color-warning\",\n  info: \"--color-info\",\n  error: \"--color-error\",\n  controlsBg: \"--aicut-controls-bg\",\n  controlsBorder: \"--aicut-controls-border\",\n  controlsText: \"--aicut-controls-text\",\n  controlsHover: \"--aicut-controls-hover\",\n  controlsActive: \"--aicut-controls-active\",\n  previewBg: \"--aicut-preview-bg\",\n  radiusSm: \"--aicut-radius-sm\",\n  radiusMd: \"--aicut-radius-md\",\n  radiusLg: \"--aicut-radius-lg\",\n};\n\nexport function applyTheme(root: HTMLElement, theme: Theme | undefined): void {\n  if (!theme) return;\n  for (const key of Object.keys(theme) as Array<keyof Theme>) {\n    const cssVar = THEME_VARS[key];\n    const value = theme[key];\n    if (cssVar && value) root.style.setProperty(cssVar, value);\n  }\n}\n","/**\n * UI strings the editor paints into the DOM (toolbar tooltips, the\n * fullscreen exit button) and onto the timeline canvas (phantom new-\n * track label, track header labels). Every user-visible literal in\n * `@aicut/core` flows through this interface — there are no hidden\n * hard-coded translations elsewhere in the library.\n *\n * Defaults to English. Hosts that want Chinese (or any other locale)\n * pass `locale: localeZh` to `Editor.create` / `Timeline.create`, or\n * override individual keys with `locale: { undo: \"撤销\" }`.\n */\nexport interface Locale {\n  // Toolbar tooltips\n  undo: string;\n  redo: string;\n  split: string;\n  trimLeft: string;\n  trimRight: string;\n  playPause: string;\n  fullscreen: string;\n  snap: string;\n  /** Title shown on the snap button when snap is ON (clicking turns OFF). */\n  snapOnTitle: string;\n  /** Title shown when snap is OFF (clicking turns ON). */\n  snapOffTitle: string;\n  zoomOut: string;\n  zoomIn: string;\n  reset: string;\n  /** Toolbar tooltip when no keyframe exists at the playhead. */\n  keyframeAdd: string;\n  /** Toolbar tooltip when one exists — clicking removes it. */\n  keyframeRemove: string;\n  /** Toolbar tooltip — jump the playhead to the selected clip's start. */\n  seekClipStart: string;\n  /** Toolbar tooltip — jump the playhead to the selected clip's end. */\n  seekClipEnd: string;\n\n  /** Toolbar tooltip — \"+ PiP overlay\" action button (host's file\n   *  picker takes over on click). */\n  pipAdd: string;\n\n  // Aspect-ratio picker (built-in, opt-in via aspect.enabled)\n  /** Toolbar button tooltip — opens the aspect picker popover. */\n  aspectTitle: string;\n  /** Header inside the popover — sits above the ratio grid. */\n  aspectMenuLabel: string;\n  /** Label for the \"follow source clip\" item — clears `Project.aspect`. */\n  aspectOriginal: string;\n\n  // Keyframe panel chrome\n  /** Header text on the keyframe parameter panel. */\n  keyframePanelTitle: string;\n  /** Row label for the X-translation numeric input. */\n  keyframePanelLabelX: string;\n  /** Row label for the Y-translation numeric input. */\n  keyframePanelLabelY: string;\n  /** Row label for the scale numeric input. */\n  keyframePanelLabelScale: string;\n  /** Row label for the easing dropdown. */\n  keyframePanelLabelEasing: string;\n  /** Reset button label — pins this kf to identity (0, 0, 1). */\n  keyframePanelReset: string;\n  /** Reset button tooltip. */\n  keyframePanelResetTitle: string;\n  /** Badge tooltip — kf for THIS prop is pinned at this moment. */\n  keyframePanelBadgePinned: string;\n  /** Badge tooltip — prop has kfs elsewhere but not at this moment. */\n  keyframePanelBadgeAnimated: string;\n  /** Badge tooltip — prop has no kfs (riding the static base). */\n  keyframePanelBadgeStatic: string;\n  /** Time display suffix — appended after the seconds value. */\n  keyframePanelTimeSuffix: string;\n  // Easing dropdown options (curve names)\n  keyframeEasingLinear: string;\n  keyframeEasingEaseIn: string;\n  keyframeEasingEaseOut: string;\n  keyframeEasingEaseInOut: string;\n\n  // Fullscreen exit overlay\n  exitFullscreen: string;\n  exitFullscreenTitle: string;\n\n  // Timeline canvas labels\n  /** Phantom row that appears under the last track during a drag. */\n  newTrack: string;\n  /** Track header — `{n}` is replaced with the 1-based track index. */\n  videoTrackLabel: string;\n  /** Same template format as videoTrackLabel. */\n  audioTrackLabel: string;\n}\n\n/** English. The library default — chosen over Chinese as the OSS norm. */\nexport const localeEn: Locale = {\n  undo: \"Undo (⌘Z)\",\n  redo: \"Redo (⇧⌘Z)\",\n  split: \"Split (K)\",\n  trimLeft: \"Trim left edge (Q)\",\n  trimRight: \"Trim right edge (W)\",\n  playPause: \"Play / Pause (Space)\",\n  fullscreen: \"Fullscreen preview\",\n  snap: \"Snap\",\n  snapOnTitle: \"Turn off snap\",\n  snapOffTitle: \"Turn on snap\",\n  zoomOut: \"Zoom out\",\n  zoomIn: \"Zoom in\",\n  reset: \"Reset edits (keep sources)\",\n  keyframeAdd: \"Add keyframe at playhead\",\n  keyframeRemove: \"Remove keyframe at playhead\",\n  seekClipStart: \"Jump to clip start (I)\",\n  seekClipEnd: \"Jump to clip end (O)\",\n  pipAdd: \"Add picture-in-picture overlay\",\n  aspectTitle: \"Aspect ratio\",\n  aspectMenuLabel: \"Aspect ratio\",\n  aspectOriginal: \"Original\",\n  keyframePanelTitle: \"Keyframe\",\n  keyframePanelLabelX: \"X\",\n  keyframePanelLabelY: \"Y\",\n  keyframePanelLabelScale: \"Scale\",\n  keyframePanelLabelEasing: \"Easing\",\n  keyframePanelReset: \"Reset to 0 0 1\",\n  keyframePanelResetTitle:\n    \"Pin this keyframe to identity (panX=0, panY=0, scale=1)\",\n  keyframePanelBadgePinned: \"Pinned at this moment\",\n  keyframePanelBadgeAnimated: \"Animated — but not pinned at this exact moment\",\n  keyframePanelBadgeStatic: \"Static value\",\n  keyframePanelTimeSuffix: \"s\",\n  keyframeEasingLinear: \"Linear\",\n  keyframeEasingEaseIn: \"Ease in\",\n  keyframeEasingEaseOut: \"Ease out\",\n  keyframeEasingEaseInOut: \"Ease in-out\",\n  exitFullscreen: \"Exit fullscreen\",\n  exitFullscreenTitle: \"Exit fullscreen (Esc)\",\n  newTrack: \"+ New track\",\n  videoTrackLabel: \"Video {n}\",\n  audioTrackLabel: \"Audio {n}\",\n};\n\n/** Simplified Chinese. */\nexport const localeZh: Locale = {\n  undo: \"撤销 (⌘Z)\",\n  redo: \"重做 (⇧⌘Z)\",\n  split: \"分割 (K)\",\n  trimLeft: \"向左裁剪 (Q)\",\n  trimRight: \"向右裁剪 (W)\",\n  playPause: \"播放 / 暂停 (Space)\",\n  fullscreen: \"全屏预览\",\n  snap: \"吸附\",\n  snapOnTitle: \"关闭吸附\",\n  snapOffTitle: \"开启吸附\",\n  zoomOut: \"缩小\",\n  zoomIn: \"放大\",\n  reset: \"重置编辑（保留视频源）\",\n  keyframeAdd: \"添加关键帧\",\n  keyframeRemove: \"删除当前关键帧\",\n  seekClipStart: \"跳到片段起点 (I)\",\n  seekClipEnd: \"跳到片段末尾 (O)\",\n  pipAdd: \"添加画中画\",\n  aspectTitle: \"比例\",\n  aspectMenuLabel: \"画面比例\",\n  aspectOriginal: \"原始\",\n  keyframePanelTitle: \"关键帧\",\n  keyframePanelLabelX: \"X 位移\",\n  keyframePanelLabelY: \"Y 位移\",\n  keyframePanelLabelScale: \"缩放\",\n  keyframePanelLabelEasing: \"缓动\",\n  keyframePanelReset: \"重置为 0 0 1\",\n  keyframePanelResetTitle:\n    \"将该关键帧重置为初始姿态（panX=0, panY=0, scale=1）\",\n  keyframePanelBadgePinned: \"已在该时刻固定\",\n  keyframePanelBadgeAnimated: \"整段有动画，但当前时刻没有锁点\",\n  keyframePanelBadgeStatic: \"未动画（沿用静态值）\",\n  keyframePanelTimeSuffix: \"秒\",\n  keyframeEasingLinear: \"线性\",\n  keyframeEasingEaseIn: \"缓入\",\n  keyframeEasingEaseOut: \"缓出\",\n  keyframeEasingEaseInOut: \"缓入缓出\",\n  exitFullscreen: \"退出全屏\",\n  exitFullscreenTitle: \"退出全屏 (Esc)\",\n  newTrack: \"+ 新轨道\",\n  videoTrackLabel: \"视频 {n}\",\n  audioTrackLabel: \"音频 {n}\",\n};\n\n/** Spread defaults under host overrides — host can supply a partial. */\nexport function mergeLocale(partial: Partial<Locale> | undefined): Locale {\n  return partial ? { ...localeEn, ...partial } : localeEn;\n}\n\n/**\n * Replace `{key}` placeholders in a template. We only need `{n}`\n * substitution today; the implementation is generic so additional\n * keys (e.g. `{name}`) won't need a second pass.\n */\nexport function formatLabel(\n  template: string,\n  vars: Record<string, string | number>,\n): string {\n  return template.replace(/\\{(\\w+)\\}/g, (_, k) =>\n    k in vars ? String(vars[k]) : `{${k}}`,\n  );\n}\n","import type { Ms } from \"../types.js\";\n\nconst THUMB_HEIGHT = 44;\nconst THUMB_WIDTH = Math.round(THUMB_HEIGHT * (16 / 9));\n/**\n * Round all sample times to this bucket so multiple zoom levels share\n * cache hits. 250ms means at the highest zoom (400 px/s) we still get\n * a fresh thumbnail roughly every 100px — plenty of visual continuity.\n */\nconst BUCKET_MS = 250;\n\ninterface SourceState {\n  video: HTMLVideoElement;\n  /** Bucketed ms → bitmap, once extracted. */\n  cache: Map<number, ImageBitmap>;\n  /** Times currently being extracted. */\n  inflight: Set<number>;\n  /** Resolved when the video is past readyState=1 (have metadata). */\n  ready: Promise<void>;\n  /** Pending samples to extract, FIFO. */\n  queue: number[];\n  /** True while a seek/draw cycle is in progress. */\n  busy: boolean;\n}\n\n/**\n * Extracts frame thumbnails from a hidden `<video>` per source and\n * paints them onto a per-clip strip canvas. Decoupled from the main\n * `PlaybackEngine` videos so seeking-for-thumbnails doesn't disturb\n * playback.\n *\n * Strategy: lazy, only extract what the timeline asks for via\n * `paintStrip`. Missing thumbnails get queued; when extraction\n * completes, we call `onUpdate` so the host can request another\n * paint with the now-available bitmap.\n */\nexport class ThumbnailRibbon {\n  private host: HTMLElement;\n  private sources = new Map<string, SourceState>();\n  private onUpdate: () => void;\n\n  static get THUMB_HEIGHT(): number {\n    return THUMB_HEIGHT;\n  }\n  static get THUMB_WIDTH(): number {\n    return THUMB_WIDTH;\n  }\n\n  constructor(host: HTMLElement, onUpdate: () => void) {\n    this.host = host;\n    this.onUpdate = onUpdate;\n  }\n\n  syncSources(sources: Array<{ id: string; url: string; kind: string }>): void {\n    const wanted = new Set(sources.map((s) => s.id));\n    for (const [id, st] of this.sources) {\n      if (!wanted.has(id)) {\n        st.video.remove();\n        for (const bmp of st.cache.values()) bmp.close();\n        this.sources.delete(id);\n      }\n    }\n    for (const src of sources) {\n      if (src.kind !== \"video\") continue;\n      if (this.sources.has(src.id)) continue;\n      const v = document.createElement(\"video\");\n      v.src = src.url;\n      v.preload = \"auto\";\n      v.muted = true;\n      v.playsInline = true;\n      // Off-screen but in the layout so the browser actually decodes it.\n      v.style.position = \"absolute\";\n      v.style.left = \"-9999px\";\n      v.style.top = \"-9999px\";\n      v.style.width = \"160px\";\n      v.style.height = \"90px\";\n      this.host.appendChild(v);\n      const ready = new Promise<void>((resolve) => {\n        if (v.readyState >= 1) resolve();\n        else v.addEventListener(\"loadedmetadata\", () => resolve(), { once: true });\n      });\n      this.sources.set(src.id, {\n        video: v,\n        cache: new Map(),\n        inflight: new Set(),\n        ready,\n        queue: [],\n        busy: false,\n      });\n    }\n  }\n\n  /**\n   * Paint thumbnails for the clip's visible window onto `ctx`. The\n   * canvas is the per-clip strip — width = clip's px width, height =\n   * `pxHeight` (defaults to the cached `THUMB_HEIGHT`). Source-time\n   * range derives from the clip's `in/out` and the px range we're\n   * drawing into.\n   *\n   * `pxHeight` lets the caller stretch thumbs to fill a taller clip\n   * body when `trackHeight` is configured above the default. Aspect\n   * ratio is already broken per-thumb (we slice variable widths from a\n   * fixed-aspect cached bitmap), so stretching height too is fine — it\n   * preserves the \"filmstrip\" look without leaving an empty bottom\n   * band of the brand gradient showing through.\n   */\n  paintStrip(\n    ctx: CanvasRenderingContext2D,\n    sourceId: string,\n    sourceInMs: Ms,\n    sourceOutMs: Ms,\n    pxWidth: number,\n    pxHeight: number = THUMB_HEIGHT,\n  ): void {\n    ctx.clearRect(0, 0, pxWidth, pxHeight);\n    const st = this.sources.get(sourceId);\n    if (!st) return;\n    if (sourceOutMs <= sourceInMs || pxWidth <= 0) return;\n\n    const count = Math.max(1, Math.ceil(pxWidth / THUMB_WIDTH));\n    const spanMs = sourceOutMs - sourceInMs;\n    for (let i = 0; i < count; i++) {\n      const tMs = sourceInMs + (spanMs * i) / count;\n      const bucket = Math.round(tMs / BUCKET_MS) * BUCKET_MS;\n      const bmp = st.cache.get(bucket);\n      const x = Math.round((i * pxWidth) / count);\n      const w =\n        Math.round(((i + 1) * pxWidth) / count) - x;\n      if (bmp) {\n        ctx.drawImage(bmp, x, 0, w, pxHeight);\n      } else {\n        // Placeholder shimmer block — same color as track surface.\n        ctx.fillStyle = \"rgba(255,255,255,0.04)\";\n        ctx.fillRect(x, 0, w, pxHeight);\n        this.enqueue(st, bucket);\n      }\n    }\n  }\n\n  destroy(): void {\n    for (const st of this.sources.values()) {\n      st.video.remove();\n      for (const bmp of st.cache.values()) bmp.close();\n    }\n    this.sources.clear();\n  }\n\n  // ---- internals ------------------------------------------------------\n\n  private enqueue(st: SourceState, bucketMs: number): void {\n    if (st.cache.has(bucketMs) || st.inflight.has(bucketMs)) return;\n    st.inflight.add(bucketMs);\n    st.queue.push(bucketMs);\n    void this.drain(st);\n  }\n\n  private async drain(st: SourceState): Promise<void> {\n    if (st.busy) return;\n    st.busy = true;\n    try {\n      await st.ready;\n      while (st.queue.length > 0) {\n        const t = st.queue.shift()!;\n        try {\n          const bmp = await this.extractFrame(st.video, t);\n          st.cache.set(t, bmp);\n        } catch {\n          // ignore — failed extractions just leave the placeholder\n        } finally {\n          st.inflight.delete(t);\n        }\n        this.onUpdate();\n      }\n    } finally {\n      st.busy = false;\n    }\n  }\n\n  private extractFrame(\n    video: HTMLVideoElement,\n    timeMs: Ms,\n  ): Promise<ImageBitmap> {\n    const targetSec = Math.max(\n      0,\n      Math.min((video.duration || Infinity) - 0.05, timeMs / 1000),\n    );\n    return new Promise((resolve, reject) => {\n      const onSeeked = () => {\n        try {\n          const cnv = document.createElement(\"canvas\");\n          cnv.width = THUMB_WIDTH;\n          cnv.height = THUMB_HEIGHT;\n          const cx = cnv.getContext(\"2d\");\n          if (!cx) return reject(new Error(\"no 2d ctx\"));\n          // Cover-crop the source into the fixed 16:9 thumb box so a\n          // portrait / square video doesn't get squished into a strip.\n          // Mirrors CapCut / Premiere timeline thumbnails (centered\n          // crop of the active frame). Source-rect math, dest fills.\n          const vw = video.videoWidth || THUMB_WIDTH;\n          const vh = video.videoHeight || THUMB_HEIGHT;\n          const targetAr = THUMB_WIDTH / THUMB_HEIGHT;\n          const srcAr = vw / vh;\n          let sx = 0;\n          let sy = 0;\n          let sw = vw;\n          let sh = vh;\n          if (srcAr > targetAr) {\n            // Source wider than thumb — crop the sides.\n            sw = vh * targetAr;\n            sx = (vw - sw) / 2;\n          } else if (srcAr < targetAr) {\n            // Source taller than thumb — crop top + bottom.\n            sh = vw / targetAr;\n            sy = (vh - sh) / 2;\n          }\n          cx.drawImage(video, sx, sy, sw, sh, 0, 0, THUMB_WIDTH, THUMB_HEIGHT);\n          // createImageBitmap is async but cheap and gives a portable\n          // GPU-friendly handle the strip canvas can blit fast.\n          createImageBitmap(cnv).then(resolve, reject);\n        } catch (e) {\n          reject(e as Error);\n        }\n      };\n      video.addEventListener(\"seeked\", onSeeked, { once: true });\n      try {\n        video.currentTime = targetSec;\n      } catch (e) {\n        video.removeEventListener(\"seeked\", onSeeked);\n        reject(e as Error);\n      }\n    });\n  }\n}\n","import type { Ms } from \"../types.js\";\n\n/** mm:ss (rounded to seconds) — matches the toolbar reference. */\nexport function fmtClock(ms: Ms): string {\n  const total = Math.max(0, Math.round(ms / 1000));\n  const m = Math.floor(total / 60);\n  const s = total % 60;\n  return `${pad2(m)}:${pad2(s)}`;\n}\n\n/** mm:ss.mmm with millisecond precision — used in the time label. */\nexport function fmtClockMs(ms: Ms): string {\n  const total = Math.max(0, Math.round(ms));\n  const m = Math.floor(total / 60000);\n  const s = Math.floor((total % 60000) / 1000);\n  const r = total % 1000;\n  return `${pad2(m)}:${pad2(s)}.${pad3(r)}`;\n}\n\nconst pad2 = (n: number) => (n < 10 ? `0${n}` : `${n}`);\nconst pad3 = (n: number) => n.toString().padStart(3, \"0\");\n","import { formatLabel, type Locale } from \"../i18n.js\";\nimport type {\n  Clip,\n  Keyframe,\n  MediaSource,\n  Project,\n  Track,\n} from \"../types.js\";\nimport { fmtClockMs } from \"../ui/format.js\";\nimport type { ThumbnailRibbon } from \"../ui/thumbnails.js\";\nimport {\n  CLIP_INSET,\n  HEADER_WIDTH,\n  RULER_HEIGHT,\n  SCROLLBAR_INSET,\n  SCROLLBAR_MIN_THUMB,\n  SCROLLBAR_THICKNESS,\n  TRACK_HEIGHT,\n  contentHeight,\n  contentLeftX,\n  contentWidth,\n  formatRulerLabel,\n  pickRulerTicks,\n  trackY,\n  uncoveredIntervals,\n} from \"./layout.js\";\nimport { projectFps } from \"../model.js\";\n\nexport interface DrawStyle {\n  bg: string;\n  border: string;\n  text: string;\n  textMuted: string;\n  trackBg: string;\n  brand: string;\n  brandTo: string;\n  info: string;\n  clipText: string;\n  selectedRing: string;\n  playhead: string;\n}\n\nexport interface DrawState {\n  project: Project;\n  pxPerSec: number;\n  scrollLeft: number;\n  scrollTop: number;\n  timeMs: number;\n  selectedClipId: string | null;\n  hoveredClipId: string | null;\n  hoveredTrackIndex: number | null;\n  dropTargetTrackIndex: number | null;\n  /** While any drag is in flight, draw a \"+ 新轨道\" phantom row at the\n   *  bottom that the user can drop into to explicitly create a track. */\n  isDragging: boolean;\n  snapX: number | null;\n  showHeader: boolean;\n  viewportWidth: number;\n  viewportHeight: number;\n  /** 0–1 fade opacity for each scrollbar. 0 hides it entirely. */\n  scrollbarOpacityY: number;\n  scrollbarOpacityX: number;\n  /** Active = currently being dragged → render at full opacity + emphasized. */\n  scrollbarActiveY: boolean;\n  scrollbarActiveX: boolean;\n  /** Resolved locale used for canvas-painted labels. */\n  locale: Locale;\n  /** Minimum pixel gap between ruler major ticks — drives the auto\n   *  picker. Mirrored from `TimelineOptions.rulerMinTickPx` (default 80). */\n  rulerMinTickPx: number;\n  /** When true, paint a diamond marker on each clip per keyframe.\n   *  Wired to `Editor.isKeyframesEnabled()`. */\n  keyframesEnabled: boolean;\n  /** Currently selected keyframe (rendered with brand-color fill). */\n  selectedKeyframe: { clipId: string; keyframeId: string } | null;\n  /** Currently hovered keyframe (rendered with brand outline). */\n  hoveredKeyframe: { clipId: string; keyframeId: string } | null;\n  /** While a keyframe-drag is in flight, the dragged diamond paints\n   *  at this ghost time instead of its committed time so the visual\n   *  follows the cursor. */\n  keyframeDragGhost: {\n    clipId: string;\n    keyframeId: string;\n    ghostTimeMs: number;\n  } | null;\n  /**\n   * In-flight drag preview. While set, the clip with `clipId` is\n   * drawn faded at its real position AND a fully-opaque \"ghost\" of it\n   * is drawn at (ghostStart, ghostTrackIndex). `wouldOverlap` flips\n   * the ghost to a warning color so users see auto-split coming.\n   */\n  dragGhost: {\n    clipId: string;\n    ghostStart: number;\n    ghostTrackIndex: number;\n    wouldOverlap: boolean;\n  } | null;\n}\n\n/**\n * Paint the entire timeline. Stateless — given the same DrawState\n * twice you get the same pixels.\n *\n * Layout has FOUR regions with different sticky behavior:\n *   - Ruler band  (top, scrolls X only)\n *   - Headers col (left, scrolls Y only — when showHeader)\n *   - Tracks      (the main grid, scrolls both)\n *   - Scrollbars  (edge overlays, never scroll)\n *\n * We render in passes; each pass `clip`s to its region and (where\n * needed) translates by `-scrollTop` so paint functions can keep\n * working in their natural untranslated coordinates.\n */\nexport function drawAll(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n  thumbs: ThumbnailRibbon,\n): void {\n  const { viewportWidth: W, viewportHeight: H } = state;\n  ctx.fillStyle = style.bg;\n  ctx.fillRect(0, 0, W, H);\n\n  const baseX = contentLeftX(state.showHeader);\n  const trackAreaW = W - baseX - SCROLLBAR_THICKNESS;\n  const trackAreaH = H - RULER_HEIGHT - SCROLLBAR_THICKNESS;\n\n  // --- Pass 1: Track grid (scrolls X + Y) -----------------------------\n  ctx.save();\n  ctx.beginPath();\n  ctx.rect(baseX, RULER_HEIGHT, trackAreaW, trackAreaH);\n  ctx.clip();\n  ctx.translate(0, -state.scrollTop);\n  drawTracks(ctx, state, style, thumbs);\n  if (state.isDragging) {\n    drawPhantomRow(ctx, state.project.tracks.length, baseX, state, style);\n  }\n  if (state.dragGhost) drawDragGhost(ctx, state, style, thumbs);\n  ctx.restore();\n\n  // --- Pass 2: Headers column (sticky X, scrolls Y) -------------------\n  if (state.showHeader) {\n    ctx.save();\n    ctx.beginPath();\n    ctx.rect(0, RULER_HEIGHT, HEADER_WIDTH, trackAreaH);\n    ctx.clip();\n    ctx.translate(0, -state.scrollTop);\n    drawHeaders(ctx, state, style);\n    ctx.restore();\n  }\n\n  // --- Pass 3: Ruler (sticky Y, scrolls X) ----------------------------\n  ctx.save();\n  ctx.beginPath();\n  ctx.rect(baseX, 0, trackAreaW, RULER_HEIGHT);\n  ctx.clip();\n  drawRuler(ctx, state, style);\n  ctx.restore();\n\n  // --- Pass 4: Coverage-gap warning (scrolls X, full visible height) --\n  // Painted AFTER both tracks and the ruler so the amber tint + the\n  // diagonal \"broken teeth\" hatch sit on top of timecode markings —\n  // that's what makes a missing segment instantly catchable when the\n  // user is scanning the ruler row.\n  ctx.save();\n  ctx.beginPath();\n  ctx.rect(baseX, 0, trackAreaW, H - SCROLLBAR_THICKNESS);\n  ctx.clip();\n  drawCoverageGaps(ctx, state, style);\n  ctx.restore();\n\n  // --- Pass 5: Snap guide only (playhead moves to the top layer) -----\n  ctx.save();\n  ctx.beginPath();\n  ctx.rect(baseX, 0, trackAreaW, H - SCROLLBAR_THICKNESS);\n  ctx.clip();\n  drawSnapGuide(ctx, state, style);\n  ctx.restore();\n\n  // --- Pass 6: Scrollbars (no clip — overlay at edges) ---------------\n  drawScrollbarV(ctx, state, style);\n  drawScrollbarH(ctx, state, style);\n\n  // --- Pass 7: Playhead — drawn LAST so it sits on top of every\n  // other layer (ruler ticks, scrollbar gutters, coverage tint).\n  // Clip excludes the header column but INCLUDES the left/right\n  // padding, so the time-bubble at t=0 can extend into the pad zone\n  // instead of being half-eaten by a tight clip anchored at baseX.\n  // The bubble itself is still clamped inside the playable area in\n  // drawPlayhead so it never crosses the header edge regardless.\n  const playheadLeft = state.showHeader ? HEADER_WIDTH : 0;\n  ctx.save();\n  ctx.beginPath();\n  ctx.rect(playheadLeft, 0, W - playheadLeft, H);\n  ctx.clip();\n  drawPlayhead(ctx, state, style);\n  ctx.restore();\n}\n\n/**\n * Highlight time spans where no video clip is present anywhere on any\n * track — a warning to the user that the export will have a hard cut\n * to black at this point. Painted as a translucent amber vertical\n * strip spanning the full track stack, plus a slightly more saturated\n * strip in the ruler band so it's catchable even when the user is\n * scanning the timecode row.\n */\nfunction drawCoverageGaps(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  const gaps = uncoveredIntervals(state.project);\n  if (gaps.length === 0) return;\n  const baseX = contentLeftX(state.showHeader);\n  // Span the visible track area, not the (potentially huge) total —\n  // pre-clipped by drawAll's pass-2 region anyway, but explicit\n  // height keeps the hatch math clean.\n  const trackStackH =\n    state.viewportHeight - RULER_HEIGHT - SCROLLBAR_THICKNESS;\n  for (const [s, e] of gaps) {\n    const x1 = Math.max(\n      baseX,\n      baseX + (s / 1000) * state.pxPerSec - state.scrollLeft,\n    );\n    const x2 = Math.min(\n      state.viewportWidth,\n      baseX + (e / 1000) * state.pxPerSec - state.scrollLeft,\n    );\n    if (x2 <= x1) continue;\n    // Ruler band — stronger so it's the first thing the eye catches.\n    ctx.fillStyle = \"rgba(250, 167, 0, 0.35)\";\n    ctx.fillRect(x1, 0, x2 - x1, RULER_HEIGHT);\n    // Track band — faint so it doesn't fight the clip thumbnails on\n    // adjacent rows.\n    ctx.fillStyle = \"rgba(250, 167, 0, 0.12)\";\n    ctx.fillRect(x1, RULER_HEIGHT, x2 - x1, trackStackH);\n    // Hatched marker on the ruler so it reads as a problem, not a\n    // selection. Diagonal lines at 6px spacing.\n    ctx.save();\n    ctx.strokeStyle = \"rgba(250, 167, 0, 0.6)\";\n    ctx.lineWidth = 1;\n    ctx.beginPath();\n    for (let hx = Math.floor(x1); hx < x2; hx += 6) {\n      ctx.moveTo(hx, RULER_HEIGHT - 1);\n      ctx.lineTo(hx + 6, RULER_HEIGHT - 7);\n    }\n    ctx.stroke();\n    ctx.restore();\n    void style;\n  }\n}\n\nfunction drawDragGhost(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n  thumbs: ThumbnailRibbon,\n): void {\n  const ghost = state.dragGhost!;\n  // Locate the real clip so the ghost reuses its source / duration.\n  let real: Clip | null = null;\n  for (const t of state.project.tracks) {\n    const c = t.clips.find((c) => c.id === ghost.clipId);\n    if (c) {\n      real = c;\n      break;\n    }\n  }\n  if (!real) return;\n\n  const baseX = contentLeftX(state.showHeader);\n  const widthPx = Math.max(2, ((real.out - real.in) / 1000) * state.pxPerSec);\n  const startX =\n    baseX + (ghost.ghostStart / 1000) * state.pxPerSec - state.scrollLeft;\n\n  // ---- Drop-slot outline ------------------------------------------------\n  // Always paint a dashed rectangle where the clip will land — the\n  // outline is the \"slot\" and the solid ghost above it is the clip.\n  // When the drop would overlap (→ Editor will auto-split onto a\n  // brand-new track below), draw an ADDITIONAL phantom row at the\n  // bottom + outline there, so the user sees the new track coming.\n  const overlap = ghost.wouldOverlap;\n  // Phantom row is now drawn unconditionally during drag (see drawAll);\n  // we only need the dashed drop outline here, on whichever row the\n  // ghost is currently above.\n  drawDropOutline(\n    ctx,\n    startX,\n    overlap ? state.project.tracks.length : ghost.ghostTrackIndex,\n    widthPx,\n    style.info,\n    overlap,\n  );\n\n  // ---- Ghost clip body --------------------------------------------------\n  // Slight transparency so the user reads it as \"preview\" rather than\n  // the committed clip. The drop outline + phantom row carry the rest\n  // of the wayfinding.\n  ctx.save();\n  ctx.globalAlpha = 0.85;\n  drawClipAt(\n    ctx,\n    real,\n    overlap ? state.project.tracks.length : ghost.ghostTrackIndex,\n    ghost.ghostStart,\n    state.project.sources,\n    state,\n    style,\n    thumbs,\n    /* dim = */ false,\n    /* warn = */ overlap,\n  );\n  ctx.restore();\n}\n\nfunction drawDropOutline(\n  ctx: CanvasRenderingContext2D,\n  startX: number,\n  trackIndex: number,\n  widthPx: number,\n  color: string,\n  emphasized: boolean,\n): void {\n  // 1px solid info-tinted outline — present, but doesn't shout.\n  // `emphasized` (used when the drop would land on the phantom new\n  // track) bumps to a slightly thicker stroke + a faint glow halo.\n  const y = trackY(trackIndex) + CLIP_INSET - 1;\n  const h = TRACK_HEIGHT - CLIP_INSET * 2 + 2;\n  ctx.save();\n  if (emphasized) {\n    ctx.shadowColor = withAlpha(color, 0.45);\n    ctx.shadowBlur = 6;\n  }\n  ctx.strokeStyle = withAlpha(color, emphasized ? 0.9 : 0.7);\n  ctx.lineWidth = 1;\n  roundRect(ctx, startX - 0.5, y, widthPx + 1, h, 6);\n  ctx.stroke();\n  ctx.restore();\n}\n\n/**\n * Hairline placeholder row beneath the existing tracks, visible only\n * while a drag is active. Deliberately understated — top + bottom\n * dashed borders + a tiny label, no fill — so it reads as \"available\n * slot\" rather than \"selection target\".\n */\nfunction drawPhantomRow(\n  ctx: CanvasRenderingContext2D,\n  trackIndex: number,\n  baseX: number,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  const y = trackY(trackIndex);\n  const w = state.viewportWidth - baseX;\n  ctx.save();\n  // Very faint background tint — keeps the row visually grouped with\n  // the rest of the timeline without competing with clip thumbnails.\n  ctx.fillStyle = withAlpha(style.info, 0.04);\n  ctx.fillRect(baseX, y, w, TRACK_HEIGHT);\n  // Dashed top + bottom hairlines so the eye reads it as a slot.\n  ctx.strokeStyle = withAlpha(style.info, 0.35);\n  ctx.lineWidth = 1;\n  ctx.setLineDash([3, 4]);\n  ctx.beginPath();\n  ctx.moveTo(baseX, y + 0.5);\n  ctx.lineTo(baseX + w, y + 0.5);\n  ctx.moveTo(baseX, y + TRACK_HEIGHT - 0.5);\n  ctx.lineTo(baseX + w, y + TRACK_HEIGHT - 0.5);\n  ctx.stroke();\n  ctx.setLineDash([]);\n  if (state.showHeader) {\n    ctx.fillStyle = withAlpha(style.info, 0.7);\n    ctx.font = \"10px system-ui, -apple-system, sans-serif\";\n    ctx.textBaseline = \"middle\";\n    ctx.fillText(state.locale.newTrack, 12, y + TRACK_HEIGHT / 2);\n  }\n  ctx.restore();\n}\n\n// ---- ruler ----------------------------------------------------------------\n\nfunction drawRuler(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  const { pxPerSec, scrollLeft, viewportWidth: W } = state;\n  const baseX = contentLeftX(state.showHeader);\n  const rulerW = W - baseX;\n\n  ctx.fillStyle = style.bg;\n  ctx.fillRect(baseX, 0, rulerW, RULER_HEIGHT);\n\n  // Bottom border under the ruler.\n  ctx.strokeStyle = style.border;\n  ctx.lineWidth = 1;\n  ctx.beginPath();\n  ctx.moveTo(baseX, RULER_HEIGHT - 0.5);\n  ctx.lineTo(W, RULER_HEIGHT - 0.5);\n  ctx.stroke();\n\n  const minPx = state.rulerMinTickPx;\n  const fps = projectFps(state.project);\n  const { majorSec, subSec } = pickRulerTicks(minPx / pxPerSec, fps, pxPerSec);\n  // Sub-ticks per major. Round to int because sub-tick spacing is\n  // 1/fps at high zoom and the division isn't exact in binary.\n  const subDiv = Math.max(1, Math.round(majorSec / subSec));\n\n  const firstVisibleSec = Math.max(0, scrollLeft / pxPerSec - subSec);\n  const lastVisibleSec = (scrollLeft + rulerW) / pxPerSec + subSec;\n\n  ctx.textBaseline = \"bottom\";\n  ctx.font = \"10px system-ui, -apple-system, sans-serif\";\n\n  // Sub + major ticks in one pass.\n  const startStep = Math.floor(firstVisibleSec / subSec);\n  const endStep = Math.ceil(lastVisibleSec / subSec);\n\n  for (let i = startStep; i <= endStep; i++) {\n    const s = i * subSec;\n    if (s < 0) continue;\n    const x = baseX + s * pxPerSec - scrollLeft;\n    if (x < baseX || x > W) continue;\n    // Index within the current major (0 → at a whole-second boundary).\n    // Integer modulo dodges the float-mod glitch where e.g.\n    // `0.6 / 0.2 = 2.9999…` would miss a label like 0.6s.\n    const subIdx = ((i % subDiv) + subDiv) % subDiv;\n    const isMajor = subIdx === 0;\n    // Frame mode (subDiv > 5) gets secondary labels every 5 frames\n    // inside the second — keeps \"5f / 10f / 15f / …\" visible even\n    // when the next whole-second mark is off-screen. Low-zoom mode\n    // (subDiv === 5) already has labels at every major, no secondary\n    // needed.\n    const isMidLabel = !isMajor && subDiv > 5 && subIdx % 5 === 0;\n    ctx.strokeStyle = isMajor\n      ? withAlpha(style.text, 0.5)\n      : isMidLabel\n        ? withAlpha(style.text, 0.35)\n        : withAlpha(style.text, 0.22);\n    ctx.lineWidth = 1;\n    const h = isMajor ? 10 : isMidLabel ? 8 : 5;\n    ctx.beginPath();\n    ctx.moveTo(x + 0.5, RULER_HEIGHT - h);\n    ctx.lineTo(x + 0.5, RULER_HEIGHT - 1);\n    ctx.stroke();\n    if (isMajor) {\n      ctx.fillStyle = withAlpha(style.textMuted, 0.85);\n      ctx.fillText(formatRulerLabel(s), x + 3, RULER_HEIGHT - 12);\n    } else if (isMidLabel) {\n      ctx.fillStyle = withAlpha(style.textMuted, 0.55);\n      ctx.fillText(`${subIdx}f`, x + 3, RULER_HEIGHT - 12);\n    }\n  }\n}\n\n// ---- tracks + clips -------------------------------------------------------\n\nfunction drawTracks(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n  thumbs: ThumbnailRibbon,\n): void {\n  const { project } = state;\n  for (let ti = 0; ti < project.tracks.length; ti++) {\n    drawTrackRow(ctx, ti, project.tracks[ti]!, project.sources, state, style, thumbs);\n  }\n}\n\nfunction drawTrackRow(\n  ctx: CanvasRenderingContext2D,\n  trackIndex: number,\n  track: Track,\n  sources: MediaSource[],\n  state: DrawState,\n  style: DrawStyle,\n  thumbs: ThumbnailRibbon,\n): void {\n  const { viewportWidth: W } = state;\n  const baseX = contentLeftX(state.showHeader);\n  const y = trackY(trackIndex);\n\n  // Track surface: just the default tint. Drop-target highlight is now\n  // limited to a 1px top + bottom info-tinted hairline (instead of a\n  // brand-color flood) so the dragged ghost reads as primary content\n  // and the row hint stays quiet.\n  ctx.fillStyle = style.trackBg;\n  ctx.fillRect(baseX, y, W - baseX, TRACK_HEIGHT);\n\n  // Row separator (bottom border).\n  ctx.strokeStyle = style.border;\n  ctx.lineWidth = 1;\n  ctx.beginPath();\n  ctx.moveTo(baseX, y + TRACK_HEIGHT - 0.5);\n  ctx.lineTo(W, y + TRACK_HEIGHT - 0.5);\n  ctx.stroke();\n\n  if (state.dropTargetTrackIndex === trackIndex) {\n    ctx.strokeStyle = withAlpha(style.info, 0.45);\n    ctx.lineWidth = 1;\n    ctx.beginPath();\n    ctx.moveTo(baseX, y + 0.5);\n    ctx.lineTo(W, y + 0.5);\n    ctx.moveTo(baseX, y + TRACK_HEIGHT - 0.5);\n    ctx.lineTo(W, y + TRACK_HEIGHT - 0.5);\n    ctx.stroke();\n  }\n\n  for (const clip of track.clips) {\n    const dim = state.dragGhost?.clipId === clip.id;\n    drawClipAt(\n      ctx,\n      clip,\n      trackIndex,\n      clip.start,\n      sources,\n      state,\n      style,\n      thumbs,\n      dim,\n      false,\n    );\n  }\n}\n\n/**\n * Paint a clip at a virtual `(trackIndex, startMs)` that may differ\n * from its data position. Used for both normal clip rendering (passing\n * the clip's real `start` + `trackIndex`) and for the in-flight drag\n * ghost (where the values come from pointer position).\n *\n *   `dim`  — render at low opacity (the \"leave-behind\" at the drag's\n *            origin so the user sees where the clip will return if\n *            they release without moving).\n *   `warn` — paint the body in warning color (orange-ish) to telegraph\n *            \"if you drop here, this will create a new track because\n *            of the overlap rule.\"\n */\nfunction drawClipAt(\n  ctx: CanvasRenderingContext2D,\n  clip: Clip,\n  trackIndex: number,\n  startMs: number,\n  sources: MediaSource[],\n  state: DrawState,\n  style: DrawStyle,\n  thumbs: ThumbnailRibbon,\n  dim: boolean,\n  warn: boolean,\n): void {\n  const { pxPerSec, scrollLeft } = state;\n  const baseX = contentLeftX(state.showHeader);\n  const startX = baseX + (startMs / 1000) * pxPerSec - scrollLeft;\n  const widthPx = Math.max(2, ((clip.out - clip.in) / 1000) * pxPerSec);\n  const y = trackY(trackIndex) + CLIP_INSET;\n  const h = TRACK_HEIGHT - CLIP_INSET * 2;\n  if (startX + widthPx < baseX || startX > state.viewportWidth) return;\n\n  ctx.save();\n  if (dim) ctx.globalAlpha = 0.3;\n\n  // Body fill — brand gradient by default. `warn` (drop would\n  // auto-create a new track) tints toward a soft amber rather than\n  // the previous loud red/orange.\n  const grad = ctx.createLinearGradient(0, y, 0, y + h);\n  if (warn) {\n    grad.addColorStop(0, \"rgba(250, 175, 70, 0.7)\");\n    grad.addColorStop(1, \"rgba(240, 145, 50, 0.62)\");\n  } else {\n    grad.addColorStop(0, withAlpha(style.brand, 0.8));\n    grad.addColorStop(1, withAlpha(style.brandTo, 0.7));\n  }\n  ctx.fillStyle = grad;\n  roundRect(ctx, startX, y, widthPx, h, 6);\n  ctx.fill();\n\n  // Thumbnail strip — passes the clip body height so thumbs stretch\n  // to fill when trackHeight is configured above the default. Otherwise\n  // the brand gradient (purple-ish on dark themes) shows through the\n  // bottom band of tall tracks.\n  ctx.save();\n  roundRect(ctx, startX, y, widthPx, h, 6);\n  ctx.clip();\n  ctx.translate(startX, y);\n  thumbs.paintStrip(ctx, clip.sourceId, clip.in, clip.out, widthPx, h);\n  ctx.restore();\n\n  // Inner highlight (1px white inset).\n  ctx.strokeStyle = \"rgba(255,255,255,0.2)\";\n  ctx.lineWidth = 1;\n  roundRect(ctx, startX + 0.5, y + 0.5, widthPx - 1, h - 1, 6);\n  ctx.stroke();\n\n  // Label.\n  const src = sources.find((s) => s.id === clip.sourceId);\n  const label = src?.name ?? src?.url.split(\"/\").pop() ?? clip.id;\n  ctx.font = \"11px system-ui, -apple-system, sans-serif\";\n  ctx.textBaseline = \"top\";\n  ctx.fillStyle = \"rgba(0,0,0,0.6)\";\n  ctx.fillText(label, startX + 9, y + 5);\n  ctx.fillStyle = \"#fff\";\n  ctx.fillText(label, startX + 8, y + 4);\n\n  // Selection ring (skip when dimmed — selection has no meaning on a\n  // ghost source clip; the ghost itself draws its own ring if you add\n  // one later).\n  if (!dim && state.selectedClipId === clip.id) {\n    ctx.strokeStyle = style.selectedRing;\n    ctx.lineWidth = 2;\n    roundRect(ctx, startX - 1, y - 1, widthPx + 2, h + 2, 7);\n    ctx.stroke();\n  }\n\n  // Edge handles on hover or selection.\n  const showHandles =\n    !dim && (state.selectedClipId === clip.id || state.hoveredClipId === clip.id);\n  if (showHandles) {\n    ctx.fillStyle = \"rgba(255,255,255,0.75)\";\n    ctx.fillRect(startX + 2, y + 12, 2, h - 24);\n    ctx.fillRect(startX + widthPx - 4, y + 12, 2, h - 24);\n  }\n\n  // Keyframe markers — one diamond per UNIQUE moment in time (a\n  // moment is a cluster of per-prop keyframes at the same time —\n  // typically the panX/panY/scale trio from a single toolbar click).\n  // Painted on the clip body vertical center; selected = brand fill,\n  // hovered = brighter + slightly bigger.\n  // Keyframes paint on BOTH the real (possibly dim) clip and any\n  // ghost clip during a drag — skipping them on dim made the diamond\n  // appear to vanish the moment a user clicked just outside the kf\n  // hit radius (their click drags the clip, the real clip dims, and\n  // the diamond on the ORIGINAL position quietly drops out of the\n  // canvas — looks like \"I dragged the kf and it disappeared\"). The\n  // ghost clip painted underneath still carries its own diamonds at\n  // the drag offset, so the user can see both the residual position\n  // and the destination.\n  if (\n    state.keyframesEnabled &&\n    clip.keyframes &&\n    clip.keyframes.length > 0\n  ) {\n    const diamondY = y + h / 2;\n    const halfSize = 5; // visible diamond is 10 × 10 px\n    // Group keyframes by time (within 16 ms of each other = \"same moment\").\n    const moments = groupKeyframesByTime(clip.keyframes, 16);\n    const ghost = state.keyframeDragGhost;\n    for (const moment of moments) {\n      // The dragged kf within this moment (if any) carries the\n      // ghost time. We just paint one diamond per moment though, so\n      // any one kf belonging to it is enough to detect the ghost.\n      const draggedHere = ghost\n        ? moment.kfs.find(\n            (k) => ghost.clipId === clip.id && ghost.keyframeId === k.id,\n          )\n        : undefined;\n      const effectiveTime = draggedHere ? ghost!.ghostTimeMs : moment.time;\n      const kfX = startX + (effectiveTime / 1000) * pxPerSec;\n      if (kfX < baseX - halfSize || kfX > state.viewportWidth + halfSize) continue;\n      const isSelected =\n        state.selectedKeyframe?.clipId === clip.id &&\n        moment.kfs.some((k) => k.id === state.selectedKeyframe?.keyframeId);\n      const isHovered =\n        state.hoveredKeyframe?.clipId === clip.id &&\n        moment.kfs.some((k) => k.id === state.hoveredKeyframe?.keyframeId);\n      const drawSize = isHovered ? halfSize + 1.5 : halfSize;\n      ctx.beginPath();\n      ctx.moveTo(kfX, diamondY - drawSize);\n      ctx.lineTo(kfX + drawSize, diamondY);\n      ctx.lineTo(kfX, diamondY + drawSize);\n      ctx.lineTo(kfX - drawSize, diamondY);\n      ctx.closePath();\n      // Dim clips paint diamonds at reduced opacity — visible but\n      // muted, so the user sees both the \"where it WAS\" residual on\n      // the source position and the \"where it IS now\" diamond on the\n      // ghost.\n      const fillAlpha = dim ? 0.4 : 0.85;\n      const strokeAlpha = dim ? 0.3 : 0.65;\n      ctx.fillStyle = isSelected\n        ? style.selectedRing\n        : isHovered\n          ? \"#ffffff\"\n          : withAlpha(style.text, fillAlpha);\n      ctx.fill();\n      ctx.strokeStyle = isHovered\n        ? style.selectedRing\n        : `rgba(0, 0, 0, ${strokeAlpha})`;\n      ctx.lineWidth = isHovered ? 1.5 : 1;\n      ctx.stroke();\n    }\n  }\n\n  ctx.restore();\n}\n\n// ---- headers --------------------------------------------------------------\n\nfunction drawHeaders(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  ctx.fillStyle = style.bg;\n  ctx.fillRect(0, 0, HEADER_WIDTH, state.viewportHeight);\n\n  // Right border separating headers from scrollable area.\n  ctx.strokeStyle = style.border;\n  ctx.lineWidth = 1;\n  ctx.beginPath();\n  ctx.moveTo(HEADER_WIDTH - 0.5, 0);\n  ctx.lineTo(HEADER_WIDTH - 0.5, state.viewportHeight);\n  ctx.stroke();\n\n  ctx.textBaseline = \"middle\";\n  ctx.font = \"11px system-ui, -apple-system, sans-serif\";\n  for (let i = 0; i < state.project.tracks.length; i++) {\n    const t = state.project.tracks[i]!;\n    const y = trackY(i);\n    // Track row separator.\n    ctx.strokeStyle = style.border;\n    ctx.beginPath();\n    ctx.moveTo(0, y + TRACK_HEIGHT - 0.5);\n    ctx.lineTo(HEADER_WIDTH, y + TRACK_HEIGHT - 0.5);\n    ctx.stroke();\n\n    ctx.fillStyle = withAlpha(style.text, 0.7);\n    const template =\n      t.kind === \"video\"\n        ? state.locale.videoTrackLabel\n        : state.locale.audioTrackLabel;\n    const label = formatLabel(template, { n: i + 1 });\n    ctx.fillText(label, 12, y + TRACK_HEIGHT / 2);\n\n    // Delete-track button — × icon at the right edge. Only painted\n    // for empty tracks (hit-test agrees) so a busy row's UI doesn't\n    // dangle a destructive button next to actual content.\n    if (t.clips.length === 0) {\n      const hovered = state.hoveredTrackIndex === i;\n      const btnSize = 18;\n      const btnLeft = HEADER_WIDTH - btnSize - 6;\n      const btnTop = y + (TRACK_HEIGHT - btnSize) / 2;\n      ctx.save();\n      if (hovered) {\n        ctx.fillStyle = withAlpha(style.text, 0.1);\n        roundRect(ctx, btnLeft, btnTop, btnSize, btnSize, 5);\n        ctx.fill();\n      }\n      ctx.strokeStyle = withAlpha(style.text, hovered ? 0.85 : 0.4);\n      ctx.lineWidth = 1.4;\n      const pad = 5;\n      ctx.beginPath();\n      ctx.moveTo(btnLeft + pad, btnTop + pad);\n      ctx.lineTo(btnLeft + btnSize - pad, btnTop + btnSize - pad);\n      ctx.moveTo(btnLeft + btnSize - pad, btnTop + pad);\n      ctx.lineTo(btnLeft + pad, btnTop + btnSize - pad);\n      ctx.stroke();\n      ctx.restore();\n    }\n  }\n}\n\n// ---- playhead -------------------------------------------------------------\n\nfunction drawPlayhead(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  const baseX = contentLeftX(state.showHeader);\n  const x = baseX + (state.timeMs / 1000) * state.pxPerSec - state.scrollLeft;\n  if (x < baseX - 2 || x > state.viewportWidth + 2) return;\n\n  // Vertical line through ruler + tracks.\n  ctx.strokeStyle = style.playhead;\n  ctx.lineWidth = 2;\n  ctx.beginPath();\n  ctx.moveTo(x, 0);\n  ctx.lineTo(x, state.viewportHeight);\n  ctx.stroke();\n\n  // Time bubble centered on the playhead at the top of the ruler.\n  // Clamped to the content area's bounds so it doesn't get clipped\n  // (or hidden behind the header column) when the playhead sits at\n  // t=0 or scrolled to the very end. The triangle stays anchored to\n  // the playhead line so the visual link survives the clamp.\n  const label = fmtClockMs(state.timeMs);\n  ctx.font = \"10px system-ui, -apple-system, sans-serif\";\n  const padX = 6;\n  const w = ctx.measureText(label).width + padX * 2;\n  const h = 14;\n  const contentRight = state.viewportWidth - SCROLLBAR_THICKNESS;\n  const rawBx = x - w / 2;\n  const bx = Math.max(baseX, Math.min(contentRight - w, rawBx));\n  const by = 2;\n  ctx.fillStyle = style.playhead;\n  roundRect(ctx, bx, by, w, h, 4);\n  ctx.fill();\n  // Triangle hanging below the bubble — keeps the visual link to the\n  // playhead line even when the bubble is clamped.\n  ctx.beginPath();\n  ctx.moveTo(x - 4, by + h);\n  ctx.lineTo(x + 4, by + h);\n  ctx.lineTo(x, by + h + 4);\n  ctx.closePath();\n  ctx.fill();\n  ctx.fillStyle = \"#fff\";\n  ctx.textBaseline = \"middle\";\n  ctx.fillText(label, bx + padX, by + h / 2);\n}\n\n// ---- snap guide -----------------------------------------------------------\n\nfunction drawSnapGuide(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  if (state.snapX == null) return;\n  ctx.strokeStyle = style.info;\n  ctx.lineWidth = 1;\n  ctx.setLineDash([3, 3]);\n  ctx.beginPath();\n  ctx.moveTo(state.snapX + 0.5, 0);\n  ctx.lineTo(state.snapX + 0.5, state.viewportHeight);\n  ctx.stroke();\n  ctx.setLineDash([]);\n}\n\n// ---- utilities ------------------------------------------------------------\n\n// ---- scrollbars -----------------------------------------------------------\n\n/**\n * Right-edge vertical scrollbar. Opacity is host-controlled (set by\n * Timeline based on time-since-interaction + hover). Thumb position\n * and length derive from scrollTop / contentHeight / visibleHeight.\n */\nfunction drawScrollbarV(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  if (state.scrollbarOpacityY <= 0.01) return;\n  const visibleH = state.viewportHeight - RULER_HEIGHT - SCROLLBAR_THICKNESS;\n  const contentH = contentHeight(state.project.tracks, state.isDragging);\n  if (contentH <= visibleH) return;\n  const trackX = state.viewportWidth - SCROLLBAR_THICKNESS + SCROLLBAR_INSET;\n  const trackY0 = RULER_HEIGHT + SCROLLBAR_INSET;\n  const trackLen = visibleH - SCROLLBAR_INSET * 2;\n  const thumbLen = Math.max(\n    SCROLLBAR_MIN_THUMB,\n    trackLen * (visibleH / contentH),\n  );\n  const maxScroll = contentH - visibleH;\n  const thumbY =\n    trackY0 + (maxScroll > 0 ? (state.scrollTop / maxScroll) * (trackLen - thumbLen) : 0);\n  paintScrollbar(\n    ctx,\n    style,\n    trackX,\n    trackY0,\n    SCROLLBAR_THICKNESS - SCROLLBAR_INSET * 2,\n    trackLen,\n    thumbY - trackY0,\n    thumbLen,\n    state.scrollbarOpacityY,\n    state.scrollbarActiveY,\n    \"v\",\n  );\n}\n\nfunction drawScrollbarH(\n  ctx: CanvasRenderingContext2D,\n  state: DrawState,\n  style: DrawStyle,\n): void {\n  if (state.scrollbarOpacityX <= 0.01) return;\n  const baseX = contentLeftX(state.showHeader);\n  const visibleW = state.viewportWidth - baseX - SCROLLBAR_THICKNESS;\n  const contentW = contentWidth(state.project, state.pxPerSec);\n  if (contentW <= visibleW) return;\n  const trackY0 = state.viewportHeight - SCROLLBAR_THICKNESS + SCROLLBAR_INSET;\n  const trackX0 = baseX + SCROLLBAR_INSET;\n  const trackLen = visibleW - SCROLLBAR_INSET * 2;\n  const thumbLen = Math.max(\n    SCROLLBAR_MIN_THUMB,\n    trackLen * (visibleW / contentW),\n  );\n  const maxScroll = contentW - visibleW;\n  const thumbX =\n    trackX0 + (maxScroll > 0 ? (state.scrollLeft / maxScroll) * (trackLen - thumbLen) : 0);\n  paintScrollbar(\n    ctx,\n    style,\n    trackX0,\n    trackY0,\n    trackLen,\n    SCROLLBAR_THICKNESS - SCROLLBAR_INSET * 2,\n    thumbX - trackX0,\n    thumbLen,\n    state.scrollbarOpacityX,\n    state.scrollbarActiveX,\n    \"h\",\n  );\n}\n\n/**\n * Common drawing for both scrollbars. The thumb fades with `opacity`;\n * `active` (dragging) emphasizes via thicker stroke. Gutter is a\n * subtle background — visible to suggest \"you can grab here\" but\n * never loud enough to fight clip content.\n */\nfunction paintScrollbar(\n  ctx: CanvasRenderingContext2D,\n  style: DrawStyle,\n  trackX: number,\n  trackY0: number,\n  trackW: number,\n  trackH: number,\n  thumbOffset: number,\n  thumbLen: number,\n  opacity: number,\n  active: boolean,\n  axis: \"h\" | \"v\",\n): void {\n  ctx.save();\n  ctx.globalAlpha = opacity;\n  // Gutter — barely visible track lane.\n  ctx.fillStyle = withAlpha(style.text, 0.06);\n  roundRect(ctx, trackX, trackY0, trackW, trackH, Math.min(trackW, trackH) / 2);\n  ctx.fill();\n  // Thumb — neutral by default, info-tinted when actively dragged.\n  ctx.fillStyle = active\n    ? withAlpha(style.info, 0.85)\n    : withAlpha(style.text, 0.4);\n  if (axis === \"v\") {\n    roundRect(ctx, trackX, trackY0 + thumbOffset, trackW, thumbLen, trackW / 2);\n  } else {\n    roundRect(ctx, trackX + thumbOffset, trackY0, thumbLen, trackH, trackH / 2);\n  }\n  ctx.fill();\n  ctx.restore();\n}\n\nfunction roundRect(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  w: number,\n  h: number,\n  r: number,\n): void {\n  const rr = Math.min(r, w / 2, h / 2);\n  ctx.beginPath();\n  ctx.moveTo(x + rr, y);\n  ctx.lineTo(x + w - rr, y);\n  ctx.quadraticCurveTo(x + w, y, x + w, y + rr);\n  ctx.lineTo(x + w, y + h - rr);\n  ctx.quadraticCurveTo(x + w, y + h, x + w - rr, y + h);\n  ctx.lineTo(x + rr, y + h);\n  ctx.quadraticCurveTo(x, y + h, x, y + h - rr);\n  ctx.lineTo(x, y + rr);\n  ctx.quadraticCurveTo(x, y, x + rr, y);\n  ctx.closePath();\n}\n\n/** color-mix substitute that works directly on hex/rgba strings via\n * canvas — quick & dirty: parse-or-pass-through. For named css colors\n * we fall back to the original. Good enough for our palette. */\nfunction mix(a: string, b: string, t: number): string {\n  const ca = parseColor(a);\n  const cb = parseColor(b);\n  if (!ca || !cb) return a;\n  const r = Math.round(ca[0] + (cb[0] - ca[0]) * (1 - t));\n  const g = Math.round(ca[1] + (cb[1] - ca[1]) * (1 - t));\n  const bl = Math.round(ca[2] + (cb[2] - ca[2]) * (1 - t));\n  return `rgb(${r}, ${g}, ${bl})`;\n}\n\nfunction withAlpha(color: string, alpha: number): string {\n  const c = parseColor(color);\n  if (!c) return color;\n  return `rgba(${c[0]}, ${c[1]}, ${c[2]}, ${alpha})`;\n}\n\nfunction parseColor(s: string): [number, number, number] | null {\n  if (s.startsWith(\"#\")) {\n    const hex = s.slice(1);\n    if (hex.length === 3) {\n      return [\n        parseInt(hex[0]! + hex[0]!, 16),\n        parseInt(hex[1]! + hex[1]!, 16),\n        parseInt(hex[2]! + hex[2]!, 16),\n      ];\n    }\n    if (hex.length === 6) {\n      return [\n        parseInt(hex.slice(0, 2), 16),\n        parseInt(hex.slice(2, 4), 16),\n        parseInt(hex.slice(4, 6), 16),\n      ];\n    }\n  }\n  const m = s.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n  if (m) return [Number(m[1]), Number(m[2]), Number(m[3])];\n  return null;\n}\n\n/**\n * Cluster per-property keyframes by clip-local time. Two keyframes\n * within `epsilonMs` are considered the same \"moment\" (a UX concept\n * — the user thinks of \"this point in time\" as a single keyframe\n * regardless of which props are pinned). Used for one-diamond-per-\n * moment rendering and for moment-aware hit-testing.\n */\nexport function groupKeyframesByTime(\n  kfs: Keyframe[],\n  epsilonMs: number,\n): Array<{ time: number; kfs: Keyframe[] }> {\n  const sorted = [...kfs].sort((a, b) => a.time - b.time);\n  const out: Array<{ time: number; kfs: Keyframe[] }> = [];\n  for (const k of sorted) {\n    const last = out[out.length - 1];\n    if (last && Math.abs(k.time - last.time) < epsilonMs) {\n      last.kfs.push(k);\n    } else {\n      out.push({ time: k.time, kfs: [k] });\n    }\n  }\n  return out;\n}\n","import type { Project } from \"../types.js\";\nimport {\n  HANDLE_PX,\n  HEADER_WIDTH,\n  RULER_HEIGHT,\n  SCROLLBAR_INSET,\n  SCROLLBAR_MIN_THUMB,\n  SCROLLBAR_THICKNESS,\n  TRACK_HEIGHT,\n  contentHeight,\n  contentLeftX,\n  contentWidth,\n  trackIndexAt,\n  trackY,\n  xToMs,\n} from \"./layout.js\";\n\nexport type HitTarget =\n  | { kind: \"ruler\" }\n  | { kind: \"header\"; trackIndex: number }\n  | { kind: \"header-delete\"; trackIndex: number }\n  | { kind: \"track-empty\"; trackIndex: number }\n  | { kind: \"clip\"; trackIndex: number; clipId: string }\n  | { kind: \"clip-handle-left\"; trackIndex: number; clipId: string }\n  | { kind: \"clip-handle-right\"; trackIndex: number; clipId: string }\n  | { kind: \"keyframe\"; trackIndex: number; clipId: string; keyframeId: string }\n  | { kind: \"phantom-new-track\" }\n  /** Drag the thumb itself — caller stores pointerStart + scrollStart. */\n  | { kind: \"scrollbar-thumb-v\"; thumbY: number; thumbLen: number }\n  | { kind: \"scrollbar-thumb-h\"; thumbX: number; thumbLen: number }\n  /** Click the gutter (anywhere on the bar that isn't the thumb) →\n   *  page-jump by one viewport in the direction of the click. */\n  | { kind: \"scrollbar-track-v\"; before: boolean }\n  | { kind: \"scrollbar-track-h\"; before: boolean }\n  | { kind: \"outside\" };\n\nexport interface HitContext {\n  project: Project;\n  pxPerSec: number;\n  scrollLeft: number;\n  scrollTop: number;\n  showHeader: boolean;\n  viewportWidth: number;\n  viewportHeight: number;\n  isDragging: boolean;\n  /** When true, hit-test keyframe diamonds before the broad clip body. */\n  keyframesEnabled: boolean;\n}\n\n/** Pixel half-width of the keyframe diamond hit zone — generous so a\n *  small target is easy to grab even at low zoom. */\n/**\n * Hit radius for keyframe diamonds. Visual diamond is 10×10 px, so a\n * 12 px radius makes the kf reliably grabbable even when the cursor\n * lands a few px off-center — without it, a near-miss click slips\n * through to clip-drag and the user thinks \"the diamond vanished\n * when I tried to drag it\" (the dim source clip used to skip drawing\n * its keyframes, compounding the perception). Compromise: trim\n * handles get crowded out a little further, but trim is its own\n * dedicated edge with bigger hit zones.\n */\nconst KEYFRAME_HIT_RADIUS = 12;\n\n/**\n * Pixel → semantic target. Branches in roughly this order:\n *   1. Ruler band (top RULER_HEIGHT px) → scrub\n *   2. Header column (left HEADER_WIDTH px, when visible) → track header\n *   3. Track row contents → clip body / edge handle / empty space\n *\n * The handle-edge check is generous (HANDLE_PX) so users can grab a\n * trim handle even on a clip that's only a few px wide at low zoom.\n */\nexport function hitTest(x: number, y: number, ctx: HitContext): HitTarget {\n  if (y < 0 || x < 0) return { kind: \"outside\" };\n\n  // ---- Scrollbars first ----------------------------------------------\n  // The bars overlay everything else, so a click on the thumb must NEVER\n  // fall through to \"select clip\" / \"seek\". Check them before any other\n  // region resolves.\n  const baseX = contentLeftX(ctx.showHeader);\n  const visibleH = ctx.viewportHeight - RULER_HEIGHT - SCROLLBAR_THICKNESS;\n  const contentH = contentHeight(ctx.project.tracks, ctx.isDragging);\n  // Vertical bar\n  if (\n    contentH > visibleH &&\n    x >= ctx.viewportWidth - SCROLLBAR_THICKNESS &&\n    x < ctx.viewportWidth &&\n    y >= RULER_HEIGHT &&\n    y < ctx.viewportHeight - SCROLLBAR_THICKNESS\n  ) {\n    const trackLen = visibleH - SCROLLBAR_INSET * 2;\n    const thumbLen = Math.max(\n      SCROLLBAR_MIN_THUMB,\n      trackLen * (visibleH / contentH),\n    );\n    const maxScroll = contentH - visibleH;\n    const thumbY =\n      RULER_HEIGHT +\n      SCROLLBAR_INSET +\n      (maxScroll > 0 ? (ctx.scrollTop / maxScroll) * (trackLen - thumbLen) : 0);\n    if (y >= thumbY && y <= thumbY + thumbLen) {\n      return { kind: \"scrollbar-thumb-v\", thumbY, thumbLen };\n    }\n    return { kind: \"scrollbar-track-v\", before: y < thumbY };\n  }\n  // Horizontal bar\n  const visibleW = ctx.viewportWidth - baseX - SCROLLBAR_THICKNESS;\n  const contentW = contentWidth(ctx.project, ctx.pxPerSec);\n  if (\n    contentW > visibleW &&\n    y >= ctx.viewportHeight - SCROLLBAR_THICKNESS &&\n    y < ctx.viewportHeight &&\n    x >= baseX &&\n    x < ctx.viewportWidth - SCROLLBAR_THICKNESS\n  ) {\n    const trackLen = visibleW - SCROLLBAR_INSET * 2;\n    const thumbLen = Math.max(\n      SCROLLBAR_MIN_THUMB,\n      trackLen * (visibleW / contentW),\n    );\n    const maxScroll = contentW - visibleW;\n    const thumbX =\n      baseX +\n      SCROLLBAR_INSET +\n      (maxScroll > 0\n        ? (ctx.scrollLeft / maxScroll) * (trackLen - thumbLen)\n        : 0);\n    if (x >= thumbX && x <= thumbX + thumbLen) {\n      return { kind: \"scrollbar-thumb-h\", thumbX, thumbLen };\n    }\n    return { kind: \"scrollbar-track-h\", before: x < thumbX };\n  }\n\n  if (ctx.showHeader && x < HEADER_WIDTH && y >= RULER_HEIGHT) {\n    const ti = trackIndexAt(y, ctx.project.tracks.length, ctx.scrollTop);\n    if (ti >= 0) {\n      const track = ctx.project.tracks[ti]!;\n      if (track.clips.length === 0) {\n        const btnSize = 18;\n        const btnLeft = HEADER_WIDTH - btnSize - 6;\n        // Header rows are translated by -scrollTop when painted, so\n        // their visible top in viewport coords is `trackY(i) - scrollTop`.\n        const btnTop =\n          RULER_HEIGHT +\n          ti * TRACK_HEIGHT +\n          (TRACK_HEIGHT - btnSize) / 2 -\n          ctx.scrollTop;\n        if (\n          x >= btnLeft &&\n          x <= btnLeft + btnSize &&\n          y >= btnTop &&\n          y <= btnTop + btnSize\n        ) {\n          return { kind: \"header-delete\", trackIndex: ti };\n        }\n      }\n      return { kind: \"header\", trackIndex: ti };\n    }\n    return { kind: \"outside\" };\n  }\n\n  if (y < RULER_HEIGHT) return { kind: \"ruler\" };\n\n  const ti = trackIndexAt(y, ctx.project.tracks.length, ctx.scrollTop);\n  if (ti < 0) return { kind: \"outside\" };\n  const track = ctx.project.tracks[ti]!;\n  const ms = xToMs(x, ctx.pxPerSec, ctx.scrollLeft, ctx.showHeader);\n\n  // Pass 1 — when keyframes mode is on, scan every clip on the row\n  // for a diamond within KEYFRAME_HIT_RADIUS. Done BEFORE the per-\n  // clip handle / body pass because:\n  //   - A keyframe at the clip's start (clip-local time = 0) sits\n  //     exactly on top of the trim handle's hit zone. Without\n  //     priority here, the handle wins and the keyframe becomes\n  //     unclickable. Common case: user pins the opening pose with\n  //     keyframe at t=0 — exactly what the toolbar button creates.\n  //   - The hit radius (8 px) can also extend slightly outside the\n  //     clip body (e.g. into a small inter-clip gap), so checking\n  //     before the \"ms inside clip\" branch keeps the kf clickable\n  //     near edges.\n  // Trade-off: while keyframes mode is enabled, dragging the trim\n  // handle of a clip with a kf at t=0 needs you to grab a kf-free\n  // spot first. Acceptable since keyframe editing is the active mode.\n  if (ctx.keyframesEnabled) {\n    for (const clip of track.clips) {\n      if (!clip.keyframes || clip.keyframes.length === 0) continue;\n      const startX = msToXLocal(clip.start, ctx);\n      for (const kf of clip.keyframes) {\n        const kfX = startX + (kf.time / 1000) * ctx.pxPerSec;\n        if (Math.abs(x - kfX) <= KEYFRAME_HIT_RADIUS) {\n          return {\n            kind: \"keyframe\",\n            trackIndex: ti,\n            clipId: clip.id,\n            keyframeId: kf.id,\n          };\n        }\n      }\n    }\n  }\n\n  // Pass 2 — clip handles + body. Same logic as before.\n  for (const clip of track.clips) {\n    const start = clip.start;\n    const end = clip.start + (clip.out - clip.in);\n    const startX = msToXLocal(start, ctx);\n    const endX = msToXLocal(end, ctx);\n\n    if (x >= startX - HANDLE_PX && x <= startX + HANDLE_PX) {\n      return { kind: \"clip-handle-left\", trackIndex: ti, clipId: clip.id };\n    }\n    if (x >= endX - HANDLE_PX && x <= endX + HANDLE_PX) {\n      return { kind: \"clip-handle-right\", trackIndex: ti, clipId: clip.id };\n    }\n    if (ms >= start && ms < end) {\n      return { kind: \"clip\", trackIndex: ti, clipId: clip.id };\n    }\n  }\n  return { kind: \"track-empty\", trackIndex: ti };\n}\n\nfunction msToXLocal(ms: number, ctx: HitContext): number {\n  return contentLeftX(ctx.showHeader) + (ms / 1000) * ctx.pxPerSec - ctx.scrollLeft;\n}\n","import { type Locale, mergeLocale } from \"../i18n.js\";\nimport { applyTheme } from \"../theme.js\";\nimport type { Theme } from \"../types.js\";\nimport {\n  bigFrameStepMs,\n  frameStepMs,\n  normalizeProject,\n  projectDuration,\n} from \"../model.js\";\nimport type { Clip, Ms, Project } from \"../types.js\";\nimport { ThumbnailRibbon } from \"../ui/thumbnails.js\";\nimport {\n  drawAll,\n  type DrawState,\n  type DrawStyle,\n} from \"./draw.js\";\nimport { hitTest, type HitTarget } from \"./hit.js\";\nimport {\n  HEADER_WIDTH,\n  RULER_HEIGHT,\n  SCROLLBAR_INSET,\n  SCROLLBAR_MIN_THUMB,\n  SCROLLBAR_THICKNESS,\n  TIMELINE_PAD_RIGHT,\n  TRACK_HEIGHT,\n  clampScale,\n  contentHeight,\n  contentLeftX,\n  contentWidth,\n  findClip,\n  snapTargets,\n  trackIndexAt,\n  wouldOverlap,\n  xToMs,\n} from \"./layout.js\";\n\n/**\n * Public options for the standalone `Timeline` component. The class\n * is framework-agnostic — `@aicut/react` and `@aicut/vue` wrap it,\n * and the built-in `Editor` composes one internally for its timeline\n * panel. Reuse the same instance for a \"frame-picker\" use case by\n * loading a project with a single video clip and `readOnly: true`.\n */\nexport interface TimelineOptions {\n  /** Host element. Will be wiped on init. */\n  container: HTMLElement;\n  project: Project;\n  /** Pixels per second. Defaults to 80; auto-fits on mount when possible. */\n  pxPerSec?: number;\n  /** Initial playhead position. */\n  time?: Ms;\n  /** Initially selected clip. */\n  selectedClipId?: string | null;\n  /** Show the track-name header column (left). Default true. */\n  showHeader?: boolean;\n  /**\n   * Minimum pixel gap between ruler major ticks. Drives the auto\n   * picker via `niceTickSeconds(minPx / pxPerSec)` — smaller values\n   * pack more labels per zoom level, larger values space them out.\n   * Default 80; sensible range ~40–160.\n   */\n  rulerMinTickPx?: number;\n  /** Disable interactions — useful for read-only preview / frame picker. */\n  readOnly?: boolean;\n  /** Snap to clip edges + playhead when dragging. Default true. */\n  snap?: boolean;\n  /** Compute and apply fit-to-window on first project change. Default true. */\n  autoFit?: boolean;\n  /** UI string overrides (English defaults). Use `localeZh` for Chinese. */\n  locale?: Partial<Locale>;\n  /**\n   * Theme tokens — applied as `--aicut-*` CSS variables on the host\n   * container. Same shape as the video Editor's `theme` option, so a\n   * host can pass the SAME object to both an Editor and a standalone\n   * Timeline. Reactive via `setTheme(...)`. */\n  theme?: Theme;\n  /**\n   * Render an empty 36px toolbar strip at the top of the host element\n   * with `toolbarLeft` / `toolbarRight` flex slots. The library paints\n   * NOTHING into either slot — hosts append their own controls (an\n   * export button, a size/aspect dropdown, etc.). Default false; the\n   * canvas takes the full host height when the toolbar is off, so\n   * adopting the slot later is a non-breaking opt-in.\n   */\n  toolbar?: boolean;\n\n  onSeek?: (timeMs: Ms) => void;\n  onSelectClip?: (clipId: string | null) => void;\n  onScaleChange?: (pxPerSec: number) => void;\n  onDeleteTrack?: (trackId: string) => void;\n  onMoveClip?: (\n    clipId: string,\n    opts: { start?: Ms; trackId?: string; newTrack?: boolean },\n  ) => void;\n  onResizeClip?: (\n    clipId: string,\n    edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>,\n  ) => void;\n  onChange?: (project: Project) => void;\n\n  /**\n   * Hosts wire these to forward keyframe edits to the Editor. The\n   * Timeline only paints + hit-tests; mutation goes through these\n   * callbacks so the Editor can push history + emit events.\n   */\n  onSelectKeyframe?: (\n    target: { clipId: string; keyframeId: string } | null,\n  ) => void;\n  onMoveKeyframe?: (\n    clipId: string,\n    keyframeId: string,\n    timeMs: Ms,\n  ) => void;\n\n  /** Host-driven state mirror — Editor passes these on every render\n   *  via `Timeline.setKeyframeState`. */\n  keyframesEnabled?: boolean;\n  selectedKeyframe?: { clipId: string; keyframeId: string } | null;\n\n  /**\n   * Lets the host predict where a drop will actually land — used to\n   * keep the drag-ghost visual honest. The Editor wires this to its\n   * smart routing (intended → source → other → new track), so the\n   * ghost shows the real outcome rather than just the user's hover.\n   *\n   * Return `{ trackIndex }` for an existing track, or\n   * `{ wouldCreateNew: true }` for the auto-split case.\n   */\n  resolveDrop?: (\n    clipId: string,\n    intent: { start: Ms; intendedTrackIndex: number },\n  ) => { trackIndex: number; wouldCreateNew: boolean };\n}\n\ninterface DragMove {\n  kind: \"move\";\n  clipId: string;\n  trackIndex: number;\n  pointerStartX: number;\n  pointerStartY: number;\n  originalStart: Ms;\n}\ninterface DragTrim {\n  kind: \"trim-left\" | \"trim-right\";\n  clipId: string;\n  trackIndex: number;\n  pointerStartX: number;\n  originalStart: Ms;\n  originalIn: Ms;\n  originalOut: Ms;\n}\ninterface DragScrub {\n  kind: \"scrub\";\n}\ninterface DragKeyframe {\n  kind: \"keyframe-drag\";\n  clipId: string;\n  keyframeId: string;\n  trackIndex: number;\n  pointerStartX: number;\n  originalTimeMs: Ms;\n  /** Latest snapped time during the drag — committed once on pointer-up\n   *  so the history stack records one entry per drag, not one per\n   *  rAF tick. Draw uses this to render the ghost position. */\n  ghostTimeMs: Ms;\n}\ntype DragCtx = DragMove | DragTrim | DragScrub | DragKeyframe;\n\nconst SNAP_PX = 8;\nconst DEFAULT_SCALE = 80;\nconst WHEEL_ZOOM_RATE = 0.012;\nconst SCROLLBAR_FADE_HOLD_MS = 800;\nconst SCROLLBAR_FADE_OUT_MS = 400;\n\n/**\n * Canvas-rendered, framework-free timeline. Owns ruler, multi-track\n * layout, headers, frame-thumbnails, playhead, snap, and all pointer\n * gestures. No DOM children for clips/ticks/etc — every pixel is\n * painted via 2D canvas, so even hundreds of clips render in <2ms.\n */\nexport class Timeline {\n  private root: HTMLElement;\n  private opts: TimelineOptions;\n  private canvas: HTMLCanvasElement;\n  private ctx: CanvasRenderingContext2D;\n  private thumbs: ThumbnailRibbon;\n  private hiddenHost: HTMLDivElement;\n  private toolbarEl: HTMLDivElement | null = null;\n  /**\n   * Public flex slot at the left of the top toolbar. `null` when\n   * `toolbar` is disabled. Hosts append their own elements (e.g. a\n   * size/aspect dropdown). React/Vue wrappers portal children here.\n   */\n  readonly toolbarLeft: HTMLDivElement | null = null;\n  /** Right-side counterpart — conventionally used for export/save. */\n  readonly toolbarRight: HTMLDivElement | null = null;\n\n  private project: Project;\n  private pxPerSec: number;\n  private timeMs: Ms;\n  private selectedClipId: string | null;\n  private snapEnabled: boolean;\n  private showHeader: boolean;\n  private readOnly: boolean;\n  private autoFitEnabled: boolean;\n  private locale: Locale;\n  private rulerMinTickPx: number;\n  private keyframesEnabled = false;\n  private selectedKeyframe:\n    | { clipId: string; keyframeId: string }\n    | null = null;\n\n  private scrollLeft = 0;\n  private scrollTop = 0;\n  private viewportWidth = 0;\n  private viewportHeight = 0;\n  /**\n   * `Date.now()` of the last interaction with each scrollbar (scroll\n   * change OR hover OR drag). Drives the macOS-style fade — bars are\n   * fully opaque for SCROLLBAR_FADE_HOLD_MS after activity, then ease\n   * out over the next SCROLLBAR_FADE_OUT_MS.\n   */\n  private lastScrollInteractY = 0;\n  private lastScrollInteractX = 0;\n  private hoverScrollbarY = false;\n  private hoverScrollbarX = false;\n  /** When set, pointer is dragging a scrollbar thumb. */\n  private scrollbarDrag: {\n    axis: \"v\" | \"h\";\n    pointerStart: number;\n    scrollStart: number;\n  } | null = null;\n  private hoveredClipId: string | null = null;\n  private hoveredTrackIndex: number | null = null;\n  private hoveredKeyframe:\n    | { clipId: string; keyframeId: string }\n    | null = null;\n  private hoverCursor: string = \"default\";\n  private dropTargetTrackIndex: number | null = null;\n  private snapX: number | null = null;\n  private drag: DragCtx | null = null;\n  /**\n   * In-flight ghost of the clip being dragged. Decoupled from the\n   * project data so the data stays clean and undo-able only commits\n   * on release. Has both the proposed `start` (X) and `trackIndex`\n   * (Y), so the rendered ghost follows the cursor across tracks.\n   */\n  private dragGhost: {\n    clipId: string;\n    ghostStart: Ms;\n    ghostTrackIndex: number;\n    wouldOverlap: boolean;\n  } | null = null;\n  /**\n   * Most recent local pointer coords during a move drag — used by the\n   * edge-autoscroll loop to re-run drop-target resolution between\n   * pointermove events while scrollTop ticks under a stationary cursor.\n   */\n  private lastDragPointerX = 0;\n  private lastDragPointerY = 0;\n  private dragScrollRafPending = false;\n  private rafPending = false;\n  private hasAutoFitted = false;\n  private resizeObs: ResizeObserver | null = null;\n  private destroyed = false;\n\n  static create(opts: TimelineOptions): Timeline {\n    return new Timeline(opts);\n  }\n\n  constructor(opts: TimelineOptions) {\n    this.opts = opts;\n    this.root = opts.container;\n    this.project = normalizeProject(opts.project);\n    this.pxPerSec = clampScale(opts.pxPerSec ?? DEFAULT_SCALE);\n    this.timeMs = opts.time ?? 0;\n    this.selectedClipId = opts.selectedClipId ?? null;\n    this.snapEnabled = opts.snap !== false;\n    this.showHeader = opts.showHeader !== false;\n    this.readOnly = opts.readOnly === true;\n    this.autoFitEnabled = opts.autoFit !== false;\n    this.locale = mergeLocale(opts.locale);\n    this.rulerMinTickPx = opts.rulerMinTickPx ?? 80;\n    this.keyframesEnabled = opts.keyframesEnabled === true;\n    this.selectedKeyframe = opts.selectedKeyframe ?? null;\n\n    this.root.classList.add(\"aicut-timeline-canvas\");\n    this.root.innerHTML = \"\";\n    this.root.style.position = this.root.style.position || \"relative\";\n    applyTheme(this.root, opts.theme);\n\n    // Toolbar strip — opt-in. When enabled the root becomes a flex\n    // column so the toolbar reserves vertical space and the canvas\n    // gets whatever's left via flex:1. When off, the canvas keeps\n    // its old 100%-height layout — zero-cost for existing callers.\n    if (opts.toolbar) {\n      this.root.style.display = \"flex\";\n      this.root.style.flexDirection = \"column\";\n      const bar = document.createElement(\"div\");\n      bar.className = \"aicut-timeline-toolbar\";\n      const left = document.createElement(\"div\");\n      left.className = \"aicut-timeline-toolbar-left\";\n      const right = document.createElement(\"div\");\n      right.className = \"aicut-timeline-toolbar-right\";\n      bar.appendChild(left);\n      bar.appendChild(right);\n      this.root.appendChild(bar);\n      this.toolbarEl = bar;\n      (this as { toolbarLeft: HTMLDivElement | null }).toolbarLeft = left;\n      (this as { toolbarRight: HTMLDivElement | null }).toolbarRight = right;\n    }\n\n    this.canvas = document.createElement(\"canvas\");\n    this.canvas.style.display = \"block\";\n    this.canvas.style.width = \"100%\";\n    if (opts.toolbar) {\n      // Flex child: take remaining height; min-height:0 lets us shrink\n      // below content size when the host is constrained.\n      this.canvas.style.flex = \"1 1 0\";\n      this.canvas.style.minHeight = \"0\";\n    } else {\n      this.canvas.style.height = \"100%\";\n    }\n    this.canvas.style.touchAction = \"none\";\n    // No data-testid on the canvas itself — both the editor's and a\n    // standalone frame-picker timeline would collide. Tests select via\n    // the host element instead (e.g. `[data-testid=\"aicut-timeline\"] canvas`).\n    this.root.appendChild(this.canvas);\n\n    const ctx = this.canvas.getContext(\"2d\");\n    if (!ctx) throw new Error(\"2d context unavailable\");\n    this.ctx = ctx;\n\n    // Off-screen <video> elements for thumbnail extraction live here.\n    this.hiddenHost = document.createElement(\"div\");\n    this.hiddenHost.style.position = \"absolute\";\n    this.hiddenHost.style.overflow = \"hidden\";\n    this.hiddenHost.style.width = \"0\";\n    this.hiddenHost.style.height = \"0\";\n    this.hiddenHost.style.pointerEvents = \"none\";\n    this.root.appendChild(this.hiddenHost);\n\n    this.thumbs = new ThumbnailRibbon(this.hiddenHost, () =>\n      this.scheduleRender(),\n    );\n    this.thumbs.syncSources(this.project.sources);\n\n    this.attachPointer();\n    this.attachWheel();\n    this.attachKeyboard();\n    this.attachResize();\n    this.resizeCanvas();\n    this.scheduleRender();\n  }\n\n  // ---- public API -----------------------------------------------------\n\n  /**\n   * Sync the project data. Does NOT reset the auto-fit latch — that's\n   * what caused the editor-side zoom feedback loop: every Editor\n   * mutation called `ui.render() → timeline.setProject()` which used\n   * to reset auto-fit, refit on the next frame, emit a new scale,\n   * which re-rendered… and round we went. Callers that genuinely\n   * want a re-fit (e.g. when the host swaps to a brand-new project)\n   * should call `refit()` explicitly.\n   */\n  setProject(p: Project): void {\n    this.project = normalizeProject(p);\n    this.thumbs.syncSources(this.project.sources);\n    this.scheduleRender();\n  }\n\n  /** Force a re-fit on the next render. */\n  refit(): void {\n    if (!this.autoFitEnabled) return;\n    this.hasAutoFitted = false;\n    this.scheduleRender();\n  }\n\n  getProject(): Project {\n    return JSON.parse(JSON.stringify(this.project)) as Project;\n  }\n\n  setTime(timeMs: Ms): void {\n    this.timeMs = Math.max(0, timeMs);\n    this.scheduleRender();\n  }\n\n  getTime(): Ms {\n    return this.timeMs;\n  }\n\n  setScale(pxPerSec: number): void {\n    const next = clampScale(pxPerSec);\n    if (next === this.pxPerSec) return;\n    this.pxPerSec = next;\n    this.hasAutoFitted = true;\n    this.scheduleRender();\n  }\n\n  getScale(): number {\n    return this.pxPerSec;\n  }\n\n  setSelection(id: string | null): void {\n    if (id === this.selectedClipId) return;\n    this.selectedClipId = id;\n    this.scheduleRender();\n  }\n\n  getSelection(): string | null {\n    return this.selectedClipId;\n  }\n\n  setSnap(snap: boolean): void {\n    this.snapEnabled = snap;\n  }\n\n  getSnap(): boolean {\n    return this.snapEnabled;\n  }\n\n  setLocale(locale: Partial<Locale>): void {\n    this.locale = mergeLocale(locale);\n    this.scheduleRender();\n  }\n\n  setRulerMinTickPx(px: number): void {\n    if (px === this.rulerMinTickPx) return;\n    this.rulerMinTickPx = Math.max(20, Math.round(px));\n    this.scheduleRender();\n  }\n\n  /** Swap the theme tokens at runtime. Same Theme shape as the video\n   *  Editor's `setTheme`. */\n  setTheme(theme: Theme): void {\n    applyTheme(this.root, theme);\n    // Force a re-paint — the canvas reads CSS vars at draw time and\n    // caches them into pixels, so without this the timeline keeps its\n    // old colours until the next mouse move / scroll / focus interaction.\n    this.scheduleRender();\n  }\n\n  /** Fit the project's full duration into the current viewport width. */\n  fitToWindow(): void {\n    const fit = this.computeFitScale();\n    if (fit == null) return;\n    this.pxPerSec = fit;\n    this.hasAutoFitted = true;\n    this.scrollLeft = 0;\n    this.opts.onScaleChange?.(this.pxPerSec);\n    this.scheduleRender();\n  }\n\n  /**\n   * Test/debug introspection — pixel coordinates of every visible clip,\n   * the playhead, and the headers. Because clips are canvas-painted\n   * there are no DOM nodes to query in e2e; tests use this instead.\n   * Exposed publicly so React/Vue wrappers can forward it to a ref.\n   */\n  getDebugInfo(): {\n    pxPerSec: number;\n    scrollLeft: number;\n    viewportWidth: number;\n    viewportHeight: number;\n    playheadX: number;\n    clips: Array<{\n      id: string;\n      trackIndex: number;\n      x: number;\n      width: number;\n      y: number;\n      height: number;\n    }>;\n  } {\n    const baseX = contentLeftX(this.showHeader);\n    const clips: Array<{\n      id: string;\n      trackIndex: number;\n      x: number;\n      width: number;\n      y: number;\n      height: number;\n    }> = [];\n    for (let ti = 0; ti < this.project.tracks.length; ti++) {\n      const t = this.project.tracks[ti]!;\n      for (const c of t.clips) {\n        const x = baseX + (c.start / 1000) * this.pxPerSec - this.scrollLeft;\n        const width = ((c.out - c.in) / 1000) * this.pxPerSec;\n        const y = RULER_HEIGHT + ti * TRACK_HEIGHT + 6;\n        clips.push({\n          id: c.id,\n          trackIndex: ti,\n          x,\n          width,\n          y,\n          height: TRACK_HEIGHT - 12,\n        });\n      }\n    }\n    return {\n      pxPerSec: this.pxPerSec,\n      scrollLeft: this.scrollLeft,\n      viewportWidth: this.viewportWidth,\n      viewportHeight: this.viewportHeight,\n      playheadX:\n        baseX + (this.timeMs / 1000) * this.pxPerSec - this.scrollLeft,\n      clips,\n    };\n  }\n\n  destroy(): void {\n    if (this.destroyed) return;\n    this.destroyed = true;\n    this.resizeObs?.disconnect();\n    this.thumbs.destroy();\n    this.root.innerHTML = \"\";\n    this.root.classList.remove(\"aicut-timeline-canvas\");\n    if (this.opts.toolbar) {\n      this.root.style.display = \"\";\n      this.root.style.flexDirection = \"\";\n    }\n  }\n\n  // ---- size / layout --------------------------------------------------\n\n  private resizeCanvas(): void {\n    // Read the canvas's own box, not the root's — when the toolbar\n    // strip is enabled the root flex-allots part of its height to it,\n    // and the canvas's rect is the only honest source of the drawing\n    // area. With no toolbar, canvas fills root, so this still matches.\n    const rect = this.canvas.getBoundingClientRect();\n    this.viewportWidth = Math.max(1, Math.floor(rect.width));\n    this.viewportHeight = Math.max(\n      Math.floor(rect.height) || RULER_HEIGHT + TRACK_HEIGHT + SCROLLBAR_THICKNESS,\n      RULER_HEIGHT + TRACK_HEIGHT + SCROLLBAR_THICKNESS,\n    );\n    const dpr = window.devicePixelRatio || 1;\n    // canvas.width/height are the BACKING buffer (pixel) size. CSS layout\n    // size (height: 100% or flex: 1 1 0) is set once in the constructor\n    // and not touched here — writing `canvas.style.height = ${...}px`\n    // here would freeze the inline height at the value sampled on first\n    // paint, so any subsequent parent-container resize (e.g. EditorOptions\n    // timelineHeight changing reactively) leaves the canvas stuck at the\n    // original size.\n    this.canvas.width = Math.floor(this.viewportWidth * dpr);\n    this.canvas.height = Math.floor(this.viewportHeight * dpr);\n    this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n  }\n\n  private computeFitScale(): number | null {\n    const baseX = contentLeftX(this.showHeader);\n    const w = this.viewportWidth - baseX - 24;\n    const dur = projectDuration(this.project);\n    if (w <= 0 || dur <= 0) return null;\n    return clampScale(w / (dur / 1000));\n  }\n\n  private maxScrollLeft(): number {\n    const baseX = contentLeftX(this.showHeader);\n    const visibleW = this.viewportWidth - baseX - SCROLLBAR_THICKNESS;\n    const cw = contentWidth(this.project, this.pxPerSec);\n    // Tail pad keeps the right padding visible even when scrolled to\n    // the project's end, mirroring the left content padding.\n    return Math.max(0, cw - visibleW + TIMELINE_PAD_RIGHT);\n  }\n\n  private maxScrollTop(): number {\n    const visibleH =\n      this.viewportHeight - RULER_HEIGHT - SCROLLBAR_THICKNESS;\n    const ch = contentHeight(this.project.tracks, this.drag?.kind === \"move\");\n    return Math.max(0, ch - visibleH);\n  }\n\n  private clampScroll(): void {\n    this.scrollLeft = Math.max(0, Math.min(this.scrollLeft, this.maxScrollLeft()));\n    this.scrollTop = Math.max(0, Math.min(this.scrollTop, this.maxScrollTop()));\n  }\n\n  /**\n   * Scrollbar opacity = full for SCROLLBAR_FADE_HOLD_MS after last\n   * interaction, then linearly fades to 0 over SCROLLBAR_FADE_OUT_MS.\n   * Hovering or actively dragging the bar pins opacity at 1. Returns\n   * 0 if the bar isn't needed (content fits).\n   */\n  private scrollbarOpacity(axis: \"v\" | \"h\"): number {\n    if (axis === \"v\" && this.maxScrollTop() <= 0) return 0;\n    if (axis === \"h\" && this.maxScrollLeft() <= 0) return 0;\n    if (\n      (axis === \"v\" && (this.hoverScrollbarY || this.scrollbarDrag?.axis === \"v\")) ||\n      (axis === \"h\" && (this.hoverScrollbarX || this.scrollbarDrag?.axis === \"h\"))\n    ) {\n      return 1;\n    }\n    const last = axis === \"v\" ? this.lastScrollInteractY : this.lastScrollInteractX;\n    const elapsed = Date.now() - last;\n    if (elapsed < SCROLLBAR_FADE_HOLD_MS) return 1;\n    const fade = elapsed - SCROLLBAR_FADE_HOLD_MS;\n    if (fade >= SCROLLBAR_FADE_OUT_MS) return 0;\n    return 1 - fade / SCROLLBAR_FADE_OUT_MS;\n  }\n\n  /** Mark a scrollbar axis as just-touched so its fade timer restarts. */\n  private touchScrollbar(axis: \"v\" | \"h\"): void {\n    if (axis === \"v\") this.lastScrollInteractY = Date.now();\n    else this.lastScrollInteractX = Date.now();\n    this.scheduleRender();\n  }\n\n  // ---- rendering ------------------------------------------------------\n\n  private scheduleRender(): void {\n    if (this.rafPending) return;\n    this.rafPending = true;\n    requestAnimationFrame(() => {\n      this.rafPending = false;\n      if (this.destroyed) return;\n      this.maybeAutoFit();\n      this.resizeCanvas();\n      this.clampScroll();\n      drawAll(\n        this.ctx,\n        this.buildDrawState(),\n        this.readStyle(),\n        this.thumbs,\n      );\n      this.canvas.style.cursor = this.hoverCursor;\n      this.maybeContinueFade();\n    });\n  }\n\n  /**\n   * Keep the raf loop alive while a scrollbar is still in its HOLD or\n   * fade-out window. Without this, opacity is sampled once and the\n   * bar would freeze at whatever value it had at the last input event\n   * instead of smoothly fading out. Skipped when a bar is pinned\n   * (hover or active drag) since opacity is constant there.\n   */\n  private maybeContinueFade(): void {\n    const total = SCROLLBAR_FADE_HOLD_MS + SCROLLBAR_FADE_OUT_MS;\n    const now = Date.now();\n    const needV =\n      this.maxScrollTop() > 0 &&\n      !this.hoverScrollbarY &&\n      this.scrollbarDrag?.axis !== \"v\" &&\n      now - this.lastScrollInteractY < total;\n    const needH =\n      this.maxScrollLeft() > 0 &&\n      !this.hoverScrollbarX &&\n      this.scrollbarDrag?.axis !== \"h\" &&\n      now - this.lastScrollInteractX < total;\n    if (needV || needH) this.scheduleRender();\n  }\n\n  private maybeAutoFit(): void {\n    if (!this.autoFitEnabled || this.hasAutoFitted) return;\n    if (projectDuration(this.project) <= 0) return;\n    const fit = this.computeFitScale();\n    if (fit == null) return;\n    this.hasAutoFitted = true;\n    if (Math.abs(fit - this.pxPerSec) > 0.5) {\n      this.pxPerSec = fit;\n      this.opts.onScaleChange?.(fit);\n    }\n  }\n\n  private buildDrawState(): DrawState {\n    return {\n      project: this.project,\n      pxPerSec: this.pxPerSec,\n      scrollLeft: this.scrollLeft,\n      scrollTop: this.scrollTop,\n      timeMs: this.timeMs,\n      selectedClipId: this.selectedClipId,\n      hoveredClipId: this.hoveredClipId,\n      hoveredTrackIndex: this.hoveredTrackIndex,\n      dropTargetTrackIndex: this.dropTargetTrackIndex,\n      isDragging: this.drag?.kind === \"move\",\n      snapX: this.snapX,\n      showHeader: this.showHeader,\n      viewportWidth: this.viewportWidth,\n      viewportHeight: this.viewportHeight,\n      dragGhost: this.dragGhost,\n      scrollbarOpacityY: this.scrollbarOpacity(\"v\"),\n      scrollbarOpacityX: this.scrollbarOpacity(\"h\"),\n      scrollbarActiveY: this.scrollbarDrag?.axis === \"v\",\n      scrollbarActiveX: this.scrollbarDrag?.axis === \"h\",\n      locale: this.locale,\n      rulerMinTickPx: this.rulerMinTickPx,\n      keyframesEnabled: this.keyframesEnabled,\n      selectedKeyframe: this.selectedKeyframe,\n      hoveredKeyframe: this.hoveredKeyframe,\n      keyframeDragGhost:\n        this.drag?.kind === \"keyframe-drag\"\n          ? {\n              clipId: this.drag.clipId,\n              keyframeId: this.drag.keyframeId,\n              ghostTimeMs: this.drag.ghostTimeMs,\n            }\n          : null,\n    };\n  }\n\n  /** Host-pushed state — Editor calls this when its keyframe mode\n   *  changes or when a keyframe is selected/deselected externally. */\n  setKeyframeState(state: {\n    enabled?: boolean;\n    selected?: { clipId: string; keyframeId: string } | null;\n  }): void {\n    let dirty = false;\n    if (state.enabled !== undefined && state.enabled !== this.keyframesEnabled) {\n      this.keyframesEnabled = state.enabled;\n      dirty = true;\n    }\n    if (state.selected !== undefined) {\n      const a = this.selectedKeyframe;\n      const b = state.selected;\n      const same =\n        a?.clipId === b?.clipId && a?.keyframeId === b?.keyframeId;\n      if (!same) {\n        this.selectedKeyframe = b;\n        dirty = true;\n      }\n    }\n    if (dirty) this.scheduleRender();\n  }\n\n  private readStyle(): DrawStyle {\n    const cs = getComputedStyle(this.root);\n    const v = (name: string, fallback: string) =>\n      cs.getPropertyValue(name).trim() || fallback;\n    return {\n      bg: v(\"--aicut-controls-bg\", \"#1f1f22\"),\n      border: v(\"--aicut-controls-border\", \"rgba(255,255,255,0.08)\"),\n      // Pass the resolved text color straight through — draw.ts'\n      // withAlpha can adjust it for tick / muted variants.\n      text: v(\"--aicut-controls-text\", \"rgba(255,255,255,0.85)\"),\n      textMuted: v(\"--color-muted\", \"#999999\"),\n      trackBg: \"rgba(255,255,255,0.06)\",\n      brand: v(\"--color-brand\", \"#9a31f4\"),\n      brandTo: v(\"--color-secondary\", \"#9a31f4\"),\n      info: v(\"--color-info\", \"#1077ff\"),\n      clipText: \"#fff\",\n      selectedRing: v(\"--color-info\", \"#1077ff\"),\n      playhead: v(\"--color-brand\", \"#9a31f4\"),\n    };\n  }\n\n  // ---- pointer / wheel ------------------------------------------------\n\n  private attachPointer(): void {\n    this.canvas.addEventListener(\"pointerdown\", (e) => this.onPointerDown(e));\n    this.canvas.addEventListener(\"pointermove\", (e) => this.onPointerMove(e));\n    this.canvas.addEventListener(\"pointerup\", (e) => this.onPointerUp(e));\n    this.canvas.addEventListener(\"pointercancel\", (e) => this.onPointerUp(e));\n    this.canvas.addEventListener(\"pointerleave\", () => {\n      if (!this.drag && !this.scrollbarDrag) {\n        this.hoveredClipId = null;\n        this.hoveredKeyframe = null;\n        this.hoverCursor = \"default\";\n        this.hoverScrollbarY = false;\n        this.hoverScrollbarX = false;\n        this.scheduleRender();\n      }\n    });\n  }\n\n  private onPointerDown(e: PointerEvent): void {\n    const { x, y } = this.localCoords(e);\n    const target = this.hitTarget(x, y);\n    this.canvas.setPointerCapture(e.pointerId);\n\n    // Scrollbar hits are handled BEFORE readOnly / other targets so the\n    // bar works as a regular scroll affordance even in frame-picker mode.\n    if (target.kind === \"scrollbar-thumb-v\") {\n      this.scrollbarDrag = {\n        axis: \"v\",\n        pointerStart: y,\n        scrollStart: this.scrollTop,\n      };\n      this.touchScrollbar(\"v\");\n      return;\n    }\n    if (target.kind === \"scrollbar-thumb-h\") {\n      this.scrollbarDrag = {\n        axis: \"h\",\n        pointerStart: x,\n        scrollStart: this.scrollLeft,\n      };\n      this.touchScrollbar(\"h\");\n      return;\n    }\n    if (target.kind === \"scrollbar-track-v\") {\n      const page = Math.max(\n        TRACK_HEIGHT,\n        this.viewportHeight - RULER_HEIGHT - SCROLLBAR_THICKNESS,\n      );\n      this.scrollTop += target.before ? -page : page;\n      this.clampScroll();\n      this.touchScrollbar(\"v\");\n      return;\n    }\n    if (target.kind === \"scrollbar-track-h\") {\n      const baseX = contentLeftX(this.showHeader);\n      const page = Math.max(\n        80,\n        this.viewportWidth - baseX - SCROLLBAR_THICKNESS,\n      );\n      this.scrollLeft += target.before ? -page : page;\n      this.clampScroll();\n      this.touchScrollbar(\"h\");\n      return;\n    }\n\n    // Read-only mode (e.g. frame-picker) — every click in the track\n    // area becomes a seek. Drag = scrub. No selection / move / trim.\n    if (this.readOnly) {\n      if (\n        target.kind === \"ruler\" ||\n        target.kind === \"clip\" ||\n        target.kind === \"clip-handle-left\" ||\n        target.kind === \"clip-handle-right\" ||\n        target.kind === \"track-empty\"\n      ) {\n        this.drag = { kind: \"scrub\" };\n        const ms = this.applySnap(\n          xToMs(x, this.pxPerSec, this.scrollLeft, this.showHeader),\n          null,\n        );\n        this.timeMs = ms;\n        this.opts.onSeek?.(ms);\n        this.scheduleRender();\n      }\n      return;\n    }\n\n    if (target.kind === \"header-delete\") {\n      const t = this.project.tracks[target.trackIndex];\n      if (t) this.opts.onDeleteTrack?.(t.id);\n      return;\n    }\n\n    if (target.kind === \"header\") return;\n\n    if (target.kind === \"ruler\") {\n      this.drag = { kind: \"scrub\" };\n      const ms = this.applySnap(\n        xToMs(x, this.pxPerSec, this.scrollLeft, this.showHeader),\n        null,\n      );\n      this.timeMs = ms;\n      this.opts.onSeek?.(ms);\n      this.scheduleRender();\n      return;\n    }\n\n    if (target.kind === \"keyframe\") {\n      // Look up the current keyframe time (clip-local).\n      const found = findClip(this.project, target.clipId);\n      const kf = found?.clip.keyframes?.find((k) => k.id === target.keyframeId);\n      if (!found || !kf) return;\n      this.selectedKeyframe = {\n        clipId: target.clipId,\n        keyframeId: target.keyframeId,\n      };\n      this.opts.onSelectKeyframe?.({\n        clipId: target.clipId,\n        keyframeId: target.keyframeId,\n      });\n      // Also jump the playhead to the keyframe — matches CapCut. Lets\n      // the user instantly see + edit the pinned transform.\n      const absMs = found.clip.start + kf.time;\n      this.timeMs = absMs;\n      this.opts.onSeek?.(absMs);\n      this.drag = {\n        kind: \"keyframe-drag\",\n        clipId: target.clipId,\n        keyframeId: target.keyframeId,\n        trackIndex: target.trackIndex,\n        pointerStartX: x,\n        originalTimeMs: kf.time,\n        ghostTimeMs: kf.time,\n      };\n      this.scheduleRender();\n      return;\n    }\n\n    if (target.kind === \"clip\") {\n      const found = findClip(this.project, target.clipId);\n      if (!found) return;\n      this.selectedClipId = target.clipId;\n      this.opts.onSelectClip?.(target.clipId);\n      this.drag = {\n        kind: \"move\",\n        clipId: target.clipId,\n        trackIndex: target.trackIndex,\n        pointerStartX: x,\n        pointerStartY: y,\n        originalStart: found.clip.start,\n      };\n      this.scheduleRender();\n      return;\n    }\n\n    if (\n      target.kind === \"clip-handle-left\" ||\n      target.kind === \"clip-handle-right\"\n    ) {\n      const found = findClip(this.project, target.clipId);\n      if (!found) return;\n      this.selectedClipId = target.clipId;\n      this.opts.onSelectClip?.(target.clipId);\n      this.drag = {\n        kind: target.kind === \"clip-handle-left\" ? \"trim-left\" : \"trim-right\",\n        clipId: target.clipId,\n        trackIndex: target.trackIndex,\n        pointerStartX: x,\n        originalStart: found.clip.start,\n        originalIn: found.clip.in,\n        originalOut: found.clip.out,\n      };\n      this.scheduleRender();\n      return;\n    }\n\n    if (target.kind === \"track-empty\") {\n      // Bare-track click = deselect + seek to clicked time.\n      this.selectedClipId = null;\n      this.opts.onSelectClip?.(null);\n      const ms = this.applySnap(\n        xToMs(x, this.pxPerSec, this.scrollLeft, this.showHeader),\n        null,\n      );\n      this.timeMs = ms;\n      this.opts.onSeek?.(ms);\n      this.drag = { kind: \"scrub\" };\n      this.scheduleRender();\n      return;\n    }\n  }\n\n  private onPointerMove(e: PointerEvent): void {\n    const { x, y } = this.localCoords(e);\n\n    // Scrollbar thumb drag has priority — pointer delta along the bar's\n    // axis maps to a scroll delta scaled by (maxScroll / freeTrackLen).\n    // freeTrackLen is the gutter length minus the thumb length, i.e.\n    // how far the thumb can actually travel.\n    if (this.scrollbarDrag) {\n      if (this.scrollbarDrag.axis === \"v\") {\n        const visibleH =\n          this.viewportHeight - RULER_HEIGHT - SCROLLBAR_THICKNESS;\n        const contentH = contentHeight(\n          this.project.tracks,\n          this.drag?.kind === \"move\",\n        );\n        const trackLen = visibleH - SCROLLBAR_INSET * 2;\n        const thumbLen = Math.max(\n          SCROLLBAR_MIN_THUMB,\n          trackLen * (visibleH / contentH),\n        );\n        const maxScroll = Math.max(0, contentH - visibleH);\n        const free = Math.max(1, trackLen - thumbLen);\n        const ratio = maxScroll / free;\n        this.scrollTop =\n          this.scrollbarDrag.scrollStart +\n          (y - this.scrollbarDrag.pointerStart) * ratio;\n      } else {\n        const baseX = contentLeftX(this.showHeader);\n        const visibleW = this.viewportWidth - baseX - SCROLLBAR_THICKNESS;\n        const contentW = contentWidth(this.project, this.pxPerSec);\n        const trackLen = visibleW - SCROLLBAR_INSET * 2;\n        const thumbLen = Math.max(\n          SCROLLBAR_MIN_THUMB,\n          trackLen * (visibleW / contentW),\n        );\n        const maxScroll = Math.max(0, contentW - visibleW);\n        const free = Math.max(1, trackLen - thumbLen);\n        const ratio = maxScroll / free;\n        this.scrollLeft =\n          this.scrollbarDrag.scrollStart +\n          (x - this.scrollbarDrag.pointerStart) * ratio;\n      }\n      this.clampScroll();\n      this.touchScrollbar(this.scrollbarDrag.axis);\n      return;\n    }\n\n    if (!this.drag) {\n      // Hover-only — update cursor + hoveredClipId + hoveredTrackIndex.\n      const target = this.hitTarget(x, y);\n      let nextHover: string | null = null;\n      let nextHoverTrack: number | null = null;\n      let cursor = \"default\";\n      let onScrollbarV = false;\n      let onScrollbarH = false;\n      let nextHoverKeyframe: { clipId: string; keyframeId: string } | null =\n        null;\n      if (target.kind === \"clip\") {\n        nextHover = target.clipId;\n        nextHoverTrack = target.trackIndex;\n        cursor = this.readOnly ? \"pointer\" : \"grab\";\n      } else if (target.kind === \"keyframe\") {\n        nextHover = target.clipId;\n        nextHoverTrack = target.trackIndex;\n        nextHoverKeyframe = {\n          clipId: target.clipId,\n          keyframeId: target.keyframeId,\n        };\n        cursor = \"pointer\";\n      } else if (\n        target.kind === \"clip-handle-left\" ||\n        target.kind === \"clip-handle-right\"\n      ) {\n        nextHover = target.clipId;\n        nextHoverTrack = target.trackIndex;\n        cursor = \"ew-resize\";\n      } else if (target.kind === \"ruler\") {\n        cursor = \"ew-resize\";\n      } else if (target.kind === \"track-empty\") {\n        nextHoverTrack = target.trackIndex;\n        cursor = \"crosshair\";\n      } else if (target.kind === \"header\") {\n        nextHoverTrack = target.trackIndex;\n        cursor = \"default\";\n      } else if (target.kind === \"header-delete\") {\n        nextHoverTrack = target.trackIndex;\n        cursor = \"pointer\";\n      } else if (\n        target.kind === \"scrollbar-thumb-v\" ||\n        target.kind === \"scrollbar-track-v\"\n      ) {\n        onScrollbarV = true;\n        cursor = \"default\";\n      } else if (\n        target.kind === \"scrollbar-thumb-h\" ||\n        target.kind === \"scrollbar-track-h\"\n      ) {\n        onScrollbarH = true;\n        cursor = \"default\";\n      }\n      const hoverChanged =\n        onScrollbarV !== this.hoverScrollbarY ||\n        onScrollbarH !== this.hoverScrollbarX;\n      const kfHoverChanged =\n        (nextHoverKeyframe?.clipId ?? null) !==\n          (this.hoveredKeyframe?.clipId ?? null) ||\n        (nextHoverKeyframe?.keyframeId ?? null) !==\n          (this.hoveredKeyframe?.keyframeId ?? null);\n      if (\n        nextHover !== this.hoveredClipId ||\n        nextHoverTrack !== this.hoveredTrackIndex ||\n        cursor !== this.hoverCursor ||\n        hoverChanged ||\n        kfHoverChanged\n      ) {\n        this.hoveredClipId = nextHover;\n        this.hoveredTrackIndex = nextHoverTrack;\n        this.hoverCursor = cursor;\n        this.hoverScrollbarY = onScrollbarV;\n        this.hoverScrollbarX = onScrollbarH;\n        this.hoveredKeyframe = nextHoverKeyframe;\n        this.scheduleRender();\n      }\n      return;\n    }\n\n    if (this.drag.kind === \"scrub\") {\n      const ms = this.applySnap(\n        xToMs(x, this.pxPerSec, this.scrollLeft, this.showHeader),\n        null,\n      );\n      this.timeMs = ms;\n      this.opts.onSeek?.(ms);\n      this.scheduleRender();\n      return;\n    }\n\n    if (this.drag.kind === \"move\") {\n      this.lastDragPointerX = x;\n      this.lastDragPointerY = y;\n      this.processMoveDrag(x, y);\n      this.scheduleRender();\n      this.maybeStartDragAutoScroll();\n      return;\n    }\n\n    if (this.drag.kind === \"keyframe-drag\") {\n      // Compute the snapped clip-local time and stash it on the drag\n      // struct. The actual mutation is deferred to pointer-up so the\n      // history stack gets a single entry per drag (not one per tick).\n      const found = findClip(this.project, this.drag.clipId);\n      if (!found) return;\n      const clip = found.clip;\n      const duration = clip.out - clip.in;\n      const dxPx = x - this.drag.pointerStartX;\n      const dxMs = (dxPx / this.pxPerSec) * 1000;\n      const nextLocal = Math.max(\n        0,\n        Math.min(duration, this.drag.originalTimeMs + dxMs),\n      );\n      const snappedAbs = this.applySnap(clip.start + nextLocal, null);\n      const snappedLocal = Math.max(\n        0,\n        Math.min(duration, snappedAbs - clip.start),\n      );\n      this.drag.ghostTimeMs = Math.round(snappedLocal);\n      this.scheduleRender();\n      return;\n    }\n\n    if (this.drag.kind === \"trim-left\" || this.drag.kind === \"trim-right\") {\n      const dxPx = x - this.drag.pointerStartX;\n      const dxMs = (dxPx / this.pxPerSec) * 1000;\n      const found = findClip(this.project, this.drag.clipId);\n      if (!found) return;\n      const c = found.clip;\n      if (this.drag.kind === \"trim-left\") {\n        // Move start + in by the same delta; clip's right edge stays put.\n        let nextStart = Math.max(0, this.drag.originalStart + dxMs);\n        nextStart = this.applySnap(nextStart, this.drag.clipId);\n        const delta = nextStart - this.drag.originalStart;\n        const nextIn = Math.max(\n          0,\n          Math.min(this.drag.originalIn + delta, this.drag.originalOut - 50),\n        );\n        const adjStart = this.drag.originalStart + (nextIn - this.drag.originalIn);\n        c.in = nextIn;\n        c.start = adjStart;\n      } else {\n        // trim-right — move out only.\n        const nextOut = Math.max(\n          this.drag.originalIn + 50,\n          this.drag.originalOut + dxMs,\n        );\n        c.out = nextOut;\n      }\n      this.scheduleRender();\n      return;\n    }\n  }\n\n  /**\n   * Update dragGhost + dropTargetTrackIndex for the in-flight move\n   * drag, given the current viewport pointer position. Pulled out of\n   * onPointerMove so the edge-autoscroll loop can re-run it on each\n   * tick — autoscroll moves scrollTop under a stationary cursor, and\n   * the ghost must follow the new row under that cursor.\n   */\n  private processMoveDrag(x: number, y: number): void {\n    if (!this.drag || this.drag.kind !== \"move\") return;\n    const drag = this.drag;\n    const dxPx = x - drag.pointerStartX;\n    const dxMs = (dxPx / this.pxPerSec) * 1000;\n    let nextStart = Math.max(0, drag.originalStart + dxMs);\n    nextStart = this.applySnap(nextStart, drag.clipId);\n\n    const tiRaw = this.trackIndexAtY(y);\n    const phantomIdx = this.project.tracks.length;\n    const phantomScreenY =\n      RULER_HEIGHT + phantomIdx * TRACK_HEIGHT - this.scrollTop;\n    // Hit zone for the \"+ 新轨道\" phantom row: anywhere below the last\n    // existing track up to the viewport bottom. Visually the phantom\n    // still draws at `phantomScreenY` (one row tall), but when the\n    // viewport is compact (small timelineHeight) the phantom is\n    // pushed below the visible area and the user can only reach it\n    // after auto-scrolling. Extending the hit zone all the way down\n    // means \"drop anywhere in the empty space below the tracks\" is\n    // interpreted as \"create a new track\" — matches the visual\n    // intent without requiring scroll gymnastics.\n    const viewportBottom = this.viewportHeight - SCROLLBAR_THICKNESS;\n    const onPhantom =\n      y >= phantomScreenY && y < Math.max(phantomScreenY + TRACK_HEIGHT, viewportBottom);\n    const intendedTrackIndex = onPhantom\n      ? phantomIdx\n      : tiRaw >= 0\n        ? tiRaw\n        : drag.trackIndex;\n\n    let ghostTrackIndex = intendedTrackIndex;\n    let overlap = false;\n    if (onPhantom) {\n      ghostTrackIndex = phantomIdx;\n      overlap = true;\n    } else if (this.opts.resolveDrop) {\n      const r = this.opts.resolveDrop(drag.clipId, {\n        start: nextStart,\n        intendedTrackIndex,\n      });\n      ghostTrackIndex = r.trackIndex;\n      overlap = r.wouldCreateNew;\n    } else {\n      const found = findClip(this.project, drag.clipId);\n      const dur = found ? found.clip.out - found.clip.in : 0;\n      const targetTrack = this.project.tracks[intendedTrackIndex];\n      overlap = targetTrack\n        ? wouldOverlap(targetTrack, drag.clipId, nextStart, nextStart + dur)\n        : false;\n    }\n\n    this.dragGhost = {\n      clipId: drag.clipId,\n      ghostStart: nextStart,\n      ghostTrackIndex,\n      wouldOverlap: overlap,\n    };\n    this.dropTargetTrackIndex =\n      ghostTrackIndex !== drag.trackIndex ? ghostTrackIndex : null;\n  }\n\n  /**\n   * Px-per-frame scroll speed when the pointer is in a vertical edge\n   * zone of the track region. Returns 0 outside the zone. Speed ramps\n   * linearly from 0 at the zone's inner edge to ~16 px/frame at the\n   * outer edge, so brushing the edge gives a gentle nudge and parking\n   * deep at it gives a brisk auto-scroll.\n   */\n  private dragScrollSpeedY(): number {\n    if (!this.drag || this.drag.kind !== \"move\") return 0;\n    const y = this.lastDragPointerY;\n    const top = RULER_HEIGHT;\n    const bottom = this.viewportHeight - SCROLLBAR_THICKNESS;\n    const zone = 36;\n    const maxSpeed = 16;\n    if (y >= top && y < top + zone) {\n      // Top zone — scroll up (decrease scrollTop), but only if there's\n      // somewhere to go (otherwise the loop would tick forever).\n      if (this.scrollTop <= 0) return 0;\n      const depth = (top + zone - y) / zone;\n      return -Math.max(2, maxSpeed * depth);\n    }\n    if (y <= bottom && y > bottom - zone) {\n      if (this.scrollTop >= this.maxScrollTop()) return 0;\n      const depth = (y - (bottom - zone)) / zone;\n      return Math.max(2, maxSpeed * depth);\n    }\n    return 0;\n  }\n\n  /**\n   * Drive vertical auto-scroll while the user holds a clip near the\n   * top/bottom edge of the track area. Self-stopping — exits the loop\n   * once the pointer leaves the zone, the drag ends, or scroll bottoms\n   * out at the clamp.\n   */\n  private maybeStartDragAutoScroll(): void {\n    if (this.dragScrollRafPending) return;\n    if (this.dragScrollSpeedY() === 0) return;\n    this.dragScrollRafPending = true;\n    requestAnimationFrame(() => {\n      this.dragScrollRafPending = false;\n      if (this.destroyed) return;\n      const speed = this.dragScrollSpeedY();\n      if (speed === 0 || !this.drag || this.drag.kind !== \"move\") return;\n      this.scrollTop += speed;\n      this.clampScroll();\n      this.touchScrollbar(\"v\");\n      this.processMoveDrag(this.lastDragPointerX, this.lastDragPointerY);\n      this.scheduleRender();\n      this.maybeStartDragAutoScroll();\n    });\n  }\n\n  private onPointerUp(_e: PointerEvent): void {\n    if (this.scrollbarDrag) {\n      const axis = this.scrollbarDrag.axis;\n      this.scrollbarDrag = null;\n      this.touchScrollbar(axis);\n      return;\n    }\n    if (!this.drag) return;\n    const drag = this.drag;\n    const ghost = this.dragGhost;\n    this.drag = null;\n    this.dragGhost = null;\n    this.dropTargetTrackIndex = null;\n    this.snapX = null;\n\n    if (drag.kind === \"move\") {\n      if (ghost) {\n        const isPhantom = ghost.ghostTrackIndex >= this.project.tracks.length;\n        const finalTrackId = isPhantom\n          ? undefined\n          : ghost.ghostTrackIndex !== drag.trackIndex\n            ? this.project.tracks[ghost.ghostTrackIndex]?.id\n            : undefined;\n        this.opts.onMoveClip?.(drag.clipId, {\n          start: ghost.ghostStart,\n          trackId: finalTrackId,\n          // Phantom row drop is the user explicitly asking for a new\n          // track — bypass the editor's smart routing in that case\n          // (which would otherwise route back to the source track and\n          // make the gesture a no-op).\n          newTrack: isPhantom,\n        });\n        this.opts.onChange?.(this.getProject());\n      }\n    } else if (drag.kind === \"keyframe-drag\") {\n      if (drag.ghostTimeMs !== drag.originalTimeMs) {\n        this.opts.onMoveKeyframe?.(\n          drag.clipId,\n          drag.keyframeId,\n          drag.ghostTimeMs,\n        );\n      }\n    } else if (drag.kind === \"trim-left\" || drag.kind === \"trim-right\") {\n      const found = findClip(this.project, drag.clipId);\n      if (found) {\n        this.opts.onResizeClip?.(drag.clipId, {\n          in: found.clip.in,\n          out: found.clip.out,\n          start: found.clip.start,\n        });\n        this.opts.onChange?.(this.getProject());\n      }\n    }\n    this.scheduleRender();\n  }\n\n  private attachKeyboard(): void {\n    // Make the canvas focusable so it can receive keydown. Without\n    // tabIndex the browser's accessibility tree refuses to deliver\n    // key events to a <canvas>. -1 means \"focusable by click but not\n    // by tab\" — the timeline isn't a primary tab stop, but it\n    // accepts focus when the user clicks on it.\n    this.canvas.tabIndex = -1;\n    this.canvas.style.outline = \"none\"; // suppress the focus ring\n    this.canvas.addEventListener(\"keydown\", (e) => {\n      if (e.code !== \"ArrowLeft\" && e.code !== \"ArrowRight\") return;\n      // Frame-stepping nav — step size derived from Project.fps\n      // (defaults to 30). Same helpers as EditorUI so behavior stays\n      // consistent whether the timeline is embedded or standalone.\n      e.preventDefault();\n      const step = e.shiftKey\n        ? bigFrameStepMs(this.project)\n        : frameStepMs(this.project);\n      const dir = e.code === \"ArrowLeft\" ? -1 : 1;\n      const dur = projectDuration(this.project);\n      const next = Math.max(0, Math.min(dur, this.timeMs + dir * step));\n      if (next === this.timeMs) return;\n      this.timeMs = next;\n      this.opts.onSeek?.(next);\n      this.scheduleRender();\n    });\n    // Auto-focus on pointer-down so the very first arrow press after\n    // clicking the timeline actually moves the playhead. Without this\n    // the canvas only gets focus on the second interaction, which\n    // feels broken.\n    this.canvas.addEventListener(\"pointerdown\", () => {\n      if (document.activeElement !== this.canvas) this.canvas.focus();\n    });\n  }\n\n  private attachWheel(): void {\n    this.canvas.addEventListener(\n      \"wheel\",\n      (e) => {\n        if (e.ctrlKey || e.metaKey) {\n          e.preventDefault();\n          const rect = this.canvas.getBoundingClientRect();\n          const cursorX = e.clientX - rect.left;\n          const anchorMs = xToMs(\n            cursorX,\n            this.pxPerSec,\n            this.scrollLeft,\n            this.showHeader,\n          );\n          const dy = Math.max(-50, Math.min(50, e.deltaY));\n          const factor = Math.exp(-dy * WHEEL_ZOOM_RATE);\n          const next = clampScale(this.pxPerSec * factor);\n          if (Math.abs(next - this.pxPerSec) < 0.01) return;\n          this.pxPerSec = next;\n          this.hasAutoFitted = true;\n          // Re-anchor: keep the time under the cursor visually pinned.\n          const baseX = contentLeftX(this.showHeader);\n          this.scrollLeft =\n            (anchorMs / 1000) * this.pxPerSec - (cursorX - baseX);\n          this.clampScroll();\n          this.touchScrollbar(\"h\");\n          this.opts.onScaleChange?.(this.pxPerSec);\n          this.scheduleRender();\n          return;\n        }\n        // Pan. Trackpad horizontal swipe (|deltaX|>|deltaY|) → X axis.\n        // Otherwise vertical wheel/swipe → Y axis when tracks overflow,\n        // falling through to X when there's no Y to scroll (preserves\n        // the single-track UX where a mouse wheel pans horizontally).\n        const horizDominant = Math.abs(e.deltaX) > Math.abs(e.deltaY);\n        if (horizDominant) {\n          if (e.deltaX === 0) return;\n          e.preventDefault();\n          this.scrollLeft += e.deltaX;\n          this.clampScroll();\n          this.touchScrollbar(\"h\");\n          this.scheduleRender();\n          return;\n        }\n        if (e.deltaY === 0) return;\n        e.preventDefault();\n        if (this.maxScrollTop() > 0) {\n          this.scrollTop += e.deltaY;\n          this.clampScroll();\n          this.touchScrollbar(\"v\");\n        } else {\n          this.scrollLeft += e.deltaY;\n          this.clampScroll();\n          this.touchScrollbar(\"h\");\n        }\n        this.scheduleRender();\n      },\n      { passive: false },\n    );\n  }\n\n  private attachResize(): void {\n    if (typeof ResizeObserver === \"undefined\") return;\n    this.resizeObs = new ResizeObserver(() => {\n      this.resizeCanvas();\n      if (!this.hasAutoFitted && this.autoFitEnabled) {\n        const fit = this.computeFitScale();\n        if (fit != null) {\n          this.pxPerSec = fit;\n          this.opts.onScaleChange?.(fit);\n        }\n      }\n      this.scheduleRender();\n    });\n    this.resizeObs.observe(this.root);\n  }\n\n  // ---- helpers --------------------------------------------------------\n\n  private localCoords(e: PointerEvent): { x: number; y: number } {\n    const rect = this.canvas.getBoundingClientRect();\n    return { x: e.clientX - rect.left, y: e.clientY - rect.top };\n  }\n\n  private hitTarget(x: number, y: number): HitTarget {\n    return hitTest(x, y, {\n      project: this.project,\n      pxPerSec: this.pxPerSec,\n      scrollLeft: this.scrollLeft,\n      scrollTop: this.scrollTop,\n      showHeader: this.showHeader,\n      viewportWidth: this.viewportWidth,\n      viewportHeight: this.viewportHeight,\n      isDragging: this.drag?.kind === \"move\",\n      keyframesEnabled: this.keyframesEnabled,\n    });\n  }\n\n  private trackIndexAtY(y: number): number {\n    return trackIndexAt(y, this.project.tracks.length, this.scrollTop);\n  }\n\n  private applySnap(ms: Ms, ignoreClipId: string | null): Ms {\n    if (!this.snapEnabled) {\n      this.snapX = null;\n      return ms;\n    }\n    const tolMs = Math.max(20, (SNAP_PX / this.pxPerSec) * 1000);\n    const targets = snapTargets(this.project, this.timeMs, ignoreClipId);\n    let best = ms;\n    let bestDist = tolMs;\n    for (const t of targets) {\n      const d = Math.abs(t - ms);\n      if (d < bestDist) {\n        bestDist = d;\n        best = t;\n      }\n    }\n    if (best !== ms) {\n      const baseX = contentLeftX(this.showHeader);\n      this.snapX = baseX + (best / 1000) * this.pxPerSec - this.scrollLeft;\n    } else {\n      this.snapX = null;\n    }\n    return best;\n  }\n}\n\n// Expose helpers from layout.ts via a deep import for consumers who\n// want the px math without instantiating Timeline.\nexport { TRACK_HEIGHT, RULER_HEIGHT, HEADER_WIDTH } from \"./layout.js\";\n","import type { Editor } from \"../editor.js\";\nimport { getEffectiveTransform } from \"../keyframes/index.js\";\nimport type { Clip } from \"../types.js\";\n\n/**\n * Eight resize handles: 4 corners (tl/tr/bl/br) + 4 edge midpoints\n * (t/r/b/l). Corners resize both dimensions; edges resize only the\n * perpendicular dimension. Aspect is locked either way (single\n * `scale` value on the clip), so a horizontal edge drag still\n * changes the clip's height proportionally — same posture as\n * shift-resize in any graphics editor.\n */\ntype HandleKind = \"tl\" | \"tr\" | \"bl\" | \"br\" | \"t\" | \"r\" | \"b\" | \"l\";\n\n/**\n * Direct-manipulation overlay on top of the preview area. When\n * keyframes mode is on AND the active engine exposes a frame rect,\n * paints a 1px dashed border around the OUTPUT frame (fixed) + four\n * corner handles attached to the CONTENT (moves with the transform).\n *\n * Pointer gestures all act on the SELECTED clip's three transform\n * properties (`panX`, `panY`, `scale`), routed through\n * `Editor.setValueAtPlayhead` — so a gesture either updates the\n * clip's static base (no animation track yet) or upserts a keyframe\n * at the playhead (when the prop is already animated).\n *\n *   - Drag inside the frame body            → setValueAtPlayhead(panX, panY)\n *   - Drag a corner handle (or pinch wheel) → setValueAtPlayhead(scale)\n *\n * Overlay element has `pointer-events: none` so non-keyframe clicks\n * pass through to whatever lives below; only the body + handles\n * capture clicks. Hidden via display: none when keyframe mode is off.\n */\nexport class KeyframeOverlay {\n  private editor: Editor;\n  private host: HTMLElement;\n  readonly root: HTMLDivElement;\n  /**\n   * Static canvas-extent guide pinned to the OUTPUT rect. Shows the\n   * editable area regardless of selection — same affordance the\n   * dashed border had before PiP. Visibility gated on\n   * `previewFrame.enabled`. Always purely visual: pointer-events\n   * pass through so clicks land on whatever lives below.\n   */\n  private canvasGuide: HTMLDivElement;\n  /** Selection-following frame pinned to the SELECTED clip's content\n   *  rect. Doubles as the drag-to-pan hit target when keyframes mode\n   *  is on; corner handles attach to its bounds. */\n  private frameBody: HTMLDivElement;\n  private handles: Record<HandleKind, HTMLDivElement>;\n  private rafHandle: number | null = null;\n  private destroyed = false;\n  private drag:\n    | {\n        kind: \"translate\";\n        clipId: string;\n        pointerStartX: number;\n        pointerStartY: number;\n        startPanX: number;\n        startPanY: number;\n      }\n    | {\n        kind: \"scale\";\n        clipId: string;\n        /** Viewport coords of the anchored point — stays fixed. For\n         *  corner drags this is the opposite corner; for edge drags\n         *  it's the opposite edge's midpoint. */\n        anchorX: number;\n        anchorY: number;\n        /** Direction from anchor to dragged corner / edge. ±1 per axis. */\n        dirX: 1 | -1;\n        dirY: 1 | -1;\n        /** Per-axis projection mask: corners use both (1, 1); edge\n         *  handles only consume the perpendicular axis so a top-edge\n         *  drag ignores horizontal cursor motion. */\n        axisX: 0 | 1;\n        axisY: 0 | 1;\n        /** Content dims when scale = 1, in viewport CSS px. */\n        baseW: number;\n        baseH: number;\n        /** Output canvas center in viewport coords — to convert\n         *  newCenter into pan offsets. */\n        canvasCenterX: number;\n        canvasCenterY: number;\n        /** Offset between the pointerdown position and the\n         *  handle's LOGICAL anchor point (corner / edge midpoint).\n         *  Subtracted from every subsequent cursor read so the clip\n         *  doesn't jump at the start of a drag when the user clicks\n         *  off-center inside the 18×6 / 6×18 handle hit zone. */\n        grabOffsetX: number;\n        grabOffsetY: number;\n      }\n    | null = null;\n  private capturedPointerId: number | null = null;\n  /** Timer handle for the wheel-burst → interaction commit. */\n  private wheelInteractionTimer: number | null = null;\n  /** Snap-target threshold in CSS px — the same feel as the timeline. */\n  private static readonly SNAP_PX = 8;\n\n  constructor(host: HTMLElement, editor: Editor) {\n    this.host = host;\n    this.editor = editor;\n\n    this.root = document.createElement(\"div\");\n    this.root.className = \"aicut-keyframe-overlay\";\n    this.root.setAttribute(\"data-testid\", \"aicut-keyframe-overlay\");\n    this.root.style.display = \"none\";\n\n    this.canvasGuide = document.createElement(\"div\");\n    this.canvasGuide.className = \"aicut-keyframe-overlay__canvas-guide\";\n    this.canvasGuide.setAttribute(\"data-testid\", \"aicut-keyframe-canvas-guide\");\n    this.root.appendChild(this.canvasGuide);\n\n    this.frameBody = document.createElement(\"div\");\n    this.frameBody.className = \"aicut-keyframe-overlay__frame\";\n    this.frameBody.setAttribute(\"data-testid\", \"aicut-keyframe-frame\");\n    this.frameBody.addEventListener(\"pointerdown\", (e) => this.onTransStart(e));\n    // Pinch-to-zoom: macOS trackpads fire `wheel` events with\n    // ctrlKey: true. We preventDefault the page zoom and reinterpret\n    // as a scale change on the selected clip.\n    this.frameBody.addEventListener(\n      \"wheel\",\n      (e) => this.onPinchScale(e),\n      { passive: false },\n    );\n    this.root.appendChild(this.frameBody);\n\n    this.handles = {\n      tl: this.makeHandle(\"tl\"),\n      tr: this.makeHandle(\"tr\"),\n      bl: this.makeHandle(\"bl\"),\n      br: this.makeHandle(\"br\"),\n      t: this.makeHandle(\"t\"),\n      r: this.makeHandle(\"r\"),\n      b: this.makeHandle(\"b\"),\n      l: this.makeHandle(\"l\"),\n    };\n\n    host.appendChild(this.root);\n    // Click-to-select on the preview host — capture phase so it\n    // runs BEFORE the overlay's own frame body / handles fire their\n    // pointerdown. Without that, selecting the main clip would\n    // stretch the frame body across the whole canvas and every\n    // subsequent click would start a translate drag of the main\n    // clip instead of selecting the PiP underneath the cursor.\n    this.host.addEventListener(\"pointerdown\", this.onHostPointerDown, true);\n    this.startTick();\n  }\n\n  private onHostPointerDown = (e: PointerEvent): void => {\n    if (e.button !== 0) return;\n    if (!this.editor.isKeyframesEnabled()) return;\n    // Always ignore clicks on the resize handles — they have their\n    // own scale-drag handler.\n    const target = e.target as HTMLElement | null;\n    if (\n      target &&\n      target.classList.contains(\"aicut-keyframe-overlay__handle\")\n    ) {\n      return;\n    }\n    const project = this.editor.getProject();\n    const timeMs = this.editor.getTime();\n    const hostRect = this.host.getBoundingClientRect();\n    const cx = e.clientX - hostRect.left;\n    const cy = e.clientY - hostRect.top;\n    const currentSelection = this.editor.getSelection();\n    // Walk tracks top-down (highest index = topmost z) so PiP\n    // overlays win the hit-test over the main background.\n    for (let i = project.tracks.length - 1; i >= 0; i--) {\n      const track = project.tracks[i]!;\n      if (track.kind !== \"video\") continue;\n      const clip = track.clips.find(\n        (c) =>\n          timeMs >= c.start && timeMs < c.start + (c.out - c.in),\n      );\n      if (!clip) continue;\n      const rect = this.editor.getClipFrameRect(clip.id);\n      if (!rect) continue;\n      if (\n        cx < rect.x ||\n        cx > rect.x + rect.w ||\n        cy < rect.y ||\n        cy > rect.y + rect.h\n      ) {\n        continue;\n      }\n      if (clip.id === currentSelection) {\n        // Click landed on the already-selected clip — let the\n        // frame body's pointerdown fire and start a translate\n        // drag like before.\n        return;\n      }\n      // Re-route the click to a selection change and prevent the\n      // frame body from interpreting it as a drag of the previously\n      // selected clip.\n      this.editor.setSelection(clip.id);\n      e.stopPropagation();\n      e.preventDefault();\n      return;\n    }\n  };\n\n  destroy(): void {\n    this.destroyed = true;\n    this.host.removeEventListener(\n      \"pointerdown\",\n      this.onHostPointerDown,\n      true,\n    );\n    if (this.rafHandle != null) cancelAnimationFrame(this.rafHandle);\n    if (this.wheelInteractionTimer != null) {\n      clearTimeout(this.wheelInteractionTimer);\n      this.wheelInteractionTimer = null;\n      // The editor outlives this overlay on a normal teardown, but\n      // if a burst was in flight we still owe it an endInteraction\n      // to balance the begin (otherwise pushHistory stays muted).\n      this.editor.endInteraction();\n    }\n    this.root.remove();\n  }\n\n  // ---- frame body drag (translate) -------------------------------------\n\n  private onTransStart(e: PointerEvent): void {\n    if (e.button !== 0) return;\n    const ctx = this.ensureSelectedClip();\n    if (!ctx) return;\n    e.preventDefault();\n    e.stopPropagation();\n    this.frameBody.setPointerCapture(e.pointerId);\n    this.capturedPointerId = e.pointerId;\n    this.drag = {\n      kind: \"translate\",\n      clipId: ctx.clip.id,\n      pointerStartX: e.clientX,\n      pointerStartY: e.clientY,\n      startPanX: ctx.transform.panX,\n      startPanY: ctx.transform.panY,\n    };\n    // Open a drag session so the 30-100 pointermove mutations\n    // coalesce into ONE history entry — committed on pointer-up.\n    this.editor.beginInteraction();\n    this.frameBody.addEventListener(\"pointermove\", this.onPointerMove);\n    this.frameBody.addEventListener(\"pointerup\", this.onPointerUp);\n    this.frameBody.addEventListener(\"pointercancel\", this.onPointerUp);\n  }\n\n  // ---- pinch-to-scale --------------------------------------------------\n\n  private onPinchScale(e: WheelEvent): void {\n    if (!e.ctrlKey) return;\n    const ctx = this.ensureSelectedClip();\n    if (!ctx) return;\n    e.preventDefault();\n    e.stopPropagation();\n    const step = Math.max(-50, Math.min(50, -e.deltaY));\n    const factor = Math.exp(step * 0.01);\n    const next = Math.max(\n      0.05,\n      Math.min(16, ctx.transform.scale * factor),\n    );\n    // Wheel events have no down / up boundary, so use a debounce-\n    // flush instead: first event opens an interaction, every\n    // subsequent event within 200ms resets the timer, and 200ms\n    // after the last wheel tick we commit. The result is one\n    // history entry per \"burst\" of scrolling — matches the user's\n    // mental model of \"I scrolled, then I stopped\".\n    if (this.wheelInteractionTimer == null) {\n      this.editor.beginInteraction();\n    } else {\n      clearTimeout(this.wheelInteractionTimer);\n    }\n    this.wheelInteractionTimer = window.setTimeout(() => {\n      this.wheelInteractionTimer = null;\n      this.editor.endInteraction();\n    }, 200);\n    this.editor.setValueAtPlayhead(\n      ctx.clip.id,\n      \"scale\",\n      Math.round(next * 100) / 100,\n    );\n  }\n\n  // ---- corner-handle drag (scale) --------------------------------------\n\n  private onScaleStart(handle: HandleKind, e: PointerEvent): void {\n    if (e.button !== 0) return;\n    const ctx = this.ensureSelectedClip();\n    if (!ctx) return;\n    e.preventDefault();\n    e.stopPropagation();\n    // CapCut-style anchored resize: the OPPOSITE corner / edge stays\n    // pinned. For edge handles the anchor is the parallel edge — the\n    // dragged edge moves only along its perpendicular axis but the\n    // perpendicular axis still drives a uniform scale, so the\n    // dragged edge follows the cursor along its drag axis and the\n    // perpendicular axis grows / shrinks in tandem.\n    const clipRect = this.editor.getActiveFrameRect();\n    const outRect = this.editor.getActiveOutputFrameRect();\n    if (!clipRect || !outRect) return;\n    const hostRect = this.host.getBoundingClientRect();\n\n    // Edge handles ignore one axis entirely. For top edge, anchor =\n    // bottom edge midpoint; for left edge, anchor = right edge\n    // midpoint; etc. Corner handles anchor the opposite corner.\n    const touchesTop = handle === \"tl\" || handle === \"tr\" || handle === \"t\";\n    const touchesBottom = handle === \"bl\" || handle === \"br\" || handle === \"b\";\n    const touchesLeft = handle === \"tl\" || handle === \"bl\" || handle === \"l\";\n    const touchesRight = handle === \"tr\" || handle === \"br\" || handle === \"r\";\n    // Anchor goes to the OPPOSITE side of whatever the handle\n    // touches. When the handle doesn't touch a given side (e.g. the\n    // \"t\" edge handle is on top but doesn't touch left/right), the\n    // anchor along that axis sits at the clip CENTER — i.e. that\n    // axis is shared 50/50 across the resize, mirroring the edge\n    // expansion symmetrically.\n    let anchorOffsetX: number;\n    let dirX: 1 | -1;\n    if (touchesLeft) {\n      anchorOffsetX = clipRect.w; // anchor at right edge\n      dirX = -1;\n    } else if (touchesRight) {\n      anchorOffsetX = 0; // anchor at left edge\n      dirX = 1;\n    } else {\n      anchorOffsetX = clipRect.w / 2; // anchor at horizontal center\n      dirX = 1; // unused for edge handles' projection\n    }\n    let anchorOffsetY: number;\n    let dirY: 1 | -1;\n    if (touchesTop) {\n      anchorOffsetY = clipRect.h;\n      dirY = -1;\n    } else if (touchesBottom) {\n      anchorOffsetY = 0;\n      dirY = 1;\n    } else {\n      anchorOffsetY = clipRect.h / 2;\n      dirY = 1;\n    }\n    const anchorX = hostRect.left + clipRect.x + anchorOffsetX;\n    const anchorY = hostRect.top + clipRect.y + anchorOffsetY;\n\n    // Base content size at scale = 1.\n    const baseW = clipRect.w / ctx.transform.scale;\n    const baseH = clipRect.h / ctx.transform.scale;\n    if (baseW < 1 || baseH < 1) return;\n\n    const canvasCenterX = hostRect.left + outRect.x + outRect.w / 2;\n    const canvasCenterY = hostRect.top + outRect.y + outRect.h / 2;\n\n    const target = this.handles[handle];\n    target.setPointerCapture(e.pointerId);\n    this.capturedPointerId = e.pointerId;\n    const axisX: 0 | 1 = touchesLeft || touchesRight ? 1 : 0;\n    const axisY: 0 | 1 = touchesTop || touchesBottom ? 1 : 0;\n    // Where the handle's LOGICAL anchor point sits in viewport\n    // coords — the actual edge / corner position, not the click\n    // location. Used to compute the grab offset below.\n    const handleLogicalX = touchesLeft\n      ? hostRect.left + clipRect.x\n      : touchesRight\n        ? hostRect.left + clipRect.x + clipRect.w\n        : hostRect.left + clipRect.x + clipRect.w / 2;\n    const handleLogicalY = touchesTop\n      ? hostRect.top + clipRect.y\n      : touchesBottom\n        ? hostRect.top + clipRect.y + clipRect.h\n        : hostRect.top + clipRect.y + clipRect.h / 2;\n    const grabOffsetX = e.clientX - handleLogicalX;\n    const grabOffsetY = e.clientY - handleLogicalY;\n    this.drag = {\n      kind: \"scale\",\n      clipId: ctx.clip.id,\n      anchorX,\n      anchorY,\n      dirX,\n      dirY,\n      axisX,\n      axisY,\n      baseW,\n      baseH,\n      canvasCenterX,\n      canvasCenterY,\n      grabOffsetX,\n      grabOffsetY,\n    };\n    this.editor.beginInteraction();\n    target.addEventListener(\"pointermove\", this.onPointerMove);\n    target.addEventListener(\"pointerup\", this.onPointerUp);\n    target.addEventListener(\"pointercancel\", this.onPointerUp);\n  }\n\n  private onPointerMove = (e: PointerEvent): void => {\n    if (!this.drag) return;\n    if (this.drag.kind === \"translate\") {\n      const dxCss = e.clientX - this.drag.pointerStartX;\n      const dyCss = e.clientY - this.drag.pointerStartY;\n      // Convert the CSS-pixel cursor delta into CANVAS pixels — the\n      // unit pan values are stored in. `getActiveOutputFrameRect`\n      // returns the canvas guide's CSS-px bounds; the editor knows\n      // the canvas dims. Ratio = canvasPx / cssPx.\n      const out = this.editor.getActiveOutputFrameRect();\n      const canvas = this.editor.getOutput();\n      const cssToCanvasX = out && out.w > 0 ? canvas.width / out.w : 1;\n      const cssToCanvasY = out && out.h > 0 ? canvas.height / out.h : 1;\n      const rawPanX = this.drag.startPanX + dxCss * cssToCanvasX;\n      const rawPanY = this.drag.startPanY + dyCss * cssToCanvasY;\n      // Snap to: centered (0), and (when content > output) left/right\n      // / top/bottom edge alignment between content and output.\n      const snapped = this.applySnap(this.drag.clipId, rawPanX, rawPanY);\n      this.editor.setValueAtPlayhead(\n        this.drag.clipId,\n        \"panX\",\n        Math.round(snapped.panX),\n      );\n      this.editor.setValueAtPlayhead(\n        this.drag.clipId,\n        \"panY\",\n        Math.round(snapped.panY),\n      );\n    } else {\n      // Corner resize with the OPPOSITE corner anchored. Aspect is\n      // locked (single `scale` value); we project the cursor's\n      // displacement from the anchor onto the natural diagonal\n      // direction (baseW, baseH). This gives a smooth, jitter-free\n      // scale that doesn't flicker between axes the way max(sx, sy)\n      // does when the cursor wanders slightly off-diagonal — the\n      // opposite corner stays pinned to within float-rounding noise\n      // instead of bouncing by a pixel each frame.\n      // Subtract the grab-offset so the math always treats the\n      // cursor as if it had clicked exactly on the handle's logical\n      // anchor point. Eliminates the 1-2px \"jump\" the user sees the\n      // moment they press on a wide edge handle slightly off-center.\n      const cursorX = e.clientX - this.drag.grabOffsetX;\n      const cursorY = e.clientY - this.drag.grabOffsetY;\n      const offsetX = (cursorX - this.drag.anchorX) * this.drag.dirX;\n      const offsetY = (cursorY - this.drag.anchorY) * this.drag.dirY;\n      // Mask out axes the handle isn't supposed to consume (edge\n      // handles only listen to the perpendicular axis). For corners\n      // axisX = axisY = 1, so this is a no-op.\n      const projX = offsetX * this.drag.axisX;\n      const projY = offsetY * this.drag.axisY;\n      // Effective base length along the active axes. For an edge\n      // handle this collapses to a single axis; for a corner it's\n      // the natural diagonal. Either way the scale comes out as the\n      // ratio along that axis, which is exactly the\n      // opposite-anchor-stays-pinned semantics.\n      const activeBaseW = this.drag.baseW * this.drag.axisX;\n      const activeBaseH = this.drag.baseH * this.drag.axisY;\n      const L = Math.hypot(activeBaseW, activeBaseH) || 1;\n      const proj = (projX * activeBaseW + projY * activeBaseH) / L;\n      let next = Math.max(0.05, Math.min(16, proj / L));\n      // Snap the scale to common stops (full canvas, half, quarter,\n      // double) when the snap toggle is on AND the user gets close\n      // enough. Distance threshold is in CSS px on the active axis,\n      // converted from the SNAP_PX timeline threshold so the feel\n      // matches: edges that look \"near full canvas\" lock in.\n      if (this.editor.getSnap()) {\n        const snapTargets = [1, 0.5, 0.25, 2];\n        for (const target of snapTargets) {\n          const targetProj = target * L;\n          if (Math.abs(proj - targetProj) <= KeyframeOverlay.SNAP_PX) {\n            next = target;\n            break;\n          }\n        }\n      }\n      const newW = this.drag.baseW * next;\n      const newH = this.drag.baseH * next;\n      // For edge handles the perpendicular axis is the anchor's own\n      // axis (axisX = 0 means anchor sits at the clip's horizontal\n      // center; axisY = 0 means it sits at the vertical center).\n      // Multiplying by axisX/axisY gates the half-dimension offset\n      // so an edge drag doesn't shove the clip sideways by half its\n      // width — `anchorX + dirX * (newW/2)` would push horizontally\n      // for a top-edge drag, which is exactly the \"jumps right by\n      // the full width\" symptom we were seeing.\n      const newCenterX =\n        this.drag.anchorX + this.drag.axisX * this.drag.dirX * (newW / 2);\n      const newCenterY =\n        this.drag.anchorY + this.drag.axisY * this.drag.dirY * (newH / 2);\n      // `newCenter - canvasCenter` is in CSS px (both are viewport\n      // coords). panX/panY now live in CANVAS pixels, so convert via\n      // the same ratio the translate-drag uses — without this the\n      // anchored corner appears to \"jump\" the moment the user starts\n      // dragging because the stored value reads back through paint()\n      // at the wrong scale.\n      const outRect = this.editor.getActiveOutputFrameRect();\n      const canvas = this.editor.getOutput();\n      const cssToCanvasX = outRect && outRect.w > 0 ? canvas.width / outRect.w : 1;\n      const cssToCanvasY = outRect && outRect.h > 0 ? canvas.height / outRect.h : 1;\n      // Don't round pan offsets here — quantising them to integers\n      // would let the anchored corner jitter as scale grows\n      // continuously. Storage precision is fine for floats and the\n      // editor commits one history entry per drag anyway.\n      const newPanX = (newCenterX - this.drag.canvasCenterX) * cssToCanvasX;\n      const newPanY = (newCenterY - this.drag.canvasCenterY) * cssToCanvasY;\n      this.editor.setValueAtPlayhead(this.drag.clipId, \"scale\", next);\n      this.editor.setValueAtPlayhead(this.drag.clipId, \"panX\", newPanX);\n      this.editor.setValueAtPlayhead(this.drag.clipId, \"panY\", newPanY);\n    }\n  };\n\n  /**\n   * Snap raw pan to: centered (panX/Y = 0) and the four edge-alignment\n   * stops (content's L/R/T/B edge flush with the output's matching\n   * edge). All math here is in CANVAS pixels — the unit pan values\n   * are stored in. CSS-px frame rects from the engine get converted\n   * up via the canvas/CSS ratio so snap thresholds stay visually 8 px\n   * on screen regardless of preview size.\n   */\n  private applySnap(\n    clipId: string,\n    rawPanX: number,\n    rawPanY: number,\n  ): { panX: number; panY: number } {\n    const out = this.editor.getActiveOutputFrameRect();\n    if (!out) return { panX: rawPanX, panY: rawPanY };\n    const clip = this.findClip(clipId);\n    if (!clip) return { panX: rawPanX, panY: rawPanY };\n    const canvas = this.editor.getOutput();\n    const cssToCanvasX = out.w > 0 ? canvas.width / out.w : 1;\n    const cssToCanvasY = out.h > 0 ? canvas.height / out.h : 1;\n    // Content size at current scale (which may differ from base — the\n    // user can be mid-scaling alongside the drag conceptually).\n    const t = (() => {\n      try {\n        const transformer = this.editor.getActiveFrameRect();\n        if (!transformer) return null;\n        return { w: transformer.w, h: transformer.h };\n      } catch {\n        return null;\n      }\n    })();\n    const contentWCss = t?.w ?? out.w;\n    const contentHCss = t?.h ?? out.h;\n    // Edge stops in canvas pixels.\n    const edgeX = ((contentWCss - out.w) / 2) * cssToCanvasX;\n    const edgeY = ((contentHCss - out.h) / 2) * cssToCanvasY;\n    const xTargets = [0, edgeX, -edgeX];\n    const yTargets = [0, edgeY, -edgeY];\n    const thresholdX = KeyframeOverlay.SNAP_PX * cssToCanvasX;\n    const thresholdY = KeyframeOverlay.SNAP_PX * cssToCanvasY;\n    const px = nearestSnap(rawPanX, xTargets, thresholdX);\n    const py = nearestSnap(rawPanY, yTargets, thresholdY);\n    return { panX: px, panY: py };\n  }\n\n  private findClip(clipId: string): Clip | null {\n    const project = this.editor.getProject();\n    for (const t of project.tracks) {\n      const c = t.clips.find((cl) => cl.id === clipId);\n      if (c) return c;\n    }\n    return null;\n  }\n\n  private onPointerUp = (e: PointerEvent): void => {\n    if (!this.drag) return;\n    const targetEl = e.currentTarget as HTMLElement | null;\n    if (targetEl && this.capturedPointerId === e.pointerId) {\n      try {\n        targetEl.releasePointerCapture(e.pointerId);\n      } catch {\n        /* already released */\n      }\n    }\n    targetEl?.removeEventListener(\"pointermove\", this.onPointerMove);\n    targetEl?.removeEventListener(\"pointerup\", this.onPointerUp);\n    targetEl?.removeEventListener(\"pointercancel\", this.onPointerUp);\n    this.drag = null;\n    this.capturedPointerId = null;\n    // Commit the drag session — single history entry for the whole\n    // gesture, dropped entirely if the project ended up unchanged\n    // (e.g. mousedown without movement).\n    this.editor.endInteraction();\n  };\n\n  // ---- per-frame layout ------------------------------------------------\n\n  private startTick(): void {\n    const tick = () => {\n      if (this.destroyed) return;\n      this.layout();\n      this.rafHandle = requestAnimationFrame(tick);\n    };\n    this.rafHandle = requestAnimationFrame(tick);\n  }\n\n  private layout(): void {\n    const frameVisible = this.editor.isPreviewFrameEnabled();\n    const interactive = this.editor.isKeyframesEnabled();\n    if (!frameVisible && !interactive) {\n      this.root.style.display = \"none\";\n      return;\n    }\n    // Output rect = the FIXED stage where the video gets clipped.\n    // The brand-colored border + body drag-target are anchored here.\n    // Without a loaded clip the engine has nothing to report; fall\n    // back to an aspect-fit rect inside the preview host so the user\n    // sees \"this is where the video will land\" before uploading\n    // anything. Driven by `Project.aspect` so switching ratios in\n    // the built-in picker is visible even in the empty state.\n    const outRect =\n      this.editor.getActiveOutputFrameRect() ??\n      (frameVisible ? this.computeEmptyStateRect() : null);\n    // Content rect = where the video pixels currently land (after\n    // transform). Scale handles attach to its corners so they visually\n    // grow / shrink WITH the video.\n    const contentRect = this.editor.getActiveFrameRect() ?? outRect;\n    if (!outRect) {\n      this.root.style.display = \"none\";\n      return;\n    }\n    this.root.style.display = \"block\";\n    // Interactive bits (frame-body drag-to-pan + corner scale handles)\n    // light up only with keyframes mode. Without it the frame is a\n    // pure outline — pointer events pass straight through.\n    this.root.classList.toggle(\n      \"aicut-keyframe-overlay--interactive\",\n      interactive,\n    );\n    // Canvas guide — dashed outline of the output canvas. Same\n    // affordance the dashed border had before PiP existed. Gated on\n    // `previewFrame.enabled` regardless of selection.\n    this.canvasGuide.style.display = frameVisible ? \"block\" : \"none\";\n    Object.assign(this.canvasGuide.style, {\n      left: `${outRect.x}px`,\n      top: `${outRect.y}px`,\n      width: `${outRect.w}px`,\n      height: `${outRect.h}px`,\n    });\n\n    // Selection-following frame body — wraps the SELECTED clip's\n    // content rect so a PiP overlay (content < canvas) gets a clear\n    // outline + handles around the actual clip, while a normal full-\n    // frame clip behaves identically to before (content == canvas).\n    // Visibility ties to whether there's anything to select: with no\n    // active clip the body collapses out of the way and only the\n    // canvas guide remains.\n    const hasSelection = this.editor.getSelection() != null;\n    const frameRect = contentRect ?? outRect;\n    this.frameBody.style.display = hasSelection ? \"block\" : \"none\";\n    Object.assign(this.frameBody.style, {\n      left: `${frameRect.x}px`,\n      top: `${frameRect.y}px`,\n      width: `${frameRect.w}px`,\n      height: `${frameRect.h}px`,\n    });\n    // Border warn state: only relevant when the SELECTED clip is\n    // intended to fill the canvas (scale ≈ 1). For a deliberately-\n    // shrunk PiP overlay, \"content doesn't cover canvas\" is the\n    // entire point — firing the red warn ring would be noise. Heuristic:\n    // suppress warn whenever the content rect is meaningfully smaller\n    // than the canvas (>5% gap on either axis). When it's near full\n    // size we still flag panning that exposes letterbox.\n    const intentionallySmall =\n      contentRect != null &&\n      (contentRect.w < outRect.w * 0.95 ||\n        contentRect.h < outRect.h * 0.95);\n    const fullyCovered =\n      intentionallySmall ||\n      (contentRect\n        ? contentRect.x <= outRect.x + 0.5 &&\n          contentRect.x + contentRect.w >= outRect.x + outRect.w - 0.5 &&\n          contentRect.y <= outRect.y + 0.5 &&\n          contentRect.y + contentRect.h >= outRect.y + outRect.h - 0.5\n        : true);\n    this.frameBody.classList.toggle(\n      \"aicut-keyframe-overlay__frame--warn\",\n      !fullyCovered,\n    );\n    const r = contentRect ?? outRect;\n    const fbLeft = r.x;\n    const fbTop = r.y;\n    const fbRight = r.x + r.w;\n    const fbBottom = r.y + r.h;\n    // Handle half-dim (px): corners are 12×12 squares, top/bottom\n    // edges 18×6, left/right edges 6×18 — keep in sync with the CSS.\n    const place = (\n      el: HTMLDivElement,\n      cx: number,\n      cy: number,\n      halfW: number,\n      halfH: number,\n    ): void => {\n      el.style.left = `${cx - halfW}px`;\n      el.style.top = `${cy - halfH}px`;\n    };\n    place(this.handles.tl, fbLeft, fbTop, 6, 6);\n    place(this.handles.tr, fbRight, fbTop, 6, 6);\n    place(this.handles.bl, fbLeft, fbBottom, 6, 6);\n    place(this.handles.br, fbRight, fbBottom, 6, 6);\n    const midX = (fbLeft + fbRight) / 2;\n    const midY = (fbTop + fbBottom) / 2;\n    place(this.handles.t, midX, fbTop, 9, 3);\n    place(this.handles.r, fbRight, midY, 3, 9);\n    place(this.handles.b, midX, fbBottom, 9, 3);\n    place(this.handles.l, fbLeft, midY, 3, 9);\n  }\n\n  // ---- helpers ---------------------------------------------------------\n\n  /**\n   * Fallback rect used in the \"no clip loaded yet\" empty state — so\n   * the dashed outline visualises the chosen aspect ratio even before\n   * the user uploads anything. Aspect-fit math inside the preview\n   * host with a 16px breathing margin; defaults to 16:9 when no\n   * `Project.aspect` is set.\n   */\n  private computeEmptyStateRect(): { x: number; y: number; w: number; h: number } | null {\n    const aspect = this.editor.getAspect();\n    const [aw, ah] = parseAspect(aspect) ?? [16, 9];\n    const containerW = this.host.clientWidth;\n    const containerH = this.host.clientHeight;\n    if (containerW <= 0 || containerH <= 0) return null;\n    const margin = 16;\n    const innerW = Math.max(0, containerW - margin * 2);\n    const innerH = Math.max(0, containerH - margin * 2);\n    if (innerW <= 0 || innerH <= 0) return null;\n    const targetAr = aw / ah;\n    const containerAr = innerW / innerH;\n    let w: number;\n    let h: number;\n    if (containerAr > targetAr) {\n      h = innerH;\n      w = h * targetAr;\n    } else {\n      w = innerW;\n      h = w / targetAr;\n    }\n    return {\n      x: (containerW - w) / 2,\n      y: (containerH - h) / 2,\n      w,\n      h,\n    };\n  }\n\n  private makeHandle(name: HandleKind): HTMLDivElement {\n    const el = document.createElement(\"div\");\n    const isEdge = name.length === 1;\n    el.className =\n      `aicut-keyframe-overlay__handle aicut-keyframe-overlay__handle--${name}` +\n      (isEdge ? \" aicut-keyframe-overlay__handle--edge\" : \"\");\n    el.setAttribute(\"data-testid\", `aicut-keyframe-handle-${name}`);\n    el.addEventListener(\"pointerdown\", (e) => this.onScaleStart(name, e));\n    this.root.appendChild(el);\n    return el;\n  }\n\n  /**\n   * Resolve the currently selected clip + its current effective\n   * transform (so drag baselines are correct). Returns null when no\n   * clip is selected or the playhead isn't over it.\n   */\n  private ensureSelectedClip():\n    | {\n        clip: Clip;\n        transform: { panX: number; panY: number; scale: number };\n      }\n    | null {\n    const selectedClipId = this.editor.getSelection();\n    if (!selectedClipId) return null;\n    const project = this.editor.getProject();\n    let clip: Clip | null = null;\n    for (const t of project.tracks) {\n      const c = t.clips.find((cl) => cl.id === selectedClipId);\n      if (c) {\n        clip = c;\n        break;\n      }\n    }\n    if (!clip) return null;\n    const playheadLocal = this.editor.getTime() - clip.start;\n    if (playheadLocal < 0 || playheadLocal > clip.out - clip.in) {\n      return null;\n    }\n    const transform = getEffectiveTransform(clip, playheadLocal);\n    return { clip, transform };\n  }\n}\n\n/** Pick the snap target within `threshold`, else return the raw value. */\nfunction nearestSnap(\n  raw: number,\n  targets: number[],\n  threshold: number,\n): number {\n  let best = raw;\n  let bestDist = threshold;\n  for (const t of targets) {\n    const d = Math.abs(raw - t);\n    if (d < bestDist) {\n      bestDist = d;\n      best = t;\n    }\n  }\n  return best;\n}\n\n/**\n * Parse an aspect-ratio string like \"16:9\" into a [w, h] tuple.\n * Returns null for malformed input so callers can apply a default.\n */\nfunction parseAspect(value: string | null): [number, number] | null {\n  if (!value) return null;\n  const m = value.match(/^\\s*(\\d+(?:\\.\\d+)?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*$/);\n  if (!m) return null;\n  const w = Number(m[1]);\n  const h = Number(m[2]);\n  if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) {\n    return null;\n  }\n  return [w, h];\n}\n","import type { Editor } from \"../editor.js\";\nimport type { Locale } from \"../i18n.js\";\nimport {\n  getEffectiveTransform,\n  hasKeyframesForProp,\n  keyframesForProp,\n} from \"../keyframes/index.js\";\nimport type { Clip, EasingKind, Keyframe, KeyframeProp } from \"../types.js\";\n\nconst EASING_VALUES: EasingKind[] = [\n  \"linear\",\n  \"easeIn\",\n  \"easeOut\",\n  \"easeInOut\",\n];\nfunction easingLabel(value: EasingKind, locale: Locale): string {\n  switch (value) {\n    case \"linear\":\n      return locale.keyframeEasingLinear;\n    case \"easeIn\":\n      return locale.keyframeEasingEaseIn;\n    case \"easeOut\":\n      return locale.keyframeEasingEaseOut;\n    case \"easeInOut\":\n      return locale.keyframeEasingEaseInOut;\n  }\n}\n\nconst TIME_EPS_MS = 16;\n\n/**\n * Floating numeric panel anchored to the preview's top-left corner.\n * Visible only when keyframe mode is on AND a keyframe is selected.\n *\n * A keyframe is per-property (one of panX / panY / scale), but the\n * UX groups all kfs at the same time into one \"moment\" — the panel\n * shows the three transform values for that moment. Editing an input\n * upserts the matching prop's keyframe at that exact time; the Reset\n * button writes identity values (0, 0, 1) for all three props at the\n * selected time in a single history step.\n */\nexport class KeyframePanel {\n  private editor: Editor;\n  private locale: Locale;\n  readonly root: HTMLDivElement;\n  private inputs: Record<KeyframeProp, HTMLInputElement>;\n  private kfBadges: Record<KeyframeProp, HTMLSpanElement>;\n  private timeLabel: HTMLSpanElement;\n  private titleLabel!: HTMLSpanElement;\n  private resetBtn: HTMLButtonElement;\n  private easingTrigger!: HTMLButtonElement;\n  private easingTriggerLabel!: HTMLSpanElement;\n  private easingMenu!: HTMLUListElement;\n  private easingItems!: Map<EasingKind, HTMLLIElement>;\n  private easingValue: EasingKind = \"linear\";\n  private easingDisabled = false;\n  private easingOpen = false;\n  private easingLabelEl!: HTMLLabelElement;\n  private rowLabels!: Record<KeyframeProp, HTMLLabelElement>;\n  private lastSyncKey = \"\";\n  // Bound once so add/remove listener pairs reference the same fn.\n  private boundOutsideClick: ((e: MouseEvent) => void) | null = null;\n  private boundDocKeydown: ((e: KeyboardEvent) => void) | null = null;\n\n  constructor(host: HTMLElement, editor: Editor, locale: Locale) {\n    this.editor = editor;\n    this.locale = locale;\n\n    this.root = document.createElement(\"div\");\n    this.root.className = \"aicut-keyframe-panel\";\n    this.root.setAttribute(\"data-testid\", \"aicut-keyframe-panel\");\n    this.root.style.display = \"none\";\n    this.root.addEventListener(\"pointerdown\", (e) => e.stopPropagation());\n    this.root.addEventListener(\"wheel\", (e) => e.stopPropagation());\n\n    const title = document.createElement(\"div\");\n    title.className = \"aicut-keyframe-panel__title\";\n    this.titleLabel = document.createElement(\"span\");\n    this.timeLabel = document.createElement(\"span\");\n    this.timeLabel.className = \"aicut-keyframe-panel__time\";\n    title.append(this.titleLabel, this.timeLabel);\n    this.root.appendChild(title);\n\n    const xRow = this.makeRow(\"kf-x\", \"panX\", 1);\n    const yRow = this.makeRow(\"kf-y\", \"panY\", 1);\n    const scaleRow = this.makeRow(\"kf-scale\", \"scale\", 0.05);\n    this.inputs = {\n      panX: xRow.input,\n      panY: yRow.input,\n      scale: scaleRow.input,\n    };\n    this.rowLabels = {\n      panX: xRow.label,\n      panY: yRow.label,\n      scale: scaleRow.label,\n    };\n    this.kfBadges = {\n      panX: this.makeBadge(this.inputs.panX),\n      panY: this.makeBadge(this.inputs.panY),\n      scale: this.makeBadge(this.inputs.scale),\n    };\n\n    // Easing — one dropdown applies to all three props at this moment.\n    // Shapes the curve from THIS moment to the next kf on each prop.\n    // Custom dropdown (not native <select>) so the floating panel can\n    // be themed consistently across browsers — native <option> styling\n    // is OS-locked and looks foreign next to the rest of the panel.\n    const easingRow = document.createElement(\"div\");\n    easingRow.className =\n      \"aicut-keyframe-panel__row aicut-keyframe-panel__row--easing\";\n    this.easingLabelEl = document.createElement(\"label\");\n\n    const dd = document.createElement(\"div\");\n    dd.className = \"aicut-keyframe-panel__dropdown\";\n    dd.setAttribute(\"data-testid\", \"aicut-kf-easing\");\n\n    this.easingTrigger = document.createElement(\"button\");\n    this.easingTrigger.type = \"button\";\n    this.easingTrigger.className = \"aicut-keyframe-panel__dropdown-trigger\";\n    this.easingTrigger.setAttribute(\"aria-haspopup\", \"listbox\");\n    this.easingTrigger.setAttribute(\"aria-expanded\", \"false\");\n    this.easingTriggerLabel = document.createElement(\"span\");\n    this.easingTriggerLabel.className =\n      \"aicut-keyframe-panel__dropdown-trigger-label\";\n    const chevron = document.createElement(\"span\");\n    chevron.className = \"aicut-keyframe-panel__dropdown-chevron\";\n    chevron.setAttribute(\"aria-hidden\", \"true\");\n    this.easingTrigger.append(this.easingTriggerLabel, chevron);\n    this.easingTrigger.addEventListener(\"click\", (e) => {\n      e.stopPropagation();\n      if (this.easingDisabled) return;\n      this.toggleEasingMenu();\n    });\n    this.easingTrigger.addEventListener(\"keydown\", (e) => {\n      if (this.easingDisabled) return;\n      if (e.key === \"Enter\" || e.key === \" \" || e.key === \"ArrowDown\") {\n        e.preventDefault();\n        if (!this.easingOpen) this.openEasingMenu();\n        // Focus the currently selected item so arrows step from there.\n        this.easingItems.get(this.easingValue)?.focus();\n      }\n    });\n\n    this.easingMenu = document.createElement(\"ul\");\n    this.easingMenu.className = \"aicut-keyframe-panel__dropdown-menu\";\n    this.easingMenu.setAttribute(\"role\", \"listbox\");\n    this.easingMenu.style.display = \"none\";\n    this.easingItems = new Map();\n    for (const value of EASING_VALUES) {\n      const li = document.createElement(\"li\");\n      li.className = \"aicut-keyframe-panel__dropdown-item\";\n      li.setAttribute(\"role\", \"option\");\n      li.setAttribute(\"data-value\", value);\n      li.setAttribute(\"tabindex\", \"-1\");\n      li.addEventListener(\"click\", (e) => {\n        e.stopPropagation();\n        this.selectEasing(value);\n      });\n      li.addEventListener(\"keydown\", (e) => this.onMenuKeydown(e, value));\n      this.easingItems.set(value, li);\n      this.easingMenu.appendChild(li);\n    }\n\n    dd.append(this.easingTrigger, this.easingMenu);\n    easingRow.append(this.easingLabelEl, dd);\n    this.root.appendChild(easingRow);\n\n    const actions = document.createElement(\"div\");\n    actions.className = \"aicut-keyframe-panel__actions\";\n    this.resetBtn = document.createElement(\"button\");\n    this.resetBtn.type = \"button\";\n    this.resetBtn.className = \"aicut-keyframe-panel__reset\";\n    this.resetBtn.setAttribute(\"data-testid\", \"aicut-keyframe-reset\");\n    this.resetBtn.addEventListener(\"click\", () => this.onReset());\n    actions.appendChild(this.resetBtn);\n    this.root.appendChild(actions);\n\n    // Paint all locale-driven text up front. setLocale() reuses this.\n    this.applyLocaleText();\n\n    host.appendChild(this.root);\n  }\n\n  setLocale(locale: Locale): void {\n    this.locale = locale;\n    this.applyLocaleText();\n    // Force a render so the time-suffix / badge tooltips also refresh\n    // (those are written inside render()'s value path).\n    this.lastSyncKey = \"\";\n    this.render();\n  }\n\n  private applyLocaleText(): void {\n    this.titleLabel.textContent = this.locale.keyframePanelTitle;\n    this.rowLabels.panX.textContent = this.locale.keyframePanelLabelX;\n    this.rowLabels.panY.textContent = this.locale.keyframePanelLabelY;\n    this.rowLabels.scale.textContent = this.locale.keyframePanelLabelScale;\n    this.easingLabelEl.textContent = this.locale.keyframePanelLabelEasing;\n    this.resetBtn.textContent = this.locale.keyframePanelReset;\n    this.resetBtn.title = this.locale.keyframePanelResetTitle;\n    // Re-label each menu item + the trigger's visible label.\n    for (const [value, li] of this.easingItems) {\n      li.textContent = easingLabel(value, this.locale);\n    }\n    this.easingTriggerLabel.textContent = easingLabel(\n      this.easingValue,\n      this.locale,\n    );\n  }\n\n  destroy(): void {\n    // Make sure the document-level listeners detached if the panel is\n    // torn down while the menu was open (e.g. editor.destroy() during\n    // an interaction).\n    this.closeEasingMenu();\n    this.root.remove();\n  }\n\n  render(): void {\n    const enabled = this.editor.isKeyframesEnabled();\n    const sel = this.editor.getSelectedKeyframe();\n    if (!enabled || !sel) {\n      this.root.style.display = \"none\";\n      this.lastSyncKey = \"\";\n      return;\n    }\n    const clip = this.findClip(sel.clipId);\n    const anchorKf = clip?.keyframes?.find((k) => k.id === sel.keyframeId);\n    if (!clip || !anchorKf) {\n      this.root.style.display = \"none\";\n      this.lastSyncKey = \"\";\n      return;\n    }\n    const time = anchorKf.time;\n    // The \"moment\" — all kfs on this clip within 16ms of the selected\n    // kf's time. Usually exactly the 3 sibling kfs from a single\n    // toolbar-button click, but we tolerate near-matches.\n    const moment = (clip.keyframes ?? []).filter(\n      (k) => Math.abs(k.time - time) < TIME_EPS_MS,\n    );\n    // Values to show: prefer the kf at this exact moment if one\n    // exists for the prop; else fall back to the currently interpolated\n    // value (held / lerped from other kfs at other times).\n    const interp = getEffectiveTransform(clip, time);\n    const valueOf = (prop: KeyframeProp): number => {\n      const m = moment.find((k) => k.prop === prop);\n      if (m) return m.value;\n      return interp[prop];\n    };\n    const v = {\n      panX: valueOf(\"panX\"),\n      panY: valueOf(\"panY\"),\n      scale: valueOf(\"scale\"),\n    };\n    // Easing shown in the dropdown — the moment's \"shared\" easing,\n    // which is the common value across panX/panY/scale at this time.\n    // If they diverge we surface the anchor kf's easing (the one the\n    // user clicked); changing the dropdown re-syncs all three.\n    const sharedEasing = (() => {\n      if (moment.length === 0) return \"linear\" as EasingKind;\n      const anchor = moment.find((k) => k.id === sel.keyframeId) ?? moment[0]!;\n      return anchor.easing ?? \"linear\";\n    })();\n    const syncKey = `${clip.id}|${time}|${v.panX.toFixed(2)}|${v.panY.toFixed(2)}|${v.scale.toFixed(4)}|${moment.map((m) => m.prop).join(\",\")}|${sharedEasing}`;\n    this.root.style.display = \"flex\";\n    if (syncKey === this.lastSyncKey) return;\n    this.lastSyncKey = syncKey;\n\n    this.setIfBlur(this.inputs.panX, String(Math.round(v.panX)));\n    this.setIfBlur(this.inputs.panY, String(Math.round(v.panY)));\n    this.setIfBlur(this.inputs.scale, v.scale.toFixed(2));\n    this.timeLabel.textContent = `${(time / 1000).toFixed(2)}${this.locale.keyframePanelTimeSuffix}`;\n    this.setEasingValue(sharedEasing);\n    // Disable when there's no kf at this moment to attach easing to —\n    // panel can also surface for \"future kf\" cases where the moment\n    // array is empty.\n    this.setEasingDisabled(moment.length === 0);\n\n    // Filled dot = a keyframe for THIS prop pins THIS moment.\n    // Outlined = no kf at this moment for the prop (the displayed\n    // value is interpolated; editing will add a kf at this time).\n    for (const p of [\"panX\", \"panY\", \"scale\"] as const) {\n      const animated =\n        moment.some((k) => k.prop === p) || hasKeyframesForProp(clip, p);\n      const pinned = moment.some((k) => k.prop === p);\n      this.kfBadges[p].classList.toggle(\n        \"aicut-keyframe-panel__badge--on\",\n        pinned,\n      );\n      this.kfBadges[p].title = pinned\n        ? this.locale.keyframePanelBadgePinned\n        : animated\n          ? this.locale.keyframePanelBadgeAnimated\n          : this.locale.keyframePanelBadgeStatic;\n    }\n    // Reset enabled when we have a clip + time to write into.\n    this.resetBtn.disabled = false;\n  }\n\n  // ---- internals ------------------------------------------------------\n\n  private makeRow(\n    testId: string,\n    prop: KeyframeProp,\n    step: number,\n  ): { input: HTMLInputElement; label: HTMLLabelElement } {\n    const row = document.createElement(\"div\");\n    row.className = \"aicut-keyframe-panel__row\";\n    const lab = document.createElement(\"label\");\n    const input = document.createElement(\"input\");\n    input.type = \"number\";\n    input.step = String(step);\n    input.setAttribute(\"data-testid\", `aicut-${testId}`);\n    input.addEventListener(\"blur\", () => this.commit(prop, input.value));\n    input.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Enter\") input.blur();\n    });\n    row.append(lab, input);\n    this.root.appendChild(row);\n    return { input, label: lab };\n  }\n\n  private makeBadge(input: HTMLInputElement): HTMLSpanElement {\n    const dot = document.createElement(\"span\");\n    dot.className = \"aicut-keyframe-panel__badge\";\n    input.parentElement?.appendChild(dot);\n    return dot;\n  }\n\n  private commit(prop: KeyframeProp, raw: string): void {\n    const num = Number(raw);\n    if (!Number.isFinite(num)) return;\n    const sel = this.editor.getSelectedKeyframe();\n    if (!sel) return;\n    const clip = this.findClip(sel.clipId);\n    const anchorKf = clip?.keyframes?.find((k) => k.id === sel.keyframeId);\n    if (!clip || !anchorKf) return;\n    // Upsert this prop's kf at the selected moment. addKeyframe with\n    // an explicit time handles upsert via the underlying helper.\n    this.editor.addKeyframe(sel.clipId, prop, {\n      time: anchorKf.time,\n      value: num,\n    });\n    // If the anchor kf is for this prop, the upsert just updated its\n    // value — keep selection. Else a new kf was created at the same\n    // time; select THAT one so the user can keep editing it.\n    if (anchorKf.prop !== prop) {\n      const refreshedClip = this.findClip(sel.clipId);\n      const created = (refreshedClip?.keyframes ?? []).find(\n        (k) =>\n          k.prop === prop && Math.abs(k.time - anchorKf.time) < TIME_EPS_MS,\n      );\n      if (created) {\n        this.editor.setSelectedKeyframe({\n          clipId: sel.clipId,\n          keyframeId: created.id,\n        });\n      }\n    }\n  }\n\n  // ---- custom dropdown -------------------------------------------------\n\n  private setEasingValue(value: EasingKind): void {\n    if (this.easingValue === value) return;\n    this.easingValue = value;\n    this.easingTriggerLabel.textContent = easingLabel(value, this.locale);\n    for (const [v, li] of this.easingItems) {\n      li.classList.toggle(\n        \"aicut-keyframe-panel__dropdown-item--selected\",\n        v === value,\n      );\n      li.setAttribute(\"aria-selected\", v === value ? \"true\" : \"false\");\n    }\n  }\n\n  private setEasingDisabled(disabled: boolean): void {\n    if (this.easingDisabled === disabled) return;\n    this.easingDisabled = disabled;\n    this.easingTrigger.disabled = disabled;\n    this.easingTrigger.classList.toggle(\n      \"aicut-keyframe-panel__dropdown-trigger--disabled\",\n      disabled,\n    );\n    if (disabled && this.easingOpen) this.closeEasingMenu();\n  }\n\n  private toggleEasingMenu(): void {\n    if (this.easingOpen) this.closeEasingMenu();\n    else this.openEasingMenu();\n  }\n\n  private openEasingMenu(): void {\n    if (this.easingOpen || this.easingDisabled) return;\n    this.easingOpen = true;\n    this.easingMenu.style.display = \"\";\n    this.easingTrigger.setAttribute(\"aria-expanded\", \"true\");\n    this.easingTrigger.classList.add(\n      \"aicut-keyframe-panel__dropdown-trigger--open\",\n    );\n    // rAF defers the listeners so the same click event that opened\n    // the menu doesn't immediately close it via the outside-click path.\n    requestAnimationFrame(() => {\n      if (!this.easingOpen) return;\n      this.boundOutsideClick = (e: MouseEvent) => {\n        if (!this.easingMenu.contains(e.target as Node)\n          && !this.easingTrigger.contains(e.target as Node)) {\n          this.closeEasingMenu();\n        }\n      };\n      this.boundDocKeydown = (e: KeyboardEvent) => {\n        if (e.key === \"Escape\") {\n          e.stopPropagation();\n          this.closeEasingMenu();\n          this.easingTrigger.focus();\n        } else if (e.key === \"Tab\") {\n          // Tabbing out should close the menu.\n          this.closeEasingMenu();\n        }\n      };\n      document.addEventListener(\"click\", this.boundOutsideClick, true);\n      document.addEventListener(\"keydown\", this.boundDocKeydown);\n    });\n  }\n\n  private closeEasingMenu(): void {\n    if (!this.easingOpen) return;\n    this.easingOpen = false;\n    this.easingMenu.style.display = \"none\";\n    this.easingTrigger.setAttribute(\"aria-expanded\", \"false\");\n    this.easingTrigger.classList.remove(\n      \"aicut-keyframe-panel__dropdown-trigger--open\",\n    );\n    if (this.boundOutsideClick) {\n      document.removeEventListener(\"click\", this.boundOutsideClick, true);\n      this.boundOutsideClick = null;\n    }\n    if (this.boundDocKeydown) {\n      document.removeEventListener(\"keydown\", this.boundDocKeydown);\n      this.boundDocKeydown = null;\n    }\n  }\n\n  private selectEasing(value: EasingKind): void {\n    this.closeEasingMenu();\n    this.easingTrigger.focus();\n    const sel = this.editor.getSelectedKeyframe();\n    if (!sel) return;\n    const clip = this.findClip(sel.clipId);\n    const anchorKf = clip?.keyframes?.find((k) => k.id === sel.keyframeId);\n    if (!clip || !anchorKf) return;\n    this.editor.setKeyframesEasingAtTime(sel.clipId, anchorKf.time, value);\n  }\n\n  private onMenuKeydown(e: KeyboardEvent, value: EasingKind): void {\n    if (e.key === \"Enter\" || e.key === \" \") {\n      e.preventDefault();\n      this.selectEasing(value);\n      return;\n    }\n    if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n      e.preventDefault();\n      const idx = EASING_VALUES.indexOf(value);\n      const next = e.key === \"ArrowDown\"\n        ? EASING_VALUES[(idx + 1) % EASING_VALUES.length]!\n        : EASING_VALUES[(idx - 1 + EASING_VALUES.length) % EASING_VALUES.length]!;\n      this.easingItems.get(next)?.focus();\n    }\n  }\n\n  private onReset(): void {\n    const sel = this.editor.getSelectedKeyframe();\n    if (!sel) return;\n    const clip = this.findClip(sel.clipId);\n    const anchorKf = clip?.keyframes?.find((k) => k.id === sel.keyframeId);\n    if (!clip || !anchorKf) return;\n    this.editor.resetKeyframesAtTime(sel.clipId, anchorKf.time);\n  }\n\n  private setIfBlur(input: HTMLInputElement, value: string): void {\n    if (document.activeElement === input) return;\n    if (input.value !== value) input.value = value;\n  }\n\n  private findClip(clipId: string): Clip | null {\n    const project = this.editor.getProject();\n    for (const t of project.tracks) {\n      const c = t.clips.find((cl) => cl.id === clipId);\n      if (c) return c;\n    }\n    return null;\n  }\n}\n// Re-export internal helper for tests / docs that want to walk the\n// per-prop keyframe lists with the same sort the panel uses.\nexport { keyframesForProp };\n","/**\n * Inline SVG icon set. Strings, not JSX, since core has no framework.\n * Each icon is 14×14 paint-area inside a 16×16 viewbox; `currentColor`\n * so toolbar buttons can recolor by `color`.\n */\n\nconst wrap = (path: string) =>\n  `<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">${path}</svg>`;\n\nexport const ICONS = {\n  undo: wrap(\n    `<g transform=\"translate(1 1)\"><path d=\"M5.66577 1.38721L2.85034 4.20264H9.64624C11.8471 4.20264 13.6313 5.98724 13.6316 8.18799C13.6315 10.3889 11.8472 12.1733 9.64624 12.1733H7.19116V11.1235H9.64624C11.2673 11.1235 12.5817 9.80904 12.5818 8.18799C12.5815 6.56714 11.2672 5.25342 9.64624 5.25342H2.85034L5.66577 8.06885L4.92358 8.81201L0.8396 4.72803L4.92358 0.644043L5.66577 1.38721Z\" fill=\"currentColor\"/></g>`,\n  ),\n  redo: wrap(\n    `<g transform=\"translate(1 1)\"><path d=\"M8.55005 2.04655L11.3659 4.86239L4.56982 4.86239C2.36897 4.86251 0.584578 6.64687 0.584473 8.84774C0.584646 11.0485 2.36901 12.833 4.56982 12.8331L7.0245 12.8331L7.0245 11.7832H4.56982C2.94891 11.7831 1.63453 10.4686 1.63436 8.84774C1.63446 7.22677 2.94886 5.91297 4.56982 5.91284H11.3659L8.55005 8.72811L9.29289 9.47095L13.3768 5.38761L9.29289 1.30371L8.55005 2.04655Z\" fill=\"currentColor\"/></g>`,\n  ),\n  split: wrap(\n    `<g transform=\"translate(1 1)\"><path d=\"M5.7168 12.7754H1.75V11.7246H4.68164V2.27539H1.75V1.22461H5.7168V12.7754ZM12.25 2.27539H9.31836V11.7246H12.25V12.7754H8.2832V1.22461H12.25V2.27539Z\" fill=\"currentColor\"/></g>`,\n  ),\n  trimLeft: wrap(\n    `<g transform=\"translate(1 1)\"><path d=\"M2.7998 12.7754H1.75V11.7246H2.7998V12.7754ZM4.25781 12.7754H3.20801V11.7246H4.25781V12.7754ZM5.7168 12.7754H4.66699V11.7246H5.7168V12.7754ZM12.25 2.27539H9.31836V11.7246H12.25V12.7754H8.2832V1.22461H12.25V2.27539ZM5.7168 11.0254H4.66699V9.97461H5.7168V11.0254ZM5.7168 9.27539H4.66699V8.22461H5.7168V9.27539ZM5.7168 7.52539H4.66699V6.47461H5.7168V7.52539ZM5.7168 5.77539H4.66699V4.72461H5.7168V5.77539ZM5.7168 4.02539H4.66699V2.97461H5.7168V4.02539ZM2.7998 2.27539H1.75V1.22461H2.7998V2.27539ZM4.25781 2.27539H3.20801V1.22461H4.25781V2.27539ZM5.7168 2.27539H4.66699V1.22461H5.7168V2.27539Z\" fill=\"currentColor\"/></g>`,\n  ),\n  trimRight: wrap(\n    `<g transform=\"translate(1 1)\"><path d=\"M5.7168 12.7754H1.75V11.7246H4.68164V2.27539H1.75V1.22461H5.7168V12.7754ZM9.33301 12.7754H8.2832V11.7246H9.33301V12.7754ZM10.792 12.7754H9.74219V11.7246H10.792V12.7754ZM12.25 12.7754H11.2002V11.7246H12.25V12.7754ZM9.33301 11.0254H8.2832V9.97461H9.33301V11.0254ZM9.33301 9.27539H8.2832V8.22461H9.33301V9.27539ZM9.33301 7.52539H8.2832V6.47461H9.33301V7.52539ZM9.33301 5.77539H8.2832V4.72461H9.33301V5.77539ZM9.33301 4.02539H8.2832V2.97461H9.33301V4.02539ZM9.33301 2.27539H8.2832V1.22461H9.33301V2.27539ZM10.792 2.27539H9.74219V1.22461H10.792V2.27539ZM12.25 2.27539H11.2002V1.22461H12.25V2.27539Z\" fill=\"currentColor\"/></g>`,\n  ),\n  speed: wrap(\n    `<g transform=\"translate(1 1)\"><path d=\"M7.00175 0.595229C7.32353 0.596316 7.58439 0.858333 7.58378 1.18019C7.583 1.50212 7.32071 1.76265 6.99882 1.76222C6.45361 1.76108 5.90722 1.8449 5.38065 2.01417C4.23393 2.38294 3.24874 3.13519 2.59061 4.14406C1.93249 5.15302 1.64169 6.35801 1.76639 7.55617C1.89121 8.75413 2.4235 9.87343 3.27518 10.7251C4.12694 11.5767 5.24613 12.1092 6.44413 12.2339C7.6422 12.3585 8.84735 12.0678 9.85624 11.4097C10.8649 10.7516 11.6173 9.76618 11.9861 8.61964C12.5967 6.72047 12.1219 5.04361 11.0633 3.76124L8.57792 6.24757C8.68682 6.4756 8.74974 6.72999 8.74979 6.99953C8.74979 7.9659 7.96612 8.74933 6.99979 8.74953C6.03345 8.74934 5.24979 7.96591 5.24979 6.99953C5.24997 6.03329 6.03356 5.24971 6.99979 5.24953C7.26941 5.24958 7.52464 5.31244 7.75272 5.4214L10.6707 2.50441L10.7137 2.46535C10.8174 2.38043 10.9485 2.33351 11.0838 2.33351C11.2382 2.33369 11.3867 2.39519 11.4959 2.50441C13.0855 4.09426 13.9307 6.38102 13.0965 8.97609C12.6458 10.3776 11.726 11.5819 10.493 12.3862C9.25989 13.1905 7.7873 13.5464 6.32303 13.3941C4.8588 13.2416 3.49099 12.5903 2.44999 11.5493C1.40904 10.5083 0.757676 9.14058 0.605261 7.67628C0.452904 6.21196 0.808759 4.73947 1.61307 3.50636C2.41742 2.27338 3.62178 1.35455 5.02323 0.903823C5.66695 0.696861 6.33524 0.593807 7.00175 0.595229Z\" fill=\"currentColor\"/></g>`,\n  ),\n  play: wrap(\n    // Triangle bbox center at viewBox x=9.4 vs viewBox center 8 — the\n    // raw path leans right. Optical centering: translate by half the\n    // bbox offset (-0.7) so the centroid stays near 7.5 (slight left\n    // of center, which the eye accepts as balanced for a right-pointing\n    // triangle) while the bbox is no longer obviously off to one side.\n    `<g transform=\"translate(-0.7 0)\"><path d=\"M4.66699 2.64248C4.66717 1.82358 5.59736 1.35167 6.25781 1.83584L13.5674 7.19619C14.1117 7.59579 14.1118 8.40897 13.5674 8.8085L6.25781 14.1688C5.59734 14.6528 4.6671 14.1811 4.66699 13.3622V2.64248Z\" fill=\"currentColor\"/></g>`,\n  ),\n  pause: wrap(\n    `<path d=\"M4 3h2.5v10H4V3zm5.5 0H12v10H9.5V3z\" fill=\"currentColor\"/>`,\n  ),\n  fullscreen:\n    `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 3H5a2 2 0 00-2 2v3\"/><path d=\"M21 8V5a2 2 0 00-2-2h-3\"/><path d=\"M3 16v3a2 2 0 002 2h3\"/><path d=\"M16 21h3a2 2 0 002-2v-3\"/></svg>`,\n  snap:\n    `<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M8.275.783a5.07 5.07 0 0 1 4.929 4.927 5.07 5.07 0 0 1-1.311 3.542l-3.937 3.95a.526.526 0 0 1-.744 0l-2.334-2.334a.525.525 0 0 1 .001-.743l2.55-2.538a.5.5 0 0 1 .171-.17l.976-.97a.723.723 0 0 0-1.01-1.008L3.87 9.12a.526.526 0 0 1-.743 0L.795 6.784a.526.526 0 0 1 0-.742l3.937-3.95.022-.02a5.07 5.07 0 0 1 3.52-1.29m-2.281 9.715 1.588 1.589 1.884-1.889-1.583-1.583zm2.253-8.666a4.02 4.02 0 0 0-2.785 1.017l-.936.939 1.602 1.603.729-.726.052-.045a1.776 1.776 0 0 1 2.33.154 1.775 1.775 0 0 1 .155 2.332 1 1 0 0 1-.046.053l-.72.716 1.58 1.58.924-.929a4.019 4.019 0 0 0-2.885-6.694M1.909 6.413 3.5 8.005 5.384 6.13l-1.6-1.6z\"/></svg>`,\n  zoomOut:\n    `<svg width=\"14\" height=\"14\" viewBox=\"0 0 20.2618 20.2564\" fill=\"none\" aria-hidden=\"true\"><path d=\"M9 0C13.9706 0 18 4.02944 18 9C18 11.1612 17.2374 13.1438 15.9678 14.6953L19.998 18.7197C20.3494 19.071 20.3498 19.6404 19.999 19.9922C19.6476 20.3441 19.0775 20.3446 18.7256 19.9932L14.6953 15.9678C13.1438 17.2374 11.1612 18 9 18C4.02944 18 0 13.9706 0 9C0 4.02944 4.02944 0 9 0ZM9 1.7998C5.02355 1.7998 1.7998 5.02355 1.7998 9C1.7998 12.9765 5.02355 16.2002 9 16.2002C12.9765 16.2002 16.2002 12.9765 16.2002 9C16.2002 5.02355 12.9765 1.7998 9 1.7998ZM12.5996 8.09961C13.0969 8.09961 13.5 8.50273 13.5 9C13.5 9.49727 13.0969 9.90039 12.5996 9.90039H5.40039C4.90312 9.90039 4.5 9.49727 4.5 9C4.5 8.50273 4.90312 8.09961 5.40039 8.09961H12.5996Z\" fill=\"currentColor\"/></svg>`,\n  zoomIn:\n    `<svg width=\"14\" height=\"14\" viewBox=\"0 0 20.2613 20.2565\" fill=\"none\" aria-hidden=\"true\"><path d=\"M9 0C13.9705 6.59711e-05 18 4.02948 18 9C18 11.1612 17.2374 13.1438 15.9678 14.6953L19.9971 18.7197C20.3489 19.0711 20.3494 19.6403 19.998 19.9922C19.6466 20.3441 19.0765 20.3446 18.7246 19.9932L14.6953 15.9678C13.1438 17.2374 11.1611 18 9 18C4.02944 18 0 13.9706 0 9C0 4.02944 4.02944 0 9 0ZM9 1.7998C5.02355 1.7998 1.7998 5.02355 1.7998 9C1.7998 12.9765 5.02355 16.2002 9 16.2002C12.9764 16.2001 16.2002 12.9764 16.2002 9C16.2002 5.02359 12.9764 1.79987 9 1.7998ZM8.99512 4.50488C9.49233 4.50495 9.89551 4.90804 9.89551 5.40527V8.09961H12.5996C13.0968 8.09968 13.5 8.50277 13.5 9C13.5 9.49723 13.0968 9.90032 12.5996 9.90039H9.89551V12.6045C9.89551 13.1017 9.49233 13.5048 8.99512 13.5049C8.49785 13.5049 8.09473 13.1018 8.09473 12.6045V9.90039H5.40039C4.90312 9.90039 4.5 9.49727 4.5 9C4.5 8.50273 4.90312 8.09961 5.40039 8.09961H8.09473V5.40527C8.09473 4.908 8.49785 4.50488 8.99512 4.50488Z\" fill=\"currentColor\"/></svg>`,\n  export:\n    `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/></svg>`,\n  addTrack: wrap(\n    `<g transform=\"translate(2 2)\"><rect x=\"0\" y=\"1.5\" width=\"12\" height=\"2.5\" rx=\"0.5\" fill=\"currentColor\"/><rect x=\"0\" y=\"8\" width=\"12\" height=\"2.5\" rx=\"0.5\" fill=\"currentColor\" opacity=\"0.55\"/><circle cx=\"10\" cy=\"10\" r=\"3.4\" fill=\"currentColor\"/><rect x=\"9.4\" y=\"8.5\" width=\"1.2\" height=\"3\" rx=\"0.4\" fill=\"#fff\"/><rect x=\"8.5\" y=\"9.4\" width=\"3\" height=\"1.2\" rx=\"0.4\" fill=\"#fff\"/></g>`,\n  ),\n  trash: wrap(\n    `<g transform=\"translate(1 1)\" fill=\"currentColor\"><path d=\"M5 1.25h4v.9H13v1.05H1V2.15h4v-.9zM2.4 4.1h9.2l-.65 8.9c-.04.55-.5.96-1.05.96H4.1c-.55 0-1.01-.41-1.05-.96L2.4 4.1zm2.3 1.7l.35 7.1h1l-.35-7.1h-1zm2.65 0v7.1h1V5.8h-1zm2.3 0l-.35 7.1h1l.35-7.1h-1z\"/></g>`,\n  ),\n  /** \"Skip to start\" — vertical bar + left-pointing triangle. Sits to\n   *  the left of the keyframe diamond so the clip-edge nav cluster\n   *  reads as [|◀ ◇ ▶|] = \"go to clip start / add kf / go to clip end\". */\n  seekClipStart: wrap(\n    `<g transform=\"translate(2 3)\" fill=\"currentColor\"><rect x=\"0\" y=\"0\" width=\"1.6\" height=\"10\" rx=\"0.4\"/><path d=\"M11 0.6c0-0.5-0.55-0.78-0.95-0.48l-6.5 4.4c-0.34 0.23-0.34 0.73 0 0.96l6.5 4.4c0.4 0.3 0.95 0.02 0.95-0.48z\"/></g>`,\n  ),\n  /** \"Skip to end\" — mirror of seekClipStart. */\n  seekClipEnd: wrap(\n    `<g transform=\"translate(1 3)\" fill=\"currentColor\"><path d=\"M0 0.6c0-0.5 0.55-0.78 0.95-0.48l6.5 4.4c0.34 0.23 0.34 0.73 0 0.96l-6.5 4.4c-0.4 0.3-0.95 0.02-0.95-0.48z\"/><rect x=\"10.4\" y=\"0\" width=\"1.6\" height=\"10\" rx=\"0.4\"/></g>`,\n  ),\n  /** Outlined diamond (rotated square) — \"add keyframe\" affordance. */\n  keyframeOutline: wrap(\n    `<g transform=\"translate(8 8) rotate(45) translate(-4 -4)\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><rect x=\"0.5\" y=\"0.5\" width=\"7\" height=\"7\" rx=\"0.5\"/></g>`,\n  ),\n  /** Filled diamond — shown when a keyframe already exists at playhead. */\n  keyframeFilled: wrap(\n    `<g transform=\"translate(8 8) rotate(45) translate(-4 -4)\" fill=\"currentColor\"><rect x=\"0\" y=\"0\" width=\"8\" height=\"8\" rx=\"0.8\"/></g>`,\n  ),\n  /** Aspect-ratio picker — outlined rounded rectangle (landscape\n   *  proportions) with a portrait rectangle nested inside it. Matches\n   *  CapCut's \"比例\" affordance: a frame-within-frame conveying\n   *  \"choose which output canvas to crop into\". */\n  aspect: wrap(\n    `<g transform=\"translate(1 1.5)\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"0.6\" y=\"2.4\" width=\"12.8\" height=\"8.2\" rx=\"1.2\"/><rect x=\"4.6\" y=\"4.4\" width=\"4.8\" height=\"6.2\" rx=\"0.9\" stroke-width=\"1.1\" opacity=\"0.85\"/></g>`,\n  ),\n  /** Picture-in-picture frame outline + smaller inset frame at the\n   *  top-right corner. Outlined when PiP is off. */\n  pipOutline: wrap(\n    `<g transform=\"translate(1.5 2)\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"0.5\" y=\"0.5\" width=\"12\" height=\"9\" rx=\"1.2\"/><rect x=\"6.8\" y=\"3\" width=\"5\" height=\"4\" rx=\"0.6\" stroke-width=\"1.1\"/></g>`,\n  ),\n  /** Filled inset frame — PiP is on. */\n  pipFilled: wrap(\n    `<g transform=\"translate(1.5 2)\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"0.5\" y=\"0.5\" width=\"12\" height=\"9\" rx=\"1.2\"/><rect x=\"6.8\" y=\"3\" width=\"5\" height=\"4\" rx=\"0.6\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n  ),\n  /** Counter-clockwise circular arrow — \"reset to initial layout\". */\n  reset:\n    `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/></svg>`,\n};\n\nexport type IconName = keyof typeof ICONS;\n","import type { Locale } from \"../i18n.js\";\nimport { fmtClock } from \"./format.js\";\nimport { ICONS } from \"./icons.js\";\n\n/**\n * Playback controls rendered as an overlay inside the preview area\n * (CapCut-desktop style). Owns the time / play / duration /\n * fullscreen affordances that used to live in the top toolbar's\n * center cluster. Mounting these inside the preview lets the\n * toolbar collapse to its edit + viewport clusters, frees up\n * vertical pixels, and gives the playback chrome a contextual home\n * next to the video it controls.\n */\nexport interface PreviewControlsCallbacks {\n  onPlayToggle: () => void;\n  onFullscreen: () => void;\n}\n\nexport interface PreviewControlsState {\n  playing: boolean;\n  time: number;\n  duration: number;\n}\n\nexport class PreviewControls {\n  readonly element: HTMLDivElement;\n  private playBtn: HTMLButtonElement;\n  private playIcon: HTMLSpanElement;\n  private timeLabel: HTMLSpanElement;\n  private durationLabel: HTMLSpanElement;\n  private fullscreenBtn: HTMLButtonElement;\n  private locale: Locale;\n  private lastState: PreviewControlsState | null = null;\n\n  constructor(cb: PreviewControlsCallbacks, locale: Locale) {\n    this.locale = locale;\n    this.element = document.createElement(\"div\");\n    this.element.className = \"aicut-preview-controls\";\n    this.element.setAttribute(\"data-testid\", \"aicut-preview-controls\");\n\n    this.timeLabel = document.createElement(\"span\");\n    this.timeLabel.className = \"aicut-time-current\";\n    this.timeLabel.setAttribute(\"data-testid\", \"aicut-time-current\");\n    this.timeLabel.textContent = \"00:00\";\n\n    this.playBtn = document.createElement(\"button\");\n    this.playBtn.type = \"button\";\n    this.playBtn.className = \"aicut-play-btn\";\n    this.playBtn.title = locale.playPause;\n    this.playBtn.setAttribute(\"aria-label\", locale.playPause);\n    this.playBtn.setAttribute(\"data-testid\", \"aicut-play\");\n    this.playIcon = document.createElement(\"span\");\n    this.playIcon.innerHTML = ICONS.play;\n    this.playBtn.appendChild(this.playIcon);\n    this.playBtn.addEventListener(\"click\", () => cb.onPlayToggle());\n\n    this.durationLabel = document.createElement(\"span\");\n    this.durationLabel.className = \"aicut-time-total\";\n    this.durationLabel.setAttribute(\"data-testid\", \"aicut-time-total\");\n    this.durationLabel.textContent = \"00:00\";\n\n    this.fullscreenBtn = document.createElement(\"button\");\n    this.fullscreenBtn.type = \"button\";\n    this.fullscreenBtn.className = \"aicut-icon-btn aicut-fullscreen\";\n    this.fullscreenBtn.title = locale.fullscreen;\n    this.fullscreenBtn.setAttribute(\"aria-label\", locale.fullscreen);\n    this.fullscreenBtn.setAttribute(\"data-testid\", \"aicut-fullscreen\");\n    this.fullscreenBtn.innerHTML = ICONS.fullscreen;\n    this.fullscreenBtn.addEventListener(\"click\", () => cb.onFullscreen());\n\n    this.element.append(\n      this.timeLabel,\n      this.playBtn,\n      this.durationLabel,\n      this.fullscreenBtn,\n    );\n  }\n\n  render(state: PreviewControlsState): void {\n    if (!this.lastState || this.lastState.time !== state.time) {\n      this.timeLabel.textContent = fmtClock(state.time);\n    }\n    if (!this.lastState || this.lastState.duration !== state.duration) {\n      this.durationLabel.textContent = fmtClock(state.duration);\n    }\n    if (!this.lastState || this.lastState.playing !== state.playing) {\n      this.playIcon.innerHTML = state.playing ? ICONS.pause : ICONS.play;\n      this.playBtn.setAttribute(\n        \"data-state\",\n        state.playing ? \"playing\" : \"paused\",\n      );\n    }\n    this.lastState = { ...state };\n  }\n\n  setLocale(locale: Locale): void {\n    this.locale = locale;\n    this.playBtn.title = locale.playPause;\n    this.playBtn.setAttribute(\"aria-label\", locale.playPause);\n    this.fullscreenBtn.title = locale.fullscreen;\n    this.fullscreenBtn.setAttribute(\"aria-label\", locale.fullscreen);\n  }\n\n  destroy(): void {\n    this.element.remove();\n  }\n}\n","import type { Locale } from \"../i18n.js\";\nimport type { AspectRatio } from \"../types.js\";\n\n/**\n * Common output ratios offered in the picker. Matches CapCut's roster\n * so users coming from CapCut find their muscle memory intact. Ordered\n * landscape → portrait → square → classic to mirror what the popover\n * shows visually.\n */\nexport const ASPECT_OPTIONS: ReadonlyArray<{\n  value: AspectRatio;\n  label: string;\n  /** Aspect for the preview tile inside the menu — width-major. */\n  tileW: number;\n  tileH: number;\n}> = [\n  { value: \"16:9\", label: \"16:9\", tileW: 22, tileH: 12 },\n  { value: \"9:16\", label: \"9:16\", tileW: 12, tileH: 22 },\n  { value: \"1:1\", label: \"1:1\", tileW: 18, tileH: 18 },\n  { value: \"4:3\", label: \"4:3\", tileW: 22, tileH: 16 },\n  { value: \"3:4\", label: \"3:4\", tileW: 16, tileH: 22 },\n  { value: \"4:5\", label: \"4:5\", tileW: 16, tileH: 20 },\n  { value: \"21:9\", label: \"21:9\", tileW: 24, tileH: 10 },\n];\n\nexport interface AspectPickerCallbacks {\n  onChange: (aspect: AspectRatio | null) => void;\n}\n\n/**\n * Built-in aspect-ratio picker. Renders a chip-style button that opens\n * a popover with the common ratios listed in `ASPECT_OPTIONS`. The\n * \"Original\" entry clears `Project.aspect`. Popover positioning uses\n * `position: fixed` to escape the toolbar's overflow clipping.\n */\nexport class AspectPicker {\n  readonly element: HTMLDivElement;\n  private button: HTMLButtonElement;\n  private valueLabel: HTMLSpanElement;\n  private popover: HTMLDivElement | null = null;\n  private cb: AspectPickerCallbacks;\n  private locale: Locale;\n  private value: AspectRatio | null = null;\n  private docClick: ((e: MouseEvent) => void) | null = null;\n  private docKey: ((e: KeyboardEvent) => void) | null = null;\n  private docResize: (() => void) | null = null;\n\n  constructor(cb: AspectPickerCallbacks, locale: Locale) {\n    this.cb = cb;\n    this.locale = locale;\n    this.element = document.createElement(\"div\");\n    this.element.className = \"aicut-aspect-picker\";\n    this.element.setAttribute(\"data-testid\", \"aicut-aspect-picker\");\n\n    this.button = document.createElement(\"button\");\n    this.button.type = \"button\";\n    this.button.className = \"aicut-aspect-trigger\";\n    this.button.setAttribute(\"aria-haspopup\", \"menu\");\n    this.button.setAttribute(\"aria-expanded\", \"false\");\n    this.button.setAttribute(\"data-testid\", \"aicut-aspect-trigger\");\n\n    // Dropped the leading frame icon — the ratio label (\"16:9\" /\n    // \"1:1\" / etc.) is more informative AND tabular, so the chip\n    // stays compact and self-explanatory without the extra glyph.\n    this.valueLabel = document.createElement(\"span\");\n    this.valueLabel.className = \"aicut-aspect-trigger-label\";\n\n    const caret = document.createElement(\"span\");\n    caret.className = \"aicut-aspect-trigger-caret\";\n    caret.setAttribute(\"aria-hidden\", \"true\");\n    caret.innerHTML =\n      `<svg width=\"8\" height=\"8\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\"><path d=\"M2 4l3 3 3-3\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\n    this.button.append(this.valueLabel, caret);\n    this.button.addEventListener(\"click\", () => this.toggle());\n    this.element.appendChild(this.button);\n\n    this.applyLocale();\n    this.applyValue();\n  }\n\n  setLocale(locale: Locale): void {\n    this.locale = locale;\n    this.applyLocale();\n    if (this.popover) {\n      this.closePopover();\n      this.openPopover();\n    }\n  }\n\n  setValue(value: AspectRatio | null): void {\n    if (value === this.value) return;\n    this.value = value;\n    this.applyValue();\n    if (this.popover) this.refreshSelectedState();\n  }\n\n  destroy(): void {\n    this.closePopover();\n    this.element.remove();\n  }\n\n  private applyLocale(): void {\n    this.button.title = this.locale.aspectTitle;\n    this.button.setAttribute(\"aria-label\", this.locale.aspectTitle);\n  }\n\n  private applyValue(): void {\n    this.valueLabel.textContent = this.value ?? this.locale.aspectOriginal;\n  }\n\n  private toggle(): void {\n    if (this.popover) this.closePopover();\n    else this.openPopover();\n  }\n\n  private openPopover(): void {\n    if (this.popover) return;\n    const pop = document.createElement(\"div\");\n    pop.className = \"aicut-aspect-menu\";\n    pop.setAttribute(\"role\", \"menu\");\n    pop.setAttribute(\"data-testid\", \"aicut-aspect-menu\");\n\n    const header = document.createElement(\"div\");\n    header.className = \"aicut-aspect-menu-header\";\n    header.textContent = this.locale.aspectMenuLabel;\n    pop.appendChild(header);\n\n    const grid = document.createElement(\"div\");\n    grid.className = \"aicut-aspect-menu-grid\";\n\n    for (const opt of ASPECT_OPTIONS) {\n      grid.appendChild(this.makeOption(opt.value, opt.label, opt.tileW, opt.tileH));\n    }\n    // \"Original\" is a separate option at the end — picking it clears\n    // `Project.aspect` so the host falls back to whatever default it\n    // was using before the picker existed.\n    grid.appendChild(this.makeOption(null, this.locale.aspectOriginal, 20, 16));\n\n    pop.appendChild(grid);\n    document.body.appendChild(pop);\n    this.popover = pop;\n    this.button.setAttribute(\"aria-expanded\", \"true\");\n    // Popover lives outside `.aicut-root`, so the editor's CSS\n    // custom properties don't cascade in. Copy the ones the popover\n    // styles depend on so the theme follows the editor that opened it.\n    const cs = getComputedStyle(this.button);\n    for (const name of [\n      \"--aicut-controls-bg\",\n      \"--aicut-controls-border\",\n      \"--aicut-controls-text\",\n      \"--aicut-controls-hover\",\n      \"--aicut-controls-active\",\n      \"--color-brand\",\n    ]) {\n      const v = cs.getPropertyValue(name).trim();\n      if (v) pop.style.setProperty(name, v);\n    }\n    this.positionPopover();\n    this.refreshSelectedState();\n\n    this.docClick = (e) => {\n      const t = e.target as Node | null;\n      if (!t) return;\n      if (this.popover?.contains(t)) return;\n      if (this.button.contains(t)) return;\n      this.closePopover();\n    };\n    this.docKey = (e) => {\n      if (e.key === \"Escape\") {\n        e.preventDefault();\n        this.closePopover();\n        this.button.focus();\n      }\n    };\n    this.docResize = () => this.positionPopover();\n    // Defer until after this click event finishes so the synthetic\n    // toggle click doesn't immediately close us.\n    setTimeout(() => {\n      if (!this.docClick) return;\n      document.addEventListener(\"mousedown\", this.docClick, true);\n    }, 0);\n    document.addEventListener(\"keydown\", this.docKey);\n    window.addEventListener(\"resize\", this.docResize);\n    window.addEventListener(\"scroll\", this.docResize, true);\n  }\n\n  private closePopover(): void {\n    if (!this.popover) return;\n    this.popover.remove();\n    this.popover = null;\n    this.button.setAttribute(\"aria-expanded\", \"false\");\n    if (this.docClick) {\n      document.removeEventListener(\"mousedown\", this.docClick, true);\n      this.docClick = null;\n    }\n    if (this.docKey) {\n      document.removeEventListener(\"keydown\", this.docKey);\n      this.docKey = null;\n    }\n    if (this.docResize) {\n      window.removeEventListener(\"resize\", this.docResize);\n      window.removeEventListener(\"scroll\", this.docResize, true);\n      this.docResize = null;\n    }\n  }\n\n  private positionPopover(): void {\n    if (!this.popover) return;\n    const r = this.button.getBoundingClientRect();\n    const padding = 8;\n    // Default: open below, left-aligned with the button.\n    let top = r.bottom + 6;\n    let left = r.left;\n    const popRect = this.popover.getBoundingClientRect();\n    const vw = window.innerWidth;\n    const vh = window.innerHeight;\n    if (left + popRect.width + padding > vw) {\n      left = Math.max(padding, vw - popRect.width - padding);\n    }\n    if (top + popRect.height + padding > vh) {\n      // Flip above when there's no room below.\n      top = Math.max(padding, r.top - popRect.height - 6);\n    }\n    this.popover.style.position = \"fixed\";\n    this.popover.style.top = `${Math.round(top)}px`;\n    this.popover.style.left = `${Math.round(left)}px`;\n  }\n\n  private refreshSelectedState(): void {\n    if (!this.popover) return;\n    const items = this.popover.querySelectorAll<HTMLButtonElement>(\n      \".aicut-aspect-option\",\n    );\n    for (const el of items) {\n      const v = el.getAttribute(\"data-aspect\");\n      const matches = v === (this.value ?? \"__original__\");\n      el.classList.toggle(\"aicut-aspect-option-active\", matches);\n      el.setAttribute(\"aria-checked\", matches ? \"true\" : \"false\");\n    }\n  }\n\n  private makeOption(\n    value: AspectRatio | null,\n    label: string,\n    tileW: number,\n    tileH: number,\n  ): HTMLButtonElement {\n    const btn = document.createElement(\"button\");\n    btn.type = \"button\";\n    btn.className = \"aicut-aspect-option\";\n    btn.setAttribute(\"role\", \"menuitemradio\");\n    btn.setAttribute(\"data-aspect\", value ?? \"__original__\");\n    btn.setAttribute(\"data-testid\", `aicut-aspect-option-${value ?? \"original\"}`);\n\n    const tileWrap = document.createElement(\"span\");\n    tileWrap.className = \"aicut-aspect-option-tile-wrap\";\n    const tile = document.createElement(\"span\");\n    tile.className = \"aicut-aspect-option-tile\";\n    tile.style.width = `${tileW}px`;\n    tile.style.height = `${tileH}px`;\n    tileWrap.appendChild(tile);\n\n    const text = document.createElement(\"span\");\n    text.className = \"aicut-aspect-option-label\";\n    text.textContent = label;\n\n    btn.append(tileWrap, text);\n    btn.addEventListener(\"click\", () => {\n      this.cb.onChange(value);\n      this.closePopover();\n    });\n    return btn;\n  }\n}\n","import type { Locale } from \"../i18n.js\";\nimport { SCALE_MAX, SCALE_MIN } from \"../timeline/layout.js\";\nimport type { AspectRatio } from \"../types.js\";\nimport { AspectPicker } from \"./aspect-picker.js\";\nimport { ICONS, type IconName } from \"./icons.js\";\n\nexport interface ToolbarCallbacks {\n  onUndo: () => void;\n  onRedo: () => void;\n  onSplit: () => void;\n  onTrimLeft: () => void;\n  onTrimRight: () => void;\n  onReset: () => void;\n  onSnapToggle: () => void;\n  onScaleChange: (pxPerSec: number) => void;\n  /** Add a keyframe at the playhead — or remove the existing one if\n   *  a keyframe already sits exactly at the playhead's clip-local time\n   *  (CapCut-style toggle on the same button). */\n  onKeyframeToggle: () => void;\n  /** Move the playhead to the selected clip's start / end. End seek\n   *  intentionally lands 1ms inside the clip so subsequent\n   *  keyframe-add finds the clip — see Editor.seekToSelectedClipEdge. */\n  onSeekClipStart: () => void;\n  onSeekClipEnd: () => void;\n  /** User picked an output aspect from the built-in picker. `null`\n   *  means \"Original\" (clear Project.aspect). */\n  onAspectChange: (aspect: AspectRatio | null) => void;\n  /** \"+ PiP overlay\" toolbar button click — the editor fires\n   *  `requestPictureInPictureAdd` and lets the host's upload pipeline\n   *  take over. The library doesn't run an upload itself. */\n  onPictureInPictureAdd: () => void;\n}\n\ninterface ToolbarState {\n  canUndo: boolean;\n  canRedo: boolean;\n  canSplit: boolean;\n  canTrim: boolean;\n  snap: boolean;\n  pxPerSec: number;\n  /** True when keyframe mode is enabled AND the selected clip\n   *  contains the playhead — only then is the button clickable. */\n  canKeyframe: boolean;\n  /** True when a keyframe exists at the exact playhead time on the\n   *  selected clip. Drives the button icon (filled vs outlined) and\n   *  the tooltip (remove vs add). */\n  hasKeyframeAtPlayhead: boolean;\n  /** Only render the keyframe button at all when keyframe mode is on,\n   *  matching the user's \"demo只一个开关\" requirement — chrome stays\n   *  identical to today when the feature is disabled. */\n  keyframesEnabled: boolean;\n  /** Enable the |◀ / ▶| jump-to-clip-edge buttons. Mirrors the\n   *  selection-driven gating used by split / trim. */\n  canSeekClipEdge: boolean;\n  /** Host opt-in for the clip-edge nav cluster. Matches the keyframes\n   *  toggle pattern: when off the |◀ / ▶| buttons are completely\n   *  hidden (display: none) so they don't take up toolbar real estate. */\n  clipEdgeNavEnabled: boolean;\n  /** Host opt-in for the built-in aspect picker. When off, the chip\n   *  is completely hidden so today's chrome layout is unchanged for\n   *  hosts who roll their own picker via `toolbarLeft`. */\n  aspectEnabled: boolean;\n  /** Current output aspect — null = \"Original\" (no Project.aspect). */\n  aspect: AspectRatio | null;\n  /** Host opt-in for the \"+ PiP overlay\" toolbar button. When off\n   *  (default), the button is hidden — same pattern as the\n   *  keyframes / clipEdgeNav cluster. */\n  pipToolbarAddEnabled: boolean;\n}\n\n/**\n * Top toolbar — three groups laid out per the reference:\n *   left: [undo] [redo] [split] [trim-left] [trim-right] [speed]\n *   center: [time]  ▶  [duration]  [fullscreen]\n *   right: [snap] [zoom-out] [zoom-slider] [zoom-in] [reset]\n *\n * Export is intentionally NOT built-in — every host has its own\n * pipeline (download, server pipeline, etc.). Drop a custom button\n * into `editor.toolbarRight` or call `editor.requestExport()` from\n * any host UI to fire the `export` event.\n */\nexport class Toolbar {\n  private root: HTMLDivElement;\n  private cb: ToolbarCallbacks;\n  private locale: Locale;\n\n  /**\n   * Bookend slots reserved for host-supplied controls. The library\n   * paints nothing into either — hosts (React/Vue wrappers or plain\n   * JS) append their own buttons / dropdowns. `extrasLeft` sits at\n   * the very start of the toolbar; `extrasRight` at the very end.\n   * Empty by default and visually hidden (no separator) until they\n   * actually contain children.\n   */\n  readonly extrasLeft: HTMLDivElement;\n  readonly extrasRight: HTMLDivElement;\n\n  private aspectPicker!: AspectPicker;\n  private undoBtn!: HTMLButtonElement;\n  private redoBtn!: HTMLButtonElement;\n  private splitBtn!: HTMLButtonElement;\n  private trimLeftBtn!: HTMLButtonElement;\n  private trimRightBtn!: HTMLButtonElement;\n  private seekClipStartBtn!: HTMLButtonElement;\n  private seekClipEndBtn!: HTMLButtonElement;\n  private keyframeBtn!: HTMLButtonElement;\n  private pipBtn!: HTMLButtonElement;\n  private snapBtn!: HTMLButtonElement;\n  private zoomOutBtn!: HTMLButtonElement;\n  private zoomSlider!: HTMLInputElement;\n  private zoomInBtn!: HTMLButtonElement;\n  private resetBtn!: HTMLButtonElement;\n  private lastState: ToolbarState | null = null;\n\n  constructor(host: HTMLElement, cb: ToolbarCallbacks, locale: Locale) {\n    this.cb = cb;\n    this.locale = locale;\n    this.root = document.createElement(\"div\");\n    this.root.className = \"aicut-toolbar\";\n    this.root.setAttribute(\"data-testid\", \"aicut-toolbar\");\n\n    this.extrasLeft = mkGroup(\"aicut-toolbar-extras aicut-toolbar-extras-left\");\n    this.extrasRight = mkGroup(\"aicut-toolbar-extras aicut-toolbar-extras-right\");\n\n    const left = mkGroup(\"aicut-toolbar-left\");\n    // Built-in aspect picker. Hidden until render() flips\n    // aspectEnabled on, to keep today's chrome unchanged for hosts\n    // who don't opt in.\n    this.aspectPicker = new AspectPicker(\n      { onChange: (a) => cb.onAspectChange(a) },\n      locale,\n    );\n    this.aspectPicker.element.style.display = \"none\";\n    left.appendChild(this.aspectPicker.element);\n    this.undoBtn = mkIconButton(\"undo\", locale.undo, () => cb.onUndo(), \"aicut-undo\");\n    this.redoBtn = mkIconButton(\"redo\", locale.redo, () => cb.onRedo(), \"aicut-redo\");\n    this.splitBtn = mkIconButton(\"split\", locale.split, () => cb.onSplit(), \"aicut-split\");\n    this.trimLeftBtn = mkIconButton(\"trimLeft\", locale.trimLeft, () => cb.onTrimLeft(), \"aicut-trim-left\");\n    this.trimRightBtn = mkIconButton(\"trimRight\", locale.trimRight, () => cb.onTrimRight(), \"aicut-trim-right\");\n    this.seekClipStartBtn = mkIconButton(\n      \"seekClipStart\",\n      locale.seekClipStart,\n      () => cb.onSeekClipStart(),\n      \"aicut-seek-clip-start\",\n    );\n    this.seekClipStartBtn.style.display = \"none\"; // gated by render() on clipEdgeNavEnabled\n    this.keyframeBtn = mkIconButton(\n      \"keyframeOutline\",\n      locale.keyframeAdd,\n      () => cb.onKeyframeToggle(),\n      \"aicut-keyframe\",\n    );\n    this.keyframeBtn.style.display = \"none\"; // gated by render() on keyframesEnabled\n    this.seekClipEndBtn = mkIconButton(\n      \"seekClipEnd\",\n      locale.seekClipEnd,\n      () => cb.onSeekClipEnd(),\n      \"aicut-seek-clip-end\",\n    );\n    this.seekClipEndBtn.style.display = \"none\"; // gated by render() on clipEdgeNavEnabled\n    this.pipBtn = mkIconButton(\n      \"pipOutline\",\n      locale.pipAdd,\n      () => cb.onPictureInPictureAdd(),\n      \"aicut-pip-add\",\n    );\n    this.pipBtn.style.display = \"none\"; // gated by render() on pipToolbarAddEnabled\n    // Order: trim handles, then [|◀ ◇ ▶|] — start, kf, end — so the\n    // three nav buttons cluster around the keyframe affordance. PiP\n    // toggle goes at the end of the cluster.\n    left.append(\n      this.undoBtn,\n      this.redoBtn,\n      this.splitBtn,\n      this.trimLeftBtn,\n      this.trimRightBtn,\n      this.seekClipStartBtn,\n      this.keyframeBtn,\n      this.seekClipEndBtn,\n      this.pipBtn,\n    );\n\n    const right = mkGroup(\"aicut-toolbar-right\");\n    this.snapBtn = mkIconButton(\"snap\", locale.snap, () => cb.onSnapToggle(), \"aicut-snap\");\n    this.zoomOutBtn = mkIconButton(\"zoomOut\", locale.zoomOut, () => this.nudgeZoom(-1), \"aicut-zoom-out\");\n    this.zoomSlider = document.createElement(\"input\");\n    this.zoomSlider.type = \"range\";\n    this.zoomSlider.min = \"0\";\n    this.zoomSlider.max = \"100\";\n    this.zoomSlider.className = \"aicut-zoom-slider\";\n    this.zoomSlider.setAttribute(\"data-testid\", \"aicut-zoom-slider\");\n    this.zoomSlider.addEventListener(\"input\", () => {\n      const ratio = Number(this.zoomSlider.value) / 100;\n      cb.onScaleChange(sliderToScale(ratio));\n    });\n    this.zoomInBtn = mkIconButton(\"zoomIn\", locale.zoomIn, () => this.nudgeZoom(1), \"aicut-zoom-in\");\n    this.resetBtn = mkIconButton(\"reset\", locale.reset, () => cb.onReset(), \"aicut-reset\");\n    right.append(this.snapBtn, this.zoomOutBtn, this.zoomSlider, this.zoomInBtn, this.resetBtn);\n\n    this.root.append(this.extrasLeft, left, right, this.extrasRight);\n    host.appendChild(this.root);\n  }\n\n  get element(): HTMLDivElement {\n    return this.root;\n  }\n\n  /**\n   * Idempotent render. Critically: only mutates DOM when a state\n   * field actually changed. Without this, `playIcon.innerHTML = ICONS`\n   * re-parsed the SVG every playback tick (~60Hz) — and replacing the\n   * element between a user's mousedown and mouseup meant the browser\n   * never fired `click` (the two events landed on different element\n   * identities). That manifested as \"needs 3 clicks to pause\".\n   *\n   * Rule of thumb here: any `innerHTML =` / element rebuild MUST be\n   * behind a \"did the input change\" guard. Plain `.disabled` /\n   * `.textContent` writes are idempotent in browsers and safe to set\n   * unconditionally, but we still diff them for cheap CPU.\n   */\n  render(state: ToolbarState): void {\n    if (!this.lastState || this.lastState.canUndo !== state.canUndo) {\n      this.undoBtn.disabled = !state.canUndo;\n    }\n    if (!this.lastState || this.lastState.canRedo !== state.canRedo) {\n      this.redoBtn.disabled = !state.canRedo;\n    }\n    if (!this.lastState || this.lastState.canSplit !== state.canSplit) {\n      this.splitBtn.disabled = !state.canSplit;\n    }\n    if (!this.lastState || this.lastState.canTrim !== state.canTrim) {\n      this.trimLeftBtn.disabled = !state.canTrim;\n      this.trimRightBtn.disabled = !state.canTrim;\n    }\n    if (\n      !this.lastState ||\n      this.lastState.clipEdgeNavEnabled !== state.clipEdgeNavEnabled\n    ) {\n      const display = state.clipEdgeNavEnabled ? \"\" : \"none\";\n      this.seekClipStartBtn.style.display = display;\n      this.seekClipEndBtn.style.display = display;\n    }\n    if (\n      !this.lastState ||\n      this.lastState.canSeekClipEdge !== state.canSeekClipEdge\n    ) {\n      this.seekClipStartBtn.disabled = !state.canSeekClipEdge;\n      this.seekClipEndBtn.disabled = !state.canSeekClipEdge;\n    }\n    if (!this.lastState || this.lastState.snap !== state.snap) {\n      this.snapBtn.setAttribute(\"aria-pressed\", state.snap ? \"true\" : \"false\");\n      this.snapBtn.classList.toggle(\"aicut-toggle-on\", state.snap);\n      this.snapBtn.title = state.snap\n        ? this.locale.snapOnTitle\n        : this.locale.snapOffTitle;\n    }\n    if (\n      !this.lastState ||\n      this.lastState.aspectEnabled !== state.aspectEnabled\n    ) {\n      this.aspectPicker.element.style.display = state.aspectEnabled\n        ? \"\"\n        : \"none\";\n    }\n    if (!this.lastState || this.lastState.aspect !== state.aspect) {\n      this.aspectPicker.setValue(state.aspect);\n    }\n    // PiP \"+ overlay\" button — visibility gated on host opt-in;\n    // single state, click emits requestPictureInPictureAdd.\n    if (\n      !this.lastState ||\n      this.lastState.pipToolbarAddEnabled !== state.pipToolbarAddEnabled\n    ) {\n      this.pipBtn.style.display = state.pipToolbarAddEnabled ? \"\" : \"none\";\n    }\n    // Keyframe button — toggle visibility via display, swap icon to\n    // reflect whether a kf exists at the playhead, swap tooltip.\n    if (\n      !this.lastState ||\n      this.lastState.keyframesEnabled !== state.keyframesEnabled\n    ) {\n      this.keyframeBtn.style.display = state.keyframesEnabled ? \"\" : \"none\";\n    }\n    if (state.keyframesEnabled) {\n      if (\n        !this.lastState ||\n        this.lastState.hasKeyframeAtPlayhead !== state.hasKeyframeAtPlayhead\n      ) {\n        this.keyframeBtn.innerHTML = state.hasKeyframeAtPlayhead\n          ? ICONS.keyframeFilled\n          : ICONS.keyframeOutline;\n        const title = state.hasKeyframeAtPlayhead\n          ? this.locale.keyframeRemove\n          : this.locale.keyframeAdd;\n        this.keyframeBtn.title = title;\n        this.keyframeBtn.setAttribute(\"aria-label\", title);\n        this.keyframeBtn.setAttribute(\n          \"data-state\",\n          state.hasKeyframeAtPlayhead ? \"on\" : \"off\",\n        );\n      }\n      if (\n        !this.lastState ||\n        this.lastState.canKeyframe !== state.canKeyframe\n      ) {\n        this.keyframeBtn.disabled = !state.canKeyframe;\n      }\n    }\n    if (!this.lastState || this.lastState.pxPerSec !== state.pxPerSec) {\n      const ratio = scaleToSlider(state.pxPerSec);\n      const nextVal = String(Math.round(ratio * 100));\n      if (this.zoomSlider.value !== nextVal) this.zoomSlider.value = nextVal;\n      this.zoomSlider.style.setProperty(\n        \"--aicut-zoom-fill\",\n        `${Math.round(ratio * 100)}%`,\n      );\n    }\n    this.lastState = { ...state };\n  }\n\n  destroy(): void {\n    this.aspectPicker.destroy();\n    this.root.remove();\n  }\n\n  /**\n   * Apply a new locale to all already-mounted controls. Re-uses the\n   * same DOM elements (so event listeners and pointer-capture state\n   * stay intact) — only writes `title` / `aria-label`. Snap toggle\n   * title is then refreshed via the next render pass.\n   */\n  setLocale(locale: Locale): void {\n    this.locale = locale;\n    this.aspectPicker.setLocale(locale);\n    const applyTitle = (\n      el: HTMLElement | undefined,\n      title: string,\n    ): void => {\n      if (!el) return;\n      el.title = title;\n      el.setAttribute(\"aria-label\", title);\n    };\n    applyTitle(this.undoBtn, locale.undo);\n    applyTitle(this.redoBtn, locale.redo);\n    applyTitle(this.splitBtn, locale.split);\n    applyTitle(this.trimLeftBtn, locale.trimLeft);\n    applyTitle(this.trimRightBtn, locale.trimRight);\n    applyTitle(this.seekClipStartBtn, locale.seekClipStart);\n    applyTitle(this.seekClipEndBtn, locale.seekClipEnd);\n    applyTitle(this.snapBtn, locale.snap);\n    applyTitle(this.zoomOutBtn, locale.zoomOut);\n    applyTitle(this.zoomInBtn, locale.zoomIn);\n    applyTitle(this.resetBtn, locale.reset);\n    if (this.pipBtn) {\n      this.pipBtn.title = locale.pipAdd;\n      this.pipBtn.setAttribute(\"aria-label\", locale.pipAdd);\n    }\n    // Keyframe button tooltip — picks add/remove off the lastState if\n    // we have one, otherwise default to add.\n    if (this.keyframeBtn) {\n      const hasKf = this.lastState?.hasKeyframeAtPlayhead === true;\n      const t = hasKf ? locale.keyframeRemove : locale.keyframeAdd;\n      this.keyframeBtn.title = t;\n      this.keyframeBtn.setAttribute(\"aria-label\", t);\n    }\n    // Force snap title re-evaluation on next render.\n    if (this.lastState) {\n      this.snapBtn.title = this.lastState.snap\n        ? locale.snapOnTitle\n        : locale.snapOffTitle;\n    }\n  }\n\n  private nudgeZoom(dir: -1 | 1): void {\n    const cur = Number(this.zoomSlider.value);\n    const next = Math.max(0, Math.min(100, cur + dir * 8));\n    this.zoomSlider.value = String(next);\n    this.cb.onScaleChange(sliderToScale(next / 100));\n  }\n}\n\nfunction mkGroup(cls: string): HTMLDivElement {\n  const d = document.createElement(\"div\");\n  d.className = cls;\n  return d;\n}\n\nfunction mkIconButton(\n  icon: IconName,\n  title: string,\n  onClick: () => void,\n  testId?: string,\n): HTMLButtonElement {\n  const b = document.createElement(\"button\");\n  b.type = \"button\";\n  b.className = \"aicut-icon-btn\";\n  b.title = title;\n  b.setAttribute(\"aria-label\", title);\n  b.innerHTML = ICONS[icon];\n  if (testId) b.setAttribute(\"data-testid\", testId);\n  b.addEventListener(\"click\", onClick);\n  return b;\n}\n\n/**\n * Slider ↔ scale mapping is exponential so the slider feels uniform\n * across a wide zoom range. Matches the figma reference (exp-based\n * zoom step). 0 → SCALE_MIN, 1 → SCALE_MAX.\n */\nfunction sliderToScale(ratio: number): number {\n  const lo = Math.log(SCALE_MIN);\n  const hi = Math.log(SCALE_MAX);\n  return Math.exp(lo + (hi - lo) * ratio);\n}\n\nfunction scaleToSlider(scale: number): number {\n  const lo = Math.log(SCALE_MIN);\n  const hi = Math.log(SCALE_MAX);\n  return (Math.log(Math.max(SCALE_MIN, Math.min(SCALE_MAX, scale))) - lo) /\n    (hi - lo);\n}\n","import {\n  bigFrameStepMs,\n  clipDuration,\n  findClipContaining,\n  findTrackOfClip,\n  frameStepMs,\n} from \"../model.js\";\nimport type { Editor, PreviewLayout } from \"../editor.js\";\nimport { Timeline } from \"../timeline/index.js\";\nimport type { Clip, Ms } from \"../types.js\";\nimport type { Locale } from \"../i18n.js\";\nimport { KeyframeOverlay } from \"./keyframe-overlay.js\";\nimport { KeyframePanel } from \"./keyframe-panel.js\";\nimport { PreviewControls } from \"./preview-controls.js\";\nimport { Toolbar, type ToolbarCallbacks } from \"./toolbar.js\";\n\n/**\n * Callbacks the editor wires into the UI. The toolbar contributes the\n * top-bar buttons; the timeline contributes click/drag intents that\n * the editor turns into model mutations (with overlap → new-track\n * routing centralised in `Editor.moveClip`).\n */\nexport interface UICallbacks extends ToolbarCallbacks {\n  /** Play/pause toggle — wired into the preview-overlay play button. */\n  onPlayToggle: () => void;\n  /** Fullscreen toggle — wired into the preview-overlay fullscreen button. */\n  onFullscreen: () => void;\n  onSeek: (timeMs: Ms) => void;\n  onSelectClip: (clipId: string | null) => void;\n  onDeleteClip: (clipId: string) => void;\n  onMoveClip: (\n    clipId: string,\n    opts: { start?: Ms; trackId?: string; newTrack?: boolean },\n  ) => void;\n  onResizeClip: (\n    clipId: string,\n    edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>,\n  ) => void;\n  onSelectKeyframe: (\n    target: { clipId: string; keyframeId: string } | null,\n  ) => void;\n  onMoveKeyframe: (\n    clipId: string,\n    keyframeId: string,\n    timeMs: Ms,\n  ) => void;\n}\n\n/**\n * Composes the editor: preview host on top, toolbar middle, canvas\n * Timeline at the bottom. Single source of repaint via `render()`;\n * frequent `onTimeTick()` is the playback-fast path that only nudges\n * the playhead-related surfaces.\n */\nexport class EditorUI {\n  private root: HTMLElement;\n  private editor: Editor;\n  private header: HTMLDivElement;\n  /** Host-extensible slot at the very left of the editor header. */\n  readonly headerLeft: HTMLDivElement;\n  /** Host-extensible slot at the very right of the editor header. */\n  readonly headerRight: HTMLDivElement;\n  /** Wrapping element below the header that holds the side panels +\n   *  preview. Becomes a 3-column grid when previewLayout = centered. */\n  private main: HTMLDivElement;\n  /** Side panel slot to the left of the preview. Visible only when\n   *  previewLayout = centered. */\n  readonly panelLeft: HTMLDivElement;\n  /** Side panel slot to the right of the preview. */\n  readonly panelRight: HTMLDivElement;\n  /** The \"card\" wrapping the video viewport + playback footer. Width\n   *  is capped via CSS; height auto-fits via the host's aspect ratio. */\n  private previewCard: HTMLDivElement;\n  private preview: HTMLDivElement;\n  private previewControls: PreviewControls;\n  private fullscreenExitBtn: HTMLButtonElement;\n  private toolbar: Toolbar;\n  private timelineHost: HTMLDivElement;\n  private timeline: Timeline;\n  private keyframePanel: KeyframePanel;\n  private keyframeOverlay: KeyframeOverlay;\n  private fullscreen = false;\n  private onDocKeydown: ((e: KeyboardEvent) => void) | null = null;\n\n  constructor(root: HTMLElement, editor: Editor, cb: UICallbacks) {\n    this.root = root;\n    this.editor = editor;\n    const locale = editor.getLocale();\n\n    root.classList.add(\"aicut-root\");\n    root.innerHTML = \"\";\n\n    // Optional header above the preview — left/right bookend slots\n    // the host fills via React/Vue wrappers. Always rendered; CSS\n    // collapses it via :has() when both slots are empty so callers\n    // who don't use it see exactly today's layout.\n    this.header = document.createElement(\"div\");\n    this.header.className = \"aicut-header\";\n    this.header.setAttribute(\"data-testid\", \"aicut-header\");\n    this.headerLeft = document.createElement(\"div\");\n    this.headerLeft.className = \"aicut-header-slot aicut-header-left\";\n    this.headerRight = document.createElement(\"div\");\n    this.headerRight.className = \"aicut-header-slot aicut-header-right\";\n    this.header.append(this.headerLeft, this.headerRight);\n    root.appendChild(this.header);\n\n    // Main area below the header. In fullWidth layout it's a single\n    // cell holding the preview; in centered layout it becomes a\n    // 3-column grid `panel-left | preview | panel-right`. CSS reads\n    // `data-preview-layout` on the editor root to switch templates.\n    this.main = document.createElement(\"div\");\n    this.main.className = \"aicut-main\";\n    this.main.setAttribute(\"data-testid\", \"aicut-main\");\n    this.panelLeft = document.createElement(\"div\");\n    this.panelLeft.className = \"aicut-panel aicut-panel-left\";\n    this.panelLeft.setAttribute(\"data-testid\", \"aicut-panel-left\");\n    this.panelRight = document.createElement(\"div\");\n    this.panelRight.className = \"aicut-panel aicut-panel-right\";\n    this.panelRight.setAttribute(\"data-testid\", \"aicut-panel-right\");\n\n    // Preview \"card\" — capped width, aspect-driven height, rounded\n    // surface that visually separates the viewport from the chrome\n    // around it. CapCut-desktop's preview area uses this same pattern:\n    // a fixed-width media frame with the playback strip as a footer\n    // beneath it, rather than overlaying the controls on top of the\n    // video where they can collide with the canvas / keyframe guides.\n    this.previewCard = document.createElement(\"div\");\n    this.previewCard.className = \"aicut-preview-card\";\n    this.previewCard.setAttribute(\"data-testid\", \"aicut-preview-card\");\n\n    this.preview = document.createElement(\"div\");\n    this.preview.className = \"aicut-preview-host\";\n    this.preview.setAttribute(\"data-testid\", \"aicut-preview\");\n\n    this.fullscreenExitBtn = document.createElement(\"button\");\n    this.fullscreenExitBtn.type = \"button\";\n    this.fullscreenExitBtn.className = \"aicut-fullscreen-exit\";\n    this.fullscreenExitBtn.title = locale.exitFullscreenTitle;\n    this.fullscreenExitBtn.setAttribute(\"data-testid\", \"aicut-fullscreen-exit\");\n    this.fullscreenExitBtn.textContent = locale.exitFullscreen;\n    this.fullscreenExitBtn.addEventListener(\"click\", () =>\n      this.setFullscreen(false),\n    );\n    this.preview.appendChild(this.fullscreenExitBtn);\n\n    // Playback controls — time / play / duration / fullscreen — sit\n    // as a card footer beneath the viewport (CapCut-desktop style),\n    // not as an overlay on the video. Keeps the footer chrome from\n    // colliding with the canvas guide / keyframe handles inside the\n    // viewport.\n    this.previewControls = new PreviewControls(\n      { onPlayToggle: cb.onPlayToggle, onFullscreen: cb.onFullscreen },\n      locale,\n    );\n\n    this.previewCard.append(this.preview, this.previewControls.element);\n    this.main.append(this.panelLeft, this.previewCard, this.panelRight);\n    root.appendChild(this.main);\n\n    this.toolbar = new Toolbar(root, cb, locale);\n    root.setAttribute(\"data-preview-layout\", editor.getPreviewLayout());\n    this.applyAspect(editor.getAspect());\n\n    this.timelineHost = document.createElement(\"div\");\n    this.timelineHost.className = \"aicut-timeline\";\n    this.timelineHost.setAttribute(\"data-testid\", \"aicut-timeline\");\n    root.appendChild(this.timelineHost);\n\n    this.timeline = Timeline.create({\n      container: this.timelineHost,\n      project: editor.getProject(),\n      pxPerSec: editor.getScale(),\n      time: editor.getTime(),\n      selectedClipId: editor.getSelection(),\n      snap: editor.getSnap(),\n      autoFit: true,\n      locale,\n      rulerMinTickPx: editor.getRulerMinTickPx(),\n      keyframesEnabled: editor.isKeyframesEnabled(),\n      selectedKeyframe: editor.getSelectedKeyframe(),\n      onSeek: cb.onSeek,\n      onSelectClip: cb.onSelectClip,\n      onMoveClip: cb.onMoveClip,\n      onResizeClip: cb.onResizeClip,\n      onSelectKeyframe: cb.onSelectKeyframe,\n      onMoveKeyframe: cb.onMoveKeyframe,\n      onScaleChange: cb.onScaleChange,\n      onDeleteTrack: (trackId) => editor.removeTrack(trackId),\n      // Mirror the editor's smart routing into the drag preview so\n      // the ghost lands on the same row the commit will pick.\n      resolveDrop: (clipId, intent) => {\n        const proj = editor.getProject();\n        const intendedTrack = proj.tracks[intent.intendedTrackIndex];\n        const pred = editor.previewMoveTarget(\n          clipId,\n          intent.start,\n          intendedTrack?.id,\n        );\n        if (!pred) {\n          return {\n            trackIndex: intent.intendedTrackIndex,\n            wouldCreateNew: false,\n          };\n        }\n        return {\n          trackIndex: pred.trackIndex,\n          wouldCreateNew: pred.wouldCreateNew,\n        };\n      },\n    });\n\n    // Keyframe panel — mounts into the editor's left panel column so\n    // the numeric editor lives next to the preview rather than on top\n    // of it. Visible only when keyframes mode is on AND a keyframe is\n    // selected. In `fullWidth` layout the panelLeft column is hidden,\n    // so hosts who run that layout typically don't need this panel —\n    // dragging the in-preview overlay handles is enough.\n    this.keyframePanel = new KeyframePanel(this.panelLeft, editor, locale);\n    // Keyframe overlay — frame border + scale handles on top of the\n    // preview; drives drag-to-translate and corner-handle-to-scale\n    // gestures via direct manipulation. Hidden when keyframes off.\n    this.keyframeOverlay = new KeyframeOverlay(this.preview, editor);\n\n    this.attachKeyboard(cb);\n  }\n\n  // ---- fullscreen -----------------------------------------------------\n\n  isFullscreen(): boolean {\n    return this.fullscreen;\n  }\n\n  toggleFullscreen(): void {\n    this.setFullscreen(!this.fullscreen);\n  }\n\n  setFullscreen(on: boolean): void {\n    if (on === this.fullscreen) return;\n    this.fullscreen = on;\n    this.root.classList.toggle(\"aicut-fullscreen\", on);\n    if (on) {\n      this.onDocKeydown = (e) => {\n        if (e.key === \"Escape\") {\n          e.preventDefault();\n          this.setFullscreen(false);\n        }\n      };\n      document.addEventListener(\"keydown\", this.onDocKeydown);\n    } else if (this.onDocKeydown) {\n      document.removeEventListener(\"keydown\", this.onDocKeydown);\n      this.onDocKeydown = null;\n    }\n  }\n\n  get previewHost(): HTMLElement {\n    return this.preview;\n  }\n\n  /** Host-extensible slot at the very left of the top toolbar. */\n  get toolbarLeft(): HTMLElement {\n    return this.toolbar.extrasLeft;\n  }\n\n  /** Host-extensible slot at the very right of the top toolbar. */\n  get toolbarRight(): HTMLElement {\n    return this.toolbar.extrasRight;\n  }\n\n  /** Public for e2e — read-back of timeline canvas state (no DOM clips). */\n  getTimelineDebug(): ReturnType<Timeline[\"getDebugInfo\"]> {\n    return this.timeline.getDebugInfo();\n  }\n\n  /** Full sync from editor state. Idempotent. */\n  render(): void {\n    const project = this.editor.getProject();\n    const time = this.editor.getTime();\n    const duration = this.editor.getDuration();\n    const selectedClipId = this.editor.getSelection();\n    const pxPerSec = this.editor.getScale();\n    const snap = this.editor.getSnap();\n\n    const kfEnabled = this.editor.isKeyframesEnabled();\n    const kfState = this.computeKeyframeToolbarState(\n      project,\n      selectedClipId,\n      time,\n      kfEnabled,\n    );\n    this.toolbar.render({\n      canUndo: this.editor.canUndo(),\n      canRedo: this.editor.canRedo(),\n      canSplit: this.canSplitAt(time),\n      canTrim: this.canTrimAt(time, selectedClipId),\n      canSeekClipEdge: selectedClipId != null,\n      clipEdgeNavEnabled: this.editor.isClipEdgeNavEnabled(),\n      aspectEnabled: this.editor.isAspectEnabled(),\n      aspect: this.editor.getAspect(),\n      // Gate the toolbar \"+ PiP\" button on the master enable flag.\n      // When PiP is disabled there's no point adding overlay clips\n      // (they wouldn't paint), so the button stays hidden — same\n      // semantics CapCut surfaces in its sidebar PiP toggle.\n      pipToolbarAddEnabled:\n        this.editor.isPictureInPictureToolbarAddEnabled() &&\n        this.editor.isPictureInPictureEnabled(),\n      snap,\n      pxPerSec,\n      ...kfState,\n    });\n    this.previewControls.render({\n      playing: this.editor.isPlaying(),\n      time,\n      duration,\n    });\n\n    this.timeline.setProject(project);\n    this.timeline.setTime(time);\n    this.timeline.setScale(pxPerSec);\n    this.timeline.setSelection(selectedClipId);\n    this.timeline.setSnap(snap);\n    this.timeline.setKeyframeState({\n      enabled: this.editor.isKeyframesEnabled(),\n      selected: this.editor.getSelectedKeyframe(),\n    });\n    this.keyframePanel.render();\n  }\n\n  /** Playback-fast path: nudge playhead + toolbar time label only. */\n  onTimeTick(timeMs: Ms): void {\n    this.timeline.setTime(timeMs);\n    const selectedClipId = this.editor.getSelection();\n    const kfEnabled = this.editor.isKeyframesEnabled();\n    const kfState = this.computeKeyframeToolbarState(\n      this.editor.getProject(),\n      selectedClipId,\n      timeMs,\n      kfEnabled,\n    );\n    this.toolbar.render({\n      canUndo: this.editor.canUndo(),\n      canRedo: this.editor.canRedo(),\n      canSplit: this.canSplitAt(timeMs),\n      canTrim: this.canTrimAt(timeMs, selectedClipId),\n      canSeekClipEdge: selectedClipId != null,\n      clipEdgeNavEnabled: this.editor.isClipEdgeNavEnabled(),\n      aspectEnabled: this.editor.isAspectEnabled(),\n      aspect: this.editor.getAspect(),\n      pipToolbarAddEnabled:\n        this.editor.isPictureInPictureToolbarAddEnabled() &&\n        this.editor.isPictureInPictureEnabled(),\n      snap: this.editor.getSnap(),\n      pxPerSec: this.editor.getScale(),\n      ...kfState,\n    });\n    this.previewControls.render({\n      playing: this.editor.isPlaying(),\n      time: timeMs,\n      duration: this.editor.getDuration(),\n    });\n  }\n\n  setPreviewLayout(layout: PreviewLayout): void {\n    this.root.setAttribute(\"data-preview-layout\", layout);\n  }\n\n  setRulerMinTickPx(px: number): void {\n    this.timeline.setRulerMinTickPx(px);\n  }\n\n  /** Update the preview card's aspect-ratio so its height auto-fits\n   *  the chosen ratio. Called by Editor when the user picks a new\n   *  aspect (or clears to \"Original\"). */\n  setAspect(aspect: import(\"../types.js\").AspectRatio | null): void {\n    this.applyAspect(aspect);\n  }\n\n  private applyAspect(aspect: import(\"../types.js\").AspectRatio | null): void {\n    // \"Original\" (null) collapses to a sensible default — 16:9 is the\n    // overwhelming majority of source material; if the host wants\n    // something else they pick from the aspect chip.\n    const ratio = aspect ?? \"16:9\";\n    const [w, h] = ratio.split(\":\");\n    this.root.style.setProperty(\"--aicut-preview-aspect\", `${w} / ${h}`);\n  }\n\n  /** Explicit re-fit — Editor calls this when a brand-new project replaces the current one. */\n  resetAutoFit(): void {\n    this.timeline.refit();\n  }\n\n  setLocale(locale: Locale): void {\n    this.toolbar.setLocale(locale);\n    this.previewControls.setLocale(locale);\n    this.fullscreenExitBtn.title = locale.exitFullscreenTitle;\n    this.fullscreenExitBtn.textContent = locale.exitFullscreen;\n    this.timeline.setLocale(locale);\n    this.keyframePanel.setLocale(locale);\n    this.render();\n  }\n\n  destroy(): void {\n    if (this.onDocKeydown) {\n      document.removeEventListener(\"keydown\", this.onDocKeydown);\n      this.onDocKeydown = null;\n    }\n    this.toolbar.destroy();\n    this.previewControls.destroy();\n    this.timeline.destroy();\n    this.keyframePanel.destroy();\n    this.keyframeOverlay.destroy();\n    this.root.innerHTML = \"\";\n    this.root.classList.remove(\"aicut-root\", \"aicut-fullscreen\");\n    this.root.removeAttribute(\"data-preview-layout\");\n  }\n\n  // ---- helpers --------------------------------------------------------\n\n  /** Walk the selected clip + playhead state to figure out (a) whether\n   *  the keyframe button should be enabled, and (b) whether a keyframe\n   *  already exists at the playhead's clip-local time (so the button\n   *  swaps to \"remove\" mode). */\n  private computeKeyframeToolbarState(\n    project: { tracks: { clips: Clip[] }[] },\n    selectedClipId: string | null,\n    time: Ms,\n    keyframesEnabled: boolean,\n  ): { canKeyframe: boolean; hasKeyframeAtPlayhead: boolean; keyframesEnabled: boolean } {\n    if (!keyframesEnabled || !selectedClipId) {\n      return {\n        canKeyframe: false,\n        hasKeyframeAtPlayhead: false,\n        keyframesEnabled,\n      };\n    }\n    let clip: Clip | null = null;\n    for (const t of project.tracks) {\n      const c = t.clips.find((cl) => cl.id === selectedClipId);\n      if (c) {\n        clip = c;\n        break;\n      }\n    }\n    if (!clip) {\n      return {\n        canKeyframe: false,\n        hasKeyframeAtPlayhead: false,\n        keyframesEnabled,\n      };\n    }\n    const localMs = time - clip.start;\n    const duration = clipDuration(clip);\n    if (localMs < 0 || localMs > duration) {\n      return {\n        canKeyframe: false,\n        hasKeyframeAtPlayhead: false,\n        keyframesEnabled,\n      };\n    }\n    const roundedLocal = Math.round(localMs);\n    const hasKf =\n      clip.keyframes?.some((k) => k.time === roundedLocal) ?? false;\n    return {\n      canKeyframe: true,\n      hasKeyframeAtPlayhead: hasKf,\n      keyframesEnabled,\n    };\n  }\n\n  private canSplitAt(timeMs: Ms): boolean {\n    const project = this.editor.getProject();\n    for (const t of project.tracks) {\n      for (const c of t.clips) {\n        if (timeMs > c.start && timeMs < c.start + clipDuration(c)) return true;\n      }\n    }\n    return false;\n  }\n\n  private canTrimAt(timeMs: Ms, selectedClipId: string | null): boolean {\n    const project = this.editor.getProject();\n    if (selectedClipId) {\n      const trk = findTrackOfClip(project, selectedClipId);\n      const cl = trk?.clips.find((c: Clip) => c.id === selectedClipId);\n      if (cl && timeMs > cl.start && timeMs < cl.start + clipDuration(cl)) {\n        return true;\n      }\n    }\n    for (const t of project.tracks) {\n      const cl = findClipContaining(t, timeMs);\n      if (cl) return true;\n    }\n    return false;\n  }\n\n  private attachKeyboard(cb: UICallbacks): void {\n    this.root.tabIndex = 0;\n    this.root.addEventListener(\"keydown\", (e) => {\n      const target = e.target as HTMLElement | null;\n      if (target && [\"INPUT\", \"TEXTAREA\"].includes(target.tagName)) return;\n      if (e.code === \"Space\") {\n        e.preventDefault();\n        cb.onPlayToggle();\n      } else if (e.code === \"KeyK\") {\n        e.preventDefault();\n        cb.onSplit();\n      } else if (e.code === \"KeyQ\") {\n        e.preventDefault();\n        cb.onTrimLeft();\n      } else if (e.code === \"KeyW\") {\n        e.preventDefault();\n        cb.onTrimRight();\n      } else if (e.code === \"KeyI\" && this.editor.isClipEdgeNavEnabled()) {\n        e.preventDefault();\n        cb.onSeekClipStart();\n      } else if (e.code === \"KeyO\" && this.editor.isClipEdgeNavEnabled()) {\n        e.preventDefault();\n        cb.onSeekClipEnd();\n      } else if (e.code === \"ArrowLeft\" || e.code === \"ArrowRight\") {\n        // Frame-stepping nav — matches Premiere / Final Cut / CapCut /\n        // After Effects: ← / → = one frame, Shift+← / → = 10 frames.\n        // Step size derived from Project.fps (defaults to 30 when\n        // unset) so a 60 fps project nudges in half-frames relative\n        // to a 30 fps one.\n        e.preventDefault();\n        const project = this.editor.getProject();\n        const step = e.shiftKey ? bigFrameStepMs(project) : frameStepMs(project);\n        const dir = e.code === \"ArrowLeft\" ? -1 : 1;\n        const next = Math.max(\n          0,\n          Math.min(this.editor.getDuration(), this.editor.getTime() + dir * step),\n        );\n        cb.onSeek(next);\n      } else if ((e.metaKey || e.ctrlKey) && e.code === \"KeyZ\") {\n        e.preventDefault();\n        if (e.shiftKey) cb.onRedo();\n        else cb.onUndo();\n      } else if (e.code === \"Delete\" || e.code === \"Backspace\") {\n        const sel = this.editor.getSelection();\n        if (sel) {\n          e.preventDefault();\n          cb.onDeleteClip(sel);\n        }\n      }\n    });\n  }\n}\n","import { EventBus } from \"./events.js\";\nimport { HistoryStack } from \"./history.js\";\nimport { createId } from \"./ids.js\";\nimport {\n  clipDuration,\n  clipEnd,\n  createEmptyProject,\n  defaultOutputForAspect,\n  findClipContaining,\n  findTrackOfClip,\n  normalizeProject,\n  projectDuration,\n  splitClipAt,\n  trackEnd,\n} from \"./model.js\";\nimport {\n  SCALE_MAX,\n  SCALE_MIN,\n  setTimelineMetrics,\n  wouldOverlap,\n} from \"./timeline/layout.js\";\nimport {\n  HtmlVideoEngine,\n  type PlaybackEngine,\n  type PlaybackEngineFactory,\n} from \"./playback/index.js\";\nimport { applyTheme } from \"./theme.js\";\nimport { type Locale, mergeLocale } from \"./i18n.js\";\nimport type {\n  AspectRatio,\n  Clip,\n  EasingKind,\n  Keyframe,\n  KeyframeProp,\n  MediaSource,\n  Ms,\n  Project,\n  Theme,\n  Track,\n} from \"./types.js\";\nimport {\n  getEffectiveTransform,\n  interpolateProp,\n  upsertKeyframe,\n} from \"./keyframes/index.js\";\nimport { EditorUI } from \"./ui/index.js\";\n\n/**\n * State-only knobs that ALL editor entry points accept — used by the\n * headless (`createHeadless`) path AND the mounted `create` path.\n * Split from `EditorOptions` so React's `<EditorProvider>` and Vue's\n * `useAicutEditor()` can spin up an Editor without a mount container\n * and each primitive component (`<Preview>`, `<Timeline>`, buttons,\n * …) mounts its own DOM independently.\n */\nexport interface HeadlessEditorOptions {\n  /** Initial project state. Falls back to an empty single-track project. */\n  project?: Project;\n  /** CSS variable overrides — applied by `editor.applyThemeTo(el)`. */\n  theme?: Theme;\n  /** Initial playhead position (ms). */\n  initialTime?: Ms;\n  /** Initial timeline zoom (pixels per second). Defaults to 80. */\n  initialScale?: number;\n  /** Initial snap toggle. Defaults to true. */\n  initialSnap?: boolean;\n  /**\n   * UI string overrides. Falls back to English (`localeEn`) for any\n   * keys not provided. Use `localeZh` as the value for full Chinese.\n   */\n  locale?: Partial<Locale>;\n  /**\n   * Optional factory for a custom playback engine. Receives the\n   * preview host element + the initial project, returns anything\n   * satisfying `PlaybackEngine`. Defaults to the built-in\n   * `HtmlVideoEngine`. The engine is created LAZILY on\n   * `editor.attachPreview(host)` — headless editors have no engine\n   * until a Preview primitive mounts.\n   */\n  playbackEngine?: PlaybackEngineFactory;\n  /** See `EditorOptions`. */\n  trackHeight?: number;\n  rulerHeight?: number;\n  timelineHeight?: number;\n  rulerMinTickPx?: number;\n  keyframes?: { enabled?: boolean };\n  clipEdgeNav?: { enabled?: boolean };\n  previewFrame?: { enabled?: boolean };\n  pictureInPicture?: { enabled?: boolean; toolbarAdd?: boolean };\n  aspect?: { enabled?: boolean };\n  previewLayout?: PreviewLayout;\n}\n\nexport interface EditorOptions extends HeadlessEditorOptions {\n  /** Host element to mount the editor into. Will be wiped on init. */\n  container: HTMLElement;\n  /** Initial project state. Falls back to an empty single-track project. */\n  project?: Project;\n  /** CSS variable overrides. */\n  theme?: Theme;\n  /** Initial playhead position (ms). */\n  initialTime?: Ms;\n  /** Initial timeline zoom (pixels per second). Defaults to 80. */\n  initialScale?: number;\n  /** Initial snap toggle. Defaults to true. */\n  initialSnap?: boolean;\n  /**\n   * UI string overrides. Falls back to English (`localeEn`) for any\n   * keys not provided. Use `localeZh` as the value for full Chinese.\n   * Call `editor.setLocale(...)` to switch at runtime.\n   */\n  locale?: Partial<Locale>;\n  /**\n   * Optional factory for a custom playback engine. Receives the\n   * editor's preview host element + the initial project, returns\n   * anything satisfying `PlaybackEngine`. Defaults to the built-in\n   * `HtmlVideoEngine` (one hidden `<video>` per source, swap on\n   * boundaries). Hosts that need frame-accurate editing, multi-track\n   * compositing, transitions, etc. pass a `WebCodecsEngine` factory\n   * (v0.6+) or their own.\n   */\n  playbackEngine?: PlaybackEngineFactory;\n  /**\n   * Pixel height of each track row in the timeline (default 56). Lower\n   * values (~32–40) shrink the timeline footprint for small viewports\n   * where the default crowds out the preview. Reasonable range:\n   * [28, 96]. Applied process-wide via `setTimelineMetrics` — multi-\n   * editor mounts share the value.\n   */\n  trackHeight?: number;\n  /**\n   * Pixel height of the timeline ruler / time-label strip (default 24).\n   * Pair with `trackHeight` to compact the whole timeline. Reasonable\n   * range: [18, 36].\n   */\n  rulerHeight?: number;\n  /**\n   * Pixel height of the whole bottom timeline area (default 240). The\n   * canvas inside fills 100% of this and shows a vertical scrollbar\n   * when there are more tracks than fit. Lower this (~120–180) on\n   * small viewports so the preview takes more of the editor's height.\n   * Reasonable range: [120, 480].\n   */\n  timelineHeight?: number;\n  /**\n   * Minimum pixel gap between ruler major ticks. The library picks the\n   * \"nicest\" interval (1s, 0.5s, 0.2s, …) that keeps majors at least\n   * this far apart for the current zoom. Default 80; lower (~50) packs\n   * labels denser, higher (~140) spaces them out. Reactive via\n   * `editor.setRulerMinTickPx(...)`.\n   */\n  rulerMinTickPx?: number;\n  /**\n   * Per-clip keyframe animation (X / Y / Scale). Off by default; flip\n   * `enabled: true` to surface keyframe markers on the timeline and\n   * route the canvas / WebCodecs engines through `getEffectiveTransform`\n   * when painting. Data is preserved either way — disabling just hides\n   * the editing UI and renders identity transforms.\n   *\n   * HtmlVideoEngine cannot apply per-frame transforms (it shows a raw\n   * `<video>`), so keyframes are silently ignored on that engine\n   * regardless of this flag. Swap to `CanvasCompositorEngine` or\n   * `WebCodecsEngine` for live preview.\n   */\n  keyframes?: { enabled?: boolean };\n  /**\n   * Show the |◀ / ▶| \"jump to clip start / end\" toolbar buttons and\n   * bind the I / O keyboard shortcuts. Off by default — hosts opt in\n   * the same way they do for keyframes. When off the buttons are\n   * completely hidden (display: none) so they don't take up toolbar\n   * space, and the I / O keys fall through to the page.\n   */\n  clipEdgeNav?: { enabled?: boolean };\n  /**\n   * Dashed output-frame outline on top of the preview. Independent\n   * of keyframes mode — the frame is purely visual (it shows the\n   * fixed output canvas where the video lands after transforms), so\n   * it's useful even when keyframe editing is off (e.g. to visualize\n   * the current aspect-ratio choice). On by default; pass\n   * `{ enabled: false }` to hide it entirely. When keyframes mode is\n   * also on, the frame body becomes draggable (pan) and grows corner\n   * scale handles — both are gated by `keyframes.enabled` regardless\n   * of this flag.\n   */\n  previewFrame?: { enabled?: boolean };\n  /**\n   * Built-in aspect-ratio picker (CapCut-style \"比例\" dropdown).\n   * Off by default — hosts who want to provide their own picker keep\n   * today's behaviour by leaving this off and rendering a control\n   * into `editor.toolbarLeft`. When `enabled: true`, the editor\n   * renders the picker before the left-hand button cluster and emits\n   * `aspectChange` whenever the user picks. The selected value is\n   * persisted on `Project.aspect`.\n   *\n   * Hosts wire `onAspectChange` to update their preview letterbox /\n   * export defaults — the library does not letterbox the preview by\n   * itself (different engines have different paint pipelines).\n   */\n  aspect?: { enabled?: boolean };\n  /**\n   * Multi-track picture-in-picture compositing in the preview. Off by\n   * default so today's single-clip behaviour is unchanged. When on,\n   * every video track's currently-active clip paints at the playhead\n   * with track `0` on top — matching the timeline's visual order.\n   *\n   * Audio policy: only the top track's clip stays unmuted; lower\n   * tracks mute to avoid stacking audio playback. Hosts wanting\n   * per-track audio control should disable PiP and roll their own\n   * mixer.\n   *\n   * Same-source caveat: a single `<video>` / decoder can only be at\n   * one `currentTime`, so a clip dropped on two tracks at different\n   * timeline positions visually appears in both, but plays from\n   * whichever position was activated last. The fix is to upload the\n   * source twice (separate `MediaSource.id`s).\n   *\n   * `HtmlVideoEngine`, `CanvasCompositorEngine` both implement PiP\n   * via `PlaybackEngine.setPictureInPictureEnabled`. Other engines\n   * fall back to single-clip.\n   *\n   * `toolbarAdd: true` surfaces a built-in \"+ PiP overlay\" icon\n   * button in the toolbar (next to the keyframe button). Clicking\n   * it emits the `requestPictureInPictureAdd` event — the LIBRARY\n   * doesn't run an upload itself. Hosts wire this to their existing\n   * file-picker / upload pipeline and then create the new clip\n   * wherever makes sense for their data model. Defaults to false\n   * so the chrome stays unchanged for hosts that roll their own UI.\n   *\n   * `enabled` controls whether multi-track composition actually\n   * happens. It's intentionally orthogonal to the toolbar button:\n   * the toolbar is \"add a PiP\", the enable flag is \"show the\n   * compositor\". Hosts typically wire a sidebar checkbox or\n   * settings menu to it.\n   */\n  pictureInPicture?: {\n    enabled?: boolean;\n    toolbarAdd?: boolean;\n  };\n  /**\n   * High-level editor layout.\n   *\n   * - `\"centered\"` (default): three-column grid — host content on\n   *   the left, preview locked to the centre 1/3, host content on\n   *   the right. CapCut-desktop convention.\n   * - `\"fullWidth\"`: preview spans the editor's full width with no\n   *   side columns — useful for embeds where the host doesn't want\n   *   to render any panels.\n   *   The preview's aspect frame sizes its height from that 1/3\n   *   width and the video letterboxes inside. Playback chrome\n   *   (time / play / duration / fullscreen) renders as an overlay\n   *   inside the preview, CapCut-desktop style, so the top toolbar\n   *   collapses to edit + viewport clusters only.\n   *\n   * Hosts wire `panelLeft` / `panelRight` slots via the React /\n   * Vue wrappers to fill the side columns. Reactive — flip via\n   * `editor.setPreviewLayout(...)`.\n   */\n  previewLayout?: PreviewLayout;\n}\n\nexport type PreviewLayout = \"fullWidth\" | \"centered\";\n\nexport interface EditorEventMap {\n  /** Emitted whenever the project mutates. */\n  change: { project: Project };\n  /** Playhead position update — driven by the playback tick loop. */\n  time: { timeMs: Ms };\n  play: void;\n  pause: void;\n  /** A source's metadata finished loading (duration etc). */\n  ready: { sourceId: string | null };\n  /** User clicked the Export button. Host decides what to do with the JSON. */\n  export: { project: Project };\n  error: { error: Error };\n  /** Currently selected clip id, or null. */\n  selectionChange: { clipId: string | null };\n  /** Currently selected keyframe (parent clip + keyframe id), or null.\n   *  Selecting a keyframe also selects its parent clip — listeners\n   *  watching `selectionChange` get notified independently. */\n  keyframeSelectionChange: {\n    target: { clipId: string; keyframeId: string } | null;\n  };\n  /** Keyframe-mode toggle changed (Editor.setKeyframesEnabled). */\n  keyframesEnabledChange: { enabled: boolean };\n  /** Jump-to-clip-edge nav toggle changed (Editor.setClipEdgeNavEnabled). */\n  clipEdgeNavEnabledChange: { enabled: boolean };\n  /** Output-frame outline visibility flipped (Editor.setPreviewFrameEnabled). */\n  previewFrameEnabledChange: { enabled: boolean };\n  /** Multi-track preview compositing toggle changed\n   *  (Editor.setPictureInPictureEnabled). */\n  pictureInPictureEnabledChange: { enabled: boolean };\n  /** Layout flipped between fullWidth and centered. */\n  previewLayoutChange: { layout: PreviewLayout };\n  /**\n   * User clicked the built-in \"+ PiP overlay\" toolbar button. Host\n   * is expected to surface its own file-picker / upload affordance\n   * and append the resulting clip somewhere appropriate (typically\n   * a new video track). The library doesn't ship an upload UI on\n   * purpose — different hosts have very different upload pipelines.\n   */\n  requestPictureInPictureAdd: void;\n  /**\n   * Aspect-ratio picker toggle changed (Editor.setAspectEnabled). Only\n   * fires when the host-facing visibility flips — picking a new ratio\n   * fires `aspectChange` instead.\n   */\n  aspectEnabledChange: { enabled: boolean };\n  /**\n   * User (or programmatic call) chose a different output aspect ratio.\n   * `aspect` is null when cleared back to \"Original\" (use the source\n   * clip's intrinsic aspect). Persisted on `Project.aspect`.\n   */\n  aspectChange: { aspect: AspectRatio | null };\n  /** Zoom (px/sec) changed. */\n  scaleChange: { pxPerSec: number };\n  /** Snap toggle changed. */\n  snapChange: { snap: boolean };\n  /** Undo/redo stack states changed (button enablement). */\n  historyChange: { canUndo: boolean; canRedo: boolean };\n  /** Theme tokens changed via `editor.setTheme(...)`. Subscribers (e.g.\n   *  the standalone `<TimelinePrimitive>`) use this to force a canvas\n   *  re-paint since CSS custom properties don't invalidate the canvas\n   *  on their own. */\n  themeChange: { theme: Theme };\n  /** Locale tokens changed via `editor.setLocale(...)`. */\n  localeChange: { locale: Locale };\n}\n\nexport type EditorEventName = keyof EditorEventMap;\n\nexport interface EditorApi {\n  // playback\n  play(): void;\n  pause(): void;\n  togglePlay(): void;\n  seek(timeMs: Ms): void;\n  getTime(): Ms;\n  getDuration(): Ms;\n  isPlaying(): boolean;\n  enterFullscreen(): Promise<void>;\n  exitFullscreen(): Promise<void>;\n  isFullscreen(): boolean;\n\n  // editing\n  split(timeMs?: Ms): string[] | null;\n  /** Alias of split, kept for back-compat. */\n  cut(timeMs?: Ms): string[] | null;\n  /** Trim the selected clip's left edge to the given time (or playhead). */\n  trimLeft(timeMs?: Ms): boolean;\n  /** Trim the selected clip's right edge to the given time (or playhead). */\n  trimRight(timeMs?: Ms): boolean;\n  removeClip(clipId: string): boolean;\n  setClipSpeed(clipId: string, speed: number): boolean;\n  previewMoveTarget(\n    clipId: string,\n    start: Ms,\n    intendedTrackId?: string,\n  ): { trackIndex: number; trackId: string; wouldCreateNew: boolean } | null;\n\n  // tracks\n  addTrack(kind: Track[\"kind\"]): Track;\n  removeTrack(trackId: string): boolean;\n  moveClip(\n    clipId: string,\n    opts: { start?: Ms; trackId?: string; newTrack?: boolean },\n  ): boolean;\n  resizeClip(clipId: string, edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>): boolean;\n\n  // sources & state\n  addSource(source: MediaSource, opts?: { appendClip?: boolean }): MediaSource;\n  setProject(project: Project): void;\n  getProject(): Project;\n  /** Replace the project with a brand-new empty one. */\n  reset(): void;\n  setTheme(theme: Theme): void;\n  /**\n   * Swap the UI locale at runtime. Partial overrides merge with the\n   * English default. Triggers a re-render so the toolbar tooltips\n   * and timeline canvas labels pick up the new strings immediately.\n   */\n  setLocale(locale: Partial<Locale>): void;\n  /** Currently resolved `Locale` object (merged with `localeEn` for\n   *  any keys the host didn't override). Emits `localeChange` on\n   *  update — used by the React `useLocale()` hook. */\n  getLocale(): Locale;\n  /**\n   * Fire the `export` event with the current project JSON. Hosts call\n   * this from their own export button (built into their toolbarRight\n   * slot, a keyboard shortcut, a menu item, etc.) to surface project\n   * data to whatever pipeline they own. The library never invokes\n   * this on its own — it has no UI for export.\n   */\n  requestExport(): void;\n\n  // viewport\n  getScale(): number;\n  setScale(pxPerSec: number): void;\n  getSnap(): boolean;\n  setSnap(snap: boolean): void;\n\n  /** Read current ruler tick min-pixel-gap (see `rulerMinTickPx` option). */\n  getRulerMinTickPx(): number;\n  /** Update the ruler tick density at runtime. */\n  setRulerMinTickPx(px: number): void;\n\n  // selection\n  getSelection(): string | null;\n  setSelection(clipId: string | null): void;\n\n  // keyframes\n  isKeyframesEnabled(): boolean;\n  setKeyframesEnabled(enabled: boolean): void;\n  isClipEdgeNavEnabled(): boolean;\n  setClipEdgeNavEnabled(enabled: boolean): void;\n  /** Dashed output-frame outline visibility. Defaults to true. */\n  isPreviewFrameEnabled(): boolean;\n  setPreviewFrameEnabled(enabled: boolean): void;\n  /** Multi-track preview compositing (picture-in-picture). Defaults\n   *  to false. Flipping triggers an engine-side re-composite. */\n  isPictureInPictureEnabled(): boolean;\n  setPictureInPictureEnabled(enabled: boolean): void;\n  /** Current high-level editor layout. Defaults to \"centered\". */\n  getPreviewLayout(): PreviewLayout;\n  setPreviewLayout(layout: PreviewLayout): void;\n  /** Built-in aspect picker visibility (CapCut-style 比例 dropdown). */\n  isAspectEnabled(): boolean;\n  setAspectEnabled(enabled: boolean): void;\n  /** Current output aspect ratio, or null when \"Original\" (follow source). */\n  getAspect(): AspectRatio | null;\n  /**\n   * Set the output aspect ratio. Pass `null` to clear back to\n   * \"Original\". Persists on `Project.aspect`, also writes the matching\n   * 1080p-tier dims into `Project.output`, emits `aspectChange`, and\n   * pushes a history entry so the change participates in undo. No-op\n   * when the value didn't change.\n   */\n  setAspect(aspect: AspectRatio | null): void;\n  /**\n   * Output canvas dims in pixels. THIS is the reference coordinate\n   * system every spatial value in the project lives in — keyframe\n   * panX/panY, the canvas guide rect, the export resolution. Falls\n   * back to `aspect`-derived dims, then to the first clip's intrinsic\n   * source size, when nothing's been set on the project explicitly.\n   */\n  getOutput(): { width: number; height: number; fps?: number };\n  /**\n   * Write output canvas dims into `Project.output`. Even-snaps both\n   * axes (H.264 requirement) and pushes history. Pan / scale already\n   * stored against the previous canvas are NOT rescaled — same as\n   * how Premiere handles a sequence-settings change. Hosts who want\n   * value preservation should normalize keyframes themselves.\n   */\n  setOutput(output: { width: number; height: number; fps?: number }): void;\n  /** Screen-space CSS-pixel rect of the active rendered frame, post\n   *  transform, relative to the editor preview. Null when none. */\n  getActiveFrameRect():\n    | { x: number; y: number; w: number; h: number }\n    | null;\n  /** Same as `getActiveFrameRect` but for an arbitrary clipId. Used\n   *  by the overlay's hit-testing to figure out which PiP clip a\n   *  click in the preview lands on. Null when the clip isn't\n   *  currently being painted. */\n  getClipFrameRect(\n    clipId: string,\n  ): { x: number; y: number; w: number; h: number } | null;\n  /** Output frame rect (fixed bounds, no transform). The overlay\n   *  draws the dashed border here. */\n  getActiveOutputFrameRect():\n    | { x: number; y: number; w: number; h: number }\n    | null;\n  /**\n   * Upsert a per-property keyframe at the given clip-local time. If a\n   * keyframe for the same `prop` already exists within ~1 frame of\n   * `time` it gets its value updated; else a new one is appended.\n   * Returns the keyframe's id, or null when the clip can't be found.\n   *\n   * Defaults: `time` = playhead in clip-local coords; `value` = the\n   * currently interpolated value for that prop (so adding doesn't\n   * cause a visible jump).\n   */\n  addKeyframe(\n    clipId: string,\n    prop: KeyframeProp,\n    opts?: { time?: Ms; value?: number },\n  ): string | null;\n  removeKeyframe(clipId: string, keyframeId: string): boolean;\n  moveKeyframe(clipId: string, keyframeId: string, timeMs: Ms): boolean;\n  /** Change one keyframe's value (single number, since each kf is\n   *  per-property). */\n  setKeyframeValue(\n    clipId: string,\n    keyframeId: string,\n    value: number,\n  ): boolean;\n  /**\n   * Change one keyframe's outgoing easing curve. Shapes only the\n   * segment from this kf to the NEXT kf in time on the same prop.\n   * The kf's value is untouched.\n   */\n  setKeyframeEasing(\n    clipId: string,\n    keyframeId: string,\n    easing: EasingKind,\n  ): boolean;\n  /**\n   * Batch-set the outgoing easing on every kf at one moment in time\n   * (within the 16ms tolerance that the rest of the API uses) on a\n   * single clip. Mirrors the panel's \"one dropdown for the moment\"\n   * UX so all three props (panX / panY / scale) at the selected\n   * moment animate with the same curve. Single history entry.\n   */\n  setKeyframesEasingAtTime(\n    clipId: string,\n    timeMs: Ms,\n    easing: EasingKind,\n  ): boolean;\n  /**\n   * CapCut-style auto-record: write `value` for `prop` at the playhead.\n   * - If the prop already has keyframes → upsert a keyframe at the\n   *   playhead with this value.\n   * - If the prop has no keyframes → just update the static base\n   *   (panX / panY / scale on the clip) so the visual changes\n   *   without committing the user to an animation track yet.\n   * Returns true if the project changed.\n   */\n  setValueAtPlayhead(\n    clipId: string,\n    prop: KeyframeProp,\n    value: number,\n  ): boolean;\n  getSelectedKeyframe(): { clipId: string; keyframeId: string } | null;\n  setSelectedKeyframe(\n    target: { clipId: string; keyframeId: string } | null,\n  ): void;\n  /**\n   * Toolbar-style toggle. If ANY keyframe exists at the playhead time\n   * on the selected clip, remove every keyframe at that time (all\n   * props). Otherwise, capture one keyframe per prop (panX, panY,\n   * scale) at the playhead with the currently interpolated values.\n   * Returns true when the project changed.\n   */\n  toggleKeyframeAtPlayhead(): boolean;\n  /**\n   * Clear every keyframe AND every static transform value on a clip,\n   * restoring the identity pose (panX=0, panY=0, scale=1). Single\n   * history entry. */\n  resetClipTransform(clipId: string): boolean;\n  /**\n   * Pin all three transform props (panX, panY, scale) to identity\n   * (0, 0, 1) at one specific clip-local time. Upserts on each prop —\n   * keyframes that already exist at that time get their values\n   * overwritten; props with no kf there get one added. Single history\n   * entry. Used by the panel's Reset button when a keyframe is selected.\n   */\n  resetKeyframesAtTime(clipId: string, timeMs: Ms): boolean;\n  /**\n   * Move the playhead to a clip edge. \"end\" intentionally lands 1ms\n   * INSIDE the clip (clipEnd - 1) so the playhead remains inside the\n   * clip — that lets the user immediately press the keyframe button\n   * (or the I/O shortcut) and have it find the right clip + drop a\n   * keyframe at clip-local time `duration - 1ms`. Without the -1ms\n   * offset the playhead lands on the seam and `toggleKeyframeAtPlayhead`\n   * picks the next clip (or none at all).\n   * Returns true when the seek actually moved.\n   */\n  seekToClipEdge(clipId: string, edge: \"start\" | \"end\"): boolean;\n  /** Convenience for the toolbar: act on the currently-selected clip. */\n  seekToSelectedClipEdge(edge: \"start\" | \"end\"): boolean;\n\n  // history\n  canUndo(): boolean;\n  canRedo(): boolean;\n  undo(): boolean;\n  redo(): boolean;\n  /**\n   * Open a \"drag session\". While open, every internal `pushHistory`\n   * call captures the pre-session snapshot ONCE — subsequent calls\n   * during the same session are no-ops. The session commits a single\n   * history entry on `endInteraction()` (or is dropped entirely if\n   * the project ended up unchanged). Nestable: nested begin/end pairs\n   * count by depth and only the outermost commits.\n   *\n   * Hosts call this around continuous gestures (drag the preview\n   * overlay, scrub a numeric slider, wheel-zoom) so a single user\n   * gesture becomes ONE undo entry instead of 30-100. Without this,\n   * each pointermove of an overlay drag pushes its own history entry\n   * and the user has to mash Cmd+Z that many times to fully undo.\n   */\n  beginInteraction(): void;\n  endInteraction(): void;\n\n  /**\n   * Bookend slot at the very left of the top toolbar — host appends\n   * its own controls (e.g. an aspect-ratio dropdown). Empty by default\n   * and renders no separator until populated.\n   */\n  /**\n   * Preview host element the playback engine paints into. React /\n   * Vue `<Preview>` primitives teleport this into their own slots via\n   * `appendChild`. Available in both mounted mode (returns the built-in\n   * UI's preview host) and headless mode (returns the detached\n   * `.aicut-preview-host` div created in the constructor).\n   */\n  readonly previewHost: HTMLElement;\n  readonly toolbarLeft: HTMLElement;\n  /** Right-side bookend slot — conventionally export / save / share. */\n  readonly toolbarRight: HTMLElement;\n  /**\n   * Optional editor header above the preview. Host appends branding,\n   * project name, file menu, etc. on the left and Share / Export /\n   * profile / settings on the right. Layout is identical to today's\n   * editor when both slots are empty — CSS collapses the bar.\n   */\n  readonly headerLeft: HTMLElement;\n  /** Right-side header slot — conventionally Share / Export / etc. */\n  readonly headerRight: HTMLElement;\n  /**\n   * Side panel slot, rendered only when `previewLayout === \"centered\"`.\n   * Sits to the LEFT of the preview at 1/3 of the editor's width.\n   * Conventionally a media library / asset browser. Empty when the\n   * layout is `\"fullWidth\"` — the editor's overall grid still\n   * reserves the slot but CSS collapses it.\n   */\n  readonly panelLeft: HTMLElement;\n  /** Right side panel slot — conventionally an inspector / clip\n   *  properties panel. See `panelLeft`. */\n  readonly panelRight: HTMLElement;\n\n  // events\n  on<K extends EditorEventName>(\n    event: K,\n    handler: (payload: EditorEventMap[K]) => void,\n  ): () => void;\n  off<K extends EditorEventName>(\n    event: K,\n    handler: (payload: EditorEventMap[K]) => void,\n  ): void;\n  destroy(): void;\n}\n\nconst DEFAULT_PX_PER_SEC = 80;\nconst MIN_PX_PER_SEC = SCALE_MIN;\nconst MAX_PX_PER_SEC = SCALE_MAX;\n/** Snap distance in pixels at the current zoom. Converted to ms per call. */\nconst SNAP_PX = 8;\n\n/**\n * Top-level editor instance — the only stateful object a host app\n * interacts with. Owns the project, the playback engine, the vanilla\n * DOM UI, plus viewport (zoom/snap), selection, and history state.\n *\n * Framework wrappers (`@aicut/react`, `@aicut/vue`) should mount a\n * container, instantiate this once, mirror prop changes (`theme`)\n * into it, and forward events as framework-native callbacks.\n */\nexport class Editor implements EditorApi {\n  private container: HTMLElement | null;\n  /** Only populated in headless mode — the offscreen `.aicut-preview-host`\n   *  the engine paints into until a `<Preview>` primitive teleports it\n   *  into the visible tree. */\n  private detachedPreviewHost: HTMLElement | null = null;\n  private project: Project;\n  private engine: PlaybackEngine;\n  private ui: EditorUI | null;\n  private bus = new EventBus<EditorEventMap>();\n  private history = new HistoryStack();\n\n  private selectedClipId: string | null = null;\n  private selectedKeyframe: { clipId: string; keyframeId: string } | null =\n    null;\n  private keyframesEnabled: boolean;\n  private clipEdgeNavEnabled: boolean;\n  private aspectEnabled: boolean;\n  private previewFrameEnabled: boolean;\n  private pictureInPictureEnabled: boolean;\n  private previewLayout: PreviewLayout;\n  private pictureInPictureToolbarAddEnabled: boolean;\n  /** Drag-session bookkeeping for ripple-merge undo. See\n   *  beginInteraction / endInteraction docs on EditorApi. */\n  private interactionDepth = 0;\n  private interactionStartSnapshot: string | null = null;\n  private pxPerSec: number;\n  private snap: boolean;\n  private locale: Locale;\n  private rulerMinTickPx: number;\n  private destroyed = false;\n\n  constructor(opts: EditorOptions | (HeadlessEditorOptions & { container?: undefined | null })) {\n    this.container = opts.container ?? null;\n    this.project = normalizeProject(opts.project ?? createEmptyProject());\n    this.pxPerSec = clampScale(opts.initialScale ?? DEFAULT_PX_PER_SEC);\n    this.snap = opts.initialSnap !== false;\n    this.locale = mergeLocale(opts.locale);\n    this.rulerMinTickPx = Math.max(20, Math.round(opts.rulerMinTickPx ?? 80));\n    this.keyframesEnabled = opts.keyframes?.enabled === true;\n    this.clipEdgeNavEnabled = opts.clipEdgeNav?.enabled === true;\n    this.aspectEnabled = opts.aspect?.enabled === true;\n    // Default true — the dashed frame is purely visual and harmless\n    // even when keyframe editing is off; hosts who want a clean\n    // preview pass `previewFrame: { enabled: false }` to opt out.\n    this.previewFrameEnabled = opts.previewFrame?.enabled !== false;\n    this.pictureInPictureEnabled = opts.pictureInPicture?.enabled === true;\n    this.previewLayout = opts.previewLayout ?? \"centered\";\n    this.pictureInPictureToolbarAddEnabled =\n      opts.pictureInPicture?.toolbarAdd === true;\n\n    // Must run before EditorUI builds the Timeline — those layout\n    // values are read at canvas init time.\n    if (opts.trackHeight != null || opts.rulerHeight != null) {\n      setTimelineMetrics({\n        ...(opts.trackHeight != null ? { trackHeight: opts.trackHeight } : {}),\n        ...(opts.rulerHeight != null ? { rulerHeight: opts.rulerHeight } : {}),\n      });\n    }\n\n    if (this.container) {\n      applyTheme(this.container, opts.theme);\n      if (opts.timelineHeight != null && opts.timelineHeight > 0) {\n        // CSS custom property — `.aicut-timeline` reads it via var() so\n        // every editor instance can have its own height even though we\n        // share the class. Falls back to 240px when unset.\n        this.container.style.setProperty(\n          \"--aicut-timeline-height\",\n          `${Math.round(opts.timelineHeight)}px`,\n        );\n      }\n      this.ui = new EditorUI(this.container, this, {\n        onPlayToggle: () => this.togglePlay(),\n        onSplit: () => this.split(),\n        onTrimLeft: () => this.trimLeft(),\n        onTrimRight: () => this.trimRight(),\n        onUndo: () => this.undo(),\n        onRedo: () => this.redo(),\n        onReset: () => this.reset(),\n        onFullscreen: () => this.ui?.toggleFullscreen(),\n        onSnapToggle: () => this.setSnap(!this.snap),\n        onScaleChange: (s) => this.setScale(s),\n        onSeek: (t) => this.seek(t),\n        onSelectClip: (id) => this.setSelection(id),\n        onDeleteClip: (id) => this.removeClip(id),\n        onMoveClip: (id, opts) => this.moveClip(id, opts),\n        onResizeClip: (id, edits) => this.resizeClip(id, edits),\n        onSelectKeyframe: (target) => this.setSelectedKeyframe(target),\n        onMoveKeyframe: (clipId, keyframeId, timeMs) =>\n          this.moveKeyframe(clipId, keyframeId, timeMs),\n        onKeyframeToggle: () => this.toggleKeyframeAtPlayhead(),\n        onSeekClipStart: () => this.seekToSelectedClipEdge(\"start\"),\n        onSeekClipEnd: () => this.seekToSelectedClipEdge(\"end\"),\n        onAspectChange: (a) => this.setAspect(a),\n        onPictureInPictureAdd: () =>\n          this.bus.emit(\"requestPictureInPictureAdd\", undefined),\n      });\n    } else {\n      // Headless: no container, no built-in UI. Primitives mount their\n      // own DOM and drive the engine via the editor API. Theme is\n      // applied per-container by the host via `editor.applyThemeTo(el)`.\n      this.ui = null;\n    }\n\n    // Engine host: use the built-in UI's preview-host when mounted, or\n    // a detached div in headless. The detached div isn't attached to\n    // document — canvas / <video> still render into it just fine; the\n    // React `<Preview>` primitive appendChild's it into the visible\n    // tree when it mounts.\n    const engineHost =\n      this.ui?.previewHost ??\n      (this.detachedPreviewHost = this.createDetachedPreviewHost());\n\n    const engineFactory: PlaybackEngineFactory =\n      opts.playbackEngine ?? ((o) => new HtmlVideoEngine(o));\n    this.engine = engineFactory({\n      host: engineHost,\n      project: this.project,\n    });\n    // Push initial PiP state to the engine. Engines that don't\n    // implement the flag just ignore it.\n    this.engine.setPictureInPictureEnabled?.(this.pictureInPictureEnabled);\n    this.engine.onTimeUpdate = (ms) => {\n      this.bus.emit(\"time\", { timeMs: ms });\n      this.ui?.onTimeTick(ms);\n    };\n    this.engine.onEnded = () => this.bus.emit(\"pause\", undefined);\n    this.engine.onError = (err) => this.bus.emit(\"error\", { error: err });\n    this.engine.onReady = () => this.bus.emit(\"ready\", { sourceId: null });\n    this.engine.onSourceMetadata = (sourceId, durMs) =>\n      this.handleSourceMetadata(sourceId, durMs);\n\n    if (opts.initialTime) this.engine.seek(opts.initialTime);\n    this.ui?.render();\n  }\n\n  private createDetachedPreviewHost(): HTMLElement {\n    // Mirrors the DOM the built-in EditorUI creates for the preview\n    // slot. Kept detached from document — a React `<Preview>` primitive\n    // will teleport this into the user's slot at mount time.\n    const div = document.createElement(\"div\");\n    div.className = \"aicut-preview-host\";\n    div.setAttribute(\"data-testid\", \"aicut-preview\");\n    div.style.position = \"relative\";\n    div.style.width = \"100%\";\n    div.style.height = \"100%\";\n    return div;\n  }\n\n  /**\n   * Preview host element the engine paints into. React / Vue primitives\n   * grab this to teleport it into their own slots via `appendChild`.\n   * In built-in mode this is the EditorUI's preview-host div; in\n   * headless mode it's the detached div created at construction.\n   */\n  get previewHost(): HTMLElement {\n    return this.ui?.previewHost ?? this.detachedPreviewHost!;\n  }\n\n  /**\n   * Apply the editor's theme tokens to any host container. Primitives\n   * use this on their root divs so custom compositions inherit the\n   * same CSS variable set as the built-in shell.\n   */\n  applyThemeTo(el: HTMLElement, theme?: Theme): void {\n    applyTheme(el, theme);\n  }\n\n  /**\n   * Headless entry point — creates an Editor with state + engine but\n   * no built-in DOM. React `<EditorProvider>` and Vue `useAicutEditor`\n   * use this so hosts can compose their own layout out of the exposed\n   * primitives (`<Preview>`, `<Timeline>`, `<PlayButton>`, …).\n   */\n  static createHeadless(opts: HeadlessEditorOptions = {}): Editor {\n    // Cast: the constructor accepts an optional container — passing\n    // `container: undefined` triggers the headless branch.\n    return new Editor(opts as HeadlessEditorOptions & { container?: undefined });\n  }\n\n  static create(opts: EditorOptions): Editor {\n    return new Editor(opts);\n  }\n\n  get toolbarLeft(): HTMLElement {\n    return this.requireUi(\"toolbarLeft\").toolbarLeft;\n  }\n\n  get toolbarRight(): HTMLElement {\n    return this.requireUi(\"toolbarRight\").toolbarRight;\n  }\n\n  get headerLeft(): HTMLElement {\n    return this.requireUi(\"headerLeft\").headerLeft;\n  }\n\n  get headerRight(): HTMLElement {\n    return this.requireUi(\"headerRight\").headerRight;\n  }\n\n  get panelLeft(): HTMLElement {\n    return this.requireUi(\"panelLeft\").panelLeft;\n  }\n\n  get panelRight(): HTMLElement {\n    return this.requireUi(\"panelRight\").panelRight;\n  }\n\n  /** Slot-getter guard — the built-in slots only exist when EditorUI\n   *  was mounted. Headless callers should compose their own layout via\n   *  primitives instead of reaching for these DOM handles. */\n  private requireUi(slot: string): EditorUI {\n    if (!this.ui) {\n      throw new Error(\n        `Editor.${slot} is only available in mounted mode. Use React / Vue primitives (<Preview>, <Timeline>, buttons) to compose a headless editor instead.`,\n      );\n    }\n    return this.ui;\n  }\n\n  // ---- playback -------------------------------------------------------\n\n  play(): void {\n    this.engine.play();\n    this.bus.emit(\"play\", undefined);\n    this.ui?.render();\n  }\n\n  pause(): void {\n    this.engine.pause();\n    this.bus.emit(\"pause\", undefined);\n    this.ui?.render();\n  }\n\n  togglePlay(): void {\n    if (this.engine.isPlaying()) this.pause();\n    else this.play();\n  }\n\n  seek(timeMs: Ms): void {\n    this.engine.seek(timeMs);\n    this.ui?.render();\n  }\n\n  getTime(): Ms {\n    // Engine may not exist yet during UI construction (we build UI\n    // first to get its previewHost). Treat as 0 in that case.\n    return this.engine?.getTime() ?? 0;\n  }\n\n  getDuration(): Ms {\n    return projectDuration(this.project);\n  }\n\n  isPlaying(): boolean {\n    return this.engine?.isPlaying() ?? false;\n  }\n\n  /**\n   * In-tab \"fullscreen\" — covers the browser viewport via fixed\n   * positioning, NOT the OS Fullscreen API. This is what the reference\n   * UI calls \"全屏预览\": the user stays in their tab, no browser\n   * permission prompt, ESC exits. Browser fullscreen would also work\n   * but is heavier UX and gets blocked in iframes.\n   */\n  async enterFullscreen(): Promise<void> {\n    this.ui?.setFullscreen(true);\n  }\n\n  async exitFullscreen(): Promise<void> {\n    this.ui?.setFullscreen(false);\n  }\n\n  isFullscreen(): boolean {\n    return this.ui?.isFullscreen() ?? false;\n  }\n\n  // ---- editing --------------------------------------------------------\n\n  /**\n   * Split the clip at `timeMs` (or playhead). Returns the two new clip ids\n   * or null if there's no clip to split at that time.\n   */\n  split(timeMs?: Ms): string[] | null {\n    const t = timeMs ?? this.engine.getTime();\n    // Pick the track of the currently selected clip, else the first\n    // video track that has a clip at this time.\n    let target: { track: Track; clip: Clip } | null = null;\n    if (this.selectedClipId) {\n      const trk = findTrackOfClip(this.project, this.selectedClipId);\n      const cl = trk?.clips.find((c) => c.id === this.selectedClipId) ?? null;\n      if (trk && cl && t > cl.start && t < clipEnd(cl)) target = { track: trk, clip: cl };\n    }\n    if (!target) {\n      for (const trk of this.project.tracks) {\n        const cl = findClipContaining(trk, t);\n        if (cl && t > cl.start && t < clipEnd(cl)) {\n          target = { track: trk, clip: cl };\n          break;\n        }\n      }\n    }\n    if (!target) return null;\n    const split = splitClipAt(target.clip, t - target.clip.start);\n    if (!split) return null;\n    this.pushHistory();\n    const [left, right] = split;\n    target.track.clips = target.track.clips\n      .filter((c) => c.id !== target!.clip.id)\n      .concat(left, right)\n      .sort((a, b) => a.start - b.start);\n    this.afterMutation();\n    return [left.id, right.id];\n  }\n\n  cut(timeMs?: Ms): string[] | null {\n    return this.split(timeMs);\n  }\n\n  trimLeft(timeMs?: Ms): boolean {\n    const t = timeMs ?? this.engine.getTime();\n    const target = this.resolveTrimTarget(t);\n    if (!target) return false;\n    const { clip } = target;\n    const delta = t - clip.start;\n    if (delta <= 0 || delta >= clipDuration(clip)) return false;\n    this.pushHistory();\n    const oldStart = clip.start;\n    clip.in += delta;\n    clip.start += delta;\n\n    // Ripple-close the gap [oldStart, oldStart + delta] when it isn't\n    // covered by any clip on any other track. The user's mental model:\n    // \"trim away the lead-in and tighten the timeline\" — but only if\n    // we're not stranding material on a parallel track that was lining\n    // up with the trimmed region.\n    const gapStart = oldStart;\n    const gapEnd = clip.start;\n    let covered = false;\n    outer: for (const trk of this.project.tracks) {\n      for (const c of trk.clips) {\n        if (c.id === clip.id) continue;\n        const cEnd = c.start + clipDuration(c);\n        if (c.start < gapEnd && cEnd > gapStart) {\n          covered = true;\n          break outer;\n        }\n      }\n    }\n    if (!covered) {\n      clip.start = gapStart;\n      for (const trk of this.project.tracks) {\n        for (const c of trk.clips) {\n          if (c.id === clip.id) continue;\n          if (c.start >= gapEnd) c.start -= delta;\n        }\n        trk.clips.sort((a, b) => a.start - b.start);\n      }\n    }\n\n    this.afterMutation();\n    return true;\n  }\n\n  trimRight(timeMs?: Ms): boolean {\n    const t = timeMs ?? this.engine.getTime();\n    const target = this.resolveTrimTarget(t);\n    if (!target) return false;\n    const { clip } = target;\n    const delta = clipEnd(clip) - t;\n    if (delta <= 0 || delta >= clipDuration(clip)) return false;\n    this.pushHistory();\n    clip.out -= delta;\n    this.afterMutation();\n    return true;\n  }\n\n  removeClip(clipId: string): boolean {\n    let removed = false;\n    const before = JSON.stringify(this.project);\n    for (const t of this.project.tracks) {\n      const len = t.clips.length;\n      t.clips = t.clips.filter((c) => c.id !== clipId);\n      if (t.clips.length !== len) removed = true;\n    }\n    if (!removed) return false;\n    // Restore previous state in `history` keyed off the pre-mutation\n    // snapshot for accurate undo.\n    this.history.push(JSON.parse(before) as Project);\n    if (this.selectedClipId === clipId) {\n      this.selectedClipId = null;\n      this.bus.emit(\"selectionChange\", { clipId: null });\n    }\n    this.afterMutation();\n    return true;\n  }\n\n  setClipSpeed(clipId: string, speed: number): boolean {\n    if (!Number.isFinite(speed) || speed <= 0) return false;\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return false;\n    this.pushHistory();\n    cl.speed = speed === 1 ? undefined : speed;\n    this.afterMutation();\n    return true;\n  }\n\n  // ---- tracks ---------------------------------------------------------\n\n  addTrack(kind: Track[\"kind\"]): Track {\n    this.pushHistory();\n    const t: Track = { id: createId(\"track\"), kind, clips: [] };\n    this.project.tracks.push(t);\n    this.afterMutation();\n    return t;\n  }\n\n  removeTrack(trackId: string): boolean {\n    const idx = this.project.tracks.findIndex((t) => t.id === trackId);\n    if (idx < 0) return false;\n    this.pushHistory();\n    this.project.tracks.splice(idx, 1);\n    this.afterMutation();\n    return true;\n  }\n\n  /**\n   * Pure prediction of where a `moveClip(...)` would land — same smart\n   * routing as the real move (intended → source → other → new track),\n   * just no mutation, no history. Lets the Timeline preview the\n   * ACTUAL outcome of a drop so the ghost stops lying about new\n   * tracks that won't get created.\n   */\n  previewMoveTarget(\n    clipId: string,\n    start: Ms,\n    intendedTrackId?: string,\n  ): { trackIndex: number; trackId: string; wouldCreateNew: boolean } | null {\n    const fromTrack = findTrackOfClip(this.project, clipId);\n    const clip = fromTrack?.clips.find((c) => c.id === clipId);\n    if (!fromTrack || !clip) return null;\n    const nextStart = Math.max(0, start);\n    const nextEnd = nextStart + clipDuration(clip);\n    const intended = intendedTrackId\n      ? this.project.tracks.find((t) => t.id === intendedTrackId)\n      : fromTrack;\n    const candidates: Track[] = [];\n    const seen = new Set<string>();\n    const push = (t: Track | undefined) => {\n      if (!t || seen.has(t.id)) return;\n      seen.add(t.id);\n      candidates.push(t);\n    };\n    push(intended);\n    push(fromTrack);\n    for (const t of this.project.tracks) {\n      if (t.kind === fromTrack.kind) push(t);\n    }\n    for (const c of candidates) {\n      if (!wouldOverlap(c, clipId, nextStart, nextEnd)) {\n        const idx = this.project.tracks.indexOf(c);\n        return { trackIndex: idx, trackId: c.id, wouldCreateNew: false };\n      }\n    }\n    // No fit → preview a brand-new track appended at the end.\n    return {\n      trackIndex: this.project.tracks.length,\n      trackId: \"\",\n      wouldCreateNew: true,\n    };\n  }\n\n  moveClip(\n    clipId: string,\n    opts: { start?: Ms; trackId?: string; newTrack?: boolean },\n  ): boolean {\n    const fromTrack = findTrackOfClip(this.project, clipId);\n    const clip = fromTrack?.clips.find((c) => c.id === clipId);\n    if (!fromTrack || !clip) return false;\n    const nextStart = Math.max(0, opts.start ?? clip.start);\n    const nextEnd = nextStart + clipDuration(clip);\n\n    // Explicit \"new track\" intent from the UI's phantom-row drop —\n    // bypass smart routing entirely, append a fresh track, move there.\n    if (opts.newTrack) {\n      this.pushHistory();\n      const created = this.appendTrack({ kind: fromTrack.kind });\n      clip.start = nextStart;\n      fromTrack.clips = fromTrack.clips.filter((c) => c.id !== clipId);\n      created.clips.push(clip);\n      if (\n        fromTrack.clips.length === 0 &&\n        this.project.tracks.filter((t) => t.kind === fromTrack.kind).length > 1\n      ) {\n        this.project.tracks = this.project.tracks.filter(\n          (t) => t.id !== fromTrack.id,\n        );\n      }\n      this.afterMutation();\n      return true;\n    }\n\n    const intended = opts.trackId\n      ? this.project.tracks.find((t) => t.id === opts.trackId)\n      : fromTrack;\n    if (!intended) return false;\n\n    this.pushHistory();\n\n    // Smart routing — prefer in priority:\n    //   1. intended track (user's hover target)\n    //   2. the source track (because vacating it for a brand-new track\n    //      would be wasteful when there's room on the original row)\n    //   3. any other existing track of the same kind\n    //   4. as a last resort, a freshly-appended track\n    //\n    // `wouldOverlap` excludes the dragged clip itself, so the source\n    // track always has room for it back where it started (the user\n    // can effectively cancel a cross-track drag by hovering somewhere\n    // crowded — we drop back onto source).\n    const candidates: Track[] = [];\n    const seen = new Set<string>();\n    const push = (t: Track | undefined) => {\n      if (!t || seen.has(t.id)) return;\n      seen.add(t.id);\n      candidates.push(t);\n    };\n    push(intended);\n    push(fromTrack);\n    for (const t of this.project.tracks) {\n      if (t.kind === fromTrack.kind) push(t);\n    }\n\n    let targetTrack: Track | null = null;\n    for (const c of candidates) {\n      if (!wouldOverlap(c, clipId, nextStart, nextEnd)) {\n        targetTrack = c;\n        break;\n      }\n    }\n    if (!targetTrack) {\n      targetTrack = this.appendTrack({ kind: fromTrack.kind });\n    }\n\n    // Apply the move.\n    clip.start = nextStart;\n    if (targetTrack !== fromTrack) {\n      fromTrack.clips = fromTrack.clips.filter((c) => c.id !== clipId);\n      targetTrack.clips.push(clip);\n    }\n    targetTrack.clips.sort((a, b) => a.start - b.start);\n\n    // Auto-prune: if the source track is now empty AND it isn't the\n    // only track of its kind, drop it. Keeps the UI compact when the\n    // user is shuffling clips around — without this the track count\n    // monotonically grows.\n    if (\n      fromTrack !== targetTrack &&\n      fromTrack.clips.length === 0 &&\n      this.project.tracks.filter((t) => t.kind === fromTrack.kind).length > 1\n    ) {\n      this.project.tracks = this.project.tracks.filter(\n        (t) => t.id !== fromTrack.id,\n      );\n    }\n\n    this.afterMutation();\n    return true;\n  }\n\n  resizeClip(\n    clipId: string,\n    edits: Partial<Pick<Clip, \"in\" | \"out\" | \"start\">>,\n  ): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return false;\n    const next: Clip = { ...cl, ...edits };\n    if (next.out <= next.in) return false;\n    if (next.start < 0) return false;\n    this.pushHistory();\n    Object.assign(cl, next);\n    trk.clips.sort((a, b) => a.start - b.start);\n    this.afterMutation();\n    return true;\n  }\n\n  addSource(\n    source: MediaSource,\n    opts: { appendClip?: boolean } = {},\n  ): MediaSource {\n    const src: MediaSource = { ...source, id: source.id || createId(\"src\") };\n    this.pushHistory();\n    this.project.sources.push(src);\n    const append = opts.appendClip !== false;\n    if (append && src.kind === \"video\") {\n      const track =\n        this.project.tracks.find((t) => t.kind === \"video\") ??\n        this.appendTrack({ kind: \"video\" });\n      const start = trackEnd(track);\n      track.clips.push({\n        id: createId(\"clip\"),\n        sourceId: src.id,\n        in: 0,\n        out: src.duration ?? 0,\n        start,\n      });\n    }\n    this.afterMutation();\n    return src;\n  }\n\n  // ---- project --------------------------------------------------------\n\n  setProject(project: Project): void {\n    this.pushHistory();\n    this.project = normalizeProject(project);\n    this.engine.setProject(this.project);\n    this.bus.emit(\"change\", { project: this.getProject() });\n    this.emitHistory();\n    // Re-fit on project swap — the new project's duration is likely\n    // different so the previous scale is meaningless.\n    this.ui?.resetAutoFit();\n    this.ui?.setAspect(this.getAspect());\n    this.ui?.render();\n  }\n\n  getProject(): Project {\n    return JSON.parse(JSON.stringify(this.project)) as Project;\n  }\n\n  /**\n   * Restore the \"fresh import\" state: same media library, single\n   * default video track, one full-length clip per video source laid\n   * end-to-end. This mirrors the initial layout a host would get\n   * after dropping their videos in, so \"reset\" feels like \"start\n   * over without re-importing\" rather than \"wipe everything\".\n   *\n   * Goes through the regular history stack — ⌘Z brings the previous\n   * edit back. Sources without a known duration are skipped (they'd\n   * render as zero-width clips, which is worse than absent).\n   */\n  reset(): void {\n    const sources = this.project.sources.map((s) => ({ ...s }));\n    const trackId = createId(\"track\");\n    const clips: Clip[] = [];\n    let start = 0;\n    for (const src of sources) {\n      if (src.kind !== \"video\") continue;\n      const dur = src.duration;\n      if (!dur || dur <= 0) continue;\n      clips.push({\n        id: createId(\"clip\"),\n        sourceId: src.id,\n        in: 0,\n        out: dur,\n        start,\n      });\n      start += dur;\n    }\n    this.setProject({\n      version: 1,\n      sources,\n      tracks: [{ id: trackId, kind: \"video\", clips }],\n    });\n  }\n\n  setTheme(theme: Theme): void {\n    if (this.container) applyTheme(this.container, theme);\n    // The timeline canvas reads CSS vars at paint time and bakes them\n    // into pixels — it has no way to know the vars just changed.\n    // Without this re-render, the chrome (toolbar/headers) flips\n    // immediately via CSS but the canvas keeps its last colours until\n    // the next interaction (wheel, click, etc.). Force a repaint now.\n    this.ui?.render();\n    // Fanout to headless subscribers (e.g. the standalone\n    // `<TimelinePrimitive>` spun up under `<EditorProvider>`) — they\n    // need the signal because there's no built-in UI to call\n    // `timeline.setTheme` for them.\n    this.bus.emit(\"themeChange\", { theme });\n  }\n\n  setLocale(locale: Partial<Locale>): void {\n    this.locale = mergeLocale(locale);\n    this.ui?.setLocale(this.locale);\n    this.bus.emit(\"localeChange\", { locale: this.locale });\n  }\n\n  /** Internal — UI reads the resolved locale here on each render. */\n  getLocale(): Locale {\n    return this.locale;\n  }\n\n  requestExport(): void {\n    this.bus.emit(\"export\", { project: this.getProject() });\n  }\n\n  // ---- viewport -------------------------------------------------------\n\n  getScale(): number {\n    return this.pxPerSec;\n  }\n\n  setScale(pxPerSec: number): void {\n    const next = clampScale(pxPerSec);\n    if (next === this.pxPerSec) return;\n    this.pxPerSec = next;\n    this.bus.emit(\"scaleChange\", { pxPerSec: next });\n    this.ui?.render();\n  }\n\n  getSnap(): boolean {\n    return this.snap;\n  }\n\n  setSnap(snap: boolean): void {\n    if (snap === this.snap) return;\n    this.snap = snap;\n    this.bus.emit(\"snapChange\", { snap });\n    this.ui?.render();\n  }\n\n  getRulerMinTickPx(): number {\n    return this.rulerMinTickPx;\n  }\n\n  setRulerMinTickPx(px: number): void {\n    const next = Math.max(20, Math.round(px));\n    if (next === this.rulerMinTickPx) return;\n    this.rulerMinTickPx = next;\n    this.ui?.setRulerMinTickPx(next);\n  }\n\n  /** Snap a candidate ms to the nearest snappable surface within SNAP_PX. */\n  snapMs(timeMs: Ms, ignoreClipId?: string | null): Ms {\n    if (!this.snap) return timeMs;\n    const snapTol = Math.max(20, (SNAP_PX / this.pxPerSec) * 1000);\n    const targets: Ms[] = [0, this.engine.getTime()];\n    for (const t of this.project.tracks) {\n      for (const c of t.clips) {\n        if (c.id === ignoreClipId) continue;\n        targets.push(c.start, clipEnd(c));\n        if (c.keyframes) {\n          for (const kf of c.keyframes) targets.push(c.start + kf.time);\n        }\n      }\n    }\n    let best: Ms = timeMs;\n    let bestDist = snapTol;\n    for (const t of targets) {\n      const d = Math.abs(t - timeMs);\n      if (d < bestDist) {\n        bestDist = d;\n        best = t;\n      }\n    }\n    return best;\n  }\n\n  // ---- selection ------------------------------------------------------\n\n  getSelection(): string | null {\n    return this.selectedClipId;\n  }\n\n  setSelection(clipId: string | null): void {\n    if (clipId === this.selectedClipId) return;\n    this.selectedClipId = clipId;\n    this.bus.emit(\"selectionChange\", { clipId });\n    // Clearing the clip selection or moving to a different clip\n    // clears any orphan keyframe selection — selecting a keyframe\n    // outside the current clip would be confusing UX.\n    if (\n      this.selectedKeyframe &&\n      this.selectedKeyframe.clipId !== clipId\n    ) {\n      this.selectedKeyframe = null;\n      this.bus.emit(\"keyframeSelectionChange\", { target: null });\n    }\n    this.ui?.render();\n  }\n\n  // ---- keyframes ------------------------------------------------------\n\n  isKeyframesEnabled(): boolean {\n    return this.keyframesEnabled;\n  }\n\n  /**\n   * Screen-space CSS-pixel rect of the actively painted frame\n   * (post-transform), relative to the editor's preview element.\n   * Null when no clip is active, the engine doesn't expose\n   * `getFrameRect`, or the rect isn't computed yet. Used by the\n   * library's keyframe-editing overlay.\n   *\n   * When PiP is on and a non-primary clip is selected, returns\n   * THAT clip's rect — that's how the overlay's dashed border +\n   * corner handles latch onto a picture-in-picture overlay. With\n   * PiP off (or nothing selected) falls back to the primary clip.\n   */\n  getActiveFrameRect():\n    | { x: number; y: number; w: number; h: number }\n    | null {\n    const selected = this.pictureInPictureEnabled\n      ? (this.selectedClipId ?? undefined)\n      : undefined;\n    return this.engine.getFrameRect?.(selected) ?? null;\n  }\n\n  getClipFrameRect(\n    clipId: string,\n  ): { x: number; y: number; w: number; h: number } | null {\n    return this.engine.getFrameRect?.(clipId) ?? null;\n  }\n\n  /**\n   * Screen-space CSS-pixel rect of the OUTPUT FRAME (the fixed\n   * stage that clips the rendered video). Different from\n   * `getActiveFrameRect` which includes the keyframe transform —\n   * this one stays put as the user drags / scales the content.\n   * Used by the overlay to anchor the dashed border + drag body.\n   */\n  getActiveOutputFrameRect():\n    | { x: number; y: number; w: number; h: number }\n    | null {\n    const selected = this.pictureInPictureEnabled\n      ? (this.selectedClipId ?? undefined)\n      : undefined;\n    return this.engine.getOutputFrameRect?.(selected) ?? null;\n  }\n\n  setKeyframesEnabled(enabled: boolean): void {\n    if (enabled === this.keyframesEnabled) return;\n    this.keyframesEnabled = enabled;\n    // Disabling clears any active keyframe selection (the UI for it\n    // is about to disappear).\n    if (!enabled && this.selectedKeyframe) {\n      this.selectedKeyframe = null;\n      this.bus.emit(\"keyframeSelectionChange\", { target: null });\n    }\n    this.bus.emit(\"keyframesEnabledChange\", { enabled });\n    this.ui?.render();\n  }\n\n  isClipEdgeNavEnabled(): boolean {\n    return this.clipEdgeNavEnabled;\n  }\n\n  setClipEdgeNavEnabled(enabled: boolean): void {\n    if (enabled === this.clipEdgeNavEnabled) return;\n    this.clipEdgeNavEnabled = enabled;\n    this.bus.emit(\"clipEdgeNavEnabledChange\", { enabled });\n    this.ui?.render();\n  }\n\n  isPreviewFrameEnabled(): boolean {\n    return this.previewFrameEnabled;\n  }\n\n  setPreviewFrameEnabled(enabled: boolean): void {\n    if (enabled === this.previewFrameEnabled) return;\n    this.previewFrameEnabled = enabled;\n    this.bus.emit(\"previewFrameEnabledChange\", { enabled });\n    this.ui?.render();\n  }\n\n  isPictureInPictureEnabled(): boolean {\n    return this.pictureInPictureEnabled;\n  }\n\n  /** Whether the built-in \"+ PiP overlay\" toolbar button is rendered. */\n  isPictureInPictureToolbarAddEnabled(): boolean {\n    return this.pictureInPictureToolbarAddEnabled;\n  }\n\n  setPictureInPictureEnabled(enabled: boolean): void {\n    if (enabled === this.pictureInPictureEnabled) return;\n    this.pictureInPictureEnabled = enabled;\n    // Push to the engine — engines that implement it re-composite on\n    // the next paint tick. Engines that don't ignore the call.\n    this.engine.setPictureInPictureEnabled?.(enabled);\n    this.bus.emit(\"pictureInPictureEnabledChange\", { enabled });\n    this.ui?.render();\n  }\n\n  getPreviewLayout(): PreviewLayout {\n    return this.previewLayout;\n  }\n\n  setPreviewLayout(layout: PreviewLayout): void {\n    if (layout === this.previewLayout) return;\n    this.previewLayout = layout;\n    this.ui?.setPreviewLayout(layout);\n    this.bus.emit(\"previewLayoutChange\", { layout });\n    this.ui?.render();\n  }\n\n  isAspectEnabled(): boolean {\n    return this.aspectEnabled;\n  }\n\n  setAspectEnabled(enabled: boolean): void {\n    if (enabled === this.aspectEnabled) return;\n    this.aspectEnabled = enabled;\n    this.bus.emit(\"aspectEnabledChange\", { enabled });\n    this.ui?.render();\n  }\n\n  getAspect(): AspectRatio | null {\n    return this.project.aspect ?? null;\n  }\n\n  setAspect(aspect: AspectRatio | null): void {\n    const current = this.project.aspect ?? null;\n    if (aspect === current) return;\n    this.pushHistory();\n    if (aspect == null) {\n      delete this.project.aspect;\n    } else {\n      this.project.aspect = aspect;\n      // Mirror the chosen aspect into the authoritative `output`\n      // dims — picking 9:16 should immediately give the canvas a\n      // 9:16 reference frame in EVERY consumer (preview, overlay,\n      // backend export), without each having to derive the size\n      // from the aspect string separately.\n      const dims = defaultOutputForAspect(aspect);\n      const prevFps = this.project.output?.fps;\n      this.project.output = {\n        width: dims.width,\n        height: dims.height,\n        ...(prevFps != null ? { fps: prevFps } : {}),\n      };\n    }\n    this.afterMutation();\n    this.ui?.setAspect(aspect);\n    this.bus.emit(\"aspectChange\", { aspect });\n  }\n\n  getOutput(): { width: number; height: number; fps?: number } {\n    const out = this.project.output;\n    if (out) {\n      return out.fps != null\n        ? { width: out.width, height: out.height, fps: out.fps }\n        : { width: out.width, height: out.height };\n    }\n    // No `output` field yet — derive a reasonable canvas size for\n    // hosts that need to query before the user picks anything. Order\n    // mirrors normalizeProject: aspect → first-clip source dims →\n    // 1080p fallback.\n    if (this.project.aspect) {\n      const dims = defaultOutputForAspect(this.project.aspect);\n      return { width: dims.width, height: dims.height };\n    }\n    const ref = this.engine.getCanvasReferenceDims?.();\n    if (ref) return { width: ref[0], height: ref[1] };\n    return { width: 1920, height: 1080 };\n  }\n\n  setOutput(output: { width: number; height: number; fps?: number }): void {\n    const w = evenPx(output.width);\n    const h = evenPx(output.height);\n    if (w <= 0 || h <= 0) return;\n    const current = this.project.output;\n    if (\n      current &&\n      current.width === w &&\n      current.height === h &&\n      (current.fps ?? null) === (output.fps ?? null)\n    ) {\n      return;\n    }\n    this.pushHistory();\n    this.project.output = {\n      width: w,\n      height: h,\n      ...(output.fps != null && output.fps > 0 ? { fps: output.fps } : {}),\n    };\n    this.afterMutation();\n    this.ui?.render();\n  }\n\n  addKeyframe(\n    clipId: string,\n    prop: KeyframeProp,\n    opts: { time?: Ms; value?: number } = {},\n  ): string | null {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return null;\n    const duration = clipDuration(cl);\n    const playheadLocal = this.engine.getTime() - cl.start;\n    const rawTime = opts.time ?? playheadLocal;\n    const time = Math.max(0, Math.min(duration, Math.round(rawTime)));\n    const value = opts.value ?? interpolateProp(cl, prop, time);\n    this.pushHistory();\n    cl.keyframes = upsertKeyframe(cl.keyframes, prop, time, value, () =>\n      createId(\"kf\"),\n    );\n    cl.keyframes.sort((a, b) => {\n      if (a.prop !== b.prop) return a.prop.localeCompare(b.prop);\n      return a.time - b.time;\n    });\n    this.afterMutation();\n    const created = cl.keyframes.find(\n      (k) => k.prop === prop && Math.abs(k.time - time) < 16,\n    );\n    return created?.id ?? null;\n  }\n\n  removeKeyframe(clipId: string, keyframeId: string): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl || !cl.keyframes) return false;\n    const idx = cl.keyframes.findIndex((k) => k.id === keyframeId);\n    if (idx < 0) return false;\n    this.pushHistory();\n    const next = cl.keyframes.slice();\n    next.splice(idx, 1);\n    cl.keyframes = next.length > 0 ? next : undefined;\n    if (\n      this.selectedKeyframe &&\n      this.selectedKeyframe.clipId === clipId &&\n      this.selectedKeyframe.keyframeId === keyframeId\n    ) {\n      this.selectedKeyframe = null;\n      this.bus.emit(\"keyframeSelectionChange\", { target: null });\n    }\n    this.afterMutation();\n    return true;\n  }\n\n  moveKeyframe(clipId: string, keyframeId: string, timeMs: Ms): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    const kf = cl?.keyframes?.find((k) => k.id === keyframeId);\n    if (!trk || !cl || !kf || !cl.keyframes) return false;\n    const duration = clipDuration(cl);\n    const clamped = Math.max(0, Math.min(duration, Math.round(timeMs)));\n    // Identify every kf in the same \"moment\" as the grabbed one (same\n    // clip-local time, within the 16 ms tolerance the timeline uses for\n    // visual grouping). When the user pins via the toolbar \"+ kf\"\n    // button all three props (panX / panY / scale) land at the same\n    // time; dragging one without the others would visually fracture\n    // the moment so move them all as a unit.\n    const MOMENT_TOL = 16;\n    const groupOriginalTime = kf.time;\n    const group = cl.keyframes.filter(\n      (k) => Math.abs(k.time - groupOriginalTime) <= MOMENT_TOL,\n    );\n    const groupIds = new Set(group.map((k) => k.id));\n    const delta = clamped - groupOriginalTime;\n    if (delta === 0) return false;\n    // Reject collisions: any kf that's NOT part of the moving group\n    // at the same prop+time would land on top.\n    for (const g of group) {\n      const newTime = g.time + delta;\n      const collision = cl.keyframes.some(\n        (k) =>\n          !groupIds.has(k.id) &&\n          k.prop === g.prop &&\n          Math.abs(k.time - newTime) < 1,\n      );\n      if (collision) return false;\n    }\n    this.pushHistory();\n    for (const g of group) g.time += delta;\n    cl.keyframes.sort((a, b) => {\n      if (a.prop !== b.prop) return a.prop.localeCompare(b.prop);\n      return a.time - b.time;\n    });\n    this.afterMutation();\n    return true;\n  }\n\n  setKeyframeValue(\n    clipId: string,\n    keyframeId: string,\n    value: number,\n  ): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    const kf = cl?.keyframes?.find((k) => k.id === keyframeId);\n    if (!trk || !cl || !kf) return false;\n    if (Math.abs(kf.value - value) < 1e-9) return false;\n    this.pushHistory();\n    kf.value = value;\n    this.afterMutation();\n    return true;\n  }\n\n  setKeyframeEasing(\n    clipId: string,\n    keyframeId: string,\n    easing: EasingKind,\n  ): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    const kf = cl?.keyframes?.find((k) => k.id === keyframeId);\n    if (!trk || !cl || !kf) return false;\n    const current = kf.easing ?? \"linear\";\n    if (current === easing) return false;\n    this.pushHistory();\n    if (easing === \"linear\") {\n      // Strip the field rather than store the default — keeps the\n      // serialized project minimal for hosts that diff JSON.\n      delete kf.easing;\n    } else {\n      kf.easing = easing;\n    }\n    this.afterMutation();\n    return true;\n  }\n\n  setKeyframesEasingAtTime(\n    clipId: string,\n    timeMs: Ms,\n    easing: EasingKind,\n  ): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl || !cl.keyframes) return false;\n    const t = Math.round(timeMs);\n    const matches = cl.keyframes.filter((k) => Math.abs(k.time - t) < 16);\n    if (matches.length === 0) return false;\n    const anyChange = matches.some((k) => (k.easing ?? \"linear\") !== easing);\n    if (!anyChange) return false;\n    this.pushHistory();\n    for (const kf of matches) {\n      if (easing === \"linear\") delete kf.easing;\n      else kf.easing = easing;\n    }\n    this.afterMutation();\n    return true;\n  }\n\n  setValueAtPlayhead(\n    clipId: string,\n    prop: KeyframeProp,\n    value: number,\n  ): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return false;\n    const duration = clipDuration(cl);\n    const playheadLocal = this.engine.getTime() - cl.start;\n    const time = Math.max(0, Math.min(duration, Math.round(playheadLocal)));\n    const hasKf = cl.keyframes?.some((k) => k.prop === prop) ?? false;\n    if (hasKf) {\n      // Upsert at playhead → animation gets another anchor.\n      this.pushHistory();\n      cl.keyframes = upsertKeyframe(cl.keyframes, prop, time, value, () =>\n        createId(\"kf\"),\n      );\n      cl.keyframes.sort((a, b) => {\n        if (a.prop !== b.prop) return a.prop.localeCompare(b.prop);\n        return a.time - b.time;\n      });\n      this.afterMutation();\n      return true;\n    }\n    // No keyframes for this prop yet → update the static base. The\n    // user can promote it to an animated property later by clicking\n    // the toolbar keyframe button.\n    if ((cl[prop] ?? (prop === \"scale\" ? 1 : 0)) === value) return false;\n    this.pushHistory();\n    cl[prop] = value;\n    this.afterMutation();\n    return true;\n  }\n\n  getSelectedKeyframe(): { clipId: string; keyframeId: string } | null {\n    return this.selectedKeyframe;\n  }\n\n  resetClipTransform(clipId: string): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return false;\n    const dirty =\n      (cl.keyframes && cl.keyframes.length > 0) ||\n      cl.panX !== undefined ||\n      cl.panY !== undefined ||\n      cl.scale !== undefined;\n    if (!dirty) return false;\n    this.pushHistory();\n    delete cl.panX;\n    delete cl.panY;\n    delete cl.scale;\n    cl.keyframes = undefined;\n    if (\n      this.selectedKeyframe &&\n      this.selectedKeyframe.clipId === clipId\n    ) {\n      this.selectedKeyframe = null;\n      this.bus.emit(\"keyframeSelectionChange\", { target: null });\n    }\n    this.afterMutation();\n    return true;\n  }\n\n  resetKeyframesAtTime(clipId: string, timeMs: Ms): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return false;\n    const duration = clipDuration(cl);\n    const t = Math.max(0, Math.min(duration, Math.round(timeMs)));\n    // Identity values for each prop. Upsert in one batch so the\n    // history stack records a single \"reset\" entry, not three.\n    this.pushHistory();\n    let kfs = cl.keyframes ?? [];\n    kfs = upsertKeyframe(kfs, \"panX\", t, 0, () => createId(\"kf\"));\n    kfs = upsertKeyframe(kfs, \"panY\", t, 0, () => createId(\"kf\"));\n    kfs = upsertKeyframe(kfs, \"scale\", t, 1, () => createId(\"kf\"));\n    kfs.sort((a, b) => {\n      if (a.prop !== b.prop) return a.prop.localeCompare(b.prop);\n      return a.time - b.time;\n    });\n    cl.keyframes = kfs;\n    this.afterMutation();\n    return true;\n  }\n\n  seekToClipEdge(clipId: string, edge: \"start\" | \"end\"): boolean {\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return false;\n    // \"end\" lands 1ms inside the clip so the playhead stays inside —\n    // toggleKeyframeAtPlayhead and friends look up the clip via the\n    // playhead time, and a playhead landing exactly on the clip-end\n    // seam picks up the *next* clip (or nothing). The 1ms backoff\n    // costs nothing perceptually and keeps the keyframe-add workflow\n    // single-click. See seekToClipEdge doc in the API surface.\n    const target =\n      edge === \"start\" ? cl.start : Math.max(cl.start, clipEnd(cl) - 1);\n    if (this.engine.getTime() === target) return false;\n    this.seek(target);\n    return true;\n  }\n\n  seekToSelectedClipEdge(edge: \"start\" | \"end\"): boolean {\n    if (!this.selectedClipId) return false;\n    return this.seekToClipEdge(this.selectedClipId, edge);\n  }\n\n  toggleKeyframeAtPlayhead(): boolean {\n    const clipId = this.selectedClipId;\n    if (!clipId) return false;\n    const trk = findTrackOfClip(this.project, clipId);\n    const cl = trk?.clips.find((c) => c.id === clipId);\n    if (!trk || !cl) return false;\n    const localMs = this.engine.getTime() - cl.start;\n    const duration = clipDuration(cl);\n    if (localMs < 0 || localMs > duration) return false;\n    const t = Math.round(localMs);\n    const existing = cl.keyframes?.filter((k) => Math.abs(k.time - t) < 16);\n    if (existing && existing.length > 0) {\n      this.pushHistory();\n      const ids = new Set(existing.map((k) => k.id));\n      const next = cl.keyframes!.filter((k) => !ids.has(k.id));\n      cl.keyframes = next.length > 0 ? next : undefined;\n      if (\n        this.selectedKeyframe &&\n        ids.has(this.selectedKeyframe.keyframeId)\n      ) {\n        this.selectedKeyframe = null;\n        this.bus.emit(\"keyframeSelectionChange\", { target: null });\n      }\n      this.afterMutation();\n      return true;\n    }\n    // Capture one keyframe per prop at the playhead. Use the currently\n    // interpolated values so the preview doesn't jump.\n    const current = getEffectiveTransform(cl, t);\n    this.pushHistory();\n    let kfs = cl.keyframes ?? [];\n    kfs = upsertKeyframe(kfs, \"panX\", t, current.panX, () => createId(\"kf\"));\n    kfs = upsertKeyframe(kfs, \"panY\", t, current.panY, () => createId(\"kf\"));\n    kfs = upsertKeyframe(kfs, \"scale\", t, current.scale, () => createId(\"kf\"));\n    kfs.sort((a, b) => {\n      if (a.prop !== b.prop) return a.prop.localeCompare(b.prop);\n      return a.time - b.time;\n    });\n    cl.keyframes = kfs;\n    // Auto-select the new moment so the left panel pops up\n    // immediately — saves the user a second click. Pick the panX kf\n    // as the deterministic anchor (the moment's grouping logic\n    // doesn't care which sibling is the anchor).\n    const anchor = kfs.find(\n      (k) => k.prop === \"panX\" && Math.abs(k.time - t) < 16,\n    );\n    if (anchor) {\n      this.selectedKeyframe = { clipId, keyframeId: anchor.id };\n      this.bus.emit(\"keyframeSelectionChange\", {\n        target: this.selectedKeyframe,\n      });\n    }\n    this.afterMutation();\n    return true;\n  }\n\n  setSelectedKeyframe(\n    target: { clipId: string; keyframeId: string } | null,\n  ): void {\n    if (\n      target?.clipId === this.selectedKeyframe?.clipId &&\n      target?.keyframeId === this.selectedKeyframe?.keyframeId\n    ) {\n      return;\n    }\n    this.selectedKeyframe = target;\n    // Couple selection to the parent clip — clicking a keyframe makes\n    // the host's clip-level UI light up too.\n    if (target && target.clipId !== this.selectedClipId) {\n      this.selectedClipId = target.clipId;\n      this.bus.emit(\"selectionChange\", { clipId: target.clipId });\n    }\n    this.bus.emit(\"keyframeSelectionChange\", { target });\n    this.ui?.render();\n  }\n\n  // ---- history --------------------------------------------------------\n\n  canUndo(): boolean {\n    return this.history.canUndo();\n  }\n\n  canRedo(): boolean {\n    return this.history.canRedo();\n  }\n\n  undo(): boolean {\n    const prev = this.history.undo(this.project);\n    if (!prev) return false;\n    this.project = prev;\n    this.reconcileSelectionsWithProject();\n    this.engine.setProject(this.project);\n    this.bus.emit(\"change\", { project: this.getProject() });\n    this.emitHistory();\n    this.ui?.render();\n    return true;\n  }\n\n  redo(): boolean {\n    const next = this.history.redo(this.project);\n    if (!next) return false;\n    this.project = next;\n    this.reconcileSelectionsWithProject();\n    this.engine.setProject(this.project);\n    this.bus.emit(\"change\", { project: this.getProject() });\n    this.emitHistory();\n    this.ui?.render();\n    return true;\n  }\n\n  beginInteraction(): void {\n    this.interactionDepth += 1;\n  }\n\n  endInteraction(): void {\n    if (this.interactionDepth === 0) return;\n    this.interactionDepth -= 1;\n    if (this.interactionDepth > 0) return; // still nested\n    const snapshot = this.interactionStartSnapshot;\n    this.interactionStartSnapshot = null;\n    if (snapshot == null) return; // no mutation happened inside\n    // Drop no-op sessions — if the project ended up identical to its\n    // pre-session state (e.g. user pressed mouse, made no real move,\n    // released), don't pollute history with an empty entry.\n    const now = JSON.stringify(this.project);\n    if (now === snapshot) return;\n    this.history.push(JSON.parse(snapshot) as Project);\n    this.emitHistory();\n  }\n\n  /**\n   * Selections (clipId + selectedKeyframe) live OUTSIDE the project\n   * snapshot, so undo / redo can leave them pointing at ids that no\n   * longer exist. Defend against dangling refs by clearing anything\n   * the restored project doesn't actually contain — and emit the\n   * paired change events so panels / overlays hide cleanly instead\n   * of holding zombie references.\n   */\n  private reconcileSelectionsWithProject(): void {\n    if (this.selectedKeyframe) {\n      const trk = findTrackOfClip(this.project, this.selectedKeyframe.clipId);\n      const cl = trk?.clips.find((c) => c.id === this.selectedKeyframe!.clipId);\n      const kf = cl?.keyframes?.find(\n        (k) => k.id === this.selectedKeyframe!.keyframeId,\n      );\n      if (!kf) {\n        this.selectedKeyframe = null;\n        this.bus.emit(\"keyframeSelectionChange\", { target: null });\n      }\n    }\n    if (this.selectedClipId) {\n      const trk = findTrackOfClip(this.project, this.selectedClipId);\n      const cl = trk?.clips.find((c) => c.id === this.selectedClipId);\n      if (!cl) {\n        this.selectedClipId = null;\n        this.bus.emit(\"selectionChange\", { clipId: null });\n      }\n    }\n  }\n\n  // ---- events ---------------------------------------------------------\n\n  on<K extends EditorEventName>(\n    event: K,\n    handler: (payload: EditorEventMap[K]) => void,\n  ): () => void {\n    return this.bus.on(event, handler);\n  }\n\n  off<K extends EditorEventName>(\n    event: K,\n    handler: (payload: EditorEventMap[K]) => void,\n  ): void {\n    this.bus.off(event, handler);\n  }\n\n  destroy(): void {\n    if (this.destroyed) return;\n    this.destroyed = true;\n    this.engine.destroy();\n    this.ui?.destroy();\n    this.bus.clear();\n    this.history.clear();\n  }\n\n  // ---- internals ------------------------------------------------------\n\n  private appendTrack(opts: { kind: Track[\"kind\"] }): Track {\n    const t: Track = { id: createId(\"track\"), kind: opts.kind, clips: [] };\n    this.project.tracks.push(t);\n    return t;\n  }\n\n  private resolveTrimTarget(\n    timeMs: Ms,\n  ): { track: Track; clip: Clip } | null {\n    if (this.selectedClipId) {\n      const trk = findTrackOfClip(this.project, this.selectedClipId);\n      const cl = trk?.clips.find((c) => c.id === this.selectedClipId);\n      if (trk && cl && timeMs >= cl.start && timeMs <= clipEnd(cl)) {\n        return { track: trk, clip: cl };\n      }\n    }\n    for (const trk of this.project.tracks) {\n      const cl = findClipContaining(trk, timeMs);\n      if (cl) return { track: trk, clip: cl };\n    }\n    return null;\n  }\n\n  private pushHistory(): void {\n    // Inside a drag session, only the FIRST pushHistory captures —\n    // subsequent calls during the same session coalesce. endInteraction\n    // is the one that actually pushes the captured snapshot onto the\n    // stack. See beginInteraction / endInteraction docs.\n    if (this.interactionDepth > 0) {\n      if (this.interactionStartSnapshot == null) {\n        this.interactionStartSnapshot = JSON.stringify(this.project);\n      }\n      return;\n    }\n    this.history.push(this.project);\n    this.emitHistory();\n  }\n\n  private emitHistory(): void {\n    this.bus.emit(\"historyChange\", {\n      canUndo: this.history.canUndo(),\n      canRedo: this.history.canRedo(),\n    });\n  }\n\n  private afterMutation(): void {\n    this.engine.setProject(this.project);\n    this.bus.emit(\"change\", { project: this.getProject() });\n    this.ui?.render();\n  }\n\n  private handleSourceMetadata(sourceId: string, durMs: Ms): void {\n    const src = this.project.sources.find((s) => s.id === sourceId);\n    let mutated = false;\n    if (src && !src.duration) {\n      src.duration = durMs;\n      mutated = true;\n    }\n    for (const t of this.project.tracks) {\n      for (const c of t.clips) {\n        if (c.sourceId === sourceId && c.out === 0) {\n          c.out = durMs;\n          mutated = true;\n        }\n      }\n    }\n    this.bus.emit(\"ready\", { sourceId });\n    if (mutated) {\n      // Source metadata patching is not a user action — don't pollute\n      // the undo stack with it.\n      this.engine.setProject(this.project);\n      this.bus.emit(\"change\", { project: this.getProject() });\n      this.ui?.render();\n    }\n  }\n}\n\nfunction clampScale(s: number): number {\n  return Math.max(MIN_PX_PER_SEC, Math.min(MAX_PX_PER_SEC, s));\n}\n\n/** H.264 requires even output dims — snap to the nearest even pixel,\n *  trimming rather than expanding so the canvas never exceeds the\n *  requested size. */\nfunction evenPx(n: number): number {\n  const r = Math.max(2, Math.round(n));\n  return r % 2 === 0 ? r : r - 1;\n}\n"]}