/* EIPME Handwerker-Spot — 1200×1200, ~11.5s, comic style.
   Reads Stage/Sprite/useTime/Easing/interpolate/animate from window (animations.jsx). */

const { Stage, Sprite, useTime, useSprite, Easing, interpolate, animate, clamp } = window;
const R = React;

/* ---------- palette (EIPME tokens, literal values) ---------- */
const C = {
  blue: "#1F5EFF", blue600: "#0A47E0", blue300: "#8AA8FF", blue100: "#D9E4FF", blue50: "#EEF3FF",
  orange: "#FF7A1A", orange300: "#FFA15C", orange100: "#FFDEC2",
  red: "#FF3B47", red600: "#E51F2D", red100: "#FFD6DA",
  ink: "#0C0E13", ink700: "#1C202A", ink500: "#3D434F", ink300: "#858B98", ink100: "#D6D9DF",
  paper: "#FAFBFC", white: "#FFFFFF", sky: "#EEF3FF",
  skin: "#FFD9B8", skinShade: "#F2BE93", cheek: "#FFB08A",
};
const INK = C.ink;
const GEIST = "'Geist', system-ui, sans-serif";
const MONO = "'Geist Mono', ui-monospace, monospace";

/* ============================================================
   HANDWERKER — comic character, slightly exaggerated proportions.
   expression: 'grin' | 'wink' | 'shock' | 'smile'
   pose: 'crossed' (arms crossed) | 'up' (thumbs-up-ish open pose)
   Drawn in a 360×520 viewBox, anchored bottom-center.
   ============================================================ */
