// scenes.jsx — RD8 "How it works" explainer scenes
// Composes Sprites (from animations.jsx) with RD8 brand styling + the engine.
// Exports window.Scenes (array rendered inside <Stage>) and window.RootBackdrop.

const { Sprite, Easing, clamp, useSprite } = window;
const DS = window.RD8DesignSystem_2f2a8a;

// ── shared tokens / helpers ─────────────────────────────────────────────────
const W = 1920, H = 1080, MX = 150;
const F_DISPLAY = 'var(--font-display)';
const F_MONO = 'var(--font-mono)';
const F_BODY = 'var(--font-body)';
const F_SERIF = 'var(--font-serif-accent)';
const FILL = 'var(--text-heading-fill)';

// staged entry: returns {opacity, ty} for an element revealing at `at` over `dur`
function rise(t, at = 0, dur = 0.6, dist = 28, ease = Easing.easeOutCubic) {
  const p = clamp((t - at) / dur, 0, 1);
  const e = ease(p);
  return { opacity: e, ty: (1 - e) * dist };
}
// whole-scene fade so cuts aren't hard: fades content out in last `out` secs
function sceneFade(t, dur, inDur = 0.4, out = 0.5) {
  const fin = clamp(t / inDur, 0, 1);
  const fout = clamp((dur - t) / out, 0, 1);
  return Math.min(fin, fout);
}

// ── small brand atoms ───────────────────────────────────────────────────────
function Eyebrow({ children, t, at = 0, color = 'var(--rd8-green-bright)' }) {
  const r = rise(t, at, 0.5);
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 14,
      opacity: r.opacity, transform: `translateY(${r.ty}px)`,
      fontFamily: F_MONO, fontSize: 21, letterSpacing: '0.18em',
      textTransform: 'uppercase', color, whiteSpace: 'nowrap',
    }}>
      <span style={{ width: 38, height: 2, background: color }} />
      {children}
    </div>
  );
}

function Display({ children, t, at = 0, size = 104, lh = 0.98, stagger = 0, style = {} }) {
  const r = rise(t, at + stagger, 0.7, 34);
  return (
    <h1 style={{
      margin: 0, paddingBottom: '0.08em', fontFamily: F_DISPLAY, fontWeight: 600, fontSize: size, lineHeight: lh,
      textTransform: 'uppercase', letterSpacing: '-0.01em',
      background: FILL, WebkitBackgroundClip: 'text', backgroundClip: 'text', color: 'transparent',
      opacity: r.opacity, transform: `translateY(${r.ty}px)`, ...style,
    }}>{children}</h1>
  );
}
const Accent = ({ children, green = true }) => (
  <span style={{
    fontFamily: F_DISPLAY, fontWeight: 600,
    textTransform: 'uppercase', letterSpacing: '-0.01em',
    background: green ? 'none' : FILL, WebkitBackgroundClip: green ? 'border-box' : 'text',
    color: green ? 'var(--rd8-green-bright)' : 'transparent',
  }}>{children}</span>
);

function Body({ children, t, at = 0, width = 620, size = 25, color = 'var(--text-secondary)' }) {
  const r = rise(t, at, 0.6);
  return (
    <p style={{
      margin: 0, fontFamily: F_BODY, fontSize: size, lineHeight: 1.5, color, maxWidth: width,
      opacity: r.opacity, transform: `translateY(${r.ty}px)`, textWrap: 'pretty',
    }}>{children}</p>
  );
}

// giant outlined step numeral, e.g. "01"
function Numeral({ n, t, at = 0 }) {
  const r = rise(t, at, 0.8, 0, Easing.easeOutCubic);
  const draw = clamp((t - at) / 1.0, 0, 1);
  return (
    <div style={{ position: 'relative', opacity: r.opacity }}>
      <span style={{
        fontFamily: F_DISPLAY, fontWeight: 600, fontSize: 150, lineHeight: 1,
        textTransform: 'uppercase',
        WebkitTextStroke: '2px var(--rd8-green)', color: 'transparent',
        letterSpacing: '-0.01em',
      }}>{n}</span>
      <div style={{
        position: 'absolute', left: 4, bottom: -14, height: 3, width: `${draw * 120}px`,
        background: 'var(--rd8-green-bright)',
      }} />
    </div>
  );
}

// generic card surface
const cardStyle = (extra = {}) => ({
  backgroundImage: 'var(--surface-gradient-card)',
  border: '1px solid var(--border-subtle)',
  borderRadius: 14, ...extra,
});

