// Scene 1 → 2: a cluttered desk that organizes itself.
// Items are physical-feeling paper objects (documents, sticky notes, receipts,
// invoices, ledger pages, a calculator, a coffee-cup ring) scattered across
// the surface at varied angles — like an overwhelmed nonprofit ED's desk
// before a board meeting.
//
// Phases:
//   chaos:  0.0 – 2.8s   drift / breathe in place at varied positions+rotations
//   sweep:  2.6 – 4.6s   gather to a tidy stack on the LEFT side of the canvas
//   held:   4.6 – 7.0s   neat squared stack
//   exit:   7.0 – 7.9s   stack slides/fades off as dashboard reveals
//
// Each item type renders its own small SVG/HTML so the chaos reads as physical
// paper and office stuff, not floating text.

// ── Color tokens (kept local so this file is self-contained) ────────────────
const PAPER       = '#fbf7ec';
const PAPER_WARM  = '#f5ecd7';
const PAPER_COOL  = '#eef0f3';
const STICKY_Y    = '#f6dd7a';
const STICKY_P    = '#f3b8b0';
const STICKY_B    = '#a8c7e0';
const INK         = '#0e1f3a';
const INK_SOFT    = '#3b4a66';
const RULE        = '#c8c0ad';
const RULE_SOFT   = '#dcd3bd';
const ACCENT      = '#9b6a3f';
const RED_INK     = '#8a3a2c';

// ── Generic paper card wrapper used by most items ───────────────────────────
function PaperCard({ width, height, tint = PAPER, children, style = {} }) {
  return (
    <div style={{
      width, height,
      background: tint,
      // subtle paper edge: drop shadow + tiny inner border
      boxShadow: '0 6px 14px rgba(20,18,12,0.10), 0 1px 2px rgba(20,18,12,0.06)',
      position: 'relative',
      overflow: 'hidden',
      borderRadius: 1,
      ...style,
    }}>
      {children}
    </div>
  );
}

// ── Item renderers ──────────────────────────────────────────────────────────

// Bank statement: header + account # + ruled rows
function BankStatement() {
  return (
    <PaperCard width={300} height={380} tint={PAPER}>
      <div style={{ padding: '18px 20px 0' }}>
        <div style={{
          fontFamily: 'Source Serif 4, Georgia, serif',
          fontSize: 16, fontWeight: 500, color: INK,
          letterSpacing: '-0.01em',
        }}>First National · Statement</div>
        <div style={{
          fontFamily: 'JetBrains Mono, ui-monospace, monospace',
          fontSize: 9, color: INK_SOFT, marginTop: 2, letterSpacing: '0.04em',
        }}>ACCT ····4218 · MAR 2026</div>
        <div style={{ height: 1, background: RULE, margin: '10px 0' }}/>
        {Array.from({ length: 12 }).map((_, i) => (
          <div key={i} style={{
            display: 'flex', justifyContent: 'space-between',
            fontFamily: 'JetBrains Mono, ui-monospace, monospace',
            fontSize: 9, color: INK_SOFT,
            padding: '3px 0',
            borderBottom: `1px solid ${RULE_SOFT}`,
          }}>
            <span>03/{(i + 4).toString().padStart(2, '0')}</span>
            <span style={{ flex: 1, padding: '0 8px', color: INK }}>{['ACH Deposit', 'Payroll', 'Henson Fdn', 'Office', 'Utilities', 'Donor #2148', 'Stripe', 'Insurance'][i % 8]}</span>
            <span style={{ color: i % 3 === 0 ? RED_INK : INK }}>{i % 3 === 0 ? '−' : '+'}{(Math.random()*9000+200).toFixed(2)}</span>
          </div>
        ))}
      </div>
    </PaperCard>
  );
}

