// scenes-spotlight.jsx — four product spotlights, each with its own micro-scene.
// Layout alternates left/right. The "visual" half is different for each product:
//   Core — phone with floating page snippets (morning light)
//   Roam — phone with orbiting tabs/spaces (night)
//   Code — a typing terminal window
//   Desk — a desktop with floating cards & a search prompt
//
// All visuals use scroll-reveal + idle motion (rotation, drift, blink).

const { useRef: useRefS, useEffect: useEffectS, useState: useStateS, useMemo: useMemoS } = React;

// --- Shared layout shell ---
function SpotlightShell({ id, eyebrow, title, suf, lede, features, cta, more, flipped, theme, visual }) {
  const ref = useRefS(null);
  const seen = window.useInView ? window.useInView(ref, { threshold: 0.18 }) : true;

  const colors = {
    core: { eyebrow: 'var(--gold)', accent: 'var(--gold)', text: 'var(--ink)', sub: 'var(--sepia)' },
    roam: { eyebrow: 'var(--lavender)', accent: 'var(--lavender)', text: 'var(--lavender-2)', sub: 'var(--lavender)' },
    code: { eyebrow: 'var(--gold-light)', accent: 'var(--gold-light)', text: 'var(--lavender-2)', sub: 'var(--lavender)' },
    desk: { eyebrow: 'var(--lavender)', accent: 'var(--lavender)', text: 'var(--lavender-2)', sub: 'var(--lavender)' },
  }[theme] || {};

  return (
    <section id={id} ref={ref} style={{
      position: 'relative',
      padding: '160px 8vw',
      minHeight: '100vh',
      display: 'flex', alignItems: 'center',
      color: colors.text,
    }}>
      <div className="spot-grid" style={{
        maxWidth: 1380, width: '100%', margin: '0 auto',
        display: 'grid', gridTemplateColumns: flipped ? '1.05fr 1fr' : '1fr 1.05fr',
        gap: 100, alignItems: 'center',
      }}>
        <div style={{
          order: flipped ? 2 : 1,
          opacity: seen ? 1 : 0,
          transform: seen ? 'translateY(0)' : 'translateY(40px)',
          transition: 'opacity 1.2s, transform 1.4s cubic-bezier(.2,.7,.2,1)',
        }}>
          <div style={{
            fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '0.45em',
            textTransform: 'uppercase', color: colors.eyebrow, marginBottom: 28,
            display: 'flex', alignItems: 'center', gap: 14,
          }}>
            <span style={{ width: 32, height: 1, background: 'currentColor', display: 'inline-block' }}></span>
            {eyebrow}
          </div>
          <h2 style={{
            fontFamily: 'var(--serif)',
            fontSize: 'clamp(56px, 7vw, 130px)',
            lineHeight: 0.92,
            letterSpacing: '-0.035em',
            fontWeight: 300,
            margin: '0 0 28px',
          }}>{title}<br/>
            <span style={{
              fontFamily: 'var(--mono)', fontSize: 'clamp(14px, 1.2vw, 20px)',
              letterSpacing: '0.4em', opacity: 0.55, display: 'block', marginTop: 16,
              textTransform: 'uppercase', fontWeight: 400,
            }}>{suf}</span>
          </h2>
          <p style={{
            fontFamily: 'var(--serif)', fontSize: 'clamp(20px, 1.6vw, 26px)',
            fontStyle: 'italic', lineHeight: 1.4, maxWidth: 520,
            color: colors.sub, marginBottom: 44,
          }}>{lede}</p>
          <div className="feat-grid" style={{
            display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '28px 40px',
            marginBottom: 44, maxWidth: 540,
          }}>
            {features.map((f, i) => (
              <div key={i} style={{ position: 'relative', paddingLeft: 22 }}>
                <span style={{
                  position: 'absolute', left: 0, top: 4, fontSize: 10, color: colors.accent, opacity: 0.7,
                }}>◆</span>
                <h5 style={{
                  fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '0.25em',
                  textTransform: 'uppercase', marginBottom: 8, color: colors.accent,
                  fontWeight: 500,
                }}>{f.h}</h5>
                <p style={{ fontSize: 15, lineHeight: 1.55, opacity: 0.8, fontFamily: 'var(--serif)' }}>{f.p}</p>
              </div>
            ))}
          </div>
          <div className="cta-row" style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 24 }}>
            <a href={cta.href} data-cursor="hover" style={{
              display: 'inline-flex', alignItems: 'center', gap: 14,
              padding: '16px 24px', borderRadius: 99,
              background: colors.accent, color: theme === 'roam' || theme === 'desk' || theme === 'code' ? 'var(--night)' : 'var(--cream-paper)',
              fontFamily: 'var(--serif)', fontSize: 18,
              transition: 'transform .3s, box-shadow .3s',
            }} onMouseEnter={(e)=>{e.currentTarget.style.transform='translateY(-3px)';e.currentTarget.style.boxShadow=`0 16px 40px ${theme==='core'?'rgba(176,125,40,.35)':'rgba(200,184,255,.35)'}`}}
               onMouseLeave={(e)=>{e.currentTarget.style.transform='';e.currentTarget.style.boxShadow=''}}>
              <span style={{
                fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.3em',
                textTransform: 'uppercase', opacity: 0.6, marginRight: 6,
              }}>{cta.platform}</span>
              {cta.label}
              <span>→</span>
            </a>
            {more && (
              <a href={more.href} data-cursor="hover" style={{
                fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '0.24em',
                textTransform: 'uppercase', color: colors.eyebrow,
                display: 'inline-flex', alignItems: 'center', gap: 8,
                borderBottom: '1px solid currentColor', paddingBottom: 4,
                transition: 'gap .25s, opacity .25s', opacity: 0.85,
              }} onMouseEnter={(e)=>{e.currentTarget.style.gap='12px';e.currentTarget.style.opacity='1'}}
                 onMouseLeave={(e)=>{e.currentTarget.style.gap='8px';e.currentTarget.style.opacity='0.85'}}>
                {more.label || 'Read the full page'} <span>→</span>
              </a>
            )}
          </div>
        </div>

        <div style={{
          order: flipped ? 1 : 2,
          opacity: seen ? 1 : 0,
          transform: seen ? 'translateY(0) scale(1)' : 'translateY(60px) scale(.94)',
          transition: 'opacity 1.4s, transform 1.6s cubic-bezier(.2,.7,.2,1) .15s',
        }}>{visual}</div>
      </div>
    </section>
  );
}

