/* avscreen.jsx — AdsViewer "Creative Research" product surface, rendered at
   1920×1080 for the export-flow screen recording. Pure presentational:
   everything is driven by the `s` (state) prop from the director. */

const AV = {
  bg: '#f7f6f3',
  surface: '#ffffff',
  surface2: '#f1efea',
  line: '#e6e3dd',
  lineStrong: '#d6d2ca',
  fg: '#1b1a17',
  muted: '#6c675e',
  subtle: '#9b958a',
  accent: '#2c7be5',
  accentSoft: '#e8f0fd',
  mono: "'Geist Mono', ui-monospace, SFMono-Regular, monospace",
  sans: "'IBM Plex Sans', system-ui, sans-serif",
};

// Tracked-competitor creatives (real S3 thumbnails — load in-browser).
const NOTION_IMGS = [
  'https://assets.adsviewer.io/assets/expiring_assets/cmhdti6o000imus0ipzyg6ii8/cmn6ay9ff37xr0kw55o7x0pwg/94d65604154c9d3112862ffda6f8980ebb3f384417ba057b9fc2004dd9fe6dd2.jpg',
  'https://assets.adsviewer.io/assets/expiring_assets/cmhdti6o000imus0ipzyg6ii8/cmn6ay9ff37xr0kw55o7x0pwg/1b1cc4c8ab14b15903d3e157356410f1476c3ce751e601a4de4cf81505103e5a.jpg',
  'https://assets.adsviewer.io/assets/expiring_assets/cmhdti6o000imus0ipzyg6ii8/cmn6ay9ff37xr0kw55o7x0pwg/a807e41452aa4b7264ca5c4d698d7e98fee3bf261671be50be74ea4af9957d20.jpg',
  'https://assets.adsviewer.io/assets/expiring_assets/cmhdti6o000imus0ipzyg6ii8/cmn6ay9ff37xr0kw55o7x0pwg/6e350a986542499de15511431f452350f7c1899969b5b4c3e86deeb0fbcd9d39.jpg',
];

// Grid layout constants (screen coords) — shared with the director.
const GRID = {
  x: 80, y: 296, cols: 5, cw: 336, ch: 432, gap: 20, mediaH: 300,
};
GRID.cardCenter = (i) => {
  const col = i % GRID.cols, row = Math.floor(i / GRID.cols);
  return {
    x: GRID.x + col * (GRID.cw + GRID.gap) + GRID.cw / 2,
    y: GRID.y + row * (GRID.ch + GRID.gap) + GRID.ch / 2,
  };
};

const CARDS = [
  { id: 'n1', type: 'img', src: NOTION_IMGS[0], name: 'NOTION_UGC_9x16_07', reach: '2.1M', days: 24 },
  { id: 'n2', type: 'img', src: NOTION_IMGS[1], name: 'NOTION_AI_9x16_03', reach: '1.4M', days: 18 },
  { id: 'n3', type: 'img', src: NOTION_IMGS[2], name: 'NOTION_TEMPLATES_12', reach: '980k', days: 31 },
  { id: 'n4', type: 'img', src: NOTION_IMGS[3], name: 'NOTION_CALENDAR_05', reach: '760k', days: 9 },
  { id: 'n5', type: 'vid', name: 'NOTION_UGC_video_22', reach: '3.0M', days: 12 },
  { id: 'n6', type: 'vid', name: 'NOTION_MAIL_video_01', reach: '540k', days: 6 },
  { id: 'n7', type: 'img', src: NOTION_IMGS[1], name: 'NOTION_AI_static_09', reach: '1.1M', days: 21 },
  { id: 'n8', type: 'vid', name: 'NOTION_TEAMS_video_14', reach: '420k', days: 4 },
  { id: 'n9', type: 'img', src: NOTION_IMGS[2], name: 'NOTION_DOCS_static_18', reach: '690k', days: 27 },
  { id: 'n10', type: 'vid', name: 'NOTION_CALENDAR_vid_02', reach: '310k', days: 3 },
];

function ImgOrPlaceholder({ src, label = 'Notion', mono = 'N', fit = 'cover' }) {
  return (
    <div style={{ position: 'absolute', inset: 0, background: fit === 'contain' ? 'transparent' : 'linear-gradient(150deg,#f3f1ec,#e7e3db)', overflow: 'hidden' }}>
      <img src={src} alt="" onError={(e) => { e.target.style.display = 'none'; }} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: fit, display: 'block' }} />
    </div>
  );
}