// Form 990 page (IRS-style header)
function Form990() {
  return (
    <PaperCard width={280} height={360} tint={PAPER}>
      <div style={{ padding: '16px 18px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div style={{
            fontFamily: 'Source Serif 4, Georgia, serif',
            fontSize: 28, fontWeight: 500, color: INK, lineHeight: 1,
          }}>Form 990</div>
          <div style={{
            fontFamily: 'JetBrains Mono, ui-monospace, monospace',
            fontSize: 9, color: INK_SOFT,
          }}>OMB No. 1545-0047</div>
        </div>
        <div style={{
          fontFamily: 'Inter, system-ui, sans-serif',
          fontSize: 10, color: INK_SOFT, marginTop: 4,
          fontStyle: 'italic',
        }}>Return of Organization Exempt From Income Tax</div>
        <div style={{ height: 2, background: INK, margin: '10px 0' }}/>
        {/* fake numbered fields */}
        {[
          ['1', 'Briefly describe the organization\'s mission'],
          ['2', 'Check if the organization discontinued operations'],
          ['3', 'Number of voting members of the governing body'],
          ['4', 'Number of independent voting members'],
          ['5', 'Total number of individuals employed'],
          ['6', 'Total number of volunteers'],
        ].map(([n, l]) => (
          <div key={n} style={{
            display: 'flex', gap: 8, padding: '5px 0',
            fontFamily: 'Inter, system-ui, sans-serif', fontSize: 9, color: INK,
            borderBottom: `1px solid ${RULE_SOFT}`,
          }}>
            <div style={{ width: 14, fontWeight: 600 }}>{n}</div>
            <div style={{ flex: 1 }}>{l}</div>
            <div style={{ width: 50, height: 12, borderBottom: `1px solid ${INK_SOFT}` }}/>
          </div>
        ))}
        <div style={{ marginTop: 14, height: 80, background: PAPER_WARM, opacity: 0.6, borderTop: `1px solid ${RULE_SOFT}` }}/>
      </div>
    </PaperCard>
  );
}

// Invoice
function Invoice() {
  return (
    <PaperCard width={260} height={340} tint={PAPER}>
      <div style={{ padding: '16px 18px' }}>
        <div style={{
          fontFamily: 'Source Serif 4, Georgia, serif',
          fontSize: 26, fontWeight: 500, color: INK, letterSpacing: '0.02em',
        }}>INVOICE</div>
        <div style={{
          fontFamily: 'JetBrains Mono, ui-monospace, monospace',
          fontSize: 10, color: INK_SOFT, marginTop: 2,
        }}>#2026-0418</div>
        <div style={{ height: 1, background: RULE, margin: '12px 0' }}/>
        <div style={{
          fontFamily: 'Inter, system-ui, sans-serif', fontSize: 10, color: INK_SOFT,
          textTransform: 'uppercase', letterSpacing: '0.1em',
        }}>Bill to</div>
        <div style={{
          fontFamily: 'Inter, system-ui, sans-serif', fontSize: 12, color: INK,
          fontWeight: 500, marginTop: 2,
        }}>Bridgeway Programs</div>
        <div style={{ marginTop: 14 }}>
          {[
            ['Curriculum dev.', '$ 4,200.00'],
            ['Site coordinator', '$ 6,800.00'],
            ['Materials', '$ 1,140.00'],
          ].map(([l, v]) => (
            <div key={l} style={{
              display: 'flex', justifyContent: 'space-between',
              padding: '6px 0', borderBottom: `1px solid ${RULE_SOFT}`,
              fontFamily: 'Inter, system-ui, sans-serif', fontSize: 11, color: INK,
            }}>
              <span>{l}</span>
              <span style={{ fontFamily: 'JetBrains Mono, ui-monospace, monospace' }}>{v}</span>
            </div>
          ))}
        </div>
        <div style={{
          marginTop: 14, display: 'flex', justifyContent: 'space-between',
          fontFamily: 'Source Serif 4, Georgia, serif', fontSize: 18, fontWeight: 500, color: INK,
        }}>
          <span>Total</span>
          <span style={{ fontVariantNumeric: 'tabular-nums' }}>$ 12,140.00</span>
        </div>
        <div style={{
          marginTop: 16,
          fontFamily: 'Inter, system-ui, sans-serif',
          fontSize: 9, color: RED_INK, fontWeight: 600,
          letterSpacing: '0.1em', textTransform: 'uppercase',
        }}>Past due — 47 days</div>
      </div>
    </PaperCard>
  );
}

