/* Smith & Victory — Küchenstudio-VSL 16:9 · Kurzfassung, getaktet auf Tonspur (93.75s).
   7 Beats · aufwendige, eng getaktete Animationen · Ton folgt der Stage-Uhr. */
const O = "#FF6C4B", OD = "#E04E2C", INK = "#141210", GRAY = "#8a8378", PAPER = "#FBF2EA", CREAM = "#FFF3EC", GRUEN = "#3A7D5C";
const B = [0, 13.0, 34.0, 52.0, 62.0, 70.0, 79.0, 93.75];
const AUDIO_DUR = 93.75;
const VSL_RATE = 1.0;
const VSL_DUR = AUDIO_DUR;
function aTRaw() { return window.useTime() * VSL_RATE; }
const LAG = 0.4; /* Visuals kommen leicht NACH dem gesprochenen Wort */
function aT() { return aTRaw() - LAG; }
const E = Easing;
function osc(spd, amp, ph = 0) { return Math.sin(aTRaw() * spd + ph) * amp; }
function Float({ amp = 8, spd = 1.6, ph = 0, children, style }) { return <div style={{ transform: `translateY(${osc(spd, amp, ph)}px)`, ...style }}>{children}</div>; }
function PulseRing({ color = O, thick = 3, max = 0.35, spd = 0.85 }) { const p = (aTRaw() * spd) % 1; return <div style={{ position: "absolute", inset: -6, borderRadius: "inherit", border: `${thick}px solid ${color}`, opacity: (1 - p) * 0.55, transform: `scale(${1 + p * max})`, pointerEvents: "none" }}></div>; }
function Ambient() { const t = aTRaw(); const blobs = [[12, 22, 260, O, 0.07, 8, 0], [84, 24, 320, OD, 0.06, 10, 1.5], [72, 74, 280, O, 0.055, 12, 3], [20, 72, 220, GRUEN, 0.05, 9, 2]]; return (<div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 0 }}>{blobs.map((b, i) => <div key={i} style={{ position: "absolute", left: `calc(${b[0]}% + ${Math.sin(t / b[5] + b[6]) * 26}px)`, top: `calc(${b[1]}% + ${Math.cos(t / b[5] * 0.8 + b[6]) * 22}px)`, width: b[2], height: b[2], borderRadius: "50%", background: b[3], opacity: b[4], filter: "blur(70px)", transform: "translate(-50%,-50%)" }}></div>)}</div>); }

function VAudio({ src }) {
  const t = aTRaw();
  const ref = React.useRef(null);
  if (!ref.current) ref.current = document.getElementById('vslAudio');
  if (!window.__vslAudioIsMaster && ref.current && isFinite(t)) {
    const a = ref.current, st = (ref.current.__st = ref.current.__st || { lastT: -1, stag: 0 });
    const diff = a.currentTime - t;
    a.playbackRate = VSL_RATE * (window.__stageRate || 1) * (1 - Math.max(-0.05, Math.min(0.05, diff * 0.6)));
    const adv = t > st.lastT + 0.0001, rew = t < st.lastT - 0.2;
    if (window.__vslVoiceOn === false) { if (!a.paused) a.pause(); }
    else if (adv || rew) {
      st.stag = 0;
      if (Math.abs(a.currentTime - t) > 0.25) { try { a.currentTime = Math.max(0, Math.min(t, a.duration || t)); } catch (e) {} }
      if (a.paused && t < AUDIO_DUR - 1.4) a.play().catch(() => {});
      if (t >= AUDIO_DUR - 1.4 && !a.paused) a.pause();
    } else { st.stag++; if (st.stag > 8 && !a.paused) a.pause(); }
    st.lastT = t;
  }
  React.useEffect(() => {
    const onP = (e) => { const au = ref.current; if (!au || window.__vslAudioIsMaster) return; if (!e.detail) { if (!au.paused) au.pause(); } };
    window.addEventListener('stage-playing', onP);
    return () => window.removeEventListener('stage-playing', onP);
  }, []);
  return document.getElementById('vslAudio') ? null : <audio ref={ref} src={src} preload="auto" />;
}