function Handwerker({ expression = "grin", pose = "crossed", sweat = 0, bob = 0, blink = 0 }) {
  const shocked = expression === "shock";
  // head bobs gently; on shock it jumps a bit
  const headY = bob;

  /* --- eyes --- */
  let eyes;
  if (expression === "wink") {
    eyes = (
      <g>
        {/* left eye open */}
        <circle cx="150" cy="118" r="9" fill={INK} />
        {/* right eye winking: arc */}
        <path d="M 196 118 q 12 10 24 0" stroke={INK} strokeWidth="7" fill="none" strokeLinecap="round" />
      </g>
    );
  } else if (shocked) {
    eyes = (
      <g>
        <circle cx="148" cy="130" r="20" fill={C.white} stroke={INK} strokeWidth="6" />
        <circle cx="151" cy="133" r="7" fill={INK} />
        <circle cx="210" cy="130" r="20" fill={C.white} stroke={INK} strokeWidth="6" />
        <circle cx="207" cy="133" r="7" fill={INK} />
      </g>
    );
  } else {
    const closed = blink > 0.5;
    eyes = closed ? (
      <g>
        <path d="M 141 120 q 9 6 18 0" stroke={INK} strokeWidth="6" fill="none" strokeLinecap="round" />
        <path d="M 199 120 q 9 6 18 0" stroke={INK} strokeWidth="6" fill="none" strokeLinecap="round" />
      </g>
    ) : (
      <g>
        <circle cx="150" cy="118" r="9" fill={INK} />
        <circle cx="208" cy="118" r="9" fill={INK} />
      </g>
    );
  }

  /* --- mouth --- */
  let mouth;
  if (shocked) {
    mouth = <ellipse cx="179" cy="172" rx="17" ry="21" fill={INK} />;
  } else if (expression === "smile") {
    mouth = <path d="M 150 152 q 29 26 58 0" stroke={INK} strokeWidth="7" fill="none" strokeLinecap="round" />;
  } else {
    // confident grin (open)
    mouth = (
      <g>
        <path d="M 146 148 q 33 34 66 0 z" fill={C.white} stroke={INK} strokeWidth="6" strokeLinejoin="round" />
      </g>
    );
  }

  /* --- brows --- */
  const brows = shocked ? (
    <g>
      <path d="M 132 100 q 16 -14 34 -6" stroke={INK} strokeWidth="7" fill="none" strokeLinecap="round" />
      <path d="M 192 94 q 18 -8 34 6" stroke={INK} strokeWidth="7" fill="none" strokeLinecap="round" />
    </g>
  ) : (
    <g>
      <path d="M 136 98 q 15 -8 30 -3" stroke={INK} strokeWidth="7" fill="none" strokeLinecap="round" />
      <path d="M 194 95 q 15 -5 30 3" stroke={INK} strokeWidth="7" fill="none" strokeLinecap="round" />
    </g>
  );

  /* --- arms --- */
  const arms =
    pose === "crossed" ? (
      <g>
        {/* crossed arms over chest */}
        <path d="M 96 330 q 20 34 84 30 q -8 26 -52 22 q -40 -6 -32 -52 z" fill={C.blue600} stroke={INK} strokeWidth="7" strokeLinejoin="round" />
        <path d="M 262 330 q -20 34 -84 30 q 8 26 52 22 q 40 -6 32 -52 z" fill={C.blue600} stroke={INK} strokeWidth="7" strokeLinejoin="round" />
        {/* fists */}
        <circle cx="128" cy="368" r="17" fill={C.skin} stroke={INK} strokeWidth="6" />
        <circle cx="230" cy="368" r="17" fill={C.skin} stroke={INK} strokeWidth="6" />
      </g>
    ) : (
      <g>
        {/* open, hands slightly raised — friendly */}
        <path d="M 100 322 q -34 24 -40 66" stroke={C.blue600} strokeWidth="30" fill="none" strokeLinecap="round" />
        <path d="M 258 322 q 34 24 40 66" stroke={C.blue600} strokeWidth="30" fill="none" strokeLinecap="round" />
        <path d="M 100 322 q -34 24 -40 66" stroke={INK} strokeWidth="42" fill="none" strokeLinecap="round" opacity="0" />
        <circle cx="58" cy="392" r="19" fill={C.skin} stroke={INK} strokeWidth="6" />
        <circle cx="300" cy="392" r="19" fill={C.skin} stroke={INK} strokeWidth="6" />
      </g>
    );

  return (
    <svg viewBox="0 0 360 520" style={{ width: "100%", height: "100%", display: "block", overflow: "visible" }}>
      {/* legs */}
      <g>
        <rect x="126" y="440" width="40" height="56" rx="14" fill={C.ink700} stroke={INK} strokeWidth="6" />
        <rect x="192" y="440" width="40" height="56" rx="14" fill={C.ink700} stroke={INK} strokeWidth="6" />
        <path d="M 116 496 h 58 a 8 8 0 0 1 8 8 v 6 h -74 v -6 a 8 8 0 0 1 8 -8 z" fill={INK} />
        <path d="M 184 496 h 58 a 8 8 0 0 1 8 8 v 6 h -74 v -6 a 8 8 0 0 1 8 -8 z" fill={INK} />
      </g>

      {/* body — blue Latzhose over orange shirt */}
      <g>
        <path d="M 96 290 q 83 -26 166 0 l 6 160 q -89 18 -178 0 z" fill={C.orange300} stroke={INK} strokeWidth="7" strokeLinejoin="round" />
        {/* Latzhose bib + trousers */}
        <path d="M 106 336 q 73 -20 146 0 l 4 114 q -77 16 -154 0 z" fill={C.blue} stroke={INK} strokeWidth="7" strokeLinejoin="round" />
        <rect x="138" y="300" width="82" height="72" rx="12" fill={C.blue} stroke={INK} strokeWidth="7" />
        {/* straps */}
        <path d="M 118 292 l 30 24" stroke={C.blue} strokeWidth="16" strokeLinecap="round" />
        <path d="M 240 292 l -30 24" stroke={C.blue} strokeWidth="16" strokeLinecap="round" />
        <circle cx="150" cy="314" r="7" fill={C.orange} stroke={INK} strokeWidth="5" />
        <circle cx="208" cy="314" r="7" fill={C.orange} stroke={INK} strokeWidth="5" />
        {/* bib pocket with pencil */}
        <rect x="158" y="328" width="42" height="30" rx="8" fill={C.blue600} stroke={INK} strokeWidth="5" />
        <rect x="170" y="318" width="8" height="22" rx="3" fill={C.orange} stroke={INK} strokeWidth="4" />
      </g>

      {arms}

      {/* head group (bobs) */}
      <g transform={`translate(0 ${headY})`}>
        {/* neck */}
        <rect x="160" y="252" width="38" height="34" rx="12" fill={C.skin} stroke={INK} strokeWidth="6" />
        {/* head — big, comic */}
        <path d="M 106 130 q 0 -74 73 -74 q 73 0 73 74 l 0 60 q 0 62 -73 62 q -73 0 -73 -62 z" fill={C.skin} stroke={INK} strokeWidth="7" />
        {/* ears */}
        <circle cx="103" cy="160" r="15" fill={C.skin} stroke={INK} strokeWidth="6" />
        <circle cx="255" cy="160" r="15" fill={C.skin} stroke={INK} strokeWidth="6" />
        {/* cheeks */}
        {!shocked && <circle cx="128" cy="146" r="9" fill={C.cheek} opacity="0.55" />}
        {!shocked && <circle cx="230" cy="146" r="9" fill={C.cheek} opacity="0.55" />}
        {/* moustache */}
        <path d="M 146 138 q 33 16 66 0 q -8 22 -33 22 q -25 0 -33 -22 z" fill="#B5772F" stroke={INK} strokeWidth="5" strokeLinejoin="round" transform="translate(0 4)" opacity="0" />
        {brows}
        {eyes}
        {/* nose — big friendly */}
        <ellipse cx="179" cy={shocked ? 148 : 136} rx="15" ry="12" fill={C.skinShade} stroke={INK} strokeWidth="6" />
        {mouth}
        {/* cap (Mütze) — blue with orange brim + E badge */}
        <g>
          <path d="M 104 106 q 0 -62 75 -62 q 75 0 75 62 l 0 6 q -75 -18 -150 0 z" fill={C.blue} stroke={INK} strokeWidth="7" strokeLinejoin="round" />
          <path d="M 96 108 q 83 -22 166 0 q 6 2 4 10 q -2 7 -10 6 q -77 -20 -154 0 q -8 1 -10 -6 q -2 -8 4 -10 z" fill={C.orange} stroke={INK} strokeWidth="6" strokeLinejoin="round" />
          <circle cx="179" cy="76" r="15" fill={C.white} stroke={INK} strokeWidth="5" />
          <text x="179" y="83" textAnchor="middle" fontFamily={GEIST} fontWeight="800" fontStyle="italic" fontSize="20" fill={C.blue}>E</text>
        </g>
        {/* sweat drops (comic) */}
        {sweat > 0 && (
          <g opacity={Math.min(1, sweat * 2)}>
            <SweatDrop x={92} y={86} p={sweat} dir={-1} delay={0} />
            <SweatDrop x={262} y={78} p={sweat} dir={1} delay={0.18} />
            <SweatDrop x={112} y={54} p={sweat} dir={-0.6} delay={0.34} />
            <SweatDrop x={248} y={110} p={sweat} dir={1.1} delay={0.5} />
          </g>
        )}
      </g>
    </svg>
  );
}