// Ledger page (green-bar accounting style)
function LedgerPage() {
  return (
    <PaperCard width={340} height={300} tint={PAPER}>
      <div style={{ padding: '14px 16px' }}>
        <div style={{
          fontFamily: 'Source Serif 4, Georgia, serif',
          fontSize: 14, fontWeight: 500, color: INK, marginBottom: 8,
        }}>General Ledger · Mar 2026</div>
        <div>
          {Array.from({ length: 14 }).map((_, i) => (
            <div key={i} style={{
              display: 'flex', alignItems: 'center',
              height: 16,
              background: i % 2 === 0 ? '#dfe9d8' : 'transparent',
              padding: '0 6px',
              fontFamily: 'JetBrains Mono, ui-monospace, monospace',
              fontSize: 9, color: INK,
              gap: 8,
            }}>
              <span style={{ width: 30, color: INK_SOFT }}>{(4000 + i * 10).toString()}</span>
              <span style={{ flex: 1 }}>{['Program svc rev', 'Salaries', 'Rent', 'Supplies', 'Insurance', 'Travel', 'Conf', 'Tech'][i % 8]}</span>
              <span style={{ width: 60, textAlign: 'right' }}>{(Math.random()*40000+1000).toFixed(2)}</span>
              <span style={{ width: 60, textAlign: 'right' }}>{(Math.random()*40000+1000).toFixed(2)}</span>
            </div>
          ))}
        </div>
      </div>
    </PaperCard>
  );
}

// Sticky note
function StickyNote({ color = STICKY_Y, lines = ['Call board re:', 'Q4 forecast'], rotate = 0 }) {
  return (
    <div style={{
      width: 180, height: 180,
      background: color,
      boxShadow: '0 8px 16px rgba(20,18,12,0.18), 0 1px 2px rgba(20,18,12,0.06)',
      padding: '20px 18px',
      transform: `rotate(${rotate}deg)`,
      // tiny darker tab at top to suggest adhesive
      position: 'relative',
    }}>
      <div style={{
        position: 'absolute', top: 0, left: '20%', right: '20%', height: 4,
        background: 'rgba(0,0,0,0.06)',
      }}/>
      {lines.map((l, i) => (
        <div key={i} style={{
          fontFamily: '"Caveat", "Bradley Hand", cursive',
          fontSize: i === 0 ? 22 : 20,
          color: INK, lineHeight: 1.2, marginBottom: 4,
          fontWeight: i === 0 ? 600 : 400,
        }}>{l}</div>
      ))}
    </div>
  );
}

