animot-presenter 0.5.25 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@
18
18
  import { cameraTransform, defaultCamera, parallaxOffset } from './utils/camera';
19
19
  import { parseEmbedUrl } from './utils/video-embed';
20
20
  import EmbedPlayer from './EmbedPlayer.svelte';
21
- import { easeInOutCubic, getEasingFn, getBackgroundStyle, gradientShapeToCss, hashFraction, getFloatAnimName, computeFloatAmp, computeFloatSpeed } from './engine/utils';
21
+ import { easeInOutCubic, getEasingFn, getBackgroundStyle, gradientShapeToCss, hashFraction, getFloatAnimName, getIdleAnimName, computeFloatAmp, computeFloatSpeed, entranceRuntimeKeyframe, exitRuntimeKeyframe, emphasisKeyframeName } from './engine/utils';
22
22
  import type {
23
23
  AnimotProject, AnimotPresenterProps, CanvasElement, CodeElement, TextElement,
24
24
  ArrowElement, ImageElement, VideoElement, ShapeElement, CounterElement, ChartElement, IconElement,
@@ -329,6 +329,60 @@
329
329
  let error = $state<string | null>(null);
330
330
  let currentSlideIndex = $state(0);
331
331
  let isTransitioning = $state(false);
332
+ // Phase 2 — runtime entrance/exit registry. Read by the inline
333
+ // style:animation-name on each element render. Window-scoped so the
334
+ // rendering closure can pull the current value without each render
335
+ // needing to be a $derived (Svelte 5 reactive cost). Cleared by timers.
336
+ if (typeof window !== 'undefined') {
337
+ (window as any).__animotPresenterRuntime ||= new Map<string, { entrance?: string; exit?: string; durationMs: number }>();
338
+ }
339
+ const runtimeAnimTimersPresenter = new Map<string, number>();
340
+ function presenterRegisterRuntimeAnim(elementId: string, kind: 'entrance' | 'exit', keyframe: string, durationMs: number, delayMs: number = 0) {
341
+ if (typeof window === 'undefined') return;
342
+ const reg: Map<string, { entrance?: string; exit?: string; durationMs: number; entranceDelayMs?: number; exitDelayMs?: number }> = (window as any).__animotPresenterRuntime;
343
+ const existing = reg.get(elementId) ?? { durationMs };
344
+ const delayKey = kind === 'entrance' ? 'entranceDelayMs' : 'exitDelayMs';
345
+ const next = { ...existing, [kind]: keyframe, durationMs, [delayKey]: delayMs };
346
+ // Drop any stale entrance entry when registering exit so it can't
347
+ // re-fire after the exit clears (would briefly flash the element back).
348
+ if (kind === 'exit' && next.entrance) {
349
+ delete (next as any).entrance;
350
+ delete (next as any).entranceDelayMs;
351
+ const prevEntrTimer = runtimeAnimTimersPresenter.get(`${elementId}:entrance`);
352
+ if (prevEntrTimer) { clearTimeout(prevEntrTimer); runtimeAnimTimersPresenter.delete(`${elementId}:entrance`); }
353
+ }
354
+ reg.set(elementId, next);
355
+ runtimeBump = (runtimeBump + 1) % 1000;
356
+ const key = `${elementId}:${kind}`;
357
+ const prev = runtimeAnimTimersPresenter.get(key);
358
+ if (prev) clearTimeout(prev);
359
+ const t = window.setTimeout(() => {
360
+ const cur = reg.get(elementId);
361
+ if (!cur) return;
362
+ const cleared = { ...cur };
363
+ delete cleared[kind];
364
+ delete cleared[delayKey as 'entranceDelayMs' | 'exitDelayMs'];
365
+ if (!cleared.entrance && !cleared.exit) reg.delete(elementId);
366
+ else reg.set(elementId, cleared);
367
+ runtimeBump = (runtimeBump + 1) % 1000;
368
+ // On exit completion, force inline opacity to 0 so the keyframe's
369
+ // fill-mode-hold state is preserved when the animation-name drops.
370
+ if (kind === 'exit') {
371
+ const animated = animatedElements.get(elementId);
372
+ if (animated) animated.opacity.to(0, { duration: 0 });
373
+ }
374
+ // On entrance completion, snap inline opacity to the element's
375
+ // declared opacity (replaces the keyframe's fill-mode hold).
376
+ if (kind === 'entrance') {
377
+ const animated = animatedElements.get(elementId);
378
+ const el = elementContent.get(elementId);
379
+ const targetOpacity = (el as any)?.opacity ?? 1;
380
+ if (animated) animated.opacity.to(targetOpacity, { duration: 0 });
381
+ }
382
+ }, delayMs + durationMs + 50);
383
+ runtimeAnimTimersPresenter.set(key, t);
384
+ }
385
+ let runtimeBump = $state(0);
332
386
  let isAutoplay = $state(false);
333
387
  let transitionClass = $state('');
334
388
  let transitionDirection = $state<'forward' | 'backward'>('forward');
@@ -810,6 +864,9 @@
810
864
 
811
865
  animateKeyframes(firstSlide);
812
866
  animateMotionPaths(firstSlide);
867
+ // Fire entrance presets so a looping autoplay re-plays the first
868
+ // slide's entrance the same way the initial mount did.
869
+ firePresenterEntrancePresets(0);
813
870
  onslidechange?.(0, slides.length);
814
871
  }
815
872
 
@@ -835,6 +892,25 @@
835
892
  const hasSlideTransition = transition.type !== 'none';
836
893
 
837
894
  if (hasSlideTransition) {
895
+ // Phase 2 sprint-1 polish — fire per-element exit presets BEFORE
896
+ // the slide-level CSS transition starts so they're visible alongside
897
+ // the cross-fade. Skip elements still on the target slide (morph case).
898
+ for (const el of currentSlide.canvas.elements) {
899
+ const exitMode = el.animationConfig?.exit;
900
+ if (!exitMode || exitMode === 'none' || exitMode === 'fade') continue;
901
+ const kf = exitRuntimeKeyframe(exitMode);
902
+ if (!kf) continue;
903
+ const stillOnTarget = !!getElementInSlide(targetSlide, el.id);
904
+ if (stillOnTarget) continue;
905
+ const dur = el.animationConfig?.exitDuration ?? el.animationConfig?.duration ?? 600;
906
+ presenterRegisterRuntimeAnim(el.id, 'exit', kf, dur);
907
+ // Snap opacity to 0 after the CSS exit keyframe finishes so the
908
+ // element vanishes cleanly once the runtime registry entry expires.
909
+ const elId = el.id;
910
+ const animatedRef = animatedElements.get(elId);
911
+ if (animatedRef) setTimeout(() => animatedRef.opacity.to(0, { duration: 0 }), dur);
912
+ }
913
+
838
914
  transitionClass = `transition-${transition.type}-out`;
839
915
  await new Promise(r => setTimeout(r, duration * 0.4));
840
916
  const newElementContent = new Map(elementContent);
@@ -888,7 +964,13 @@
888
964
  }
889
965
  if (animated.motionPathProgress) animated.motionPathProgress.to(0, { duration: 0 });
890
966
  }
891
- } else if (animated) { animated.opacity.to(0, { duration: 0 }); }
967
+ } else if (animated) {
968
+ // Skip instant opacity snap when an exit preset is mid-animation;
969
+ // its setTimeout handles the opacity-to-0 after exit duration.
970
+ const reg = typeof window !== 'undefined' ? (window as any).__animotPresenterRuntime as Map<string, { exit?: string }> | undefined : undefined;
971
+ const hasActiveExit = !!reg?.get(elementId)?.exit;
972
+ if (!hasActiveExit) animated.opacity.to(0, { duration: 0 });
973
+ }
892
974
  }
893
975
  for (const [, element] of newElementContent) {
894
976
  if (element.type === 'code') {
@@ -917,6 +999,10 @@
917
999
  }
918
1000
  }
919
1001
  transitionClass = `transition-${transition.type}-in`;
1002
+ // Fire per-element entrance presets on the target slide so they
1003
+ // play alongside the slide-level cross-fade-in. Without this,
1004
+ // slide-level transitions skip per-element entrance animations.
1005
+ firePresenterEntrancePresets(targetIndex);
920
1006
  await new Promise(r => setTimeout(r, duration * 0.6));
921
1007
  transitionClass = '';
922
1008
  animateKeyframes(targetSlide);
@@ -1000,6 +1086,55 @@
1000
1086
  const delay = animConfig?.delay ?? 0;
1001
1087
  const elementDuration = animConfig?.duration ?? duration;
1002
1088
 
