/* global React, Sprite, useSprite, useTime, Easing, interpolate, animate, clamp,
   ScrollStage, CursorTrail, CanvasChrome, SidePanel, useIsMobile */
// Bataj Products Scroll-Reel — the products section as one big scroll-driven
// video. Replaces ProductsIntro + AllProducts + Stats + Process.
//
// Story arc (60 units of time mapped to ~750vh of scroll):
//   00–03  Intro:   "PRODUCTOS · Cuatro universos."
//   03–12  Turnos:  warm calendar booking, slot ignites, confirm pulses
//   12–21  Sak:     editorial luxury catalog, cards reveal, price glows
//   21–30  Delivery: dark console, orders flow through pipeline
//   30–39  Dunamis: dashboard, KPIs tick up, sparklines draw, alerts pop
//   39–46  Stats:   4 monumental numbers count up
//   46–53  Process: 01→04 BRIEF/SISTEMA/BUILD/LAUNCH march in
//   53–60  Outro:   "Mismo estudio. Cuatro lenguajes." + CTA wink

const _cl = (v, lo, hi) => Math.max(lo, Math.min(hi, v));

/* ─────────────  Small reusable helpers  ───────────── */

// progress 0 → 1 across [from, to] within sprite-local time
function ramp(localTime, from, to, ease = Easing.easeOutCubic) {
  return ease(_cl((localTime - from) / Math.max(0.0001, to - from), 0, 1));
}

// integer count tween
function counted(localTime, from, to, target, fmt = (v) => v) {
  const t = ramp(localTime, from, to, Easing.easeOutCubic);
  return fmt(target * t);
}

function TrafficDots({ colors = ['#d0c8b8', '#d0c8b8', '#d0c8b8'] }) {
  return (
    <div style={{ display: 'flex', gap: 8 }}>
      {colors.map((c, i) => (
        <span key={i} style={{ width: 12, height: 12, borderRadius: 99, background: c }} />
      ))}
    </div>
  );
}

/* ─────────────  Window chrome shell  ───────────── */

