/* modul-video-scenes.jsx — databites Modul-Video (insights · match · flow · daily)
   Reads timeline globals from window (set by animations.jsx). Exposes window.ModulVideo. */

(function () {
  const R = React;

  // ---- module accents --------------------------------------------------
  const ACC = { insights: '#c3e48b', match: '#f87666', flow: '#ddb771', daily: '#5899e2' };

  // ---- look presets (the "options") ------------------------------------
  const LOOKS = {
    studio: { label: 'Studio', bg: '#223539', fg: '#f4efe6', muted: 'rgba(244,239,230,0.60)',
      frame: true, chrome: '#e7eeec', chromeDot: '#b8c6c4', glow: 0.24, logo: 'light', shotBg: '#e7eeec' },
    kino: { label: 'Kino', bg: '#0b1315', fg: '#f4efe6', muted: 'rgba(244,239,230,0.58)',
      frame: false, chrome: '#0f1a1d', chromeDot: '#2a3b3f', glow: 0.34, logo: 'light', shotBg: '#dbe3e1' },
    hell: { label: 'Hell', bg: '#f4efe6', fg: '#223539', muted: '#5b6b78',
      frame: true, chrome: '#ffffff', chromeDot: '#cdd6dd', glow: 0.16, logo: 'dark', shotBg: '#eef2f5' },
  };

  // ---- timeline (seconds) ---------------------------------------------
  const DUR = 240;
  const MODS = [
    {
      key: 'insights', name: 'insights', acc: ACC.insights, seg: [12, 64],
      kicker: 'Klare Zahlen',
      claim: 'Alle Zahlen.<br>Ein <em>Blick.</em>',
      does: 'insights führt die Kennzahlen aller Filialen an einem Ort zusammen. In Echtzeit, ohne Suchen.',
      heute: 'Zahlen <em>suchen</em>',
      fix: 'Zahlen <em>verstehen</em>',
      payoff: 'Damit du <em>entscheidest</em>,<br>statt zu suchen.',
    },
    {
      key: 'match', name: 'match', acc: ACC.match, seg: [64, 116],
      kicker: 'Starke Teams',
      claim: 'Menschen finden.<br>Menschen <em>halten.</em>',
      does: 'match begleitet den ganzen Weg. Vom ersten Bedarf über die Einarbeitung bis in die Personalakte.',
      heute: '<em>Aktenchaos</em>',
      fix: 'Ein <em>roter Faden</em>',
      payoff: 'Damit dein Team<br><em>zusammenbleibt.</em>',
    },
    {
      key: 'flow', name: 'flow', acc: ACC.flow, seg: [116, 168],
      kicker: 'Runder Warenfluss',
      claim: 'Vom Rezept<br>zur <em>Liefertreue.</em>',
      does: 'flow bringt Sortiment, Produktion und Warenfluss in einen Takt. Sauber geplant, Tag für Tag.',
      heute: 'Ware <em>fehlt</em>',
      fix: 'Alles <em>greift ineinander</em>',
      payoff: 'Damit ankommt,<br>was <em>gebacken</em> wird.',
    },
    {
      key: 'daily', name: 'daily', acc: ACC.daily, seg: [168, 220],
      kicker: 'Ruhiger Filialtag',
      claim: 'Der ganze Tag.<br>An <em>einem Ort.</em>',
      does: 'daily bündelt den Filialalltag. Aufgaben, Kommunikation und Tagesabschluss, klar an einer Stelle.',
      heute: 'Zettel <em>und Chaos</em>',
      fix: 'Ein klarer <em>Rahmen</em>',
      payoff: 'Damit abends<br><em>alle</em> Bescheid wissen.',
    },
  ];
  const INTRO = [0, 12];
  const OUTRO = [220, 240];

  // ---- helpers ---------------------------------------------------------
  function ip(kf, vals, ease) { return window.interpolate(kf, vals, ease); }
  const easeOut = () => window.Easing.easeOutCubic;
  const easeBack = () => window.Easing.easeOutBack;
  function capLabel(c) {
    return {
      fontFamily: "'JetBrains Mono', monospace", fontSize: 18, fontWeight: 700,
      letterSpacing: '0.18em', textTransform: 'uppercase', color: c,
    };
  }

  function Html({ html, style, className }) {
    return R.createElement('div', { className, style, dangerouslySetInnerHTML: { __html: html } });
  }

  function Glow({ acc, alpha }) {
    return R.createElement('div', {
      style: {
        position: 'absolute', inset: 0, zIndex: 0, pointerEvents: 'none',
        background:
          'radial-gradient(ellipse 62% 46% at 100% -6%, ' + hexA(acc, alpha) + ', transparent 60%)' +
          ', radial-gradient(ellipse 50% 40% at -8% 108%, ' + hexA(acc, alpha * 0.6) + ', transparent 62%)',
      },
    });
  }

  function BrandDots({ acc, size, gap }) {
    const d = { width: size, height: size, borderRadius: '50%', background: acc, display: 'block' };
    const cell = { display: 'grid', gridTemplateColumns: size + 'px ' + size + 'px', gap: gap + 'px' };
    return R.createElement('div', { style: cell },
      R.createElement('span', { style: d }), R.createElement('span', { style: d }),
      R.createElement('span', { style: d }), R.createElement('span', { style: d }));
  }

  function hexA(hex, a) {
    const h = hex.replace('#', '');
    const r = parseInt(h.slice(0, 2), 16), g = parseInt(h.slice(2, 4), 16), b = parseInt(h.slice(4, 6), 16);
    return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
  }

  // ---- module pill -----------------------------------------------------
  function Pill({ mod, L, o, dx }) {
    return R.createElement('div', {
      style: {
        display: 'inline-flex', alignItems: 'center', gap: 15, padding: '13px 28px 13px 22px',
        borderRadius: 999, fontSize: 30, fontWeight: 700, letterSpacing: '0.01em',
        color: L.logo === 'dark' ? '#223539' : mod.acc,
        background: hexA(mod.acc, L.logo === 'dark' ? 0.18 : 0.16),
        border: '1px solid ' + hexA(mod.acc, 0.5),
        opacity: o, transform: 'translateX(' + dx + 'px)',
      },
    },
      R.createElement('span', { style: { width: 16, height: 16, borderRadius: 999, background: mod.acc } }),
      mod.name);
  }

  // ---- native app mock (no screenshots) -------------------------------
  const ICONS = {
    euro: 'M15 8a4 4 0 1 0 0 8M6 10h6M6 14h6',
    users: 'M8 11a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM3 19a5 5 0 0 1 10 0M16 6a3 3 0 0 1 0 6M18 19a5 5 0 0 0-3-4.6',
    cart: 'M4 5h2l2 10h9l2-7H7M9 19a1 1 0 1 0 .01 0M17 19a1 1 0 1 0 .01 0',
    pulse: 'M3 12h4l2-6 4 12 2-6h6',
    briefcase: 'M4 8h16v11H4zM9 8V6a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2',
    clock: 'M12 12l3 2M12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16z',
    check: 'M4 12l5 5L20 6',
    truck: 'M3 7h11v9H3zM14 10h4l3 3v3h-7M7 19a2 2 0 1 0 .01 0M17 19a2 2 0 1 0 .01 0',
    box: 'M12 3l8 4-8 4-8-4 8-4zM4 7v9l8 4 8-4V7',
    gauge: 'M5 18a8 8 0 1 1 14 0M12 14l4-4',
    list: 'M8 6h12M8 12h12M8 18h12M4 6h.01M4 12h.01M4 18h.01',
    doc: 'M6 3h8l4 4v14H6zM14 3v4h4',
    feed: 'M5 5a14 14 0 0 1 14 14M5 12a7 7 0 0 1 7 7M6 18a1 1 0 1 0 .01 0',
  };
  function Icon({ name, color }) {
    return R.createElement('svg', { width: 22, height: 22, viewBox: '0 0 24 24', fill: 'none',
      stroke: color, strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
      R.createElement('path', { d: ICONS[name] || ICONS.list }));
  }
  function sparkPath(vals, w, h) {
    const n = vals.length, pad = 3;
    const step = (w - pad * 2) / (n - 1);
    return vals.map((v, i) => {
      const x = pad + i * step, y = pad + (1 - v) * (h - pad * 2);
      return (i ? 'L' : 'M') + x.toFixed(1) + ' ' + y.toFixed(1);
    }).join(' ');
  }
  function fmtVal(v, tile) {
    if (tile.fmt === 'eur') return v.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' €';
    if (tile.fmt === 'eurh') return v.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' €/h';
    if (tile.fmt === 'pct') return v.toFixed(2).replace('.', ',') + ' %';
    if (tile.fmt === 'dec') return v.toFixed(2).replace('.', ',');
    if (tile.unit) return Math.round(v).toLocaleString('de-DE') + ' ' + tile.unit;
    return Math.round(v).toLocaleString('de-DE');
  }
  const MI = { bg: '#eef2f1', card: '#ffffff', fg: '#223539', sub: '#8a98a0', line: '#e6ecea',
    chipUpBg: '#e7f2d6', chipUpFg: '#5f7d33', chipDnBg: '#fbe2dd', chipDnFg: '#c0432f', iconBg: '#f1f5f3' };

  function ScoreTile({ tile, acc, t, start }) {
    const cp = ip([start, start + 1.3], [0, 1], easeOut())(t);
    const val = tile.value * cp;
    const chipO = ip([start + 0.8, start + 1.5], [0, 1])(t);
    const draw = ip([start + 0.4, start + 1.6], [0, 1], easeOut())(t);
    const up = tile.up;
    return R.createElement('div', {
      style: { background: MI.card, border: '1px solid ' + MI.line, borderRadius: 14,
        padding: '16px 18px', position: 'relative', overflow: 'hidden' },
    },
      R.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 } },
        R.createElement('div', { style: { width: 34, height: 34, borderRadius: 9, background: MI.iconBg,
          display: 'flex', alignItems: 'center', justifyContent: 'center' } },
          R.createElement(Icon, { name: tile.icon, color: '#5f6f74' })),
        R.createElement('div', { style: { fontSize: 17, fontWeight: 700, color: MI.fg } }, tile.label)),
      R.createElement('div', { style: { fontSize: 34, fontWeight: 800, color: MI.fg, letterSpacing: '-0.02em',
        fontVariantNumeric: 'tabular-nums' } }, fmtVal(val, tile)),
      tile.sub ? R.createElement('div', { style: { fontSize: 15, color: MI.sub, marginTop: 6, opacity: chipO } }, tile.sub) : null,
      R.createElement('div', { style: { marginTop: 10, opacity: chipO } },
        R.createElement('span', { style: { fontSize: 13, fontWeight: 700, padding: '4px 10px', borderRadius: 999,
          background: up ? MI.chipUpBg : MI.chipDnBg, color: up ? MI.chipUpFg : MI.chipDnFg } }, tile.chip)),
      R.createElement('svg', { width: 96, height: 40, viewBox: '0 0 96 40',
        style: { position: 'absolute', right: 16, bottom: 16, overflow: 'visible' } },
        R.createElement('path', { d: sparkPath(tile.spark, 96, 40), fill: 'none', stroke: acc,
          strokeWidth: 2.4, strokeLinecap: 'round', strokeLinejoin: 'round',
          pathLength: 1, strokeDasharray: 1, strokeDashoffset: 1 - draw })));
  }

  // ---- score ring ------------------------------------------------------
  function scoreColor(sc) { return sc >= 7 ? '#4a9d5b' : sc >= 4 ? '#e0a63a' : '#d9564a'; }
  const BAR = { g: '#7cc67c', y: '#e8b84b', r: '#e5654e' };
  function ScoreRing({ score, size, draw }) {
    const r = size / 2 - 3, C = 2 * Math.PI * r, col = scoreColor(score);
    return R.createElement('svg', { width: size, height: size, viewBox: '0 0 ' + size + ' ' + size },
      R.createElement('circle', { cx: size / 2, cy: size / 2, r, fill: 'none', stroke: '#e9efec', strokeWidth: 3 }),
      R.createElement('circle', { cx: size / 2, cy: size / 2, r, fill: 'none', stroke: col, strokeWidth: 3,
        strokeLinecap: 'round', strokeDasharray: C, strokeDashoffset: C * (1 - (score / 10) * draw),
        transform: 'rotate(-90 ' + size / 2 + ' ' + size / 2 + ')' }),
      R.createElement('text', { x: '50%', y: '50%', dy: '0.35em', textAnchor: 'middle',
        fontSize: size * 0.42, fontWeight: 800, fill: '#3a4a50', fontFamily: "'Montserrat', sans-serif" }, score));
  }

  function ScoreView({ mod, t }) {
    const s = mod.seg[0];
    const m = mod.mock;
    return R.createElement('div', { style: { flex: 1, display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 16 } },
      m.cols.map((col, ci) => R.createElement('div', { key: ci, style: { display: 'flex', flexDirection: 'column', gap: 10 } },
        // column header
        (function () {
          const hs = s + 2.4 + ci * 0.3;
          const o = ip([hs, hs + 0.7], [0, 1], easeOut())(t);
          const draw = ip([hs + 0.2, hs + 1.1], [0, 1], easeOut())(t);
          return R.createElement('div', { key: 'h', style: { display: 'flex', alignItems: 'center', gap: 8,
            paddingBottom: 8, borderBottom: '1px solid ' + MI.line, opacity: o } },
            R.createElement(Icon, { name: col.icon, color: '#5f6f74' }),
            R.createElement('div', { style: { fontSize: 16, fontWeight: 800, color: MI.fg, flex: 1 } }, col.name),
            R.createElement(ScoreRing, { score: col.score, size: 30, draw }));
        })(),
        // cards
        col.cards.map((card, ki) => {
          const cs = s + 3.0 + (ki * 3 + ci) * 0.16;
          const o = ip([cs, cs + 0.6], [0, 1], easeOut())(t);
          const y = ip([cs, cs + 0.6], [12, 0], easeOut())(t);
          const draw = ip([cs + 0.2, cs + 1.0], [0, 1], easeOut())(t);
          const bw = ip([cs + 0.3, cs + 0.9], [0, 1], easeOut())(t);
          return R.createElement('div', { key: ki, style: { background: MI.card, border: '1px solid ' + MI.line,
            borderRadius: 12, padding: '12px 14px', opacity: o, transform: 'translateY(' + y + 'px)' } },
            R.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 } },
              R.createElement(Icon, { name: card.icon, color: '#839196' }),
              R.createElement('div', { style: { fontSize: 13, fontWeight: 800, letterSpacing: '0.03em',
                textTransform: 'uppercase', color: '#4a5a60', flex: 1 } }, card.label),
              R.createElement(ScoreRing, { score: card.score, size: 26, draw })),
            R.createElement('div', { style: { display: 'flex', gap: 6 } },
              card.bars.map((b, bi) => R.createElement('div', { key: bi, style: { flex: 1, height: 8, borderRadius: 4,
                background: BAR[b], transformOrigin: 'left', transform: 'scaleX(' + bw + ')' } }))));
        }))));
  }

  // ---- pipeline view ---------------------------------------------------
  function PipelineView({ mod, t }) {
    const s = mod.seg[0];
    const m = mod.mock;
    const trackW = ip([s + 3.2, s + 4.6], [0, 1], easeOut())(t);
    return R.createElement('div', { style: { flex: 1, display: 'flex', flexDirection: 'column' } },
      // stat strip
      R.createElement('div', { style: { display: 'flex', gap: 30, marginBottom: 8 } },
        m.stats.map((st, i) => {
          const o = ip([s + 2.4 + i * 0.25, s + 3.0 + i * 0.25], [0, 1], easeOut())(t);
          return R.createElement('div', { key: i, style: { display: 'flex', alignItems: 'baseline', gap: 8, opacity: o } },
            R.createElement('span', { style: { fontSize: 30, fontWeight: 800, color: st.c, fontVariantNumeric: 'tabular-nums' } }, st.n),
            R.createElement('span', { style: { fontSize: 15, fontWeight: 600, color: MI.sub } }, st.label));
        })),
      // pipeline
      R.createElement('div', { style: { flex: 1, position: 'relative', display: 'flex', alignItems: 'center' } },
        R.createElement('div', { style: { position: 'absolute', left: '7%', right: '7%', top: '50%', height: 3,
          background: 'linear-gradient(90deg,#5899e2,#e0a63a,#3fae9a,#8b7bd8,#6fae5a,#6d78d6,#e08a3a)',
          borderRadius: 2, transformOrigin: 'left', transform: 'translateY(-14px) scaleX(' + trackW + ')' } }),
        R.createElement('div', { style: { position: 'relative', flex: 1, display: 'flex', justifyContent: 'space-between' } },
          m.stages.map((st, i) => {
            const ns = s + 3.0 + i * 0.32;
            const o = ip([ns, ns + 0.5], [0, 1], easeOut())(t);
            const sc = ip([ns, ns + 0.5], [0.4, 1], easeBack())(t);
            const cnt = ip([ns + 0.2, ns + 1.0], [0, 1], easeOut())(t);
            return R.createElement('div', { key: i, style: { width: 96, display: 'flex', flexDirection: 'column',
              alignItems: 'center', gap: 8, opacity: o } },
              R.createElement('div', { style: { width: 52, height: 52, borderRadius: 999, background: MI.card,
                border: '3px solid ' + st.c, display: 'flex', alignItems: 'center', justifyContent: 'center',
                transform: 'scale(' + sc + ')', boxShadow: '0 4px 12px ' + hexA(st.c, 0.25),
                fontSize: 22, fontWeight: 800, color: st.c, fontVariantNumeric: 'tabular-nums' } },
                Math.round(st.n * cnt)),
              R.createElement('div', { style: { fontSize: 12, fontWeight: 700, color: '#4a5a60', textAlign: 'center',
                lineHeight: 1.2, height: 30 } }, st.name));
          }))));
  }

  // ---- feed view -------------------------------------------------------
  function FeedView({ mod, t }) {
    const s = mod.seg[0];
    const m = mod.mock;
    const p = m.post;
    const imgO = ip([s + 3.0, s + 4.0], [0, 1], easeOut())(t);
    const imgSc = ip([s + 3.0, s + 4.2], [0.94, 1], easeOut())(t);
    const titleO = ip([s + 3.4, s + 4.2], [0, 1], easeOut())(t);
    const metaO = ip([s + 3.8, s + 4.6], [0, 1], easeOut())(t);
    const textO = ip([s + 4.4, s + 5.4], [0, 1], easeOut())(t);
    return R.createElement('div', { style: { flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 } },
      // category chips
      R.createElement('div', { style: { display: 'flex', gap: 8, marginBottom: 16, flexWrap: 'wrap' } },
        m.chips.map((c, i) => {
          const o = ip([s + 2.4 + i * 0.12, s + 2.9 + i * 0.12], [0, 1], easeOut())(t);
          return R.createElement('span', { key: i, style: { fontSize: 13, fontWeight: 700, padding: '6px 14px',
            borderRadius: 999, opacity: o,
            color: c.active ? '#fff' : c.c, background: c.active ? c.c : hexA(c.c, 0.10),
            border: '1px solid ' + (c.active ? c.c : hexA(c.c, 0.35)) } }, c.name);
        })),
      // post card
      R.createElement('div', { style: { flex: 1, display: 'flex', gap: 20, background: MI.card,
        border: '1px solid ' + MI.line, borderRadius: 14, padding: 18, minHeight: 0 } },
        R.createElement('div', { style: { flex: '0 0 320px', borderRadius: 10, overflow: 'hidden',
          opacity: imgO, transform: 'scale(' + imgSc + ')', background: '#e7ece9' } },
          R.createElement('image-slot', { id: 'modvid-daily-feed', placeholder: 'Team-Foto (optional)',
            shape: 'rounded', radius: '10', style: { width: '100%', height: '100%', display: 'block' } })),
        R.createElement('div', { style: { flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 } },
          R.createElement('div', { style: { display: 'flex', alignItems: 'flex-start', gap: 12, opacity: titleO } },
            R.createElement('div', { style: { fontSize: 24, fontWeight: 800, color: MI.fg, lineHeight: 1.15, flex: 1,
              letterSpacing: '-0.01em' } }, p.title),
            R.createElement('span', { style: { flex: '0 0 auto', fontSize: 12, fontWeight: 700, color: '#5899e2',
              border: '1px solid ' + hexA('#5899e2', 0.4), borderRadius: 999, padding: '4px 12px' } }, p.tag)),
          R.createElement('div', { style: { fontSize: 14, color: MI.sub, marginTop: 10, opacity: metaO } },
            'Von ' + p.author + ' · ' + p.date),
          R.createElement('div', { style: { height: 1, background: MI.line, margin: '14px 0', opacity: metaO } }),
          R.createElement('div', { style: { fontSize: 17, lineHeight: 1.55, color: '#48585e', opacity: textO } }, p.text))));
  }

  function AppMock({ mod, t }) {
    const s = mod.seg[0];
    const m = mod.mock;
    let body;
    if (m.type === 'score') body = R.createElement(ScoreView, { mod, t });
    else if (m.type === 'pipeline') body = R.createElement(PipelineView, { mod, t });
    else if (m.type === 'feed') body = R.createElement(FeedView, { mod, t });
    else body = R.createElement('div', { style: { flex: 1, display: 'grid', gridTemplateColumns: '1fr 1fr',
      gridTemplateRows: m.tiles.length <= 2 ? '1fr' : '1fr 1fr', gap: 16 } },
      m.tiles.map((tile, i) => R.createElement(ScoreTile, { key: i, tile, acc: mod.acc, t, start: s + 2.6 + i * 0.5 })));
    return R.createElement('div', { style: { position: 'absolute', inset: 0, background: MI.bg,
      padding: 26, display: 'flex', flexDirection: 'column' } },
      R.createElement('div', { style: { fontFamily: "'JetBrains Mono', monospace", fontSize: 13,
        color: MI.sub, letterSpacing: '0.04em', marginBottom: 6 } }, m.crumb),
      R.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 14, marginBottom: 18 } },
        R.createElement('div', { style: { fontSize: 26, fontWeight: 800, color: MI.fg, letterSpacing: '-0.02em' } }, m.title),
        R.createElement('span', { style: { fontSize: 13, fontWeight: 700, color: mod.acc,
          background: hexA(mod.acc, 0.16), padding: '5px 13px', borderRadius: 999 } }, m.pill)),
      body);
  }

  // ---- browser frame --------------------------------------------------
  function Shot({ mod, L, kb, o, dx }) {
    const t = window.useTime();
    const shotBox = R.createElement('div', {
      style: {
        position: 'relative', width: '100%', height: L.frame ? 'calc(100% - 52px)' : '100%',
        overflow: 'hidden', background: MI.bg, borderRadius: L.frame ? 0 : 18,
      },
    }, R.createElement(AppMock, { mod, t }));

    const chrome = L.frame ? R.createElement('div', {
      style: { display: 'flex', alignItems: 'center', gap: 11, height: 52, padding: '0 22px', background: L.chrome },
    },
      R.createElement('span', { style: dotS(L) }), R.createElement('span', { style: dotS(L) }),
      R.createElement('span', { style: dotS(L) }),
      R.createElement('span', {
        style: {
          marginLeft: 18, fontFamily: "'JetBrains Mono', monospace", fontSize: 15,
          color: L.logo === 'dark' ? '#7f8b92' : '#8ea0a6', letterSpacing: '0.02em',
        },
      }, 'app.databites.de / ' + mod.name)) : null;

    return R.createElement('div', {
      style: {
        position: 'absolute', left: 992, top: 244, width: 812, height: 592,
        borderRadius: 18, overflow: 'hidden',
        background: L.frame ? L.chrome : MI.bg,
        boxShadow: L.logo === 'dark'
          ? '0 40px 90px rgba(27,40,51,0.20)'
          : '0 44px 100px rgba(0,0,0,0.5)',
        border: L.frame ? '1px solid ' + hexA('#ffffff', L.logo === 'dark' ? 0 : 0.08) : 'none',
        opacity: o, transform: 'translateX(' + dx + 'px)',
      },
    }, chrome, shotBox);
  }
  function dotS(L) { return { width: 15, height: 15, borderRadius: 999, background: L.chromeDot, display: 'block' }; }

  // ---- feature line ----------------------------------------------------
  function Feat({ text, acc, L, o, dy, active }) {
    return R.createElement('div', {
      style: {
        display: 'flex', alignItems: 'flex-start', gap: 18, marginBottom: 20,
        opacity: o, transform: 'translateY(' + dy + 'px)', transition: 'none',
      },
    },
      R.createElement('span', {
        style: {
          marginTop: 10, flex: '0 0 auto', width: 17, height: 17, borderRadius: 999,
          background: active ? acc : 'transparent', border: '2px solid ' + acc,
          boxShadow: active ? '0 0 0 6px ' + hexA(acc, 0.18) : 'none',
        },
      }),
      R.createElement('span', {
        style: {
          fontSize: 30, lineHeight: 1.3, fontWeight: 600,
          color: active ? L.fg : L.muted, maxWidth: 660,
        },
      }, text));
  }

  // ---- scene wrapper (full canvas + crossfade) -------------------------
  function Scene({ seg, children }) {
    const t = window.useTime();
    if (t < seg[0] - 0.05 || t > seg[1] + 0.05) return null;
    const fade = 0.7;
    const o = ip([seg[0], seg[0] + fade, seg[1] - fade, seg[1]], [0, 1, 1, 0])(t);
    return R.createElement('div', {
      style: { position: 'absolute', inset: 0, width: 1920, height: 1080, opacity: o },
    }, children);
  }

  // ---- INTRO -----------------------------------------------------------
  function Intro({ seg, L }) {
    const t = window.useTime();
    const s = seg[0];
    const dotsO = ip([s + 0.2, s + 1.1], [0, 1], easeOut())(t);
    const dotsSc = ip([s + 0.2, s + 1.1], [0.6, 1], easeBack())(t);
    const logoO = ip([s + 1.1, s + 2.1], [0, 1], easeOut())(t);
    const logoY = ip([s + 1.1, s + 2.1], [28, 0], easeOut())(t);
    const subO = ip([s + 2.6, s + 3.6], [0, 1], easeOut())(t);
    const rowO = ip([s + 4.4, s + 5.2], [0, 1], easeOut())(t);
    const logoSrc = (window.DB_LOGO ? (L.logo === 'dark' ? window.DB_LOGO.dark : window.DB_LOGO.light) : (L.logo === 'dark' ? 'assets/logo-dark.png' : 'assets/logo-light.png'));

    const chips = MODS.map((m, i) => {
      const co = ip([s + 4.6 + i * 0.45, s + 5.3 + i * 0.45], [0, 1], easeOut())(t);
      const cy = ip([s + 4.6 + i * 0.45, s + 5.3 + i * 0.45], [16, 0], easeOut())(t);
      return R.createElement('div', {
        key: m.key,
        style: {
          display: 'inline-flex', alignItems: 'center', gap: 13, padding: '12px 26px',
          borderRadius: 999, border: '1px solid ' + hexA(m.acc, 0.5),
          background: hexA(m.acc, 0.1), fontSize: 30, fontWeight: 700,
          color: L.logo === 'dark' ? '#223539' : L.fg, opacity: co, transform: 'translateY(' + cy + 'px)',
        },
      },
        R.createElement('span', { style: { width: 15, height: 15, borderRadius: 999, background: m.acc } }),
        m.name);
    });

    return R.createElement(Scene, { seg },
      R.createElement(Glow, { acc: ACC.insights, alpha: L.glow * 0.7 }),
      R.createElement('div', {
        style: {
          position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
          alignItems: 'center', justifyContent: 'center', gap: 34, zIndex: 1,
        },
      },
        R.createElement('img', {
          src: logoSrc, alt: 'databites',
          style: { height: 92, opacity: logoO, transform: 'translateY(' + logoY + 'px)' },
        }),
        R.createElement('div', {
          style: { fontSize: 40, fontWeight: 500, color: L.muted, opacity: subO, textAlign: 'center' },
        }, 'Vier Module. Eine Plattform für das Bäckerhandwerk.'),
        R.createElement('div', {
          style: { display: 'flex', gap: 20, marginTop: 14, opacity: rowO },
        }, chips)));
  }

  // ---- MODULE ----------------------------------------------------------
  function Module({ mod, L }) {
    const t = window.useTime();
    const [s, e] = mod.seg;
    const lt = t - s;              // local seconds
    const dur = e - s;
    const p = Math.max(0, Math.min(1, lt / dur));

    const acc = mod.acc;

    // three beats: WAS (claim) → WANDEL (heute → fix) → WARUM (payoff)
    const aO = ip([s + 0.6, s + 1.8], [0, 1], easeOut())(t) * ip([s + 17, s + 18], [1, 0])(t);
    const claimY = ip([s + 0.6, s + 2.0], [30, 0], easeOut())(t);
    const eyebrowAO = ip([s + 0.3, s + 1.2], [0, 1], easeOut())(t);
    const doesO = ip([s + 2.4, s + 3.6], [0, 1], easeOut())(t);

    const bEnv = ip([s + 18.5, s + 19.7], [0, 1], easeOut())(t) * ip([s + 36, s + 37], [1, 0])(t);
    const heuteI = ip([s + 18.8, s + 20.0], [0, 1], easeOut())(t);
    const arrowI = ip([s + 21.4, s + 22.6], [0, 1], easeOut())(t);
    const fixI = ip([s + 22.2, s + 23.6], [0, 1], easeOut())(t);

    const cO = ip([s + 37.6, s + 39.0], [0, 1], easeOut())(t);
    const kickerCO = ip([s + 37.6, s + 38.6], [0, 1], easeOut())(t);
    const payY = ip([s + 38.2, s + 39.8], [30, 0], easeOut())(t);

    const drift = -Math.min(Math.max(lt, 0), dur) * 0.16;

    const layer = (o) => ({ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
      justifyContent: 'center', paddingLeft: 168, paddingRight: 140, opacity: o, zIndex: 1 });
    const eyebrow = (o) => ({ fontFamily: "'JetBrains Mono', monospace", fontSize: 22, fontWeight: 700,
      letterSpacing: '0.22em', textTransform: 'uppercase', color: acc, opacity: o, marginBottom: 26 });
    const miniLabel = (col) => ({ fontFamily: "'JetBrains Mono', monospace", fontSize: 20, fontWeight: 700,
      letterSpacing: '0.2em', textTransform: 'uppercase', color: col, marginBottom: 16 });

    return R.createElement(Scene, { seg: mod.seg },
      R.createElement('div', { style: { position: 'absolute', inset: 0, background: L.bg } }),
      R.createElement(Glow, { acc, alpha: L.glow }),
      // faint background wordmark
      R.createElement('div', { style: { position: 'absolute', right: -34, bottom: -78, zIndex: 0,
        fontFamily: "'Montserrat', sans-serif", fontWeight: 800, fontStyle: 'italic', fontSize: 380,
        lineHeight: 1, letterSpacing: '-0.04em', color: hexA(acc, 0.06), pointerEvents: 'none' } }, mod.name),
      // persistent module pill
      R.createElement('div', { style: { position: 'absolute', left: 168, top: 150, zIndex: 3 } },
        R.createElement(Pill, { mod, L, o: ip([s + 0.3, s + 1.6], [0, 1], easeOut())(t), dx: 0 })),

      // BEAT A — was wir tun
      R.createElement('div', { style: layer(aO) },
        R.createElement('div', { style: eyebrow(eyebrowAO) }, mod.kicker),
        R.createElement(Html, { html: mod.claim, className: 'mv-head',
          style: { fontFamily: "'Montserrat', sans-serif", fontWeight: 800, fontSize: 128, lineHeight: 0.96,
            letterSpacing: '-0.035em', color: L.fg, '--em': acc, transform: 'translateY(' + (claimY + drift) + 'px)' } }),
        R.createElement('div', { style: { marginTop: 34, maxWidth: 1000, fontSize: 36, lineHeight: 1.45,
          fontWeight: 500, color: L.muted, opacity: doesO } }, mod.does)),

      // BEAT B — von heute zu databites
      R.createElement('div', { style: layer(bEnv) },
        R.createElement('div', { style: { display: 'flex', alignItems: 'flex-end', gap: 44, flexWrap: 'wrap',
          transform: 'translateY(' + drift + 'px)' } },
          R.createElement('div', { style: { opacity: heuteI } },
            R.createElement('div', { style: miniLabel(L.muted) }, 'heute'),
            R.createElement(Html, { html: mod.heute, className: 'mv-head',
              style: { fontFamily: "'Montserrat', sans-serif", fontWeight: 800, fontSize: 76, lineHeight: 1.0,
                letterSpacing: '-0.03em', color: L.muted, '--em': L.muted } })),
          R.createElement('div', { style: { fontSize: 76, fontWeight: 300, color: acc, opacity: arrowI,
            transform: 'translateY(-10px)', lineHeight: 1 } }, '\u2192'),
          R.createElement('div', { style: { opacity: fixI } },
            R.createElement('div', { style: miniLabel(acc) }, 'mit databites'),
            R.createElement(Html, { html: mod.fix, className: 'mv-head',
              style: { fontFamily: "'Montserrat', sans-serif", fontWeight: 800, fontSize: 76, lineHeight: 1.0,
                letterSpacing: '-0.03em', color: L.fg, '--em': acc } })))),

      // BEAT C — warum wir es tun
      R.createElement('div', { style: layer(cO) },
        R.createElement('div', { style: eyebrow(kickerCO) }, 'darum ' + mod.name),
        R.createElement(Html, { html: mod.payoff, className: 'mv-head',
          style: { fontFamily: "'Montserrat', sans-serif", fontWeight: 800, fontSize: 118, lineHeight: 1.0,
            letterSpacing: '-0.035em', color: L.fg, '--em': acc, transform: 'translateY(' + payY + 'px)' } })));
  }

  // ---- OUTRO -----------------------------------------------------------
  function Outro({ seg, L }) {
    const t = window.useTime();
    const s = seg[0];
    const logoO = ip([s + 0.4, s + 1.6], [0, 1], easeOut())(t);
    const logoY = ip([s + 0.4, s + 1.6], [22, 0], easeOut())(t);
    const rowO = ip([s + 1.6, s + 2.6], [0, 1], easeOut())(t);
    const ctaO = ip([s + 2.8, s + 3.8], [0, 1], easeOut())(t);
    const logoSrc = (window.DB_LOGO ? (L.logo === 'dark' ? window.DB_LOGO.dark : window.DB_LOGO.light) : (L.logo === 'dark' ? 'assets/logo-dark.png' : 'assets/logo-light.png'));

    const chips = MODS.map((m, i) => R.createElement('span', {
      key: m.key, style: { display: 'inline-flex', alignItems: 'center', gap: 11, fontSize: 30, fontWeight: 700, color: L.fg },
    },
      R.createElement('span', { style: { width: 14, height: 14, borderRadius: 999, background: m.acc } }),
      m.name));

    const sep = () => R.createElement('span', { style: { color: L.muted, fontSize: 26, margin: '0 4px' } }, '·');

    return R.createElement(Scene, { seg },
      R.createElement(Glow, { acc: ACC.insights, alpha: L.glow * 0.7 }),
      R.createElement('div', {
        style: {
          position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
          alignItems: 'center', justifyContent: 'center', gap: 40, zIndex: 1,
        },
      },
        R.createElement('img', { src: logoSrc, alt: 'databites', style: { height: 96, opacity: logoO, transform: 'translateY(' + logoY + 'px)' } }),
        R.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, opacity: rowO } },
          chips[0], sep(), chips[1], sep(), chips[2], sep(), chips[3]),
        R.createElement('div', {
          className: 'mv-cta',
          contentEditable: false,
          style: {
            marginTop: 8, fontSize: 34, fontWeight: 700, letterSpacing: '0.01em',
            color: L.logo === 'dark' ? '#223539' : ACC.insights, opacity: ctaO,
            padding: '16px 40px', borderRadius: 999, border: '1px solid ' + hexA(ACC.insights, 0.5),
            background: hexA(ACC.insights, 0.12),
          },
        }, 'Jetzt kennenlernen')));
  }

  // ---- APP -------------------------------------------------------------
  function ModulVideo() {
    const L = LOOKS.studio;
    // Hide the Stage's playback bar → clean, chromeless, auto-looping video.
    R.useEffect(() => {
      const hide = () => {
        const svg = document.querySelector('[data-om-exportable-video-with-duration-secs]');
        if (!svg) return false;
        const canvasArea = svg.parentElement;
        const stageRoot = canvasArea && canvasArea.parentElement;
        if (!stageRoot) return false;
        Array.prototype.forEach.call(stageRoot.children, (c) => {
          if (c !== canvasArea) c.style.display = 'none';
        });
        return true;
      };
      if (!hide()) {
        const id = setInterval(() => { if (hide()) clearInterval(id); }, 120);
        setTimeout(() => clearInterval(id), 3000);
      }
    }, []);

    return R.createElement('div', { style: { position: 'fixed', inset: 0, background: L.bg } },
      R.createElement(window.Stage, { width: 1920, height: 1080, duration: DUR, background: L.bg, loop: true, autoplay: true },
        // music baked into the video export (muted in the live player)
        R.createElement(window.VideoSprite, { src: 'music-bed.wav', start: 0, end: 33.1,
          style: { position: 'absolute', width: 2, height: 2, opacity: 0, right: 0, bottom: 0, pointerEvents: 'none' } }),
        R.createElement(Intro, { seg: INTRO, L }),
        MODS.map((m) => R.createElement(Module, { key: m.key, mod: m, L })),
        R.createElement(Outro, { seg: OUTRO, L })));
  }

  window.ModulVideo = ModulVideo;
})();