// --- Phone frame primitive ---
function PhoneFrame({ src, w = 320, style }) {
  return (
    <div style={{
      position: 'relative', width: w, borderRadius: 44,
      background: '#000', padding: 12,
      boxShadow: '0 50px 100px rgba(0,0,0,.4), 0 0 0 1px rgba(255,255,255,.06) inset',
      ...style,
    }}>
      <div style={{
        position: 'absolute', top: 12, left: '50%', transform: 'translateX(-50%)',
        width: 110, height: 28, background: '#000', borderRadius: '0 0 16px 16px', zIndex: 3,
      }}/>
      <img src={src} alt="" style={{ borderRadius: 34, width: '100%', display: 'block' }}/>
    </div>
  );
}

// --- Core visual: phone with floating page snippets ---
function CoreVisual() {
  return (
    <div style={{ position: 'relative', display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: 640 }}>
      {/* Halo */}
      <div style={{
        position: 'absolute', width: 480, height: 480, borderRadius: '50%',
        background: 'radial-gradient(circle, rgba(212,168,90,.35), transparent 65%)',
        filter: 'blur(40px)',
      }}/>
      <PhoneFrame src="assets/core-home.png" w={340} style={{ animation: 'phoneFloat 6s ease-in-out infinite', position: 'relative', zIndex: 2 }}/>
      {/* Floating fragments */}
      <div style={{
        position: 'absolute', left: '4%', top: '12%', width: 240,
        background: 'var(--cream-paper)', padding: '20px 24px',
        borderRadius: 12, boxShadow: '0 24px 48px rgba(35,27,16,.2)',
        fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 18,
        color: 'var(--ink)', transform: 'rotate(-4deg)',
        animation: 'float1 8s ease-in-out infinite',
      }}>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '.3em', opacity: .55, marginBottom: 8, textTransform: 'uppercase' }}>Almanac · Tuesday</div>
        Sunrise at 6:14. Tea steeping. The first quiet hour.
      </div>
      <div style={{
        position: 'absolute', right: '0%', top: '50%', width: 200,
        background: 'var(--ink)', padding: '18px 22px',
        borderRadius: 12, boxShadow: '0 24px 48px rgba(0,0,0,.3)',
        fontFamily: 'var(--serif)', fontSize: 16, color: 'var(--cream-paper)',
        transform: 'rotate(5deg)',
        animation: 'float2 9s ease-in-out infinite',
      }}>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '.3em', opacity: .55, marginBottom: 8, textTransform: 'uppercase' }}>Asked Ari</div>
        <em>"Read me three poems for the train."</em>
      </div>
      <div style={{
        position: 'absolute', left: '10%', bottom: '8%', width: 180,
        background: 'rgba(246,239,222,.85)', padding: '14px 18px',
        borderRadius: 99, boxShadow: '0 16px 32px rgba(35,27,16,.18)',
        fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.22em',
        color: 'var(--sepia)', transform: 'rotate(-2deg)',
        animation: 'float3 7s ease-in-out infinite',
        textTransform: 'uppercase', textAlign: 'center',
      }}>◐ Offline — local model</div>
      <style>{`
        @keyframes phoneFloat { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-12px)} }
        @keyframes float1 { 0%,100%{transform:rotate(-4deg) translateY(0)} 50%{transform:rotate(-4deg) translateY(-14px)} }
        @keyframes float2 { 0%,100%{transform:rotate(5deg) translateY(0)} 50%{transform:rotate(5deg) translateY(-10px)} }
        @keyframes float3 { 0%,100%{transform:rotate(-2deg) translateY(0)} 50%{transform:rotate(-2deg) translateY(-8px)} }
      `}</style>
    </div>
  );
}