function WindowFrame({ x, y, w, h, bar, barBg, lineColor, bg, children, scaleAtEntry = 0 }) {
  // scaleAtEntry: 0 = no entry animation, otherwise it's an entrance progress 0->1
  const scale = 0.94 + 0.06 * scaleAtEntry;
  const opacity = _cl(scaleAtEntry / 0.6, 0, 1);
  return (
    <div className="neo-card neo-glow" style={{
      position: 'absolute', left: x, top: y, width: w, height: h,
      zIndex: 10,
      background: 'var(--bataj-paper)', borderRadius: 18, overflow: 'hidden',
      transform: `scale(${scale})`, transformOrigin: '50% 60%',
      opacity, willChange: 'transform, opacity',
      color: 'var(--bataj-ink)',
    }}>
      <div style={{
        height: 38, padding: '0 16px', display: 'flex', alignItems: 'center',
        background: barBg, borderBottom: `1px solid ${lineColor}`,
        fontFamily: 'JetBrains Mono, monospace', fontSize: 12,
        color: 'rgba(0,0,0,.5)', gap: 12,
      }}>
        {bar}
      </div>
      <div style={{ position: 'relative', width: '100%', height: h - 38 }}>{children}</div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   SCENE 0 — INTRO  (0 → 3)
   ═══════════════════════════════════════════════════════════════════════ */

function SceneIntro() {
  const isMobile = useIsMobile();
  const { localTime } = useSprite();
  const a1 = ramp(localTime, 0.1, 0.9, Easing.easeOutBack);
  const a2 = ramp(localTime, 0.6, 1.4);
  const a3 = ramp(localTime, 1.4, 2.2);
  const out = 1 - ramp(localTime, 2.4, 3.0);

  return (
    <div style={{ position: 'absolute', inset: 0, opacity: out }}>
      <div style={{
        position: 'absolute', top: isMobile ? '28%' : '38%', left: isMobile ? 50 : 96,
        fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 24 : 22,
        letterSpacing: '0.22em', textTransform: 'uppercase',
        color: 'color-mix(in srgb, var(--bataj-ink) 60%, transparent)',
        opacity: a2, transform: `translateY(${(1 - a2) * 14}px)`,
      }}>
        ▸ Sec.03 · Catálogo · 04 productos
      </div>

      <div style={{
        position: 'absolute', top: isMobile ? '35%' : '46%', left: isMobile ? 50 : 96,
        fontFamily: 'Pixelify Sans, monospace', fontWeight: 700,
        fontSize: isMobile ? 180 : 280, lineHeight: 0.82, letterSpacing: '-0.04em',
        color: 'var(--bataj-ink)',
        opacity: a1, transform: `translateY(${(1 - a1) * 60}px)`,
      }}>
        PRO<span style={{ color: 'var(--bataj-accent)' }}>_</span>DUCTOS
      </div>

      <div style={{
        position: 'absolute', bottom: isMobile ? '24%' : '14%', left: isMobile ? 50 : 96, right: isMobile ? 50 : 96,
        display: 'flex', flexDirection: isMobile ? 'column' : 'row', justifyContent: 'space-between', alignItems: isMobile ? 'flex-start' : 'baseline',
        opacity: a3, transform: `translateY(${(1 - a3) * 20}px)`,
      }}>
        <div style={{
          fontFamily: 'var(--bataj-display)', fontStyle: 'italic',
          fontSize: isMobile ? 72 : 96, lineHeight: 0.95, color: 'var(--bataj-ink)',
          letterSpacing: '-0.02em', marginBottom: isMobile ? 24 : 0,
        }}>
          Cuatro <span style={{ color: 'var(--bataj-accent)' }}>universos</span>.
        </div>
        <div style={{
          fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 24 : 16,
          letterSpacing: '0.18em', textTransform: 'uppercase',
          color: 'color-mix(in srgb, var(--bataj-ink) 65%, transparent)',
          textAlign: isMobile ? 'left' : 'right', lineHeight: 1.6,
        }}>
          01 · TURNOS<br />02 · SAK<br />03 · DELIVERY<br />04 · DUNAMIS
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   SCENE 1 — APP TURNOS  (3 → 12)
   ═══════════════════════════════════════════════════════════════════════ */

function SceneTurnosLive() {
  const isMobile = useIsMobile();
  const { localTime, duration } = useSprite();
  const entry = ramp(localTime, 0, 1.0);
  const exit  = ramp(localTime, duration - 0.8, duration, Easing.easeInCubic);
  const opacity = entry * (1 - exit);

  // animation phases
  const headerIn  = ramp(localTime, 0.3, 1.1);
  const weekIn    = ramp(localTime, 0.9, 1.6);
  const slotsIn   = ramp(localTime, 1.5, 2.4);
  const selectIn  = ramp(localTime, 2.6, 3.4, Easing.easeOutBack);
  const ctaPulse  = Math.sin(_cl((localTime - 3.7) * 4, 0, Math.PI * 2)) * 0.5 + 0.5;
  const toastIn   = ramp(localTime, 4.4, 5.0, Easing.easeOutBack);
  const toastOut  = ramp(localTime, 7.0, 7.6);

  // cursor keyframes (absolute canvas coordinates)
  const cursorKf = [
    { t: 0.6,  x: 1750, y: 850 },                     // off-canvas right
    { t: 1.4,  x: 760,  y: 540 },                     // hover Lun 27
    { t: 2.2,  x: 760,  y: 540 },                     // hold
    { t: 3.1,  x: 660,  y: 800, click: true },        // click 15:00
    { t: 3.8,  x: 660,  y: 800 },
    { t: 4.4,  x: 1070, y: 920, click: true },        // click Confirmar
    { t: 5.5,  x: 1070, y: 920 },
    { t: 7.0,  x: 1300, y: 980 },
  ];

  const slots = ['09:00','09:30','10:00','10:30','11:00','11:30','12:00','14:00','14:30','15:00','15:30','16:00'];
  const taken = new Set(['10:00','11:30','14:30']);

  return (
    <div style={{ position: 'absolute', inset: 0, opacity }}>
      <CanvasChrome idx={1} total={4} code="BTJ-01" title="APP TURNOS" sub="SALUD · WELLNESS" accent="#A29CBB" />
      <SidePanel
        kicker="Salud · Wellness"
        code="BTJ-01 · app.turnos.studio"
        name="App Turnos"
        tagline="Tu agenda, sin teléfono."
        blurb="Reservas online para profesionales de salud y bienestar. Pacientes que se agendan solos, recordatorios automáticos y cobros integrados."
        stats={[
          { l: 'REDUCCIÓN AUSENCIAS', v: '-85%' },
          { l: 'TIEMPO AHORRADO', v: '14h/sem' },
          { l: 'RETENCIÓN PACIENTES', v: '98%' }
        ]}
        stack={['VUE 3','LARAVEL','MySQL','MP']}
        accent="#A29CBB"
      />

      <WindowFrame
        x={isMobile ? -50 : 88} y={isMobile ? 1100 : 170} w={1180} h={780}
        bg="var(--bataj-paper)"
        barBg="var(--bataj-bg)"
        lineColor="rgba(0,0,0,.08)"
        scaleAtEntry={entry}
        bar={<>
          <TrafficDots />
          <span style={{ marginLeft: 8 }}>app.turnos.studio / reservar</span>
        </>}
      >
        {/* Sidebar */}
        <div style={{
          position:'absolute', top:0, left:0, width: 250, height:'100%',
          background:'color-mix(in srgb, var(--bataj-bg) 70%, var(--bataj-paper))', borderRight:'1px solid rgba(0,0,0,.08)',
          padding: 24, color:'var(--bataj-ink)',
          opacity: ramp(localTime, 0.2, 0.8),
        }}>
          <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom: 24 }}>
            <div style={{ width:34, height:34, borderRadius:99, background:'var(--bataj-ink)', color:'var(--bataj-paper)', display:'grid', placeItems:'center', fontFamily:'var(--bataj-display)', fontSize:18, paddingBottom:2 }}>A</div>
            <div>
              <div style={{ fontFamily:'var(--bataj-display)', fontSize:18, lineHeight:1 }}>Aurelia Reyes</div>
              <div style={{ fontFamily:'var(--bataj-sans)', fontSize:11, color:'rgba(0,0,0,.55)', marginTop:3 }}>Psicología clínica</div>
            </div>
          </div>
          {['Agenda','Pacientes','Notas','Cobros','Historial'].map((x,i) => (
            <div key={x} style={{
              fontFamily:'var(--bataj-sans)', fontSize:14, padding:'8px 12px',
              borderRadius: 8, marginBottom: 2,
              background: i === 0 ? 'var(--bataj-ink)' : 'transparent',
              color: i === 0 ? 'var(--bataj-paper)' : 'rgba(0,0,0,.75)',
            }}>{x}</div>
          ))}
          {/* upcoming card */}
          <div style={{
            marginTop: 30, padding: 14, borderRadius: 12, background:'color-mix(in srgb, var(--bataj-bg) 50%, var(--bataj-paper))',
            opacity: toastIn * (1 - toastOut),
          }}>
            <div style={{
              fontFamily:'JetBrains Mono,monospace', fontSize:10, letterSpacing:'0.16em',
              textTransform:'uppercase', color:'var(--bataj-accent)', marginBottom: 4,
            }}>Próximo · Confirmado</div>
            <div style={{ fontFamily:'var(--bataj-display)', fontSize:18, color:'var(--bataj-ink)' }}>Mariana López</div>
            <div style={{ fontFamily:'var(--bataj-sans)', fontSize:12, color:'rgba(0,0,0,.65)' }}>15:00 · Sesión seguimiento</div>
          </div>
        </div>

        {/* Calendar area */}
        <div style={{
          position:'absolute', left:250, right:0, top:0, bottom:0, padding: '36px 40px',
          color:'var(--bataj-ink)',
        }}>
          <div style={{ opacity: headerIn, transform: `translateY(${(1 - headerIn) * 14}px)` }}>
            <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize:11, letterSpacing:'0.18em', textTransform:'uppercase', color:'rgba(0,0,0,.55)', marginBottom: 4 }}>
              Lunes, 27 de mayo
            </div>
            <div style={{ fontFamily:'var(--bataj-display)', fontStyle:'italic', fontSize:46, lineHeight:1, marginBottom: 24 }}>
              Reservá tu sesión
            </div>
          </div>

          {/* Week strip */}
          <div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap: 8, marginBottom: 22 }}>
            {['Lun 27','Mar 28','Mié 29','Jue 30','Vie 31','Sáb 1','Dom 2'].map((d, i) => {
              const a = ramp(localTime, 0.9 + i * 0.04, 1.4 + i * 0.04, Easing.easeOutBack);
              const isSelected = i === 0;
              return (
                <div key={d} style={{
                  textAlign:'center', padding:'12px 0', borderRadius: 12,
                  background: isSelected ? 'var(--bataj-accent)' : 'var(--bataj-bg)',
                  color: isSelected ? 'var(--bataj-paper)' : 'rgba(0,0,0,.75)',
                  fontFamily:'var(--bataj-sans)',
                  opacity: a, transform: `translateY(${(1 - a) * 14}px)`,
                }}>
                  <div style={{ fontSize:12, fontWeight: 500 }}>{d.split(' ')[0]}</div>
                  <div style={{ fontFamily:'var(--bataj-display)', fontSize:22, lineHeight:1, marginTop: 4 }}>{d.split(' ')[1]}</div>
                </div>
              );
            })}
          </div>

          {/* Slots */}
          <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize:11, letterSpacing:'0.18em', textTransform:'uppercase', color:'rgba(0,0,0,.55)', marginBottom: 12, opacity: slotsIn }}>
            Horarios disponibles
          </div>
          <div style={{ display:'grid', gridTemplateColumns:'repeat(4,1fr)', gap: 10 }}>
            {slots.map((s, i) => {
              const a = ramp(localTime, 1.5 + (i * 0.05), 2.1 + (i * 0.05), Easing.easeOutCubic);
              const isTaken = taken.has(s);
              const isSel = s === '15:00';
              const selRamp = isSel ? selectIn : 0;
              return (
                <div key={s} style={{
                  padding:'12px 0', textAlign:'center', borderRadius: 12,
                  fontFamily:'var(--bataj-sans)', fontSize:14,
                  border: `1px solid ${isSel ? 'var(--bataj-ink)' : 'rgba(0,0,0,.18)'}`,
                  background: isSel ? `color-mix(in srgb, var(--bataj-ink) ${selRamp * 100}%, transparent)` : 'transparent',
                  color: isSel
                    ? `color-mix(in srgb, var(--bataj-paper) ${selRamp * 100}%, var(--bataj-ink))`
                    : isTaken ? 'rgba(0,0,0,.3)' : 'rgba(0,0,0,.85)',
                  textDecoration: isTaken ? 'line-through' : 'none',
                  opacity: a,
                  transform: isSel
                    ? `translateY(${(1 - a) * 12}px) scale(${0.96 + 0.04 * selRamp})`
                    : `translateY(${(1 - a) * 12}px)`,
                  boxShadow: isSel ? `0 0 0 ${4 * selRamp}px color-mix(in srgb, var(--bataj-accent) ${30 * selRamp}%, transparent)` : 'none',
                  transition: 'box-shadow .2s ease',
                }}>{s}</div>
              );
            })}
          </div>

          {/* Footer row + CTA */}
          <div style={{ position:'absolute', bottom: 30, left: 40, right: 40, display:'flex', justifyContent:'space-between', alignItems:'center' }}>
            <div style={{ fontFamily:'var(--bataj-sans)', fontSize:13, color:'rgba(0,0,0,.55)' }}>
              Sesión 50 min · ARS 18.000
            </div>
            <div style={{
              fontFamily:'var(--bataj-sans)', fontWeight: 500, fontSize: 14,
              padding: '11px 22px', borderRadius: 999,
              background: 'var(--bataj-accent)', color: 'var(--bataj-paper)',
              transform: `scale(${1 + ctaPulse * 0.04})`,
              boxShadow: `0 0 0 ${ctaPulse * 6}px color-mix(in srgb, var(--bataj-accent) ${20 - ctaPulse * 10}%, transparent)`,
              opacity: ramp(localTime, 1.7, 2.2),
            }}>Confirmar reserva →</div>
          </div>

          {/* Toast confirmation */}
          {toastIn > 0 && toastOut < 1 && (
            <div style={{
              position:'absolute', bottom: 100, right: 40,
              padding: '14px 18px', borderRadius: 12,
              background: 'var(--bataj-ink)', color: 'var(--bataj-paper)',
              fontFamily:'var(--bataj-sans)', fontSize: 13,
              boxShadow: '0 14px 30px -10px rgba(0,0,0,.4)',
              opacity: toastIn * (1 - toastOut),
              transform: `translateY(${(1 - toastIn) * 20}px)`,
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <span style={{ width: 8, height: 8, borderRadius: 99, background: 'var(--bataj-accent)' }} />
              <div>
                <div style={{ fontWeight: 600 }}>Reserva confirmada</div>
                <div style={{ fontSize: 11, color: 'rgba(247,242,230,.6)' }}>Lun 27 · 15:00 · Te llegará un email</div>
              </div>
            </div>  )}
        </div>
      </WindowFrame>
      <CursorTrail keyframes={[{t:0,x:750,y:600},{t:0.1,x:750,y:600},{t:0.25,x:585,y:482,click:true},{t:0.35,x:585,y:482},{t:0.5,x:750,y:600},{t:1,x:750,y:600}]} />
    </div>
  );
}