/* schwebende Partikel-Ebene (Funken, driften langsam nach oben) */
function Sparks({ n = 14, tint = O }) {
  const t = aTRaw(); const els = [];
  for (let i = 0; i < n; i++) {
    const seed = i * 137.5, x = (seed % 100), base = (seed * 0.7) % 100;
    const y = (base - (t * 6 + i * 3) % 120 + 120) % 120 - 10;
    const s = 3 + (i % 4), o = 0.10 + (i % 5) * 0.03;
    els.push(<div key={i} style={{ position: "absolute", left: `${x}%`, top: `${y}%`, width: s, height: s, borderRadius: "50%", background: tint, opacity: o }}></div>);
  }
  return <div style={{ position: "absolute", inset: 0, overflow: "hidden", zIndex: 1, pointerEvents: "none" }}>{els}</div>;
}
/* Seiten-Schienen: laufende Ticks links & rechts, geben dem Rand Leben */
function SideRails() {
  const t = aTRaw();
  const ticks = 26;
  const rail = (side) => (
    <div style={{ position: "absolute", top: 0, bottom: 0, [side]: 30, width: 3, zIndex: 2, background: "linear-gradient(180deg,transparent,rgba(20,18,16,0.06) 12%,rgba(20,18,16,0.06) 88%,transparent)", overflow: "hidden" }}>
      {Array.from({ length: ticks }).map((_, i) => {
        const y = ((i / ticks * 120) - (t * 7 + (side === "left" ? 0 : 40)) % 120 + 120) % 120 - 10;
        const on = Math.sin(t * 2 + i) > 0.4;
        return <div key={i} style={{ position: "absolute", top: `${y}%`, [side]: -4, width: on ? 16 : 9, height: 3, background: on ? O : "rgba(20,18,16,0.18)", borderRadius: 2, transition: "none" }}></div>;
      })}
    </div>
  );
  return <React.Fragment>{rail("left")}{rail("right")}</React.Fragment>;
}
/* Ecken-Klammern, atmen leicht */
function Corners() {
  const s = 1 + 0.04 * Math.sin(aTRaw() * 1.4);
  const c = (pos) => <div style={{ position: "absolute", ...pos, width: 46, height: 46, borderColor: OD, borderStyle: "solid", opacity: 0.5, transform: `scale(${s})`, zIndex: 2 }}></div>;
  return <React.Fragment>
    {c({ top: 30, left: 30, borderWidth: "3px 0 0 3px" })}
    {c({ top: 30, right: 30, borderWidth: "3px 3px 0 0" })}
    {c({ bottom: 30, left: 30, borderWidth: "0 0 3px 3px" })}
    {c({ bottom: 30, right: 30, borderWidth: "0 3px 3px 0" })}
  </React.Fragment>;
}
/* driftende Emoji-Icons in den Randzonen (nie hinter dem Text-Zentrum) */
function FloatIcons() {
  const t = aTRaw();
  const items = [["🍳", 6, 30, 1.7, 0], ["💶", 92, 34, 1.4, 1.2], ["📈", 90, 70, 1.9, 2.4], ["🔑", 7, 68, 1.5, 3.1], ["📞", 94, 52, 1.6, 0.7], ["✅", 5, 48, 1.8, 2]];
  return <div style={{ position: "absolute", inset: 0, zIndex: 2, pointerEvents: "none" }}>
    {items.map((it, i) => <div key={i} style={{ position: "absolute", left: `${it[1]}%`, top: `${it[2] + Math.sin(t / it[3] + it[4]) * 3}%`, fontSize: 46, opacity: 0.16 + 0.06 * Math.sin(t * 1.2 + i), transform: `translate(-50%,-50%) rotate(${Math.sin(t / it[3] + it[4]) * 8}deg)`, filter: "grayscale(0.2)" }}>{it[0]}</div>)}
  </div>;
}
/* Boom: Shockwave-Ring + Weißblitz bei jedem Beatwechsel */
function Boom() {
  const t = aT();
  let d = 99;
  for (let i = 1; i < B.length - 1; i++) { const dd = t - B[i]; if (dd >= 0 && dd < 0.9) { d = dd; break; } }
  if (d > 0.9) return null;
  const p = d / 0.9;
  return <div style={{ position: "absolute", inset: 0, zIndex: 16, pointerEvents: "none", display: "flex", alignItems: "center", justifyContent: "center" }}>
    <div style={{ width: 200, height: 200, borderRadius: "50%", border: `${(1 - p) * 10 + 2}px solid ${O}`, opacity: (1 - p) * 0.7, transform: `scale(${1 + p * 6})` }}></div>
    <div style={{ position: "absolute", width: 200, height: 200, borderRadius: "50%", border: `${(1 - p) * 6 + 1}px solid ${OD}`, opacity: (1 - p) * 0.5, transform: `scale(${1 + p * 3.5})` }}></div>
  </div>;
}
function Chrome() {
  const t = aTRaw();
  return (<React.Fragment>
    <img src="assets/logo-ink.png" style={{ position: "absolute", top: 40, left: "50%", transform: "translateX(-50%)", height: 42, zIndex: 20, opacity: 0.9 }} />
    <div style={{ position: "absolute", left: 0, bottom: 0, height: 8, width: `${(t / AUDIO_DUR) * 100}%`, background: O, zIndex: 21, boxShadow: `0 0 18px ${O}` }}></div>
  </React.Fragment>);
}
function BeatFlash() {
  const t = aT();
  let f = 0;
  for (let i = 1; i < B.length - 1; i++) { const d = t - B[i]; if (d >= 0 && d < 0.3) { f = 1 - d / 0.3; break; } }
  if (f <= 0) return null;
  return <div style={{ position: "absolute", inset: 0, zIndex: 15, pointerEvents: "none", background: `radial-gradient(circle at 50% 50%, rgba(255,108,75,${f * 0.32}), transparent 65%)` }}></div>;
}
function Beat({ i, children }) {
  const t = aT();
  const a = B[i], b = B[i + 1], F = 0.3;
  if (t < a - 0.05 || t > b + F) return null;
  const drift = 1 + 0.035 * clamp((t - a) / (b - a), 0, 1);
  const ein = E.easeOutCubic(clamp((t - a) / 0.34, 0, 1));
  const eout = i < B.length - 2 ? E.easeInCubic(clamp((t - b) / F, 0, 1)) : 0;
  return (
    <div style={{ position: "absolute", inset: "112px 80px 96px 80px", zIndex: 3, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", opacity: ein * (1 - eout), transform: `translateY(${(1 - ein) * 26 - eout * 40}px) scale(${(1.03 - 0.03 * ein - 0.03 * eout) * drift})`, willChange: "transform, opacity" }}>{children}</div>
  );
}
function Rv({ at, children, style, dy = 22, dur = 0.42 }) {
  const t = aT();
  if (t < at) return null;
  const p = E.easeOutCubic(clamp((t - at) / dur, 0, 1));
  const blur = (1 - p) * 4;
  return <div style={{ opacity: p, filter: blur > 0.3 ? `blur(${blur}px)` : "none", transform: `translateY(${(1 - p) * dy}px) scale(${0.97 + 0.03 * p})`, ...style }}>{children}</div>;
}
function Slam({ at, children, size = 90, bg, color = INK, style }) {
  const t = aT();
  if (t < at) return null;
  const p = E.easeOutBack(clamp((t - at) / 0.32, 0, 1));
  return <div style={{ font: `700 ${size}px/1.08 'Space Grotesk', sans-serif`, letterSpacing: "-0.02em", color: bg ? CREAM : color, background: bg || "none", padding: bg ? "0.04em 0.22em 0.1em" : 0, borderRadius: bg ? 14 : 0, display: "inline-block", opacity: clamp(p * 1.6, 0, 1), transform: `scale(${0.5 + 0.5 * p}) rotate(${(1 - p) * -2.5}deg)`, ...style }}>{children}</div>;
}
function Num({ at, to, dur = 1.6, prefix = "", suffix = "", size = 150, color = OD }) {
  const t = aT();
  if (t < at) return null;
  const raw = clamp((t - at) / dur, 0, 1);
  const p = 1 - Math.pow(1 - raw, 4);
  const pop = raw >= 1 ? 1 + 0.07 * Math.max(0, 1 - (t - at - dur) / 0.3) : 1;
  return <div style={{ font: `700 ${size}px/1 'Space Grotesk', sans-serif`, letterSpacing: "-0.03em", color, fontVariantNumeric: "tabular-nums", display: "inline-block", transform: `scale(${pop})` }}>{prefix}{Math.round(to * p).toLocaleString("de-DE")}{suffix}</div>;
}
function Pill({ at, children, color = O }) {
  const t = aT();
  if (t < at) return null;
  const p = E.easeOutBack(clamp((t - at) / 0.3, 0, 1));
  return <div style={{ font: "600 27px/1 'Space Grotesk', sans-serif", color: INK, background: "#fff", border: `2.5px solid ${color}`, borderRadius: 999, padding: "14px 24px", boxShadow: "0 10px 26px rgba(20,10,4,0.1)", opacity: clamp(p * 1.3, 0, 1), transform: `scale(${0.5 + 0.5 * p})` }}>{children}</div>;
}
/* SVG-Pfad, der sich zeichnet */
function Draw({ d, at, dur = 1.0, stroke = OD, w = 5, fill = "none" }) {
  const t = aT();
  const p = clamp((t - at) / dur, 0, 1);
  const len = 1400;
  return <path d={d} fill={fill} stroke={stroke} strokeWidth={w} strokeLinecap="round" strokeLinejoin="round" strokeDasharray={len} strokeDashoffset={len * (1 - p)} />;
}
const HL = { background: O, color: CREAM, padding: "0.02em 0.16em 0.08em", borderRadius: 10 };

/* ═══ Beat 1 · HOOK · 0–13 ═══ */
function CalGrid({ at, booked, tint }) {
  const t = aT(); const cells = [];
  for (let i = 0; i < 20; i++) {
    const isBk = booked && i < 15;
    const on = isBk && t > at + 0.4 + i * 0.1;
    const pop = on ? E.easeOutBack(clamp((t - (at + 0.4 + i * 0.1)) / 0.28, 0, 1)) : 0;
    cells.push(<div key={i} style={{ position: "relative", width: 52, height: 40, borderRadius: 7, background: on ? tint : "rgba(20,18,16,0.06)", transform: `scale(${on ? 0.6 + 0.4 * pop : 1})`, boxShadow: on ? "0 6px 14px rgba(255,108,75,0.3)" : "none", transition: "background 120ms", display: "flex", alignItems: "center", justifyContent: "center" }}>
      {on && pop > 0.6 && <span style={{ color: "#fff", font: "700 20px 'Space Grotesk'", opacity: (pop - 0.6) / 0.4 }}>✓</span>}
    </div>);
  }
  return <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 52px)", gap: 8, justifyContent: "center" }}>{cells}</div>;
}
function B1() {
  const t = aT();
  const bookings = Math.min(15, Math.max(0, Math.floor((t - 3.4) / 0.1)));
  const winP = E.easeOutCubic(clamp((t - 3.0) / 0.5, 0, 1));
  const loseP = E.easeOutCubic(clamp((t - 3.4) / 0.5, 0, 1));
  const vsP = E.easeOutBack(clamp((t - 3.8) / 0.4, 0, 1));
  return (<Beat i={0}>
    <Rv at={0.3}><div style={{ font: "600 26px/1 'IBM Plex Mono', monospace", color: OD, letterSpacing: "0.32em", textTransform: "uppercase", marginBottom: 26 }}>Für Küchenstudio-Inhaber</div></Rv>
    <Slam at={0.8} size={70}>Zwei Küchenstudios.<br />Dieselbe Stadt.</Slam>
    <div style={{ marginTop: 40, display: "flex", gap: 30, alignItems: "center", justifyContent: "center" }}>
      {/* Gewinner */}
      <Float amp={7} spd={1.1}>
        <div style={{ position: "relative", background: "#fff", borderRadius: 22, padding: "22px 26px 24px", boxShadow: "0 26px 60px rgba(255,108,75,0.28)", border: `3px solid ${O}`, opacity: winP, transform: `translateY(${(1 - winP) * 40}px) scale(${winP})` }}>
          <PulseRing max={0.14} />
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 }}>
            <div style={{ font: "600 17px/1 'IBM Plex Mono', monospace", color: GRAY, letterSpacing: "0.14em" }}>SICHTBAR</div>
            <div style={{ display: "flex", alignItems: "center", gap: 6, background: "rgba(58,125,92,0.12)", color: GRUEN, borderRadius: 20, padding: "4px 12px", font: "700 16px 'Space Grotesk'" }}>▲ voll</div>
          </div>
          <CalGrid at={3.0} booked={true} tint={O} />
          <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 16 }}>
            <div style={{ font: "700 44px/1 'Space Grotesk', sans-serif", color: OD }}>+{bookings}</div>
            <div style={{ font: "600 22px/1 'Space Grotesk', sans-serif", color: INK }}>Anfragen · 3 Wochen ausgebucht</div>
          </div>
        </div>
      </Float>
      {/* VS */}
      <div style={{ width: 64, height: 64, borderRadius: "50%", background: INK, color: CREAM, display: "flex", alignItems: "center", justifyContent: "center", font: "700 24px 'Space Grotesk'", flex: "none", opacity: clamp(vsP, 0, 1), transform: `scale(${vsP}) rotate(${(1 - vsP) * -40}deg)`, boxShadow: "0 14px 30px rgba(20,10,4,0.25)" }}>VS</div>
      {/* Verlierer */}
      <div style={{ background: "#fff", borderRadius: 22, padding: "22px 26px 24px", boxShadow: "0 12px 30px rgba(20,10,4,0.06)", border: "2.5px solid rgba(20,18,16,0.12)", opacity: loseP * 0.72, transform: `translateY(${(1 - loseP) * 40}px) scale(${0.96 + loseP * 0.04})`, filter: "grayscale(0.5)" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 }}>
          <div style={{ font: "600 17px/1 'IBM Plex Mono', monospace", color: GRAY, letterSpacing: "0.14em" }}>UNSICHTBAR</div>
          <div style={{ display: "flex", alignItems: "center", gap: 6, background: "rgba(20,18,16,0.06)", color: GRAY, borderRadius: 20, padding: "4px 12px", font: "700 16px 'Space Grotesk'" }}>▼ leer</div>
        </div>
        <CalGrid at={3.0} booked={false} tint={O} />
        <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 16 }}>
          <div style={{ font: "700 44px/1 'Space Grotesk', sans-serif", color: GRAY }}>0</div>
          <div style={{ font: "600 22px/1 'Space Grotesk', sans-serif", color: GRAY }}>Anfragen · Ausstellung leer</div>
        </div>
      </div>
    </div>
    <Rv at={8.3} style={{ marginTop: 26 }}><div style={{ font: "500 30px/1.3 'Space Grotesk', sans-serif", color: GRAY }}>Gleiche Marken. Gleiche Preise. Gleiche Qualität.</div></Rv>
    <Slam at={10.8} size={58} style={{ marginTop: 18 }}>Der Unterschied: <span style={HL}>Sichtbarkeit</span>.</Slam>
  </Beat>);
}

