// scene3.jsx — "Feedzap dashboard — Top Issues" (light, matches real Feedzap dashboard)

function FeedzapTopBar() {
  return (
    <div
      style={{
        height: 56,
        background: '#fff',
        borderBottom: '1px solid #e5e7eb',
        display: 'flex',
        alignItems: 'center',
        padding: '0 24px',
        gap: 16,
        flexShrink: 0
      }}>
      
      <FeedzapWordmark size={22} color="#0f172a" />
      <div
        style={{
          marginLeft: 16,
          padding: '5px 10px',
          background: '#f1f5f9',
          color: '#475569',
          borderRadius: 6,
          fontSize: 12,
          fontWeight: 600
        }}>
        
        Acme · Production
      </div>
      <div style={{ flex: 1 }} />
      <div
        style={{
          height: 34,
          padding: '0 12px',
          background: '#f8fafc',
          border: '1px solid #e5e7eb',
          borderRadius: 8,
          display: 'flex',
          alignItems: 'center',
          gap: 8,
          color: '#94a3b8',
          fontSize: 13,
          minWidth: 280
        }}>
        
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="11" cy="11" r="7" /><path d="m21 21-4.3-4.3" /></svg>
        Search feedback…
      </div>
      <div
        style={{
          width: 32,
          height: 32,
          borderRadius: 99,
          background: '#0f172a',
          color: '#fff',
          fontWeight: 700,
          fontSize: 13,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center'
        }}>
        
        J
      </div>
    </div>);

}

function FeedzapSidebar() {
  const items = [
  { label: 'Inbox', icon: 'inbox', count: 247 },
  { label: 'Analytics', icon: 'chart' },
  { label: 'Insights', icon: 'sparkles' },
  { label: 'AI Agent', icon: 'bolt', active: true, badge: 3 },
  { label: 'Team', icon: 'users' },
  { label: 'Install', icon: 'gear' },
  { label: 'Billing', icon: 'card' }];

  return (
    <aside
      style={{
        width: 232,
        background: '#fff',
        borderRight: '1px solid #e5e7eb',
        padding: '16px 12px',
        display: 'flex',
        flexDirection: 'column',
        gap: 2,
        flexShrink: 0
      }}>
      
      <div
        style={{
          fontSize: 11,
          fontWeight: 600,
          color: '#94a3b8',
          textTransform: 'uppercase',
          letterSpacing: '0.08em',
          padding: '8px 10px 4px'
        }}>
        
        Workspace
      </div>
      {items.map((it) =>
      <div
        key={it.label}
        style={{
          display: 'flex',
          alignItems: 'center',
          gap: 10,
          padding: '9px 10px',
          borderRadius: 7,
          background: it.active ? '#0f172a' : 'transparent',
          color: it.active ? '#fff' : '#475569',
          fontSize: 13.5,
          fontWeight: it.active ? 600 : 500
        }}>
        
          <span
          style={{
            width: 16,
            height: 16,
            display: 'inline-flex',
            alignItems: 'center',
            justifyContent: 'center'
          }}>
          
            {Icons[it.icon](16, 'currentColor')}
          </span>
          <span style={{ flex: 1 }}>{it.label}</span>
          {it.count != null &&
        <span
          style={{
            fontSize: 11,
            color: it.active ? '#cbd5e1' : '#94a3b8',
            fontWeight: 500
          }}>
          
              {it.count}
            </span>
        }
          {it.badge &&
        <span
          style={{
            fontSize: 10,
            fontWeight: 700,
            padding: '2px 6px',
            borderRadius: 99,
            background: '#3b82f6',
            color: '#fff'
          }}>
          
              {it.badge}
            </span>
        }
        </div>
      )}
    </aside>);

}

