// Scene components for all 5 reels.
// Each scene is ~10-20s, dimensions 540×960 (9:16 portrait).
// CTA across all: wnbpc.app — free 3-min AI Readiness Index, no signup.

const W = 540, H = 960;

// ─── Brand tokens ───
const INK = '#1F1F23';
const PURPLE = '#6B53A3';
const PURPLE_DEEP = '#2E205E';
const PURPLE_LIGHT = '#9985BF';
const PURPLE_WASH = '#ECE7F5';
const CARD = '#E7DFF3';
const WHITE = '#FFFFFF';
const WARN = '#C97C18';
const MUTED = '#6D6D78';

const FONT_DISPLAY = 'Manrope, system-ui, sans-serif';
const FONT_BODY = 'Inter, system-ui, sans-serif';
const FONT_MONO = 'JetBrains Mono, ui-monospace, monospace';

// ─── Shared overlays ───
function BrandChip({ top = 24 }) {
  return (
    <div style={{
      position:'absolute', top, left:24, display:'flex', alignItems:'center', gap:8, zIndex:50,
      fontFamily:FONT_DISPLAY, fontWeight:700, fontSize:15, color:'#fff',
      mixBlendMode:'normal'
    }}>
      <img src="../assets/dkube_icon_logo.avif" style={{height:20, filter:'brightness(0) invert(1)'}}/>
      DKube
      <span style={{width:1,height:12,background:'rgba(255,255,255,.3)',margin:'0 4px'}}/>
      <span style={{fontFamily:FONT_MONO, fontSize:10, letterSpacing:'.08em', color:'rgba(255,255,255,.7)'}}>READINESS INDEX</span>
    </div>
  );
}
function BrandChipDark({ top = 24 }) {
  return (
    <div style={{
      position:'absolute', top, left:24, display:'flex', alignItems:'center', gap:8, zIndex:50,
      fontFamily:FONT_DISPLAY, fontWeight:700, fontSize:15, color:INK,
    }}>
      <img src="../assets/dkube_icon_logo.avif" style={{height:20}}/>
      DKube
      <span style={{width:1,height:12,background:'rgba(0,0,0,.2)',margin:'0 4px'}}/>
      <span style={{fontFamily:FONT_MONO, fontSize:10, letterSpacing:'.08em', color:MUTED}}>READINESS INDEX</span>
    </div>
  );
}