function SweatDrop({ x, y, p, dir, delay }) {
  const lp = clamp((p - delay) / 0.6, 0, 1);
  if (lp <= 0) return null;
  const fly = Easing.easeOutCubic(lp);
  const dx = dir * 46 * fly;
  const dy = -30 * fly + 26 * fly * fly;
  return (
    <g transform={`translate(${x + dx} ${y + dy}) scale(${0.7 + 0.5 * fly})`} opacity={1 - Math.max(0, lp - 0.7) / 0.3}>
      <path d="M 0 -12 q 9 12 9 19 a 9 9 0 1 1 -18 0 q 0 -7 9 -19 z" fill={C.blue300} stroke={INK} strokeWidth="4" />
    </g>
  );
}

/* ============================================================
   WERKSTATT — flat comic facade. Includes door + window w/ screen.
   Drawn 1200×1200 backdrop.
   screen: 'ok' | 'alarm' ; alarmT: 0..1 pulse driver
   ============================================================ */
function Werkstatt({ screen = "ok", alarmT = 0, doorSign = null }) {
  const alarmOn = screen === "alarm";
  const pulse = alarmOn ? 0.75 + 0.25 * Math.sin(alarmT * Math.PI * 6) : 0;
  return (
    <svg viewBox="0 0 1200 1200" style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }}>
      <g transform="translate(0 -64)">
      {/* sky */}
      <rect width="1200" height="1200" fill={C.sky} />
      <circle cx="985" cy="140" r="70" fill={C.orange100} stroke={INK} strokeWidth="7" />
      {/* clouds */}
      <g fill={C.white} stroke={INK} strokeWidth="6">
        <ellipse cx="240" cy="150" rx="86" ry="34" />
        <ellipse cx="320" cy="132" rx="60" ry="26" />
      </g>
      {/* ground */}
      <rect x="0" y="980" width="1200" height="340" fill={C.ink100} />
      <line x1="0" y1="980" x2="1200" y2="980" stroke={INK} strokeWidth="8" />

      {/* facade */}
      <g>
        <rect x="120" y="330" width="960" height="650" fill={C.paper} stroke={INK} strokeWidth="10" />
        {/* roof band */}
        <path d="M 90 330 h 1020 l -40 -90 h -940 z" fill={C.blue} stroke={INK} strokeWidth="10" strokeLinejoin="round" />
        {/* awning stripes over window */}
        <g>
          <path d="M 600 430 h 400 l 26 70 h -452 z" fill={C.orange} stroke={INK} strokeWidth="8" strokeLinejoin="round" />
          <path d="M 660 430 l 18 70 h 60 l -18 -70 z M 780 430 l 18 70 h 60 l -18 -70 z M 900 430 l 18 70 h 60 l -18 -70 z" fill={C.paper} stroke={INK} strokeWidth="6" />
        </g>
        {/* shop sign */}
        <g>
          <rect x="330" y="262" width="540" height="96" rx="18" fill={C.white} stroke={INK} strokeWidth="9" />
          <text x="600" y="327" textAnchor="middle" fontFamily={GEIST} fontWeight="800" fontStyle="italic" fontSize="58" letterSpacing="6" fill={INK}>WERKSTATT</text>
        </g>

        {/* window with desk + screen */}
        <g>
          <rect x="620" y="520" width="360" height="300" rx="10" fill={C.blue100} stroke={INK} strokeWidth="9" />
          {/* desk */}
          <rect x="640" y="740" width="320" height="18" fill={C.ink700} stroke={INK} strokeWidth="6" />
          {/* monitor */}
          <g>
            <rect x="700" y="580" width="200" height="140" rx="12" fill={alarmOn ? C.red : C.ink700} stroke={INK} strokeWidth="8" />
            {alarmOn ? (
              <g opacity={0.9 + 0.1 * pulse}>
                {/* lock icon */}
                <g transform={`translate(800 650) scale(${1 + 0.08 * pulse})`}>
                  <rect x="-30" y="-8" width="60" height="46" rx="10" fill={C.white} stroke={INK} strokeWidth="6" />
                  <path d="M -18 -8 v -12 a 18 18 0 0 1 36 0 v 12" fill="none" stroke={C.white} strokeWidth="9" />
                  <circle cx="0" cy="12" r="7" fill={C.red600} />
                  <rect x="-3" y="12" width="6" height="14" rx="3" fill={C.red600} />
                </g>
              </g>
            ) : (
              <g stroke={C.blue300} strokeWidth="7" strokeLinecap="round">
                <line x1="724" y1="612" x2="836" y2="612" />
                <line x1="724" y1="640" x2="868" y2="640" />
                <line x1="724" y1="668" x2="820" y2="668" />
              </g>
            )}
            <rect x="780" y="720" width="40" height="16" fill={C.ink700} stroke={INK} strokeWidth="6" />
          </g>
          {/* window frame bar */}
          <line x1="620" y1="520" x2="980" y2="520" stroke={INK} strokeWidth="9" />
        </g>

        {/* door */}
        <g>
          <rect x="230" y="560" width="270" height="420" rx="14" fill={C.blue} stroke={INK} strokeWidth="10" />
          <rect x="262" y="600" width="206" height="150" rx="10" fill={C.blue100} stroke={INK} strokeWidth="8" />
          <circle cx="462" cy="800" r="12" fill={C.orange} stroke={INK} strokeWidth="6" />
          {doorSign}
        </g>
      </g>
      </g>
    </svg>
  );
}