function VideoTile() {
  return (
    <div style={{
      width: '100%', height: '100%',
      background: 'radial-gradient(circle at 50% 42%, rgba(255,255,255,0.08), transparent 60%), linear-gradient(160deg, #2a2740, #181626)',
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 10,
      color: 'rgba(255,255,255,0.82)',
    }}>
      <svg width="34" height="34" viewBox="0 0 16 16" fill="currentColor" style={{ filter: 'drop-shadow(0 1px 3px rgba(0,0,0,.5))' }}><path d="M4 3l9 5-9 5z" /></svg>
      <span style={{ fontFamily: AV.mono, fontSize: 13, color: 'rgba(255,255,255,0.6)', background: 'rgba(0,0,0,0.4)', padding: '2px 8px', borderRadius: 10 }}>0:15</span>
    </div>
  );
}

function AdCard({ card, index, selected }) {
  const c = GRID.cardCenter(index);
  const left = c.x - GRID.cw / 2, top = c.y - GRID.ch / 2;
  return (
    <div style={{
      position: 'absolute', left, top, width: GRID.cw, height: GRID.ch,
      borderRadius: 14, overflow: 'hidden', background: AV.surface,
      border: selected ? `2px solid ${AV.accent}` : `1px solid ${AV.line}`,
      boxShadow: selected ? `0 0 0 4px ${AV.accentSoft}, 0 14px 32px rgba(20,30,60,0.14)` : '0 1px 2px rgba(0,0,0,0.05)',
      transition: 'box-shadow 120ms', display: 'flex', flexDirection: 'column',
    }}>
      {/* header: checkbox + active badge + menu */}
      <div style={{ height: 46, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 12px', flexShrink: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div style={{
            width: 22, height: 22, borderRadius: 6,
            background: selected ? AV.accent : AV.surface,
            border: selected ? 'none' : `1.5px solid ${AV.lineStrong}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {selected && <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3.4" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6L9 17l-5-5" /></svg>}
          </div>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: AV.sans, fontSize: 12.5, fontWeight: 600, color: '#15803d' }}>
            <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#22c55e' }} />Active
          </span>
        </div>
        <svg width="18" height="18" viewBox="0 0 24 24" fill={AV.subtle}><circle cx="12" cy="5" r="1.6" /><circle cx="12" cy="12" r="1.6" /><circle cx="12" cy="19" r="1.6" /></svg>
      </div>
      {/* media — contain (full creative visible, like the real card) */}
      <div style={{ height: GRID.mediaH, borderTop: `1px solid ${AV.line}`, borderBottom: `1px solid ${AV.line}`, background: '#f1efe9', position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }}>
        <div style={{ position: 'absolute', top: 10, right: 10, zIndex: 3, fontFamily: AV.mono, fontSize: 11, padding: '3px 8px', borderRadius: 6, background: 'rgba(255,255,255,0.92)', color: AV.fg, border: `1px solid ${AV.line}` }}>Meta</div>
        {card.type === 'img'
          ? <ImgOrPlaceholder src={card.src} fit="contain" />
          : <VideoTile />}
      </div>
      {/* footer: page + CTA */}
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 14px', gap: 10 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 9, minWidth: 0 }}>
          <span style={{ width: 30, height: 30, borderRadius: '50%', background: '#15171c', color: '#fff', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, fontSize: 14, flexShrink: 0 }}>N</span>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontFamily: AV.sans, fontSize: 13.5, fontWeight: 600, color: AV.fg, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>Notion</div>
            <div style={{ fontFamily: AV.mono, fontSize: 10.5, color: AV.subtle }}>{card.reach} · {card.days}d</div>
          </div>
        </div>
        <div style={{ fontFamily: AV.sans, fontSize: 13, fontWeight: 500, color: AV.fg, border: `1px solid ${AV.lineStrong}`, borderRadius: 8, padding: '7px 14px', flexShrink: 0 }}>Visit</div>
      </div>
    </div>
  );
}

function ActionsButton({ s }) {
  if (s.actionsScale <= 0.001) return null;
  const pulse = s.actionsPulse; // 1..1.06
  return (
    <div style={{
      position: 'absolute', left: 960, top: 168, zIndex: 40,
      transform: `translateX(-50%) scale(${s.actionsScale * pulse})`, transformOrigin: 'center top',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        background: 'linear-gradient(135deg, #2c7be5, #5b3df5)', color: '#fff',
        padding: '13px 22px', borderRadius: 999, fontFamily: AV.sans, fontSize: 17, fontWeight: 600,
        boxShadow: '0 10px 30px rgba(44,90,200,0.4)', whiteSpace: 'nowrap',
      }}>
        <svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2v8M12 10l4-3M12 10l-4-3" /><path d="M5 13l-1 9 8-4 8 4-1-9" /></svg>
        Actions ({s.count})
      </div>
      {/* dropdown menu */}
      {s.menu > 0.001 && (
        <div style={{
          position: 'absolute', top: 62, left: '50%',
          transform: `translateX(-50%) scale(${s.menu})`, transformOrigin: 'center top',
          width: 380, background: AV.surface, borderRadius: 12, border: `1px solid ${AV.line}`,
          boxShadow: '0 18px 50px rgba(20,20,40,0.22)', padding: 8, opacity: s.menu,
        }}>
          <MenuItem icon="bookmark" label="Add 4 items to collection" />
          <MenuItem icon="ppt" label="Export selected items to PowerPoint" highlight={s.menuHi} />
          <div style={{ height: 1, background: AV.line, margin: '8px 4px' }} />
          <MenuItem icon="x" label="Deselect all" color="#c2410c" />
        </div>
      )}
    </div>
  );
}

function MenuItem({ icon, label, highlight, color }) {
  const icons = {
    bookmark: <path d="M6 3h12v18l-6-4-6 4z" />,
    ppt: <><rect x="4" y="3" width="16" height="18" rx="2" /><path d="M8 8h5a3 3 0 0 1 0 6H8zM8 8v9" /></>,
    x: <path d="M6 6l12 12M18 6L6 18" />,
  };
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', borderRadius: 8,
      background: highlight ? AV.accentSoft : 'transparent',
      fontFamily: AV.sans, fontSize: 16, color: color || AV.fg, fontWeight: 500,
    }}>
      <svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke={color || (icon === 'ppt' ? AV.accent : AV.fg)} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">{icons[icon]}</svg>
      {label}
    </div>
  );
}

function ExportModal({ s }) {
  if (s.modal <= 0.001) return null;
  const W = 580, H = 640;
  return (
    <>
      <div style={{ position: 'absolute', inset: 0, background: 'rgba(15,18,28,0.42)', zIndex: 50, opacity: s.modal }} />
      <div style={{
        position: 'absolute', left: 960, top: 540, zIndex: 51,
        width: W, height: H, marginLeft: -W / 2, marginTop: -H / 2,
        transform: `scale(${0.94 + 0.06 * s.modal})`, opacity: s.modal,
        background: AV.surface, borderRadius: 18, border: `1px solid ${AV.line}`,
        boxShadow: '0 40px 100px rgba(15,20,40,0.34)', padding: 30,
        fontFamily: AV.sans, display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 6 }}>
          <div style={{ width: 38, height: 38, borderRadius: 9, background: '#d24726', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8"><rect x="4" y="3" width="16" height="18" rx="2" /><path d="M8 8h5a3 3 0 0 1 0 6H8zM8 8v9" /></svg>
          </div>
          <div style={{ fontSize: 21, fontWeight: 600, color: AV.fg }}>Export to PowerPoint</div>
        </div>
        <div style={{ fontSize: 15, color: AV.muted, marginBottom: 22 }}>Exporting <b style={{ color: AV.fg }}>4 selected assets</b> from <b style={{ color: AV.fg }}>Notion</b>.</div>

        <Field label="Export only media">
          <div style={{ width: 52, height: 30, borderRadius: 999, background: AV.accent, position: 'relative' }}>
            <div style={{ position: 'absolute', top: 3, left: 25, width: 24, height: 24, borderRadius: '50%', background: '#fff' }} />
          </div>
        </Field>
        <Field label="Assets per slide"><Input value="3" /></Field>
        <Field label="Sort order"><Input value="EU Reach (Highest First)" chev /></Field>
        <Field label="Compression"><Input value="None" chev /></Field>
        <Field label="Assets to include"><Input value="All" chev /></Field>

        <div style={{ flex: 1 }} />
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 12, marginTop: 18 }}>
          <div style={{ padding: '12px 20px', borderRadius: 10, border: `1px solid ${AV.lineStrong}`, fontSize: 16, fontWeight: 500, color: AV.fg }}>Cancel</div>
          <div style={{
            display: 'flex', alignItems: 'center', gap: 9, padding: '12px 22px', borderRadius: 10,
            background: s.startHi ? '#1f6fd6' : AV.accent, color: '#fff', fontSize: 16, fontWeight: 600,
            boxShadow: '0 8px 22px rgba(44,90,200,0.32)',
          }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9"><rect x="4" y="3" width="16" height="18" rx="2" /><path d="M8 8h5a3 3 0 0 1 0 6H8zM8 8v9" /></svg>
            Start export
          </div>
        </div>
      </div>
    </>
  );
}

function Field({ label, children }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
      <div style={{ fontSize: 15, color: AV.fg, fontWeight: 500 }}>{label}</div>
      {children}
    </div>
  );
}
function Input({ value, chev }) {
  return (
    <div style={{ minWidth: 250, height: 44, borderRadius: 10, border: `1px solid ${AV.lineStrong}`, background: AV.surface, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 14px', fontSize: 15, color: AV.fg }}>
      {value}
      {chev && <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={AV.subtle} strokeWidth="2"><path d="M6 9l6 6 6-6" /></svg>}
    </div>
  );
}

function ExportToast({ s }) {
  if (s.toast <= 0.001) return null;
  const done = s.progress >= 0.999;
  return (
    <div style={{
      position: 'absolute', right: 40, bottom: 40, zIndex: 60, width: 440,
      transform: `translateY(${(1 - s.toast) * 30}px)`, opacity: s.toast,
      background: AV.surface, borderRadius: 14, border: `1px solid ${AV.line}`,
      boxShadow: '0 22px 60px rgba(15,20,40,0.26)', padding: 20, fontFamily: AV.sans,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 13 }}>
        <div style={{ width: 40, height: 40, borderRadius: 9, background: done ? '#15803d' : '#d24726', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          {done
            ? <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6L9 17l-5-5" /></svg>
            : <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8"><rect x="4" y="3" width="16" height="18" rx="2" /><path d="M8 8h5a3 3 0 0 1 0 6H8zM8 8v9" /></svg>}
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 16, fontWeight: 600, color: AV.fg }}>{done ? 'Export ready' : 'Building your deck…'}</div>
          <div style={{ fontFamily: AV.mono, fontSize: 12.5, color: AV.subtle, marginTop: 2 }}>Notion_Creative_Report.pptx · 4 assets</div>
        </div>
        <div style={{ fontFamily: AV.mono, fontSize: 14, color: done ? '#15803d' : AV.muted, fontWeight: 600 }}>{Math.round(s.progress * 100)}%</div>
      </div>
      <div style={{ height: 7, borderRadius: 4, background: AV.surface2, marginTop: 15, overflow: 'hidden' }}>
        <div style={{ height: '100%', width: `${s.progress * 100}%`, background: done ? '#15803d' : 'linear-gradient(90deg,#2c7be5,#5b3df5)', borderRadius: 4 }} />
      </div>
    </div>
  );
}

function AVScreen({ s }) {
  return (
    <div style={{ position: 'absolute', inset: 0, background: AV.bg, fontFamily: AV.sans, overflow: 'hidden' }}>
      {/* browser chrome */}
      <div style={{ height: 44, background: '#e9e7e2', borderBottom: `1px solid ${AV.line}`, display: 'flex', alignItems: 'center', gap: 10, padding: '0 16px' }}>
        <div style={{ display: 'flex', gap: 8 }}>
          {['#ff5f57', '#febc2e', '#28c840'].map((c) => <div key={c} style={{ width: 13, height: 13, borderRadius: '50%', background: c }} />)}
        </div>
        <div style={{ flex: 1, maxWidth: 560, margin: '0 auto', height: 28, borderRadius: 8, background: '#fbfaf8', border: `1px solid ${AV.line}`, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, fontFamily: AV.mono, fontSize: 12.5, color: AV.muted }}>
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke={AV.subtle} strokeWidth="2"><rect x="5" y="11" width="14" height="10" rx="2" /><path d="M8 11V7a4 4 0 0 1 8 0v4" /></svg>
          app.adsviewer.io/creative-research
        </div>
      </div>
      {/* app header */}
      <div style={{ height: 64, background: AV.surface, borderBottom: `1px solid ${AV.line}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 28px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontWeight: 600, fontSize: 18, color: AV.fg }}>
          <span style={{ width: 28, height: 28, borderRadius: 7, background: AV.fg, color: AV.bg, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, fontSize: 16 }}>A</span>
          AdsViewer
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <span style={{ fontFamily: AV.mono, fontSize: 13, color: AV.muted, border: `1px solid ${AV.line}`, borderRadius: 999, padding: '5px 13px' }}>1,284 cr</span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 9, fontSize: 14, color: AV.fg, border: `1px solid ${AV.line}`, borderRadius: 8, padding: '7px 12px' }}>
            <span style={{ width: 16, height: 16, borderRadius: 4, background: 'linear-gradient(135deg,#2c7be5,#00d4ff)' }} />
            Agency
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke={AV.subtle} strokeWidth="2"><path d="M6 9l6 6 6-6" /></svg>
          </span>
        </div>
      </div>
      {/* page header */}
      <div style={{ padding: '26px 80px 0', display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between' }}>
        <div>
          <div style={{ fontFamily: AV.mono, fontSize: 13, color: AV.subtle, letterSpacing: '0.06em' }}>/ creative research · tracking</div>
          <div style={{ fontSize: 30, fontWeight: 600, color: AV.fg, letterSpacing: '-0.02em', marginTop: 6 }}>Notion · tracked competitor</div>
        </div>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
          <Pill text="814 ads" /><Pill text="last 30d" /><Pill text="sort: reach ↓" />
        </div>
      </div>
      {/* grid */}
      {CARDS.map((c, i) => <AdCard key={c.id} card={c} index={i} selected={s.selected.includes(i)} />)}

      <ActionsButton s={s} />
      <ExportModal s={s} />
      <ExportToast s={s} />
    </div>
  );
}