/* ═══ Beat 2 · PROBLEM + KOSTEN · 13–34 ═══ */
function SearchUI({ at }) {
  const t = aT();
  const full = "Küche Musterstadt";
  const chars = Math.max(0, Math.min(full.length, Math.floor((t - at) / 0.06)));
  const rows = [["Küchen Nord", true, 13.9], ["Studio Meier", true, 14.7], ["KüchenWelt XXL", true, 15.5], ["Dein Studio", false, 17.0]];
  return (
    <div style={{ width: 720, background: "#fff", borderRadius: 20, boxShadow: "0 26px 60px rgba(20,10,4,0.14)", overflow: "hidden", textAlign: "left" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "20px 24px", borderBottom: "1px solid rgba(20,18,16,0.08)" }}>
        <div style={{ width: 26, height: 26, borderRadius: "50%", border: `4px solid ${GRAY}`, borderRightColor: "transparent", transform: `rotate(${t * 40}deg)` }}></div>
        <div style={{ font: "500 30px/1 'Space Grotesk', sans-serif", color: INK }}>{full.slice(0, chars)}<span style={{ opacity: Math.sin(t * 6) > 0 ? 1 : 0, color: O }}>|</span></div>
      </div>
      {rows.map((r, i) => {
        const on = t > r[2];
        const p = E.easeOutCubic(clamp((t - r[2]) / 0.3, 0, 1));
        return <div key={i} style={{ display: "flex", alignItems: "center", gap: 16, padding: "16px 24px", opacity: on ? 1 : 0, transform: `translateX(${(1 - p) * -30}px)`, background: r[1] ? "transparent" : "rgba(255,108,75,0.06)" }}>
          <div style={{ width: 40, height: 40, borderRadius: 10, background: r[1] ? GRUEN : "rgba(20,18,16,0.1)", color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", font: "700 22px 'Space Grotesk'" }}>{r[1] ? "✓" : "?"}</div>
          <div style={{ font: `${r[1] ? 600 : 500} 27px/1 'Space Grotesk', sans-serif`, color: r[1] ? INK : OD, textDecoration: r[1] ? "none" : "none" }}>{r[0]}{!r[1] && <span style={{ font: "500 20px/1 'IBM Plex Mono', monospace", color: OD, marginLeft: 12 }}>nicht gefunden</span>}</div>
        </div>;
      })}
    </div>
  );
}
function LossBars({ at }) {
  const t = aT();
  const bars = [0.92, 0.78, 0.62, 0.48, 0.32, 0.18];
  const lineP = E.easeInOutCubic(clamp((t - at - 0.2) / 1.4, 0, 1));
  /* fliegende Euro-Scheine, driften nach oben rechts weg */
  const notes = [];
  for (let i = 0; i < 7; i++) {
    const start = at + 0.5 + i * 0.28;
    const p = clamp((t - start) / 1.5, 0, 1);
    if (p > 0 && p < 1) {
      const ease = E.easeInCubic(p);
      notes.push(<div key={i} style={{ position: "absolute", left: 40 + (i % 3) * 60 + ease * 260, top: 150 - ease * 190, fontSize: 30 + (i % 2) * 8, opacity: (1 - p) * 0.9, transform: `rotate(${ease * (i % 2 ? 40 : -30)}deg) scale(${1 - p * 0.3})` }}>💶</div>);
    }
  }
  return (
    <div style={{ position: "relative", width: 540, height: 240 }}>
      <svg viewBox="0 0 540 240" style={{ width: 540, height: 240 }}>
        <defs>
          <linearGradient id="lossbar" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor={O} /><stop offset="100%" stopColor={OD} /></linearGradient>
          <filter id="lossglow"><feGaussianBlur stdDeviation="4" result="b" /><feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge></filter>
        </defs>
        {[0, 1, 2, 3].map(i => <line key={i} x1="20" y1={40 + i * 45} x2="520" y2={40 + i * 45} stroke="rgba(20,18,16,0.06)" strokeWidth="2" />)}
        {bars.map((h, i) => {
          const p = E.easeOutCubic(clamp((t - at - i * 0.12) / 0.5, 0, 1));
          const bh = h * 165 * p;
          return <g key={i}>
            <rect x={24 + i * 84} y={200 - bh} width={60} height={bh} rx={8} fill="url(#lossbar)" opacity={0.5 + 0.5 * (i / bars.length)} />
            <text x={54 + i * 84} y={224} textAnchor="middle" fill={GRAY} style={{ font: "600 15px 'IBM Plex Mono', monospace" }}>{["Jan", "Feb", "Mär", "Apr", "Mai", "Jun"][i]}</text>
          </g>;
        })}
        <line x1="24" y1="42" x2={24 + 490 * lineP} y2={42 + 150 * lineP} stroke={OD} strokeWidth="5" strokeLinecap="round" filter="url(#lossglow)" />
        {lineP > 0.98 && <polygon points="510,188 516,196 502,198" fill={OD} />}
      </svg>
      {notes}
    </div>
  );
}
function B2() {
  const t = aT();
  const kosten = t > 23.6;
  return (<Beat i={1}>
    {!kosten ? (
      <React.Fragment>
        <Rv at={13.3} style={{ marginBottom: 26 }}><div style={{ font: "700 50px/1.15 'Space Grotesk', sans-serif", color: INK }}>Wer heute eine Küche plant,<br />sucht <span style={HL}>zuerst online</span>.</div></Rv>
        <SearchUI at={13.6} />
        <Slam at={19.3} size={50} bg={INK} style={{ marginTop: 28 }}>Wer da nicht auftaucht, existiert nicht.</Slam>
      </React.Fragment>
    ) : (
      <div style={{ display: "flex", alignItems: "center", gap: 56 }}>
        <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-start", gap: 4 }}>
          <Rv at={23.7}><div style={{ font: "600 22px/1 'IBM Plex Mono', monospace", color: OD, letterSpacing: "0.16em", textTransform: "uppercase", marginBottom: 8 }}>Die Rechnung</div></Rv>
          <Rv at={24.0}><div style={{ font: "500 26px/1.2 'Space Grotesk', sans-serif", color: GRAY }}>Eine verkaufte Küche</div></Rv>
          <Num at={24.3} to={12000} dur={1.2} suffix=" €" size={92} color={INK} />
          <Rv at={27.9} style={{ marginTop: 18, display: "flex", alignItems: "center", gap: 10 }}><div style={{ width: 30, height: 30, borderRadius: "50%", background: "rgba(255,108,75,0.14)", color: OD, display: "flex", alignItems: "center", justifyContent: "center", font: "700 20px 'Space Grotesk'" }}>×</div><div style={{ font: "500 26px/1.3 'Space Grotesk', sans-serif", color: GRAY }}>nur 2 verlorene Kunden / Monat</div></Rv>
          <div style={{ position: "relative", marginTop: 6 }}>
            <Num at={30.2} to={280000} dur={2.0} prefix="− " suffix=" €" size={128} color={OD} />
            {t > 31 && <div style={{ position: "absolute", inset: -14, borderRadius: 20, boxShadow: `0 0 ${40 + Math.sin(t * 5) * 14}px rgba(224,78,44,0.35)`, pointerEvents: "none" }}></div>}
          </div>
          <Slam at={32.6} size={44} bg={INK} style={{ marginTop: 16 }}>pro Jahr. Einfach weg.</Slam>
        </div>
        <Rv at={30.0} dur={0.4}><LossBars at={30.2} /></Rv>
      </div>
    )}
  </Beat>);
}

/* ═══ Beat 3 · SYSTEM · 34–52 ═══ */
function Karte({ n, title, at, active, children }) {
  const t = aT();
  const p = E.easeOutCubic(clamp((t - at) / 0.5, 0, 1));
  return (
    <div style={{ position: "relative", width: 430, borderRadius: 24, background: "#fff", padding: "24px 24px 20px", border: active ? `4px solid ${O}` : "2.5px solid rgba(20,18,16,0.12)", boxShadow: active ? "0 26px 60px rgba(255,108,75,0.24)" : "0 12px 30px rgba(20,10,4,0.07)", opacity: clamp(p * 1.2, 0, 1), transform: `translateY(${(1 - p) * 46 + osc(1.3, active ? 5 : 2, n) }px) scale(${active ? 1.04 : 0.96})`, display: "flex", flexDirection: "column", alignItems: "center", gap: 10, transition: "border 260ms, box-shadow 260ms" }}>
      {active && <PulseRing max={0.1} />}
      <div style={{ font: "600 21px/1 'IBM Plex Mono', monospace", color: OD, letterSpacing: "0.24em" }}>SCHRITT {n}</div>
      <div style={{ font: "700 38px/1 'Space Grotesk', sans-serif", color: INK }}>{title}</div>
      <div style={{ height: 180, display: "flex", alignItems: "center", justifyContent: "center" }}>{children}</div>
    </div>
  );
}
function B3() {
  const t = aT();
  const sweep = ((t - 38.3) % 2.4) / 2.4;
  const dotP = clamp((t - 38.3) / 12, 0, 1);
  return (<Beat i={2}>
    <Rv at={34.2} style={{ marginBottom: 26 }}><div style={{ font: "700 54px/1.12 'Space Grotesk', sans-serif", color: INK }}>Unser <span style={HL}>Küchen-Kunden-System</span>.</div></Rv>
    <div style={{ position: "relative" }}>
      <svg viewBox="0 0 1360 20" style={{ position: "absolute", top: 96, left: 0, width: 1360, height: 20, zIndex: 0 }}>
        <line x1="20" y1="10" x2="1340" y2="10" stroke="rgba(20,18,16,0.12)" strokeWidth="4" strokeDasharray="4 10" />
        <line x1="20" y1="10" x2={20 + 1320 * dotP} y2="10" stroke={O} strokeWidth="5" />
        <circle cx={20 + 1320 * dotP} cy="10" r="9" fill={OD} />
      </svg>
      <div style={{ display: "flex", gap: 34, position: "relative", zIndex: 1 }}>
        <Karte n="1" title="In 48 h" at={38.3} active={t >= 38.3 && t < 42.1}>
          <div style={{ position: "relative", width: 160, height: 160 }}>
            {[54, 76].map(r => <div key={r} style={{ position: "absolute", left: 80 - r, top: 80 - r, width: r * 2, height: r * 2, borderRadius: "50%", border: "2px solid rgba(255,108,75,0.3)" }}></div>)}
            <div style={{ position: "absolute", left: 80, top: 80, width: 76, height: 3, background: `linear-gradient(90deg, ${O}, transparent)`, transformOrigin: "left center", transform: `rotate(${sweep * 360}deg)` }}></div>
            {[[46, -28], [-54, 22], [22, 50], [-30, -46]].map((d, i) => { const lit = ((sweep * 360) % 360) > (Math.atan2(d[1], d[0]) * 180 / Math.PI + 360) % 360 - 40; return <div key={i} style={{ position: "absolute", left: 80 + d[0] - 7, top: 80 + d[1] - 7, width: 14, height: 14, borderRadius: "50%", background: lit ? O : "rgba(20,18,16,0.18)", boxShadow: lit ? "0 0 12px rgba(255,108,75,0.7)" : "none" }}></div>; })}
            <div style={{ position: "absolute", left: 0, right: 0, bottom: -4, textAlign: "center", font: "500 18px/1.2 'Space Grotesk', sans-serif", color: GRAY }}>Anzeigen · Texte<br />· Zielgruppen</div>
          </div>
        </Karte>
        <Karte n="2" title="Ab Tag 3" at={42.1} active={t >= 42.1 && t < 46.7}>
          <div style={{ display: "flex", flexDirection: "column", gap: 10, width: "100%" }}>
            {[["✓ Name & Nummer", 42.5], ["✓ Grobes Budget", 43.6], ["📩 direkt bei dir", 44.8]].map((p, i) => {
              const pp = E.easeOutBack(clamp((t - p[1]) / 0.4, 0, 1));
              return <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, background: "rgba(255,108,75,0.08)", border: "1.5px solid rgba(255,108,75,0.3)", borderRadius: 12, padding: "10px 16px", font: "600 22px/1.2 'Space Grotesk', sans-serif", color: INK, opacity: clamp(pp * 1.4, 0, 1), transform: `translateX(${(1 - pp) * 40}px)` }}>{p[0]}</div>;
            })}
          </div>
        </Karte>
        <Karte n="3" title="25+ / Monat" at={46.7} active={t >= 46.7}>
          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4 }}>
            <div style={{ display: "flex", alignItems: "flex-end", gap: 5, height: 60, marginBottom: 6 }}>
              {[0.3, 0.45, 0.6, 0.75, 0.9, 1].map((h, i) => { const pp = E.easeOutCubic(clamp((t - 47.2 - i * 0.14) / 0.4, 0, 1)); return <div key={i} style={{ width: 14, height: h * 54 * pp, background: `linear-gradient(180deg,${O},${OD})`, borderRadius: 3 }}></div>; })}
            </div>
            <Num at={47.8} to={25} dur={1.0} suffix="+" size={76} />
            <div style={{ font: "500 21px/1.2 'Space Grotesk', sans-serif", color: GRAY, textAlign: "center" }}>qualifizierte<br />Anfragen, stabil</div>
          </div>
        </Karte>
      </div>
    </div>
  </Beat>);
}

