/* global React, Stage, Sprite, useSprite, clamp, C, SCENES, TOTAL,
          FrameChrome, ReadoutPanel, BridgeGround, BridgeSolid, BridgeWireframe,
          BR, P, polyPath, linePath, makeBridgePoints, AssetTitle */
// ============================================================
// Inframind — Workflow Animation (Scenes 3–9 + Video root)
// ============================================================

const { useMemo: useMemoSc } = React;

// ============================================================
// SCENE 03 — RECONSTRUCT: point cloud to surface twin
// ============================================================

function SceneReconstruct() {
  const { progress } = useSprite();
  const ph = (start, full, fadeOutStart = 1.01, end = 1.01) => {
    if (progress < start) return 0;
    if (progress < full)  return (progress - start) / (full - start);
    if (progress < fadeOutStart) return 1;
    if (progress >= end) return 0;
    return 1 - (progress - fadeOutStart) / (end - fadeOutStart);
  };
  const phCloud   = ph(0.05, 0.25, 0.55, 0.72);
  const phWire    = ph(0.20, 0.45, 0.78, 0.88);
  const phSurface = ph(0.50, 0.70);

  const points = useMemoSc(() => makeBridgePoints(), []);

  return (
    <div style={{position: "absolute", inset: 0}}>
      <AssetTitle text="Asset model · A14 Bridge-07 / Span-02 · Concrete · 4-girder · 92m"/>

      <svg viewBox="0 0 1920 1080" style={{position: "absolute", inset: 0, width: "100%", height: "100%"}}>
        <BridgeGround opacity={Math.min(1, phCloud + phSurface)}/>

        {phSurface > 0 && <BridgeSolid opacity={phSurface * 0.9}/>}

        {phWire > 0 && <BridgeWireframe opacity={Math.max(phWire, phSurface * 0.45)}/>}

        {/* Point cloud raining in */}
        {phCloud > 0 && (
          <g opacity={phCloud * (1 - phSurface * 0.5)}>
            {points.map((pt, i) => {
              const fall = clamp((progress * 1.6 - pt.jitter * 0.5 - 0.05) / 0.5, 0, 1);
              const fallEased = 1 - Math.pow(1 - fall, 2);
              const [sx, sy] = P(pt.pos);
              const fallY = sy - (1 - fallEased) * 220;
              if (fall < 0.02) return null;
              return <circle key={i} cx={sx} cy={fallY}
                             r={0.5 + pt.jitter * 0.8}
                             fill={C.scan}
                             opacity={(0.4 + (1 - pt.depth) * 0.4) * fallEased}/>;
            })}
          </g>
        )}

      </svg>

      {/* Layers panel (left) */}
      <div style={{
        position: "absolute", left: 64, top: 420,
        width: 280,
        background: C.paper,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        padding: "18px 22px",
        fontFamily: "JetBrains Mono, monospace",
        boxShadow: "0 1px 2px rgba(0,0,0,0.04), 0 4px 12px -4px rgba(0,0,0,0.08)",
      }}>
        <div style={{fontSize: 11, color: C.muted, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 14, paddingBottom: 10, borderBottom: `1px solid ${C.borderSoft}`}}>Layers</div>
        <LayerRow label="Surface mesh"     tag="LiDAR" done={phSurface > 0.3}/>
        <LayerRow label="Wireframe"        tag="MESH"  done={phSurface > 0.3}/>
      </div>

      <ReadoutPanel x={1380} y={420} width={320} title="Reconstruction" items={[
        { k: "Phase",       v: phSurface > 0.5 ? "Surface mesh" : phWire > 0.3 ? "Triangulation" : "Point cloud", color: C.scan },
        { k: "Points",      v: `${(progress * 1.4).toFixed(2)} M`,                                                                                       color: C.scanLite },
        { k: "Triangles",   v: `${Math.floor(progress * 840)}k`,                                                                                          color: phWire > 0.3 ? C.scan : C.dim },
      ]}/>
    </div>
  );
}

function LayerRow({ label, tag, done, amber }) {
  return (
    <div style={{
      display: "grid", gridTemplateColumns: "14px 1fr auto",
      gap: 10, alignItems: "center",
      padding: "8px 0", borderBottom: `1px solid ${C.borderSoft}`,
    }}>
      <span style={{
        width: 12, height: 12,
        border: `1.5px solid ${done ? C.ink : C.dim}`,
        background: done ? C.ink : "transparent",
        borderRadius: 2,
        display: "flex", alignItems: "center", justifyContent: "center",
      }}>
        {done && <span style={{color: C.paper, fontSize: 9, lineHeight: 1}}>✓</span>}
      </span>
      <span style={{fontFamily: "Inter, sans-serif", fontSize: 13, color: C.ink}}>{label}</span>
      <span style={{fontSize: 9, color: amber && done ? C.high : C.muted, letterSpacing: "0.12em"}}>{tag}</span>
    </div>
  );
}

