const { useState, useEffect, useRef } = React;

/* ---------- helpers ---------- */
const clamp01 = (x) => x < 0 ? 0 : x > 1 ? 1 : x;
const smooth = (x, a, b) => { const t = clamp01((x - a) / (b - a)); return t * t * (3 - 2 * t); };

/* ---------- typing helper (instant under no-motion) ---------- */
function useTyping(text, speed = 22, start = true, restart = 0) {
  const [out, setOut] = useState("");
  useEffect(() => {
    if (!start) { setOut(""); return; }
    if (document.body.classList.contains('no-motion')) { setOut(text); return; }
    setOut("");
    let i = 0;
    const id = setInterval(() => {
      i++;
      setOut(text.slice(0, i));
      if (i >= text.length) clearInterval(id);
    }, speed);
    return () => clearInterval(id);
  }, [text, start, speed, restart]);
  return out;
}

/* ---------- live sparkline ---------- */
function Spark({ running = true, trend = false, w = 120, h = 28 }) {
  const seed = trend
    ? Array.from({ length: 24 }, (_, i) => 6 + i * 0.7 + Math.random() * 4)
    : Array.from({ length: 24 }, () => 10 + Math.random() * 16);
  const [pts, setPts] = useState(seed);
  useEffect(() => {
    if (!running || document.body.classList.contains('no-motion')) return;
    const id = setInterval(() => {
      setPts(p => [...p.slice(1), (trend ? p[p.length - 1] + (Math.random() * 6 - 2) : 8 + Math.random() * 20)]);
    }, 700);
    return () => clearInterval(id);
  }, [running, trend]);
  const max = Math.max(...pts, 1);
  const norm = pts.map(y => (y / max) * (h - 4) + 2);
  const step = w / (norm.length - 1);
  const d = norm.map((y, i) => `${i === 0 ? 'M' : 'L'}${(i * step).toFixed(1)},${(h - y).toFixed(1)}`).join(' ');
  const area = `${d} L${w},${h} L0,${h} Z`;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: 'block' }}>
      <defs>
        <linearGradient id={`sparkFill${trend ? 'T' : ''}`} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="var(--accent)" stopOpacity="0.35" />
          <stop offset="100%" stopColor="var(--accent)" stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={area} fill={`url(#sparkFill${trend ? 'T' : ''})`} />
      <path d={d} fill="none" stroke="var(--accent)" strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  );
}

function Check() {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <circle cx="7" cy="7" r="6" stroke="var(--accent-line)" strokeWidth="1" />
      <path d="M4 7.5l2 2 4-5" stroke="var(--accent)" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

function SidebarIcon({ i }) {
  const paths = [
    "M3 5h10v6H3z M3 5l5 4 5-4",
    "M4 3h6l3 3v7H4z M10 3v3h3",
    "M3 8h10 M3 4h10 M3 12h6",
    "M3 4h10v8H3z M3 8h10",
    "M3 12V4 M3 12h10 M6 12V8 M9 12V6 M12 12V9",
    "M8 5v6 M5 8h6 M8 2v2 M8 12v2 M2 8h2 M12 8h2",
  ];
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round">
      <path d={paths[i]} />
    </svg>
  );
}

function Dot() {
  return <span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--accent)', display: 'inline-block' }} />;
}