// Finale CTA card — used by all reels in the last ~3s
function CTACard({ start, duration, darkBg = true }) {
  return (
    <Sprite start={start} end={start + duration}>
      {({ progress, localTime }) => {
        const ease = Easing.easeOutBack(clamp(localTime/0.5, 0, 1));
        const exitP = localTime > duration - 0.3 ? Easing.easeInQuad((localTime-(duration-0.3))/0.3) : 0;
        const ty = (1-ease)*40 - exitP*20;
        const op = ease * (1 - exitP);
        return (
          <div style={{
            position:'absolute', left:0, right:0, bottom:0,
            padding:'40px 32px 56px',
            transform:`translateY(${ty}px)`, opacity:op,
            background: darkBg
              ? 'linear-gradient(180deg, rgba(14,11,20,0) 0%, rgba(14,11,20,.88) 35%, rgba(14,11,20,.96) 100%)'
              : 'linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.9) 35%, #fff 100%)',
            zIndex:60,
          }}>
            <div style={{fontFamily:FONT_MONO, fontSize:11, letterSpacing:'.16em', color:darkBg?PURPLE_LIGHT:PURPLE, textTransform:'uppercase', fontWeight:700, marginBottom:10}}>
              Free · 3 minutes · No signup
            </div>
            <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:38, lineHeight:1.05, color:darkBg?'#fff':INK, letterSpacing:'-.02em', marginBottom:6}}>
              Take the AI<br/>Readiness Index.
            </div>
            <div style={{fontFamily:FONT_BODY, fontSize:15, color:darkBg?'rgba(255,255,255,.72)':MUTED, lineHeight:1.4, marginBottom:22}}>
              30 questions. Honest answers. A real timeline for AI in your company.
            </div>
            <div style={{
              display:'inline-flex', alignItems:'center', gap:10,
              background:'#fff', color:INK, padding:'14px 22px', borderRadius:999,
              fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:17, letterSpacing:'-.005em',
              boxShadow:'0 8px 24px rgba(0,0,0,.3)'
            }}>
              <span style={{fontFamily:FONT_MONO, fontSize:12, color:PURPLE, fontWeight:700}}>→</span>
              wnbpc.app
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

// Animated timer / progress 3 min indicator
function ThreeMinBadge({ start, end }) {
  return (
    <Sprite start={start} end={end}>
      {({ localTime, duration }) => {
        const op = Easing.easeOutCubic(clamp(localTime/0.4, 0, 1));
        const p = clamp(localTime/duration, 0, 1);
        return (
          <div style={{
            position:'absolute', top:24, right:24, zIndex:50,
            display:'flex', alignItems:'center', gap:8,
            background:'rgba(14,11,20,.7)', backdropFilter:'blur(6px)',
            padding:'6px 12px', borderRadius:999, opacity:op,
            fontFamily:FONT_MONO, fontSize:11, color:'#fff', letterSpacing:'.06em'
          }}>
            <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
              <circle cx="6" cy="6" r="5" stroke="rgba(255,255,255,.3)" strokeWidth="1.5"/>
              <path d={`M 6 6 L 6 1 A 5 5 0 ${p > 0.5 ? 1 : 0} 1 ${6 + 5*Math.sin(p*2*Math.PI)} ${6 - 5*Math.cos(p*2*Math.PI)} Z`} fill={PURPLE_LIGHT}/>
            </svg>
            3 MIN
          </div>
        );
      }}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════
// REEL 1 — "The Buyer's Monday" (15s)
// Storyline: A pile of unread PDFs crashes down → 80% highlighted → exceptions only → CTA
// ════════════════════════════════════════════════════════════════
function Reel1_BuyerMonday() {
  return (
    <>
      {/* Stage background */}
      <div style={{position:'absolute', inset:0, background:'#FBE8E5'}}/>

      <BrandChipDark top={24}/>
      <ThreeMinBadge start={11.5} end={15}/>

      {/* 0-3s: Monday opener */}
      <Sprite start={0} end={3.2}>
        {({localTime}) => {
          const op = Easing.easeOutCubic(clamp(localTime/0.4,0,1)) * (1 - Easing.easeInQuad(clamp((localTime-2.8)/0.4,0,1)));
          const ty = (1-Easing.easeOutCubic(clamp(localTime/0.4,0,1))) * 20;
          return (
            <div style={{position:'absolute',inset:0,display:'flex',flexDirection:'column',justifyContent:'center',padding:'0 40px',opacity:op,transform:`translateY(${ty}px)`}}>
              <div style={{fontFamily:FONT_MONO,fontSize:13,color:'#7a1a12',letterSpacing:'.16em',fontWeight:700,marginBottom:16}}>MONDAY · 8:47 AM</div>
              <div style={{fontFamily:FONT_DISPLAY,fontWeight:800,fontSize:54,lineHeight:1.02,color:'#2a0a05',letterSpacing:'-.025em'}}>
                Your buyer<br/>opens her inbox.
              </div>
            </div>
          );
        }}
      </Sprite>

      {/* 2.8-7s: PDF pile crashing down */}
      <Sprite start={2.8} end={7.5}>
        {({localTime}) => {
          const docs = Array.from({length: 14}, (_, i) => i);
          return (
            <div style={{position:'absolute', inset:0, overflow:'hidden'}}>
              {docs.map(i => {
                const delay = 0.15 + i*0.12;
                const t = Math.max(0, localTime - delay);
                const fall = Easing.easeInQuad(clamp(t/0.6, 0, 1));
                const bounce = t > 0.6 ? Math.sin((t-0.6)*14) * Math.exp(-(t-0.6)*5) * 8 : 0;
                const y = -200 + fall * (400 + i*18) + bounce;
                const rot = -30 + Math.sin(i*2.7)*60;
                const left = 30 + (i*37)%480;
                return (
                  <div key={i} style={{
                    position:'absolute', left, top:y,
                    width: 120, height: 156, background:'#fff',
                    borderRadius:6, padding:12,
                    transform:`rotate(${rot}deg)`,
                    boxShadow:'0 6px 18px rgba(0,0,0,.18)',
                    border:'1px solid rgba(0,0,0,.08)'
                  }}>
                    <div style={{fontFamily:FONT_MONO, fontSize:7, color:'#7a1a12', fontWeight:700, marginBottom:6}}>PO / INV</div>
                    {[.9,.7,.8,.6,.75,.5].map((w,j)=>(
                      <div key={j} style={{height:3, background:'#E7E4EE', borderRadius:99, marginBottom:3, width:`${w*100}%`}}/>
                    ))}
                  </div>
                );
              })}
            </div>
          );
        }}
      </Sprite>

      <Sprite start={4} end={7}>
        {({localTime}) => {
          const op = Easing.easeOutCubic(clamp(localTime/0.4, 0, 1)) * (1 - Easing.easeInQuad(clamp((localTime-2.6)/0.4,0,1)));
          return (
            <div style={{position:'absolute', left:0, right:0, bottom:120, textAlign:'center', opacity:op, zIndex:10}}>
              <div style={{display:'inline-block', background:'#fff', padding:'14px 26px', borderRadius:99, boxShadow:'0 10px 30px rgba(0,0,0,.2)'}}>
                <span style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:30, color:INK, letterSpacing:'-.01em'}}>1,247</span>
                <span style={{fontFamily:FONT_BODY, fontSize:14, color:MUTED, marginLeft:8}}>supplier docs. This week.</span>
              </div>
            </div>
          );
        }}
      </Sprite>

      {/* 7-11.5s: The question that stops her */}
      <Sprite start={7} end={11.5}>
        {({localTime}) => {
          const p1 = Easing.easeOutCubic(clamp(localTime/0.5, 0, 1));
          const bgOp = clamp(localTime/0.4, 0, 1);
          return (
            <>
              <div style={{position:'absolute', inset:0, background:PURPLE_DEEP, opacity:bgOp}}/>
              <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', justifyContent:'center', padding:'0 40px', opacity:p1, transform:`translateY(${(1-p1)*20}px)`}}>
                <div style={{fontFamily:FONT_MONO, fontSize:13, color:PURPLE_LIGHT, letterSpacing:'.16em', fontWeight:700, marginBottom:18}}>WAIT —</div>
                <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:46, lineHeight:1.05, color:'#fff', letterSpacing:'-.02em', textWrap:'balance'}}>
                  Is your company<br/>even <span style={{color:PURPLE_LIGHT, fontStyle:'italic', fontWeight:500}}>ready</span> for AI<br/>to do this?
                </div>
                <div style={{fontFamily:FONT_BODY, fontSize:16, color:'rgba(255,255,255,.7)', marginTop:20, lineHeight:1.4, maxWidth:420}}>
                  Data. Workflows. Integration surface. People. It's not a guess.
                </div>
              </div>
            </>
          );
        }}
      </Sprite>

      <CTACard start={11.5} duration={3.5} darkBg={true}/>
      <div style={{position:'absolute', inset:0, background:PURPLE_DEEP, zIndex:-1}}/>
    </>
  );
}

// ════════════════════════════════════════════════════════════════
// REEL 2 — "30 Questions. 3 Minutes." (12s)
// Storyline: Question cards flip through rapidly → timer counts down → CTA
// ════════════════════════════════════════════════════════════════
function Reel2_ThirtyQuestions() {
  const questions = [
    "How many suppliers send you PDFs?",
    "Is your ERP API-accessible?",
    "Who owns data quality today?",
    "Do buyers have line-level visibility?",
    "How many exceptions per week?",
    "Is procurement on one system?",
    "What % of POs match first time?",
    "Do you have a cloud preference?",
    "Who signs off on invoices?",
    "How fast must anomalies surface?",
  ];
  return (
    <>
      <div style={{position:'absolute', inset:0, background:PURPLE_WASH}}/>
      <BrandChipDark top={24}/>

      {/* Opener */}
      <Sprite start={0} end={2.2}>
        {({localTime}) => {
          const op = Easing.easeOutCubic(clamp(localTime/0.35, 0, 1)) * (1 - Easing.easeInQuad(clamp((localTime-1.85)/0.35, 0, 1)));
          return (
            <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', justifyContent:'center', padding:'0 40px', opacity:op}}>
              <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:62, lineHeight:.95, color:INK, letterSpacing:'-.03em'}}>
                30<br/>questions.
              </div>
              <div style={{fontFamily:FONT_DISPLAY, fontWeight:700, fontSize:36, color:PURPLE, marginTop:18, letterSpacing:'-.02em'}}>
                ~3 minutes.
              </div>
              <div style={{fontFamily:FONT_BODY, fontSize:16, color:MUTED, marginTop:16, maxWidth:400, lineHeight:1.45}}>
                That's the whole thing. No signup. No sales call.
              </div>
            </div>
          );
        }}
      </Sprite>

      {/* Rapid question cards 2-8.5s */}
      <Sprite start={2} end={8.5}>
        {({localTime}) => {
          const perCard = 0.6;
          const activeIdx = Math.min(questions.length - 1, Math.floor(localTime / perCard));
          const local = (localTime - activeIdx * perCard) / perCard;
          return (
            <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', justifyContent:'center', padding:'0 36px'}}>
              <div style={{fontFamily:FONT_MONO, fontSize:12, color:MUTED, letterSpacing:'.14em', fontWeight:700, marginBottom:14}}>
                QUESTION <span style={{color:PURPLE, fontSize:15}}>{String(activeIdx+1).padStart(2,'0')}</span> / 30
              </div>
              <div style={{
                background:'#fff', border:`1.5px solid ${PURPLE_LIGHT}`, borderRadius:18, padding:24,
                boxShadow:'0 12px 32px rgba(46,32,94,.14)',
                transform:`translateX(${(1-Easing.easeOutCubic(clamp(local*3, 0, 1)))*30}px) rotate(${(1-local)*-1.2}deg)`,
                opacity: Easing.easeOutCubic(clamp(local*3, 0, 1))
              }}>
                <div style={{fontFamily:FONT_DISPLAY, fontWeight:700, fontSize:22, color:INK, lineHeight:1.2, marginBottom:18, letterSpacing:'-.015em'}}>
                  {questions[activeIdx]}
                </div>
                <div style={{display:'flex', flexDirection:'column', gap:8}}>
                  {['Not yet','Some of them','Most','All'].map((opt, i) => (
                    <div key={i} style={{
                      padding:'10px 14px', borderRadius:10,
                      background: i===1 ? PURPLE_WASH : '#F7F5FB',
                      border: i===1 ? `1.5px solid ${PURPLE}` : '1px solid #E7E4EE',
                      fontFamily:FONT_BODY, fontSize:13, color: i===1 ? PURPLE_DEEP : MUTED, fontWeight: i===1 ? 600 : 400,
                      display:'flex', alignItems:'center', gap:10
                    }}>
                      <div style={{
                        width:14, height:14, borderRadius:99,
                        border:`1.5px solid ${i===1 ? PURPLE : '#C8C4D4'}`,
                        background: i===1 ? PURPLE : 'transparent',
                        display:'flex', alignItems:'center', justifyContent:'center'
                      }}>
                        {i===1 && <div style={{width:6, height:6, borderRadius:99, background:'#fff'}}/>}
                      </div>
                      {opt}
                    </div>
                  ))}
                </div>
              </div>
              <div style={{marginTop:18, height:4, background:'rgba(0,0,0,.08)', borderRadius:99, overflow:'hidden'}}>
                <div style={{height:'100%', background:PURPLE, width:`${(activeIdx+local)/questions.length*100}%`, transition:'none'}}/>
              </div>
            </div>
          );
        }}
      </Sprite>

      <CTACard start={8.5} duration={3.5} darkBg={false}/>
      <div style={{position:'absolute', inset:0, background:PURPLE_WASH, zIndex:-1}}/>
    </>
  );
}