1089
+ // Phase 2 opt-out: when currentEl has an exit preset and element
1090
+ // continues to next slide, exit on current, snap to target pose,
1091
+ // then play target's entrance. Overrides morph.
1092
+ const exitPresetMode = currentEl?.animationConfig?.exit;
1093
+ const hasExitOptOut = !!currentEl && !!targetEl
1094
+ && exitPresetMode && exitPresetMode !== 'none' && exitPresetMode !== 'fade';
1095
+ if (hasExitOptOut) {
1096
+ const exitKf = exitRuntimeKeyframe(exitPresetMode);
1097
+ const exitDuration = currentEl.animationConfig?.exitDuration ?? elementDuration;
1098
+ const entranceMode = targetEl.animationConfig?.entrance;
1099
+ const entranceKf = entranceMode ? entranceRuntimeKeyframe(entranceMode) : null;
1100
+ const entranceDuration = entranceMode && entranceMode !== 'none' && entranceMode !== 'fade'
1101
+ ? (targetEl.animationConfig?.entranceDuration ?? targetEl.animationConfig?.duration ?? 600)
1102
+ : 0;
1103
+ if (exitKf) presenterRegisterRuntimeAnim(currentEl.id, 'exit', exitKf, exitDuration);
1104
+ animationTasks.push({
1105
+ elementId,
1106
+ order,
1107
+ delay,
1108
+ elementDuration: exitDuration + entranceDuration,
1109
+ run: () => [(async () => {
1110
+ await new Promise(r => setTimeout(r, exitDuration));
1111
+ animated.x.to(targetEl.position.x, { duration: 0 });
1112
+ animated.y.to(targetEl.position.y, { duration: 0 });
1113
+ animated.width.to(targetEl.size.width, { duration: 0 });
1114
+ animated.height.to(targetEl.size.height, { duration: 0 });
1115
+ animated.rotation.to(targetEl.rotation, { duration: 0 });
1116
+ animated.skewX.to(targetEl.skewX ?? 0, { duration: 0 });
1117
+ animated.skewY.to(targetEl.skewY ?? 0, { duration: 0 });
1118
+ animated.tiltX.to(targetEl.tiltX ?? 0, { duration: 0 });
1119
+ animated.tiltY.to(targetEl.tiltY ?? 0, { duration: 0 });
1120
+ animated.perspective.to(targetEl.perspective ?? 1000, { duration: 0 });
1121
+ animated.borderRadius.to((targetEl as any).borderRadius ?? 0, { duration: 0 });
1122
+ animated.opacity.to((targetEl as any).opacity ?? 1, { duration: 0 });
1123
+ if (targetEl.type === 'text' && animated.fontSize) {
1124
+ animated.fontSize.to((targetEl as TextElement).fontSize, { duration: 0 });
1125
+ }
1126
+ if (targetEl.type === 'shape') {
1127
+ const shapeEl = targetEl as ShapeElement;
1128
+ if (animated.fillColor) animated.fillColor.to(shapeEl.fillColor, { duration: 0 });
1129
+ if (animated.strokeColor) animated.strokeColor.to(shapeEl.strokeColor, { duration: 0 });
1130
+ if (animated.strokeWidth) animated.strokeWidth.to(shapeEl.strokeWidth, { duration: 0 });
1131
+ }
1132
+ if (entranceKf) presenterRegisterRuntimeAnim(targetEl.id, 'entrance', entranceKf, entranceDuration);
1133
+ })()]
1134
+ });
1135
+ continue;
1136
+ }
1137
+
1003
1138
  if (targetEl) {
1004
1139
  const easing = getEasingFn(animConfig?.easing);
1005
1140
  const propertySequences = targetEl.animationConfig?.propertySequences;
@@ -1036,7 +1171,9 @@
1036
1171
  if (!sequencedProps.has('perspective')) anims.push(animated.perspective.to(targetEl.perspective ?? 1000, { duration: elementDuration, easing }));
1037
1172
  if (!sequencedProps.has('opacity')) {
1038
1173
  const targetOpacity = (targetEl as any).opacity ?? 1;
1039
- if (animated.opacity.current !== targetOpacity) anims.push(animated.opacity.to(targetOpacity, { duration: elementDuration, easing }));
1174
+ const entrPreset = (targetEl as any).animationConfig?.entrance;
1175
+ const hasPresetEntrance = entrPreset && entrPreset !== 'fade' && entrPreset !== 'none';
1176
+ if (!hasPresetEntrance && animated.opacity.current !== targetOpacity) anims.push(animated.opacity.to(targetOpacity, { duration: elementDuration, easing }));
1040
1177
  }
1041
1178
  const sortedSeqs = [...propertySequences].sort((a, b) => a.order - b.order);
1042
1179
  let cumulativeDelay = 0;
@@ -1086,10 +1223,13 @@
1086
1223
  anims.push(animated.contrast.to(targetEl.contrast ?? 100, { duration: elementDuration, easing }));
1087
1224
  anims.push(animated.saturate.to(targetEl.saturate ?? 100, { duration: elementDuration, easing }));
1088
1225
  anims.push(animated.grayscale.to(targetEl.grayscale ?? 0, { duration: elementDuration, easing }));
1089
- // Opacity interpolation for morphing elements
1226
+ // Opacity. Skip when a preset entrance is configured so the
1227
+ // CSS keyframe owns opacity for the entire entrance.
1228
+ const entrPreset = (targetEl as any).animationConfig?.entrance;
1229
+ const hasPresetEntrance = entrPreset && entrPreset !== 'fade' && entrPreset !== 'none';
1090
1230
  const currOpacity = animated.opacity.current;
1091
1231
  const targetOpacity = (targetEl as any).opacity ?? 1;
1092
- if (currOpacity !== targetOpacity) {
1232
+ if (!hasPresetEntrance && currOpacity !== targetOpacity) {
1093
1233
  anims.push(animated.opacity.to(targetOpacity, { duration: elementDuration, easing }));
1094
1234
  }
1095
1235
  }
@@ -1154,7 +1294,11 @@
1154
1294
  }
1155
1295
  const entrance = targetEl.animationConfig?.entrance ?? 'fade';
1156
1296
  const targetOpacity = (targetEl as any).opacity ?? 1;
1157
- if (entrance === 'fade') {
1297
+ const presetKf = entranceRuntimeKeyframe(entrance);
1298
+ if (presetKf && entrance !== 'fade' && entrance !== 'none') {
1299
+ // Let CSS keyframe own opacity for entire entrance (no inline snap).
1300
+ presenterRegisterRuntimeAnim(targetEl.id, 'entrance', presetKf, targetEl.animationConfig?.entranceDuration ?? elementDuration, order * 100 + delay);
1301
+ } else if (entrance === 'fade') {
1158
1302
  anims.push(animated.opacity.to(targetOpacity, { duration: elementDuration / 2, easing }));
1159
1303
  } else {
1160
1304
  anims.push(animated.opacity.to(targetOpacity, { duration: 0 }));
@@ -1164,8 +1308,23 @@
1164
1308
  }
1165
1309
  });