/* ═══ Beat 4 · GARANTIE · 52–62 ═══ */
function Burst({ at }) {
  const t = aT();
  const p = clamp((t - at) / 0.7, 0, 1);
  if (p <= 0 || p >= 1) return null;
  const rays = [];
  for (let i = 0; i < 12; i++) { const a = i / 12 * Math.PI * 2, d = 40 + p * 120; rays.push(<div key={i} style={{ position: "absolute", left: 110 + Math.cos(a) * d, top: 110 + Math.sin(a) * d, width: 12, height: 12, borderRadius: "50%", background: O, opacity: 1 - p }}></div>); }
  return <div style={{ position: "absolute", inset: 0 }}>{rays}</div>;
}
function B4() {
  const t = aT();
  const stampAt = 57.9;
  const sp = E.easeInCubic(clamp((t - stampAt) / 0.26, 0, 1));
  const shake = t > stampAt + 0.26 && t < stampAt + 0.66 ? Math.sin(t * 90) * 9 * (1 - (t - stampAt - 0.26) / 0.4) : 0;
  return (<Beat i={3}>
    <div style={{ transform: `translate(${shake}px, ${shake * 0.6}px)`, display: "flex", flexDirection: "column", alignItems: "center" }}>
      <Rv at={52.2} style={{ marginBottom: 44 }}><div style={{ font: "700 60px/1.12 'Space Grotesk', sans-serif", color: INK }}>Wir versprechen nicht.<br />Wir <span style={{ background: O, color: CREAM, padding: "0.02em 0.16em 0.08em", borderRadius: 12 }}>garantieren</span>.</div></Rv>
      <div style={{ position: "relative", width: 660, height: 280 }}>
        <div style={{ position: "absolute", inset: 0, background: "#fff", borderRadius: 18, boxShadow: "0 26px 60px rgba(20,10,4,0.14)", padding: "28px 40px", textAlign: "left" }}>
          <div style={{ font: "600 18px/1 'IBM Plex Mono', monospace", color: GRAY, letterSpacing: "0.2em", marginBottom: 14 }}>VEREINBARUNG · SCHWARZ AUF WEISS</div>
          {[85, 100, 72].map((w, i) => <div key={i} style={{ height: 12, width: `${w}%`, background: "rgba(20,18,16,0.1)", borderRadius: 6, marginBottom: 11 }}></div>)}
          <div style={{ font: "700 32px/1.2 'Space Grotesk', sans-serif", color: INK, marginTop: 8, paddingRight: 120 }}>Mind. <span style={{ color: OD }}>25 qualifizierte Anfragen</span> / Monat</div>
          <svg viewBox="0 0 220 60" style={{ position: "absolute", left: 40, bottom: 22, width: 220, height: 60 }}>
            <Draw d="M4 40 C 26 6, 40 6, 48 34 C 54 54, 66 54, 74 30 C 82 10, 104 10, 120 40 C 140 20, 176 22, 214 30" at={54.6} dur={1.8} stroke={OD} w={4} />
          </svg>
        </div>
        {t > stampAt && (
          <div style={{ position: "absolute", right: -85, top: -85, width: 220, height: 220 }}>
            <Burst at={stampAt} />
            <div style={{ position: "absolute", inset: 0, borderRadius: "50%", border: `10px solid ${OD}`, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", background: "rgba(251,242,234,0.95)", color: OD, transform: `rotate(-13deg) scale(${3 - 2 * sp})`, opacity: sp, boxShadow: "0 20px 50px rgba(224,78,44,0.3)" }}>
              {sp >= 1 && <PulseRing color={OD} max={0.3} spd={0.7} />}
              <div style={{ font: "700 66px/1 'Space Grotesk', sans-serif" }}>25+</div>
              <div style={{ font: "600 17px/1.25 'IBM Plex Mono', monospace", letterSpacing: "0.1em", textAlign: "center" }}>GARANTIERT<br />ODER 0 €</div>
            </div>
          </div>
        )}
      </div>
      <Slam at={60.0} size={54} bg={INK} style={{ marginTop: 32 }}>… oder du zahlst 0 €.</Slam>
    </div>
  </Beat>);
}

/* ═══ Beat 5 · BEWEIS · 62–70 ═══ */
function B5() {
  const t = aT();
  const card = { background: "#fff", borderRadius: 24, boxShadow: "0 22px 56px rgba(20,10,4,0.1)", padding: "32px 48px", display: "flex", flexDirection: "column", alignItems: "center", gap: 4 };
  const chips = ["Seel Küchen", "CB Küchen", "Bayer. Trendhaus", "+ 24 weitere"];
  return (<Beat i={4}>
    <Rv at={62.2} style={{ marginBottom: 32 }}><div style={{ font: "700 54px/1.15 'Space Grotesk', sans-serif", color: INK }}>Warum wir uns das trauen?</div></Rv>
    <div style={{ display: "flex", gap: 40, alignItems: "stretch" }}>
      <div style={card}><Num at={64.4} to={27} dur={1.0} size={116} /><div style={{ font: "600 24px/1.2 'Space Grotesk', sans-serif", color: GRAY }}>Küchenstudios betreut</div></div>
      <div style={card}><Num at={66.0} to={100} dur={0.5} suffix=" %" size={116} color={GRUEN} /><div style={{ font: "600 24px/1.2 'Space Grotesk', sans-serif", color: GRAY }}>Erfolgsquote</div></div>
    </div>
    <div style={{ display: "flex", gap: 14, marginTop: 30, flexWrap: "wrap", justifyContent: "center" }}>
      {chips.map((c, i) => { const at = 67.2 + i * 0.35; const p = E.easeOutBack(clamp((t - at) / 0.32, 0, 1)); return <div key={i} style={{ font: "600 24px/1 'Space Grotesk', sans-serif", color: INK, background: "#fff", border: "2px solid rgba(20,18,16,0.12)", borderRadius: 12, padding: "12px 20px", opacity: clamp(p * 1.3, 0, 1), transform: `translateY(${(1 - p) * 20}px)` }}>{c}</div>; })}
    </div>
  </Beat>);
}

/* ═══ Beat 6 · VERKNAPPUNG · 70–79 ═══ */
function B6() {
  const t = aT();
  const lock = t > 74.0;
  const lp = E.easeOutBack(clamp((t - 74.0) / 0.4, 0, 1));
  return (<Beat i={5}>
    <Rv at={70.2}><div style={{ font: "600 26px/1 'IBM Plex Mono', monospace", color: OD, letterSpacing: "0.24em", textTransform: "uppercase", marginBottom: 26 }}>Ein Punkt noch</div></Rv>
    <Slam at={72.1} size={60}>Pro Region <span style={HL}>nur ein Studio</span>.</Slam>
    <Rv at={74.0} style={{ marginTop: 34 }} dur={0.34}>
      <div style={{ position: "relative", width: 300, height: 220 }}>
        <svg viewBox="0 0 300 220" style={{ width: 300, height: 220 }}>
          <path d="M40 30 H260 V170 H160 L150 200 L140 170 H40 Z" fill="#fff" stroke="rgba(20,18,16,0.14)" strokeWidth="3" />
          {[[95, 80], [200, 70], [150, 130], [230, 140]].map((d, i) => <circle key={i} cx={d[0]} cy={d[1]} r="8" fill={i === 0 ? OD : "rgba(20,18,16,0.18)"} />)}
        </svg>
        <div style={{ position: "absolute", left: 78, top: 44, width: 60, height: 60, borderRadius: "50%", background: O, display: "flex", alignItems: "center", justifyContent: "center", transform: `scale(${lock ? lp : 0})`, boxShadow: "0 12px 30px rgba(255,108,75,0.5)" }}>
          <span style={{ fontSize: 30 }}>🔒</span>
        </div>
      </div>
    </Rv>
    <Rv at={76.6} style={{ marginTop: 16 }}><div style={{ font: "600 30px/1.3 'Space Grotesk', sans-serif", color: INK }}>Ist dein Gebiet vergeben, <span style={{ color: OD }}>bekommt es dein Wettbewerber.</span></div></Rv>
  </Beat>);
}

/* ═══ Beat 7 · CTA + LUIS + ENDCARD · 79–93.75 ═══ */
function B7() {
  const t = aT();
  const luis = t > 84.7, end = t > 91.2;  const btnP = E.easeOutBack(clamp((t - 81.5) / 0.5, 0, 1));
  const pulse = 1 + Math.sin(t * 4) * 0.03;
  const endP = E.easeOutCubic(clamp((t - 91.2) / 0.6, 0, 1));
  return (<Beat i={6}>
    {end ? (
      <div style={{ opacity: endP, transform: `scale(${0.96 + 0.04 * endP})`, display: "flex", flexDirection: "column", alignItems: "center", gap: 24 }}>
        <img src="assets/logo-ink.png" style={{ height: 88 }} />
        <div style={{ font: "700 58px/1.15 'Space Grotesk', sans-serif", color: INK, textAlign: "center" }}>25+ Anfragen pro Monat.<br /><span style={{ background: O, color: CREAM, padding: "0.02em 0.18em 0.08em", borderRadius: 14 }}>Garantiert.</span></div>
        <div style={{ fontSize: 50, transform: `translateY(${Math.sin(t * 4) * 10}px)` }}>👇</div>
      </div>
    ) : !luis ? (
      <React.Fragment>
        <Rv at={79.9} style={{ marginBottom: 18 }}><div style={{ font: "700 58px/1.12 'Space Grotesk', sans-serif", color: INK, maxWidth: 1300 }}>Wie viele Anfragen sind in <span style={{ color: OD }}>deiner Region</span> möglich?</div></Rv>
        <Rv at={80.9} style={{ marginBottom: 40 }}><div style={{ font: "500 30px/1.4 'Space Grotesk', sans-serif", color: GRAY }}>45 Minuten · ehrliche Analyse · konkrete Zahlen für deinen Standort.</div></Rv>
        <div style={{ position: "relative", font: "700 40px/1 'Space Grotesk', sans-serif", color: INK, background: O, borderRadius: 999, padding: "28px 54px", display: "inline-flex", alignItems: "center", gap: 18, boxShadow: "0 24px 60px rgba(255,108,75,0.4)", opacity: clamp(btnP, 0, 1), transform: `scale(${(0.6 + 0.4 * clamp(btnP, 0, 1)) * pulse})` }}>
          <PulseRing color={O} max={0.22} spd={0.7} />
          Kostenloses Erstgespräch sichern <span style={{ width: 48, height: 48, borderRadius: "50%", background: INK, color: O, display: "inline-flex", alignItems: "center", justifyContent: "center", fontSize: 26 }}>→</span>
        </div>
      </React.Fragment>
    ) : (
      <React.Fragment>
        <Rv at={85.0} style={{ marginBottom: 34 }}><div style={{ font: "700 50px/1.15 'Space Grotesk', sans-serif", color: INK }}>Den Call führst du mit <span style={{ background: O, color: CREAM, padding: "0.04em 0.2em 0.1em", borderRadius: 10 }}>Louis</span>.</div></Rv>
        <div style={{ display: "flex", alignItems: "center", gap: 46 }}>
          <Rv at={85.6}>
            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 16 }}>
              <div style={{ width: 220, height: 220, borderRadius: "50%", border: `6px solid ${O}`, overflow: "hidden", boxShadow: "0 30px 70px rgba(255,108,75,0.25)", background: "#fff", position: "relative" }}>
                <image-slot id="louis-portrait" src="assets/louis.png" shape="circle" style={{ position: "absolute", inset: 0 }} placeholder="Foto von Louis"></image-slot>
              </div>
              <div style={{ textAlign: "center" }}>
                <div style={{ font: "700 34px/1 'Space Grotesk', sans-serif", color: INK }}>Louis</div>
                <div style={{ font: "600 16px/1.4 'IBM Plex Mono', monospace", color: OD, letterSpacing: "0.14em", textTransform: "uppercase" }}>Geschäftsführer · Smith &amp; Victory</div>
              </div>
            </div>
          </Rv>
          <div style={{ display: "flex", flexDirection: "column", gap: 14, textAlign: "left" }}>
            <Pill at={87.0}>Live-Rechnung für deine Region</Pill>
            <Pill at={88.0}>Passt es, starten wir diese Woche</Pill>
            <Pill at={89.0}>Passt es nicht, sagen wir's klar</Pill>
          </div>
        </div>
      </React.Fragment>
    )}
  </Beat>);
}