/* ---------- FrameShell: the dark product window (shared chrome + sidebar) ---------- */
function FrameShell({ copy, title = "workspace", live = true, liveLabel = "live", activeNav = 1, badges = {}, user = { name: "Lara K.", role: "admin" }, sidebar = [], sidebarHead = "WORKSPACE", children, className = "" }) {
  return (
    <div className={`ws-shell frame ${className}`}>
      <div className="ws-chrome">
        <div className="ws-dots">
          <span style={{ background: '#ff5f57' }}></span>
          <span style={{ background: '#ffbd2e' }}></span>
          <span style={{ background: '#28c941' }}></span>
        </div>
        <div className="ws-title mono">{title}</div>
        <div className="ws-tools mono">
          {live ? <><span className="pulse-dot"></span> {liveLabel}</> : <span style={{ opacity: 0 }}>·</span>}
        </div>
      </div>

      <div className="ws-body">
        <aside className="ws-side">
          <div className="ws-side-head mono">{sidebarHead}</div>
          <ul>
            {sidebar.map((s, i) => (
              <li key={s} className={activeNav === i ? 'active' : ''}>
                <span className="ws-side-icon"><SidebarIcon i={i} /></span>
                {s}
                {badges[i] != null && <span className="ws-badge">{badges[i]}</span>}
              </li>
            ))}
          </ul>
          <div className="ws-side-foot">
            <div className="ws-avatar"></div>
            <div>
              <div style={{ fontSize: 12, color: 'var(--text)' }}>{user.name}</div>
              <div style={{ fontSize: 10, color: 'var(--text-3)' }} className="mono">{user.role}</div>
            </div>
          </div>
        </aside>

        <main className="ws-main">{children}</main>
      </div>

      <style>{`
        .ws-shell {
          width: 100%;
          background: linear-gradient(180deg, #0E1014, var(--bg));
          border: 1px solid var(--line);
          border-radius: var(--r-frame);
          overflow: hidden;
          box-shadow: var(--sh-frame);
          position: relative;
          display: flex;
          flex-direction: column;
        }
        .ws-chrome {
          display: flex; align-items: center; gap: 16px;
          padding: 12px 16px;
          border-bottom: 1px solid var(--line);
          background: rgba(255,255,255,0.015);
        }
        .ws-dots { display: flex; gap: 6px; }
        .ws-dots span { width: 11px; height: 11px; border-radius: 50%; }
        .ws-title { flex: 1; font-size: 11px; color: var(--text-3); text-align: center; letter-spacing: 0.04em; }
        .ws-tools { font-size: 11px; color: var(--text-3); display: flex; align-items: center; gap: 6px; }
        .pulse-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px var(--good); animation: pulse 1.8s ease-in-out infinite; }

        .ws-body { display: grid; grid-template-columns: 196px 1fr; min-height: 440px; flex: 1; }
        .ws-side { border-right: 1px solid var(--line); padding: 18px 14px; display: flex; flex-direction: column; gap: 16px; background: rgba(255,255,255,0.012); }
        .ws-side-head { font-size: 10px; color: var(--text-3); letter-spacing: 0.16em; padding: 0 8px; }
        .ws-side ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 2px; }
        .ws-side li {
          display: flex; align-items: center; gap: 10px;
          padding: 8px 10px; border-radius: 8px;
          font-size: 13px; color: var(--text-2);
          position: relative;
        }
        .ws-side li.active { background: var(--bg-3); color: var(--text); }
        .ws-side li.active::before { content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 2px; background: var(--accent); border-radius: 2px; }
        .ws-side-icon { width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center; color: var(--text-3); }
        .ws-side li.active .ws-side-icon { color: var(--accent); }
        .ws-badge { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--text-3); background: rgba(255,255,255,0.05); padding: 2px 6px; border-radius: 999px; }
        .ws-side-foot { margin-top: auto; display: flex; align-items: center; gap: 10px; padding: 10px; border-top: 1px solid var(--line); }
        .ws-avatar { width: 28px; height: 28px; border-radius: 50%; background: linear-gradient(135deg, #6E63B5, #3F8FB0); }

        .ws-main { padding: 22px; display: flex; flex-direction: column; gap: 16px; min-width: 0; }

        .ws-card { background: rgba(255,255,255,0.02); border: 1px solid var(--line); border-radius: 12px; padding: 18px; position: relative; }
        .ws-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
        .ws-card-eyebrow { font-size: 10px; color: var(--text-3); letter-spacing: 0.14em; display: flex; align-items: center; gap: 6px; text-transform: uppercase; }
        .ws-card-eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
        .ws-card-meta { font-size: 10px; color: var(--text-3); }

        .ws-pill { font-family: var(--sans); font-size: 11px; padding: 7px 12px; background: rgba(255,255,255,0.04); border: 1px solid var(--line); color: var(--text-2); border-radius: 999px; }
        .ws-pill.primary { background: var(--text); color: #0a0a0a; border-color: var(--text); }
        .ws-bignum { font-family: var(--serif); font-size: 36px; line-height: 1; letter-spacing: -0.03em; color: var(--text); }

        @media (max-width: 640px) {
          .ws-body { grid-template-columns: 1fr; }
          .ws-side { display: none; }
        }
      `}</style>
    </div>
  );
}