function SceneSakLive() {
  const isMobile = useIsMobile();
  const { localTime, duration } = useSprite();
  const entry = ramp(localTime, 0, 1.0);
  const exit = ramp(localTime, duration - 0.8, duration, Easing.easeInCubic);
  const opacity = entry * (1 - exit);

  const items = [
    { n: 'Lino Crudo',    p: 'AR$ 89.000',  tag: 'COL/26', img: 'linear-gradient(160deg,#E4D8BD,#C8B58A)' },
    { n: 'Vestido Aria',  p: 'AR$ 142.000', tag: 'NEW',    img: 'linear-gradient(160deg,#D7C2A1,#9A7A4B)' },
    { n: 'Camisa Oporto', p: 'AR$ 96.500',  tag: 'COL/26', img: 'linear-gradient(160deg,#EFE5D0,#B59C70)' },
    { n: 'Pantalón Soho', p: 'AR$ 118.000', tag: 'STAFF',  img: 'linear-gradient(160deg,#C9B797,#6F5D3B)' },
  ];

  const headerIn = ramp(localTime, 0.4, 1.2);
  const filterIn = ramp(localTime, 1.1, 1.8);

  // bag indicator ticks at click time
  const bagAdded = localTime > 5.4 ? 1 : 0;

  const cursorKf = [
    { t: 0.8,  x: 1700, y: 200 },
    { t: 2.4,  x: 820,  y: 700 },              // hover product 1
    { t: 3.6,  x: 820,  y: 700, click: true }, // click
    { t: 4.4,  x: 980,  y: 740 },              // move toward "add" pill
    { t: 5.4,  x: 980,  y: 740, click: true }, // click add
    { t: 6.6,  x: 1240, y: 130 },              // up to bag
    { t: 8.6,  x: 1240, y: 130 },
  ];

  return (
    <div style={{ position:'absolute', inset:0, opacity }}>
      <CanvasChrome idx={2} total={4} code="BTJ-02" title="SAK-COMMERCE" sub="LUJO MINIMAL" accent="#7D78A3" />
      <SidePanel
        kicker="E-commerce · Lujo"
        code="BTJ-02 · sak.studio"
        name="Sak-Commerce"
        tagline="Un atelier, online."
        blurb="Catálogo editorial, variantes y filtros sofisticados. Cada scroll, una página de revista. Métricas que importan."
        stats={[
          { l: 'TICKET PROMEDIO', v: '+45%' },
          { l: 'AUMENTO DE VENTAS', v: '+120%' },
          { l: 'CONVERSIÓN VS INFO', v: '4.8x' }
        ]}
        stack={['VUE 3','LARAVEL','STRIPE']}
        accent="#7D78A3"
      />

      <WindowFrame
        x={isMobile ? -50 : 88} y={isMobile ? 1100 : 170} w={1180} h={780}
        bg="var(--bataj-paper)"
        barBg="var(--bataj-bg)"
        lineColor="rgba(0,0,0,.08)"
        scaleAtEntry={entry}
        bar={<>
          <TrafficDots />
          <span style={{ marginLeft: 8 }}>sak.studio / colección / otoño 26</span>
        </>}
      >
        {/* editorial header */}
        <div style={{
          padding: '24px 40px', borderBottom:'1px solid rgba(0,0,0,.1)',
          display:'flex', justifyContent:'space-between', alignItems:'flex-end',
          opacity: headerIn, transform: `translateY(${(1 - headerIn) * 16}px)`,
        }}>
          <div>
            <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, letterSpacing:'0.22em', textTransform:'uppercase', color:'rgba(0,0,0,.6)', marginBottom: 6 }}>
              Otoño · MMXXVI
            </div>
            <div style={{ fontFamily:'var(--bataj-display)', fontSize: 60, lineHeight: 1, color:'var(--bataj-ink)' }}>
              Sak<span style={{ fontStyle:'italic' }}> Atelier</span>
            </div>
          </div>
          <nav style={{
            display:'flex', alignItems:'center', gap: 28,
            fontFamily:'var(--bataj-sans)', fontSize: 14, color:'rgba(0,0,0,.7)',
          }}>
            <span style={{ color:'var(--bataj-ink)', borderBottom:'1px solid var(--bataj-ink)', paddingBottom: 4 }}>Colección</span>
            <span>Lookbook</span><span>Historia</span><span>Tiendas</span>
            <span style={{ width: 1, height: 16, background:'rgba(0,0,0,.2)' }} />
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 6,
              padding: '4px 10px', borderRadius: 99,
              background: bagAdded ? 'var(--bataj-accent)' : 'transparent',
              color: bagAdded ? 'var(--bataj-paper)' : 'rgba(0,0,0,.7)',
              transition: 'background .3s, color .3s',
            }}>
              ▢ Bolsa ({2 + bagAdded})
            </span>
          </nav>
        </div>

        {/* filter row */}
        <div style={{
          padding: '12px 40px', borderBottom:'1px solid rgba(0,0,0,.08)',
          display:'flex', justifyContent:'space-between',
          fontFamily:'var(--bataj-sans)', fontSize: 13, color:'rgba(0,0,0,.65)',
          opacity: filterIn,
        }}>
          <div style={{ display:'flex', gap: 22 }}>
            <span>Filtrar:</span>
            <span style={{ color:'var(--bataj-ink)', textDecoration:'underline', textUnderlineOffset: 4 }}>Todo</span>
            <span>Lino</span><span>Algodón</span><span>Seda</span>
          </div>
          <div style={{ display:'flex', gap: 22 }}>
            <span>Orden: Editorial</span><span>Vista: Grid</span>
          </div>
        </div>

        {/* products 2x2 */}
        <div style={{ position:'relative', display:'grid', gridTemplateColumns:'1fr 1fr', gridAutoRows: 'minmax(280px, 1fr)' }}>
          {items.map((it, i) => {
            const a = ramp(localTime, 1.6 + (i * 0.25), 2.4 + (i * 0.25), Easing.easeOutCubic);
            const hovered = i === 0 && localTime > 2.0 && localTime < 7.5;
            const liftT = hovered ? ramp(localTime, 2.0, 2.6) * (1 - ramp(localTime, 7.5, 8.0)) : 0;
            return (
              <div key={it.n} style={{
                padding: '14px 28px 24px',
                borderRight: i % 2 === 0 ? '1px solid rgba(0,0,0,.08)' : 'none',
                borderBottom: i < 2 ? '1px solid rgba(0,0,0,.08)' : 'none',
                opacity: a,
                transform: `translateY(${(1 - a) * 24 - liftT * 8}px)`,
                background: liftT > 0 ? `color-mix(in srgb, var(--bataj-bg) ${liftT * 35}%, transparent)` : 'transparent',
                transition: 'background .2s ease',
              }}>
                <div style={{
                  aspectRatio: '4/5', borderRadius: 6, marginBottom: 14,
                  background: it.img,
                  position: 'relative', overflow: 'hidden',
                  transform: `scale(${1 + liftT * 0.03})`,
                  transformOrigin: 'center',
                  transition: 'transform .25s ease',
                }}>
                  <div style={{
                    position:'absolute', top: 10, left: 10,
                    fontFamily:'JetBrains Mono,monospace', fontSize: 9, letterSpacing:'0.18em', textTransform:'uppercase',
                    padding: '3px 8px', borderRadius: 99,
                    background: 'rgba(251,246,234,.85)', color: 'var(--bataj-ink)',
                  }}>{it.tag}</div>
                  <div style={{
                    position:'absolute', bottom: 10, right: 10,
                    width: 30, height: 30, borderRadius: 99,
                    background: 'rgba(251,246,234,.85)', color: 'var(--bataj-ink)',
                    display:'grid', placeItems:'center',
                  }}>♡</div>
                </div>
                <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-end' }}>
                  <div>
                    <div style={{ fontFamily:'var(--bataj-display)', fontStyle:'italic', fontSize: 24, color:'var(--bataj-ink)', lineHeight: 1 }}>{it.n}</div>
                    <div style={{ fontFamily:'var(--bataj-sans)', fontSize: 12, color:'rgba(0,0,0,.55)', marginTop: 4 }}>Lino 100% · 5 talles</div>
                  </div>
                  <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 14, color: hovered ? 'var(--bataj-accent)' : 'var(--bataj-ink)', transition: 'color .25s' }}>{it.p}</div>
                </div>
                {hovered && (
                  <div style={{
                    position: 'absolute',
                    marginTop: -50, marginLeft: 130,
                    padding: '8px 14px', borderRadius: 99,
                    background: 'var(--bataj-accent)', color: 'var(--bataj-paper)',
                    fontFamily:'var(--bataj-sans)', fontSize: 12, fontWeight: 500,
                    opacity: liftT, transform: `translateY(${(1 - liftT) * 8}px)`,
                    boxShadow: '0 6px 16px -4px rgba(0,0,0,.25)',
                  }}>Añadir a bolsa ↗</div>
                )}
              </div>
            );
          })}
        </div>
      </WindowFrame>
      <CursorTrail keyframes={[{t:0,x:600,y:400},{t:0.2,x:600,y:400},{t:0.35,x:850,y:302},{t:0.5,x:850,y:302},{t:0.7,x:600,y:400},{t:1,x:600,y:400}]} />
    </div>
  );
}

