// Act II — THE GAP — scroll-scrubbed
// 7 beats: (0) kicker + thesis banner, (1) 87% hero, (2) sub-stat strip (150+/3/0/320),
// (3-4) the four frictions staggered, (5) the inventory strip reveal,
// (6) hold for transition. The thesis banner ("Fashion museum assets are
// NOT digitized and not accessible") lands BEFORE the 87% stat so the
// audience hears the claim before the evidence.

const { useState, useEffect, useRef, useMemo, useLayoutEffect } = window;

function PainCard({ num, title, body, r }) {
  const e = 1 - Math.pow(1 - r, 3);
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: '44px 1fr', gap: 18,
      padding: '22px 0', borderBottom: '1px solid rgba(143,166,143,0.15)',
      opacity: e, transform: `translateX(${(1 - e) * 30}px)`,
    }}>
      <div><span className="font-display" style={{ fontSize: 24, color: 'var(--sage)', opacity: 0.8 }}>{num}</span></div>
      <div>
        <div className="font-display" style={{ fontSize: 22, color: 'var(--parchment)', letterSpacing: '-0.01em', marginBottom: 6 }}>{title}</div>
        <div className="font-editorial" style={{ fontSize: 15, lineHeight: 1.65, color: 'rgba(240,238,233,0.72)', maxWidth: 520 }}>{body}</div>
      </div>
    </div>
  );
}

function InventoryStrip({ r }) {
  const cells = Array.from({ length: 48 }, (_, i) => ({
    reachable: i % 12 === 3,
    opacity: 0.15 + (Math.sin(i * 1.7) + 1) * 0.18,
  }));
  return (
    <div style={{ marginTop: 48, display: 'flex', gap: 8, opacity: r }}>
      {cells.map((c, i) => (
        <div key={i} style={{
          flex: 1, height: 54,
          background: c.reachable ? 'rgba(201,168,76,0.8)' : `rgba(240,238,233,${c.opacity * 0.4})`,
          boxShadow: c.reachable ? '0 0 12px rgba(201,168,76,0.5)' : 'none',
        }} />
      ))}
    </div>
  );
}