/* ---------- WorkspaceUI: hero product (draft + intel + auto) ---------- */
function WorkspaceUI({ copy, pinned = false, alive = true }) {
  const w = copy.workspace;

  const drafts = [
    { to: "marc.lehmann@kunde.ch", subject: "Re: Angebot Q3 Roadmap", body: "Hallo Marc,\n\ndanke für deine Rückmeldung. Anbei die aktualisierte Roadmap mit den Meilensteinen für Q3. Lass uns Mittwoch 14:30 kurz syncen — ich blocke direkt im Kalender." },
    { to: "team@baeumlin.ch", subject: "Re: Onboarding-Workshop nächste Woche", body: "Hi zusammen,\n\nder Workshop ist auf Dienstag 09:00 fixiert. Die Unterlagen liegen im geteilten Drive — bitte vorab durchgehen. Bei Fragen meldet euch direkt." },
    { to: "finance@kunde.ch", subject: "Re: Rechnung INV-2026-0412", body: "Hallo,\n\ndie Rechnung wurde heute Morgen beglichen — Referenz im Anhang. Bei weiteren Fragen stehe ich gerne zur Verfügung." }
  ];

  const [draftIdx, setDraftIdx] = useState(pinned ? 1 : 0);
  const current = drafts[draftIdx];
  const body = useTyping(current.body, 14, alive, draftIdx);

  useEffect(() => {
    if (pinned) return;
    const totalMs = current.body.length * 14 + 2400;
    const id = setTimeout(() => setDraftIdx(i => (i + 1) % drafts.length), totalMs);
    return () => clearTimeout(id);
  }, [draftIdx, pinned]);

  return (
    <FrameShell copy={copy} activeNav={1} badges={{ 0: 12 }}>
      <div className="ws-card ws-draft">
        <div className="ws-card-head">
          <div className="ws-card-eyebrow mono"><span className="dot"></span>{w.draft}</div>
          <div className="ws-card-meta mono">AI · GPT-4 · just now</div>
        </div>
        <div className="ws-mail-row" style={{ marginTop: 12 }}>
          <span className="ws-label mono">TO</span>
          <span className="ws-val">{current.to}</span>
        </div>
        <div className="ws-mail-row">
          <span className="ws-label mono">SUBJ</span>
          <span className="ws-val" style={{ color: 'var(--text)' }}>{current.subject}</span>
        </div>
        <pre className="ws-body-text">{body}<span className="caret">▍</span></pre>
        <div className="ws-actions">
          <button className="ws-pill primary">Approve &amp; send ↗</button>
          <button className="ws-pill">Regenerate</button>
          <button className="ws-pill">Edit</button>
          <div style={{ flex: 1 }}></div>
          <span className="mono" style={{ fontSize: 11, color: 'var(--text-3)' }}>{w.draftSub}</span>
        </div>
      </div>

      <div className="ws-grid">
        <div className="ws-card ws-intel">
          <div className="ws-card-head">
            <div className="ws-card-eyebrow mono"><span className="dot"></span>{w.intel}</div>
            <div className="mono" style={{ fontSize: 11, color: 'var(--accent)' }}>{w.eff}</div>
          </div>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 10 }}>
            <div className="ws-bignum">{w.hours}</div>
            <div className="mono" style={{ fontSize: 11, color: 'var(--text-3)' }}>{w.saved}</div>
          </div>
          <div style={{ marginTop: 14 }}><Spark running={alive} /></div>
        </div>

        <div className="ws-card ws-auto">
          <div className="ws-card-head">
            <div className="ws-card-eyebrow mono"><span className="dot"></span>{w.auto}</div>
          </div>
          <ul className="ws-auto-list">
            {w.autoItems.map((item) => <li key={item}><Check /> {item}</li>)}
          </ul>
          <div className="ws-found">
            <div>
              <div className="mono" style={{ fontSize: 10, color: 'var(--accent)', letterSpacing: '0.12em' }}>● {w.found.toUpperCase()}</div>
              <div style={{ fontSize: 13, color: 'var(--text)', marginTop: 4 }}>{w.foundDetail}</div>
            </div>
            <button className="ws-pill">Review →</button>
          </div>
        </div>
      </div>

      <style>{`
        .ws-draft { background: linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.005)); }
        .ws-mail-row { display: flex; gap: 12px; font-size: 12px; padding: 8px 0; border-bottom: 1px dashed rgba(255,255,255,0.06); }
        .ws-label { color: var(--text-3); width: 38px; }
        .ws-val { color: var(--text-2); }
        .ws-body-text { margin: 14px 0 16px; font-family: var(--sans); font-size: 13px; color: var(--text); line-height: 1.6; white-space: pre-wrap; min-height: 56px; }
        .caret { display: inline-block; width: 8px; color: var(--accent); animation: blink 1s steps(2) infinite; transform: translateY(-1px); }
        body.no-motion .caret { animation: none; }
        .ws-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
        .ws-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
        @media (max-width: 600px) { .ws-grid { grid-template-columns: 1fr; } }
        .ws-auto-list { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-direction: column; gap: 8px; font-size: 12px; color: var(--text-2); }
        .ws-auto-list li { display: flex; align-items: center; gap: 8px; }
        .ws-found { margin-top: 14px; padding: 12px; background: rgba(255,255,255,0.025); border: 1px dashed var(--accent-line); border-radius: 8px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
      `}</style>
    </FrameShell>
  );
}