// Receipt (long thin thermal-paper look)
function Receipt() {
  return (
    <div style={{
      width: 130, height: 280,
      background: PAPER,
      boxShadow: '0 6px 12px rgba(20,18,12,0.10)',
      padding: '12px 12px',
      fontFamily: 'JetBrains Mono, ui-monospace, monospace',
      fontSize: 9, color: INK,
      // ragged bottom
      clipPath: 'polygon(0 0, 100% 0, 100% calc(100% - 8px), 92% 100%, 84% calc(100% - 6px), 76% 100%, 68% calc(100% - 6px), 60% 100%, 52% calc(100% - 6px), 44% 100%, 36% calc(100% - 6px), 28% 100%, 20% calc(100% - 6px), 12% 100%, 4% calc(100% - 6px), 0 100%)',
    }}>
      <div style={{ textAlign: 'center', fontWeight: 600, fontSize: 10 }}>STAPLES</div>
      <div style={{ textAlign: 'center', fontSize: 8, color: INK_SOFT, marginBottom: 8 }}>03/14/26  14:22</div>
      <div style={{ borderTop: `1px dashed ${INK_SOFT}`, borderBottom: `1px dashed ${INK_SOFT}`, padding: '6px 0' }}>
        {['Toner ', 'Paper  ', 'Pens   ', 'Folders', 'Tabs   '].map((l, i) => (
          <div key={i} style={{ display: 'flex', justifyContent: 'space-between' }}>
            <span>{l}</span>
            <span>{(Math.random()*40+5).toFixed(2)}</span>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6, fontWeight: 600 }}>
        <span>TOTAL</span>
        <span>147.42</span>
      </div>
    </div>
  );
}

// File folder (manila tab)
function FileFolder({ label = 'GRANTS · FY26' }) {
  return (
    <div style={{ width: 360, height: 240, position: 'relative' }}>
      {/* tab */}
      <div style={{
        position: 'absolute', left: 24, top: 0,
        width: 130, height: 22,
        background: '#d9b777',
        borderRadius: '4px 4px 0 0',
        boxShadow: 'inset 0 -1px 0 rgba(0,0,0,0.08)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 10, fontWeight: 600, color: INK,
        letterSpacing: '0.1em',
      }}>{label}</div>
      {/* body */}
      <div style={{
        position: 'absolute', left: 0, top: 18, right: 0, bottom: 0,
        background: '#e3c388',
        boxShadow: '0 8px 16px rgba(20,18,12,0.14), inset 0 1px 0 rgba(255,255,255,0.4)',
        borderRadius: '2px 6px 4px 4px',
      }}/>
      {/* peeking paper edge */}
      <div style={{
        position: 'absolute', left: 14, top: 30, right: 14, height: 8,
        background: PAPER, boxShadow: '0 1px 2px rgba(0,0,0,0.08)',
      }}/>
      <div style={{
        position: 'absolute', left: 18, top: 38, right: 18, height: 6,
        background: PAPER_WARM,
      }}/>
    </div>
  );
}

// Calculator
function Calculator() {
  const buttons = [
    'C','±','%','÷',
    '7','8','9','×',
    '4','5','6','−',
    '1','2','3','+',
    '0','·','=',
  ];
  return (
    <div style={{
      width: 180, height: 260,
      background: '#2a2a28',
      borderRadius: 10,
      boxShadow: '0 10px 22px rgba(20,18,12,0.30), inset 0 1px 0 rgba(255,255,255,0.06)',
      padding: 12,
    }}>
      {/* screen */}
      <div style={{
        background: '#9aa897',
        height: 44, borderRadius: 4,
        padding: '8px 10px', textAlign: 'right',
        fontFamily: 'JetBrains Mono, ui-monospace, monospace',
        fontSize: 22, color: '#1a201a', letterSpacing: '0.05em',
        boxShadow: 'inset 0 2px 4px rgba(0,0,0,0.25)',
      }}>1,084,392</div>
      <div style={{
        marginTop: 10,
        display: 'grid',
        gridTemplateColumns: 'repeat(4, 1fr)',
        gap: 6,
      }}>
        {buttons.slice(0, 16).map((b, i) => (
          <div key={i} style={{
            height: 26, background: '#454541',
            color: '#f1ece0',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'Inter, system-ui, sans-serif',
            fontSize: 12, fontWeight: 500,
            borderRadius: 3,
            boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.08)',
          }}>{b}</div>
        ))}
      </div>
    </div>
  );
}

// Coffee-cup ring stain
function CoffeeRing() {
  return (
    <svg width="160" height="160" viewBox="0 0 160 160">
      <defs>
        <radialGradient id="ring" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="rgba(120,80,40,0)"/>
          <stop offset="62%" stopColor="rgba(120,80,40,0)"/>
          <stop offset="74%" stopColor="rgba(120,80,40,0.32)"/>
          <stop offset="86%" stopColor="rgba(120,80,40,0.18)"/>
          <stop offset="100%" stopColor="rgba(120,80,40,0)"/>
        </radialGradient>
      </defs>
      <circle cx="80" cy="80" r="76" fill="url(#ring)"/>
    </svg>
  );
}