function ExecuteFixBtn({ hover, pressed, working }) {
  if (working) {
    return (
      <div
        style={{
          display: 'inline-flex',
          alignItems: 'center',
          gap: 10,
          padding: '11px 20px',
          borderRadius: 8,
          background: '#3b82f6',
          color: '#fff',
          fontWeight: 600,
          fontSize: 14,
          boxShadow: '0 6px 16px rgba(59,130,246,0.3)'
        }}>
        
        <div
          style={{
            width: 14,
            height: 14,
            borderRadius: 99,
            border: '2px solid rgba(255,255,255,0.4)',
            borderTopColor: '#fff',
            animation: 'fzSpin 0.8s linear infinite'
          }} />
        
        Working…
      </div>);

  }
  return (
    <div
      style={{
        display: 'inline-flex',
        alignItems: 'center',
        gap: 8,
        padding: '11px 20px',
        borderRadius: 8,
        background: hover ? '#2563eb' : '#3b82f6',
        color: '#fff',
        fontWeight: 600,
        fontSize: 14,
        boxShadow: hover ?
        '0 10px 22px rgba(59,130,246,0.42)' :
        '0 5px 14px rgba(59,130,246,0.25)',
        transform: pressed ? 'scale(0.96)' : hover ? 'translateY(-1px)' : 'translateY(0)',
        transition: 'all 150ms cubic-bezier(0.2, 0.8, 0.2, 1)',
        animation: hover ? 'none' : 'fzPulseBlue 2.4s ease-in-out infinite'
      }}>
      
      {Icons.bolt(15, 'currentColor')}
      Execute Fix
    </div>);

}

function IssueRow({
  badge,
  badgeColor,
  title,
  subtitle,
  count,
  countSub,
  highlight,
  fixHover,
  fixPressed,
  fixWorking,
  fixDisabled
}) {
  return (
    <div
      style={{
        display: 'grid',
        gridTemplateColumns: '2.4fr 160px 1fr',
        padding: '20px 24px',
        borderBottom: '1px solid #f1f5f9',
        background: highlight ? 'rgba(239,68,68,0.04)' : 'transparent',
        alignItems: 'center',
        gap: 16
      }}>
      
      <div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span
            style={{
              padding: '3px 9px',
              background: badgeColor.bg,
              color: badgeColor.fg,
              border: `1px solid ${badgeColor.border}`,
              borderRadius: 99,
              fontSize: 10.5,
              fontWeight: 700,
              letterSpacing: '0.06em',
              textTransform: 'uppercase'
            }}>
            
            {badge}
          </span>
          <span style={{ fontSize: 16, fontWeight: 600, letterSpacing: '-0.005em' }}>
            {title}
          </span>
        </div>
        <div
          style={{
            marginTop: 6,
            fontSize: 13,
            color: '#64748b',
            fontFamily: 'JetBrains Mono, ui-monospace, monospace'
          }}>
          
          {subtitle}
        </div>
      </div>
      <div>
        <div style={{ fontSize: 24, fontWeight: 700, letterSpacing: '-0.02em' }}>
          {count}
        </div>
        <div style={{ fontSize: 12, color: '#64748b', marginTop: 2 }}>
          {countSub}
        </div>
      </div>
      <div style={{ textAlign: 'right' }}>
        {fixDisabled ?
        <div
          style={{
            display: 'inline-flex',
            alignItems: 'center',
            gap: 8,
            padding: '11px 20px',
            borderRadius: 8,
            background: '#f1f5f9',
            color: '#94a3b8',
            fontWeight: 600,
            fontSize: 14,
            border: '1px solid #e2e8f0'
          }}>
          
            {Icons.bolt(15, 'currentColor')}
            Execute Fix
          </div> :

        <div data-target="executeFix" style={{ display: 'inline-block' }}><ExecuteFixBtn
            hover={fixHover}
            pressed={fixPressed}
            working={fixWorking} />
        </div>
        }
      </div>
    </div>);

}