/* ---------- InboxFrame: overflow (Problem) or done (CTA) ---------- */
function InboxFrame({ copy, mode = "overflow" }) {
  const w = copy.workspace;
  const rows = [
    { from: "Marc Lehmann", subj: "Re: Angebot Q3 Roadmap", tag: "new", time: "09:42" },
    { from: "Finance", subj: "INV-2026-0412 offen", tag: "overdue", time: "08:30" },
    { from: "Sarah K.", subj: "Onboarding-Workshop", tag: "wait", time: "Gestern" },
    { from: "Support", subj: "Ticket #8821", tag: "wait", time: "Gestern" },
    { from: "HR", subj: "Spesen-Freigabe Q2", tag: "new", time: "Mo" },
    { from: "Kunde DACH", subj: "Compliance-Auflagen?", tag: "wait", time: "Mo" },
    { from: "Marketing", subj: "Newsletter Freigabe", tag: "wait", time: "Fr" },
    { from: "PM", subj: "Status-Update Projekt", tag: "wait", time: "Fr" }
  ];
  const tagLabel = { overdue: w.overdue, wait: w.unanswered, new: "" };

  return (
    <FrameShell copy={copy} activeNav={0} badges={{ 0: mode === "done" ? 0 : 34 }}>
      {mode === "done" ? (
        <div className="ws-done">
          <div className="ws-done-check">
            <svg width="30" height="30" viewBox="0 0 24 24" fill="none"><path d="M4 12.5l5 5L20 6.5" stroke="var(--good)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /></svg>
          </div>
          <div className="ws-done-title serif">{w.allDone}</div>
          <div className="ws-done-sub">{w.allDoneSub}</div>
          <div className="ws-done-chip mono"><span className="pulse-dot" style={{ position: 'static' }}></span> {w.savedChip}</div>
        </div>
      ) : (
        <>
          <div className="ws-inhead">
            <div className="ws-in-count serif"><Counter to={34} /> <span className="ws-in-count-l">{w.unread}</span></div>
            <div className="mono ws-in-ticker">● {w.newSince}</div>
          </div>
          <div className="ws-inbox">
            {rows.map((r, i) => (
              <div className={`ws-inrow ${r.tag}`} key={i}>
                <span className="ws-in-bullet"></span>
                <div className="ws-in-main">
                  <div className="ws-in-from">{r.from}</div>
                  <div className="ws-in-subj">{r.subj}</div>
                </div>
                {r.tag !== "new" && <span className={`ws-in-tag mono ${r.tag}`}>{tagLabel[r.tag]}</span>}
                <span className="ws-in-time mono">{r.time}</span>
              </div>
            ))}
          </div>
        </>
      )}

      <style>{`
        .ws-inhead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
        .ws-in-count { font-size: 30px; color: var(--text); display: flex; align-items: baseline; gap: 8px; }
        .ws-in-count-l { font-family: var(--sans); font-size: 13px; color: var(--text-3); letter-spacing: 0; }
        .ws-in-ticker { font-size: 10px; color: var(--warn); letter-spacing: 0.08em; }
        .ws-inbox { display: flex; flex-direction: column; }
        .ws-inrow { display: flex; align-items: center; gap: 12px; padding: 11px 4px; border-bottom: 1px dashed rgba(255,255,255,0.06); }
        .ws-in-bullet { width: 6px; height: 6px; border-radius: 50%; background: var(--text-3); opacity: 0.4; flex-shrink: 0; }
        .ws-inrow.new .ws-in-bullet { background: var(--accent); opacity: 1; }
        .ws-inrow.overdue .ws-in-bullet { background: var(--warn); opacity: 1; }
        .ws-in-main { flex: 1; min-width: 0; }
        .ws-in-from { font-size: 12px; color: var(--text); }
        .ws-inrow.wait .ws-in-from, .ws-inrow.wait .ws-in-subj { color: var(--text-3); }
        .ws-in-subj { font-size: 12px; color: var(--text-2); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .ws-in-tag { font-size: 9px; padding: 3px 7px; border-radius: 999px; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; }
        .ws-in-tag.overdue { background: rgba(201,162,75,0.14); color: var(--warn); border: 1px solid rgba(201,162,75,0.34); }
        .ws-in-tag.wait { background: rgba(255,255,255,0.04); color: var(--text-3); border: 1px solid var(--line); }
        .ws-in-time { font-size: 10px; color: var(--text-3); width: 48px; text-align: right; }

        .ws-done { min-height: 380px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 12px; }
        .ws-done-check { width: 56px; height: 56px; border-radius: 50%; border: 1px solid var(--accent-line); display: flex; align-items: center; justify-content: center; background: rgba(79,180,119,0.08); }
        .ws-done-title { font-size: 28px; color: var(--text); }
        .ws-done-sub { font-size: 13px; color: var(--text-3); max-width: 30ch; }
        .ws-done-chip { margin-top: 8px; display: inline-flex; align-items: center; gap: 8px; font-size: 11px; color: var(--text-2); padding: 8px 14px; border: 1px solid var(--line); border-radius: 999px; }
      `}</style>
    </FrameShell>
  );
}

/* ---------- PilotDashboard: Proof flagship-client frame (Realit AG, live — figure-free) ---------- */
function PilotDashboard({ copy }) {
  const p = copy.proof;
  return (
    <FrameShell copy={copy} title="realit · support" liveLabel="live" activeNav={1} sidebar={p.realitSidebar} user={{ name: p.pilotName, role: "live" }}>
      <div className="ws-card ws-pilot">
        <div className="ws-card-head">
          <div className="ws-card-eyebrow mono"><span className="dot"></span>{p.pilotBoardTitle}</div>
          <div className="mono" style={{ fontSize: 11, color: 'var(--good)', display: 'flex', alignItems: 'center', gap: 6 }}><span className="pulse-dot" style={{ position: 'static' }}></span>live</div>
        </div>
        <ul className="ws-board">
          {p.pilotBoard.map((b) => (
            <li key={b.t}>
              <span className="ws-board-dot pulse-dot" style={{ position: 'static' }}></span>
              <span className="ws-board-t">{b.t}</span>
              <span className="ws-board-s mono">{b.s}</span>
            </li>
          ))}
        </ul>
        <div style={{ marginTop: 14 }}><Spark running trend w={360} h={48} /></div>
      </div>
      <div className="ws-pilot-foot mono">{p.pilotCaption}</div>

      <style>{`
        .ws-pilot { background: linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.005)); }
        .ws-pilot svg { width: 100%; }
        .ws-board { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-direction: column; }
        .ws-board li { display: flex; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px dashed rgba(255,255,255,0.06); }
        .ws-board li:last-child { border-bottom: none; }
        .ws-board-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px var(--good); flex-shrink: 0; }
        .ws-board-t { font-size: 13px; color: var(--text); flex: 1; }
        .ws-board-s { font-size: 10px; color: var(--good); letter-spacing: 0.08em; text-transform: uppercase; }
        .ws-pilot-foot { font-size: 10px; color: var(--text-3); letter-spacing: 0.1em; text-transform: uppercase; padding-left: 4px; }
      `}</style>
    </FrameShell>
  );
}

