// home.jsx — Constellation Home

function Home() {
  return (
    <>
      <Starfield />
      <Nav active="home" />
      <main className="c-page">
        <Hero />
        <Capabilities />
        <ReasoningTrace />
        <Providers />
        <StatusPulse />
        <WhyBother />
        <FinalCTA />
      </main>
      <Footer />
    </>
  );
}

// ──────────────────────────── Hero ────────────────────────────

function Hero() {
  return (
    <section className="home-hero-section" style={{ padding: '80px 0 100px', position: 'relative', zIndex: 2 }}>
      <div className="home-hero-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 60, alignItems: 'center' }}>
        <div>
          <div className="c-pill" style={{ marginBottom: 28 }}>
            <span className="c-dot" />
            LOCAL · AGENT · NO CLOUD REQUIRED
          </div>
          <h1 className="home-hero-title" style={{
            fontSize: 'clamp(54px, 6.4vw, 84px)',
            lineHeight: 0.96, margin: 0, fontWeight: 400, letterSpacing: '-2.5px',
          }}>
            An agent that<br/>
            thinks in<br/>
            <span style={{
              background: 'linear-gradient(110deg, var(--c-cyan), var(--c-mag))',
              WebkitBackgroundClip: 'text', backgroundClip: 'text',
              color: 'transparent', fontStyle: 'italic', fontWeight: 500,
            }}>evidence.</span>
          </h1>
          <p className="home-hero-copy" style={{ fontSize: 17, color: 'var(--c-dim)', lineHeight: 1.55, maxWidth: 480, marginTop: 28 }}>
            Delyx runs local LLMs on your machine. It plans, gathers sources,
            audits every claim, reroutes when evidence is thin, and shows you the trace.
            Confidence with a built-in eyebrow raise.
          </p>
          <div className="home-hero-actions" style={{ display: 'flex', gap: 12, marginTop: 36, flexWrap: 'wrap' }}>
            <a className="c-cta-primary" href={GITHUB_URL + '/releases'} target="_blank" rel="noreferrer">get delyx →</a>
            <a className="c-cta-secondary" href={GITHUB_URL} target="_blank" rel="noreferrer">view source</a>
          </div>
          <div className="home-command-row" style={{
            marginTop: 32, display: 'flex', gap: 22, flexWrap: 'wrap',
            fontFamily: 'var(--c-mono)', fontSize: 11.5, color: 'var(--c-mute)', letterSpacing: 1,
          }}>
            <span><span style={{ color: 'var(--c-cyan)' }}>$</span> ollama pull phi4-mini</span>
            <span style={{ opacity: 0.4 }}>·</span>
            <span><span style={{ color: 'var(--c-cyan)' }}>$</span> npm run tauri dev</span>
          </div>
        </div>
        <HeroGraph />
      </div>
    </section>
  );
}