/* ---------- speech bubble ---------- */
function SpeechBubble({ x, y, w, pop, text, sub }) {
  const s = Easing.easeOutBack(clamp(pop, 0, 1));
  return (
    <div style={{ position: "absolute", left: x, top: y, width: w, transform: `scale(${s})`, transformOrigin: "20% 100%", opacity: clamp(pop * 2, 0, 1) }}>
      <div style={{ position: "relative", background: C.white, border: `7px solid ${INK}`, borderRadius: 36, padding: "30px 40px", boxShadow: "0 12px 0 rgba(12,14,19,0.12)" }}>
        <div style={{ fontFamily: GEIST, fontWeight: 800, fontStyle: "italic", fontSize: 56, lineHeight: 1.08, letterSpacing: "-0.02em", color: INK, textWrap: "balance" }}>{text}</div>
        {sub}
        <svg viewBox="0 0 60 52" style={{ position: "absolute", left: 64, bottom: -46, width: 60, height: 52 }}>
          <path d="M 6 2 q 10 30 42 46 q -30 2 -46 -14 z" fill={C.white} stroke={INK} strokeWidth="7" strokeLinejoin="round" />
          <rect x="2" y="-4" width="56" height="10" fill={C.white} />
        </svg>
      </div>
    </div>
  );
}