/* ---------- GodOSHero: the cinematic hero product (chat · business · money) ---------- */
function GodOSHero({ copy, alive = true }) {
  const g = copy.god;
  const aiText = useTyping(g.chatAI, 13, alive, 0);
  return (
    <FrameShell copy={copy} title={g.title} liveLabel={g.live} activeNav={0} sidebar={g.sidebar}>
      <div className="ws-card god-chat">
        <div className="ws-card-head">
          <div className="ws-card-eyebrow mono"><span className="dot"></span>GODOS · CHAT + STIMME</div>
          <div className="ws-card-meta mono">{g.voiceTag}</div>
        </div>
        <div className="god-chat-thread">
          <div className="god-msg user"><div className="god-bub">{g.chatUser}</div></div>
          <div className="god-msg ai">
            <div className="god-bub">
              {aiText}<span className="caret">▍</span>
              <div className="god-src mono">{g.chatSrc}</div>
            </div>
          </div>
        </div>
        <div className="god-input">
          <span className="mono">{g.voiceHint}</span>
          <span className="god-voice"><span className="god-voice-dot"></span><span className="god-voice-dot"></span><span className="god-voice-dot"></span></span>
        </div>
      </div>

      <div className="ws-grid">
        <div className="ws-card god-biz">
          <div className="ws-card-head">
            <div className="ws-card-eyebrow mono"><span className="dot"></span>{g.bizTitle}</div>
          </div>
          <ul className="god-biz-list">
            {g.bizItems.map((it) => <li key={it}><Check /> {it}</li>)}
          </ul>
          <div className="god-biz-meta mono">● {g.bizMeta}</div>
        </div>

        <div className="ws-card god-money">
          <div className="ws-card-head">
            <div className="ws-card-eyebrow mono"><span className="dot"></span>{g.moneyTitle}</div>
            <div className="mono god-cashback">{g.cashback}</div>
          </div>
          <div className="god-balance">
            <span className="ws-bignum">{g.moneyBalance}</span>
            <span className="mono god-unit">{g.moneyUnit}</span>
          </div>
          <div className="god-coin">
            <span className="god-coin-mark"></span>
            <div>
              <div className="god-coin-t">{g.coinLabel}</div>
              <div className="god-coin-s mono">{g.coinSub}</div>
            </div>
            <button className="ws-pill primary">↗</button>
          </div>
        </div>
      </div>

      <style>{`
        .god-chat { background: linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.005)); }
        .god-chat-thread { display: flex; flex-direction: column; gap: 10px; margin: 14px 0 14px; }
        .god-msg { display: flex; }
        .god-msg.user { justify-content: flex-end; }
        .god-bub { max-width: 84%; padding: 11px 14px; border-radius: 14px; font-size: 13px; line-height: 1.55; }
        .god-msg.user .god-bub { background: rgba(255,255,255,0.06); color: var(--text); border-top-right-radius: 4px; }
        .god-msg.ai .god-bub { background: rgba(0,0,0,0.35); border: 1px solid var(--line); color: var(--text-2); border-top-left-radius: 4px; min-height: 18px; }
        .god-src { display: block; margin-top: 9px; padding-top: 9px; border-top: 1px dashed rgba(255,255,255,0.08); font-size: 10px; color: var(--accent); letter-spacing: 0.04em; }
        .god-input { display: flex; align-items: center; justify-content: space-between; padding: 11px 14px; border: 1px solid var(--line); border-radius: 10px; font-size: 12px; color: var(--text-3); }
        .god-voice { display: inline-flex; align-items: flex-end; gap: 3px; height: 14px; }
        .god-voice-dot { width: 3px; background: var(--accent); border-radius: 2px; animation: godVoice 1.1s ease-in-out infinite; }
        .god-voice-dot:nth-child(1) { height: 6px; animation-delay: 0s; }
        .god-voice-dot:nth-child(2) { height: 13px; animation-delay: 0.18s; }
        .god-voice-dot:nth-child(3) { height: 9px; animation-delay: 0.36s; }
        @keyframes godVoice { 0%,100% { transform: scaleY(0.5); opacity: 0.6; } 50% { transform: scaleY(1); opacity: 1; } }
        body.no-motion .god-voice-dot { animation: none; }

        .god-biz-list { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-direction: column; gap: 9px; font-size: 12px; color: var(--text-2); }
        .god-biz-list li { display: flex; align-items: center; gap: 8px; }
        .god-biz-meta { margin-top: 14px; font-size: 10px; color: var(--accent); letter-spacing: 0.1em; text-transform: uppercase; }

        .god-money { background: linear-gradient(180deg, rgba(91,147,184,0.06), rgba(255,255,255,0.005)); }
        .god-cashback { font-size: 11px; color: var(--good); }
        .god-balance { display: flex; align-items: baseline; gap: 8px; margin-top: 12px; }
        .god-unit { font-size: 12px; color: var(--text-3); }
        .god-coin { margin-top: 16px; display: flex; align-items: center; gap: 10px; padding: 11px 12px; background: rgba(255,255,255,0.025); border: 1px dashed var(--accent-line); border-radius: 8px; }
        .god-coin-mark { width: 26px; height: 26px; border-radius: 50%; background: linear-gradient(135deg, var(--accent), #6FA8C9); flex-shrink: 0; box-shadow: 0 0 0 3px rgba(91,147,184,0.12); }
        .god-coin-t { font-size: 13px; color: var(--text); }
        .god-coin-s { font-size: 10px; color: var(--text-3); margin-top: 1px; letter-spacing: 0.04em; }
        .god-coin .ws-pill { margin-left: auto; }
      `}</style>
    </FrameShell>
  );
}