function VSLVideo() {
  const t = aT();
  let bs = 0; for (let i = 0; i < B.length; i++) if (B[i] <= t) bs = B[i];
  const kick = E.easeOutCubic(Math.max(0, Math.min(1, (t - bs) / 0.5)));
  const kScale = 1.05 - 0.05 * kick;
  return (
    <div style={{ position: "absolute", inset: 0, background: PAPER, overflow: "hidden", fontFamily: "'Space Grotesk', sans-serif", transform: `scale(${kScale})`, willChange: "transform" }}>
      <div style={{ position: "absolute", inset: 0, backgroundImage: "radial-gradient(rgba(20,18,16,0.05) 1.5px, transparent 1.5px)", backgroundSize: "44px 44px", transform: `translate(${osc(0.3, 8)}px, ${osc(0.24, 8, 1)}px)` }}></div>
      <Ambient />
      <div style={{ position: "absolute", inset: 0, background: "radial-gradient(90% 70% at 50% 0%, rgba(255,108,75,0.10), transparent 60%)", opacity: 0.7 + 0.3 * Math.sin(aTRaw() * 0.9) }}></div>
      <Sparks n={16} />
      <VAudio src="assets/vsl-kueche.mp3" />
      <Chrome />
      <BeatFlash />
      <Boom />
      <B1 /><B2 /><B3 /><B4 /><B5 /><B6 /><B7 />
    </div>
  );
}
Object.assign(window, { VSLVideo, VSL_DUR });