1166
1310
  } else if (currentEl) {
1167
- const exit = currentEl.animationConfig?.exit ?? 'fade';
1168
- if (exit === 'fade') {
1311
+ // Default to instant when no exit preset is set; explicit 'fade' still fades.
1312
+ const exit = currentEl.animationConfig?.exit ?? 'none';
1313
+ const exitKf = exitRuntimeKeyframe(exit);
1314
+ if (exitKf && exit !== 'fade' && exit !== 'none') {
1315
+ const exitDuration = currentEl.animationConfig?.exitDuration ?? elementDuration;
1316
+ presenterRegisterRuntimeAnim(currentEl.id, 'exit', exitKf, exitDuration);
1317
+ animationTasks.push({
1318
+ elementId,
1319
+ order,
1320
+ delay,
1321
+ elementDuration: exitDuration,
1322
+ run: () => [(async () => {
1323
+ await new Promise(r => setTimeout(r, exitDuration));
1324
+ await animated.opacity.to(0, { duration: 0 });
1325
+ })()]
1326
+ });
1327
+ } else if (exit === 'fade') {
1169
1328
  const fadeOutDuration = Math.min(elementDuration / 2, 300);
1170
1329
  animationTasks.push({ elementId, order, delay, elementDuration, run: () => [animated.opacity.to(0, { duration: fadeOutDuration, easing: easeInOutCubic })] });
1171
1330
  } else {
@@ -1228,12 +1387,17 @@
1228
1387
  elementContent = newElementContent;
1229
1388
  currentSlideIndex = targetIndex;
1230
1389
  isTransitioning = false;
1231
- // Ensure elements not on the new slide are fully hidden
1390
+ // Ensure elements not on the new slide are fully hidden. Phase 2:
1391
+ // skip elements with an active runtime exit registration — their
1392
+ // exit task snaps opacity itself after the keyframe finishes, so a
1393
+ // preemptive snap here would cut the visual exit short.
1232
1394
  const newSlide = slides[targetIndex];
1395
+ const reg = typeof window !== 'undefined' ? (window as any).__animotPresenterRuntime as Map<string, { exit?: string }> | undefined : undefined;
1233
1396
  for (const elementId of allElementIds) {
1234
1397
  const onSlide = getElementInSlide(newSlide, elementId);
1235
1398
  const animated = animatedElements.get(elementId);
1236
- if (!onSlide && animated) { animated.opacity.to(0, { duration: 0 }); }
1399
+ const hasActiveExit = !!reg?.get(elementId)?.exit;
1400
+ if (!onSlide && animated && !hasActiveExit) { animated.opacity.to(0, { duration: 0 }); }
1237
1401
  }
1238
1402
  animateKeyframes(slides[targetIndex]);
1239
1403
  animateMotionPaths(slides[targetIndex]);
@@ -1415,6 +1579,24 @@
1415
1579
  // ResizeObserver
1416
1580
  let resizeObserver: ResizeObserver;
1417
1581
 
1582
+ // Phase 2 sprint-1 polish — fire entrance presets for elements on the
1583
+ // currently visible slide. Used at initial load AND every time the
1584
+ // reactive `currentSlide` flips (covers navigation, autoplay loop reset,
1585
+ // remote-controlled slide jumps).
1586
+ function firePresenterEntrancePresets(slideIdx: number) {
1587
+ const slide = slides[slideIdx];
1588
+ if (!slide) return;
1589
+ for (const el of slide.canvas.elements) {
1590
+ const mode = el.animationConfig?.entrance;
1591
+ if (!mode || mode === 'none' || mode === 'fade') continue;
1592
+ const kf = entranceRuntimeKeyframe(mode);
1593
+ if (!kf) continue;
1594
+ const dur = el.animationConfig?.entranceDuration ?? el.animationConfig?.duration ?? 600;
1595
+ const delay = (el.animationConfig?.order ?? 0) * 100 + (el.animationConfig?.delay ?? 0);
1596
+ presenterRegisterRuntimeAnim(el.id, 'entrance', kf, dur, delay);
1597
+ }
1598
+ }
1599
+
1418
1600
  onMount(() => {
1419
1601
  loadProject();
1420
1602
  resizeObserver = new ResizeObserver(entries => {
@@ -1425,6 +1607,9 @@
1425
1607
  });
1426
1608
  if (containerEl) resizeObserver.observe(containerEl);
1427
1609
  resetMouseIdleTimer();
1610
+ // Slide 0 entrance presets need to fire on initial mount — the
1611
+ // transition pipeline only runs on navigation, not on load.
1612
+ queueMicrotask(() => firePresenterEntrancePresets(currentSlideIndex));
1428
1613
 
1429
1614
  return () => {
1430
1615
  resizeObserver?.disconnect();
@@ -1432,6 +1617,14 @@
1432
1617
  clearAllTypewriterAnimations();
1433
1618
  if (mouseIdleTimer) clearTimeout(mouseIdleTimer);
1434
1619
  stopNarration();
1620
+ // Phase 2 — clean up runtime entrance/exit timers + registry to
1621
+ // avoid leaks when the presenter is unmounted (e.g. modal close).
1622
+ for (const t of runtimeAnimTimersPresenter.values()) clearTimeout(t);
1623
+ runtimeAnimTimersPresenter.clear();
1624
+ if (typeof window !== 'undefined') {
1625
+ const reg = (window as any).__animotPresenterRuntime as Map<string, unknown> | undefined;
1626
+ reg?.clear();
1627
+ }
1435
1628
  };
1436
1629
  });
1437
1630
 
@@ -1514,7 +1707,8 @@
1514
1707
  ? mpPoint.angle + (mpConfig.orientationOffset ?? 0)
1515
1708
  : null}
1516
1709
  {@const parallax = isCinemaMode && element?.depth ? parallaxOffset(currentCamera, element.depth, worldWidth, worldHeight) : { x: 0, y: 0 }}
1517
- {#if element && animated && animated.opacity.current > 0.01 && element.visible !== false && !(element.type === 'motionPath' && !(element as MotionPathElement).showInPresentation)}
1710
+ {@const _entranceActive = (() => { void runtimeBump; const hasReg = typeof window !== 'undefined' && !!((window as any).__animotPresenterRuntime as Map<string, { entrance?: string }> | undefined)?.get(elementId)?.entrance; return hasReg && !!getElementInSlide(currentSlide, elementId); })()}
1711
+ {#if element && animated && (animated.opacity.current > 0.01 || _entranceActive) && element.visible !== false && !(element.type === 'motionPath' && !(element as MotionPathElement).showInPresentation)}
1518
1712
  <div
1519
1713
  class="animot-element"
1520
1714
  class:floating={hasFloat}
@@ -1529,9 +1723,44 @@
1529
1723
  style:backface-visibility={element.backfaceVisibility ?? 'visible'}
1530
1724
  style:z-index={element.zIndex}
1531
1725
  style:--float-amp="{hasFloat ? computeFloatAmp(floatCfg, floatGroupId || elementId) : 10}px"
1726
+ style:--float-amp-scale={hasFloat ? 1 + computeFloatAmp(floatCfg, floatGroupId || elementId) / 200 : 1.05}
1727
+ style:--float-amp-rot="{hasFloat ? computeFloatAmp(floatCfg, floatGroupId || elementId) / 2 : 5}deg"
1532
1728
  style:--float-speed="{hasFloat ? computeFloatSpeed(floatCfg, floatGroupId || elementId) : 3}s"
1533
1729
  style:--float-delay="{hashFraction(floatGroupId || elementId, 3) * 2}s"
1534
- style:animation-name={hasFloat ? getFloatAnimName(floatCfg!.direction, floatGroupId || elementId) : 'none'}
1730
+ style:animation={(() => {
1731
+ // Phase 2 — single CSS `animation:` shorthand composing
1732
+ // runtime exit + entrance + emphasis + floating. One
1733
+ // inline write keeps all layers in sync.
1734
+ void runtimeBump;
1735
+ const parts: string[] = [];
1736
+ const ra = (typeof window !== 'undefined' && (window as any).__animotPresenterRuntime)
1737
+ ? (window as any).__animotPresenterRuntime.get(elementId)
1738
+ : null;
1739
+ if (ra?.exit) {
1740
+ const xd = ra.exitDelayMs ?? 0;
1741
+ if (xd > 0) parts.push(`${ra.durationMs}ms ease-in ${xd}ms 1 forwards ${ra.exit}`);
1742
+ else parts.push(`${ra.durationMs}ms ease-in 1 forwards ${ra.exit}`);
1743
+ }
1744
+ if (ra?.entrance) {
1745
+ const ed = ra.entranceDelayMs ?? 0;
1746
+ if (ed > 0) parts.push(`${ra.durationMs}ms ease-out ${ed}ms 1 both ${ra.entrance}`);
1747
+ else parts.push(`${ra.durationMs}ms ease-out 1 both ${ra.entrance}`);
1748
+ }
1749
+ const emphKf = emphasisKeyframeName(element?.animationConfig?.emphasis);
1750
+ if (emphKf) {
1751
+ const isOneShot = element?.animationConfig?.emphasis === 'tada' || element?.animationConfig?.emphasis === 'bob-once';
1752
+ const cfgDur = element?.animationConfig?.emphasisDuration;
1753
+ const defaultDur = isOneShot ? 1200 : 2200;
1754
+ const dur = typeof cfgDur === 'number' && cfgDur > 0 ? cfgDur : defaultDur;
1755
+ const delay = element?.animationConfig?.emphasisDelay ?? 0;
1756
+ parts.push(`${dur}ms ease-in-out ${delay}ms ${isOneShot ? '1' : 'infinite'} ${isOneShot ? 'both' : 'none'} ${emphKf}`);
1757
+ }
1758
+ if (hasFloat) {
1759
+ const speed = computeFloatSpeed(floatCfg, floatGroupId || elementId);
1760
+ parts.push(`${speed}s ease-in-out infinite none ${getIdleAnimName(floatCfg, floatGroupId || elementId)}`);
1761
+ }
1762
+ return parts.length ? parts.join(', ') : 'none';
1763
+ })()}
1535
1764
  style:filter={(() => { const parts: string[] = []; const b = animated.blur.current; const br2 = animated.brightness.current; const c = animated.contrast.current; const s = animated.saturate.current; const g = animated.grayscale.current; if (b) parts.push(`blur(${b}px)`); if (br2 !== 100) parts.push(`brightness(${br2}%)`); if (c !== 100) parts.push(`contrast(${c}%)`); if (s !== 100) parts.push(`saturate(${s}%)`); if (g) parts.push(`grayscale(${g}%)`); return parts.length ? parts.join(' ') : 'none'; })()}
1536
1765
  use:decorations={{ config: element.decorations, slideDuration: currentSlide?.duration, shape: element.type === 'shape' ? { type: (element as any).shapeType, borderRadius: (element as any).borderRadius } : undefined, key: `${currentSlideIndex}-${JSON.stringify(element.decorations ?? null)}-${element.type === 'shape' ? (element as any).shapeType + ':' + ((element as any).borderRadius ?? 0) : ''}` }}
1537
1766
  >
@@ -1598,7 +1827,7 @@
1598
1827
  {@const typewriterState = textTypewriterState.get(element.id)}
1599
1828
  {@const displayText = typewriterState?.isAnimating ? typewriterState.fullText.slice(0, typewriterState.displayedChars) : textEl.content}
1600
1829
  {@const textAnimMode = textEl.animation?.mode ?? 'instant'}
1601
- {@const isActionTextMode = textAnimMode === 'fade-letters' || textAnimMode === 'bounce-in' || textAnimMode === 'handwriting'}
1830
+ {@const isActionTextMode = textAnimMode === 'fade-letters' || textAnimMode === 'bounce-in' || textAnimMode === 'handwriting' || textAnimMode === 'scramble-in' || textAnimMode === 'slot-machine' || textAnimMode === 'drop' || textAnimMode === 'glitch' || textAnimMode === 'marquee' || textAnimMode === 'blur-in' || textAnimMode === 'stretch' || textAnimMode === 'slide-words' || textAnimMode === 'wave' || textAnimMode === 'typewriter-erase'}
1602
1831
  <div
1603
1832
  class="animot-text-element"
1604
1833
  style:font-size="{animFontSize}px"
@@ -1 +1 @@
1
- .code-morph.svelte-1hmk0l{width:100%;height:100%;margin:0;padding:0;background:transparent;font-family:var(--font-mono, "JetBrains Mono", monospace);font-size:inherit;line-height:1.6;white-space:pre-wrap;word-wrap:break-word;color:#e6edf3;box-sizing:border-box;overflow:visible}.code-morph.svelte-1hmk0l pre{margin:0;padding:16px;background:transparent!important;font-family:var(--font-mono);font-size:inherit;line-height:1.6;overflow:visible}.code-morph.svelte-1hmk0l code{font-family:inherit;font-size:inherit;font-weight:inherit}.code-morph.svelte-1hmk0l .line-number{display:inline-block;width:2.5em;margin-right:1em;text-align:right;color:#6e7681;-webkit-user-select:none;user-select:none;opacity:.6}.code-morph.svelte-1hmk0l .word-highlight{background:var(--highlight-color, #facc15);color:#000;border-radius:3px;padding:1px 3px;margin:0 -3px;-webkit-box-decoration-break:clone;box-decoration-break:clone;animation:svelte-1hmk0l-fadeHighlight var(--duration, 1s) ease-out forwards}@keyframes svelte-1hmk0l-fadeHighlight{0%{background:var(--highlight-color, #facc15);color:#000}70%{background:var(--highlight-color, #facc15);color:#000}to{background:transparent;color:inherit}}.counter.svelte-1er5jjj{width:100%;height:100%;display:flex;align-items:center;justify-content:center;box-sizing:border-box;overflow:hidden;white-space:nowrap}.animot-chart.svelte-1mq2d7j{width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;overflow:hidden}.animot-chart-title.svelte-1mq2d7j{font-weight:600;text-align:center;margin-bottom:8px}.animot-chart-content.svelte-1mq2d7j{flex:1;min-height:0;display:flex;flex-direction:column}.animot-chart-content.svelte-1mq2d7j svg:where(.svelte-1mq2d7j){width:100%;flex:1;min-height:0}.animot-bar-chart.svelte-1mq2d7j,.animot-line-chart.svelte-1mq2d7j{overflow:visible}.animot-series-legend.svelte-1mq2d7j{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;padding:6px 0 0;font-size:.85em}.animot-legend-item.svelte-1mq2d7j{display:inline-flex;align-items:center;gap:5px}.animot-swatch.svelte-1mq2d7j{width:10px;height:10px;border-radius:2px;display:inline-block}.progress-element.svelte-10tny4e{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;position:relative;box-sizing:border-box}.bar-track.svelte-10tny4e,.ring-svg.svelte-10tny4e{flex-shrink:0}.progress-element.ring.svelte-10tny4e .ring-svg:where(.svelte-10tny4e){width:100%;height:100%;min-height:0;min-width:0}.bar-track.svelte-10tny4e{position:relative;overflow:hidden}.bar-fill.svelte-10tny4e{position:absolute;display:flex;align-items:center;justify-content:center;transition:width 0s,height 0s}.bar-stripe-clip.svelte-10tny4e{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden}.bar-stripe-tape.svelte-10tny4e{position:absolute;top:0;left:0;width:calc(100% + var(--stripe-cycle));height:100%;mask-image:var(--stripe-mask);-webkit-mask-image:var(--stripe-mask);mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;animation:svelte-10tny4e-progress-stripe-x var(--stripe-speed) linear infinite;animation-direction:var(--stripe-direction);will-change:transform}.bar-stripe-tape.vertical.svelte-10tny4e{width:100%;height:calc(100% + var(--stripe-cycle));animation-name:svelte-10tny4e-progress-stripe-y}@keyframes svelte-10tny4e-progress-stripe-x{0%{transform:translate(0)}to{transform:translate(calc(-1 * var(--stripe-cycle)))}}@keyframes svelte-10tny4e-progress-stripe-y{0%{transform:translateY(0)}to{transform:translateY(calc(-1 * var(--stripe-cycle)))}}.ring-svg.svelte-10tny4e{width:100%;height:100%}.ring-spin.svelte-10tny4e{animation:svelte-10tny4e-progress-ring-spin 1.4s linear infinite;transform-origin:50% 50%}@keyframes svelte-10tny4e-progress-ring-spin{to{transform:rotate(360deg)}}.label.svelte-10tny4e{text-align:center;white-space:nowrap;pointer-events:none}.label.center.svelte-10tny4e{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.label.inside.svelte-10tny4e{padding:0 8px;flex-shrink:0}.label.inside-vertical.svelte-10tny4e{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);text-orientation:mixed;writing-mode:horizontal-tb}.animot-container-element.svelte-e5oeuv{box-sizing:border-box;pointer-events:none}.icon-element.svelte-2ld65o{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.icon-element.svelte-2ld65o svg{width:100%;height:100%}.flow-markers.svelte-15cxp1m{pointer-events:none}.embed-player.svelte-1u59mvz{position:relative;width:100%;height:100%;background:#000;overflow:hidden}.embed-frame.svelte-1u59mvz{width:100%;height:100%;display:block;border:0}.embed-frame.passthrough.svelte-1u59mvz{pointer-events:none}.custom-controls.svelte-1u59mvz{position:absolute;left:8px;right:8px;bottom:8px;display:flex;align-items:center;gap:10px;padding:6px 10px;background:#0009;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-radius:8px;opacity:0;transition:opacity .2s}.embed-player.svelte-1u59mvz:hover .custom-controls:where(.svelte-1u59mvz),.custom-controls.svelte-1u59mvz:focus-within{opacity:1}.ctrl-btn.svelte-1u59mvz{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:0;border-radius:4px;color:#fff;cursor:pointer}.ctrl-btn.svelte-1u59mvz:hover{background:#ffffff26}.ctrl-btn.svelte-1u59mvz svg:where(.svelte-1u59mvz){width:16px;height:16px}.scrub.svelte-1u59mvz{flex:1;accent-color:#6366f1}.time.svelte-1u59mvz{font-size:11px;color:#ffffffd9;font-variant-numeric:tabular-nums;min-width:80px;text-align:right}@keyframes float-vertical{0%,to{translate:0 0}50%{translate:0 calc(-1 * var(--float-amp, 10px))}}@keyframes float-horizontal{0%,to{translate:0 0}50%{translate:var(--float-amp, 10px) 0}}@keyframes float-both-0{0%{translate:0 0}15%{translate:calc(.8 * var(--float-amp, 10px)) calc(-.6 * var(--float-amp, 10px))}35%{translate:calc(-.4 * var(--float-amp, 10px)) calc(-1 * var(--float-amp, 10px))}55%{translate:calc(-.9 * var(--float-amp, 10px)) calc(.3 * var(--float-amp, 10px))}75%{translate:calc(.3 * var(--float-amp, 10px)) calc(.7 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes float-both-1{0%{translate:0 0}20%{translate:calc(-.7 * var(--float-amp, 10px)) calc(-.8 * var(--float-amp, 10px))}40%{translate:calc(.5 * var(--float-amp, 10px)) calc(-.3 * var(--float-amp, 10px))}60%{translate:calc(.9 * var(--float-amp, 10px)) calc(.6 * var(--float-amp, 10px))}80%{translate:calc(-.4 * var(--float-amp, 10px)) calc(.9 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes float-both-2{0%{translate:0 0}12%{translate:calc(.6 * var(--float-amp, 10px)) calc(.5 * var(--float-amp, 10px))}30%{translate:calc(1 * var(--float-amp, 10px)) calc(-.4 * var(--float-amp, 10px))}50%{translate:calc(-.3 * var(--float-amp, 10px)) calc(-.9 * var(--float-amp, 10px))}70%{translate:calc(-.8 * var(--float-amp, 10px)) calc(.2 * var(--float-amp, 10px))}88%{translate:calc(.2 * var(--float-amp, 10px)) calc(.8 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes float-both-3{0%{translate:0 0}17%{translate:calc(-.9 * var(--float-amp, 10px)) calc(.4 * var(--float-amp, 10px))}33%{translate:calc(-.5 * var(--float-amp, 10px)) calc(-.7 * var(--float-amp, 10px))}50%{translate:calc(.7 * var(--float-amp, 10px)) calc(-.9 * var(--float-amp, 10px))}67%{translate:calc(.9 * var(--float-amp, 10px)) calc(.5 * var(--float-amp, 10px))}83%{translate:calc(-.2 * var(--float-amp, 10px)) calc(.8 * var(--float-amp, 10px))}to{translate:0 0}}.animot-svg-element.icon-anim-draw path,.animot-svg-element.icon-anim-draw circle,.animot-svg-element.icon-anim-draw rect,.animot-svg-element.icon-anim-draw line,.animot-svg-element.icon-anim-draw polyline,.animot-svg-element.icon-anim-draw polygon,.animot-svg-element.icon-anim-draw ellipse{stroke-dashoffset:var(--path-len, 1000);animation:animot-svg-draw var(--icon-anim-duration, .8s) ease-out forwards}.animot-svg-element.icon-anim-undraw path,.animot-svg-element.icon-anim-undraw circle,.animot-svg-element.icon-anim-undraw rect,.animot-svg-element.icon-anim-undraw line,.animot-svg-element.icon-anim-undraw polyline,.animot-svg-element.icon-anim-undraw polygon,.animot-svg-element.icon-anim-undraw ellipse{stroke-dashoffset:0;animation:animot-svg-undraw var(--icon-anim-duration, .8s) ease-out forwards}.animot-svg-element.icon-anim-draw-undraw path,.animot-svg-element.icon-anim-draw-undraw circle,.animot-svg-element.icon-anim-draw-undraw rect,.animot-svg-element.icon-anim-draw-undraw line,.animot-svg-element.icon-anim-draw-undraw polyline,.animot-svg-element.icon-anim-draw-undraw polygon,.animot-svg-element.icon-anim-draw-undraw ellipse{stroke-dashoffset:var(--path-len, 1000);animation:animot-svg-draw-undraw var(--icon-anim-duration, .8s) ease-out forwards}.animot-svg-element.icon-anim-loop path,.animot-svg-element.icon-anim-loop circle,.animot-svg-element.icon-anim-loop rect,.animot-svg-element.icon-anim-loop line,.animot-svg-element.icon-anim-loop polyline,.animot-svg-element.icon-anim-loop polygon,.animot-svg-element.icon-anim-loop ellipse{animation-iteration-count:infinite!important}.animot-svg-element.icon-anim-reverse path,.animot-svg-element.icon-anim-reverse circle,.animot-svg-element.icon-anim-reverse rect,.animot-svg-element.icon-anim-reverse line,.animot-svg-element.icon-anim-reverse polyline,.animot-svg-element.icon-anim-reverse polygon,.animot-svg-element.icon-anim-reverse ellipse{animation-direction:reverse!important}@keyframes animot-svg-draw{to{stroke-dashoffset:0}}@keyframes animot-svg-undraw{0%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}@keyframes animot-svg-draw-undraw{0%{stroke-dashoffset:var(--path-len, 1000)}50%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}.animot-presenter.svelte-16ocdv9 *{margin:0;padding:0;box-sizing:border-box}.animot-presenter.svelte-16ocdv9{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;background:transparent;line-height:normal;font-size:16px;font-weight:400;font-style:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;text-indent:0;text-align:left;color:inherit}.animot-canvas-wrapper.svelte-16ocdv9{display:flex;align-items:center;justify-content:center}.animot-canvas.svelte-16ocdv9{position:relative;overflow:hidden}.animot-element.svelte-16ocdv9{position:absolute;box-sizing:border-box;will-change:transform,opacity,left,top,width,height;isolation:isolate}.animot-element.floating.svelte-16ocdv9{animation-duration:var(--float-speed, 3s);animation-timing-function:ease-in-out;animation-iteration-count:infinite;animation-delay:var(--float-delay, 0s)}.animot-code-block.svelte-16ocdv9{width:100%;height:100%;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 8px 32px #0006;margin:0;box-sizing:border-box}.animot-code-block.transparent-bg.svelte-16ocdv9{background:transparent!important;box-shadow:none}.animot-code-block.transparent-bg.svelte-16ocdv9 .animot-code-header:where(.svelte-16ocdv9){background:transparent;border-bottom-color:#ffffff0f}.animot-code-header.svelte-16ocdv9{display:flex;align-items:center;gap:8px;padding:8px 12px;background:#0003;border-bottom:1px solid rgba(255,255,255,.06);flex-shrink:0;min-height:40px}.animot-window-controls.svelte-16ocdv9{display:flex;gap:8px;align-items:center;flex-shrink:0}.macos.svelte-16ocdv9 .animot-control:where(.svelte-16ocdv9){width:12px;height:12px;border-radius:50%;display:block}.macos.svelte-16ocdv9 .animot-control.close:where(.svelte-16ocdv9){background:#ff5f57}.macos.svelte-16ocdv9 .animot-control.minimize:where(.svelte-16ocdv9){background:#febc2e}.macos.svelte-16ocdv9 .animot-control.maximize:where(.svelte-16ocdv9){background:#28c840}.windows.svelte-16ocdv9 .animot-window-controls:where(.svelte-16ocdv9){order:99;margin-left:auto;gap:0}.windows.svelte-16ocdv9 .animot-control:where(.svelte-16ocdv9){display:flex;align-items:center;justify-content:center;width:28px;height:24px;border-radius:4px;color:#ffffff73}.animot-filename-tab.svelte-16ocdv9{display:flex;align-items:center;gap:6px;background:#ffffff0f;border:1px solid rgba(255,255,255,.08);border-radius:6px;padding:4px 10px;max-width:220px;color:#fff6}.animot-file-icon.svelte-16ocdv9{flex-shrink:0}.animot-filename.svelte-16ocdv9{color:#ffffff8c;font-size:12px;line-height:18px}.animot-copy-code-btn.svelte-16ocdv9{display:flex;align-items:center;gap:5px;height:28px;padding:0 8px;margin-left:auto;background:#ffffff0f;border:1px solid rgba(255,255,255,.1);border-radius:6px;color:#fff6;cursor:pointer;opacity:0;transition:opacity .2s,background .15s,color .15s;flex-shrink:0;font-size:12px;font-family:inherit;white-space:nowrap}.animot-copy-code-btn.svelte-16ocdv9:hover{background:#ffffff1f;color:#fffc}.animot-copy-code-btn.svelte-16ocdv9 svg:where(.svelte-16ocdv9){width:14px;height:14px;flex-shrink:0}.animot-copy-code-btn.svelte-16ocdv9 .animot-check-icon:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.svelte-16ocdv9 .animot-copied-label:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-copy-icon:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-copy-label:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-check-icon:where(.svelte-16ocdv9){display:block;color:#4ade80}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-copied-label:where(.svelte-16ocdv9){display:inline;color:#4ade80}.animot-copy-code-btn.animot-floating.svelte-16ocdv9{position:absolute;top:8px;right:8px;z-index:2}.animot-code-block.svelte-16ocdv9:hover .animot-copy-code-btn:where(.svelte-16ocdv9){opacity:1}.animot-code-content.svelte-16ocdv9{flex:1;overflow:hidden;position:relative}.animot-highlighted-code.svelte-16ocdv9{width:100%;height:100%}.animot-code-content.svelte-16ocdv9 pre,.animot-highlighted-code.svelte-16ocdv9 pre{margin:0;padding:16px;background:transparent!important;line-height:1.6;font-size:inherit;overflow:visible}.animot-highlighted-code.svelte-16ocdv9 code{font-family:inherit;font-size:inherit;font-weight:inherit}.animot-highlighted-code.svelte-16ocdv9 .line-number{display:inline-block;width:2.5em;margin-right:1em;text-align:right;color:#6e7681;-webkit-user-select:none;user-select:none;opacity:.6}.animot-text-element.svelte-16ocdv9{width:100%;height:100%;display:flex;align-items:center;white-space:pre-wrap;word-wrap:break-word}.animot-typewriter-cursor.svelte-16ocdv9{animation:svelte-16ocdv9-animot-blink .7s infinite;font-weight:100}@keyframes svelte-16ocdv9-animot-blink{0%,50%{opacity:1}51%,to{opacity:0}}.animot-arrow-element.svelte-16ocdv9{width:100%;height:100%}.arrow-animate-draw.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9){stroke-dashoffset:var(--path-len, 1000);animation:svelte-16ocdv9-animot-arrow-draw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-undraw.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9){stroke-dashoffset:0;animation:svelte-16ocdv9-animot-arrow-undraw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-draw-undraw.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9){stroke-dashoffset:var(--path-len, 1000);animation:svelte-16ocdv9-animot-arrow-draw-undraw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-head-styled-draw.svelte-16ocdv9{opacity:0;animation:svelte-16ocdv9-animot-arrow-head-appear var(--arrow-anim-duration, .5s) ease-out forwards;animation-delay:calc(var(--arrow-anim-duration, .5s) * .7)}.arrow-animate-draw.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9){opacity:0;animation:svelte-16ocdv9-animot-arrow-head-appear var(--arrow-anim-duration, .5s) ease-out forwards;animation-delay:calc(var(--arrow-anim-duration, .5s) * .7)}.arrow-animate-undraw.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9),.arrow-head-undraw.svelte-16ocdv9{opacity:1;animation:svelte-16ocdv9-animot-arrow-head-disappear var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-draw-undraw.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9),.arrow-head-draw-undraw.svelte-16ocdv9{opacity:0;animation:svelte-16ocdv9-animot-arrow-head-draw-undraw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-grow.svelte-16ocdv9{transform-origin:left center;animation:svelte-16ocdv9-animot-arrow-grow var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-anim-loop.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9),.arrow-anim-loop.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9){animation-iteration-count:infinite!important}.arrow-anim-reverse.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9),.arrow-anim-reverse.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9){animation-direction:reverse!important}@keyframes svelte-16ocdv9-animot-arrow-draw{to{stroke-dashoffset:0}}@keyframes svelte-16ocdv9-animot-arrow-undraw{0%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}@keyframes svelte-16ocdv9-animot-arrow-draw-undraw{0%{stroke-dashoffset:var(--path-len, 1000)}50%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}@keyframes svelte-16ocdv9-animot-arrow-head-appear{0%{opacity:0}to{opacity:1}}@keyframes svelte-16ocdv9-animot-arrow-head-disappear{0%{opacity:1}70%{opacity:1}to{opacity:0}}@keyframes svelte-16ocdv9-animot-arrow-head-draw-undraw{0%{opacity:0}35%{opacity:1}65%{opacity:1}to{opacity:0}}@keyframes svelte-16ocdv9-animot-arrow-grow{0%{transform:scaleX(0);opacity:0}to{transform:scaleX(1);opacity:1}}.animot-image-element.svelte-16ocdv9{width:100%;height:100%;display:block}.animot-video-element.svelte-16ocdv9{width:100%;height:100%;display:block;background:#000}.animot-video-element.animot-embed-frame.svelte-16ocdv9{border:0;background:transparent}.animot-video-element.animot-embed-wrap.svelte-16ocdv9{overflow:hidden;background:#000}.animot-cinema-camera.svelte-16ocdv9{position:absolute;top:0;right:0;bottom:0;left:0;transform-origin:0 0}.animot-cinema-camera.active.svelte-16ocdv9{transition:transform var(--cinema-transition-duration, .8s) cubic-bezier(.65,0,.35,1)}.animot-cinema-camera.active.svelte-16ocdv9 .animot-element:where(.svelte-16ocdv9){transition:translate var(--cinema-transition-duration, .8s) cubic-bezier(.65,0,.35,1)}.animot-shape-element.svelte-16ocdv9{width:100%;height:100%;display:block;overflow:visible}.animot-canvas.svelte-16ocdv9{--transition-duration: .5s;transition:transform calc(var(--transition-duration) * .4) ease,opacity calc(var(--transition-duration) * .4) ease}.animot-canvas.transition-fade-out.svelte-16ocdv9{opacity:0}.animot-canvas.transition-fade-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-fadeIn calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-left-out.forward.svelte-16ocdv9{transform:translate(-100%);opacity:0}.animot-canvas.transition-slide-left-in.forward.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromRight calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-left-out.backward.svelte-16ocdv9{transform:translate(100%);opacity:0}.animot-canvas.transition-slide-left-in.backward.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromLeft calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-right-out.forward.svelte-16ocdv9{transform:translate(100%);opacity:0}.animot-canvas.transition-slide-right-in.forward.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromLeft calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-up-out.svelte-16ocdv9{transform:translateY(-100%);opacity:0}.animot-canvas.transition-slide-up-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromBottom calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-down-out.svelte-16ocdv9{transform:translateY(100%);opacity:0}.animot-canvas.transition-slide-down-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromTop calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-zoom-in-out.svelte-16ocdv9{transform:scale(.5);opacity:0}.animot-canvas.transition-zoom-in-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-zoomIn calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-zoom-out-out.svelte-16ocdv9{transform:scale(1.5);opacity:0}.animot-canvas.transition-zoom-out-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-zoomOut calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-flip-out.svelte-16ocdv9{transform:perspective(1000px) rotateY(90deg);opacity:0}.animot-canvas.transition-flip-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-flipIn calc(var(--transition-duration) * .6) ease forwards}@keyframes svelte-16ocdv9-animot-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromRight{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromLeft{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromBottom{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromTop{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes svelte-16ocdv9-animot-zoomIn{0%{transform:scale(.5);opacity:0}to{transform:scale(1);opacity:1}}@keyframes svelte-16ocdv9-animot-zoomOut{0%{transform:scale(1.5);opacity:0}to{transform:scale(1);opacity:1}}@keyframes svelte-16ocdv9-animot-flipIn{0%{transform:perspective(1000px) rotateY(-90deg);opacity:0}to{transform:perspective(1000px) rotateY(0);opacity:1}}.animot-canvas.transition-flip-x-out.svelte-16ocdv9{transform:perspective(1000px) rotateX(90deg);opacity:0}.animot-canvas.transition-flip-x-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-flipXIn calc(var(--transition-duration) * .6) ease forwards}@keyframes svelte-16ocdv9-animot-flipXIn{0%{transform:perspective(1000px) rotateX(-90deg);opacity:0}to{transform:perspective(1000px) rotateX(0);opacity:1}}.animot-canvas.transition-flip-y-out.svelte-16ocdv9{transform:perspective(1000px) rotateY(90deg);opacity:0}.animot-canvas.transition-flip-y-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-flipYIn calc(var(--transition-duration) * .6) ease forwards}@keyframes svelte-16ocdv9-animot-flipYIn{0%{transform:perspective(1000px) rotateY(-90deg);opacity:0}to{transform:perspective(1000px) rotateY(0);opacity:1}}.animot-svg-element.svelte-16ocdv9{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.animot-svg-element.svelte-16ocdv9 svg{width:100%;height:100%}.animot-controls.svelte-16ocdv9{position:absolute;bottom:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:8px;padding:8px 16px;background:#000000b3;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:10px;opacity:0;transition:opacity .3s ease .15s;z-index:100}.animot-presenter.svelte-16ocdv9:hover .animot-controls:where(.svelte-16ocdv9),.animot-menu-visible.svelte-16ocdv9 .animot-controls:where(.svelte-16ocdv9){opacity:1;transition-delay:0s}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9){display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;border:none;cursor:pointer;background:#ffffff1a;color:#fff;transition:background .2s}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9):hover:not(:disabled){background:#fff3}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9):disabled{opacity:.3;cursor:not-allowed}.animot-controls.svelte-16ocdv9 button.active:where(.svelte-16ocdv9){background:#6366f199}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9) svg:where(.svelte-16ocdv9){width:16px;height:16px}.animot-slide-indicator.svelte-16ocdv9{font-size:12px;color:#fff;min-width:50px;text-align:center;font-family:system-ui,sans-serif}.animot-arrow.svelte-16ocdv9{position:absolute;top:50%;transform:translateY(-50%);width:40px;height:40px;border-radius:50%;border:none;cursor:pointer;background:#00000080;color:#fff;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .3s .15s;z-index:100;padding:0;margin:0}.animot-presenter.svelte-16ocdv9:hover .animot-arrow:where(.svelte-16ocdv9){opacity:1;transition-delay:0s}.animot-presenter.svelte-16ocdv9:hover .animot-arrow:where(.svelte-16ocdv9):disabled{opacity:.3;cursor:not-allowed}.animot-arrow.svelte-16ocdv9:hover:not(:disabled){background:#000000b3}.animot-arrow.svelte-16ocdv9 svg:where(.svelte-16ocdv9){width:20px;height:20px}.animot-arrow-left.svelte-16ocdv9{left:8px}.animot-arrow-right.svelte-16ocdv9{right:8px}.animot-progress-bar.svelte-16ocdv9{position:absolute;bottom:0;left:0;right:0;height:3px;background:#ffffff1a;z-index:100;opacity:0;transition:opacity .3s .15s}.animot-presenter.svelte-16ocdv9:hover .animot-progress-bar:where(.svelte-16ocdv9){opacity:1;transition-delay:0s}.animot-progress-fill.svelte-16ocdv9{height:100%;background:linear-gradient(135deg,#7c3aed,#ec4899);transition:width .6s ease}.animot-loading.svelte-16ocdv9{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.animot-spinner.svelte-16ocdv9{width:32px;height:32px;border:3px solid rgba(255,255,255,.2);border-top-color:#7c3aed;border-radius:50%;animation:svelte-16ocdv9-animot-spin .8s linear infinite}@keyframes svelte-16ocdv9-animot-spin{to{transform:rotate(360deg)}}.animot-error.svelte-16ocdv9{color:#ef4444;padding:20px;text-align:center;font-family:system-ui,sans-serif}
1
+ .code-morph.svelte-1hmk0l{width:100%;height:100%;margin:0;padding:0;background:transparent;font-family:var(--font-mono, "JetBrains Mono", monospace);font-size:inherit;line-height:1.6;white-space:pre-wrap;word-wrap:break-word;color:#e6edf3;box-sizing:border-box;overflow:visible}.code-morph.svelte-1hmk0l pre{margin:0;padding:16px;background:transparent!important;font-family:var(--font-mono);font-size:inherit;line-height:1.6;overflow:visible}.code-morph.svelte-1hmk0l code{font-family:inherit;font-size:inherit;font-weight:inherit}.code-morph.svelte-1hmk0l .line-number{display:inline-block;width:2.5em;margin-right:1em;text-align:right;color:#6e7681;-webkit-user-select:none;user-select:none;opacity:.6}.code-morph.svelte-1hmk0l .word-highlight{background:var(--highlight-color, #facc15);color:#000;border-radius:3px;padding:1px 3px;margin:0 -3px;-webkit-box-decoration-break:clone;box-decoration-break:clone;animation:svelte-1hmk0l-fadeHighlight var(--duration, 1s) ease-out forwards}@keyframes svelte-1hmk0l-fadeHighlight{0%{background:var(--highlight-color, #facc15);color:#000}70%{background:var(--highlight-color, #facc15);color:#000}to{background:transparent;color:inherit}}.counter.svelte-1er5jjj{width:100%;height:100%;display:flex;align-items:center;justify-content:center;box-sizing:border-box;overflow:hidden;white-space:nowrap}.animot-chart.svelte-1mq2d7j{width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;overflow:hidden}.animot-chart-title.svelte-1mq2d7j{font-weight:600;text-align:center;margin-bottom:8px}.animot-chart-content.svelte-1mq2d7j{flex:1;min-height:0;display:flex;flex-direction:column}.animot-chart-content.svelte-1mq2d7j svg:where(.svelte-1mq2d7j){width:100%;flex:1;min-height:0}.animot-bar-chart.svelte-1mq2d7j,.animot-line-chart.svelte-1mq2d7j{overflow:visible}.animot-series-legend.svelte-1mq2d7j{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;padding:6px 0 0;font-size:.85em}.animot-legend-item.svelte-1mq2d7j{display:inline-flex;align-items:center;gap:5px}.animot-swatch.svelte-1mq2d7j{width:10px;height:10px;border-radius:2px;display:inline-block}.progress-element.svelte-10tny4e{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;position:relative;box-sizing:border-box}.bar-track.svelte-10tny4e,.ring-svg.svelte-10tny4e{flex-shrink:0}.progress-element.ring.svelte-10tny4e .ring-svg:where(.svelte-10tny4e){width:100%;height:100%;min-height:0;min-width:0}.bar-track.svelte-10tny4e{position:relative;overflow:hidden}.bar-fill.svelte-10tny4e{position:absolute;display:flex;align-items:center;justify-content:center;transition:width 0s,height 0s}.bar-stripe-clip.svelte-10tny4e{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden}.bar-stripe-tape.svelte-10tny4e{position:absolute;top:0;left:0;width:calc(100% + var(--stripe-cycle));height:100%;mask-image:var(--stripe-mask);-webkit-mask-image:var(--stripe-mask);mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;animation:svelte-10tny4e-progress-stripe-x var(--stripe-speed) linear infinite;animation-direction:var(--stripe-direction);will-change:transform}.bar-stripe-tape.vertical.svelte-10tny4e{width:100%;height:calc(100% + var(--stripe-cycle));animation-name:svelte-10tny4e-progress-stripe-y}@keyframes svelte-10tny4e-progress-stripe-x{0%{transform:translate(0)}to{transform:translate(calc(-1 * var(--stripe-cycle)))}}@keyframes svelte-10tny4e-progress-stripe-y{0%{transform:translateY(0)}to{transform:translateY(calc(-1 * var(--stripe-cycle)))}}.ring-svg.svelte-10tny4e{width:100%;height:100%}.ring-spin.svelte-10tny4e{animation:svelte-10tny4e-progress-ring-spin 1.4s linear infinite;transform-origin:50% 50%}@keyframes svelte-10tny4e-progress-ring-spin{to{transform:rotate(360deg)}}.label.svelte-10tny4e{text-align:center;white-space:nowrap;pointer-events:none}.label.center.svelte-10tny4e{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.label.inside.svelte-10tny4e{padding:0 8px;flex-shrink:0}.label.inside-vertical.svelte-10tny4e{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);text-orientation:mixed;writing-mode:horizontal-tb}.animot-container-element.svelte-e5oeuv{box-sizing:border-box;pointer-events:none}.icon-element.svelte-2ld65o{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.icon-element.svelte-2ld65o svg{width:100%;height:100%}.flow-markers.svelte-15cxp1m{pointer-events:none}.embed-player.svelte-1u59mvz{position:relative;width:100%;height:100%;background:#000;overflow:hidden}.embed-frame.svelte-1u59mvz{width:100%;height:100%;display:block;border:0}.embed-frame.passthrough.svelte-1u59mvz{pointer-events:none}.custom-controls.svelte-1u59mvz{position:absolute;left:8px;right:8px;bottom:8px;display:flex;align-items:center;gap:10px;padding:6px 10px;background:#0009;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-radius:8px;opacity:0;transition:opacity .2s}.embed-player.svelte-1u59mvz:hover .custom-controls:where(.svelte-1u59mvz),.custom-controls.svelte-1u59mvz:focus-within{opacity:1}.ctrl-btn.svelte-1u59mvz{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:0;border-radius:4px;color:#fff;cursor:pointer}.ctrl-btn.svelte-1u59mvz:hover{background:#ffffff26}.ctrl-btn.svelte-1u59mvz svg:where(.svelte-1u59mvz){width:16px;height:16px}.scrub.svelte-1u59mvz{flex:1;accent-color:#6366f1}.time.svelte-1u59mvz{font-size:11px;color:#ffffffd9;font-variant-numeric:tabular-nums;min-width:80px;text-align:right}@keyframes float-vertical{0%,to{translate:0 0}50%{translate:0 calc(-1 * var(--float-amp, 10px))}}@keyframes float-horizontal{0%,to{translate:0 0}50%{translate:var(--float-amp, 10px) 0}}@keyframes float-both-0{0%{translate:0 0}15%{translate:calc(.8 * var(--float-amp, 10px)) calc(-.6 * var(--float-amp, 10px))}35%{translate:calc(-.4 * var(--float-amp, 10px)) calc(-1 * var(--float-amp, 10px))}55%{translate:calc(-.9 * var(--float-amp, 10px)) calc(.3 * var(--float-amp, 10px))}75%{translate:calc(.3 * var(--float-amp, 10px)) calc(.7 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes float-both-1{0%{translate:0 0}20%{translate:calc(-.7 * var(--float-amp, 10px)) calc(-.8 * var(--float-amp, 10px))}40%{translate:calc(.5 * var(--float-amp, 10px)) calc(-.3 * var(--float-amp, 10px))}60%{translate:calc(.9 * var(--float-amp, 10px)) calc(.6 * var(--float-amp, 10px))}80%{translate:calc(-.4 * var(--float-amp, 10px)) calc(.9 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes float-both-2{0%{translate:0 0}12%{translate:calc(.6 * var(--float-amp, 10px)) calc(.5 * var(--float-amp, 10px))}30%{translate:calc(1 * var(--float-amp, 10px)) calc(-.4 * var(--float-amp, 10px))}50%{translate:calc(-.3 * var(--float-amp, 10px)) calc(-.9 * var(--float-amp, 10px))}70%{translate:calc(-.8 * var(--float-amp, 10px)) calc(.2 * var(--float-amp, 10px))}88%{translate:calc(.2 * var(--float-amp, 10px)) calc(.8 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes float-both-3{0%{translate:0 0}17%{translate:calc(-.9 * var(--float-amp, 10px)) calc(.4 * var(--float-amp, 10px))}33%{translate:calc(-.5 * var(--float-amp, 10px)) calc(-.7 * var(--float-amp, 10px))}50%{translate:calc(.7 * var(--float-amp, 10px)) calc(-.9 * var(--float-amp, 10px))}67%{translate:calc(.9 * var(--float-amp, 10px)) calc(.5 * var(--float-amp, 10px))}83%{translate:calc(-.2 * var(--float-amp, 10px)) calc(.8 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes idle-breathe{0%,to{scale:1}50%{scale:var(--float-amp-scale, 1.05)}}@keyframes idle-pulse{0%,to{scale:1}45%{scale:var(--float-amp-scale, 1.05)}55%{scale:var(--float-amp-scale, 1.05)}}@keyframes idle-wiggle{0%,to{translate:0 0;rotate:0deg}25%{translate:calc(-.4 * var(--float-amp, 10px)) 0;rotate:calc(-.5 * var(--float-amp-rot, 5deg))}50%{translate:0 0;rotate:0deg}75%{translate:calc(.4 * var(--float-amp, 10px)) 0;rotate:calc(.5 * var(--float-amp-rot, 5deg))}}@keyframes idle-sway{0%,to{rotate:calc(-1 * var(--float-amp-rot, 5deg))}50%{rotate:var(--float-amp-rot, 5deg)}}@keyframes idle-tilt{0%,to{transform:skew(0)}50%{transform:skew(var(--float-amp-rot, 5deg))}}@keyframes idle-bob{0%,to{translate:0 0}50%{translate:0 calc(-1 * var(--float-amp, 10px))}}@keyframes idle-drift{0%{translate:0 0}25%{translate:calc(.5 * var(--float-amp, 10px)) calc(-.3 * var(--float-amp, 10px))}50%{translate:calc(.1 * var(--float-amp, 10px)) calc(.5 * var(--float-amp, 10px))}75%{translate:calc(-.4 * var(--float-amp, 10px)) calc(-.2 * var(--float-amp, 10px))}to{translate:0 0}}@keyframes emphasis-pulse{0%,to{transform:scale(1)}50%{transform:scale(1.06)}}@keyframes emphasis-shake{0%,to{transform:translate(0)}20%{transform:translate(-4px)}40%{transform:translate(4px)}60%{transform:translate(-3px)}80%{transform:translate(3px)}}@keyframes emphasis-flash{0%,to{opacity:1}50%{opacity:.55}}@keyframes emphasis-wobble{0%,to{transform:rotate(0)}25%{transform:rotate(-4deg)}75%{transform:rotate(4deg)}}@keyframes emphasis-glow-flash{0%,to{filter:drop-shadow(0 0 0 rgba(124,58,237,0))}50%{filter:drop-shadow(0 0 16px rgba(124,58,237,.85))}}@keyframes emphasis-bob-once{0%{transform:translateY(0)}30%{transform:translateY(-12px)}60%{transform:translateY(0)}to{transform:translateY(0)}}@keyframes emphasis-tada{0%{transform:scale(1) rotate(0)}10%,20%{transform:scale(.95) rotate(-3deg)}30%,50%,70%,90%{transform:scale(1.08) rotate(3deg)}40%,60%,80%{transform:scale(1.08) rotate(-3deg)}to{transform:scale(1) rotate(0)}}@keyframes runtime-entrance-fade{0%{opacity:0}to{opacity:1}}@keyframes runtime-entrance-slide-up{0%{translate:0 60px;opacity:0}to{translate:0 0;opacity:1}}@keyframes runtime-entrance-slide-down{0%{translate:0 -60px;opacity:0}to{translate:0 0;opacity:1}}@keyframes runtime-entrance-slide-left{0%{translate:60px 0;opacity:0}to{translate:0 0;opacity:1}}@keyframes runtime-entrance-slide-right{0%{translate:-60px 0;opacity:0}to{translate:0 0;opacity:1}}@keyframes runtime-entrance-pop{0%{scale:.4;opacity:0}60%{scale:1.08;opacity:1}to{scale:1;opacity:1}}@keyframes runtime-entrance-scale-in{0%{scale:.7;opacity:0}to{scale:1;opacity:1}}@keyframes runtime-entrance-rotate-in{0%{rotate:-15deg;scale:.8;opacity:0}to{rotate:0deg;scale:1;opacity:1}}@keyframes runtime-entrance-blur-in{0%{filter:blur(20px);opacity:0}to{filter:blur(0);opacity:1}}@keyframes runtime-entrance-rise{0%{translate:0 30px;opacity:0}to{translate:0 0;opacity:1}}@keyframes runtime-entrance-flip-x{0%{opacity:0}to{opacity:1}}@keyframes runtime-entrance-flip-y{0%{opacity:0}to{opacity:1}}@keyframes runtime-entrance-bounce-in{0%{scale:.3;opacity:0}50%{scale:1.15;opacity:1}75%{scale:.92}90%{scale:1.04}to{scale:1;opacity:1}}@keyframes runtime-exit-fade{0%{opacity:1}to{opacity:0}}@keyframes runtime-exit-slide-up{0%{translate:0 0;opacity:1}to{translate:0 -60px;opacity:0}}@keyframes runtime-exit-slide-down{0%{translate:0 0;opacity:1}to{translate:0 60px;opacity:0}}@keyframes runtime-exit-slide-left{0%{translate:0 0;opacity:1}to{translate:-60px 0;opacity:0}}@keyframes runtime-exit-slide-right{0%{translate:0 0;opacity:1}to{translate:60px 0;opacity:0}}@keyframes runtime-exit-pop{0%{scale:1;opacity:1}50%{scale:1.25;opacity:1}to{scale:1.6;opacity:0}}@keyframes runtime-exit-scale-out{0%{scale:1;opacity:1}to{scale:.5;opacity:0}}@keyframes runtime-exit-rotate-out{0%{rotate:0deg;scale:1;opacity:1}to{rotate:15deg;scale:.8;opacity:0}}@keyframes runtime-exit-blur-out{0%{filter:blur(0);opacity:1}to{filter:blur(20px);opacity:0}}@keyframes runtime-exit-sink{0%{translate:0 0;opacity:1}to{translate:0 30px;opacity:0}}@keyframes runtime-exit-flip-x{0%{opacity:1}to{opacity:0}}@keyframes runtime-exit-flip-y{0%{opacity:1}to{opacity:0}}.animot-svg-element.icon-anim-draw path,.animot-svg-element.icon-anim-draw circle,.animot-svg-element.icon-anim-draw rect,.animot-svg-element.icon-anim-draw line,.animot-svg-element.icon-anim-draw polyline,.animot-svg-element.icon-anim-draw polygon,.animot-svg-element.icon-anim-draw ellipse{stroke-dashoffset:var(--path-len, 1000);animation:animot-svg-draw var(--icon-anim-duration, .8s) ease-out forwards}.animot-svg-element.icon-anim-undraw path,.animot-svg-element.icon-anim-undraw circle,.animot-svg-element.icon-anim-undraw rect,.animot-svg-element.icon-anim-undraw line,.animot-svg-element.icon-anim-undraw polyline,.animot-svg-element.icon-anim-undraw polygon,.animot-svg-element.icon-anim-undraw ellipse{stroke-dashoffset:0;animation:animot-svg-undraw var(--icon-anim-duration, .8s) ease-out forwards}.animot-svg-element.icon-anim-draw-undraw path,.animot-svg-element.icon-anim-draw-undraw circle,.animot-svg-element.icon-anim-draw-undraw rect,.animot-svg-element.icon-anim-draw-undraw line,.animot-svg-element.icon-anim-draw-undraw polyline,.animot-svg-element.icon-anim-draw-undraw polygon,.animot-svg-element.icon-anim-draw-undraw ellipse{stroke-dashoffset:var(--path-len, 1000);animation:animot-svg-draw-undraw var(--icon-anim-duration, .8s) ease-out forwards}.animot-svg-element.icon-anim-loop path,.animot-svg-element.icon-anim-loop circle,.animot-svg-element.icon-anim-loop rect,.animot-svg-element.icon-anim-loop line,.animot-svg-element.icon-anim-loop polyline,.animot-svg-element.icon-anim-loop polygon,.animot-svg-element.icon-anim-loop ellipse{animation-iteration-count:infinite!important}.animot-svg-element.icon-anim-reverse path,.animot-svg-element.icon-anim-reverse circle,.animot-svg-element.icon-anim-reverse rect,.animot-svg-element.icon-anim-reverse line,.animot-svg-element.icon-anim-reverse polyline,.animot-svg-element.icon-anim-reverse polygon,.animot-svg-element.icon-anim-reverse ellipse{animation-direction:reverse!important}@keyframes animot-svg-draw{to{stroke-dashoffset:0}}@keyframes animot-svg-undraw{0%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}@keyframes animot-svg-draw-undraw{0%{stroke-dashoffset:var(--path-len, 1000)}50%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}.animot-presenter.svelte-16ocdv9 *{margin:0;padding:0;box-sizing:border-box}.animot-presenter.svelte-16ocdv9{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;background:transparent;line-height:normal;font-size:16px;font-weight:400;font-style:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;text-indent:0;text-align:left;color:inherit}.animot-canvas-wrapper.svelte-16ocdv9{display:flex;align-items:center;justify-content:center}.animot-canvas.svelte-16ocdv9{position:relative;overflow:hidden}.animot-element.svelte-16ocdv9{position:absolute;box-sizing:border-box;will-change:transform,opacity,left,top,width,height;isolation:isolate}.animot-element.floating.svelte-16ocdv9{animation-duration:var(--float-speed, 3s);animation-timing-function:ease-in-out;animation-iteration-count:infinite;animation-delay:var(--float-delay, 0s)}.animot-code-block.svelte-16ocdv9{width:100%;height:100%;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 8px 32px #0006;margin:0;box-sizing:border-box}.animot-code-block.transparent-bg.svelte-16ocdv9{background:transparent!important;box-shadow:none}.animot-code-block.transparent-bg.svelte-16ocdv9 .animot-code-header:where(.svelte-16ocdv9){background:transparent;border-bottom-color:#ffffff0f}.animot-code-header.svelte-16ocdv9{display:flex;align-items:center;gap:8px;padding:8px 12px;background:#0003;border-bottom:1px solid rgba(255,255,255,.06);flex-shrink:0;min-height:40px}.animot-window-controls.svelte-16ocdv9{display:flex;gap:8px;align-items:center;flex-shrink:0}.macos.svelte-16ocdv9 .animot-control:where(.svelte-16ocdv9){width:12px;height:12px;border-radius:50%;display:block}.macos.svelte-16ocdv9 .animot-control.close:where(.svelte-16ocdv9){background:#ff5f57}.macos.svelte-16ocdv9 .animot-control.minimize:where(.svelte-16ocdv9){background:#febc2e}.macos.svelte-16ocdv9 .animot-control.maximize:where(.svelte-16ocdv9){background:#28c840}.windows.svelte-16ocdv9 .animot-window-controls:where(.svelte-16ocdv9){order:99;margin-left:auto;gap:0}.windows.svelte-16ocdv9 .animot-control:where(.svelte-16ocdv9){display:flex;align-items:center;justify-content:center;width:28px;height:24px;border-radius:4px;color:#ffffff73}.animot-filename-tab.svelte-16ocdv9{display:flex;align-items:center;gap:6px;background:#ffffff0f;border:1px solid rgba(255,255,255,.08);border-radius:6px;padding:4px 10px;max-width:220px;color:#fff6}.animot-file-icon.svelte-16ocdv9{flex-shrink:0}.animot-filename.svelte-16ocdv9{color:#ffffff8c;font-size:12px;line-height:18px}.animot-copy-code-btn.svelte-16ocdv9{display:flex;align-items:center;gap:5px;height:28px;padding:0 8px;margin-left:auto;background:#ffffff0f;border:1px solid rgba(255,255,255,.1);border-radius:6px;color:#fff6;cursor:pointer;opacity:0;transition:opacity .2s,background .15s,color .15s;flex-shrink:0;font-size:12px;font-family:inherit;white-space:nowrap}.animot-copy-code-btn.svelte-16ocdv9:hover{background:#ffffff1f;color:#fffc}.animot-copy-code-btn.svelte-16ocdv9 svg:where(.svelte-16ocdv9){width:14px;height:14px;flex-shrink:0}.animot-copy-code-btn.svelte-16ocdv9 .animot-check-icon:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.svelte-16ocdv9 .animot-copied-label:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-copy-icon:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-copy-label:where(.svelte-16ocdv9){display:none}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-check-icon:where(.svelte-16ocdv9){display:block;color:#4ade80}.animot-copy-code-btn.copied.svelte-16ocdv9 .animot-copied-label:where(.svelte-16ocdv9){display:inline;color:#4ade80}.animot-copy-code-btn.animot-floating.svelte-16ocdv9{position:absolute;top:8px;right:8px;z-index:2}.animot-code-block.svelte-16ocdv9:hover .animot-copy-code-btn:where(.svelte-16ocdv9){opacity:1}.animot-code-content.svelte-16ocdv9{flex:1;overflow:hidden;position:relative}.animot-highlighted-code.svelte-16ocdv9{width:100%;height:100%}.animot-code-content.svelte-16ocdv9 pre,.animot-highlighted-code.svelte-16ocdv9 pre{margin:0;padding:16px;background:transparent!important;line-height:1.6;font-size:inherit;overflow:visible}.animot-highlighted-code.svelte-16ocdv9 code{font-family:inherit;font-size:inherit;font-weight:inherit}.animot-highlighted-code.svelte-16ocdv9 .line-number{display:inline-block;width:2.5em;margin-right:1em;text-align:right;color:#6e7681;-webkit-user-select:none;user-select:none;opacity:.6}.animot-text-element.svelte-16ocdv9{width:100%;height:100%;display:flex;align-items:center;white-space:pre-wrap;word-wrap:break-word}.animot-typewriter-cursor.svelte-16ocdv9{animation:svelte-16ocdv9-animot-blink .7s infinite;font-weight:100}@keyframes svelte-16ocdv9-animot-blink{0%,50%{opacity:1}51%,to{opacity:0}}.animot-arrow-element.svelte-16ocdv9{width:100%;height:100%}.arrow-animate-draw.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9){stroke-dashoffset:var(--path-len, 1000);animation:svelte-16ocdv9-animot-arrow-draw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-undraw.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9){stroke-dashoffset:0;animation:svelte-16ocdv9-animot-arrow-undraw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-draw-undraw.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9){stroke-dashoffset:var(--path-len, 1000);animation:svelte-16ocdv9-animot-arrow-draw-undraw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-head-styled-draw.svelte-16ocdv9{opacity:0;animation:svelte-16ocdv9-animot-arrow-head-appear var(--arrow-anim-duration, .5s) ease-out forwards;animation-delay:calc(var(--arrow-anim-duration, .5s) * .7)}.arrow-animate-draw.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9){opacity:0;animation:svelte-16ocdv9-animot-arrow-head-appear var(--arrow-anim-duration, .5s) ease-out forwards;animation-delay:calc(var(--arrow-anim-duration, .5s) * .7)}.arrow-animate-undraw.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9),.arrow-head-undraw.svelte-16ocdv9{opacity:1;animation:svelte-16ocdv9-animot-arrow-head-disappear var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-draw-undraw.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9),.arrow-head-draw-undraw.svelte-16ocdv9{opacity:0;animation:svelte-16ocdv9-animot-arrow-head-draw-undraw var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-animate-grow.svelte-16ocdv9{transform-origin:left center;animation:svelte-16ocdv9-animot-arrow-grow var(--arrow-anim-duration, .5s) ease-out forwards}.arrow-anim-loop.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9),.arrow-anim-loop.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9){animation-iteration-count:infinite!important}.arrow-anim-reverse.svelte-16ocdv9 .arrow-path:where(.svelte-16ocdv9),.arrow-anim-reverse.svelte-16ocdv9 .arrow-head:where(.svelte-16ocdv9){animation-direction:reverse!important}@keyframes svelte-16ocdv9-animot-arrow-draw{to{stroke-dashoffset:0}}@keyframes svelte-16ocdv9-animot-arrow-undraw{0%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}@keyframes svelte-16ocdv9-animot-arrow-draw-undraw{0%{stroke-dashoffset:var(--path-len, 1000)}50%{stroke-dashoffset:0}to{stroke-dashoffset:var(--path-len, 1000)}}@keyframes svelte-16ocdv9-animot-arrow-head-appear{0%{opacity:0}to{opacity:1}}@keyframes svelte-16ocdv9-animot-arrow-head-disappear{0%{opacity:1}70%{opacity:1}to{opacity:0}}@keyframes svelte-16ocdv9-animot-arrow-head-draw-undraw{0%{opacity:0}35%{opacity:1}65%{opacity:1}to{opacity:0}}@keyframes svelte-16ocdv9-animot-arrow-grow{0%{transform:scaleX(0);opacity:0}to{transform:scaleX(1);opacity:1}}.animot-image-element.svelte-16ocdv9{width:100%;height:100%;display:block}.animot-video-element.svelte-16ocdv9{width:100%;height:100%;display:block;background:#000}.animot-video-element.animot-embed-frame.svelte-16ocdv9{border:0;background:transparent}.animot-video-element.animot-embed-wrap.svelte-16ocdv9{overflow:hidden;background:#000}.animot-cinema-camera.svelte-16ocdv9{position:absolute;top:0;right:0;bottom:0;left:0;transform-origin:0 0}.animot-cinema-camera.active.svelte-16ocdv9{transition:transform var(--cinema-transition-duration, .8s) cubic-bezier(.65,0,.35,1)}.animot-cinema-camera.active.svelte-16ocdv9 .animot-element:where(.svelte-16ocdv9){transition:translate var(--cinema-transition-duration, .8s) cubic-bezier(.65,0,.35,1)}.animot-shape-element.svelte-16ocdv9{width:100%;height:100%;display:block;overflow:visible}.animot-canvas.svelte-16ocdv9{--transition-duration: .5s;transition:transform calc(var(--transition-duration) * .4) ease,opacity calc(var(--transition-duration) * .4) ease}.animot-canvas.transition-fade-out.svelte-16ocdv9{opacity:0}.animot-canvas.transition-fade-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-fadeIn calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-left-out.forward.svelte-16ocdv9{transform:translate(-100%);opacity:0}.animot-canvas.transition-slide-left-in.forward.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromRight calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-left-out.backward.svelte-16ocdv9{transform:translate(100%);opacity:0}.animot-canvas.transition-slide-left-in.backward.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromLeft calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-right-out.forward.svelte-16ocdv9{transform:translate(100%);opacity:0}.animot-canvas.transition-slide-right-in.forward.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromLeft calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-up-out.svelte-16ocdv9{transform:translateY(-100%);opacity:0}.animot-canvas.transition-slide-up-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromBottom calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-slide-down-out.svelte-16ocdv9{transform:translateY(100%);opacity:0}.animot-canvas.transition-slide-down-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-slideInFromTop calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-zoom-in-out.svelte-16ocdv9{transform:scale(.5);opacity:0}.animot-canvas.transition-zoom-in-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-zoomIn calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-zoom-out-out.svelte-16ocdv9{transform:scale(1.5);opacity:0}.animot-canvas.transition-zoom-out-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-zoomOut calc(var(--transition-duration) * .6) ease forwards}.animot-canvas.transition-flip-out.svelte-16ocdv9{transform:perspective(1000px) rotateY(90deg);opacity:0}.animot-canvas.transition-flip-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-flipIn calc(var(--transition-duration) * .6) ease forwards}@keyframes svelte-16ocdv9-animot-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromRight{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromLeft{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromBottom{0%{transform:translateY(100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes svelte-16ocdv9-animot-slideInFromTop{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes svelte-16ocdv9-animot-zoomIn{0%{transform:scale(.5);opacity:0}to{transform:scale(1);opacity:1}}@keyframes svelte-16ocdv9-animot-zoomOut{0%{transform:scale(1.5);opacity:0}to{transform:scale(1);opacity:1}}@keyframes svelte-16ocdv9-animot-flipIn{0%{transform:perspective(1000px) rotateY(-90deg);opacity:0}to{transform:perspective(1000px) rotateY(0);opacity:1}}.animot-canvas.transition-flip-x-out.svelte-16ocdv9{transform:perspective(1000px) rotateX(90deg);opacity:0}.animot-canvas.transition-flip-x-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-flipXIn calc(var(--transition-duration) * .6) ease forwards}@keyframes svelte-16ocdv9-animot-flipXIn{0%{transform:perspective(1000px) rotateX(-90deg);opacity:0}to{transform:perspective(1000px) rotateX(0);opacity:1}}.animot-canvas.transition-flip-y-out.svelte-16ocdv9{transform:perspective(1000px) rotateY(90deg);opacity:0}.animot-canvas.transition-flip-y-in.svelte-16ocdv9{animation:svelte-16ocdv9-animot-flipYIn calc(var(--transition-duration) * .6) ease forwards}@keyframes svelte-16ocdv9-animot-flipYIn{0%{transform:perspective(1000px) rotateY(-90deg);opacity:0}to{transform:perspective(1000px) rotateY(0);opacity:1}}.animot-svg-element.svelte-16ocdv9{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.animot-svg-element.svelte-16ocdv9 svg{width:100%;height:100%}.animot-controls.svelte-16ocdv9{position:absolute;bottom:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:8px;padding:8px 16px;background:#000000b3;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:10px;opacity:0;transition:opacity .3s ease .15s;z-index:100}.animot-presenter.svelte-16ocdv9:hover .animot-controls:where(.svelte-16ocdv9),.animot-menu-visible.svelte-16ocdv9 .animot-controls:where(.svelte-16ocdv9){opacity:1;transition-delay:0s}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9){display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;border:none;cursor:pointer;background:#ffffff1a;color:#fff;transition:background .2s}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9):hover:not(:disabled){background:#fff3}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9):disabled{opacity:.3;cursor:not-allowed}.animot-controls.svelte-16ocdv9 button.active:where(.svelte-16ocdv9){background:#6366f199}.animot-controls.svelte-16ocdv9 button:where(.svelte-16ocdv9) svg:where(.svelte-16ocdv9){width:16px;height:16px}.animot-slide-indicator.svelte-16ocdv9{font-size:12px;color:#fff;min-width:50px;text-align:center;font-family:system-ui,sans-serif}.animot-arrow.svelte-16ocdv9{position:absolute;top:50%;transform:translateY(-50%);width:40px;height:40px;border-radius:50%;border:none;cursor:pointer;background:#00000080;color:#fff;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .3s .15s;z-index:100;padding:0;margin:0}.animot-presenter.svelte-16ocdv9:hover .animot-arrow:where(.svelte-16ocdv9){opacity:1;transition-delay:0s}.animot-presenter.svelte-16ocdv9:hover .animot-arrow:where(.svelte-16ocdv9):disabled{opacity:.3;cursor:not-allowed}.animot-arrow.svelte-16ocdv9:hover:not(:disabled){background:#000000b3}.animot-arrow.svelte-16ocdv9 svg:where(.svelte-16ocdv9){width:20px;height:20px}.animot-arrow-left.svelte-16ocdv9{left:8px}.animot-arrow-right.svelte-16ocdv9{right:8px}.animot-progress-bar.svelte-16ocdv9{position:absolute;bottom:0;left:0;right:0;height:3px;background:#ffffff1a;z-index:100;opacity:0;transition:opacity .3s .15s}.animot-presenter.svelte-16ocdv9:hover .animot-progress-bar:where(.svelte-16ocdv9){opacity:1;transition-delay:0s}.animot-progress-fill.svelte-16ocdv9{height:100%;background:linear-gradient(135deg,#7c3aed,#ec4899);transition:width .6s ease}.animot-loading.svelte-16ocdv9{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.animot-spinner.svelte-16ocdv9{width:32px;height:32px;border:3px solid rgba(255,255,255,.2);border-top-color:#7c3aed;border-radius:50%;animation:svelte-16ocdv9-animot-spin .8s linear infinite}@keyframes svelte-16ocdv9-animot-spin{to{transform:rotate(360deg)}}.animot-error.svelte-16ocdv9{color:#ef4444;padding:20px;text-align:center;font-family:system-ui,sans-serif}