function SceneDeliveryLive() {
  const isMobile = useIsMobile();
  const { localTime, duration } = useSprite();
  const entry = ramp(localTime, 0, 1.0);
  const exit  = ramp(localTime, duration - 0.8, duration, Easing.easeInCubic);
  const opacity = entry * (1 - exit);

  // Orders animate in over time; one transitions COCINA → LISTO → EN RUTA
  const allOrders = [
    { id: '#3492', cli: 'Mesa 12',   items: '2× Pizza · 1× Coca',  base: '00:14', tIn: 1.0, transitions: [{ at: 3.2, status: 'COCINA', col: 'var(--bataj-accent)' }, { at: 5.5, status: 'LISTO', col: '#FFD93D' }, { at: 7.4, status: 'EN RUTA', col: 'var(--bataj-accent)' }] },
    { id: '#3491', cli: 'Lourdes G.', items: '1× Bowl · Postre',    base: '00:08', tIn: 1.3, transitions: [{ at: 0, status: 'EN RUTA', col: 'var(--bataj-accent)' }] },
    { id: '#3490', cli: 'Diego F.',  items: '3× Empanadas',        base: '00:22', tIn: 1.6, transitions: [{ at: 0, status: 'COCINA', col: 'var(--bataj-accent)' }] },
    { id: '#3489', cli: 'Mesa 04',   items: '1× Pasta',            base: '00:31', tIn: 1.9, transitions: [{ at: 0, status: 'LISTO', col: '#FFD93D' }] },
    { id: '#3488', cli: 'Sofía R.',  items: '2× Sushi · Postre',   base: '00:42', tIn: 2.2, transitions: [{ at: 0, status: 'CERRADO', col: '#5A6071' }] },
    { id: '#3487', cli: 'Mesa 09',   items: '4× Pizza',            base: '01:02', tIn: 2.5, transitions: [{ at: 0, status: 'CERRADO', col: '#5A6071' }] },
  ];

  function currentStatus(order) {
    let cur = order.transitions[0];
    for (const tr of order.transitions) if (localTime >= tr.at + order.tIn) cur = tr;
    return cur;
  }

  // Timer ticks for first KDS card
  const ticker = (localTime > 0.5) ? Math.floor(localTime * 1.5) : 0;

  const cursorKf = [
    { t: 0.6, x: 1700, y: 200 },
    { t: 2.2, x: 700,  y: 560 },               // hover #3492
    { t: 3.4, x: 700,  y: 560, click: true },  // click row
    { t: 5.4, x: 1280, y: 350, click: true },  // mark ready in KDS
    { t: 7.4, x: 1280, y: 460, click: true },  // confirm to ruta
    { t: 8.6, x: 1700, y: 800 },
  ];

  return (
    <div style={{ position:'absolute', inset:0, opacity }}>
      <CanvasChrome idx={3} total={4} code="BTJ-03" title="DELIVERY APP" sub="OPERACIONES · MULTI-TENANT" accent="#F1B2AC" />
      <SidePanel 
        kicker="Operaciones · Gastro"
        code="BTJ-03 · deliv.app"
        name="Delivery App"
        tagline="El backbone de tu cocina."
        blurb="Plataforma operativa multi-tenant. Cinco roles, una fuente de verdad. Caja, cocina, repartidor y super, sincronizados en tiempo real."
        stats={[
          { l: 'ERRORES DE ORDEN', v: '-99%' },
          { l: 'TIEMPO DE ENTREGA', v: '-30%' },
          { l: 'AHORRO OPERATIVO', v: '$2K/mes' }
        ]}
        stack={['REACT','NODE','WS','PG']}
        accent="#F1B2AC"
      />

      <WindowFrame
        x={isMobile ? -50 : 88} y={isMobile ? 1100 : 170} w={1180} h={780}
        bg="var(--bataj-paper)"
        barBg="var(--bataj-bg)"
        lineColor="rgba(0,0,0,.08)"
        scaleAtEntry={entry}
        bar={<>
          <TrafficDots colors={['var(--bataj-accent)','#FFD93D','var(--bataj-accent)']} />
          <span style={{ marginLeft: 8, color: 'rgba(0,0,0,.55)' }}>
            deliv.app / console · tenant: cucina-roma
          </span>
          <span style={{ marginLeft: 'auto', display:'flex', alignItems:'center', gap: 8, color: 'rgba(0,0,0,.55)' }}>
            <span style={{ width: 6, height: 6, borderRadius: 99, background: 'var(--bataj-accent)' }} className="pulseDot" />
            ONLINE · LIVE
          </span>
        </>}
      >
        {/* Nav */}
        <div style={{
          position:'absolute', left:0, top:0, width: 200, bottom: 0,
          background: 'color-mix(in srgb, var(--bataj-bg) 60%, var(--bataj-paper))', borderRight:'1px solid rgba(0,0,0,.08)',
          padding: 14, color: 'var(--bataj-ink)',
          opacity: ramp(localTime, 0.3, 0.9),
        }}>
          <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 10, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase', padding:'0 8px', marginBottom: 6 }}>Tenant</div>
          <div style={{ padding:'0 8px', marginBottom: 18, fontSize: 13 }}>Cucina Roma</div>
          <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 10, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase', padding:'0 8px', marginBottom: 6 }}>Vistas</div>
          {[['Órdenes','78','active'],['Cocina','12',''],['Caja','5',''],['Delivery','9',''],['Reportes','—',''],['Settings','—','']].map(([n,c,act], i) => (
            <div key={n} style={{
              padding:'8px 10px', borderRadius: 6, marginBottom: 2,
              display:'flex', justifyContent:'space-between',
              background: act === 'active' ? 'rgba(255,106,0,.12)' : 'transparent',
              color: act === 'active' ? 'var(--bataj-accent)' : 'rgba(0,0,0,.75)',
              fontFamily:'var(--bataj-sans)', fontSize: 13,
            }}>
              <span>{n}</span><span style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, opacity:.7 }}>{c}</span>
            </div>
          ))}
        </div>

        {/* Orders table */}
        <div style={{ position:'absolute', left: 200, right: 320, top: 0, bottom: 0, padding: 20, borderRight: '1px solid rgba(0,0,0,.08)' }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-end', marginBottom: 16 }}>
            <div>
              <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase' }}>Órdenes activas</div>
              <div style={{ fontFamily:'var(--bataj-sans)', fontSize: 22, color:'var(--bataj-ink)', marginTop: 4 }}>
                78 abiertas · <span style={{ color:'var(--bataj-accent)' }}>12 en cocina</span>
              </div>
            </div>
            <div style={{ display:'flex', gap: 6, fontFamily:'JetBrains Mono,monospace', fontSize: 11 }}>
              {['TODO','COCINA','RUTA','LISTO'].map((t, i) => (
                <span key={t} style={{
                  padding: '4px 10px', borderRadius: 4,
                  background: i === 1 ? 'var(--bataj-accent)' : 'transparent',
                  color: i === 1 ? 'var(--bataj-paper)' : 'rgba(0,0,0,.7)',
                  border: i === 1 ? 'none' : '1px solid rgba(0,0,0,.15)',
                }}>{t}</span>
              ))}
            </div>
          </div>
          <table style={{ width: '100%', fontFamily:'JetBrains Mono,monospace', fontSize: 12.5, color:'rgba(0,0,0,.85)', borderCollapse: 'collapse' }}>
            <thead>
              <tr style={{ color:'rgba(0,0,0,.4)', borderBottom: '1px solid rgba(0,0,0,.1)' }}>
                <th style={{ textAlign:'left', padding:'10px 0', fontWeight: 400, width: 72 }}>ID</th>
                <th style={{ textAlign:'left', fontWeight: 400 }}>Cliente</th>
                <th style={{ textAlign:'left', fontWeight: 400 }}>Items</th>
                <th style={{ textAlign:'left', fontWeight: 400, width: 72 }}>⏱</th>
                <th style={{ textAlign:'left', fontWeight: 400, width: 120 }}>Estado</th>
              </tr>
            </thead>
            <tbody>
              {allOrders.map((o) => {
                const a = ramp(localTime, o.tIn, o.tIn + 0.4);
                const st = currentStatus(o);
                const highlighted = o.id === '#3492' && localTime > 3.2;
                return (
                  <tr key={o.id} style={{
                    borderBottom: '1px solid rgba(0,0,0,.06)',
                    opacity: a, color: 'rgba(0,0,0,.85)',
                    background: highlighted ? 'rgba(255,106,0,.05)' : 'transparent',
                    transition: 'background .3s',
                  }}>
                    <td style={{ padding:'12px 0', color:'var(--bataj-ink)' }}>{o.id}</td>
                    <td>{o.cli}</td>
                    <td style={{ color:'rgba(0,0,0,.65)' }}>{o.items}</td>
                    <td style={{ color:'rgba(0,0,0,.7)' }}>{o.base}</td>
                    <td>
                      <span style={{
                        display:'inline-flex', alignItems:'center', gap: 6,
                        padding:'2px 8px', borderRadius: 4, fontSize: 11,
                        color: st.col, border: `1px solid ${st.col}40`,
                        background: `${st.col}10`,
                        transition: 'all .3s',
                      }}>
                        <span style={{ width: 4, height: 4, borderRadius: 99, background: st.col }} />
                        {st.status}
                      </span>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {/* KDS panel */}
        <div style={{ position:'absolute', right: 0, top: 0, width: 320, bottom: 0, padding: 16, background: 'color-mix(in srgb, var(--bataj-bg) 60%, var(--bataj-paper))' }}>
          <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 10, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase', marginBottom: 12 }}>
            KDS · Cocina
          </div>
          {[
            { id:'#3492', items:['Pizza Margarita','Pizza 4 Quesos','Coca 500ml'], baseT: 14 },
            { id:'#3490', items:['Empanada Carne ×2','Empanada Pollo'], baseT: 22, urgent: true },
            { id:'#3493', items:['Ravioles caseros','Tiramisú'], baseT: 3 },
          ].map((k, i) => {
            const a = ramp(localTime, 0.8 + i * 0.2, 1.4 + i * 0.2);
            const tt = k.baseT + (i === 0 ? Math.floor(localTime) : 0);
            const isMarkedReady = i === 0 && localTime > 5.5;
            return (
              <div key={k.id} style={{
                marginBottom: 10, padding: 12, borderRadius: 6,
                border: `1px solid ${k.urgent ? 'var(--bataj-accent)' + '90' : 'rgba(0,0,0,.1)'}`,
                background: k.urgent ? 'rgba(255,106,0,.05)' :
                            isMarkedReady ? 'rgba(255,217,61,.08)' : 'transparent',
                opacity: a, transform: `translateX(${(1 - a) * 18}px)`,
                transition: 'background .3s, border-color .3s',
              }}>
                <div style={{ display:'flex', justifyContent:'space-between', marginBottom: 8 }}>
                  <span style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 12, color:'var(--bataj-ink)' }}>{k.id}</span>
                  <span style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color: k.urgent ? 'var(--bataj-accent)' : 'rgba(0,0,0,.55)' }}>
                    ⏱ 00:{String(tt).padStart(2,'0')}
                  </span>
                </div>
                <ul style={{ margin:0, padding:0, listStyle:'none', fontFamily:'var(--bataj-sans)', fontSize: 12, color:'rgba(0,0,0,.8)' }}>
                  {k.items.map((it, j) => (
                    <li key={it} style={{ display:'flex', alignItems:'center', gap: 8, padding:'3px 0' }}>
                      <span style={{
                        width: 12, height: 12, borderRadius: 3,
                        border: '1px solid rgba(0,0,0,.3)',
                        background: isMarkedReady ? 'var(--bataj-accent)' : 'transparent',
                        display:'grid', placeItems:'center',
                      }}>{isMarkedReady && <span style={{ fontSize: 9, color: 'var(--bataj-paper)' }}>✓</span>}</span>
                      <span style={{ textDecoration: isMarkedReady ? 'line-through' : 'none', opacity: isMarkedReady ? 0.55 : 1 }}>{it}</span>
                    </li>
                  ))}
                </ul>
              </div>
            );
          })}
        </div>
      </WindowFrame>
      <CursorTrail keyframes={[{t:0,x:600,y:400},{t:0.1,x:600,y:400},{t:0.2,x:820,y:87,click:true},{t:0.3,x:820,y:87},{t:0.5,x:600,y:400},{t:1,x:600,y:400}]} />
    </div>
  );
}