// --- Roam visual: phone with orbiting tabs around it ---
function RoamVisual() {
  const orbiters = useMemoS(() => [
    { label: 'arxiv.org/2410.18585', tone: 'gold', angle: -28, dist: 220, d: 0 },
    { label: 'are.na/quiet-software', tone: 'lavender', angle: 40, dist: 240, d: 0.4 },
    { label: 'kinopio.club/canvas', tone: 'lavender', angle: 140, dist: 230, d: 0.8 },
    { label: 'space · Reading', tone: 'gold', angle: -135, dist: 250, d: 1.2 },
    { label: 'thread · Local LLMs', tone: 'lavender', angle: 200, dist: 210, d: 1.6 },
  ], []);

  return (
    <div style={{ position: 'relative', display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: 720 }}>
      {/* Orbit rings */}
      <svg viewBox="-300 -300 600 600" style={{ position: 'absolute', width: 600, height: 600, opacity: 0.32 }}>
        <ellipse cx="0" cy="0" rx="260" ry="260" fill="none" stroke="url(#orbit-g)" strokeWidth="0.8" strokeDasharray="2 6"/>
        <ellipse cx="0" cy="0" rx="200" ry="200" fill="none" stroke="url(#orbit-g)" strokeWidth="0.6" strokeDasharray="2 6"/>
        <defs>
          <linearGradient id="orbit-g" x1="0" x2="1">
            <stop offset="0" stopColor="#d4a85a"/>
            <stop offset="1" stopColor="#c8b8ff"/>
          </linearGradient>
        </defs>
      </svg>
      {/* Halo */}
      <div style={{
        position: 'absolute', width: 460, height: 460, borderRadius: '50%',
        background: 'radial-gradient(circle, rgba(139,109,255,.45), transparent 65%)',
        filter: 'blur(40px)',
      }}/>
      <PhoneFrame src="assets/roam-home.png" w={320} style={{ animation: 'phoneFloat 6.5s ease-in-out infinite', position: 'relative', zIndex: 3 }}/>

      {/* Orbiting tab chips */}
      <div style={{ position: 'absolute', inset: 0, animation: 'orbitSpin 28s linear infinite', pointerEvents: 'none' }}>
        {orbiters.map((o, i) => (
          <div key={i} style={{
            position: 'absolute', left: '50%', top: '50%',
            transform: `rotate(${o.angle}deg) translateX(${o.dist}px) rotate(${-o.angle}deg)`,
            animation: `chipBob 4s ease-in-out infinite ${o.d}s`,
          }}>
            <div style={{
              padding: '10px 16px', borderRadius: 99,
              background: o.tone === 'gold' ? 'rgba(212,168,90,.18)' : 'rgba(200,184,255,.18)',
              border: `1px solid ${o.tone === 'gold' ? 'rgba(212,168,90,.45)' : 'rgba(200,184,255,.45)'}`,
              color: o.tone === 'gold' ? 'var(--gold-light)' : 'var(--lavender-2)',
              fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '.06em',
              backdropFilter: 'blur(12px)', whiteSpace: 'nowrap',
            }}>{o.label}</div>
          </div>
        ))}
      </div>
      <style>{`
        @keyframes orbitSpin { from { transform: rotate(0) } to { transform: rotate(360deg) } }
        @keyframes chipBob { 0%,100% { filter: brightness(1) } 50% { filter: brightness(1.25) } }
      `}</style>
    </div>
  );
}