// Pen
function Pen() {
  return (
    <svg width="240" height="22" viewBox="0 0 240 22">
      <rect x="0" y="6" width="20" height="10" fill="#1a1a1a" rx="2"/>
      <rect x="20" y="4" width="180" height="14" fill="#0e1f3a"/>
      <rect x="20" y="4" width="180" height="3" fill="#1c2f4f"/>
      <polygon points="200,4 222,11 200,18" fill="#cfa463"/>
      <polygon points="222,11 234,11 222,9" fill="#1a1a1a"/>
      <rect x="60" y="9" width="40" height="4" fill="#9b6a3f" opacity="0.5"/>
    </svg>
  );
}

// Highlighted ledger row (urgent, in red ink)
function UrgentMemo() {
  return (
    <PaperCard width={240} height={140} tint={PAPER}>
      <div style={{ padding: '14px 16px' }}>
        <div style={{
          fontFamily: 'Inter, system-ui, sans-serif',
          fontSize: 9, color: RED_INK, fontWeight: 700,
          letterSpacing: '0.14em', textTransform: 'uppercase',
        }}>URGENT · BOARD MEMO</div>
        <div style={{
          fontFamily: 'Source Serif 4, Georgia, serif',
          fontSize: 16, color: INK, marginTop: 8, lineHeight: 1.25,
        }}>Q4 cash projection variance — please review before Friday.</div>
        <div style={{
          marginTop: 10,
          fontFamily: '"Caveat", cursive', fontSize: 18,
          color: RED_INK, transform: 'rotate(-2deg)',
        }}>— J.M.</div>
      </div>
    </PaperCard>
  );
}