function Scene3() {
  const { localTime: rawTime } = useSprite();
  const localTime = rawTime / 1.3;

  // ── Phases (scene length 8.4s) ──────────────────────────────────────
  // 0.0–0.6  fade in
  // 0.6–1.4  AI insight badge slides in
  // 1.4–3.4  rows reveal (staggered)
  // 3.4–4.6  cursor moves toward Execute Fix
  // 4.6–4.8  hover state on button
  // 4.8–5.0  press
  // 5.0–8.0  Working… spinner
  // 8.0–8.4  fade out (handled by SceneFade)

  const insightP = Easing.easeOutCubic(clamp((localTime - 0.6) / 0.7, 0, 1));
  const rowReveal = (i) => {
    const start = 1.4 + i * 0.18;
    return Easing.easeOutCubic(clamp((localTime - start) / 0.45, 0, 1));
  };

  const fixHover = localTime >= 4.5 && localTime < 4.9;
  const fixPressed = localTime >= 4.78 && localTime < 4.95;
  const fixWorking = localTime >= 4.95;

  // Cursor: starts mid-screen (entering from scene 2's send-button position),
  // moves to button on row 1, clicks, holds.
  // Layout: sidebar 232 wide, then content. Top bar 56 tall.
  // Stage 1920×1080. Content x range 232..1920. Header padding etc.
  // Row 1 right side Execute Fix button center ≈ (1820, 540).
  const cursorPath = [
  { t: 0.0, target: 'fzSend' },
  { t: 0.6, x: 1100, y: 600 },
  { t: 2.4, x: 1100, y: 600 },
  { t: 4.6, target: 'executeFix' },
  { t: 8.4, target: 'executeFix' }];

  const clicks = [{ t: 4.85, target: 'executeFix' }];

  return (
    <SceneFade>
      <div
        style={{
          position: 'absolute',
          inset: 0,
          background: '#f6f8fb',
          display: 'flex',
          flexDirection: 'column'
        }}>
        
        <FeedzapTopBar />
        <div style={{ flex: 1, display: 'flex', overflow: 'hidden' }}>
          <FeedzapSidebar />
          <main
            style={{
              flex: 1,
              padding: '32px 56px',
              overflow: 'hidden'
            }}>
            
            <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 18 }}>
              <div>
                <div
                  style={{
                    fontSize: 12,
                    color: '#64748b',
                    textTransform: 'uppercase',
                    letterSpacing: '0.08em',
                    fontWeight: 600
                  }}>
                  
                  AI Agent
                </div>
                <div
                  style={{
                    fontSize: 32,
                    fontWeight: 700,
                    letterSpacing: '-0.02em',
                    marginTop: 4,
                    color: '#0f172a'
                  }}>
                  
                  Top Issues to Fix
                </div>
                <div style={{ fontSize: 14.5, color: '#64748b', marginTop: 6 }}>
                  Patterns Feedzap detected from your last 30 days of feedback.
                </div>
              </div>
              <div style={{ display: 'flex', gap: 10 }}>
                <div
                  style={{
                    padding: '8px 14px',
                    borderRadius: 8,
                    background: '#fff',
                    border: '1px solid #e5e7eb',
                    fontSize: 13,
                    color: '#475569',
                    fontWeight: 500,
                    display: 'inline-flex',
                    alignItems: 'center',
                    gap: 8
                  }}>
                  
                  Last 30 days
                  <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="m6 9 6 6 6-6" /></svg>
                </div>
              </div>
            </div>

            {/* AI insight badge */}
            <div
              style={{
                display: 'inline-flex',
                alignItems: 'center',
                gap: 10,
                padding: '9px 16px',
                borderRadius: 999,
                background: 'rgba(59,130,246,0.08)',
                border: '1px solid rgba(59,130,246,0.25)',
                color: '#1d4ed8',
                fontSize: 13,
                fontWeight: 600,
                marginBottom: 18,
                opacity: insightP,
                transform: `translateY(${(1 - insightP) * 8}px)`
              }}>
              
              <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                <path d="m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3z" />
              </svg>
              AI detected a pattern — same selector, 47 users
            </div>

            {/* Issues table */}
            <div
              style={{
                background: '#fff',
                border: '1px solid #e5e7eb',
                borderRadius: 12,
                overflow: 'hidden',
                boxShadow: '0 1px 2px rgba(0,0,0,0.02)'
              }}>
              
              <div
                style={{
                  padding: '14px 24px',
                  display: 'grid',
                  gridTemplateColumns: '2.4fr 160px 1fr',
                  borderBottom: '1px solid #e5e7eb',
                  background: '#f8fafc',
                  fontSize: 11,
                  fontWeight: 600,
                  color: '#64748b',
                  textTransform: 'uppercase',
                  letterSpacing: '0.08em',
                  gap: 16
                }}>
                
                <div>Issue</div>
                <div>Reports</div>
                <div style={{ textAlign: 'right' }}>Action</div>
              </div>

              {/* Rows */}
              {[
              {
                badge: 'NEW',
                badgeColor: { bg: '#fef2f2', fg: '#dc2626', border: '#fecaca' },
                title: 'Export CSV broken',
                subtitle: "button.export-btn doesn't fire on /reports — last reported 2m ago",
                count: '47',
                countSub: 'reports · 4 days',
                highlight: true,
                showFixBtn: true
              },
              {
                badge: 'PATTERN',
                badgeColor: { bg: '#fefce8', fg: '#a16207', border: '#fde68a' },
                title: 'Slow onboarding step 3',
                subtitle: 'avg time-on-step 41s on /onboard/profile',
                count: '23',
                countSub: 'reports · 7 days'
              },
              {
                badge: 'COPY',
                badgeColor: { bg: '#eff6ff', fg: '#1d4ed8', border: '#bfdbfe' },
                title: 'Confusing label "Sync"',
                subtitle: 'Settings → Integrations card',
                count: '11',
                countSub: 'reports · 12 days'
              }].
              map((r, i) =>
              <div
                key={r.title}
                style={{
                  opacity: rowReveal(i),
                  transform: `translateY(${(1 - rowReveal(i)) * 8}px)`,
                  willChange: 'opacity, transform'
                }}>
                
                  <IssueRow
                  {...r}
                  fixHover={i === 0 && fixHover}
                  fixPressed={i === 0 && fixPressed}
                  fixWorking={i === 0 && fixWorking}
                  fixDisabled={i !== 0} />
                
                </div>
              )}
            </div>
          </main>
        </div>
      </div>

      <Cursor path={cursorPath} clicks={clicks} time={localTime} />
      <SceneCaption
        scene="03"
        title="Pattern detected"
        caption="47 users hit the same broken selector. Dev presses Execute Fix." />
      
    </SceneFade>);

}