// --- Code visual: typing terminal ---
function CodeVisual() {
  const [t, setT] = useStateS(0);
  useEffectS(() => {
    let id;
    function tick() { setT((x) => x + 1); id = setTimeout(tick, 38); }
    id = setTimeout(tick, 200);
    return () => clearTimeout(id);
  }, []);

  const lines = [
    { ch: '$ ', after: 'ari plan "ship the family page"', cls: 'mono-prompt' },
    { ch: '> ', after: 'planning · 3 sections · local model · 0 telemetry', cls: 'mono-dim' },
    { ch: '', after: '' },
    { ch: '', after: '┌── Section 1 ─────────────────────────────', cls: 'mono-frame' },
    { ch: '', after: '│  hero · cream sky → lavender night', cls: 'mono-body' },
    { ch: '', after: '│  type: Cormorant Garamond / IBM Plex', cls: 'mono-body' },
    { ch: '', after: '│  motion: scroll-bound, no JS feed loop', cls: 'mono-body' },
    { ch: '', after: '└──────────────────────────────────────────', cls: 'mono-frame' },
    { ch: '', after: '' },
    { ch: '✓ ', after: 'plan written · waiting for your hand.', cls: 'mono-ok' },
  ];

  // Build cumulative text by character index
  let charsUsed = 0;
  const total = lines.reduce((s, l) => s + l.ch.length + l.after.length + 1, 0);
  const max = Math.min(t * 2, total);
  const rendered = lines.map((l, i) => {
    const full = l.ch + l.after;
    const start = charsUsed;
    const end = charsUsed + full.length;
    let shown = '';
    if (max >= end) shown = full;
    else if (max > start) shown = full.slice(0, max - start);
    charsUsed = end + 1;
    return { ...l, shown, done: max >= end };
  });

  return (
    <div style={{ position: 'relative', maxWidth: 660, margin: '0 auto' }}>
      <div style={{
        position: 'absolute', inset: -40, borderRadius: 20,
        background: 'radial-gradient(circle, rgba(212,168,90,.35), transparent 60%)',
        filter: 'blur(50px)', zIndex: 0,
      }}/>
      <div style={{
        position: 'relative', borderRadius: 14, overflow: 'hidden',
        background: 'linear-gradient(180deg, #2a2117 0%, #1a130a 100%)',
        boxShadow: '0 60px 100px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.05) inset',
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', padding: '13px 18px',
          background: 'rgba(255,255,255,.04)', borderBottom: '1px solid rgba(255,255,255,.05)', gap: 8,
        }}>
          <span style={{ width: 12, height: 12, borderRadius: '50%', background: '#e3776e' }}></span>
          <span style={{ width: 12, height: 12, borderRadius: '50%', background: '#d4ad48' }}></span>
          <span style={{ width: 12, height: 12, borderRadius: '50%', background: '#6dac5b' }}></span>
          <span style={{ flex: 1, textAlign: 'center', fontFamily: 'var(--mono)', fontSize: 11, color: 'rgba(255,255,255,.45)', letterSpacing: '.1em' }}>~/work/family</span>
        </div>
        <div style={{
          padding: '28px 32px',
          fontFamily: 'var(--mono)', fontSize: 13.5, lineHeight: 1.85,
          color: '#cda964',
          minHeight: 360, background: 'linear-gradient(180deg, #1a1308 0%, #0e0a04 100%)',
        }}>
          {rendered.map((l, i) => (
            <div key={i} style={{
              color: l.cls === 'mono-prompt' ? '#d4a85a'
                : l.cls === 'mono-dim' ? '#7a6a4a'
                : l.cls === 'mono-frame' ? '#9b8a6c'
                : l.cls === 'mono-body' ? '#e6cf99'
                : l.cls === 'mono-ok' ? '#a4d489'
                : '#cda964',
              whiteSpace: 'pre',
            }}>
              {l.shown}{i === rendered.findIndex(x => !x.done) && max < total ? <span style={{ background: '#e0b15a', display: 'inline-block', width: '0.55em', height: '1.2em', verticalAlign: '-3px', animation: 'cursorBlink 1s steps(1) infinite' }}></span> : null}
            </div>
          ))}
        </div>
      </div>
      <style>{`@keyframes cursorBlink { 0%,49%{opacity:1} 50%,100%{opacity:0} }`}</style>
    </div>
  );
}