function Pill({ text }) {
  return <span style={{ fontFamily: AV.mono, fontSize: 12.5, color: AV.muted, border: `1px solid ${AV.line}`, borderRadius: 7, padding: '7px 11px', background: AV.surface }}>{text}</span>;
}

// ── Output slide (PowerPoint payoff) ─────────────────────────────────────────
function OutputSlide({ kb = 0 }) {
  const sel = [0, 1, 2, 3].map((i) => CARDS[i]);
  return (
    <div style={{ position: 'absolute', inset: 0, background: '#11131a', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      {/* PPT app frame hint */}
      <div style={{
        width: 1500, height: 844, background: '#fff', borderRadius: 6, overflow: 'hidden',
        boxShadow: '0 40px 120px rgba(0,0,0,0.5)', transform: `scale(${1 + kb * 0.06})`,
        position: 'relative', fontFamily: AV.sans, display: 'flex', flexDirection: 'column',
      }}>
        {/* slide header band */}
        <div style={{ padding: '46px 64px 0', display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontFamily: AV.mono, fontSize: 18, color: AV.accent, letterSpacing: '0.04em' }}>AdsViewer · Creative Research</div>
            <div style={{ fontSize: 46, fontWeight: 700, color: '#15171c', letterSpacing: '-0.02em', marginTop: 8 }}>Notion — Top Performing Creatives</div>
          </div>
          <div style={{ textAlign: 'right', fontFamily: AV.mono, fontSize: 15, color: AV.subtle, lineHeight: 1.5 }}>
            Last 30 days<br />4 assets · EU reach
          </div>
        </div>
        <div style={{ height: 4, background: 'linear-gradient(90deg,#2c7be5,#5b3df5)', margin: '26px 64px 0', borderRadius: 2 }} />
        {/* slide body — 4 asset cards */}
        <div style={{ flex: 1, display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 28, padding: '34px 64px 56px' }}>
          {sel.map((c, i) => (
            <div key={i} style={{ border: `1px solid ${AV.line}`, borderRadius: 12, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
              <div style={{ flex: 1, background: '#f1efe9', minHeight: 0, position: 'relative' }}>
                <ImgOrPlaceholder src={c.src} fit="contain" />
              </div>
              <div style={{ padding: '13px 15px' }}>
                <div style={{ fontSize: 16, fontWeight: 600, color: '#15171c', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.name}</div>
                <div style={{ fontFamily: AV.mono, fontSize: 13, color: AV.subtle, marginTop: 3 }}>{c.reach} reach · {c.days}d</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AVScreen, OutputSlide, GRID, CARDS, AV });