function ActGapInner({ act, index, total }) {
  // Reduced from 6 beats to 5 (2026-04-29 click economy pass) — sub-stat
  // strip now lands with the 87% hero on beat 1 instead of having its own
  // beat. Pain cards stagger 2-3, inventory strip on beat 4.
  const b0 = useBeatProgress(0); // kicker rule + thesis banner
  const b1 = useBeatProgress(1); // 87% hero + sub-stat strip together
  const b4 = useBeatProgress(4); // inventory strip
  const e0 = 1 - Math.pow(1 - b0, 3);
  const e1 = 1 - Math.pow(1 - b1, 3);
  const e2 = e1; // sub-stat strip uses same reveal as 87%
  // Four pain cards staggered across beats 2-3
  const pains = useStaggeredBeats(4, { startBeat: 2, span: 2, ease: 0.65 });

  return (
    <ActFrame act={act} index={index} total={total} bg="var(--petrol-deep)">
      <ActSeam roman={act.roman} />
      <div style={{ paddingTop: 24 }}>
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 14, marginBottom: 18,
          opacity: e0, transform: `translateY(${(1 - e0) * 8}px)`,
        }}>
          <span className="label-text" style={{ color: 'var(--sage)' }}>Observation · 2024</span>
          <div style={{ flex: 1, height: 1, background: 'rgba(143,166,143,0.22)' }} />
          <span className="label-text" style={{ color: 'var(--taupe)' }}>FIT Internal Survey</span>
        </div>

        {/* Thesis banner — sits tight to the 87% stat (12px below) so it
            reads as "claim → evidence", not two separate slides. The "not"
            is set in gold (the deck's existing accent) rather than rust,
            which would otherwise be the only place rust appears at this
            size. */}
        <div style={{
          marginBottom: 12,
          opacity: e0, transform: `translateY(${(1 - e0) * 12}px)`,
        }}>
          <p className="font-display" style={{
            fontSize: 'clamp(26px, 2.8vw, 40px)',
            lineHeight: 1.1, letterSpacing: '-0.015em',
            color: 'var(--parchment)', margin: 0,
            textWrap: 'pretty', maxWidth: 1200,
          }}>
            Fashion museum assets are <span style={{ color: 'var(--gold)', fontStyle: 'italic' }}>not</span> digitized.
            And what is digitized is <span style={{ color: 'var(--gold)', fontStyle: 'italic' }}>not</span> accessible.
          </p>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1.1fr 1fr', gap: 80, alignItems: 'center' }}>
          <div>
            <div style={{ opacity: e1, transform: `translateY(${(1 - e1) * 30}px)` }}>
              <div className="font-display" style={{
                fontSize: 'clamp(160px, 20vw, 320px)', lineHeight: 0.88,
                color: 'var(--parchment)', letterSpacing: '-0.04em',
              }}>
                87<span style={{ color: 'var(--gold)', fontStyle: 'italic' }}>%</span>
              </div>
              <div className="font-editorial" style={{
                marginTop: 20, fontSize: 22, lineHeight: 1.55,
                color: 'rgba(240,238,233,0.88)', fontStyle: 'italic',
                maxWidth: 560, textWrap: 'pretty',
              }}>
                of U.S. fashion educators report lacking high-resolution digital archive tools — creating a curriculum gap particularly acute for students outside major fashion capitals.
              </div>
              <div className="label-text" style={{ color: 'var(--taupe)', marginTop: 12, letterSpacing: '0.28em' }}>
                FIT educator panel · n = 42 · 2024
              </div>
            </div>

            <div style={{ marginTop: 28, display: 'flex', gap: 32, opacity: e2, transform: `translateY(${(1 - e2) * 14}px)` }}>
              <div>
                <div className="font-display" style={{ fontSize: 44, color: 'var(--sage)', lineHeight: 1 }}>150<span style={{ color: 'var(--parchment-dim)', fontStyle: 'italic' }}>+</span></div>
                <div className="label-text" style={{ color: 'var(--taupe)', marginTop: 8 }}>digitized museums<br/>largely unreachable</div>
              </div>
              <div style={{ width: 1, background: 'rgba(143,166,143,0.2)' }} />
              <div>
                <div className="font-display" style={{ fontSize: 44, color: 'var(--sage)', lineHeight: 1 }}>3</div>
                <div className="label-text" style={{ color: 'var(--taupe)', marginTop: 8 }}>cities with in-person access<br/>NY · Paris · London</div>
              </div>
              <div style={{ width: 1, background: 'rgba(143,166,143,0.2)' }} />
              <div>
                <div className="font-display" style={{ fontSize: 44, color: 'var(--sage)', lineHeight: 1 }}>0</div>
                <div className="label-text" style={{ color: 'var(--taupe)', marginTop: 8 }}>scalable distribution<br/>channels for museums</div>
              </div>
            </div>
          </div>

          <div>
            <div className="label-text" style={{ color: 'var(--sage)', marginBottom: 8, opacity: Math.min(1, pains[0] * 1.5) }}>Course structure · the gap</div>
            <div className="font-editorial" style={{ fontSize: 14, color: 'var(--taupe)', marginBottom: 12, opacity: Math.min(1, pains[0] * 1.5), fontStyle: 'italic' }}>Where fashion schools&rsquo; syllabi already point — and where the assets aren&rsquo;t.</div>
            <PainCard num="01" title="No central platform"  body="Fashion schools rely on physical museum visits, scanned PDFs, and fragmented image libraries. There is no cross-collection index, no standard metadata, and no federated search." r={pains[0]} />
            <PainCard num="02" title="Curriculum gap"        body="Course structures at FIT, Parsons, SCAD, and TJU reference objects the instructor often cannot actually put in front of students — lecturers are teaching around the absence of the source." r={pains[1]} />
            <PainCard num="03" title="Access inequity"       body="Students outside New York, Paris, or London have almost no path to museum-grade primary sources. Geography still determines who gets to study what." r={pains[2]} />
            <PainCard num="04" title="Licensing friction"    body="Museums have the assets but no scalable distribution channel for educational licensing. Every deal is bespoke, every contract renegotiated, every classroom walled off." r={pains[3]} />

            {/* Directory deep-link removed 2026-04-29 — was clipping below
                the viewport on projector. Appendix is reachable directly
                if a judge wants to see the 42-school roster. */}
          </div>
        </div>

        <div style={{ marginTop: 12 }}>
          <InventoryStrip r={b4} />
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 14, opacity: b4 }}>
            <span className="label-text" style={{ color: 'var(--taupe)' }}>A 48-institution sample of 150+ digitized museums</span>
            <span className="label-text" style={{ color: 'var(--gold)' }}>◆ a handful reachable at scale · the rest dark</span>
          </div>
        </div>
      </div>
    </ActFrame>
  );
}

function ActGap({ index, total, act }) {
  return (
    <ScrollBeats beats={5} bg="var(--petrol-deep)">
      <ActGapInner act={act} index={index} total={total} />
    </ScrollBeats>
  );
}

window.ActGap = ActGap;