/* ---------- EIPME shield ---------- */
function Shield({ pop }) {
  const s = Easing.easeOutBack(clamp(pop, 0, 1));
  return (
    <svg viewBox="0 0 240 280" style={{ width: "100%", height: "100%", transform: `scale(${s})`, transformOrigin: "50% 60%", opacity: clamp(pop * 2, 0, 1), overflow: "visible", display: "block" }}>
      <defs>
        <linearGradient id="eip-shield-grad" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0" stopColor="#1F5EFF" />
          <stop offset="1" stopColor="#FF7A1A" />
        </linearGradient>
      </defs>
      <path d="M 120 12 q 54 30 96 34 q 6 96 -30 156 q -28 48 -66 66 q -38 -18 -66 -66 q -36 -60 -30 -156 q 42 -4 96 -34 z" fill="url(#eip-shield-grad)" stroke={INK} strokeWidth="9" strokeLinejoin="round" />
      <path d="M 120 34 q 42 22 74 27 q 3 78 -25 126 q -22 38 -49 53 q -27 -15 -49 -53 q -28 -48 -25 -126 q 32 -5 74 -27 z" fill="rgba(255,255,255,0.16)" />
      <path d="M 82 140 l 28 30 l 52 -58" fill="none" stroke={C.white} strokeWidth="18" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

/* ---------- EIPME logo lockup (symbol svg + Geist wordmark) ---------- */
function LogoLockup({ size = 64 }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: size * 0.32, justifyContent: "center" }}>
      <img src="../assets/eipme-symbol.svg" alt="EIPME" style={{ height: size, display: "block" }} />
      <div style={{ fontFamily: GEIST, fontWeight: 800, fontStyle: "italic", fontSize: size * 0.82, letterSpacing: "0.005em", color: INK, lineHeight: 1 }}>EIPME</div>
    </div>
  );
}

/* ============================================================
   SCENES
   ============================================================ */
const T1 = 0, T1E = 3.4;          // Szene 1
const T2 = 3.4, T2E = 6.6;        // Szene 2
const T3 = 6.6, T3E = 11.0;       // Szene 3 (+2s für Statistiken)
const T4 = 11.0, DUR = 13.6;      // Szene 4

/* camera helper: returns transform for the 1200×1200 world */
function useCam(segs) {
  const t = useTime();
  const sc = interpolate(segs.t, segs.scale, Easing.easeInOutCubic)(t);
  const cx = interpolate(segs.t, segs.x, Easing.easeInOutCubic)(t);
  const cy = interpolate(segs.t, segs.y, Easing.easeInOutCubic)(t);
  return { transform: `scale(${sc}) translate(${-cx}px, ${-cy}px)`, transformOrigin: "600px 600px" };
}