function HeroGraph() {
  const features = [
    { label: 'plan',     a:  -90, color: 'var(--c-cyan)'  },
    { label: 'retrieve', a:  -36, color: 'var(--c-cyan)'  },
    { label: 'audit',    a:   18, color: 'var(--c-amber)' },
    { label: 'reroute',  a:   72, color: 'var(--c-mag)'   },
    { label: 'compose',  a:  126, color: 'var(--c-green)' },
    { label: 'memory',   a:  180, color: 'var(--c-cyan)'  },
    { label: 'tools',    a:  234, color: 'var(--c-cyan)'  },
    { label: 'approve',  a:  288, color: 'var(--c-green)' },
  ];
  const R = 175;
  const cx = 280, cy = 280;
  return (
    <div className="home-hero-graph" style={{ position: 'relative', height: 580 }}>
      <svg viewBox="0 0 560 560" style={{ width: '100%', height: '100%' }}>
        <defs>
          <radialGradient id="coreGlow" cx="50%" cy="50%" r="50%">
            <stop offset="0%"   stopColor="#7bd9ff" stopOpacity="0.55" />
            <stop offset="60%"  stopColor="#7bd9ff" stopOpacity="0.10" />
            <stop offset="100%" stopColor="#7bd9ff" stopOpacity="0" />
          </radialGradient>
          <filter id="glow">
            <feGaussianBlur stdDeviation="2" result="b" />
            <feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge>
          </filter>
        </defs>
        <circle cx={cx} cy={cy} r={R}      fill="none" stroke="rgba(255,255,255,0.06)" strokeDasharray="2 6" />
        <circle cx={cx} cy={cy} r={R + 60} fill="none" stroke="rgba(255,255,255,0.04)" strokeDasharray="2 8" />
        <circle cx={cx} cy={cy} r={R - 60} fill="none" stroke="rgba(255,255,255,0.04)" strokeDasharray="2 8" />
        <circle cx={cx} cy={cy} r="120" fill="url(#coreGlow)" />
        {features.map((f, i) => {
          const x = cx + R * Math.cos((f.a * Math.PI) / 180);
          const y = cy + R * Math.sin((f.a * Math.PI) / 180);
          return (
            <line key={'l' + i} x1={cx} y1={cy} x2={x} y2={y}
              stroke={f.color} strokeOpacity="0.4" strokeWidth="0.8"
              strokeDasharray="3 6"
              style={{ animation: `dashflow ${4 + i * 0.4}s linear infinite` }} />
          );
        })}
        {features.map((f, i) => {
          const x = cx + R * Math.cos((f.a * Math.PI) / 180);
          const y = cy + R * Math.sin((f.a * Math.PI) / 180);
          return (
            <g key={'n' + i} style={{ animation: `float1 ${3 + (i % 4)}s ease-in-out infinite` }}>
              <circle cx={x} cy={y} r="14" fill="var(--c-ink)" stroke={f.color} strokeOpacity="0.4" />
              <circle cx={x} cy={y} r="4" fill={f.color}
                style={{ animation: `nodepulse ${2 + (i % 3)}s ease-in-out infinite` }} />
              <text x={x} y={y + 32} textAnchor="middle"
                fill="var(--c-dim)" fontSize="10.5"
                fontFamily='"JetBrains Mono", monospace' letterSpacing="1">{f.label}</text>
            </g>
          );
        })}
        {[40, 100, 160, 220, 280, 340].map((a, i) => {
          const r = R + 75 + (i % 2) * 12;
          const x = cx + r * Math.cos((a * Math.PI) / 180);
          const y = cy + r * Math.sin((a * Math.PI) / 180);
          return (
            <circle key={'s' + i} cx={x} cy={y} r="2.5" fill="#fff" opacity="0.55"
              style={{ animation: `nodepulseSmall ${3 + i * 0.3}s ease-in-out infinite` }} />
          );
        })}
        <circle cx={cx} cy={cy} r="26" fill="var(--c-ink-2)" stroke="var(--c-cyan)" strokeOpacity="0.7" filter="url(#glow)" />
        <circle cx={cx} cy={cy} r="14" fill="var(--c-cyan)" opacity="0.8" />
        <text x={cx} y={cy + 4} textAnchor="middle"
          fill="var(--c-ink)" fontSize="11" fontWeight="700"
          fontFamily='"Space Grotesk", sans-serif' letterSpacing="1.5">DELYX</text>
      </svg>
    </div>
  );
}

// ──────────────────────────── Capabilities ────────────────────────────