// --- Desk visual: floating Mac with cards flying in ---
function DeskVisual() {
  return (
    <div style={{ position: 'relative', display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: 560 }}>
      <div style={{
        position: 'absolute', width: 560, height: 460, borderRadius: 40,
        background: 'radial-gradient(circle, rgba(200,184,255,.35), transparent 65%)',
        filter: 'blur(50px)', zIndex: 0,
      }}/>
      {/* Mac window */}
      <div style={{
        position: 'relative', width: 'min(560px, 100%)', borderRadius: 14, overflow: 'hidden',
        background: '#f6efde',
        boxShadow: '0 60px 100px rgba(0,0,0,.4), 0 0 0 1px rgba(255,255,255,.5) inset',
        zIndex: 2, animation: 'macFloat 7s ease-in-out infinite',
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', padding: '12px 16px',
          background: 'rgba(0,0,0,.05)', borderBottom: '1px solid rgba(0,0,0,.08)', gap: 8,
        }}>
          <span style={{ width: 12, height: 12, borderRadius: '50%', background: '#e3776e' }}></span>
          <span style={{ width: 12, height: 12, borderRadius: '50%', background: '#d4ad48' }}></span>
          <span style={{ width: 12, height: 12, borderRadius: '50%', background: '#6dac5b' }}></span>
          <span style={{ flex: 1, textAlign: 'center', fontFamily: 'var(--mono)', fontSize: 11, color: 'rgba(35,27,16,.5)', letterSpacing: '.1em' }}>ari · desk</span>
        </div>
        <div style={{ padding: '36px 40px 44px', color: 'var(--ink)' }}>
          <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.4em', textTransform: 'uppercase', opacity: .55, marginBottom: 18 }}>Ask Ari · Tuesday, 9:14</div>
          <div style={{ fontFamily: 'var(--serif)', fontSize: 30, fontStyle: 'italic', lineHeight: 1.2, marginBottom: 28, color: 'var(--ink)' }}>
            Find the three contracts I sent in February, draft a polite follow-up, hold them until I sit down with tea.
          </div>
          {/* Status rows */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {[
              { tag: 'Found', body: '3 PDFs · Mail · Feb 4, 11, 22', accent: '#6dac5b' },
              { tag: 'Drafted', body: 'follow-up · warm tone · plain text', accent: '#d4ad48' },
              { tag: 'Holding', body: 'until 7:30 am · or your nod', accent: '#8b6dff' },
            ].map((r, i) => (
              <div key={i} style={{
                display: 'flex', alignItems: 'center', gap: 12,
                padding: '10px 14px', borderRadius: 10,
                background: 'rgba(35,27,16,.04)', border: '1px solid rgba(35,27,16,.08)',
                animation: `cardSlide 1s cubic-bezier(.2,.7,.2,1) ${0.4 + i * 0.18}s both`,
              }}>
                <span style={{ width: 7, height: 7, borderRadius: '50%', background: r.accent, boxShadow: `0 0 12px ${r.accent}` }}></span>
                <span style={{ fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '.18em', textTransform: 'uppercase', opacity: .65, minWidth: 80 }}>{r.tag}</span>
                <span style={{ fontFamily: 'var(--serif)', fontSize: 16, fontStyle: 'italic' }}>{r.body}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
      {/* Floating "found" cards drifting in */}
      <div style={{
        position: 'absolute', left: '-2%', top: '14%',
        background: 'rgba(255,255,255,.06)', padding: '12px 16px',
        borderRadius: 8, fontFamily: 'var(--mono)', fontSize: 11,
        color: 'var(--lavender-2)', letterSpacing: '.05em',
        border: '1px solid rgba(200,184,255,.18)', backdropFilter: 'blur(12px)',
        transform: 'rotate(-5deg)', zIndex: 1,
        animation: 'driftIn 1.6s ease-out .4s both, cardFloat 6s ease-in-out 2s infinite',
      }}>📄 Feb-04-Contract.pdf</div>
      <div style={{
        position: 'absolute', right: '0%', top: '20%',
        background: 'rgba(255,255,255,.06)', padding: '12px 16px',
        borderRadius: 8, fontFamily: 'var(--mono)', fontSize: 11,
        color: 'var(--lavender-2)', letterSpacing: '.05em',
        border: '1px solid rgba(200,184,255,.18)', backdropFilter: 'blur(12px)',
        transform: 'rotate(4deg)', zIndex: 1,
        animation: 'driftIn 1.6s ease-out .6s both, cardFloat 7s ease-in-out 2.2s infinite',
      }}>📄 Feb-22-Contract.pdf</div>
      <div style={{
        position: 'absolute', left: '4%', bottom: '8%',
        background: 'rgba(255,255,255,.06)', padding: '12px 16px',
        borderRadius: 8, fontFamily: 'var(--mono)', fontSize: 11,
        color: 'var(--lavender-2)', letterSpacing: '.05em',
        border: '1px solid rgba(200,184,255,.18)', backdropFilter: 'blur(12px)',
        transform: 'rotate(-3deg)', zIndex: 1,
        animation: 'driftIn 1.6s ease-out .8s both, cardFloat 6.5s ease-in-out 2.4s infinite',
      }}>✉ Follow-up · draft</div>
      <style>{`
        @keyframes macFloat { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-10px)} }
        @keyframes cardSlide { from { opacity:0; transform: translateX(-20px) } to { opacity:1; transform: none } }
        @keyframes driftIn { from { opacity:0; transform: translateY(20px) rotate(-12deg) } }
        @keyframes cardFloat { 0%,100%{ transform: translateY(0) rotate(-5deg) } 50%{ transform: translateY(-8px) rotate(-5deg) } }
      `}</style>
    </div>
  );
}

// --- Composed spotlights ---
function Spotlights() {
  return (
    <>
      <SpotlightShell
        id="core"
        eyebrow="I · CORE · iOS · DAY"
        title={<>A friend in <em style={{ color: 'var(--gold)' }}>the cream</em> of the page.</>}
        suf="ARI · CORE"
        lede="A life assistant designed like the inside cover of a hand-bound notebook. Local model, slow mornings, gentle endings."
        features={[
          { h: 'Almanac', p: 'Tides, weather, and the small rhythms of your week, written in plain serif.' },
          { h: 'Local model', p: 'Runs on your iPhone. Works on the train. No cloud, no telemetry.' },
          { h: 'One column', p: 'No tabs. No badges. One conversation, like a letter you keep adding to.' },
          { h: 'Quiet endings', p: 'A page turns at sunset. The app dims itself the way a lamp would.' },
        ]}
        cta={{ platform: 'App Store · Free', label: 'Download Ari · Core', href: 'https://apps.apple.com/gb/app/aricore/id6762657133' }}
        more={{ href: 'aricore.html', label: 'Read the full page' }}
        flipped={false}
        theme="core"
        visual={<CoreVisual/>}
      />

      <SpotlightShell
        id="roam"
        eyebrow="II · ROAM · iOS · NIGHT"
        title={<>A browser that <em>thinks</em><br/>with you.</>}
        suf="ARI · ROAM"
        lede="Spaces, skills, a copilot in every page. A midnight tab that remembers what you were reading."
        features={[
          { h: 'Spaces', p: 'A canvas for the rabbit hole — keep tabs, threads, and notes in one room.' },
          { h: 'Skills', p: 'Small recipes for repeated browser chores. Yours. Sharable. Off by default.' },
          { h: 'Reading mode', p: 'Strip the clutter. Cormorant on cream. The page as the writer meant it.' },
          { h: 'Companion', p: 'Ask the open tab a question. Get a careful answer. Keep the source.' },
        ]}
        cta={{ platform: 'App Store · Free', label: 'Download Ari · Roam', href: 'https://apps.apple.com/gb/app/ariroam/id6771599446' }}
        more={{ href: 'ariroam.html', label: 'Read the full page' }}
        flipped={true}
        theme="roam"
        visual={<RoamVisual/>}
      />

      <SpotlightShell
        id="code"
        eyebrow="III · CODE · macOS · DESK"
        title={<>A coding <em>harness</em><br/>for craftspeople.</>}
        suf="ARI · CODE"
        lede="Local-first models. Section planning. Zero telemetry. The terminal as a quiet writing desk."
        features={[
          { h: 'Plan first', p: 'Outline before you type. Section headings before paragraphs.' },
          { h: 'Local LLMs', p: 'Pair with the model on your machine, not a stranger\u2019s rack.' },
          { h: 'No telemetry', p: 'We don\u2019t see your code. Nobody does. That is the whole point.' },
          { h: 'Hand-tuned UI', p: 'A monospace meant to be read at length. Generous leading.' },
        ]}
        cta={{ platform: 'macOS · Free', label: 'Get Ari · Code', href: 'https://aricode.dev' }}
        flipped={false}
        theme="code"
        visual={<CodeVisual/>}
      />

      <SpotlightShell
        id="desk"
        eyebrow="IV · DESK · macOS · AGENT"
        title={<>An agent with <em>the full</em> power of your Mac.</>}
        suf="ARI · DESK"
        lede="Draft, sort, schedule, find. Watching nothing it does not need to watch."
        features={[
          { h: 'Long errands', p: 'Hand off a job; come back to a finished page on your desk.' },
          { h: 'Sandbox by default', p: 'Asks before touching anything you did not explicitly grant.' },
          { h: 'Local memory', p: 'Notes itself in a folder you own. Read it. Edit it. Delete it.' },
          { h: 'Free, inside AriCode', p: 'Not a separate purchase — Desk ships as a mode of AriCode. One install, two faces.' },
        ]}
        cta={{ platform: 'Inside Ari · Code', label: 'Get Ari · Code', href: 'https://aricode.dev' }}
        flipped={true}
        theme="desk"
        visual={<DeskVisual/>}
      />
    </>
  );
}

window.Spotlights = Spotlights;