// ════════════════════════════════════════════════════════════════
// REEL 3 — "Score + Timeline" (14s)
// Storyline: Score gauge fills → 12 week roadmap draws → CTA
// ════════════════════════════════════════════════════════════════
function Reel3_ScoreTimeline() {
  return (
    <>
      <div style={{position:'absolute', inset:0, background:'#0E0B14'}}/>
      {/* Ambient orb */}
      <Sprite start={0} end={14}>
        {({localTime, duration}) => {
          const x = Math.sin(localTime*.3)*60;
          const y = Math.cos(localTime*.25)*40;
          return (
            <div style={{position:'absolute', top:-150+y, left:-100+x, width:500, height:500, borderRadius:'50%',
              background:'radial-gradient(circle, rgba(153,133,191,.35), transparent 65%)', filter:'blur(20px)'}}/>
          );
        }}
      </Sprite>
      <BrandChip top={24}/>

      {/* 0-2s hook */}
      <Sprite start={0} end={2.2}>
        {({localTime}) => {
          const op = Easing.easeOutCubic(clamp(localTime/0.4, 0, 1)) * (1 - Easing.easeInQuad(clamp((localTime-1.8)/0.4, 0, 1)));
          return (
            <div style={{position:'absolute', top:140, left:40, right:40, opacity:op}}>
              <div style={{fontFamily:FONT_MONO, fontSize:12, color:PURPLE_LIGHT, letterSpacing:'.16em', fontWeight:700, marginBottom:12}}>
                YOU'LL SEE THIS AT THE END.
              </div>
              <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:44, lineHeight:1.02, color:'#fff', letterSpacing:'-.02em'}}>
                An honest<br/>readiness score.
              </div>
            </div>
          );
        }}
      </Sprite>

      {/* 2-7s gauge fills to 68% */}
      <Sprite start={2} end={7.5}>
        {({localTime}) => {
          const fillP = Easing.easeOutCubic(clamp(localTime/2.5, 0, 1));
          const value = Math.round(fillP * 68);
          const op = Easing.easeOutCubic(clamp(localTime/0.4, 0, 1)) * (1 - Easing.easeInQuad(clamp((localTime-5.1)/0.4, 0, 1)));
          const radius = 130;
          const circ = 2 * Math.PI * radius;
          return (
            <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', opacity:op}}>
              <svg width="340" height="340" viewBox="-170 -170 340 340" style={{transform:'rotate(-90deg)'}}>
                <circle cx="0" cy="0" r={radius} fill="none" stroke="rgba(255,255,255,.1)" strokeWidth="18"/>
                <circle cx="0" cy="0" r={radius} fill="none" stroke={PURPLE_LIGHT} strokeWidth="18"
                        strokeDasharray={circ} strokeDashoffset={circ * (1 - fillP*0.68)}
                        strokeLinecap="round"/>
              </svg>
              <div style={{position:'absolute', textAlign:'center'}}>
                <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:96, color:'#fff', letterSpacing:'-.04em', lineHeight:.9, fontVariantNumeric:'tabular-nums'}}>
                  {value}<span style={{fontSize:40, color:PURPLE_LIGHT}}>/100</span>
                </div>
                <div style={{fontFamily:FONT_MONO, fontSize:12, color:PURPLE_LIGHT, letterSpacing:'.2em', fontWeight:700, marginTop:8}}>
                  READINESS INDEX
                </div>
                {fillP > 0.9 && (
                  <div style={{marginTop:14, fontFamily:FONT_DISPLAY, fontWeight:600, fontSize:18, color:'#fff', opacity:Easing.easeOutCubic(clamp((fillP-.9)*10,0,1))}}>
                    Ready for a pilot. Not for production.
                  </div>
                )}
              </div>
            </div>
          );
        }}
      </Sprite>

      {/* 7-10.5s: 12-week timeline draws */}
      <Sprite start={7} end={10.8}>
        {({localTime, duration}) => {
          const drawP = Easing.easeInOutCubic(clamp(localTime/2, 0, 1));
          const op = Easing.easeOutCubic(clamp(localTime/0.4, 0, 1)) * (1 - Easing.easeInQuad(clamp((localTime-3.4)/0.4, 0, 1)));
          return (
            <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', justifyContent:'center', padding:'0 40px', opacity:op}}>
              <div style={{fontFamily:FONT_MONO, fontSize:12, color:PURPLE_LIGHT, letterSpacing:'.16em', fontWeight:700, marginBottom:12}}>YOUR PATH</div>
              <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:36, color:'#fff', letterSpacing:'-.02em', marginBottom:28, lineHeight:1.05}}>
                A real timeline.<br/>Not a wishful one.
              </div>
              <div style={{position:'relative', height:120}}>
                <div style={{position:'absolute', top:28, left:0, right:0, height:3, background:'rgba(255,255,255,.1)', borderRadius:99}}/>
                <div style={{position:'absolute', top:28, left:0, width:`${drawP*100}%`, height:3, background:PURPLE_LIGHT, borderRadius:99}}/>
                {[
                  {w:'Wk 2', t:'Data audit', x:0},
                  {w:'Wk 6', t:'Pilot', x:33},
                  {w:'Wk 10', t:'Integration', x:66},
                  {w:'Wk 12', t:'Production', x:100},
                ].map((m, i) => {
                  const appear = Easing.easeOutBack(clamp((drawP - i*0.22)*4, 0, 1));
                  return (
                    <div key={i} style={{position:'absolute', left:`calc(${m.x}% - ${m.x === 0 ? 0 : m.x === 100 ? 40 : 20}px)`, top:0, transform:`scale(${appear}) translateY(${(1-appear)*10}px)`, opacity:appear}}>
                      <div style={{width:16,height:16,borderRadius:99,background:i===3?'#fff':PURPLE_LIGHT,border:'3px solid #0E0B14',margin:'20px auto 10px'}}/>
                      <div style={{fontFamily:FONT_MONO, fontSize:10, color:PURPLE_LIGHT, letterSpacing:'.1em', fontWeight:700, textAlign:'center'}}>{m.w}</div>
                      <div style={{fontFamily:FONT_DISPLAY, fontSize:13, color:'#fff', fontWeight:600, textAlign:'center', marginTop:4, whiteSpace:'nowrap'}}>{m.t}</div>
                    </div>
                  );
                })}
              </div>
            </div>
          );
        }}
      </Sprite>

      <CTACard start={10.5} duration={3.5} darkBg={true}/>
    </>
  );
}