// ============================================================
// SCENE 04 — DETECT: AI scan reveals defects in 3D
// ============================================================

const DEFECTS_3D_SC = [
  { id: "CR-04",   pos: [-120, BR.deck.yT - 0.5, -20], surface: true,  c: C.crit,  sev: "S1", label: "12.8 mm crack",     mod: "CV"    },
  { id: "SP-12",   pos: [60,   -32, BR.deck.zN],       surface: true,  c: C.high,  sev: "S2", label: "spalling · 4.2 mm", mod: "CV"    },
  { id: "DF-02",   pos: [200,  BR.deck.yT - 0.5, 40],  surface: true,  c: C.low,   sev: "S3", label: "1.6 mm deformation", mod: "LiDAR" },
  { id: "SP-07",   pos: [120, -78, 24],                surface: false, c: C.high,  sev: "S2", label: "spalling · 6.0 mm", mod: "CV"    },
  { id: "CR-02",   pos: [220,  60, 0],                 surface: false, c: C.crit,  sev: "S1", label: "9.6 mm crack",      mod: "CV"    },
];

function SceneDetect() {
  const { progress } = useSprite();
  const scanT = clamp((progress - 0.05) / 0.7, 0, 1);
  const scanX = BR.deck.xL + scanT * (BR.deck.xR - BR.deck.xL);

  const states = DEFECTS_3D_SC.map(d => {
    const xRel = (d.pos[0] - BR.deck.xL) / (BR.deck.xR - BR.deck.xL);
    const triggered = scanT > xRel;
    const age = triggered ? clamp((scanT - xRel) * 4, 0, 1) : 0;
    return { ...d, triggered, age };
  });
  const detected = states.filter(d => d.triggered).length;
  const critical = states.filter(d => d.triggered && d.sev === "S1").length;

  return (
    <div style={{position: "absolute", inset: 0}}>
      <AssetTitle text="AI defect detection · 2 modalities · CV + LiDAR"/>

      <svg viewBox="0 0 1920 1080" style={{position: "absolute", inset: 0, width: "100%", height: "100%"}}>
        <BridgeGround opacity={0.6}/>
        <BridgeSolid opacity={0.8}/>
        <BridgeWireframe opacity={0.3}/>
        {scanT < 1 && <AIScanPlane x={scanX}/>}
        {states.map((d, i) => {
          if (!d.triggered) return null;
          const [sx, sy] = P(d.pos);
          const pulse = 1 + Math.sin(progress * 18 + i) * 0.18;
          const baseR = d.surface ? 9 : 7;
          const lx = d.surface ? sx + 50 : sx - 60;
          const ly = d.surface ? sy - 60 : sy + 60;
          return (
            <g key={d.id} opacity={d.age}>
              <circle cx={sx} cy={sy} r={baseR * 3 * pulse} fill={d.c} opacity="0.12"/>
              <circle cx={sx} cy={sy} r={baseR * 1.6} fill={d.c} opacity="0.32"/>
              <circle cx={sx} cy={sy} r={baseR} fill={d.c}/>
              <line x1={sx} y1={sy} x2={lx} y2={ly} stroke={d.c} strokeWidth="0.8" opacity="0.7"/>
              <g transform={`translate(${lx - (d.surface ? 0 : 160)}, ${ly - 30})`}>
                <rect x="0" y="0" width="160" height="42" fill={C.paper} stroke={d.c} strokeWidth="1" rx="3"/>
                <text x="10" y="16" fontFamily="JetBrains Mono, monospace" fontSize="12" fill={d.c} fontWeight="600">{d.id} · {d.sev}</text>
                <text x="10" y="30" fontFamily="JetBrains Mono, monospace" fontSize="10" fill={C.muted}>{d.label}</text>
                <text x="150" y="40" fontFamily="JetBrains Mono, monospace" fontSize="9" fill={C.dim} textAnchor="end" letterSpacing="0.06em">{d.mod}</text>
              </g>
            </g>
          );
        })}
      </svg>

      <ReadoutPanel x={1380} y={500} width={320} title="AI scan" items={[
        { k: "Chainage",         v: `${Math.floor(scanT * 800)} m`,                                  color: C.scan },
        { k: "Defects detected", v: String(detected * 30 + Math.floor(scanT * 7)),                   color: C.scanLite },
        { k: "Critical (S1)",    v: String(critical * 6),                                            color: critical > 0 ? C.crit : C.dim },
        { k: "Avg. confidence",  v: `${(0.86 + scanT * 0.08).toFixed(2)}`,                           color: C.ok },
      ]}/>
    </div>
  );
}

function AIScanPlane({ x }) {
  const corners = [
    [x, BR.deck.yT - 12, BR.deck.zN - 12],
    [x, BR.deck.yT - 12, BR.deck.zF + 12],
    [x, BR.ground + 8,   BR.deck.zF + 12],
    [x, BR.ground + 8,   BR.deck.zN - 12],
  ];
  return (
    <g>
      <path d={polyPath(corners)} fill={C.scan} fillOpacity="0.07" stroke={C.scan} strokeOpacity="0.8" strokeWidth="1"/>
    </g>
  );
}