function Capabilities() {
  const items = [
    { code: 'C01', title: 'model setup, in the app',
      detail: 'start with one model. split roles when you want answers, helper work, deep research, reasoning, embeddings, scoring.',
      shape: 'core' },
    { code: 'C02', title: 'local work, visible receipts',
      detail: 'file reads, imports, edits, commands, connectors, and memory saves all flow through approval.',
      shape: 'approve' },
    { code: 'C03', title: 'control center',
      detail: 'runs, approvals, connectors, sessions, automations, logs, and recent tools in one operational surface.',
      shape: 'grid' },
    { code: 'C04', title: 'local knowledge store',
      detail: 'notes, memories, imports, captured pages. sqlite + embeddings + hybrid retrieval.',
      shape: 'web' },
    { code: 'C05', title: 'evidence-audited research',
      detail: 'active retrieval, claim audits, numeric checks, coherence, reroutes, and conflict rendering.',
      shape: 'audit' },
    { code: 'C06', title: 'open, hackable stack',
      detail: 'tauri 2, react 19, rust, sqlite, ollama, /v1 providers, llama.cpp, MCP over stdio.',
      shape: 'stack' },
  ];
  return (
    <section id="capabilities" style={{ padding: '60px 0 100px', position: 'relative', zIndex: 2 }}>
      <SectionHeader code="// 01" eyebrow="capabilities" title="six tools, one console." />
      <div className="capabilities-grid" style={{
        display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 1,
        background: 'var(--c-line)',
        border: '1px solid var(--c-line)',
        borderRadius: 14, overflow: 'hidden',
      }}>
        {items.map((it, i) => <CapCell key={it.code} {...it} index={i} />)}
      </div>
    </section>
  );
}