// ════════════════════════════════════════════════════════════════
// REEL 4 — "Stop Guessing" (10s)
// Storyline: Question-mark chaos → clarity. Fast punchy text reel.
// ════════════════════════════════════════════════════════════════
function Reel4_StopGuessing() {
  const beats = [
    { t:0,   text:"Can AI do this for us?", sub:"You've been asked.", color:'#fff', bg:INK },
    { t:2,   text:"When can we start?",     sub:"You've been asked.", color:'#fff', bg:INK },
    { t:4,   text:"How much will it cost?", sub:"You've been asked.", color:'#fff', bg:INK },
    { t:6,   text:"Stop guessing.",          sub:"Start measuring.",    color:'#fff', bg:PURPLE_DEEP },
  ];

  return (
    <>
      <div style={{position:'absolute', inset:0, background:INK}}/>
      <BrandChip top={24}/>

      {beats.map((b, i) => (
        <Sprite key={i} start={b.t} end={b.t + (i===beats.length-1 ? 1.5 : 2.1)}>
          {({ localTime, duration }) => {
            const inEase = Easing.easeOutBack(clamp(localTime/0.4, 0, 1));
            const outStart = duration - 0.35;
            const outP = localTime > outStart ? Easing.easeInQuad(clamp((localTime-outStart)/0.35, 0, 1)) : 0;
            const op = inEase * (1 - outP);
            const scale = 0.92 + 0.08*inEase;
            const ty = (1-inEase)*12 - outP*12;
            return (
              <>
                <div style={{position:'absolute', inset:0, background:b.bg, opacity: localTime < 0.3 ? Easing.easeOutCubic(localTime/0.3) : (outP > 0 ? 1 - outP*0.2 : 1)}}/>
                <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', justifyContent:'center', padding:'0 40px'}}>
                  <div style={{fontFamily:FONT_MONO, fontSize:12, color:PURPLE_LIGHT, letterSpacing:'.2em', fontWeight:700, marginBottom:14, opacity:op}}>
                    {b.sub.toUpperCase()}
                  </div>
                  <div style={{
                    fontFamily:FONT_DISPLAY, fontWeight:800, fontSize: i===beats.length-1 ? 62 : 52, lineHeight:1.02, color:b.color, letterSpacing:'-.025em',
                    opacity:op, transform:`translateY(${ty}px) scale(${scale})`, transformOrigin:'left center', textWrap:'balance'
                  }}>
                    {b.text}
                  </div>
                </div>

                {/* floating question marks for first 3 beats */}
                {i < 3 && Array.from({length:6}).map((_,k) => {
                  const delay = k*0.2;
                  const ph = clamp((localTime-delay)/1.2, 0, 1);
                  const drift = Math.sin((localTime+k)*1.5)*8;
                  return (
                    <div key={k} style={{
                      position:'absolute',
                      left: 40 + (k*83)%460,
                      top: 200 + (k*127)%500,
                      fontFamily:FONT_DISPLAY, fontWeight:800, fontSize: 80 + (k%3)*24,
                      color:'rgba(153,133,191,.12)', letterSpacing:'-.02em',
                      opacity:ph * (1 - outP), transform:`translateY(${drift}px) rotate(${(k%2?-1:1)*6}deg)`,
                      pointerEvents:'none', userSelect:'none'
                    }}>?</div>
                  );
                })}
              </>
            );
          }}
        </Sprite>
      ))}

      <CTACard start={7.5} duration={2.5} darkBg={true}/>
    </>
  );
}