// ============================================================
// SCENE 05 — QUANTIFY: risk-ranked insights panel
// ============================================================
function SceneQuantify() {
  const { progress } = useSprite();
  const defects = [
    { label: "Longitudinal crack", id: "CR-04",  loc: "ch 412.6 · deck",   val: "12.8 mm", c: C.crit, score: 87, conf: 0.94, appear: 0.05 },
    { label: "Longitudinal crack", id: "CR-02",  loc: "pier 2 · NE",       val: "9.6 mm",  c: C.crit, score: 82, conf: 0.91, appear: 0.18 },
    { label: "Concrete spalling",  id: "SP-12",  loc: "girder 2 · ch 414", val: "4.2 mm",  c: C.high, score: 64, conf: 0.87, appear: 0.31 },
    { label: "Concrete spalling",  id: "SP-07",  loc: "deck slab · ch 420", val: "6.0 mm", c: C.high, score: 58, conf: 0.78, appear: 0.44 },
    { label: "Deformation",        id: "DF-02",  loc: "deck · 1.6 mm Δ",   val: "1.6 mm",  c: C.low,  score: 34, conf: 0.96, appear: 0.57 },
  ];
  const healthScore = Math.max(72, Math.floor(100 - progress * 32));
  const visible = defects.filter(d => progress >= d.appear);

  return (
    <div style={{position: "absolute", inset: 0}}>
      <AssetTitle text={`Asset insight · A14 Bridge-07 / Span-02 · ${visible.length} of ${defects.length} defects ranked`}/>

      {/* Asset health card (bottom-left) */}
      <div style={{
        position: "absolute", left: 64, top: 780, width: 700,
        background: C.paper,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        padding: "24px 28px",
        display: "grid", gridTemplateColumns: "1.1fr 1fr", gap: 32, alignItems: "center",
        boxShadow: "0 1px 2px rgba(0,0,0,0.04), 0 4px 12px -4px rgba(0,0,0,0.08)",
      }}>
        <div>
          <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.muted, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 8}}>Asset health score</div>
          <div style={{display: "flex", alignItems: "baseline", gap: 14}}>
            <span style={{fontSize: 72, fontWeight: 700, color: C.ink, letterSpacing: "-0.035em", fontVariantNumeric: "tabular-nums", lineHeight: 1}}>{healthScore}</span>
            <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 13, color: C.high}}>▼ {Math.floor(progress * 12)} pts</span>
          </div>
          <div style={{marginTop: 14, height: 6, display: "grid", gridTemplateColumns: "0.6fr 0.2fr 0.2fr", borderRadius: 3, overflow: "hidden"}}>
            <span style={{background: C.ok}}/><span style={{background: C.med}}/><span style={{background: C.crit}}/>
          </div>
        </div>
        <div style={{display: "flex", flexDirection: "column", gap: 8}}>
          <SevBreak label="S1 · critical" count={visible.filter(d => d.score >= 80).length * 3} color={C.crit}/>
          <SevBreak label="S2 · medium"   count={visible.filter(d => d.score >= 50 && d.score < 80).length * 4} color={C.high}/>
          <SevBreak label="S3 · low"      count={visible.filter(d => d.score < 50).length * 8 + 12} color={C.low}/>
        </div>
      </div>

      {/* Defect list */}
      <div style={{
        position: "absolute", right: 64, top: 380, width: 780,
        background: C.paper,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        padding: "28px 32px",
        boxShadow: "0 1px 2px rgba(0,0,0,0.04), 0 4px 12px -4px rgba(0,0,0,0.08)",
      }}>
        <div style={{display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 18, paddingBottom: 14, borderBottom: `1px solid ${C.borderSoft}`}}>
          <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: C.muted, letterSpacing: "0.12em", textTransform: "uppercase"}}>Risk-ranked defects · top 5</span>
          <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 13, color: C.ink}}>23 total</span>
        </div>
        <div style={{display: "flex", flexDirection: "column", gap: 10}}>
          {defects.map((d, i) => {
            if (progress < d.appear) return null;
            const local = Math.min(1, (progress - d.appear) / 0.10);
            const scoreShown = Math.floor(d.score * local);
            return (
              <div key={i} style={{
                display: "grid",
                gridTemplateColumns: "12px 1fr auto auto",
                gap: 18, alignItems: "center",
                padding: "14px 18px",
                background: C.bg,
                border: `1px solid ${C.borderSoft}`,
                borderRadius: 6,
                opacity: local,
                transform: `translateX(${(1 - local) * 24}px)`,
              }}>
                <span style={{width: 10, height: 10, background: d.c, borderRadius: "50%"}}/>
                <div style={{display: "flex", flexDirection: "column", gap: 4}}>
                  <span style={{fontSize: 16, color: C.ink, fontFamily: "Inter, sans-serif", fontWeight: 500}}>{d.label}</span>
                  <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.muted}}>{d.id} · {d.loc} · conf {d.conf}</span>
                </div>
                <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: C.muted, width: 90, textAlign: "right"}}>{d.val}</span>
                <div style={{display: "flex", alignItems: "center", gap: 12}}>
                  <div style={{width: 90, height: 5, background: C.borderSoft, borderRadius: 3, position: "relative", overflow: "hidden"}}>
                    <div style={{position: "absolute", inset: 0, width: `${scoreShown}%`, background: d.c, borderRadius: 3}}/>
                  </div>
                  <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 14, color: C.ink, width: 28, textAlign: "right", fontVariantNumeric: "tabular-nums", fontWeight: 600}}>{scoreShown}</span>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function SevBreak({ label, count, color }) {
  return (
    <div style={{display: "grid", gridTemplateColumns: "10px 1fr auto", gap: 12, alignItems: "center", paddingBottom: 8, borderBottom: `1px solid ${C.borderSoft}`}}>
      <span style={{width: 8, height: 8, background: color, borderRadius: "50%"}}/>
      <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: C.muted, letterSpacing: "0.04em"}}>{label}</span>
      <span style={{fontFamily: "Inter, sans-serif", fontSize: 20, fontWeight: 600, color: C.ink, fontVariantNumeric: "tabular-nums"}}>{count}</span>
    </div>
  );
}