/* ---------- SystemsHero: the cinematic hero frame — shows what the SYSTEMS do
   (live graphs · automations · build/grow), not a single product ---------- */
function SystemsHero({ copy, alive = true }) {
  const s = copy.systems;
  return (
    <FrameShell copy={copy} title={s.title} liveLabel="live" activeNav={0} sidebar={s.sidebar}>
      <div className="ws-card sys-see">
        <div className="ws-card-head">
          <div className="ws-card-eyebrow mono"><span className="dot"></span>{s.seeTitle}</div>
          <div className="mono sys-live"><span className="pulse-dot" style={{ position: 'static' }}></span>live</div>
        </div>
        <div className="sys-see-sub">{s.seeSub}</div>
        <div className="sys-chart"><Spark running={alive} trend w={520} h={72} /></div>
        <div className="sys-legend">
          {s.seeTags.map((t) => <span className="sys-leg mono" key={t}><span className="sys-leg-dot"></span>{t}</span>)}
        </div>
      </div>

      <div className="ws-grid">
        <div className="ws-card sys-act">
          <div className="ws-card-head">
            <div className="ws-card-eyebrow mono"><span className="dot"></span>{s.actTitle}</div>
          </div>
          <ul className="sys-feed">
            {s.actItems.map((it, i) => (
              <li key={it} style={{ animationDelay: `${i * 0.55}s` }}>
                <span className="sys-feed-dot"></span><span className="sys-feed-t">{it}</span><Check />
              </li>
            ))}
          </ul>
          <div className="sys-act-meta mono">● {s.actMeta}</div>
        </div>

        <div className="ws-card sys-grow">
          <div className="ws-card-head">
            <div className="ws-card-eyebrow mono"><span className="dot"></span>{s.growTitle}</div>
          </div>
          <div className="sys-grow-sub">{s.growSub}</div>
          <div className="sys-chart sm"><Spark running={alive} trend w={240} h={46} /></div>
          <div className="sys-grow-foot mono">{s.growFoot}</div>
        </div>
      </div>

      <style>{`
        .sys-see { background: linear-gradient(180deg, rgba(91,147,184,0.07), rgba(255,255,255,0.005)); }
        .sys-live { font-size: 11px; color: var(--good); display: flex; align-items: center; gap: 6px; }
        .sys-see-sub { font-size: 13px; color: var(--text-2); margin-top: 8px; }
        .sys-chart { margin-top: 14px; }
        .sys-chart svg { width: 100%; height: auto; display: block; }
        .sys-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 14px; }
        .sys-leg { font-size: 10px; color: var(--text-3); display: flex; align-items: center; gap: 6px; letter-spacing: 0.04em; }
        .sys-leg-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

        .sys-feed { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-direction: column; gap: 9px; }
        .sys-feed li { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-2); animation: sysFeed 2.6s ease-in-out infinite; }
        .sys-feed-t { flex: 1; }
        .sys-feed-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px var(--good); flex-shrink: 0; }
        @keyframes sysFeed { 0%, 68%, 100% { opacity: 0.5; } 12% { opacity: 1; } }
        body.no-motion .sys-feed li { animation: none; opacity: 1; }
        .sys-act-meta { margin-top: 14px; font-size: 10px; color: var(--accent); letter-spacing: 0.1em; text-transform: uppercase; }

        .sys-grow { background: linear-gradient(180deg, rgba(79,180,119,0.06), rgba(255,255,255,0.005)); }
        .sys-grow-sub { font-size: 12px; color: var(--text-2); margin-top: 8px; }
        .sys-chart.sm { margin-top: 12px; }
        .sys-grow-foot { margin-top: 12px; font-size: 10px; color: var(--text-3); letter-spacing: 0.08em; text-transform: uppercase; }
      `}</style>
    </FrameShell>
  );
}