function SceneWorkshop() {
  const t = useTime();
  const local1 = t - T1;
  const inS2 = t >= T2;
  const local2 = Math.max(0, t - T2);

  // camera: S1 slow push-in on character; S2 whip to the window/screen, then pull to face
  const cam = useCam({
    t: [0, 3.0, T2, T2 + 0.55, T2 + 1.7, T2 + 2.2, T2E],
    scale: [1.0, 1.12, 1.12, 1.85, 1.85, 1.45, 1.42],
    x: [0, 30, 30, 195, 195, 60, 55],
    y: [0, 40, 40, -9, -9, 41, 41],
  });

  // character states
  const wink = local1 > 2.1 && local1 < 2.75;
  const blink = local1 > 1.1 && local1 < 1.28 ? 1 : 0;
  const shockStart = T2 + 0.9;
  const shocked = t >= shockStart;
  const sweat = clamp((t - shockStart - 0.15) / 1.1, 0, 1);
  const bob = Math.sin(t * 2.1) * 4 + (shocked ? -6 * Easing.easeOutBack(clamp((t - shockStart) / 0.4, 0, 1)) : 0);
  const jitter = shocked ? Math.sin(t * 26) * 2.4 * clamp(1 - (t - shockStart) / 2.4, 0.25, 1) : 0;

  // alarm flash overlay on whole frame
  const alarmFlash = inS2 ? 0.10 + 0.08 * Math.sin(local2 * Math.PI * 5) : 0;
  const alarmRamp = clamp((t - (T2 + 0.35)) / 0.25, 0, 1);

  const bubblePop = clamp(local1 / 0.55, 0, 1) * (t < T2 - 0.25 ? 1 : clamp((T2 - t) / 0.25, 0, 1));

  // exclamation "!" pop over head in S2
  const bangPop = Easing.easeOutBack(clamp((t - shockStart) / 0.35, 0, 1));

  return (
    <div style={{ position: "absolute", inset: 0, overflow: "hidden" }}>
      <div style={{ position: "absolute", inset: 0, ...cam }}>
        <Werkstatt screen={t >= T2 + 0.35 ? "alarm" : "ok"} alarmT={local2} />

        {/* character standing in front, left of door */}
        <div style={{ position: "absolute", left: 300, top: 496, width: 330, height: 477, transform: `translate(${jitter}px, 0)` }}>
          <Handwerker
            expression={shocked ? "shock" : wink ? "wink" : "grin"}
            pose="crossed"
            sweat={shocked ? Math.max(sweat, 0.01) : 0}
            bob={bob}
            blink={blink}
          />
        </div>

        {/* speech bubble S1 */}
        {t < T2 && (
          <SpeechBubble x={430} y={266} w={520} pop={bubblePop} text={"Uns passiert das nicht!"} />
        )}

        {/* shock "!" S2 */}
        {shocked && t < T2E - 0.1 && (
          <div style={{ position: "absolute", left: 560, top: 406, transform: `scale(${bangPop})`, transformOrigin: "50% 100%" }}>
            <svg viewBox="0 0 90 110" style={{ width: 84, height: 104, overflow: "visible" }}>
              <path d="M 32 8 h 26 l -7 62 h -12 z" fill={C.red} stroke={INK} strokeWidth="7" strokeLinejoin="round" />
              <circle cx="45" cy="94" r="11" fill={C.red} stroke={INK} strokeWidth="7" />
            </svg>
          </div>
        )}
      </div>

      {/* red alarm wash */}
      {inS2 && (
        <div style={{ position: "absolute", inset: 0, background: C.red, opacity: alarmFlash * alarmRamp, pointerEvents: "none" }} />
      )}
      {/* red vignette in S2 */}
      {inS2 && (
        <div style={{ position: "absolute", inset: 0, boxShadow: `inset 0 0 220px rgba(229,31,45,${0.55 * alarmRamp})`, pointerEvents: "none" }} />
      )}
    </div>
  );
}