// ============================================================
// SCENE 06 — REPORT: cursor → Generate → PDF slides in
// ============================================================
function SceneReport() {
  const { progress } = useSprite();
  const cursorT = Math.min(1, progress / 0.3);
  const pressed = progress >= 0.3 && progress < 0.45;
  const reportProgress = Math.max(0, (progress - 0.45) / 0.55);
  const cx = 460 + cursorT * 320;
  const cy = 460 + cursorT * 80;

  return (
    <div style={{position: "absolute", inset: 0}}>
      <AssetTitle text="One-click evidence pack export"/>

      <div style={{
        position: "absolute", left: 200, top: 360, width: 580, height: 540,
        background: C.paper,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        padding: 28,
        boxShadow: "0 1px 2px rgba(0,0,0,0.04), 0 4px 12px -4px rgba(0,0,0,0.08)",
      }}>
        <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.muted, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 18}}>Inspection summary · A14 Bridge-07</div>
        <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 20}}>
          {[
            { k: "Defects",  v: "147" },
            { k: "Critical", v: "12",  c: C.crit },
            { k: "Reviewed", v: "92 / 147" },
            { k: "Health",   v: "72" },
          ].map((s, i) => (
            <div key={i} style={{border: `1px solid ${C.borderSoft}`, borderRadius: 6, padding: "16px 18px"}}>
              <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: C.muted, letterSpacing: "0.06em", textTransform: "uppercase"}}>{s.k}</div>
              <div style={{fontSize: 32, fontWeight: 600, marginTop: 6, color: s.c || C.ink, letterSpacing: "-0.025em"}}>{s.v}</div>
            </div>
          ))}
        </div>
        <div style={{display: "flex", flexDirection: "column", gap: 8, marginBottom: 24}}>
          {[
            { c: C.crit, t: "CR-04 · 12.8mm critical crack" },
            { c: C.crit, t: "CR-02 · 9.6mm critical crack" },
            { c: C.high, t: "SP-12 · 4.2mm spalling" },
          ].map((r, i) => (
            <div key={i} style={{display: "flex", alignItems: "center", gap: 10, padding: "10px 14px", background: C.bg, border: `1px solid ${C.borderSoft}`, borderRadius: 4, fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: C.ink}}>
              <span style={{width: 8, height: 8, background: r.c, borderRadius: "50%"}}/>{r.t}
            </div>
          ))}
        </div>
        <button style={{
          width: "100%", padding: "16px 20px",
          background: pressed ? C.ink2 : C.ink,
          border: "none",
          color: C.paper,
          fontFamily: "Inter, sans-serif", fontSize: 15, fontWeight: 600,
          letterSpacing: "0.02em",
          borderRadius: 6,
          transform: pressed ? "scale(0.985)" : "scale(1)",
          cursor: "pointer",
        }}>
          ↓ Export evidence pack
        </button>
      </div>

      <svg width="32" height="32" style={{
        position: "absolute", left: cx, top: cy, zIndex: 20,
        opacity: progress < 0.65 ? 1 : Math.max(0, 1 - (progress - 0.65) * 5),
        filter: "drop-shadow(0 2px 4px rgba(0,0,0,0.25))",
      }} viewBox="0 0 32 32">
        <path d="M5 3 L5 22 L11 18 L15 26 L19 24 L15 16 L23 16 Z" fill={C.ink} stroke={C.paper} strokeWidth="1.5"/>
      </svg>

      {reportProgress > 0 && <ReportDoc progress={reportProgress}/>}
    </div>
  );
}