/* ---------- HERO: scale-then-narrate cinematic ---------- */
function Hero({ copy, motionOn = true }) {
  const h = copy.hero;
  const trackRef = useRef(null);
  const stageRef = useRef(null);
  const frameRef = useRef(null);
  const [step, setStep] = useState(0);
  const [alive, setAlive] = useState(!motionOn);

  useEffect(() => {
    if (!motionOn) { setAlive(true); setStep(0); return; }
    setAlive(false);
    const track = trackRef.current, stage = stageRef.current;
    if (!track || !stage) return;
    let raf = 0;
    let frameH = (frameRef.current && frameRef.current.offsetHeight) || 560;
    const apply = () => {
      raf = 0;
      const vh = window.innerHeight;
      const rect = track.getBoundingClientRect();
      const denom = track.offsetHeight - vh;
      const hp = denom > 0 ? clamp01(-rect.top / denom) : 0;
      const sp = smooth(hp, 0, 0.18);
      const vg = smooth(hp, 0.04, 0.22);
      const cp = smooth(hp, 0, 0.15);
      const rel = smooth(hp, 0.90, 1);
      // cap the full scale so the product fills ~80% but never taller than 72vh —
      // this guarantees a clean band at the bottom for the narrate caption.
      const fullScale = Math.max(0.7, Math.min(1, (0.76 * vh) / frameH));
      const scale = (0.62 + (fullScale - 0.62) * sp) * (1 - 0.04 * rel);
      // REST: frame top edge sits at ~80vh (peek = bottom 20vh, consistent at any height).
      // FULL: ty -> 0 (flex-centered). frameH is the measured, unscaled layout height.
      const tyRest = 0.30 * vh + 0.31 * frameH;
      const ty = tyRest * (1 - sp);
      const s = stage.style;
      s.setProperty('--hp', hp.toFixed(4));
      s.setProperty('--frame-scale', scale.toFixed(4));
      s.setProperty('--frame-ty', ty.toFixed(1) + 'px');
      s.setProperty('--vig', (vg * (1 - rel)).toFixed(4));
      s.setProperty('--copy-op', (1 - cp).toFixed(4));
      s.setProperty('--copy-y', (-44 * cp).toFixed(1) + 'px');
      s.setProperty('--copy-blur', (5 * cp).toFixed(2) + 'px');
      const st = hp < 0.22 ? 0 : hp < 0.46 ? 1 : hp < 0.70 ? 2 : 3;
      setStep(prev => prev === st ? prev : st);
      setAlive(prev => { const a = hp > 0.20; return prev === a ? prev : a; });
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(apply); };
    const onResize = () => { frameH = (frameRef.current && frameRef.current.offsetHeight) || 560; onScroll(); };
    apply();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onResize, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onResize); if (raf) cancelAnimationFrame(raf); };
  }, [motionOn]);

  return (
    <section className={`hero-track ${motionOn ? '' : 'hero-static'}`} id="top" ref={trackRef}>
      <div className="hero-stage" ref={stageRef}>
        <div className="gridfield hero-grid" aria-hidden="true">
          <i className="gl-h gl-h1"></i>
          <i className="gl-h gl-h2"></i>
          <i className="gl-v gl-v1"></i>
          <i className="gl-v gl-v2"></i>
        </div>
        <div className="hero-vignette"></div>

        <div className="hero-copy">
          <div className="hero-pill mono"><span className="hero-pill-dot"></span>{h.pill}</div>
          <h1 className="hero-h1">
            <span className="serif">{h.h1_1}</span>{' '}
            <span className="serif" style={{ fontStyle: 'italic', color: 'var(--ink-2)' }}>{h.h1_2}</span>
            <br />
            <span className="serif">{h.h1_3}</span>
          </h1>
          <p className="hero-sub">{h.sub}</p>
          <div className="hero-ctas">
            <a href="#cta" className="btn btn-primary">{h.cta1} <span className="arrow">↗</span></a>
            <a href="#vision" className="btn btn-ghost">{h.cta2}</a>
          </div>
          <div className="hero-chips">
            {h.chips.map((c) => <div className="hero-chip mono" key={c}><Dot /> {c}</div>)}
          </div>
          <div className="hero-scrollhint mono">{h.scrollHint}<span className="hero-chev">⌄</span></div>
        </div>

        <div className="hero-frame frame" data-cap={step} ref={frameRef}>
          <SystemsHero copy={copy} alive={alive} />
        </div>

        <div className="hero-captions">
          {h.captions.map((c, i) => (
            <div className={`hero-cap ${step === i + 1 ? 'on' : ''}`} key={i}>
              <div className="hero-cap-eyebrow mono">{c.eyebrow}</div>
              <div className="hero-cap-t serif">{c.t}</div>
              <div className="hero-cap-sub mono">{c.sub}</div>
            </div>
          ))}
        </div>
      </div>

      <style>{`
        /* full-bleed cinematic section: drop the global section padding (160px) that was
           pushing the sticky stage down and opening a big gap under the nav at the top */
        .hero-track { position: relative; height: 360vh; padding: 0; }
        .hero-stage { position: sticky; top: 0; height: 100vh; overflow: hidden; display: flex; align-items: center; justify-content: center; }

        /* glowing grid behind the scene — fades out as the product takes over */
        .hero-grid { opacity: var(--copy-op, 1); transition: opacity 0.2s linear; }

        .hero-vignette {
          position: absolute; inset: 0; z-index: 1; pointer-events: none;
          opacity: var(--vig, 0);
          background:
            linear-gradient(to top, rgba(20,18,15,0.62) 0, transparent 26vh),
            linear-gradient(to bottom, rgba(20,18,15,0.52) 0, transparent 18vh),
            radial-gradient(125% 120% at 50% 42%, transparent 38%, rgba(20,18,15,0.60) 100%);
        }

        .hero-copy {
          position: absolute; inset: 0 0 20vh 0; z-index: 3;
          display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
          text-align: center; padding: clamp(78px, 9vh, 116px) 40px 0;
          opacity: var(--copy-op, 1);
          transform: translateY(var(--copy-y, 0px));
          filter: blur(var(--copy-blur, 0px));
          pointer-events: none;
        }
        .hero-copy a, .hero-copy .btn { pointer-events: auto; }

        .hero-pill {
          display: inline-flex; align-items: center; gap: 8px;
          padding: 6px 14px; border: 1px solid var(--line-2); background: var(--paper-2);
          border-radius: 999px; font-size: 11px; color: var(--ink-2); letter-spacing: 0.04em;
        }
        .hero-pill-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
        .hero-h1 {
          font-family: var(--serif);
          font-size: clamp(32px, min(4.8vw, 8.5vh), 80px);
          line-height: 1.02; letter-spacing: -0.025em;
          margin: 16px auto 0; text-wrap: balance; color: var(--ink); max-width: min(96vw, 1300px);
        }
        .hero-sub { max-width: 50ch; margin: 18px auto 0; color: var(--ink-2); font-size: clamp(16px, 1.3vw, 19px); line-height: 1.5; text-wrap: pretty; }
        .hero-ctas { display: flex; gap: 12px; justify-content: center; margin-top: 26px; }
        .hero-chips { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 20px; }
        .hero-chip { display: inline-flex; align-items: center; gap: 8px; padding: 7px 13px; background: var(--paper-2); border: 1px solid var(--line); border-radius: 999px; font-size: 11px; color: var(--ink-2); }
        .hero-scrollhint { margin-top: 24px; font-size: 10px; color: var(--ink-3); letter-spacing: 0.18em; text-transform: uppercase; display: flex; align-items: center; gap: 8px; }
        .hero-chev { display: inline-block; font-size: 14px; animation: heroChev 1.8s ease-in-out infinite; }
        body.no-motion .hero-chev { animation: none; }
        @keyframes heroChev { 0%,100% { transform: translateY(-2px); opacity: 0.6; } 50% { transform: translateY(2px); opacity: 1; } }

        .hero-frame {
          position: relative; z-index: 2;
          width: min(1280px, 82vw);
          transform: translateY(var(--frame-ty, 60vh)) scale(var(--frame-scale, 0.62));
          transform-origin: center center;
          will-change: transform;
        }
        /* spotlight by subtraction — cap1=see(analyze), cap2=act(automate), cap3=grow(build) */
        .hero-frame .sys-see, .hero-frame .sys-act, .hero-frame .sys-grow { transition: opacity 0.45s, filter 0.45s, transform 0.45s, outline-color 0.45s; outline: 1px solid transparent; }
        .hero-frame[data-cap="1"] .sys-act, .hero-frame[data-cap="1"] .sys-grow,
        .hero-frame[data-cap="2"] .sys-see, .hero-frame[data-cap="2"] .sys-grow,
        .hero-frame[data-cap="3"] .sys-see, .hero-frame[data-cap="3"] .sys-act { opacity: 0.3; filter: saturate(0.5) blur(1.5px); }
        .hero-frame[data-cap="1"] .sys-see,
        .hero-frame[data-cap="2"] .sys-act,
        .hero-frame[data-cap="3"] .sys-grow { outline-color: var(--accent-line); border-radius: 12px; transform: scale(1.012); }

        .hero-captions { position: absolute; left: 0; right: 0; bottom: 7vh; z-index: 4; text-align: center; pointer-events: none; height: 6.5em; }
        .hero-cap { position: absolute; left: 0; right: 0; opacity: 0; transform: translateY(14px); transition: opacity 0.5s cubic-bezier(0.2,0.7,0.2,1), transform 0.5s cubic-bezier(0.2,0.7,0.2,1); }
        .hero-cap.on { opacity: 1; transform: none; }
        .hero-cap-eyebrow { font-size: 11px; letter-spacing: 0.18em; color: rgba(244,241,233,0.6); }
        .hero-cap-t { font-size: clamp(26px, 3.6vw, 46px); line-height: 1.05; letter-spacing: -0.02em; color: #F4F1E9; margin-top: 10px; }
        .hero-cap-sub { font-size: 12px; letter-spacing: 0.14em; color: rgba(244,241,233,0.55); margin-top: 10px; }

        /* ---------- static fallback (reduced-motion / mobile) ---------- */
        .hero-track.hero-static { height: auto; }
        .hero-static .hero-stage { position: static; height: auto; overflow: visible; display: block; padding: calc(var(--nav-h) + 72px) 0 96px; }
        .hero-static .hero-vignette, .hero-static .hero-grid { display: none; }
        .hero-static .hero-copy { position: static; inset: auto; opacity: 1; transform: none; filter: none; pointer-events: auto; margin-bottom: 56px; }
        .hero-static .hero-frame { transform: none; width: 100%; max-width: 1080px; margin: 0 auto; }
        .hero-static .hero-frame .sys-see, .hero-static .hero-frame .sys-act, .hero-static .hero-frame .sys-grow { opacity: 1; filter: none; transform: none; outline-color: transparent; }
        .hero-static .hero-captions { position: static; height: auto; display: grid; gap: 14px; margin-top: 44px; text-align: left; padding: 0 20px; }
        .hero-static .hero-cap { position: static; opacity: 1; transform: none; padding: 16px 0; border-top: 1px solid var(--line); }
        .hero-static .hero-cap-eyebrow { color: var(--ink-3); }
        .hero-static .hero-cap-t { color: var(--ink); font-size: clamp(22px, 4vw, 30px); margin-top: 6px; }
        .hero-static .hero-cap-sub { color: var(--ink-3); }

        @media (max-width: 900px) {
          .hero-h1 { font-size: clamp(40px, 11vw, 64px); }
          .hero-ctas { flex-direction: column; align-items: stretch; width: 100%; max-width: 340px; }
        }
      `}</style>
    </section>
  );
}

Object.assign(window, { Hero, GodOSHero, WorkspaceUI, FrameShell, InboxFrame, PilotDashboard, Dot, Check, useTyping, Spark, SidebarIcon, clamp01, smooth });