// skeleton text bar
const Bar = ({ w, h = 9, c = 'var(--neutral-dark)', mt = 0, o = 1 }) => (
  <div style={{ width: w, height: h, borderRadius: 4, background: c, marginTop: mt, opacity: o }} />
);

// ── persistent backdrop (always visible, behind scenes) ─────────────────────
// Pure #080808 base; the dot-grid + green glow are radially masked so they fade
// completely to nothing before the edges — the frame blends seamlessly into the
// surrounding #080808 page with no contrast at any edge.
function RootBackdrop() {
  const edgeFade = 'radial-gradient(116% 92% at 50% 40%, #000 30%, rgba(0,0,0,0.4) 66%, transparent 88%)';
  return (
    <div style={{ position: 'absolute', inset: 0, background: '#080808', overflow: 'hidden' }}>
      <div style={{ position: 'absolute', inset: 0, WebkitMaskImage: edgeFade, maskImage: edgeFade }}>
        <window.DotGrid opacity={0.5} />
        <div style={{
          position: 'absolute', inset: 0,
          background: 'radial-gradient(105% 68% at 50% -4%, rgba(57,181,74,0.11), transparent 62%)',
        }} />
      </div>
    </div>
  );
}

// glow blob helper for a scene's media
const Glow = ({ x, y, s = 520, c = 'rgba(54,235,8,0.22)' }) => (
  <div style={{ position: 'absolute', left: x, top: y, width: s, height: s, borderRadius: '50%',
    background: `radial-gradient(circle, ${c}, transparent 68%)`, filter: 'blur(8px)', pointerEvents: 'none' }} />
);