Object.assign(window, { Scene3 });


// scene4.jsx — VSCode-style code editor showing the AI's diff + Approve action

function CodeEditor({ linesShown, aiBlockProgress, approveHover, approvePressed, approved }) {
  // Lines: each is {n, type: 'context'|'remove'|'add', content (JSX or string)}
  const lines = [
  { n: 12, type: 'context', text: <><K>const</K> exportBtn = document.<F>querySelector</F>(<S>'.export-btn'</S>);</> },
  { n: 13, type: 'context', text: '' },
  { n: 14, type: 'context', text: <><C>{`// Wire up the export handler`}</C></> },
  { n: 15, type: 'remove', text: <>exportBtn.<F>addEventListener</F>(<S>'click'</S>, handleExport);</> },
  { n: 15, type: 'add', text: <>exportBtn?.<F>addEventListener</F>(<S>'click'</S>, handleExport);</> },
  { n: 16, type: 'add', text: <><K>if</K> (!exportBtn) console.<F>warn</F>(<S>'Export button not found'</S>);</> },
  { n: 17, type: 'context', text: '' },
  { n: 18, type: 'context', text: <><K>function</K> <F>handleExport</F>(e) {`{`}</> },
  { n: 19, type: 'context', text: <>{'  '}e.<F>preventDefault</F>();</> },
  { n: 20, type: 'context', text: <>{'  '}<F>downloadCsv</F>(state.rows);</> },
  { n: 21, type: 'context', text: '}' }];


  return (
    <div
      style={{
        position: 'absolute',
        inset: 0,
        background: '#0d1117',
        display: 'flex',
        flexDirection: 'column',
        fontFamily: 'JetBrains Mono, ui-monospace, monospace',
        color: '#e6edf3'
      }}>
      
      {/* Title bar */}
      <div
        style={{
          height: 38,
          background: '#0a0d12',
          borderBottom: '1px solid #1f2937',
          display: 'flex',
          alignItems: 'center',
          padding: '0 14px',
          gap: 10,
          flexShrink: 0
        }}>
        
        <div style={{ display: 'flex', gap: 7 }}>
          <div style={{ width: 11, height: 11, borderRadius: 99, background: '#ff5f57' }} />
          <div style={{ width: 11, height: 11, borderRadius: 99, background: '#febc2e' }} />
          <div style={{ width: 11, height: 11, borderRadius: 99, background: '#28c840' }} />
        </div>
        <div
          style={{
            marginLeft: 'auto',
            marginRight: 'auto',
            fontSize: 12.5,
            color: '#8b949e',
            fontFamily: 'Inter, sans-serif'
          }}>
          
          acme-web — exportController.js
        </div>
        <div style={{ width: 50 }} />
      </div>

      {/* Tab bar */}
      <div
        style={{
          height: 36,
          background: '#0a0d12',
          borderBottom: '1px solid #1f2937',
          display: 'flex',
          flexShrink: 0
        }}>
        
        <div
          style={{
            padding: '0 18px',
            display: 'flex',
            alignItems: 'center',
            gap: 8,
            background: '#0d1117',
            borderRight: '1px solid #1f2937',
            color: '#e6edf3',
            fontSize: 13,
            fontFamily: 'Inter, sans-serif',
            position: 'relative'
          }}>
          
          <svg width="14" height="14" viewBox="0 0 24 24" fill="#f0db4f"><rect width="24" height="24" rx="3" /><text x="12" y="17" textAnchor="middle" fontSize="11" fontWeight="700" fill="#0d1117" fontFamily="Inter">JS</text></svg>
          exportController.js
          <span
            style={{
              width: 8,
              height: 8,
              borderRadius: 99,
              background: '#fb923c',
              marginLeft: 4
            }}
            title="modified" />
          
          <div
            style={{
              position: 'absolute',
              left: 0,
              right: 0,
              top: -1,
              height: 2,
              background: '#3b82f6'
            }} />
          
        </div>
      </div>

      {/* Body: code on the left, AI block on the right */}
      <div style={{ flex: 1, display: 'flex', minHeight: 0 }}>
        {/* Code area */}
        <div
          style={{
            flex: 1,
            padding: '20px 0',
            fontSize: 16,
            lineHeight: '26px',
            overflow: 'hidden'
          }}>
          
          {lines.map((line, i) => {
            const visible = i < linesShown;
            const recent = i === linesShown - 1;
            const reveal = recent ? Easing.easeOutCubic(0.3) : 1;
            const opacity = visible ? 1 : 0;
            const tx = visible ? 0 : -8;
            const isAdd = line.type === 'add';
            const isRem = line.type === 'remove';
            const bg = isAdd ?
            'rgba(34,197,94,0.12)' :
            isRem ?
            'rgba(239,68,68,0.12)' :
            'transparent';
            const marker = isAdd ? '+' : isRem ? '−' : ' ';
            const markerColor = isAdd ? '#4ade80' : isRem ? '#f87171' : '#3a414b';
            return (
              <div
                key={i}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  background: bg,
                  borderLeft: isAdd ?
                  '3px solid #22c55e' :
                  isRem ?
                  '3px solid #ef4444' :
                  '3px solid transparent',
                  opacity,
                  transform: `translateX(${tx}px)`,
                  transition: 'opacity 200ms ease-out, transform 200ms ease-out',
                  textDecoration: isRem ? 'line-through' : 'none',
                  textDecorationColor: isRem ? 'rgba(248,113,113,0.5)' : undefined
                }}>
                
                <span
                  style={{
                    width: 50,
                    textAlign: 'right',
                    color: '#3a414b',
                    fontSize: 13.5,
                    paddingRight: 14,
                    flexShrink: 0
                  }}>
                  
                  {line.n}
                </span>
                <span
                  style={{
                    width: 22,
                    textAlign: 'center',
                    color: markerColor,
                    fontWeight: 700,
                    flexShrink: 0
                  }}>
                  
                  {marker}
                </span>
                <span style={{ flex: 1 }}>{line.text || '\u00a0'}</span>
              </div>);

          })}
        </div>

        {/* AI block on the right */}
        <div
          style={{
            width: 560,
            padding: '24px 28px',
            background: 'linear-gradient(180deg, rgba(59,130,246,0.05) 0%, rgba(59,130,246,0.02) 100%)',
            borderLeft: '1px solid #1f2937',
            opacity: aiBlockProgress,
            transform: `translateX(${(1 - aiBlockProgress) * 24}px)`,
            display: 'flex',
            flexDirection: 'column',
            gap: 16,
            fontFamily: 'Inter, sans-serif',
            overflow: 'hidden'
          }}>
          
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <div
              style={{
                width: 32,
                height: 32,
                borderRadius: 8,
                background: '#3b82f6',
                color: '#fff',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center'
              }}>
              
              {Icons.bolt(16, '#fff')}
            </div>
            <div>
              <div style={{ fontSize: 14, fontWeight: 600, color: '#e6edf3' }}>
                Feedzap AI Agent
              </div>
              <div style={{ fontSize: 12, color: '#7d8590' }}>
                Suggested fix · 1 file changed
              </div>
            </div>
          </div>

          <div
            style={{
              padding: '14px 16px',
              background: 'rgba(13,17,23,0.6)',
              border: '1px solid #1f2937',
              borderRadius: 10,
              fontSize: 13.5,
              lineHeight: 1.6,
              color: '#cbd5e1'
            }}>
            
            <div style={{ color: '#93c5fd', fontWeight: 600, marginBottom: 6, fontSize: 12, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
              Why this fix
            </div>
            The element <code style={cs}>.export-btn</code> renders conditionally — when the user is on a tab where it's not in the DOM, <code style={cs}>querySelector</code> returns <code style={cs}>null</code>. Adding optional-chaining prevents the silent <code style={cs}>TypeError</code> and the warning helps catch regressions in dev.
          </div>

          <div
            style={{
              display: 'flex',
              gap: 14,
              padding: '10px 14px',
              background: 'rgba(34,197,94,0.06)',
              border: '1px solid rgba(34,197,94,0.18)',
              borderRadius: 10,
              fontSize: 12.5,
              color: '#a7f3d0'
            }}>
            
            <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <span style={{ color: '#4ade80', fontWeight: 700 }}>+2</span>
              <span style={{ color: '#86efac' }}>added</span>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <span style={{ color: '#f87171', fontWeight: 700 }}>−1</span>
              <span style={{ color: '#fca5a5' }}>removed</span>
            </div>
            <div style={{ flex: 1 }} />
            <div style={{ color: '#7d8590' }}>Affects 47 users</div>
          </div>

          <div style={{ display: 'flex', gap: 10, marginTop: 'auto' }}>
            <div
              style={{
                flex: 1,
                padding: '12px 16px',
                borderRadius: 8,
                background: '#1f2937',
                color: '#cbd5e1',
                fontSize: 14,
                fontWeight: 600,
                textAlign: 'center',
                border: '1px solid #2d3744'
              }}>
              
              Reject
            </div>
            <div
              data-target="approveBtn"
              style={{
                flex: 2,
                padding: '12px 16px',
                borderRadius: 8,
                background: approved ?
                '#16a34a' :
                approveHover ?
                '#16a34a' :
                '#22c55e',
                color: '#052e16',
                fontSize: 14,
                fontWeight: 700,
                textAlign: 'center',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                gap: 8,
                transform: approvePressed ? 'scale(0.96)' : approveHover ? 'translateY(-1px)' : 'translateY(0)',
                boxShadow: approveHover ? '0 8px 22px rgba(34,197,94,0.45)' : '0 4px 14px rgba(34,197,94,0.32)',
                transition: 'all 150ms cubic-bezier(0.2, 0.8, 0.2, 1)'
              }}>
              
              {approved ? Icons.check(16, '#052e16', 2.6) : null}
              {approved ? 'Approved · Deploying' : 'Approve & Deploy'}
            </div>
          </div>
        </div>
      </div>
    </div>);

}