function ReportDoc({ progress }) {
  const tx = (1 - Math.min(1, progress * 1.4)) * 600;
  const lineP = Math.max(0, progress - 0.2);
  return (
    <div style={{
      position: "absolute", right: 200, top: 320, width: 520, height: 640,
      background: C.paper,
      boxShadow: "0 30px 80px rgba(0,0,0,0.18), 0 0 0 1px rgba(0,0,0,0.06)",
      transform: `translateX(${tx}px)`,
      fontFamily: "Inter, sans-serif",
      color: C.ink,
      padding: 48,
      borderRadius: 4,
    }}>
      <div style={{display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 28, paddingBottom: 16, borderBottom: `1px solid ${C.border}`}}>
        <div>
          <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: C.muted, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 6}}>Evidence pack</div>
          <div style={{fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em"}}>A14 Bridge-07 · Span-02</div>
        </div>
        <img src="assets/inframind-logo.png" alt="Inframind" style={{height: 22, width: "auto"}}/>
      </div>
      <div style={{fontSize: 24, fontWeight: 700, letterSpacing: "-0.025em", marginBottom: 8, opacity: Math.min(1, lineP * 4)}}>Inspection Report</div>
      <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.muted, letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 28, opacity: Math.min(1, lineP * 4)}}>Generated · 11 Nov 2026</div>

      {[{w:"100%",t:"Asset summary"},{w:"78%",t:null},{w:"92%",t:null},{w:"60%",t:null}].map((l, i) => (
        <FakeLine key={i} index={i} progress={lineP} width={l.w} title={l.t}/>
      ))}

      <div style={{marginTop: 24, display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 10, opacity: Math.min(1, Math.max(0, (lineP - 0.4) * 3))}}>
        {[{v:"147",l:"defects"},{v:"12",l:"critical",c:C.crit},{v:"72",l:"health"}].map((s, i) => (
          <div key={i} style={{border: `1px solid ${C.border}`, padding: "10px 12px", borderRadius: 4}}>
            <div style={{fontSize: 22, fontWeight: 600, color: s.c || C.ink, letterSpacing: "-0.02em"}}>{s.v}</div>
            <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 9, color: C.muted, letterSpacing: "0.06em", textTransform: "uppercase", marginTop: 2}}>{s.l}</div>
          </div>
        ))}
      </div>

      <div style={{marginTop: 20, opacity: Math.min(1, Math.max(0, (lineP - 0.55) * 3))}}>
        <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 9, color: C.muted, letterSpacing: "0.08em", textTransform: "uppercase", marginBottom: 8}}>Top priority defects</div>
        {[
          { c: C.crit, t: "CR-04 · Longitudinal crack · 12.8mm" },
          { c: C.crit, t: "CR-02 · Longitudinal crack · 9.6mm" },
          { c: C.high, t: "SP-12 · Concrete spalling · 4.2mm" },
        ].map((r, i) => (
          <div key={i} style={{display:"flex", alignItems:"center", gap: 10, padding: "6px 0", borderBottom: i < 2 ? `1px solid ${C.hairline}` : "none"}}>
            <span style={{width: 6, height: 6, background: r.c, borderRadius: "50%"}}/>
            <span style={{fontSize: 11, color: C.ink}}>{r.t}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function FakeLine({ index, progress, width, title }) {
  const localProgress = Math.max(0, progress - index * 0.05);
  const op = Math.min(1, localProgress * 5);
  return (
    <div style={{marginBottom: 10, opacity: op}}>
      {title && <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: C.muted, letterSpacing: "0.06em", textTransform: "uppercase", marginBottom: 4}}>{title}</div>}
      <div style={{width, height: 8, background: C.borderSoft, borderRadius: 2}}/>
    </div>
  );
}

// ============================================================
// SCENE 07 — COMPARE: two side-by-side bridges
// ============================================================
function SceneCompare() {
  const { progress } = useSprite();
  const baselineDefects = [
    { pos: [-120, BR.deck.yT - 0.5, -20], c: C.high, r: 5 },
    { pos: [60,   -32, BR.deck.zN],       c: C.low,  r: 4 },
    { pos: [200,  BR.deck.yT - 0.5, 40],  c: C.low,  r: 4 },
  ];
  const currentDefects = [
    { pos: [-120, BR.deck.yT - 0.5, -20], c: C.crit, r: 8, label: "CR-04" },
    { pos: [60,   -32, BR.deck.zN],       c: C.high, r: 7 },
    { pos: [200,  BR.deck.yT - 0.5, 40],  c: C.low,  r: 5 },
    { pos: [220,  BR.deck.yT - 0.5, 10],   c: C.crit, r: 7, label: "CR-02" },
    { pos: [120,  -32, 24],                c: C.high, r: 6, label: "SP-07" },
  ];

  return (
    <div style={{position: "absolute", inset: 0}}>
      <AssetTitle text="Cross-campaign change · A14 Bridge-07 / Span-02 · baseline vs current"/>

      <div style={{
        position: "absolute", top: 420, left: 64, right: 64,
        display: "grid", gridTemplateColumns: "1fr 110px 1fr", gap: 0, alignItems: "stretch",
      }}>
        <BridgeCardSc year="2024" subtitle="Baseline survey" defects={87} health={84}
                      severity={{ s1: 4, s2: 18, s3: 65 }}
                      bridgeDefects={baselineDefects} progress={progress} delay={0}/>
        <DeltaArrow progress={progress}/>
        <BridgeCardSc year="2026" subtitle="Current survey" defects={147} health={72}
                      severity={{ s1: 12, s2: 38, s3: 97 }}
                      bridgeDefects={currentDefects} progress={progress} delay={0.12} highlight/>
      </div>

      <div style={{
        position: "absolute", bottom: 130, left: 0, right: 0,
        display: "flex", justifyContent: "center", gap: 16,
        opacity: Math.max(0, Math.min(1, (progress - 0.55) * 3)),
      }}>
        {[
          { v: "+60",     l: "new defects",          c: C.high },
          { v: "+4.2 mm", l: "max deformation Δ",    c: C.crit },
          { v: "−12",     l: "asset health pts",     c: C.crit },
          { v: "8",       l: "newly critical",       c: C.high },
        ].map((s, i) => (
          <div key={i} style={{
            padding: "18px 24px",
            background: C.paper,
            border: `1px solid ${C.border}`,
            borderRadius: 6,
            minWidth: 180,
            boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
          }}>
            <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.muted, letterSpacing: "0.08em", textTransform: "uppercase", marginBottom: 8}}>{s.l}</div>
            <div style={{fontSize: 30, fontWeight: 700, color: s.c, letterSpacing: "-0.03em", fontFamily: "Inter, sans-serif", fontVariantNumeric: "tabular-nums"}}>{s.v}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function BridgeCardSc({ year, subtitle, defects, health, severity, bridgeDefects, progress, delay, highlight }) {
  const cardP = Math.max(0, Math.min(1, (progress - delay) * 2));
  return (
    <div style={{
      background: C.paper,
      border: `1px solid ${highlight ? C.ink : C.border}`,
      borderRadius: 8,
      padding: 24,
      opacity: cardP,
      transform: `translateY(${(1 - cardP) * 16}px)`,
      display: "flex", flexDirection: "column", gap: 16,
      boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
    }}>
      <div style={{display: "flex", justifyContent: "space-between", alignItems: "baseline", paddingBottom: 12, borderBottom: `1px solid ${C.borderSoft}`}}>
        <div style={{display: "flex", alignItems: "baseline", gap: 14}}>
          <span style={{fontSize: 36, fontWeight: 700, letterSpacing: "-0.035em", color: C.ink, lineHeight: 1}}>{year}</span>
          <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: highlight ? C.ink : C.muted, letterSpacing: "0.08em", textTransform: "uppercase"}}>{subtitle}</span>
        </div>
        <span style={{
          fontFamily: "JetBrains Mono, monospace", fontSize: 10,
          color: highlight ? C.crit : C.muted,
          letterSpacing: "0.08em", textTransform: "uppercase",
          border: `1px solid ${highlight ? C.crit : C.border}`,
          padding: "3px 8px", borderRadius: 3,
        }}>
          {highlight ? "Δ DETECTED" : "BASELINE"}
        </span>
      </div>

      <div style={{height: 220, position: "relative", background: C.bg, border: `1px solid ${C.borderSoft}`, borderRadius: 6}}>
        <svg viewBox="540 380 840 360" preserveAspectRatio="xMidYMid meet" style={{position: "absolute", inset: 0, width: "100%", height: "100%"}}>
          <BridgeGround opacity={0.5}/>
          <BridgeSolid opacity={0.9}/>
          <BridgeWireframe opacity={0.3}/>
          {bridgeDefects.map((d, i) => {
            const [sx, sy] = P(d.pos);
            const pulse = 1 + Math.sin(progress * 12 + i) * 0.18;
            return (
              <g key={i}>
                <circle cx={sx} cy={sy} r={d.r * 2.8 * pulse} fill={d.c} opacity="0.12"/>
                <circle cx={sx} cy={sy} r={d.r * 1.5} fill={d.c} opacity="0.32"/>
                <circle cx={sx} cy={sy} r={d.r} fill={d.c}/>
                {d.label && (
                  <g transform={`translate(${sx + 14}, ${sy - 16})`}>
                    <rect x="0" y="-10" width="74" height="14" fill={C.paper} stroke={d.c} strokeWidth="0.6" rx="2"/>
                    <text x="6" y="0" fontFamily="JetBrains Mono, monospace" fontSize="9" fill={d.c}>{d.label}</text>
                  </g>
                )}
              </g>
            );
          })}
        </svg>
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10}}>
        <div style={{padding: "12px 14px", border: `1px solid ${C.borderSoft}`, borderRadius: 4}}>
          <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: C.muted, letterSpacing: "0.06em", textTransform: "uppercase"}}>Total defects</div>
          <div style={{fontSize: 26, fontWeight: 700, color: C.ink, marginTop: 4, letterSpacing: "-0.025em", fontVariantNumeric: "tabular-nums"}}>{defects}</div>
        </div>
        <div style={{padding: "12px 14px", border: `1px solid ${C.borderSoft}`, borderRadius: 4}}>
          <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: C.muted, letterSpacing: "0.06em", textTransform: "uppercase"}}>Asset health</div>
          <div style={{fontSize: 26, fontWeight: 700, color: highlight ? C.high : C.ok, marginTop: 4, letterSpacing: "-0.025em", fontVariantNumeric: "tabular-nums"}}>{health}</div>
        </div>
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8, paddingTop: 10, borderTop: `1px solid ${C.borderSoft}`}}>
        {[
          { l: "S1 · critical", v: severity.s1, c: C.crit },
          { l: "S2 · medium",   v: severity.s2, c: C.high },
          { l: "S3 · low",      v: severity.s3, c: C.low },
        ].map(s => (
          <div key={s.l} style={{display: "flex", flexDirection: "column", gap: 2}}>
            <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: s.c, letterSpacing: "0.04em"}}>{s.l}</span>
            <span style={{fontSize: 18, fontWeight: 700, color: C.ink, fontVariantNumeric: "tabular-nums"}}>{s.v}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function DeltaArrow({ progress }) {
  const op = Math.max(0, Math.min(1, (progress - 0.3) * 4));
  return (
    <div style={{display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", opacity: op}}>
      <svg width="80" height="80" viewBox="0 0 80 80">
        <circle cx="40" cy="40" r="28" fill={C.paper} stroke={C.ink} strokeWidth="1.5"/>
        <line x1="22" y1="40" x2="56" y2="40" stroke={C.ink} strokeWidth="2"/>
        <polygon points="50,32 62,40 50,48" fill={C.ink}/>
      </svg>
      <span style={{marginTop: 12, fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.ink, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 600}}>+ 24 months</span>
    </div>
  );
}

// ============================================================
// SCENE 08 — COLLABORATE: review activity feed
// ============================================================
function SceneCollab() {
  const { progress } = useSprite();
  const items = [
    { i: "JC", n: "J. Carter",    role: "Reviewer",    action: "approved",   target: "CR-04 · severity HIGH",            c: C.ok,   appear: 0.05 },
    { i: "MA", n: "M. Ahmadi",    role: "Engineer",    action: "edited",     target: "SP-12 · severity MED → HIGH",      c: C.high, appear: 0.18 },
    { i: "RN", n: "R. Nair",      role: "Structural eng", action: "commented",  target: "SP-07 · re-inspect requested",     c: C.scan, appear: 0.32, comment: "Spall depth looks borderline — recommend a follow-up measurement before sign-off." },
    { i: "JC", n: "J. Carter",    role: "Reviewer",    action: "assigned",   target: "CR-02 to maintenance team",        c: C.scanLite, appear: 0.46 },
    { i: "SP", n: "S. Park",      role: "Asset owner", action: "approved",   target: "Evidence pack · A14 Bridge-07 v3", c: C.ok,   appear: 0.6 },
  ];
  return (
    <div style={{position: "absolute", inset: 0}}>
      <AssetTitle text="Engineer review · A14 Bridge-07 / Span-02 · auditable workflow"/>
      <div style={{
        position: "absolute", left: 200, top: 380, right: 200, bottom: 200,
        background: C.paper,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        padding: "32px 40px",
        display: "flex", flexDirection: "column",
        boxShadow: "0 1px 2px rgba(0,0,0,0.04), 0 4px 12px -4px rgba(0,0,0,0.08)",
      }}>
        <div style={{display: "flex", justifyContent: "space-between", alignItems: "baseline", paddingBottom: 18, marginBottom: 24, borderBottom: `1px solid ${C.borderSoft}`}}>
          <div>
            <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.muted, letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 6}}>Engineer review · audit feed</div>
            <div style={{fontSize: 22, fontWeight: 700, color: C.ink, letterSpacing: "-0.02em"}}>Activity stream</div>
          </div>
          <div style={{display: "flex", alignItems: "center"}}>
            {["JC","MA","RN","SP","EM"].map((a, i) => (
              <span key={a} style={{
                marginLeft: i === 0 ? 0 : -10,
                width: 36, height: 36,
                display: "flex", alignItems: "center", justifyContent: "center",
                background: C.ink,
                color: C.paper,
                fontFamily: "JetBrains Mono, monospace", fontSize: 12, fontWeight: 600,
                border: `2px solid ${C.paper}`,
                borderRadius: "50%",
                zIndex: 5 - i,
              }}>{a}</span>
            ))}
          </div>
        </div>

        <div style={{display: "flex", flexDirection: "column", gap: 16, flex: 1}}>
          {items.map((it, i) => {
            if (progress < it.appear) return null;
            const local = Math.min(1, (progress - it.appear) / 0.1);
            return (
              <div key={i} style={{
                display: "grid", gridTemplateColumns: "44px 1fr auto",
                gap: 16, alignItems: "start",
                opacity: local, transform: `translateY(${(1 - local) * 10}px)`,
              }}>
                <span style={{
                  width: 40, height: 40,
                  display: "flex", alignItems: "center", justifyContent: "center",
                  background: C.bg,
                  border: `1px solid ${C.border}`,
                  borderRadius: "50%",
                  fontFamily: "JetBrains Mono, monospace", fontSize: 13, color: C.ink, fontWeight: 600,
                }}>{it.i}</span>
                <div style={{display: "flex", flexDirection: "column", gap: 4}}>
                  <div style={{fontSize: 15, color: C.ink}}>
                    <span style={{fontWeight: 600}}>{it.n}</span>
                    <span style={{color: C.muted, marginLeft: 8, fontSize: 13}}>· {it.role}</span>
                    <span style={{color: it.c, marginLeft: 10, fontWeight: 600}}>{it.action}</span>
                  </div>
                  <div style={{fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: C.muted}}>{it.target}</div>
                  {it.comment && (
                    <div style={{
                      marginTop: 6, padding: "10px 14px",
                      borderLeft: `2px solid ${it.c}`,
                      background: C.bg, borderRadius: 0,
                      fontSize: 13, color: C.ink2, fontStyle: "italic",
                    }}>"{it.comment}"</div>
                  )}
                </div>
                <span style={{fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: C.muted}}>{Math.floor((items.length - i) * 12)}m</span>
              </div>
            );
          })}
        </div>

        <div style={{marginTop: 20, paddingTop: 16, borderTop: `1px solid ${C.borderSoft}`, display: "flex", justifyContent: "space-between", fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: C.muted, letterSpacing: "0.04em"}}>
          <span>audit log · 412 events recorded</span>
          <span style={{color: C.ink, fontWeight: 600}}>↓ export decisions</span>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// SCENE 09 — OUTRO
// ============================================================
function SceneOutro() {
  const { progress } = useSprite();
  return (
    <div style={{position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", fontFamily: "Inter, sans-serif"}}>
      <div style={{
        display: "flex", alignItems: "center",
        opacity: Math.min(1, progress * 3),
        transform: `translateY(${(1 - Math.min(1, progress * 2)) * 16}px)`,
      }}>
        <img src="assets/inframind-logo.png" alt="Inframind" style={{height: 96, width: "auto"}}/>
      </div>
      <div style={{
        marginTop: 36, fontSize: 24, color: C.muted, maxWidth: 1000, textAlign: "center",
        letterSpacing: "-0.005em",
        opacity: Math.max(0, Math.min(1, (progress - 0.2) * 3)),
        textWrap: "balance",
      }}>
        From raw infrastructure data to risk-ranked engineering decisions.
      </div>
      <div style={{
        marginTop: 48, padding: "16px 28px",
        background: C.ink,
        color: C.paper,
        fontFamily: "Inter, sans-serif", fontSize: 14, fontWeight: 600,
        letterSpacing: "0.04em",
        borderRadius: 6,
        opacity: Math.max(0, Math.min(1, (progress - 0.4) * 3)),
      }}>
        inframindlabs.com  ·  Book a demo
      </div>
    </div>
  );
}

// ============================================================
// URL state + Video root
// ============================================================

(function applyUrlTime() {
  try {
    const h = (location.hash || "").replace(/^#/, "");
    const params = new URLSearchParams(h);
    const t = params.get("t");
    if (t != null) localStorage.setItem("inframind-anim:t", t);
  } catch (e) {}
})();

function Video() {
  const paused = typeof location !== "undefined" && /paused/.test(location.hash);
  return (
    <Stage width={1920} height={1080} duration={TOTAL} background={C.bg} persistKey="inframind-anim" autoplay={!paused}>
      <FrameChrome/>

      <Sprite start={SCENES[0].start} end={SCENES[0].end}><SceneCapture/></Sprite>
      <Sprite start={SCENES[1].start} end={SCENES[1].end}><SceneUpload/></Sprite>
      <Sprite start={SCENES[2].start} end={SCENES[2].end}><SceneReconstruct/></Sprite>
      <Sprite start={SCENES[3].start} end={SCENES[3].end}><SceneDetect/></Sprite>
      <Sprite start={SCENES[4].start} end={SCENES[4].end}><SceneQuantify/></Sprite>
      <Sprite start={SCENES[5].start} end={SCENES[5].end}><SceneReport/></Sprite>
      <Sprite start={SCENES[6].start} end={SCENES[6].end}><SceneCompare/></Sprite>
      <Sprite start={SCENES[7].start} end={SCENES[7].end}><SceneCollab/></Sprite>
      <Sprite start={SCENES[8].start} end={SCENES[8].end}><SceneOutro/></Sprite>
    </Stage>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<Video />);