function SceneDunamisLive() {
  const isMobile = useIsMobile();
  const { localTime, duration } = useSprite();
  const entry = ramp(localTime, 0, 1.0);
  const exit  = ramp(localTime, duration - 0.8, duration, Easing.easeInCubic);
  const opacity = entry * (1 - exit);

  // Build chart path progressively
  const data = [50,58,55,62,70,68,74,80,77,84,82,90,95,92,100,98,105,110,108,115,122,118,128,134,130,138,142,148,144,152];
  const maxV = Math.max(...data);
  const drawT = ramp(localTime, 1.6, 4.0, Easing.easeOutCubic);
  const drawCount = Math.max(2, Math.floor(drawT * data.length));
  const drawn = data.slice(0, drawCount);
  const chartW = 720, chartH = 220;
  const pts = drawn.map((v, i) => `${(i / (data.length - 1)) * chartW},${chartH - (v / maxV) * (chartH - 20)}`).join(' ');
  const lastPt = drawn.length
    ? { x: ((drawn.length - 1) / (data.length - 1)) * chartW, y: chartH - (drawn[drawn.length - 1] / maxV) * (chartH - 20) }
    : null;

  // KPI tick-ups
  const mrr = (84.2 * ramp(localTime, 0.6, 2.0, Easing.easeOutCubic)).toFixed(1);
  const conv = (4.82 * ramp(localTime, 0.8, 2.2, Easing.easeOutCubic)).toFixed(2);
  const churn = (2.1 * ramp(localTime, 1.0, 2.4, Easing.easeOutCubic)).toFixed(1);
  const aov = Math.floor(142 * ramp(localTime, 1.2, 2.6, Easing.easeOutCubic));

  const alert1 = ramp(localTime, 3.5, 4.2, Easing.easeOutBack);
  const alert2 = ramp(localTime, 4.5, 5.2, Easing.easeOutBack);
  const alert3 = ramp(localTime, 5.5, 6.2, Easing.easeOutBack);

  return (
    <div style={{ position:'absolute', inset:0, opacity }}>
      <CanvasChrome idx={4} total={4} code="BTJ-04" title="DUNAMIS" sub="BI · ANALYTICS · LIVE" accent="#F1B2AC" />
      <SidePanel 
        kicker="BI · Analytics"
        code="BTJ-04 · dunamis.app"
        name="Dunamis"
        tagline="El pulso de tu negocio."
        blurb="Dashboard SaaS de inteligencia comercial. KPIs en tiempo real, alertas inteligentes, historial profundo. Lo abrís entre dos reuniones y entendés todo en 8s."
        stats={[
          { l: 'TIEMPO DE DESPLIEGUE', v: '10x Más Rápido' },
          { l: 'COSTO DE DESARROLLO', v: '-65%' },
          { l: 'ADOPCIÓN DEL EQUIPO', v: '100%' }
        ]}
        stack={['REACT','CLICKHOUSE','D3']}
        accent="#F1B2AC"
      />

      <WindowFrame
        x={isMobile ? -50 : 88} y={isMobile ? 1100 : 170} w={1180} h={780}
        bg="var(--bataj-paper)"
        barBg="var(--bataj-bg)"
        lineColor="rgba(0,0,0,.08)"
        scaleAtEntry={entry}
        bar={<>
          <TrafficDots colors={['#FF5A5A','#FFD93D','var(--bataj-accent)']} />
          <span style={{ marginLeft: 8, color: 'rgba(0,0,0,.55)' }}>dunamis.app / dashboard / Q2 — 26</span>
          <span style={{ marginLeft: 'auto', display:'flex', alignItems:'center', gap: 10, fontFamily:'JetBrains Mono,monospace', color:'rgba(0,0,0,.55)' }}>
            <span style={{ padding:'2px 8px', borderRadius: 4, border: '1px solid rgba(0,0,0,.15)' }}>Últ. 30 días</span>
            <span style={{ padding:'2px 8px', borderRadius: 4, background:'var(--bataj-accent)', color:'var(--bataj-bg)' }}>LIVE</span>
          </span>
        </>}
      >
        <div style={{ padding: 22, color: 'var(--bataj-ink)' }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-end', marginBottom: 18 }}>
            <div>
              <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase' }}>Bienvenida, María</div>
              <div style={{ fontFamily:'var(--bataj-sans)', fontSize: 22, marginTop: 4 }}>
                Hoy el negocio está <span style={{ color:'var(--bataj-accent)' }}>+{mrr === '0.0' ? '0.0' : (mrr * 0.147).toFixed(1)}%</span>
              </div>
            </div>
            <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color:'rgba(0,0,0,.5)', display:'flex', gap: 16 }}>
              <span>Anomalías: <span style={{ color: alert1 + alert2 > 0 ? '#FFD93D' : 'var(--bataj-accent)' }}>{Math.round(alert1 + alert2)}</span></span>
              <span>Conectores: <span style={{ color:'var(--bataj-accent)' }}>6/6 OK</span></span>
            </div>
          </div>

          {/* KPI cards */}
          <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap: 10, marginBottom: 12 }}>
            {[
              { l: 'MRR',        v: `US$ ${mrr}k`,  d: '+8.4%',  col: 'var(--bataj-accent)' },
              { l: 'Conversión', v: `${conv}%`,     d: '+0.6pp', col: 'var(--bataj-accent)' },
              { l: 'Churn',      v: `${churn}%`,    d: '+0.3pp', col: '#FF8C8C' },
              { l: 'AOV',        v: `US$ ${aov}`,   d: '+11.0%', col: 'var(--bataj-accent)' },
            ].map((k) => (
              <div key={k.l} style={{
                padding: 14, borderRadius: 8, background: 'color-mix(in srgb, var(--bataj-bg) 60%, var(--bataj-paper))',
                border:'1px solid rgba(0,0,0,.08)',
              }}>
                <div style={{ display:'flex', justifyContent:'space-between', marginBottom: 4 }}>
                  <span style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase' }}>{k.l}</span>
                  <span style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color: k.col }}>{k.d}</span>
                </div>
                <div style={{
                  fontFamily:'Pixelify Sans, monospace', fontWeight: 700,
                  fontSize: 36, lineHeight: 1, color: 'var(--bataj-ink)', letterSpacing: '-0.03em',
                }}>{k.v}</div>
              </div>
            ))}
          </div>

          {/* Chart + alerts */}
          <div style={{ display:'grid', gridTemplateColumns:'2.2fr 1fr', gap: 10 }}>
            <div style={{ padding: 16, borderRadius: 8, background:'color-mix(in srgb, var(--bataj-bg) 60%, var(--bataj-paper))', border:'1px solid rgba(0,0,0,.08)' }}>
              <div style={{ display:'flex', justifyContent:'space-between', marginBottom: 10 }}>
                <div>
                  <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase' }}>Ingresos · 30 días</div>
                  <div style={{ fontSize: 18 }}>
                    US$ {Math.floor(312480 * ramp(localTime, 1.0, 2.6)).toLocaleString('en-US')}{' '}
                    <span style={{ color:'var(--bataj-accent)', fontFamily:'JetBrains Mono,monospace', fontSize: 12 }}>+18.2%</span>
                  </div>
                </div>
              </div>
              <svg viewBox={`0 0 ${chartW} ${chartH + 16}`} style={{ width:'100%', height: 220, display:'block' }}>
                <defs>
                  <linearGradient id="revG" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="var(--bataj-accent)" stopOpacity=".35" />
                    <stop offset="100%" stopColor="var(--bataj-accent)" stopOpacity="0" />
                  </linearGradient>
                </defs>
                {[0,1,2,3].map((i) => (
                  <line key={i} x1="0" x2={chartW} y1={30 + i * 50} y2={30 + i * 50} stroke="#1B1E27" strokeDasharray="2 4" />
                ))}
                {drawn.length > 1 && (
                  <>
                    <polyline points={`${pts} ${lastPt.x},${chartH} 0,${chartH}`} fill="url(#revG)" />
                    <polyline points={pts} fill="none" stroke="var(--bataj-accent)" strokeWidth="2" />
                    {lastPt && (
                      <circle cx={lastPt.x} cy={lastPt.y} r="5" fill="var(--bataj-accent)" stroke="var(--bataj-paper)" strokeWidth="2" />
                    )}
                  </>
                )}
              </svg>
            </div>

            <div style={{ padding: 16, borderRadius: 8, background:'color-mix(in srgb, var(--bataj-bg) 60%, var(--bataj-paper))', border:'1px solid rgba(0,0,0,.08)' }}>
              <div style={{ display:'flex', justifyContent:'space-between', marginBottom: 12 }}>
                <span style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color:'rgba(0,0,0,.4)', letterSpacing:'0.18em', textTransform:'uppercase' }}>Alertas</span>
                <span style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 11, color:'var(--bataj-accent)' }}>{Math.round(alert1 + alert2)} nuevas</span>
              </div>
              {[
                { t:'Pico de tráfico orgánico',  d:'+312% vs media · hace 14m', col:'var(--bataj-accent)', a: alert1 },
                { t:'Churn detectado plan PRO',  d:'2 cuentas · acción sugerida', col:'#FF8C8C', a: alert2 },
                { t:'Stripe webhook delay',      d:'>4s · revisar conector', col:'#FFD93D', a: alert3 },
              ].map((al, i) => (
                <div key={i} style={{
                  padding:'10px 0',
                  borderBottom: i < 2 ? '1px solid rgba(0,0,0,.06)' : 'none',
                  opacity: al.a, transform: `translateX(${(1 - al.a) * 18}px)`,
                }}>
                  <div style={{ display:'flex', alignItems:'flex-start', gap: 8 }}>
                    <span style={{ marginTop: 6, width: 6, height: 6, borderRadius: 99, background: al.col, flexShrink: 0 }} />
                    <div>
                      <div style={{ fontFamily:'var(--bataj-sans)', fontSize: 12.5, color:'var(--bataj-ink)' }}>{al.t}</div>
                      <div style={{ fontFamily:'JetBrains Mono,monospace', fontSize: 10, color:'rgba(0,0,0,.45)', marginTop: 2 }}>{al.d}</div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </WindowFrame>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   SCENE 5 — STATS  (39 → 46)
   ═══════════════════════════════════════════════════════════════════════ */

function SceneStats() {
  const { localTime, duration } = useSprite();
  const opacity = ramp(localTime, 0, 0.8) * (1 - ramp(localTime, duration - 0.6, duration));

  const stats = [
    { v: 4,     suf:'',    l:'productos en producción' },
    { v: 100,   suf:'%',   l:'diseño + dev integrado' },
    { v: 12,    suf:'sem', l:'a primer launch', pre: '<' },
    { v: 0,     suf:'',    l:'plantillas reutilizadas' },
  ];
  const headerIn = ramp(localTime, 0.2, 1.0);

  return (
    <div style={{ position:'absolute', inset:0, opacity, background:'var(--bataj-bg)' }}>
      <div style={{ position:'absolute', inset: 0, opacity: 0.15, background:'radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--bataj-accent) 30%, transparent), transparent 60%)' }} />
      <div style={{
        position:'absolute', top: 110, left: 96,
        fontFamily:'JetBrains Mono, monospace', fontSize: 16,
        letterSpacing:'0.22em', textTransform:'uppercase',
        color:'color-mix(in srgb, var(--bataj-ink) 60%, transparent)',
        opacity: headerIn, transform: `translateY(${(1 - headerIn) * 12}px)`,
      }}>
        ▸ SEC.04 / PROOF · vital signs
      </div>
      <div style={{
        position:'absolute', top: 150, left: 96,
        fontFamily:'var(--bataj-display)', fontStyle:'italic', fontSize: 96,
        lineHeight: 0.95, color:'var(--bataj-ink)', letterSpacing:'-0.02em',
        opacity: headerIn,
      }}>
        El estudio en <span style={{ color:'var(--bataj-accent)' }}>números</span>.
      </div>

      <div style={{
        position:'absolute', top: 360, left: 96, right: 96, display:'grid',
        gridTemplateColumns:'repeat(4, 1fr)', gap: 40,
      }}>
        {stats.map((s, i) => {
          const a = ramp(localTime, 0.8 + i * 0.18, 1.4 + i * 0.18, Easing.easeOutBack);
          const count = ramp(localTime, 1.0 + i * 0.15, 2.4 + i * 0.15, Easing.easeOutCubic);
          const display = s.v === 100 ? Math.floor(s.v * count)
                        : Math.floor(s.v * count);
          return (
            <div key={i} style={{
              opacity: a, transform: `translateY(${(1 - a) * 30}px)`,
            }}>
              <div style={{
                fontFamily:'Pixelify Sans, monospace', fontWeight: 700,
                fontSize: 220, lineHeight: 0.85, letterSpacing:'-0.04em',
                color:'var(--bataj-accent)',
              }}>{s.pre || ''}{display}{s.suf}</div>
              <div style={{
                fontFamily:'JetBrains Mono, monospace', fontSize: 14,
                letterSpacing:'0.18em', textTransform:'uppercase',
                color:'color-mix(in srgb, var(--bataj-ink) 60%, transparent)',
                marginTop: 16,
              }}>{s.l}</div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   SCENE 6 — PROCESS  (46 → 53)
   ═══════════════════════════════════════════════════════════════════════ */

function SceneProcess() {
  const { localTime, duration } = useSprite();
  const opacity = ramp(localTime, 0, 0.8) * (1 - ramp(localTime, duration - 0.6, duration));

  const steps = [
    { n: '01', t: 'BRIEF',   tag: '1 sem',    d: 'Entendemos el negocio. No el ticket.' },
    { n: '02', t: 'SISTEMA', tag: '2-3 sem',  d: 'Identidad, tokens, voz. Antes de codear.' },
    { n: '03', t: 'BUILD',   tag: '6-12 sem', d: 'Sprints quincenales, deploy continuo.' },
    { n: '04', t: 'LAUNCH',  tag: 'día 1',    d: 'Operativo. Cobranza, soporte, métricas.' },
  ];

  // current step pointer based on time
  const stepLen = (duration - 1.2) / steps.length;
  const idx = Math.min(steps.length - 1, Math.floor((localTime - 0.3) / stepLen));

  return (
    <div style={{ position:'absolute', inset:0, opacity, background:'var(--bataj-paper)' }}>
      <div style={{
        position:'absolute', top: 110, left: 96,
        fontFamily:'JetBrains Mono, monospace', fontSize: 16,
        letterSpacing:'0.22em', textTransform:'uppercase',
        color:'color-mix(in srgb, var(--bataj-ink) 60%, transparent)',
        opacity: ramp(localTime, 0.2, 0.9),
      }}>
        ▸ SEC.05 / PROCESO · de 0 a producto
      </div>
      <div style={{
        position:'absolute', top: 150, left: 96,
        fontFamily:'var(--bataj-display)', fontStyle:'italic', fontSize: 110,
        lineHeight: 0.95, color:'var(--bataj-ink)', letterSpacing:'-0.02em',
        opacity: ramp(localTime, 0.2, 0.9),
      }}>
        De cero a producto. <span style={{ color:'var(--bataj-accent)' }}>En semanas.</span>
      </div>

      {/* Progress rail */}
      <div style={{
        position:'absolute', top: 460, left: 96, right: 96,
        height: 3, background:'color-mix(in srgb, var(--bataj-ink) 15%, transparent)', borderRadius: 99,
      }}>
        <div style={{
          height: 3, background:'var(--bataj-accent)', borderRadius: 99,
          width: `${ramp(localTime, 0.5, duration - 0.5) * 100}%`,
          transition: 'width .2s linear',
        }} />
      </div>

      <div style={{
        position:'absolute', top: 500, left: 96, right: 96,
        display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap: 30,
      }}>
        {steps.map((s, i) => {
          const a = ramp(localTime, 0.4 + i * 0.5, 1.0 + i * 0.5, Easing.easeOutBack);
          const active = i === idx;
          return (
            <div key={s.n} style={{
              padding: 28, borderRadius: 12,
              background: active ? 'var(--bataj-bg)' : 'transparent',
              border: `1px solid color-mix(in srgb, var(--bataj-ink) ${active ? 30 : 12}%, transparent)`,
              opacity: a, transform: `translateY(${(1 - a) * 24}px)`,
              transition: 'background .25s, border-color .25s',
            }}>
              <div style={{ display:'flex', justifyContent:'space-between', marginBottom: 32 }}>
                <span style={{
                  fontFamily:'Pixelify Sans, monospace', fontWeight: 700,
                  fontSize: 36, lineHeight: 1, color: active ? 'var(--bataj-accent)' : 'color-mix(in srgb, var(--bataj-ink) 40%, transparent)',
                  letterSpacing:'-0.03em',
                }}>{s.n}</span>
                <span style={{
                  fontFamily:'JetBrains Mono, monospace', fontSize: 11,
                  letterSpacing:'0.18em', textTransform:'uppercase',
                  color:'color-mix(in srgb, var(--bataj-ink) 50%, transparent)',
                }}>{s.tag}</span>
              </div>
              <h4 style={{
                fontFamily:'Pixelify Sans, monospace', fontWeight: 700,
                fontSize: 56, lineHeight: 0.95, color:'var(--bataj-ink)',
                letterSpacing:'-0.03em', margin: 0, marginBottom: 12,
              }}>{s.t}</h4>
              <p style={{
                fontFamily:'var(--bataj-sans)', fontSize: 15, lineHeight: 1.4,
                color:'color-mix(in srgb, var(--bataj-ink) 70%, transparent)',
                margin: 0,
              }}>{s.d}</p>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   SCENE 7 — OUTRO  (53 → 60)
   ═══════════════════════════════════════════════════════════════════════ */

function SceneOutro() {
  const { localTime, duration } = useSprite();
  const a1 = ramp(localTime, 0.2, 1.2, Easing.easeOutBack);
  const a2 = ramp(localTime, 1.4, 2.4);
  const a3 = ramp(localTime, 2.8, 3.6);
  const out = 1 - ramp(localTime, duration - 0.6, duration);

  return (
    <div style={{ position:'absolute', inset:0, opacity: out }}>
      <div style={{
        position:'absolute', top: '22%', left: 96, right: 96,
        fontFamily:'JetBrains Mono, monospace', fontSize: 22,
        letterSpacing:'0.22em', textTransform:'uppercase',
        color:'color-mix(in srgb, var(--bataj-ink) 60%, transparent)',
        opacity: a1, transform: `translateY(${(1 - a1) * 14}px)`,
      }}>
        ▸ MISMO ESTUDIO · CUATRO LENGUAJES
      </div>

      <div style={{
        position:'absolute', top: '30%', left: 96,
        fontFamily:'var(--bataj-display)', fontStyle:'italic',
        fontSize: 220, lineHeight: 0.9, letterSpacing:'-0.02em',
        color:'var(--bataj-ink)',
        opacity: a1, transform: `translateY(${(1 - a1) * 40}px)`,
      }}>
        Cuatro
      </div>
      <div style={{
        position:'absolute', top: '46%', left: 200,
        fontFamily:'Pixelify Sans, monospace', fontWeight: 700,
        fontSize: 220, lineHeight: 0.85, letterSpacing:'-0.04em',
        color:'var(--bataj-accent)',
        opacity: a2, transform: `translateY(${(1 - a2) * 40}px)`,
      }}>
        UNIVERSOS<span style={{ color:'color-mix(in srgb, var(--bataj-ink) 40%, transparent)' }}>.</span>
      </div>

      <div style={{
        position:'absolute', bottom: '14%', left: 96, right: 96,
        display:'flex', justifyContent:'space-between', alignItems:'flex-end',
        opacity: a3, transform: `translateY(${(1 - a3) * 24}px)`,
      }}>
        <div style={{
          fontFamily:'var(--bataj-display)', fontStyle:'italic',
          fontSize: 64, lineHeight: 1, color:'var(--bataj-ink)',
        }}>
          ↓ contemos el <span style={{ color:'var(--bataj-accent)' }}>quinto</span>.
        </div>
        <div style={{
          fontFamily:'JetBrains Mono, monospace', fontSize: 22,
          letterSpacing:'0.18em', textTransform:'uppercase',
          color:'var(--bataj-ink)',
          padding:'18px 28px', border:'2px solid var(--bataj-ink)', borderRadius: 8,
        }}>
          ▸ hola@bataj.systems
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   COMPOSITION
   ═══════════════════════════════════════════════════════════════════════ */

function ProductsScrollReel() {
  return (
    <section id="products" className="relative">
      <ScrollStage
        width={1920} height={1080} duration={39} scrollVH={1200}
        label="Bataj.reel · catálogo"
      >
        <Sprite start={0}    end={3.0}><SceneIntro /></Sprite>
        <Sprite start={3.0}  end={12.0}><SceneTurnosLive /></Sprite>
        <Sprite start={12.0} end={21.0}><SceneSakLive /></Sprite>
        <Sprite start={21.0} end={30.0}><SceneDeliveryLive /></Sprite>
        <Sprite start={30.0} end={39.0}><SceneDunamisLive /></Sprite>
      </ScrollStage>
    </section>
  );
}

Object.assign(window, { ProductsScrollReel });