function CapCell({ code, title, detail, shape }) {
  return (
    <div style={{
      background: 'var(--c-ink-2)',
      padding: '32px 28px',
      minHeight: 290,
      position: 'relative',
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{
        position: 'absolute', top: 18, right: 22,
        fontSize: 10, color: 'var(--c-mute)', letterSpacing: 2,
        fontFamily: 'var(--c-mono)',
      }}>{code}</div>
      <CapShape shape={shape} />
      <div style={{ fontSize: 19, lineHeight: 1.25, marginTop: 'auto', color: 'var(--c-fg)', letterSpacing: -0.3, paddingTop: 20 }}>{title}</div>
      <div style={{ fontSize: 13, color: 'var(--c-dim)', marginTop: 8, lineHeight: 1.55 }}>{detail}</div>
    </div>
  );
}

function CapShape({ shape }) {
  if (shape === 'core') {
    return (
      <svg width="120" height="120" viewBox="0 0 120 120">
        <circle cx="60" cy="60" r="30" fill="none" stroke="var(--c-cyan)" strokeOpacity="0.5" />
        <circle cx="60" cy="60" r="14" fill="var(--c-cyan)" opacity="0.9" />
        {[0, 72, 144, 216, 288].map(a => {
          const x = 60 + 50 * Math.cos((a - 90) * Math.PI / 180);
          const y = 60 + 50 * Math.sin((a - 90) * Math.PI / 180);
          return <g key={a}>
            <line x1="60" y1="60" x2={x} y2={y} stroke="var(--c-cyan)" strokeOpacity="0.3" strokeDasharray="2 3" />
            <circle cx={x} cy={y} r="3" fill="var(--c-cyan)" />
          </g>;
        })}
      </svg>
    );
  }
  if (shape === 'approve') {
    return (
      <svg width="120" height="120" viewBox="0 0 120 120">
        <rect x="20" y="20" width="80" height="80" rx="8" fill="none" stroke="var(--c-green)" strokeOpacity="0.4" />
        <path d="M 35 60 L 55 78 L 88 40" fill="none" stroke="var(--c-green)" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" />
        {[30, 45, 75].map((y, i) => (
          <line key={i} x1="30" y1={y + 22} x2={80 - i * 8} y2={y + 22} stroke="var(--c-green)" strokeOpacity="0.2" />
        ))}
      </svg>
    );
  }
  if (shape === 'grid') {
    return (
      <svg width="120" height="120" viewBox="0 0 120 120">
        {[0, 1, 2].map(r => [0, 1, 2].map(c => (
          <rect key={`${r}${c}`} x={20 + c * 30} y={20 + r * 30} width="22" height="22" rx="3"
            fill={(r + c) % 2 ? 'var(--c-amber)' : 'transparent'} fillOpacity="0.45"
            stroke="var(--c-amber)" strokeOpacity="0.4" />
        )))}
      </svg>
    );
  }
  if (shape === 'web') {
    return (
      <svg width="120" height="120" viewBox="0 0 120 120">
        {[20, 35, 50].map(r => (
          <circle key={r} cx="60" cy="60" r={r} fill="none" stroke="var(--c-mag)" strokeOpacity={0.5 - r * 0.005} />
        ))}
        {[0, 60, 120, 180, 240, 300].map(a => {
          const x = 60 + 50 * Math.cos(a * Math.PI / 180);
          const y = 60 + 50 * Math.sin(a * Math.PI / 180);
          return <line key={a} x1="60" y1="60" x2={x} y2={y} stroke="var(--c-mag)" strokeOpacity="0.25" />;
        })}
        <circle cx="60" cy="60" r="6" fill="var(--c-mag)" />
      </svg>
    );
  }
  if (shape === 'audit') {
    return (
      <svg width="120" height="120" viewBox="0 0 120 120">
        {[20, 40, 60, 80].map((y, i) => (
          <g key={i}>
            <line x1="15" y1={y} x2="105" y2={y} stroke="var(--c-amber)" strokeOpacity="0.2" strokeDasharray="2 3" />
            <circle cx={25 + i * 22} cy={y} r="4" fill={i === 2 ? 'var(--c-amber)' : 'var(--c-green)'} opacity={i === 3 ? 0.6 : 1} />
            {i === 2 && <circle cx={25 + i * 22} cy={y} r="9" fill="none" stroke="var(--c-amber)" strokeOpacity="0.5" />}
          </g>
        ))}
      </svg>
    );
  }
  if (shape === 'stack') {
    return (
      <svg width="120" height="120" viewBox="0 0 120 120">
        {[0, 1, 2, 3].map(i => (
          <rect key={i} x={20 + i * 4} y={30 + i * 12} width={80 - i * 8} height="14" rx="2"
            fill="var(--c-cyan)" fillOpacity={0.15 + i * 0.08} stroke="var(--c-cyan)" strokeOpacity="0.4" />
        ))}
      </svg>
    );
  }
  return null;
}

// ──────────────────────────── Reasoning Trace ────────────────────────────

function ReasoningTrace() {
  return (
    <section style={{ padding: '80px 0 100px', position: 'relative', zIndex: 2 }}>
      <SectionHeader code="// 02" eyebrow="reasoning trace" title="what happens between question and answer." />
      <div className="trace-grid" style={{ display: 'grid', gridTemplateColumns: '1.1fr 1fr', gap: 60, alignItems: 'center' }}>
        <TraceDiagram />
        <div>
          <div style={{ fontFamily: 'var(--c-mono)', fontSize: 11, color: 'var(--c-cyan)', letterSpacing: 2, marginBottom: 16 }}>
            ONE QUESTION · ONE TRACE
          </div>
          <h3 style={{ fontSize: 32, lineHeight: 1.15, margin: 0, fontWeight: 400, letterSpacing: -0.8 }}>
            Plan, then read.<br />
            Read, then doubt.<br />
            Doubt, then reroute.
          </h3>
          <ul style={{ listStyle: 'none', padding: 0, margin: '32px 0 0' }}>
            {[
              ['decompose', 'queries break into research, comparison, diagnostic, causal, temporal, source-triangulation subtasks.'],
              ['retrieve', 'active retrieval runs up to three evidence-aware follow-up rounds.'],
              ['audit', 'every claim gets a citation check, numeric/date support, contradiction scan.'],
              ['reroute', 'weak, empty, stale, or conflicting evidence triggers one focused reroute.'],
              ['conflict', 'when sources disagree, the conflict ships in the answer. visibly.'],
            ].map(([k, v]) => (
              <li key={k} className="trace-step" style={{
                display: 'grid', gridTemplateColumns: '110px 1fr', gap: 16,
                padding: '12px 0', borderTop: '1px solid var(--c-line)',
              }}>
                <span style={{
                  fontFamily: 'var(--c-mono)', fontSize: 11, color: 'var(--c-cyan)',
                  letterSpacing: 2, textTransform: 'uppercase', paddingTop: 3,
                }}>// {k}</span>
                <span style={{ color: 'var(--c-dim)', fontSize: 14, lineHeight: 1.55 }}>{v}</span>
              </li>
            ))}
          </ul>
        </div>
      </div>
    </section>
  );
}

function TraceDiagram() {
  const steps = [
    { x:  60, y:  40, label: 'ask',     color: 'var(--c-cyan)',  size: 18 },
    { x: 200, y:  90, label: 'plan',    color: 'var(--c-cyan)',  size: 14 },
    { x: 340, y:  60, label: 'tool',    color: 'var(--c-cyan)',  size: 12 },
    { x: 460, y: 130, label: 'sources', color: 'var(--c-cyan)',  size: 14 },
    { x: 360, y: 220, label: 'audit',   color: 'var(--c-amber)', size: 16 },
    { x: 220, y: 270, label: 'reroute', color: 'var(--c-mag)',   size: 13 },
    { x: 380, y: 350, label: 'sources', color: 'var(--c-cyan)',  size: 12 },
    { x: 500, y: 290, label: 'conflict',color: 'var(--c-amber)', size: 12 },
    { x: 280, y: 420, label: 'compose', color: 'var(--c-green)', size: 16 },
    { x: 120, y: 450, label: 'answer',  color: 'var(--c-green)', size: 20 },
  ];
  const edges = [[0,1],[1,2],[2,3],[3,4],[4,5],[5,6],[5,1],[4,7],[6,8],[7,8],[8,9]];
  return (
    <div className="trace-diagram" style={{
      background: 'linear-gradient(180deg, rgba(255,255,255,0.02), transparent)',
      border: '1px solid var(--c-line)',
      borderRadius: 14, height: 540, position: 'relative', overflow: 'hidden',
    }}>
      <svg viewBox="0 0 600 520" style={{ width: '100%', height: '100%' }}>
        <defs>
          <pattern id="gridT" width="40" height="40" patternUnits="userSpaceOnUse">
            <path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(255,255,255,0.04)" />
          </pattern>
        </defs>
        <rect width="600" height="520" fill="url(#gridT)" />
        <line x1="0" x2="600" y1="0" y2="0" stroke="var(--c-cyan)" strokeOpacity="0.15" strokeWidth="60"
          style={{ animation: 'scanline 5s linear infinite' }} />
        {edges.map(([a, b], i) => (
          <line key={i}
            x1={steps[a].x} y1={steps[a].y}
            x2={steps[b].x} y2={steps[b].y}
            stroke={steps[b].color} strokeOpacity="0.5"
            strokeDasharray="4 6" strokeWidth="1.2"
            style={{ animation: `dashflow ${3 + (i % 4)}s linear infinite` }} />
        ))}
        {steps.map((s, i) => (
          <g key={i}>
            <circle cx={s.x} cy={s.y} r={s.size + 6} fill={s.color} opacity="0.08" />
            <circle cx={s.x} cy={s.y} r={s.size} fill="var(--c-ink-2)" stroke={s.color} strokeOpacity="0.6" />
            <circle cx={s.x} cy={s.y} r="4" fill={s.color}
              style={{ animation: `nodepulse ${2 + (i % 3)}s ease-in-out infinite` }} />
            <text x={s.x} y={s.y + s.size + 16}
              textAnchor="middle" fill="var(--c-fg)" fontSize="11"
              fontFamily='"JetBrains Mono", monospace' letterSpacing="1">{s.label}</text>
          </g>
        ))}
      </svg>
    </div>
  );
}

// ──────────────────────────── Providers ────────────────────────────

function Providers() {
  const providers = [
    { name: 'ollama',       sub: 'recommended start',  a:   0 },
    { name: 'lm studio',    sub: '/v1 compatible',     a:  45 },
    { name: 'llama.cpp',    sub: 'gguf, advanced',     a:  90 },
    { name: 'vllm',         sub: '/v1 compatible',     a: 135 },
    { name: 'openrouter',   sub: 'remote',             a: 180 },
    { name: 'hugging face', sub: 'remote',             a: 225 },
    { name: 'searxng',      sub: 'optional search',    a: 270 },
    { name: 'mcp · stdio',  sub: 'optional tools',     a: 315 },
  ];
  const R = 240;
  const cx = 320, cy = 320;
  return (
    <section style={{ padding: '60px 0 100px', position: 'relative', zIndex: 2 }}>
      <SectionHeader code="// 03" eyebrow="providers" title="bring your own wires." />
      <div className="providers-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 60, alignItems: 'center' }}>
        <p style={{ fontSize: 17, color: 'var(--c-dim)', lineHeight: 1.6, maxWidth: 460 }}>
          Delyx is provider-agnostic. Ollama is the lowest-friction first step.
          After that, swap in any OpenAI-compatible <code style={{ color: 'var(--c-cyan)', fontFamily: 'var(--c-mono)' }}>/v1</code> server,
          go raw with llama.cpp + GGUF, or reach for remote APIs when you must.
          Roles are configurable per task: teacher, clerk, deep, reasoning, embed, prm.
        </p>
        <div className="providers-orbit" style={{ position: 'relative', height: 640 }}>
          <svg viewBox="0 0 640 640" style={{ width: '100%', height: '100%' }}>
            <circle cx={cx} cy={cy} r={R} fill="none" stroke="rgba(255,255,255,0.06)" strokeDasharray="3 8" />
            <circle cx={cx} cy={cy} r={R - 80} fill="none" stroke="rgba(255,255,255,0.04)" strokeDasharray="3 8" />
            <circle cx={cx} cy={cy} r="50" fill="var(--c-ink-2)" stroke="var(--c-cyan)" strokeOpacity="0.7" />
            <circle cx={cx} cy={cy} r="28" fill="var(--c-cyan)" opacity="0.85" />
            <text x={cx} y={cy + 5} textAnchor="middle" fill="var(--c-ink)" fontSize="14" fontWeight="700" letterSpacing="1.5">DELYX</text>
            {providers.map((p, i) => {
              const x = cx + R * Math.cos((p.a - 90) * Math.PI / 180);
              const y = cy + R * Math.sin((p.a - 90) * Math.PI / 180);
              return (
                <g key={p.name}>
                  <line x1={cx} y1={cy} x2={x} y2={y}
                    stroke="var(--c-cyan)" strokeOpacity="0.25" strokeDasharray="2 6"
                    style={{ animation: `dashflow ${4 + i * 0.3}s linear infinite` }} />
                  <g transform={`translate(${x},${y})`}>
                    <rect x="-65" y="-22" width="130" height="44" rx="22"
                      fill="var(--c-ink-2)" stroke="rgba(255,255,255,0.15)" />
                    <text x="0" y="-3" textAnchor="middle"
                      fill="var(--c-fg)" fontSize="13" fontWeight="500">{p.name}</text>
                    <text x="0" y="13" textAnchor="middle"
                      fill="var(--c-mute)" fontSize="10"
                      fontFamily='"JetBrains Mono", monospace' letterSpacing="0.5">{p.sub}</text>
                  </g>
                </g>
              );
            })}
          </svg>
        </div>
      </div>
    </section>
  );
}

// ──────────────────────────── Status Pulse ────────────────────────────

function StatusPulse() {
  const [liveStatus, setLiveStatus] = React.useState(null);

  React.useEffect(() => {
    let mounted = true;
    loadLatestGithubStatus()
      .then((payload) => {
        if (mounted && payload) setLiveStatus(payload);
      })
      .catch((error) => console.warn('Homepage status pulse unavailable.', error));
    return () => { mounted = false; };
  }, []);

  const items = liveStatus ? homepagePulseCards(liveStatus).map((item) => [
    item.label,
    item.value,
    item.tone,
    item.detail,
  ]) : [
    ['source sync',  'origin/main - bundled',      'amber', 'Live GitHub digest is not loaded yet.'],
    ['reasoning',    'audits live',                'green', 'Active retrieval, claim audit, reroute, and conflict rendering are in the source tree.'],
    ['release path', 'windows-first',              'amber', 'Windows release plumbing exists; public signed builds are still tracked honestly.'],
    ['mobile shell', 'responsive pass',            'green', 'The site and app shells are getting tightened for small screens.'],
    ['hyp. search',  'beam/tree pending',          'amber', 'Controlled hypothesis branching remains a known reasoning gap.'],
    ['license',      'no license file yet',        'red', 'Reuse terms are not finalized until the repo adds a license file.'],
  ];
  const statusNote = liveStatus && liveStatus.generatedAt
    ? 'updated ' + statusDate(liveStatus.generatedAt) + ' from the GitHub/OpenAI digest.'
    : 'waiting on the live digest; showing the bundled status until it answers.';
  return (
    <section style={{ padding: '60px 0 100px', position: 'relative', zIndex: 2 }}>
      <SectionHeader code="// 04" eyebrow="status pulse" title="unusually honest." />
      <div className="status-pulse-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 18 }}>
        {items.map(([k, v, c, detail]) => {
          const color = statusToneColor(c);
          return (
            <div key={k + v} className="c-card status-pulse-card" style={{ position: 'relative', overflow: 'hidden' }}>
              <div style={{
                position: 'absolute', top: 22, right: 22,
                width: 8, height: 8, borderRadius: 4, background: color,
                boxShadow: `0 0 18px ${color}`,
                animation: 'pulseGreen 1.8s infinite',
              }} />
              <div style={{ fontSize: 11, color: 'var(--c-mute)', letterSpacing: 2, fontFamily: 'var(--c-mono)' }}>{k.toUpperCase()}</div>
              <div style={{ fontSize: 21, color: 'var(--c-fg)', marginTop: 8, fontWeight: 400, letterSpacing: -0.3, lineHeight: 1.25 }}>{v}</div>
              {detail && (
                <div style={{ fontSize: 12, color: 'var(--c-dim)', lineHeight: 1.5, marginTop: 10 }}>{detail}</div>
              )}
              <Sparkline color={color} />
            </div>
          );
        })}
      </div>
      <div style={{ color: 'var(--c-mute)', marginTop: 22, fontSize: 13, fontStyle: 'italic' }}>
        - {statusNote} <a className="c-link" href="status.html">see the full status -&gt;</a>
      </div>
    </section>
  );
}

function homepagePulseCards(status) {
  const fromDigest = Array.isArray(status.homepagePulse)
    ? status.homepagePulse
        .filter((item) => item && item.label && item.value)
        .map((item) => ({
          label: item.label,
          value: item.value,
          tone: item.tone || 'green',
          detail: item.detail || '',
        }))
    : [];
  if (fromDigest.length) return fromDigest.slice(0, 6);

  const head = status.headSha ? status.headSha.slice(0, 7) : 'latest';
  return [
    {
      label: 'source sync',
      value: 'origin/main - ' + head,
      tone: 'green',
      detail: status.summary || status.headline || 'GitHub commits are checked twice daily.',
    },
    ...(Array.isArray(status.bullets) ? status.bullets.slice(0, 5).map((bullet) => ({
      label: bullet.tone === 'gap' ? 'open gap' : bullet.tone === 'tech' ? 'source note' : 'landed',
      value: shortPulseValue(bullet.text),
      tone: bullet.tone === 'gap' ? 'amber' : 'green',
      detail: bullet.text || '',
    })) : []),
  ].slice(0, 6);
}

function shortPulseValue(text) {
  const cleaned = String(text || '').replace(/\s+/g, ' ').trim();
  const first = cleaned.split(/[.!?]/)[0] || cleaned;
  if (!first) return 'status item';
  if (first.length <= 58) return first;
  return (first.slice(0, 58).replace(/\s+\S*$/, '') || first.slice(0, 58)) + '...';
}

function Sparkline({ color }) {
  const pts = React.useMemo(() => {
    const seeds = [3, 5, 4, 7, 6, 8, 5, 9, 7, 10, 8, 11];
    return seeds.map((v, i) => `${i * 22},${30 - v * 1.6}`).join(' ');
  }, []);
  return (
    <svg viewBox="0 0 240 36" style={{ width: '100%', height: 36, marginTop: 18 }}>
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5" strokeOpacity="0.85" />
      <polyline points={pts} fill="none" stroke={color} strokeWidth="6" strokeOpacity="0.18" />
    </svg>
  );
}

// ──────────────────────────── Why bother ────────────────────────────

function WhyBother() {
  return (
    <section style={{ padding: '60px 0 100px', position: 'relative', zIndex: 2 }}>
      <SectionHeader code="// 05" eyebrow="why bother" title="local AI should feel usable." />
      <div className="c-grid-2">
        <div className="c-card">
          <div style={{ fontFamily: 'var(--c-mono)', fontSize: 11, color: 'var(--c-cyan)', letterSpacing: 2, marginBottom: 10 }}>
            // BEGINNER PATH
          </div>
          <h4 style={{ fontSize: 22, margin: 0, fontWeight: 500, letterSpacing: -0.3 }}>simple mode keeps the first run short.</h4>
          <p style={{ color: 'var(--c-dim)', fontSize: 14, lineHeight: 1.6, marginTop: 12 }}>
            Open-source agent projects can be powerful and still feel like a box of parts.
            Delyx moves setup, safety checks, context, evidence, and model plumbing into an app
            where normal humans can actually find them.
          </p>
        </div>
        <div className="c-card">
          <div style={{ fontFamily: 'var(--c-mono)', fontSize: 11, color: 'var(--c-mag)', letterSpacing: 2, marginBottom: 10 }}>
            // EXPERT HATCH
          </div>
          <h4 style={{ fontSize: 22, margin: 0, fontWeight: 500, letterSpacing: -0.3 }}>knobs for the kind of person who asks how many.</h4>
          <p style={{ color: 'var(--c-dim)', fontSize: 14, lineHeight: 1.6, marginTop: 12 }}>
            Expert mode opens up model roles, evals, diagnostics, reranking, worker agents,
            release-repair checks, and other knobs for advanced operators. The floorboards open.
          </p>
        </div>
      </div>
    </section>
  );
}

// ──────────────────────────── Final CTA ────────────────────────────

function FinalCTA() {
  return (
    <section style={{ padding: '40px 0 80px', position: 'relative', zIndex: 2, textAlign: 'center' }}>
      <div style={{
        position: 'relative',
        background: 'radial-gradient(ellipse 900px 500px at 50% 0%, rgba(123,217,255,0.18), transparent 70%)',
        padding: '90px 40px 70px',
        borderRadius: 24, overflow: 'hidden',
        border: '1px solid var(--c-line)',
      }}>
        <StarMark size={40} />
        <h2 style={{
          fontSize: 'clamp(40px, 5vw, 64px)', fontWeight: 400, letterSpacing: -2,
          margin: '20px 0 18px', lineHeight: 1,
        }}>
          point the agent<br/><em style={{ color: 'var(--c-cyan)', fontStyle: 'italic', fontWeight: 500 }}>inward.</em>
        </h2>
        <p style={{ color: 'var(--c-dim)', fontSize: 16.5, maxWidth: 540, margin: '0 auto', lineHeight: 1.55 }}>
          Run the signed Windows release when available, or clone the source.
          Pick Ollama, pull phi4-mini, send one small prompt.
        </p>
        <div style={{ display: 'flex', gap: 12, justifyContent: 'center', marginTop: 32, flexWrap: 'wrap' }}>
          <a className="c-cta-primary" href={GITHUB_URL + '/releases'} target="_blank" rel="noreferrer">get delyx →</a>
          <a className="c-cta-secondary" href="docs.html">read the docs</a>
        </div>
      </div>
    </section>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<Home />);