// little tag colors
const K = ({ children }) => <span style={{ color: '#ff7b72' }}>{children}</span>;
const F = ({ children }) => <span style={{ color: '#d2a8ff' }}>{children}</span>;
const S = ({ children }) => <span style={{ color: '#a5d6ff' }}>{children}</span>;
const C = ({ children }) => <span style={{ color: '#7d8590', fontStyle: 'italic' }}>{children}</span>;
const cs = {
  fontFamily: 'JetBrains Mono, ui-monospace, monospace',
  fontSize: 12.5,
  background: 'rgba(59,130,246,0.16)',
  color: '#93c5fd',
  padding: '1px 6px',
  borderRadius: 4
};

function Scene4() {
  const { localTime: rawTime } = useSprite();
  const localTime = rawTime / 1.3;

  // ── Phases (8.4s) ─────────────────────────────────────────────────────
  // 0.0–0.6  fade in editor
  // 0.6–3.4  lines reveal (~0.28s each, 11 lines)
  // 3.4–4.2  AI block slides in
  // 4.2–6.4  read pause
  // 6.4–7.2  cursor moves to Approve button
  // 7.2–7.4  hover
  // 7.4–7.6  press → approved
  // 7.6–8.4  hold approved + caption

  const totalLines = 11;
  const lineRevealStart = 0.6;
  const linesShown = Math.min(
    totalLines,
    Math.max(0, Math.floor((localTime - lineRevealStart) / 0.28) + 1) - (localTime < lineRevealStart ? 1 : 0)
  );
  const aiBlockProgress = Easing.easeOutCubic(
    clamp((localTime - 3.4) / 0.7, 0, 1)
  );

  const approveHover = localTime >= 7.1 && localTime < 7.5;
  const approvePressed = localTime >= 7.4 && localTime < 7.55;
  const approved = localTime >= 7.5;

  // Approve button center: scene 4 right column starts at right edge - 560.
  // Right column: x range 1360..1920 (0-padding 28px each side → 1388..1892).
  // Approve button is the 2/3 right-side button at the bottom. Approx center (1700, 980).
  const cursorPath = [
  { t: 0.0, target: 'executeFix' },
  { t: 0.6, x: 800, y: 500 },
  { t: 3.4, x: 800, y: 500 },
  { t: 6.4, x: 1500, y: 800 },
  { t: 7.2, target: 'approveBtn' },
  { t: 8.4, target: 'approveBtn' }];

  const clicks = [{ t: 7.45, target: 'approveBtn', color: '#22c55e' }];

  return (
    <SceneFade>
      <CodeEditor
        linesShown={linesShown}
        aiBlockProgress={aiBlockProgress}
        approveHover={approveHover}
        approvePressed={approvePressed}
        approved={approved} />
      
      <Cursor path={cursorPath} clicks={clicks} time={localTime} />
      <SceneCaption
        scene="04"
        title="AI explains the fix"
        caption="One-line patch. Dev approves in one click." />
      
    </SceneFade>);

}