// ════════════════════════════════════════════════════════════════════════════
// SCENE 0 — OPENING: "What can we do for you?" + gains
// ════════════════════════════════════════════════════════════════════════════
function SceneOpening() {
  const gains = [
    { kind: 'icon', ic: 'shield', title: 'Secure the quality', body: 'Lock in your design before production starts.' },
    { kind: 'stat', stat: '2\u00d7', title: 'Faster development', body: 'Improve development speed two-fold.' },
    { kind: 'icon', ic: 'spark', title: 'Unlock innovation', body: 'Open up new, innovative solutions.' },
  ];
  return (
    <Sprite start={0} end={8.0}>
      {({ localTime: t, duration }) => (
        <div style={{ position: 'absolute', inset: 0, opacity: sceneFade(t, duration, 0.4, 0.55),
          display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: `0 ${MX}px` }}>
          <Glow x={W / 2 - 380} y={120} s={760} c="rgba(54,235,8,0.13)" />
          <div style={{ marginBottom: 30, display: 'flex', justifyContent: 'center' }}>
            <Eyebrow t={t} at={0.15}>Robust design &amp; tolerance analysis</Eyebrow>
          </div>
          <Display t={t} at={0.45} size={118} lh={0.98} style={{ textAlign: 'center' }}>
            What can we do <Accent>for you?</Accent>
          </Display>
          <div style={{ marginTop: 72, display: 'flex', gap: 26, width: '100%', maxWidth: 1280, justifyContent: 'center' }}>
            {gains.map((g, i) => {
              const r = rise(t, 1.5 + i * 0.18, 0.6, 30);
              const line = clamp((t - (1.7 + i * 0.18)) / 0.5, 0, 1);
              return (
                <div key={g.title} style={{ flex: 1, textAlign: 'left',
                  ...cardStyle({ padding: '30px 30px 32px' }), boxShadow: 'var(--shadow-md)',
                  opacity: r.opacity, transform: `translateY(${r.ty}px)` }}>
                  <div style={{ height: 64, display: 'flex', alignItems: 'center' }}>
                    {g.kind === 'stat' ? (
                      <span style={{ fontFamily: F_DISPLAY, fontWeight: 600, fontSize: 60, lineHeight: 1, color: 'var(--rd8-green-bright)' }}>{g.stat}</span>
                    ) : (
                      <div style={{ width: 60, height: 60, borderRadius: 12, background: 'var(--surface-canvas)',
                        border: '1px solid var(--border-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <window.Icon name={g.ic} size={30} color="var(--rd8-green-bright)" />
                      </div>
                    )}
                  </div>
                  <div style={{ position: 'relative', height: 3, background: 'var(--border-strong)', margin: '20px 0 18px' }}>
                    <div style={{ position: 'absolute', inset: 0, width: `${line * 100}%`, background: 'var(--rd8-green-bright)' }} />
                  </div>
                  <div style={{ fontFamily: F_DISPLAY, fontWeight: 500, textTransform: 'uppercase', fontSize: 27, lineHeight: 1.05, letterSpacing: '0.01em', color: 'var(--text-primary)' }}>{g.title}</div>
                  <div style={{ fontFamily: F_BODY, fontSize: 18, lineHeight: 1.4, color: 'var(--text-tertiary)', marginTop: 8 }}>{g.body}</div>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 1 — HOOK / TITLE
// ════════════════════════════════════════════════════════════════════════════
function SceneHook() {
  return (
    <Sprite start={8.0} end={16.6}>
      {({ localTime: t, duration }) => (
        <div style={{ position: 'absolute', inset: 0, opacity: sceneFade(t, duration),
          display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: `0 ${MX}px` }}>
          <div style={{ marginBottom: 30 }}><Eyebrow t={t} at={0.2}>How RD8 helps you · How it works</Eyebrow></div>
          <Display t={t} at={0.5} size={138} lh={0.94}>
            A free <Accent>screening</Accent><br />of your design
          </Display>
          <div style={{ marginTop: 40 }}>
            <Body t={t} at={1.3} width={780} size={28}>
              Send your 2D drawings and 3D CAD. RD8 benchmarks them and points to real
              optimization potential — in two business days.
            </Body>
          </div>
          {/* file-type ticker */}
          <div style={{ marginTop: 54, display: 'flex', gap: 14 }}>
            {[['ruler', '2D DRAWINGS  ·  PDF / DWG'], ['cube', '3D CAD  ·  STEP']].map(([ic, lab], i) => {
              const r = rise(t, 1.9 + i * 0.15, 0.6);
              return (
                <div key={lab} style={{ ...cardStyle({ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 22px' }),
                  opacity: r.opacity, transform: `translateY(${r.ty}px)` }}>
                  <window.Icon name={ic} size={22} color="var(--rd8-green-bright)" />
                  <span style={{ fontFamily: F_MONO, fontSize: 16, letterSpacing: '0.08em', color: 'var(--text-primary)' }}>{lab}</span>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 2 — BRIDGE: three steps
// ════════════════════════════════════════════════════════════════════════════
function SceneBridge() {
  const steps = [['01', 'Set up an NDA'], ['02', 'Share your files'], ['03', 'Get your benchmarks']];
  return (
    <Sprite start={16.6} end={20.4}>
      {({ localTime: t, duration }) => (
        <div style={{ position: 'absolute', inset: 0, opacity: sceneFade(t, duration, 0.4, 0.5),
          display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: `0 ${MX}px` }}>
          <div style={{ marginBottom: 36 }}><Eyebrow t={t} at={0}>Getting started</Eyebrow></div>
          <Display t={t} at={0.25} size={92}>Three steps to start</Display>
          <div style={{ marginTop: 70, display: 'flex', gap: 30 }}>
            {steps.map(([n, label], i) => {
              const r = rise(t, 0.8 + i * 0.18, 0.6);
              const line = clamp((t - (1.0 + i * 0.18)) / 0.5, 0, 1);
              return (
                <div key={n} style={{ flex: 1, opacity: r.opacity, transform: `translateY(${r.ty}px)` }}>
                  <div style={{ height: 3, background: 'var(--border-strong)', position: 'relative', marginBottom: 22 }}>
                    <div style={{ position: 'absolute', inset: 0, width: `${line * 100}%`, background: 'var(--rd8-green-bright)' }} />
                  </div>
                  <div style={{ fontFamily: F_DISPLAY, fontWeight: 600, fontSize: 30, color: 'var(--rd8-green-bright)', letterSpacing: '0.01em' }}>{n}</div>
                  <div style={{ fontFamily: F_DISPLAY, fontWeight: 500, textTransform: 'uppercase', fontSize: 30, color: 'var(--text-primary)', marginTop: 8, letterSpacing: '0.01em' }}>{label}</div>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </Sprite>
  );
}

// shared step layout: left copy, right graphic
function StepFrame({ t, duration, n, title, body, children }) {
  return (
    <div style={{ position: 'absolute', inset: 0, opacity: sceneFade(t, duration),
      display: 'grid', gridTemplateColumns: '1fr 1fr', alignItems: 'center', padding: `0 ${MX}px`, gap: 60 }}>
      <div>
        <div style={{ marginBottom: 26 }}><Numeral n={n} t={t} at={0.1} /></div>
        <Display t={t} at={0.5} size={78} lh={1.0}>{title}</Display>
        <div style={{ marginTop: 30 }}><Body t={t} at={1.1} width={600}>{body}</Body></div>
      </div>
      <div style={{ position: 'relative', height: 620, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        {children}
      </div>
    </div>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 3 — STEP 01: NDA
// ════════════════════════════════════════════════════════════════════════════
function SceneNDA() {
  return (
    <Sprite start={20.4} end={28.0}>
      {({ localTime: t, duration }) => {
        const doc = rise(t, 0.4, 0.55, 40);
        const sign = clamp((t - 1.3) / 0.75, 0, 1);
        const stamp = clamp((t - 2.0) / 0.4, 0, 1);
        const stampScale = stamp < 1 ? 1.3 - 0.3 * Easing.easeOutCubic(stamp) : 1;
        const lockClose = clamp((t - 2.6) / 0.45, 0, 1);
        return (
          <StepFrame t={t} duration={duration} n="01" title={<>We set up an <Accent>NDA</Accent></>}
            body="So you can securely share your files. Mutual confidentiality is in place before anything changes hands.">
            <Glow x={120} y={140} s={420} />
            {/* NDA document */}
            <div style={{ position: 'relative', width: 430, opacity: doc.opacity, transform: `translateY(${doc.ty}px)` }}>
              <div style={{ ...cardStyle({ padding: '34px 36px 40px' }), boxShadow: 'var(--shadow-lg)' }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 26 }}>
                  <span style={{ fontFamily: F_MONO, fontSize: 15, letterSpacing: '0.14em', color: 'var(--rd8-green-bright)' }}>MUTUAL&nbsp;NDA</span>
                  <window.Icon name="file" size={22} color="var(--text-tertiary)" />
                </div>
                {[320, 300, 340, 280, 310, 250].map((w, i) => {
                  const o = clamp((t - (0.9 + i * 0.1)) / 0.4, 0, 1);
                  return <Bar key={i} w={w} h={8} mt={i ? 14 : 0} o={o} c="var(--neutral)" />;
                })}
                {/* signature line */}
                <div style={{ marginTop: 40, position: 'relative', height: 46 }}>
                  <div style={{ position: 'absolute', bottom: 0, width: 240, height: 2, background: 'var(--border-strong)' }} />
                  <svg width="240" height="46" style={{ position: 'absolute', bottom: 2 }}>
                    <path d="M6 34 C 30 6, 50 40, 78 20 S 120 6, 150 28 S 200 34, 226 14"
                      fill="none" stroke="var(--rd8-green-bright)" strokeWidth="3" strokeLinecap="round"
                      strokeDasharray="320" strokeDashoffset={320 - sign * 320} />
                  </svg>
                  <span style={{ position: 'absolute', bottom: -22, fontFamily: F_MONO, fontSize: 12, color: 'var(--text-tertiary)', letterSpacing: '0.1em' }}>AUTHORISED SIGNATURE</span>
                </div>
              </div>
              {/* SIGNED stamp */}
              <div style={{ position: 'absolute', right: -26, top: 150, opacity: stamp, transform: `rotate(-8deg) scale(${stampScale})` }}>
                <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '10px 18px',
                  border: '2px solid var(--rd8-green-bright)', borderRadius: 8, background: 'rgba(57,181,74,0.12)' }}>
                  <window.Icon name="check" size={20} color="var(--rd8-green-bright)" />
                  <span style={{ fontFamily: F_DISPLAY, fontWeight: 600, fontSize: 26, letterSpacing: '0.08em', color: 'var(--rd8-green-bright)' }}>SIGNED</span>
                </div>
              </div>
              {/* lock engaging */}
              <div style={{ position: 'absolute', left: -34, bottom: -34, opacity: clamp(lockClose * 1.2, 0, 1),
                transform: `translateY(${(1 - lockClose) * 14}px)`, width: 70, height: 70, borderRadius: '50%',
                background: 'var(--surface-gradient-card)', border: '1px solid var(--border-strong)',
                display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: 'var(--shadow-md)' }}>
                <window.Icon name="lock" size={30} color="var(--rd8-green-bright)" />
              </div>
            </div>
          </StepFrame>
        );
      }}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 4 — STEP 02: SHARE FILES
// ════════════════════════════════════════════════════════════════════════════
function SceneShare() {
  return (
    <Sprite start={28.0} end={36.0}>
      {({ localTime: t, duration }) => {
        const files = [
          { ic: 'ruler', a: 'DRAWING', b: '.PDF · .DWG', at: 0.55 },
          { ic: 'cube', a: 'CAD MODEL', b: '.STEP', at: 0.85 },
        ];
        const vault = rise(t, 0.35, 0.55, 0);
        const landed = clamp((t - 2.3) / 0.5, 0, 1);
        return (
          <StepFrame t={t} duration={duration} n="02" title={<>You securely <Accent>share</Accent> files</>}
            body="Drag in your 2D drawings and / or 3D CAD in STEP format. Everything is transferred over an encrypted, access-controlled channel.">
            <Glow x={300} y={130} s={430} />
            <div style={{ position: 'relative', width: 540, height: 420 }}>
              {/* moving file chips */}
              {files.map((f, i) => {
                const p = clamp((t - f.at) / 1.15, 0, 1);
                const e = Easing.easeInOutCubic(p);
                const startX = -40, endX = 300;
                const y = 60 + i * 150;
                const absorbed = p >= 1 ? clamp((t - (f.at + 1.15)) / 0.35, 0, 1) : 0;
                return (
                  <div key={f.a} style={{ position: 'absolute', left: startX + (endX - startX) * e, top: y,
                    opacity: (p > 0 ? 1 : 0) * (1 - absorbed), transform: `scale(${1 - absorbed * 0.3})` }}>
                    <div style={{ ...cardStyle({ display: 'flex', alignItems: 'center', gap: 14, padding: '16px 22px', width: 230 }), boxShadow: 'var(--shadow-md)' }}>
                      <div style={{ width: 42, height: 42, borderRadius: 8, background: 'var(--surface-canvas)',
                        border: '1px solid var(--border-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <window.Icon name={f.ic} size={22} color="var(--rd8-green-bright)" />
                      </div>
                      <div>
                        <div style={{ fontFamily: F_DISPLAY, fontWeight: 500, fontSize: 19, letterSpacing: '0.03em', color: 'var(--text-primary)' }}>{f.a}</div>
                        <div style={{ fontFamily: F_MONO, fontSize: 13, color: 'var(--text-tertiary)', marginTop: 2 }}>{f.b}</div>
                      </div>
                    </div>
                  </div>
                );
              })}
              {/* secure drop vault */}
              <div style={{ position: 'absolute', right: 0, top: 70, width: 220, height: 280, opacity: vault.opacity }}>
                <div style={{ position: 'absolute', inset: 0, borderRadius: 16, border: '2px dashed #2d40ea',
                  background: 'rgba(45,64,234,0.05)' }} />
                <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
                  alignItems: 'center', justifyContent: 'center', gap: 16 }}>
                  <div style={{ width: 78, height: 78, borderRadius: '50%', border: '1px solid var(--border-strong)',
                    background: 'var(--surface-gradient-card)', display: 'flex', alignItems: 'center', justifyContent: 'center',
                    boxShadow: landed > 0 ? '0 0 36px rgba(57,181,74,0.4)' : 'none', transition: 'none' }}>
                    <window.Icon name={landed >= 1 ? 'check' : 'upload'} size={34} color="var(--rd8-green-bright)" />
                  </div>
                  <div style={{ fontFamily: F_MONO, fontSize: 14, letterSpacing: '0.12em', color: 'var(--text-secondary)' }}>SECURE&nbsp;UPLOAD</div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 7, opacity: landed }}>
                    <window.Icon name="lock" size={13} color="var(--rd8-green-bright)" />
                    <span style={{ fontFamily: F_MONO, fontSize: 12, letterSpacing: '0.1em', color: 'var(--rd8-green-bright)' }}>ENCRYPTED · TLS</span>
                  </div>
                </div>
              </div>
            </div>
          </StepFrame>
        );
      }}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 5 — STEP 03: TWO BUSINESS DAYS → benchmarks
// ════════════════════════════════════════════════════════════════════════════
function SceneTurnaround() {
  return (
    <Sprite start={36.0} end={48.0}>
      {({ localTime: t, duration }) => {
        const fill = clamp((t - 1.2) / 1.8, 0, 1);
        const card = rise(t, 3.4, 0.7, 40);
        const rows = [
          { k: 'Tolerance grade', v: 'IT9 → IT11', pill: 'tbd' },
          { k: 'Critical dimensions', v: '31', pill: 'fail' },
          { k: 'Stack & fit', v: 'PASS', pill: 'pass' },
        ];
        return (
          <StepFrame t={t} duration={duration} n="03" title={<>Benchmarks in <Accent>two</Accent> business days</>}
            body="RD8 processes the shared material and returns benchmarks plus concrete optimization opportunities.">
            <Glow x={150} y={150} s={460} />
            <div style={{ position: 'relative', width: 540 }}>
              {/* day timeline */}
              <div style={{ display: 'flex', alignItems: 'flex-end', gap: 0, marginBottom: 46 }}>
                <span style={{ fontFamily: F_MONO, fontSize: 130, fontWeight: 500, lineHeight: 0.8, color: 'var(--rd8-green-bright)' }}>2</span>
                <span style={{ fontFamily: F_DISPLAY, fontWeight: 600, textTransform: 'uppercase', fontSize: 40, color: 'var(--text-primary)', marginLeft: 18, marginBottom: 8, letterSpacing: '0.02em' }}>Business<br />days</span>
              </div>
              <div style={{ position: 'relative', height: 4, background: 'var(--border-strong)', borderRadius: 2, marginBottom: 14 }}>
                <div style={{ position: 'absolute', inset: 0, width: `${fill * 100}%`, background: 'var(--rd8-green-bright)', borderRadius: 2 }} />
                <div style={{ position: 'absolute', left: 0, top: -5, width: 14, height: 14, marginLeft: -2, borderRadius: '50%', background: 'var(--rd8-green-bright)' }} />
                <div style={{ position: 'absolute', left: `${fill * 100}%`, top: -7, width: 18, height: 18, marginLeft: -9, borderRadius: '50%', background: 'var(--neutral-white)', border: '3px solid var(--rd8-green-bright)' }} />
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: F_MONO, fontSize: 13, letterSpacing: '0.08em', color: 'var(--text-tertiary)' }}>
                <span>FILES IN</span><span>RESULTS OUT</span>
              </div>
              {/* results card */}
              <div style={{ marginTop: 34, opacity: card.opacity, transform: `translateY(${card.ty}px)`,
                ...cardStyle({ padding: '24px 26px' }), boxShadow: 'var(--shadow-lg)' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 18 }}>
                  <window.Icon name="layers" size={18} color="var(--rd8-green-bright)" />
                  <span style={{ fontFamily: F_MONO, fontSize: 14, letterSpacing: '0.12em', color: 'var(--text-secondary)' }}>SCREENING&nbsp;BENCHMARK</span>
                </div>
                {rows.map((r, i) => {
                  const o = clamp((t - (3.9 + i * 0.2)) / 0.4, 0, 1);
                  return (
                    <div key={r.k} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                      padding: '12px 0', borderTop: i ? '1px solid var(--border-subtle)' : 'none', opacity: o }}>
                      <span style={{ fontFamily: F_BODY, fontSize: 18, color: 'var(--text-secondary)' }}>{r.k}</span>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                        <span style={{ fontFamily: F_MONO, fontSize: 18, color: 'var(--text-primary)' }}>{r.v}</span>
                        <DS.StatusPill status={r.pill} />
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          </StepFrame>
        );
      }}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 6 — INSIGHT A: 3D automated screening (Screen_rec_1)
// ════════════════════════════════════════════════════════════════════════════
function SceneInsight3D({ clip }) {
  return (
    <Sprite start={48.0} end={65.0}>
      {({ localTime: t, duration }) => {
        const win = rise(t, 0.7, 0.8, 50);
        const callout = (at) => rise(t, at, 0.6, 18);
        return (
          <div style={{ position: 'absolute', inset: 0, opacity: sceneFade(t, duration) }}>
            <div style={{ position: 'absolute', left: MX, top: 110 }}>
              <div style={{ marginBottom: 22 }}><Eyebrow t={t} at={0.1}>Automated screening · RD8 Software</Eyebrow></div>
              <Display t={t} at={0.35} size={60} lh={1.02} style={{ maxWidth: 820 }}>
                Pinpoint the potential<br />in your <Accent>3D model</Accent>
              </Display>
            </div>
            {/* window */}
            <div style={{ position: 'absolute', right: 110, top: 250, opacity: win.opacity, transform: `translateY(${win.ty}px)` }}>
              {clip && (
                <window.AppWindow width={920} height={644} variant="app" glow>
                  <window.ClipCanvas clip={clip} width={920} height={644} playSeconds={4} loop />
                </window.AppWindow>
              )}
            </div>
            {/* left callouts */}
            <div style={{ position: 'absolute', left: MX, top: 430, display: 'flex', flexDirection: 'column', gap: 18, width: 510 }}>
              {[
                ['target', 'Interfaces & contacts', 'Where variation actually lives', 1.6],
                ['layers', 'Tolerance allocation check', 'Classification of tolerance requirements', 2.0],
              ].map(([ic, a, b, at]) => {
                const r = callout(at);
                return (
                  <div key={a} style={{ ...cardStyle({ padding: '18px 22px', display: 'flex', gap: 16, alignItems: 'center' }),
                    opacity: r.opacity, transform: `translateY(${r.ty}px)`, boxShadow: 'var(--shadow-md)' }}>
                    <window.Icon name={ic} size={26} color="var(--rd8-green-bright)" style={{ flex: 'none' }} />
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 3, minWidth: 0 }}>
                      <div style={{ fontFamily: F_DISPLAY, fontWeight: 500, textTransform: 'uppercase', fontSize: 21, lineHeight: 1.1, color: 'var(--text-primary)', letterSpacing: '0.02em', whiteSpace: 'nowrap' }}>{a}</div>
                      <div style={{ fontFamily: F_BODY, fontSize: 16, lineHeight: 1.2, color: 'var(--text-tertiary)' }}>{b}</div>
                    </div>
                  </div>
                );
              })}
              {/* stat row */}
              <div style={{ display: 'flex', gap: 40, marginTop: 10 }}>
                <div style={{ opacity: callout(2.5).opacity, transform: `translateY(${callout(2.5).ty}px)` }}><DS.StatBlock value="113" label="Parts analysed" /></div>
                <div style={{ opacity: callout(2.7).opacity, transform: `translateY(${callout(2.7).ty}px)` }}><DS.StatBlock value="99.892%" label="Predicted yield" accent /></div>
              </div>
            </div>
            {/* floating PASS pill over window */}
            <div style={{ position: 'absolute', right: 150, top: 230, opacity: callout(2.9).opacity, transform: `translateY(${callout(2.9).ty}px)` }}>
              <div style={{ ...cardStyle({ padding: '10px 16px', display: 'flex', alignItems: 'center', gap: 12 }), boxShadow: 'var(--shadow-lg)' }}>
                <span style={{ fontFamily: F_BODY, fontSize: 16, color: 'var(--text-secondary)' }}>Stack &amp; fit inside Frame</span>
                <DS.StatusPill status="pass" solid />
              </div>
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 7 — INSIGHT B: 2D drawing analysis (Screen_rec_2)
// ════════════════════════════════════════════════════════════════════════════
function SceneInsight2D({ clip }) {
  return (
    <Sprite start={65.0} end={78.0}>
      {({ localTime: t, duration }) => {
        const win = rise(t, 0.7, 0.8, 50);
        const c = (at) => rise(t, at, 0.6, 18);
        const complexity = clamp((t - 2.2) / 1.2, 0, 1);
        return (
          <div style={{ position: 'absolute', inset: 0, opacity: sceneFade(t, duration) }}>
            <div style={{ position: 'absolute', left: MX, top: 130 }}>
              <div style={{ marginBottom: 22 }}><Eyebrow t={t} at={0.1}>Drawing analysis · 2D screening</Eyebrow></div>
              <Display t={t} at={0.35} size={58} lh={1.02} style={{ maxWidth: 880 }}>
                Benchmark tolerances<br />&amp; design <Accent>complexity</Accent>
              </Display>
              <div style={{ marginTop: 52 }}>
                <Body t={t} at={1.1} width={620} size={23}>
                  We read your drawings for current tolerance levels and complexity — then target
                  critical dimensions and ease over-strict tolerances.
                </Body>
              </div>
              {/* stats */}
              <div style={{ marginTop: 44, display: 'flex', gap: 44 }}>
                <div style={{ opacity: c(1.7).opacity, transform: `translateY(${c(1.7).ty}px)` }}><DS.StatBlock value="248" label="Dimensions read" /></div>
                <div style={{ opacity: c(1.9).opacity, transform: `translateY(${c(1.9).ty}px)` }}><DS.StatBlock value="31" label="Critical found" /></div>
                <div style={{ opacity: c(2.1).opacity, transform: `translateY(${c(2.1).ty}px)` }}><DS.StatBlock value="−18%" label="Tolerances eased" accent /></div>
              </div>
              {/* complexity meter */}
              <div style={{ marginTop: 40, width: 560, opacity: c(2.2).opacity, transform: `translateY(${c(2.2).ty}px)` }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: F_MONO, fontSize: 14, letterSpacing: '0.08em', color: 'var(--text-tertiary)', marginBottom: 10 }}>
                  <span>DESIGN COMPLEXITY</span><span style={{ color: 'var(--rd8-green-bright)' }}>BENCHMARKED</span>
                </div>
                <div style={{ height: 10, borderRadius: 5, background: 'var(--surface-card)', border: '1px solid var(--border-subtle)', overflow: 'hidden' }}>
                  <div style={{ height: '100%', width: `${complexity * 72}%`,
                    background: 'linear-gradient(90deg, var(--rd8-green), var(--rd8-green-bright))' }} />
                </div>
              </div>
            </div>
            {/* portrait report window */}
            <div style={{ position: 'absolute', right: 150, top: 150, opacity: win.opacity, transform: `translateY(${win.ty}px)` }}>
              {clip && (
                <window.AppWindow width={560} height={730} variant="browser" url="rd8.ai/screening/drawing" glow>
                  <window.ClipCanvas clip={clip} width={560} height={730} playSeconds={9} loop />
                </window.AppWindow>
              )}
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENE 8 — CTA END CARD
// ════════════════════════════════════════════════════════════════════════════
function SceneCTA({ cta }) {
  return (
    <Sprite start={78.0} end={87.0}>
      {({ localTime: t, duration }) => {
        const logo = rise(t, 0.3, 0.7, 20);
        const btn = rise(t, 1.5, 0.6, 16);
        return (
          <div style={{ position: 'absolute', inset: 0, opacity: sceneFade(t, duration, 0.5, 0.6),
            display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center' }}>
            <Glow x={W / 2 - 360} y={H / 2 - 360} s={720} c="rgba(54,235,8,0.16)" />
            <img src="assets/rd8-logo-white-text.png" alt="RD8" style={{ height: 116, marginBottom: 6,
              opacity: logo.opacity, transform: `translateY(${logo.ty}px)` }} />
            <Display t={t} at={0.6} size={104} lh={1.0} style={{ textAlign: 'center' }}>
              Book your free <Accent>screening</Accent>
            </Display>
            <div style={{ marginTop: 54, maxWidth: 760 }}>
              <Body t={t} at={1.1} width={760} size={26} color="var(--text-secondary)">
                Share your 2D drawings and STEP files — get benchmarks and optimization potential in two business days.
              </Body>
            </div>
            <div style={{ marginTop: 44, display: 'flex', gap: 18, alignItems: 'center', justifyContent: 'center',
              opacity: btn.opacity, transform: `translateY(${btn.ty}px)` }}>
              <a href="https://www.rd8.tech/consulting#contact" target="_blank" rel="noopener noreferrer" style={{ textDecoration: 'none' }}>
                <DS.Button variant="primary" size="lg" style={{ fontSize: 20, padding: '16px 30px' }}>{cta.primary}</DS.Button>
              </a>
            </div>
            {/* step recap */}
            <div style={{ marginTop: 56, display: 'flex', gap: 26, opacity: rise(t, 2.1, 0.6).opacity }}>
              {['01 · NDA', '02 · Share files', '03 · Benchmarks in 2 days'].map((s) => (
                <span key={s} style={{ fontFamily: F_MONO, fontSize: 15, letterSpacing: '0.1em', color: 'var(--text-tertiary)' }}>{s}</span>
              ))}
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

// expose a factory that wires clips + cta text
function DevBridge() {
  const tl = window.useTimeline();
  React.useEffect(() => {
    window.__seek = (t) => { tl.setPlaying(false); tl.setTime(t); };
    window.__play = () => tl.setPlaying(true);
  });
  return null;
}

window.buildScenes = function ({ clip3d, clip2d, cta }) {
  return [
    <RootBackdrop key="bg" />,
    <DevBridge key="dev" />,
    <SceneOpening key="opening" />,
    <SceneHook key="hook" />,
    <SceneBridge key="bridge" />,
    <SceneNDA key="nda" />,
    <SceneShare key="share" />,
    <SceneTurnaround key="turn" />,
    <SceneInsight3D key="i3d" clip={clip3d} />,
    <SceneInsight2D key="i2d" clip={clip2d} />,
    <SceneCTA key="cta" cta={cta} />,
  ];
};