/* Szene 3 — Tür + Schild "Heute geschlossen" + Zahlen */
function SceneClosed() {
  const { localTime: lt } = useSprite();
  // camera: tight on door
  const sc = interpolate([0, 4.4], [1.9, 2.02], Easing.easeInOutCubic)(lt);
  // sign drops + swings
  const drop = Easing.easeOutBounce ? Easing.easeOutBounce(clamp(lt / 0.8, 0, 1)) : Easing.easeOutBack(clamp(lt / 0.7, 0, 1));
  const dropY = -520 + 520 * drop;
  const swing = Math.sin(Math.max(0, lt - 0.75) * 4.2) * 7 * Math.exp(-Math.max(0, lt - 0.75) * 1.6);
  const statsIn = Easing.easeOutCubic(clamp((lt - 0.95) / 0.4, 0, 1));
  const statsPop = Easing.easeOutBack(clamp((lt - 0.95) / 0.55, 0, 1));
  const countP = Easing.easeOutCubic(clamp((lt - 1.0) / 1.5, 0, 1));

  const doorSign = (
    <g transform={`translate(365 ${790 + dropY})`}>
      <g transform={`rotate(${swing})`}>
        <line x1="0" y1="-56" x2="0" y2="-18" stroke={INK} strokeWidth="7" />
        <circle cx="0" cy="-56" r="8" fill={C.ink500} stroke={INK} strokeWidth="5" />
        <g transform="rotate(-2)">
          <rect x="-150" y="-18" width="300" height="110" rx="14" fill={C.white} stroke={INK} strokeWidth="8" />
          <text x="0" y="28" textAnchor="middle" fontFamily={GEIST} fontWeight="800" fontStyle="italic" fontSize="40" fill={C.red600}>Heute</text>
          <text x="0" y="72" textAnchor="middle" fontFamily={GEIST} fontWeight="800" fontStyle="italic" fontSize="40" fill={C.red600}>geschlossen</text>
        </g>
      </g>
    </g>
  );

  return (
    <div style={{ position: "absolute", inset: 0, overflow: "hidden" }}>
      <div style={{ position: "absolute", inset: 0, transform: `scale(${sc}) translate(215px, -106px)`, transformOrigin: "600px 600px" }}>
        <Werkstatt screen="alarm" alarmT={lt} doorSign={doorSign} />
      </div>
      {/* dim + stats */}
      <div style={{ position: "absolute", inset: 0, background: "rgba(12,14,19,0.55)", opacity: statsIn, pointerEvents: "none" }} />
      <div style={{ position: "absolute", left: 0, right: 0, bottom: 170, display: "flex", justifyContent: "center", opacity: statsIn, transform: `translateY(${24 * (1 - statsIn)}px) scale(${0.7 + 0.3 * statsPop})`, transformOrigin: "50% 100%" }}>
        <div style={{ display: "flex", flexDirection: "column", gap: 22, alignItems: "center" }}>
          <div style={{ display: "flex", gap: 24 }}>
            <StatChip value={87} label="betroffen" p={countP} />
            <StatChip value={59} label="Existenz bedroht" p={countP} />
          </div>
          <div style={{ fontFamily: MONO, fontWeight: 500, fontSize: 22, letterSpacing: "0.18em", textTransform: "uppercase", color: "rgba(255,255,255,0.9)" }}>Quelle · Bitkom 2025</div>
        </div>
      </div>
    </div>
  );
}

function StatChip({ value, label, p }) {
  const shown = Math.round(value * p);
  return (
    <div style={{ background: "rgba(16,19,25,0.88)", border: "1.5px solid rgba(255,255,255,0.22)", borderRadius: 24, padding: "28px 40px", display: "flex", alignItems: "baseline", gap: 16, whiteSpace: "nowrap", boxShadow: "0 1px 0 rgba(255,255,255,0.15) inset, 0 20px 50px -12px rgba(0,0,0,0.5)" }}>
      <div style={{ fontFamily: GEIST, fontWeight: 800, fontStyle: "italic", fontSize: 88, color: C.white, lineHeight: 1, fontVariantNumeric: "tabular-nums", minWidth: "2.4ch", textAlign: "right" }}>{shown} %</div>
      <div style={{ fontFamily: MONO, fontWeight: 500, fontSize: 24, letterSpacing: "0.14em", textTransform: "uppercase", color: C.red100 }}>{label}</div>
    </div>
  );
}