Object.assign(window, { Scene4 });


// scene5.jsx — Resolution / finale: "Export CSV — Fixed"

function Scene5() {
  const { localTime: rawTime } = useSprite();
  const localTime = rawTime / 1.3;

  // ── Phases (4.4s) ─────────────────────────────────────────────────────
  // 0.0–0.5  fade in
  // 0.5–1.2  big check scales in with bounce
  // 1.0–1.5  headline fades in
  // 1.4–1.9  subtext fades in
  // 1.9–2.5  stats row fades in
  // 2.5–4.4  hold + Feedzap signature

  const checkP = Easing.easeOutBack(clamp((localTime - 0.4) / 0.7, 0, 1));
  const headP = Easing.easeOutCubic(clamp((localTime - 0.95) / 0.5, 0, 1));
  const subP = Easing.easeOutCubic(clamp((localTime - 1.35) / 0.5, 0, 1));
  const statsP = Easing.easeOutCubic(clamp((localTime - 1.85) / 0.6, 0, 1));
  const sigP = Easing.easeOutCubic(clamp((localTime - 2.4) / 0.5, 0, 1));

  // Subtle ambient drift on the big check ring (decorative)
  const drift = Math.sin(localTime * 0.7) * 4;

  return (
    <SceneFade entryDur={0.5} exitDur={0.5}>
      <div
        style={{
          position: 'absolute',
          inset: 0,
          background:
          'radial-gradient(ellipse at 50% 35%, #11171f 0%, #0a0a0c 70%)',
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          gap: 28,
          overflow: 'hidden'
        }}>
        
        {/* Soft glow behind check */}
        <div
          style={{
            position: 'absolute',
            top: '32%',
            left: '50%',
            width: 520,
            height: 520,
            transform: 'translate(-50%, -50%)',
            borderRadius: 999,
            background:
            'radial-gradient(circle, rgba(52,211,153,0.18) 0%, rgba(52,211,153,0.0) 60%)',
            filter: 'blur(14px)',
            opacity: checkP,
            pointerEvents: 'none'
          }} />
        

        {/* Big check */}
        <div
          style={{
            width: 168,
            height: 168,
            borderRadius: 999,
            background: 'rgba(34,197,94,0.14)',
            border: '1.5px solid rgba(52,211,153,0.45)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            transform: `scale(${0.6 + 0.4 * checkP}) translateY(${drift}px)`,
            opacity: checkP,
            boxShadow: '0 30px 80px rgba(52,211,153,0.18)'
          }}>
          
          <svg
            width="96"
            height="96"
            viewBox="0 0 24 24"
            fill="none"
            stroke="#34d399"
            strokeWidth="2.6"
            strokeLinecap="round"
            strokeLinejoin="round">
            
            <path
              d="M20 6 9 17l-5-5"
              style={{
                strokeDasharray: 30,
                strokeDashoffset: (1 - checkP) * 30,
                transition: 'stroke-dashoffset 0.4s ease-out'
              }} />
            
          </svg>
        </div>

        {/* Headline */}
        <div
          style={{
            opacity: headP,
            transform: `translateY(${(1 - headP) * 12}px)`,
            textAlign: 'center'
          }}>
          
          <div
            style={{
              fontSize: 72,
              fontWeight: 800,
              letterSpacing: '-0.035em',
              color: '#f5f5f7',
              lineHeight: 1.05
            }}>Convert user feedback into
ready-to-ship code in seconds.

          </div>
        </div>

        {/* Subtext */}
        <div
          style={{
            opacity: subP,
            transform: `translateY(${(1 - subP) * 8}px)`,
            fontSize: 26,
            color: '#a1a1aa',
            fontWeight: 500,
            letterSpacing: '-0.01em',
            textAlign: 'center',
            marginTop: -8
          }}>
          
          4 minutes. Zero tickets. Zero Slack threads.
        </div>

        {/* Stats row */}
        <div
          style={{
            display: 'flex',
            gap: 56,
            marginTop: 36,
            opacity: statsP,
            transform: `translateY(${(1 - statsP) * 12}px)`
          }}>
          
          {[
          { value: '47', label: 'users\nfeedback collected' },
          { value: '4 min', label: 'feedback → deploy' },
          { value: '0', label: 'support tickets' }].
          map((s, i) =>
          <div
            key={i}
            style={{
              textAlign: 'center',
              minWidth: 220
            }}>
            
              <div
              style={{
                fontSize: 56,
                fontWeight: 700,
                letterSpacing: '-0.03em',
                color: '#f5f5f7',
                lineHeight: 1
              }}>
              
                {s.value}
              </div>
              <div
              style={{
                marginTop: 10,
                fontSize: 14,
                color: '#71717a',
                whiteSpace: 'pre-line',
                textTransform: 'uppercase',
                letterSpacing: '0.08em',
                fontWeight: 600
              }}>
              
                {s.label.split('\n')[0]}
              </div>
            </div>
          )}
        </div>

        {/* Feedzap signature */}
        <div
          style={{
            position: 'absolute',
            bottom: 56,
            left: 0,
            right: 0,
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            gap: 6,
            opacity: sigP,
            transform: `translateY(${(1 - sigP) * 8}px)`
          }}>
          
          <div
            style={{
              fontSize: 11,
              color: '#52525b',
              textTransform: 'uppercase',
              letterSpacing: '0.18em',
              fontWeight: 600
            }}>
            
            Powered by
          </div>
          <FeedzapWordmark size={32} color="#f5f5f7" glyphColor="#0a0a0c" />
        </div>
      </div>

      <SceneCaption
        scene="05"
        title="Loop closed"
        caption="From user click to fix — without anyone filing a ticket." />
      
    </SceneFade>);

}

Object.assign(window, { Scene5 });


// app.jsx — Stage + 5 scenes. Total ~33s, looping.

const SLOW = 1.3; // global slow-down — every scene's internal phases also divide localTime by SLOW
const SCENES = [
{ id: 's1', start: 0.0 * SLOW, end: 5.0 * SLOW, Comp: Scene1 },
{ id: 's2', start: 4.6 * SLOW, end: 13.0 * SLOW, Comp: Scene2 },
{ id: 's3', start: 12.6 * SLOW, end: 21.0 * SLOW, Comp: Scene3 },
{ id: 's4', start: 20.6 * SLOW, end: 29.0 * SLOW, Comp: Scene4 },
{ id: 's5', start: 28.6 * SLOW, end: 33.0 * SLOW, Comp: Scene5 }];


const TOTAL_DURATION = 33.0 * SLOW;

function App() {
  return (
    <Stage width={1920} height={1080} duration={TOTAL_DURATION} background="#0a0a0c">
      {SCENES.map((s) =>
      <Sprite key={s.id} start={s.start} end={s.end}>
          <s.Comp />
        </Sprite>
      )}
    </Stage>);

}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);