// ════════════════════════════════════════════════════════════════
// REEL 5 — "The Four Quadrants" (18s)
// Storyline: 4 readiness dimensions reveal one by one → score drops in → CTA
// Data / Workflow / Integration / People
// ════════════════════════════════════════════════════════════════
function Reel5_FourDimensions() {
  const quads = [
    { t:2.2, label:'DATA',        q:'Is it clean? Accessible? Labeled?',      icon:'data',    score:74 },
    { t:5.0, label:'WORKFLOWS',   q:'Do they even live in software yet?',     icon:'flow',    score:58 },
    { t:7.8, label:'INTEGRATION', q:'Can AI plug into your ERP tomorrow?',    icon:'plug',    score:62 },
    { t:10.6,label:'PEOPLE',      q:'Will buyers actually use it?',           icon:'people',  score:81 },
  ];

  const Icon = ({ type, color, size=28 }) => {
    const common = { stroke: color, strokeWidth: 1.75, fill: 'none', strokeLinecap: 'round', strokeLinejoin: 'round' };
    if (type === 'data') return (
      <svg width={size} height={size} viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="7" ry="2.5" {...common}/><path d="M5 5v7c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5V5" {...common}/><path d="M5 12v7c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-7" {...common}/></svg>
    );
    if (type === 'flow') return (
      <svg width={size} height={size} viewBox="0 0 24 24"><rect x="3" y="4" width="6" height="6" rx="1" {...common}/><rect x="15" y="14" width="6" height="6" rx="1" {...common}/><path d="M9 7h4a2 2 0 0 1 2 2v5" {...common}/></svg>
    );
    if (type === 'plug') return (
      <svg width={size} height={size} viewBox="0 0 24 24"><path d="M9 2v5M15 2v5M7 7h10v4a5 5 0 0 1-10 0z" {...common}/><path d="M12 16v5" {...common}/></svg>
    );
    return (
      <svg width={size} height={size} viewBox="0 0 24 24"><circle cx="9" cy="8" r="3" {...common}/><circle cx="17" cy="10" r="2.5" {...common}/><path d="M3 20c0-3 2.7-5 6-5s6 2 6 5M14 20c0-2.5 1.7-4 4-4s4 1.5 4 4" {...common}/></svg>
    );
  };

  return (
    <>
      <div style={{position:'absolute', inset:0, background:'#fff'}}/>
      <BrandChipDark top={24}/>
      <ThreeMinBadge start={14.5} end={18}/>

      {/* Opener */}
      <Sprite start={0} end={2.3}>
        {({localTime}) => {
          const op = Easing.easeOutCubic(clamp(localTime/0.4, 0, 1)) * (1 - Easing.easeInQuad(clamp((localTime-1.9)/0.4, 0, 1)));
          return (
            <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', justifyContent:'center', padding:'0 40px', opacity:op}}>
              <div style={{fontFamily:FONT_MONO, fontSize:12, color:PURPLE, letterSpacing:'.16em', fontWeight:700, marginBottom:16}}>
                AI READINESS · 4 DIMENSIONS
              </div>
              <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:54, lineHeight:1.02, color:INK, letterSpacing:'-.03em'}}>
                Readiness isn't<br/>one thing.
              </div>
              <div style={{fontFamily:FONT_BODY, fontSize:16, color:MUTED, marginTop:14, maxWidth:400, lineHeight:1.4}}>
                It's four. We measure all of them.
              </div>
            </div>
          );
        }}
      </Sprite>

      {/* Quadrants appear in top 2x2 grid */}
      {quads.map((q, i) => {
        const col = i % 2, row = Math.floor(i/2);
        return (
          <Sprite key={i} start={q.t} end={14.8}>
            {({localTime}) => {
              const lt = localTime;
              const appearP = Easing.easeOutBack(clamp(lt/0.5, 0, 1));
              const x = 30 + col * 244;
              const y = 120 + row * 220;
              return (
                <div style={{
                  position:'absolute', left:x, top:y, width:236, height:200,
                  background: i === (Math.floor((lt)*4)%4 === i ? i : -1) ? PURPLE_WASH : PURPLE_WASH,
                  borderRadius:16, padding:20, border:`1.5px solid ${PURPLE_HAIRLINE()}`,
                  transform:`scale(${appearP}) translateY(${(1-appearP)*20}px)`, opacity: appearP,
                  boxShadow:'0 10px 28px rgba(46,32,94,.08)'
                }}>
                  <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:10}}>
                    <div style={{width:40, height:40, background:PURPLE, borderRadius:10, display:'flex', alignItems:'center', justifyContent:'center'}}>
                      <Icon type={q.icon} color="#fff"/>
                    </div>
                    <div style={{fontFamily:FONT_MONO, fontSize:10, color:PURPLE, fontWeight:700, letterSpacing:'.12em'}}>0{i+1}</div>
                  </div>
                  <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:18, color:INK, letterSpacing:'-.01em'}}>
                    {q.label}
                  </div>
                  <div style={{fontFamily:FONT_BODY, fontSize:12, color:MUTED, lineHeight:1.35, marginTop:6}}>
                    {q.q}
                  </div>
                  {/* Mini score bar appears after 0.6s */}
                  {lt > 0.6 && (
                    <div style={{position:'absolute', bottom:16, left:20, right:20}}>
                      <div style={{height:4, background:'rgba(107,83,163,.15)', borderRadius:99, overflow:'hidden'}}>
                        <div style={{
                          height:'100%', background:PURPLE,
                          width: `${Easing.easeOutCubic(clamp((lt-0.6)/0.8, 0, 1)) * q.score}%`
                        }}/>
                      </div>
                      <div style={{display:'flex', justifyContent:'space-between', marginTop:4, fontFamily:FONT_MONO, fontSize:9, color:MUTED}}>
                        <span>SCORE</span>
                        <span style={{color:PURPLE, fontWeight:700}}>{Math.round(Easing.easeOutCubic(clamp((lt-0.6)/0.8, 0, 1)) * q.score)}/100</span>
                      </div>
                    </div>
                  )}
                </div>
              );
            }}
          </Sprite>
        );
      })}

      {/* Composite score appears at 12.5s */}
      <Sprite start={12.5} end={14.8}>
        {({localTime}) => {
          const p = Easing.easeOutBack(clamp(localTime/0.5, 0, 1));
          return (
            <div style={{
              position:'absolute', left:30, right:30, bottom:180,
              background:INK, color:'#fff', padding:'20px 24px', borderRadius:16,
              display:'flex', alignItems:'center', justifyContent:'space-between',
              transform:`scale(${p}) translateY(${(1-p)*20}px)`, opacity:p,
              boxShadow:'0 20px 40px rgba(0,0,0,.25)'
            }}>
              <div>
                <div style={{fontFamily:FONT_MONO, fontSize:10, color:PURPLE_LIGHT, letterSpacing:'.16em', fontWeight:700}}>COMPOSITE</div>
                <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:28, letterSpacing:'-.02em', marginTop:2}}>
                  Your readiness
                </div>
              </div>
              <div style={{textAlign:'right'}}>
                <div style={{fontFamily:FONT_DISPLAY, fontWeight:800, fontSize:54, color:PURPLE_LIGHT, letterSpacing:'-.04em', lineHeight:.9}}>
                  69
                </div>
                <div style={{fontFamily:FONT_MONO, fontSize:10, color:'rgba(255,255,255,.55)', letterSpacing:'.12em'}}>/100</div>
              </div>
            </div>
          );
        }}
      </Sprite>

      <CTACard start={14.5} duration={3.5} darkBg={false}/>
    </>
  );
}

function PURPLE_HAIRLINE() { return '#D9D1EC'; }

Object.assign(window, {
  Reel1_BuyerMonday, Reel2_ThirtyQuestions, Reel3_ScoreTimeline, Reel4_StopGuessing, Reel5_FourDimensions,
  W, H,
});