/* Szene 4 — hell, freundlich: Handwerker + Schild + Frage + Logo */
function SceneFinal() {
  const { localTime: lt } = useSprite();
  const inWipe = Easing.easeOutCubic(clamp(lt / 0.5, 0, 1));
  const charIn = Easing.easeOutBack(clamp((lt - 0.15) / 0.5, 0, 1));
  const shieldPop = clamp((lt - 0.5) / 0.5, 0, 1);
  const textIn = Easing.easeOutCubic(clamp((lt - 0.85) / 0.5, 0, 1));
  const logoIn = Easing.easeOutCubic(clamp((lt - 1.3) / 0.5, 0, 1));  const bob = Math.sin(lt * 2.2) * 4;
  const blink = (lt % 2.6) > 2.44 ? 1 : 0;
  const breathe = 1 + 0.006 * Math.sin(lt * 1.6);

  return (
    <div style={{ position: "absolute", inset: 0, overflow: "hidden", background: C.paper }}>
      {/* soft blue arc backdrop */}
      <div style={{ position: "absolute", inset: 0, background: `radial-gradient(circle at 50% 118%, ${C.blue100} 0%, ${C.blue50} 46%, ${C.paper} 74%)`, transform: `scale(${breathe})` }} />
      {/* circular wipe reveal */}
      <div style={{ position: "absolute", inset: 0, clipPath: `circle(${inWipe * 92}% at 50% 58%)` }}>
        <div style={{ position: "absolute", inset: 0 }}>
          {/* character bottom-left */}
          <div style={{ position: "absolute", left: 120, bottom: 150, width: 320, height: 462, transform: `scale(${charIn})`, transformOrigin: "50% 100%" }}>
            <Handwerker expression="smile" pose="crossed" bob={bob} blink={blink} />
          </div>
          {/* shield next to him */}
          <div style={{ position: "absolute", left: 400, bottom: 205, width: 216, height: 252 }}>
            <Shield pop={shieldPop} />
          </div>
          {/* headline + logo right block */}
          <div style={{ position: "absolute", left: 646, right: 70, top: 240, display: "flex", flexDirection: "column", gap: 44 }}>
            <div style={{ opacity: textIn, transform: `translateY(${26 * (1 - textIn)}px)`, fontFamily: GEIST, fontWeight: 800, fontStyle: "italic", fontSize: 92, lineHeight: 1.02, letterSpacing: "-0.03em", color: INK, textWrap: "balance" }}>
              Ist es Ihnen das wert?
            </div>
            <div style={{ opacity: logoIn, transform: `translateY(${18 * (1 - logoIn)}px)`, display: "flex", flexDirection: "column", gap: 18 }}>
              <div style={{ height: 5, width: 130, background: `linear-gradient(90deg, ${C.blue}, ${C.orange})`, borderRadius: 999 }} />
              <LogoLockup size={72} />
              <div style={{ fontFamily: MONO, fontWeight: 500, fontSize: 17, letterSpacing: "0.16em", textTransform: "uppercase", color: C.ink500, whiteSpace: "nowrap" }}>IT-Sicherheit für den Mittelstand</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============================================================ */
function HandwerkerSpot() {
  // stamp timestamp label for comments
  const ref = R.useRef(null);
  return (
    <div ref={ref} style={{ width: "100%", height: "100%" }}>
      <Stage width={1200} height={1200} duration={DUR} background={C.sky} autoplay loop>
        <TimestampLabel rootRef={ref} />
        <Sprite start={T1} end={T2E}><SceneWorkshop /></Sprite>
        <Sprite start={T3} end={T3E}><SceneClosed /></Sprite>
        <Sprite start={T4} end={DUR}><SceneFinal /></Sprite>
      </Stage>
    </div>
  );
}

function TimestampLabel({ rootRef }) {
  const t = useTime();
  const sec = Math.floor(t);
  R.useEffect(() => {
    const el = rootRef.current && rootRef.current.querySelector("[data-om-exportable-video-with-duration-secs]");
    (el || rootRef.current) && (el || rootRef.current).setAttribute("data-screen-label", "t=" + sec + "s");
  }, [sec]);
  return null;
}

window.HandwerkerSpot = HandwerkerSpot;