// Spreadsheet printout (a wide grid of rows + columns)
function Spreadsheet() {
  return (
    <PaperCard width={420} height={280} tint={PAPER}>
      <div style={{ padding: '12px 14px' }}>
        <div style={{
          fontFamily: 'Inter, system-ui, sans-serif',
          fontSize: 10, color: INK, fontWeight: 600,
          letterSpacing: '0.08em', textTransform: 'uppercase',
        }}>FY26 Operating Budget — DRAFT v7</div>
        <div style={{ height: 1, background: INK, margin: '8px 0' }}/>
        <table style={{ width: '100%', borderCollapse: 'collapse', tableLayout: 'fixed' }}>
          <thead>
            <tr style={{
              fontFamily: 'Inter, system-ui, sans-serif', fontSize: 9, color: INK_SOFT,
              textAlign: 'right',
            }}>
              <th style={{ textAlign: 'left', padding: '3px 4px', borderBottom: `1px solid ${RULE}` }}>Account</th>
              {['Q1', 'Q2', 'Q3', 'Q4', 'YTD'].map(c => (
                <th key={c} style={{ padding: '3px 4px', borderBottom: `1px solid ${RULE}` }}>{c}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {['Programs', 'Fundraising', 'Admin', 'Salaries', 'Occupancy', 'Tech', 'Travel', 'Insurance', 'Misc'].map((r, i) => (
              <tr key={r} style={{
                fontFamily: 'JetBrains Mono, ui-monospace, monospace',
                fontSize: 9, color: INK,
              }}>
                <td style={{ padding: '3px 4px', borderBottom: `1px solid ${RULE_SOFT}` }}>{r}</td>
                {[0,1,2,3,4].map(c => (
                  <td key={c} style={{ textAlign: 'right', padding: '3px 4px', borderBottom: `1px solid ${RULE_SOFT}` }}>
                    {(Math.random()*80000+5000).toFixed(0)}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
        {/* hand-scribbled circle/arrow */}
        <svg style={{ position: 'absolute', left: 220, top: 130 }} width="120" height="60">
          <path d="M 10 30 Q 60 4 110 28 Q 100 50 50 50 Q 14 48 10 30 Z" fill="none" stroke={RED_INK} strokeWidth="1.5"/>
          <path d="M 95 28 L 115 22 L 110 38" fill="none" stroke={RED_INK} strokeWidth="1.5" strokeLinecap="round"/>
        </svg>
      </div>
    </PaperCard>
  );
}

// ── The desk items: each has a chaos pose, a stack pose, and a renderer ─────
//
// Stack target is a tidy column on the left, items neatly squared.
// We also build a small "out-of-frame" exit so it doesn't just disappear.

const ITEMS = [
  // top row
  { id: 'spreadsheet', cx:  90, cy:  80, cr: -7,  sx: 120, sy: 220, sr: 0,  z: 4,  render: Spreadsheet,  w: 420, h: 280 },
  { id: 'sticky-cash', cx: 560, cy:  60, cr:  6,  sx: 130, sy: 210, sr: 0,  z: 12, render: () => <StickyNote color={STICKY_Y} lines={['Cash run-out?', 'Sept??']} rotate={0} />, w: 180, h: 180 },
  { id: 'bank',        cx: 800, cy:  40, cr: -4,  sx: 150, sy: 220, sr: 0,  z: 5,  render: BankStatement, w: 300, h: 380 },
  { id: 'receipt-1',   cx: 1140, cy: 70, cr:  8,  sx: 160, sy: 240, sr: 0,  z: 9,  render: Receipt,       w: 130, h: 280 },
  { id: 'folder',      cx: 1260, cy: 30, cr: -3,  sx: 110, sy: 200, sr: 0,  z: 3,  render: () => <FileFolder label="GRANTS · FY26" />, w: 360, h: 240 },
  { id: 'sticky-board',cx: 1640, cy: 80, cr: -8,  sx: 130, sy: 200, sr: 0,  z: 11, render: () => <StickyNote color={STICKY_P} lines={['Board pkt', 'due Fri!!']} rotate={0} />, w: 180, h: 180 },

  // upper-mid row
  { id: 'invoice',     cx: 230, cy: 380, cr:  9,  sx: 130, sy: 215, sr: 0,  z: 7,  render: Invoice,        w: 260, h: 340 },
  { id: 'pen-1',       cx: 540, cy: 460, cr: 22,  sx: 200, sy: 590, sr: 0,  z: 14, render: Pen,            w: 240, h: 22 },
  { id: 'form990',     cx: 700, cy: 360, cr: -5,  sx: 140, sy: 215, sr: 0,  z: 6,  render: Form990,        w: 280, h: 360 },
  { id: 'calc',        cx: 1080, cy: 380, cr: 4,  sx: 250, sy: 600, sr: 0,  z: 13, render: Calculator,     w: 180, h: 260 },
  { id: 'coffee',      cx: 1330, cy: 400, cr: 0,  sx: -400, sy: 400, sr: 0, z: 1,  render: CoffeeRing,     w: 160, h: 160 },
  { id: 'ledger',      cx: 1480, cy: 360, cr: 7,  sx: 110, sy: 215, sr: 0,  z: 5,  render: LedgerPage,     w: 340, h: 300 },
  { id: 'sticky-call', cx: 1750, cy: 400, cr: 12, sx: 145, sy: 215, sr: 0,  z: 11, render: () => <StickyNote color={STICKY_B} lines={['Call audit', '3pm Tue']} rotate={0} />, w: 180, h: 180 },

  // lower row
  { id: 'urgent',      cx: 110,  cy: 770, cr: -10, sx: 200, sy: 230, sr: 0, z: 10, render: UrgentMemo,     w: 240, h: 140 },
  { id: 'receipt-2',   cx: 420,  cy: 720, cr: -14, sx: 170, sy: 240, sr: 0, z: 9,  render: Receipt,        w: 130, h: 280 },
  { id: 'spreadsheet2',cx: 580,  cy: 760, cr:  4,  sx: 130, sy: 220, sr: 0, z: 4,  render: Spreadsheet,    w: 420, h: 280 },
  { id: 'sticky-pay',  cx: 1080, cy: 740, cr: -7,  sx: 140, sy: 210, sr: 0, z: 11, render: () => <StickyNote color={STICKY_Y} lines={['Payroll', 'Apr 5']} rotate={0} />, w: 180, h: 180 },
  { id: 'pen-2',       cx: 1280, cy: 820, cr: -18, sx: 220, sy: 600, sr: 0, z: 14, render: Pen,            w: 240, h: 22 },
  { id: 'ledger-2',    cx: 1380, cy: 740, cr: -3,  sx: 120, sy: 215, sr: 0, z: 5,  render: LedgerPage,     w: 340, h: 300 },
  { id: 'folder-2',    cx: 1640, cy: 800, cr:  7,  sx: 100, sy: 200, sr: 0, z: 3,  render: () => <FileFolder label="AUDIT · FY25" />, w: 360, h: 240 },
];

// ── Per-item motion ─────────────────────────────────────────────────────────
//
// New choreography:
//   chaos:    0.0 – 2.4s    held pose with idle drift
//   gather:   2.4 – 3.6s    rush inward to a tight pile at center, settle
//   hold:     3.6 – 4.0s    pile is held briefly (a satisfying "click")
//   tuck:     4.0 – 4.8s    whole pile glides to the top-left corner,
//                           shrinking, then fades as the dashboard reveals
//
function DeskItem({ item, idx, time }) {
  const stagger = (idx % 7) * 0.04;
  const gatherStart = 2.4 + stagger;
  const gatherEnd   = 3.5 + stagger * 0.4;
  const HOLD_END    = 4.0;
  const TUCK_END    = 4.8;

  // Center pile target (where they converge, before tucking)
  const PILE_CX = 960;
  const PILE_CY = 540;

  // Corner target (top-left, like the original "stack" pose but smaller)
  const CORNER_X = 90;
  const CORNER_Y = 120;
  const CORNER_SCALE = 0.32;

  // Idle micro-motion during chaos
  const seed = (idx * 7.13) % 6.28;
  const idleX = Math.sin(time * 0.6 + seed) * 1.6;
  const idleY = Math.cos(time * 0.5 + seed * 1.2) * 1.2;
  const idleR = Math.sin(time * 0.4 + seed) * 0.4;

  let x, y, rot, opacity = 1, scale = 1;

  // Pile pose: center the item on the pile, with a tiny per-item offset so
  // the stack reads as a stack of papers, not a single sheet.
  const pileJitterX = ((idx * 31) % 17) - 8;
  const pileJitterY = ((idx * 19) % 13) - 6;
  const pileRot = ((idx * 11) % 9) - 4; // small residual rotation in the pile

  const pileX = PILE_CX - item.w / 2 + pileJitterX;
  const pileY = PILE_CY - item.h / 2 + pileJitterY;

  if (time < 0.5) {
    const f = Easing.easeOutCubic(clamp(time / 0.5, 0, 1));
    opacity = f;
    x = item.cx + idleX;
    y = item.cy + idleY;
    rot = item.cr + idleR;
  } else if (time <= gatherStart) {
    x = item.cx + idleX;
    y = item.cy + idleY;
    rot = item.cr + idleR;
  } else if (time <= gatherEnd) {
    // GATHER: rush inward to the center pile
    const local = (time - gatherStart) / (gatherEnd - gatherStart);
    const eased = Easing.easeInOutCubic(clamp(local, 0, 1));
    x = item.cx + (pileX - item.cx) * eased;
    y = item.cy + (pileY - item.cy) * eased;
    rot = item.cr + (pileRot - item.cr) * eased;
    scale = 1 - eased * 0.30; // shrink a bit as they pile up (perspective)
  } else if (time <= HOLD_END) {
    // HOLD: tiny settle wobble at arrival, then steady
    const sinceArrive = time - gatherEnd;
    const settle = sinceArrive < 0.18
      ? Math.sin(sinceArrive * 30) * (1 - sinceArrive / 0.18) * 1.6
      : 0;
    x = pileX;
    y = pileY + settle;
    rot = pileRot;
    scale = 0.70;
  } else if (time <= TUCK_END) {
    // TUCK: whole pile glides to the top-left corner, shrinking and fading
    const local = (time - HOLD_END) / (TUCK_END - HOLD_END);
    const eased = Easing.easeInOutCubic(clamp(local, 0, 1));
    // Target: corner with shared scale
    const tx = CORNER_X - (item.w * CORNER_SCALE) / 2 + pileJitterX * 0.3;
    const ty = CORNER_Y - (item.h * CORNER_SCALE) / 2 + pileJitterY * 0.3;
    x = pileX + (tx - pileX) * eased;
    y = pileY + (ty - pileY) * eased;
    rot = pileRot * (1 - eased);
    scale = 0.70 + (CORNER_SCALE - 0.70) * eased;
    // Fade in the second half of the tuck
    opacity = local < 0.5 ? 1 : 1 - Easing.easeInQuad((local - 0.5) / 0.5);
  } else {
    return null;
  }

  const Comp = item.render;

  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      width: item.w, height: item.h,
      transform: `rotate(${rot}deg) scale(${scale})`,
      transformOrigin: 'center',
      opacity,
      zIndex: item.z,
      willChange: 'transform, opacity',
    }}>
      <Comp />
    </div>
  );
}

// ── Desk surface (warm wood vibe, but understated) ──────────────────────────
function DeskSurface() {
  const time = useTime();
  // Desk surface fades as the pile leaves and dashboard reveals
  const fadeStart = 3.8;
  const fadeEnd = 4.8;
  let op = 1;
  if (time >= fadeStart) {
    op = 1 - Easing.easeInCubic(clamp((time - fadeStart) / (fadeEnd - fadeStart), 0, 1));
  }
  if (op <= 0) return null;
  return (
    <div style={{
      position: 'absolute', inset: 0,
      // very subtle wood-grain feel — soft warm gradient
      background:
        'radial-gradient(ellipse at 30% 20%, #efe4cc 0%, #e6d8b8 45%, #d9c8a0 100%)',
      opacity: op,
    }}>
      {/* faint grain lines */}
      <svg width="100%" height="100%" preserveAspectRatio="none" style={{ opacity: 0.08 }}>
        <defs>
          <pattern id="grain" x="0" y="0" width="240" height="2" patternUnits="userSpaceOnUse">
            <line x1="0" y1="0" x2="240" y2="0" stroke="#7a5a30" strokeWidth="0.5"/>
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill="url(#grain)"/>
      </svg>
    </div>
  );
}

// ── Vignette + light "sweep" arc that passes across at the moment of pull ───
function SweepLight() {
  const time = useTime();
  // A warm light streak that pulses through the converge moment
  const start = 2.4, end = 4.0;
  if (time < start || time > end) return null;
  const t = (time - start) / (end - start);
  const x = -300 + t * 2400;
  const op = Math.sin(t * Math.PI) * 0.55;
  return (
    <div style={{
      position: 'absolute',
      left: x, top: -100, width: 480, height: 1300,
      background: 'linear-gradient(90deg, rgba(255,250,235,0) 0%, rgba(255,250,235,0.6) 50%, rgba(255,250,235,0) 100%)',
      filter: 'blur(40px)',
      opacity: op,
      transform: 'rotate(8deg)',
      pointerEvents: 'none',
      mixBlendMode: 'screen',
    }}/>
  );
}

function FragmentsScene() {
  const time = useTime();
  return (
    <>
      <DeskSurface />
      <SweepLight />
      {ITEMS.map((it, i) => (
        <DeskItem key={it.id} item={it} idx={i} time={time} />
      ))}
    </>
  );
}

Object.assign(window, { FragmentsScene });
