// classic-pages.jsx — site content rendered as DelyxOS windows
// Sources: home.jsx, docs.jsx, changelog.jsx, contact.jsx, get.jsx from delyx-site

const GITHUB_URL = 'https://github.com/joshua-ivy/Delyx';
const ISSUE_URL = 'https://github.com/joshua-ivy/Delyx/issues/new';

// ────────── Shared bits ──────────

function CPChev({ children, color = 'var(--cyan)' }) {
  return <span><span style={{ color, marginRight: 10, fontWeight: 600 }}>&gt;</span>{children}</span>;
}

function CPLabel({ children, id }) {
  return (
    <div style={{ fontSize: 11, color: 'var(--dim)', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 18 }}>
      <CPChev>{children}</CPChev>
      {id && <span style={{ color: 'var(--dimmer)', marginLeft: 8 }}>./{id}</span>}
    </div>
  );
}

function CPCode({ title, children }) {
  return (
    <div style={{
      background: '#06080b',
      border: '1px solid var(--line)',
      borderRadius: 8,
      overflow: 'hidden',
      margin: '8px 0',
    }}>
      <div style={{
        padding: '8px 12px', borderBottom: '1px solid var(--line)',
        display: 'flex', alignItems: 'center', gap: 6,
        fontSize: 10, color: 'var(--dim)',
      }}>
        <span style={{ width: 7, height: 7, borderRadius: 4, background: '#3a3f48' }} />
        <span style={{ width: 7, height: 7, borderRadius: 4, background: '#3a3f48' }} />
        <span style={{ width: 7, height: 7, borderRadius: 4, background: '#3a3f48' }} />
        {title && <span style={{ marginLeft: 10 }}>{title}</span>}
      </div>
      <pre style={{
        margin: 0, padding: '12px 14px', fontSize: 11, lineHeight: 1.7,
        fontFamily: 'var(--mono)', color: 'var(--fg)', whiteSpace: 'pre-wrap',
      }}>{children}</pre>
    </div>
  );
}

function CPIC({ children }) {
  return (
    <code style={{
      fontFamily: 'var(--mono)', fontSize: '0.92em',
      background: 'rgba(95,212,255,0.08)',
      color: 'var(--cyan)',
      padding: '1px 5px', borderRadius: 3,
      border: '1px solid var(--line)',
    }}>{children}</code>
  );
}

function CPCallout({ kind = 'note', children }) {
  const palette = {
    note: { c: 'var(--cyan)', label: 'note' },
    warn: { c: 'var(--warn)', label: 'heads up' },
    bad: { c: 'var(--bad)', label: 'careful' },
  }[kind];
  return (
    <div style={{
      margin: '12px 0', padding: '10px 14px',
      background: 'rgba(255,255,255,0.02)',
      border: '1px solid var(--line)',
      borderLeft: '3px solid ' + palette.c,
      borderRadius: 6,
      fontSize: 12, color: 'var(--fg-soft)', lineHeight: 1.6,
    }}>
      <span style={{ color: palette.c, fontSize: 10, letterSpacing: 1, textTransform: 'uppercase', marginRight: 8 }}>&gt; {palette.label}</span>
      {children}
    </div>
  );
}

// ────────── HOME ──────────

function ClassicHome() {
  return (
    <div style={cpPageStyle()}>
      <section style={{ padding: '24px 28px 4px' }}>
        <CPLabel>a local-first desktop AI agent</CPLabel>
        <h1 style={{
          fontFamily: 'var(--mono)', fontSize: 44, lineHeight: 1.02,
          margin: 0, fontWeight: 500, color: 'var(--fg)',
          letterSpacing: -0.5,
        }}>
          Local LLMs<br/>
          made easy. <span style={{ color: 'var(--dim)', fontStyle: 'italic' }}>Maybe.</span>
        </h1>
        <p style={{ fontSize: 13, color: 'var(--dim)', maxWidth: 560, marginTop: 18, lineHeight: 1.65 }}>
          Delyx is a desktop agent for people who want local models to feel practical: chat, knowledge, workspaces, evidence-audited research, tool previews, model setup, and a control center in one place. Less weekend wiring. More "wait, that actually helped."
        </p>

        <CPCode title="~ / GitHub source install">
          <span style={{ color: 'var(--dim)' }}># signed Windows release when available; source path for dev builds</span>{'\n'}
          <span style={{ color: 'var(--cyan)' }}>$</span> git clone https://github.com/joshua-ivy/Delyx.git{'\n'}
          <span style={{ color: 'var(--cyan)' }}>$</span> cd Delyx{'\n'}
          <span style={{ color: 'var(--cyan)' }}>$</span> npm install{'\n'}
          <span style={{ color: 'var(--cyan)' }}>$</span> ollama pull phi4-mini{'\n'}
          <span style={{ color: 'var(--cyan)' }}>$</span> npm run tauri dev{'\n'}
          {'\n'}
          <span style={{ color: 'var(--dim)' }}># in Delyx: choose Ollama -&gt; phi4-mini -&gt; Save and test</span>
        </CPCode>

        <div style={{ display: 'flex', gap: 10, marginTop: 16, alignItems: 'center' }}>
          <a href={GITHUB_URL + '/releases'} target="_blank" rel="noreferrer" style={ctaPrimary()}>get delyx <span>-&gt;</span></a>
          <a href={GITHUB_URL} target="_blank" rel="noreferrer" style={ctaSecondary()}>view source -&gt;</a>
        </div>
      </section>

      <section style={{ padding: '32px 28px 4px' }}>
        <CPLabel id="capabilities">what it does</CPLabel>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', border: '1px solid var(--line)', borderRadius: 8, overflow: 'hidden' }}>
          {[
            ['model setup in the app', 'start with one model, then split roles later for answers, helper work, deep research, max reasoning, embeddings, and scoring.'],
            ['local work with receipts', 'file reads, imports, workspace access, memory saves, edits, commands, connectors, and recurring work use visible approval flows.'],
            ['control center', 'runs, approvals, connectors, session details, automations, logs, and current status live in one operational surface.'],
            ['local knowledge store', 'save notes, memories, imported files, and captured web pages; search them with SQLite, embeddings, and hybrid retrieval.'],
            ['evidence-audited research', 'active retrieval, claim support checks, numeric/date support, coherence checks, reroutes, and conflict rendering.'],
            ['open, hackable stack', 'Tauri 2, React 19, TypeScript, Rust, SQLite, Ollama APIs, /v1 providers, optional llama.cpp, updater wiring, and MCP over stdio.'],
          ].map(([t, d], i) => (
            <div key={i} style={{
              padding: '14px 14px',
              borderRight: (i % 3 !== 2) ? '1px solid var(--line)' : 'none',
              borderBottom: (i < 3) ? '1px solid var(--line)' : 'none',
              background: 'rgba(255,255,255,0.01)',
            }}>
              <div style={{ color: 'var(--cyan)', fontSize: 10, marginBottom: 8, letterSpacing: 1 }}>0{i + 1}</div>
              <div style={{ fontSize: 12, color: 'var(--fg)', marginBottom: 4 }}>{t}</div>
              <div style={{ fontSize: 11, color: 'var(--dim)', lineHeight: 1.55 }}>{d}</div>
            </div>
          ))}
        </div>
      </section>

      <section style={{ padding: '28px 28px 4px' }}>
        <CPLabel id="status">what's actually true</CPLabel>
        <div style={{ border: '1px solid var(--line)', borderRadius: 8, background: 'rgba(255,255,255,0.01)' }}>
          {[
            ['ok', 'runs from source with Node.js, Rust, and a model provider'],
            ['ok', 'Windows is the primary tested platform right now'],
            ['ok', 'signed Windows installer/updater packaging is configured for public releases'],
            ['ok', 'Ollama is the lowest-friction first model path'],
            ['ok', 'OpenAI-compatible /v1 providers are supported, including LM Studio-style servers'],
            ['ok', 'active retrieval, claim audits, coherence checks, and conflict rendering exist in the source'],
            ['ok', 'Control Center and responsive shell surfaces are in the app'],
            ['eh', 'macOS and Linux should be possible through Tauri, but they are less exercised today'],
            ['eh', 'heavier local stacks need more VRAM, patience, or both'],
            ['eh', 'beam/tree hypothesis search is still the big reasoning gap'],
            ['eh', 'advanced systems like reranking, worker agents, reasoning budgets, verifier-led composition, and PRM scoring are experimental or opt-in'],
            ['no', 'no license file yet, so reuse rules are not finalized'],
          ].map(([s, t], i) => {
            const color = s === 'ok' ? 'var(--cyan)' : s === 'eh' ? 'var(--warn)' : 'var(--bad)';
            const label = s === 'ok' ? 'ok' : s === 'eh' ? '~ depends' : 'not yet';
            const bg = s === 'ok' ? 'rgba(95,212,255,0.10)' : s === 'eh' ? 'rgba(255,200,80,0.10)' : 'rgba(255,120,120,0.10)';
            return (
              <div key={i} style={{
                display: 'grid', gridTemplateColumns: '108px 1fr',
                padding: '9px 16px',
                borderTop: i ? '1px solid var(--line-soft)' : 'none',
                alignItems: 'center',
              }}>
                <span style={{
                  fontSize: 10, fontWeight: 600, padding: '2px 7px', borderRadius: 3,
                  width: 'fit-content', background: bg, color, letterSpacing: 1, textTransform: 'uppercase',
                }}>{label}</span>
                <span style={{ fontSize: 12, color: s === 'no' ? 'var(--dim)' : 'var(--fg-soft)' }}>{t}</span>
              </div>
            );
          })}
        </div>
        <div style={{ color: 'var(--dim)', fontSize: 11, marginTop: 10, fontStyle: 'italic' }}>
          unusually honest for a homepage, yes. the product is moving fast, and the source is still the map.
        </div>
      </section>

      <section style={{ padding: '28px 28px 4px' }}>
        <CPLabel id="works-with">works with</CPLabel>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
          {[
            ['ollama', 'recommended start'],
            ['lm studio', 'OpenAI-compatible'],
            ['llama.cpp / gguf', 'advanced local path'],
            ['vllm', '/v1 compatible'],
            ['openrouter', 'remote provider'],
            ['hugging face', 'remote provider'],
            ['searxng', 'optional search'],
            ['mcp', 'stdio servers'],
          ].map(([n, s]) => (
            <div key={n} style={{
              padding: '10px 14px', border: '1px solid var(--line)', borderRadius: 6,
              background: 'rgba(255,255,255,0.02)',
            }}>
              <div style={{ fontSize: 12, color: 'var(--fg)' }}>
                <span style={{ color: 'var(--cyan)', marginRight: 6 }}>&gt;</span>{n}
              </div>
              <div style={{ fontSize: 10, color: 'var(--dim)', paddingLeft: 14, marginTop: 2 }}>{s}</div>
            </div>
          ))}
        </div>
      </section>

      <section style={{ padding: '28px 28px 4px' }}>
        <CPLabel id="why">why bother</CPLabel>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <div style={whyCard()}>
            <div style={{ fontSize: 12, color: 'var(--cyan)', marginBottom: 8 }}><CPChev>local AI should feel usable</CPChev></div>
            <p style={{ fontSize: 12, color: 'var(--fg-soft)', lineHeight: 1.65, margin: 0 }}>
              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 style={whyCard()}>
            <div style={{ fontSize: 12, color: 'var(--cyan)', marginBottom: 8 }}><CPChev>beginner path, expert hatch</CPChev></div>
            <p style={{ fontSize: 12, color: 'var(--fg-soft)', lineHeight: 1.65, margin: 0 }}>
              Simple mode keeps the first run short. Expert mode opens up model roles, evals, diagnostics, reranking, worker agents, release repair checks, and other knobs for the kind of person who hears "knob" and immediately asks how many.
            </p>
          </div>
        </div>
      </section>

      <section style={{ padding: '32px 28px 28px' }}>
        <div style={{
          border: '1px solid var(--line)', borderRadius: 10, padding: '24px 24px',
          background: 'linear-gradient(180deg, rgba(95,212,255,0.05), transparent 70%)',
          textAlign: 'center',
        }}>
          <div style={{ fontSize: 11, color: 'var(--cyan)', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 10 }}>
            <CPChev>last thing</CPChev>
          </div>
          <h2 style={{ fontFamily: 'var(--mono)', fontSize: 28, margin: 0, fontWeight: 500, lineHeight: 1.1, color: 'var(--fg)' }}>
            make local AI practical.
          </h2>
          <p style={{ fontSize: 12, color: 'var(--dim)', marginTop: 10, maxWidth: 480, marginInline: 'auto', lineHeight: 1.6 }}>
            Use the signed Windows release when available, or clone it and run from source. Choose Ollama, pick <CPIC>phi4-mini</CPIC>, and start with one small useful prompt.
          </p>
          <div style={{ display: 'flex', gap: 10, marginTop: 16, justifyContent: 'center' }}>
            <a href={GITHUB_URL + '/releases'} target="_blank" rel="noreferrer" style={ctaPrimary()}>get delyx -&gt;</a>
            <a href={GITHUB_URL + '#readme'} target="_blank" rel="noreferrer" style={ctaSecondary()}>read the docs</a>
          </div>
        </div>
      </section>
    </div>
  );
}

function whyCard() {
  return {
    padding: '14px 16px', border: '1px solid var(--line)', borderRadius: 6,
    background: 'rgba(255,255,255,0.01)',
  };
}

// ────────── DOCS ──────────

const DOC_SECTIONS = [
  { group: 'start', items: [
    ['quickstart', 'quickstart'],
    ['requirements', 'requirements'],
    ['first-run', 'first run'],
    ['release-builds', 'release builds'],
  ]},
  { group: 'app', items: [
    ['models', 'models'],
    ['control-center', 'control center'],
    ['knowledge', 'knowledge'],
    ['workspaces', 'workspaces'],
    ['research', 'research'],
    ['evals', 'evals'],
  ]},
  { group: 'reference', items: [
    ['privacy', 'privacy + data'],
    ['commands', 'commands'],
    ['troubleshooting', 'troubleshooting'],
    ['faq', 'faq'],
  ]},
];

function ClassicDocs() {
  const [active, setActive] = React.useState('quickstart');
  const mainRef = React.useRef(null);

  const jump = (id) => {
    setActive(id);
    const el = mainRef.current?.querySelector('#docsec-' + id);
    if (el && mainRef.current) mainRef.current.scrollTo({ top: el.offsetTop - 16, behavior: 'smooth' });
  };

  React.useEffect(() => {
    const main = mainRef.current;
    if (!main) return;
    const onScroll = () => {
      const sections = main.querySelectorAll('[data-docsec]');
      let cur = 'quickstart';
      sections.forEach((el) => {
        if (el.getBoundingClientRect().top - main.getBoundingClientRect().top < 80) cur = el.id.replace('docsec-', '');
      });
      setActive(cur);
    };
    main.addEventListener('scroll', onScroll);
    return () => main.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <div style={{ height: '100%', display: 'flex', background: 'var(--ink-soft)', color: 'var(--fg)', fontFamily: 'var(--mono)' }}>
      <aside style={{ width: 196, flex: '0 0 196px', borderRight: '1px solid var(--line)', padding: 14, overflowY: 'auto', fontSize: 12 }}>
        <div style={{ fontSize: 10, color: 'var(--dimmer)', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 12 }}>
          <CPChev>docs · v0.1.0</CPChev>
        </div>
        {DOC_SECTIONS.map((g) => (
          <div key={g.group} style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 10, color: 'var(--dim)', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 4, paddingLeft: 8 }}>{g.group}</div>
            {g.items.map(([id, label]) => (
              <button key={id} onClick={() => jump(id)} style={{
                display: 'block', width: '100%', textAlign: 'left',
                padding: '4px 10px', cursor: 'pointer',
                fontSize: 12, color: active === id ? 'var(--fg)' : 'var(--dim)',
                background: active === id ? 'rgba(95,212,255,0.06)' : 'transparent',
                borderLeft: '2px solid ' + (active === id ? 'var(--cyan)' : 'transparent'),
                border: 'none', borderLeftWidth: 2, borderLeftStyle: 'solid',
                borderLeftColor: active === id ? 'var(--cyan)' : 'transparent',
                fontFamily: 'var(--mono)',
              }}>{label}</button>
            ))}
          </div>
        ))}
        <div style={{ marginTop: 18, padding: 10, border: '1px solid var(--line)', borderRadius: 6, fontSize: 11 }}>
          <div style={{ color: 'var(--fg)', marginBottom: 3 }}>found a sharp edge?</div>
          <div style={{ color: 'var(--dim)', lineHeight: 1.5 }}>open an <a href={ISSUE_URL} target="_blank" rel="noreferrer" style={{ color: 'var(--cyan)' }}>issue on GitHub</a> with the exact error.</div>
        </div>
      </aside>

      <main ref={mainRef} style={{ flex: 1, overflowY: 'auto', padding: '20px 28px' }}>
        <div style={{ fontSize: 11, color: 'var(--dim)', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 12 }}>
          <CPChev>./docs</CPChev>
        </div>
        <h1 style={{ fontFamily: 'var(--mono)', fontSize: 32, fontWeight: 500, margin: '0 0 8px', color: 'var(--fg)', letterSpacing: 0, lineHeight: 1.1 }}>
          documentation
        </h1>
        <p style={{ fontSize: 12, color: 'var(--dim)', maxWidth: 600, lineHeight: 1.6, margin: '0 0 20px' }}>
          The practical path through Delyx: install or run from source, connect a model, keep local actions reviewable, and let evidence earn its chair at the table.
        </p>

        <DocSec id="quickstart" title="quickstart" subtitle="two paths: signed Windows release when available, source when developing.">
          <p>Delyx is source-alpha software with Windows as the primary tested platform. Signed Windows release packaging is configured, but source runs remain the development path between public release builds.</p>
          <DocH3>normal Windows install</DocH3>
          <ol style={dsList()}>
            <li>Open the latest GitHub release when a signed public build is available.</li>
            <li>Install Delyx and launch the desktop app.</li>
            <li>Choose <CPIC>Ollama</CPIC>, select <CPIC>phi4-mini</CPIC>, then click <CPIC>Save and test</CPIC>.</li>
            <li>Start with a small prompt before attaching folders or enabling advanced features.</li>
          </ol>
          <DocH3>developer source path</DocH3>
          <CPCode title="terminal · source install">
            <span style={{ color: 'var(--dim)' }}># prerequisites: Git, Node.js 20.19+/22.12+, Rust stable, Tauri OS prereqs, Ollama</span>{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> git clone https://github.com/joshua-ivy/Delyx.git{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> cd Delyx{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> npm install{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> ollama pull phi4-mini{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> npm run tauri dev
          </CPCode>
          <CPCallout kind="note">
            The first desktop launch compiles the Rust backend. If it takes a few minutes, congratulations: the machine is doing the heavy lifting instead of hiding it.
          </CPCallout>
        </DocSec>

        <DocSec id="requirements" title="requirements" subtitle="small list, real dependencies.">
          <ul style={dsList()}>
            <li><CPIC>Git</CPIC> for cloning <CPIC>https://github.com/joshua-ivy/Delyx.git</CPIC>.</li>
            <li><CPIC>Node.js 20.19+</CPIC> or <CPIC>Node.js 22.12+</CPIC>.</li>
            <li><CPIC>npm</CPIC>, normally installed with Node.js.</li>
            <li><CPIC>Rust stable</CPIC> with <CPIC>cargo</CPIC>, because Tauri builds the desktop shell and Rust backend.</li>
            <li>The platform prerequisites for Tauri 2.</li>
            <li>One model provider. Recommended first-run: local Ollama with <CPIC>phi4-mini</CPIC>.</li>
          </ul>
          <CPCallout kind="warn">
            Ollama is the easy button, not a prison. Delyx can also use LM Studio, llama.cpp/GGUF, vLLM, OpenRouter, Hugging Face, or any OpenAI-compatible <CPIC>/v1</CPIC> provider.
          </CPCallout>
        </DocSec>

        <DocSec id="first-run" title="first run" subtitle="the short path once the window opens.">
          <ol style={dsList()}>
            <li>Choose <CPIC>Ollama</CPIC> when setup asks for a provider.</li>
            <li>Pick <CPIC>phi4-mini</CPIC>, or any Ollama model you already have.</li>
            <li>Click <CPIC>Save and test</CPIC>. Delyx stores explicit role assignments for answer and helper work.</li>
            <li>Send a small prompt.</li>
            <li>Only after that, add stronger models, remote providers, workspaces, or advanced role splits.</li>
          </ol>
        </DocSec>

        <DocSec id="release-builds" title="release builds" subtitle="signed Windows packaging exists; source remains the dev path.">
          <DocTable rows={[
            ['npm run tauri:build:windows', 'Builds Windows installer/updater artifacts through scripts/build-windows.ps1.'],
            ['scripts/sign-windows.ps1', 'Signs artifacts when certificate secrets are available.'],
            ['.github/workflows/release-windows.yml', 'Builds signed Windows installers in GitHub Actions and publishes draft release artifacts.'],
            ['scripts/release-smoke-windows.ps1', 'Verifies installer signatures and launch behavior.'],
            ['Settings · Repair', 'Can check signed update status when build includes updater public key + endpoint metadata.'],
          ]} />
          <CPCallout kind="warn">
            Source builds can report update checks as not configured. That's expected unless <CPIC>DELYX_UPDATER_PUBLIC_KEY</CPIC> and <CPIC>DELYX_UPDATER_ENDPOINT</CPIC> were embedded at build time.
          </CPCallout>
        </DocSec>

        <DocSec id="models" title="models" subtitle="one simple start, many paths after that.">
          <p>Delyx can start with one model for the whole agent, then split work across runtime roles when you want more control.</p>
          <DocTable rows={[
            ['Ollama', 'Recommended first-run path. Pull phi4-mini, choose Ollama, save and test.'],
            ['LM Studio / any /v1', 'Start the server, enter /v1 base URL, add a key if needed, pick a discovered model.'],
            ['llama.cpp / GGUF', 'Advanced local path. Default local answer endpoint: http://127.0.0.1:8080/v1.'],
            ['Remote providers', 'OpenRouter, Hugging Face, vLLM, etc. saved as OpenAI-compatible providers.'],
          ]} />
          <DocH3>runtime role ids</DocH3>
          <DocTable rows={[
            ['teacher', 'Main answer model for normal chat and final composition.'],
            ['clerk', 'Helper model for routing, summaries, labels, critique, small jobs.'],
            ['teacher-deep', 'Deep Research model for longer reading and synthesis.'],
            ['teacher-reasoning', 'Max reasoning model for harder Deep Research runs.'],
            ['embed', 'Embedding model for local semantic search.'],
            ['prm', 'Optional scoring/reranking for advanced quality gates.'],
          ]} />
          <CPCode title="useful Ollama pulls">
            <span style={{ color: 'var(--cyan)' }}>$</span> ollama pull phi4-mini{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> ollama pull embeddinggemma{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> ollama pull gpt-oss-20b{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> ollama pull phi4-reasoning:14b
          </CPCode>
        </DocSec>

        <DocSec id="control-center" title="control center" subtitle="runs, approvals, connectors, sessions, automations, and logs.">
          <p>The desktop app centralizes operational surfaces in Control Center. Be useful without making you chase state across five corners.</p>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 8 }}>
            {[
              ['overview', 'Runtime, approvals, active runs, connectors, sources, failures, recent tools, current status.'],
              ['approvals', 'Pending, approved, executed, denied actions with payload previews.'],
              ['automations', 'Now, Upcoming, History, Failed, Paused views with pause/cancel.'],
              ['responsive shell', 'Mobile drawer, bottom nav, desktop rail collapse, Now status surface.'],
            ].map(([name, d]) => (
              <div key={name} style={{ padding: '10px 12px', border: '1px solid var(--line)', borderRadius: 6, background: 'rgba(255,255,255,0.02)' }}>
                <div style={{ color: 'var(--cyan)', fontSize: 12 }}>{name}</div>
                <div style={{ color: 'var(--dim)', fontSize: 11, marginTop: 3, lineHeight: 1.5 }}>{d}</div>
              </div>
            ))}
          </div>
        </DocSec>

        <DocSec id="knowledge" title="knowledge" subtitle="local context that waits for permission.">
          <p>Delyx can save notes, memories, imported files, and captured web pages as local knowledge. It can build a searchable local knowledge store using SQLite, embeddings, and hybrid retrieval.</p>
          <CPCallout kind="note">
            Durable memory is for stable facts and preferences. Temporary test instructions should stay temporary; the eval suite checks for this because accidental memory is where things get awkward.
          </CPCallout>
        </DocSec>

        <DocSec id="workspaces" title="workspaces" subtitle="approved folders, visible actions.">
          <p>Attach local folders as workspaces. Delyx can read files, summarize folders, index folders, preview file edits, write files, and run terminal commands through approval flows.</p>
          <DocTable rows={[
            ['file reads', 'Used for local context and summaries inside approved workspaces.'],
            ['file edits', 'Previewed before writing; edits can create checkpoints.'],
            ['terminal commands', 'Routed through approval flows.'],
            ['checkpoints', 'Can be restored from the same control surface after risky work.'],
          ]} />
        </DocSec>

        <DocSec id="research" title="research" subtitle="grounded answers with evidence audits.">
          <p>As of May 16, 2026, Delyx has source-backed research, active retrieval, query decomposition, claim audits, global coherence checks, focused post-evidence reroutes, and user-visible conflict rendering.</p>
          <ul style={dsList()}>
            <li>Active retrieval can run up to three evidence-aware rounds.</li>
            <li>Query decomposition supports general, comparison, diagnostic, causal, temporal, and source-triangulation subtasks.</li>
            <li>Claim audit checks citation support, evidence IDs, numeric/date support, contradictions.</li>
            <li>Weak, empty, stale, near-match, missing-field, or conflicting evidence can trigger a focused reroute.</li>
            <li>The current architecture tracker is <CPIC>docs/REASONING_GAPS_ARCHITECTURE.md</CPIC>.</li>
          </ul>
          <CPCallout kind="warn">
            The big remaining reasoning gap is controlled hypothesis search. ReAct still follows one dominant path unless rescue/reroute logic fires.
          </CPCallout>
        </DocSec>

        <DocSec id="evals" title="evals" subtitle="the scoreboard got teeth. tiny, polite teeth.">
          <p>The eval harness now covers more than phrase matching. Semantic assertions, numeric tolerances, ranked items, citation support, contradiction expectations, trace markers, opt-in LLM judge rubrics.</p>
          <CPCode title="eval and smoke commands">
            <span style={{ color: 'var(--cyan)' }}>$</span> npm run eval:response{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> npm run eval:sports-fixtures{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> npm run smoke:responsive{'\n'}
            <span style={{ color: 'var(--cyan)' }}>$</span> npm test
          </CPCode>
        </DocSec>

        <DocSec id="privacy" title="privacy + data" subtitle="where the bits live and when they leave.">
          <p>Delyx stores app state locally through Tauri's app data directory. Active app id:</p>
          <CPCode title="app identifier">com.geaux.delyx</CPCode>
          <p>The main local database is <CPIC>&lt;app-data&gt;/workspace/state.sqlite3</CPIC>. Local provider secrets are written outside the repo.</p>
          <DocTable rows={[
            ['workspace/state.sqlite3', 'Conversations, turns, workspaces, knowledge rows, approvals, tools, feedback, skills, MCP servers, indexes.'],
            ['workspace/artifacts', 'Copied imported files and app-managed artifacts.'],
            ['workspace/delyx/skills', 'Promoted local skills as SKILL.md files.'],
            ['scratchpad/*.jsonl', 'Per-day process traces for diagnostics and possible distillation.'],
            ['%LOCALAPPDATA%\\Delyx\\local_config.json', 'Windows local provider config and secrets outside the repo.'],
          ]} />
          <CPCallout kind="note">
            Delyx does not require an inbound gateway daemon for normal use. Optional remote providers, web search, connectors, and update checks can still use network egress when configured.
          </CPCallout>
        </DocSec>

        <DocSec id="commands" title="commands" subtitle="repo commands you'll actually run.">
          <DocTable rows={[
            ['npm run tauri dev', 'run the desktop app in dev mode'],
            ['npm run dev', 'Vite frontend only; UI work, not the full agent'],
            ['npm run build', 'typecheck and build the frontend'],
            ['npm run tauri build', 'build a desktop bundle'],
            ['npm run tauri:build:windows', 'build Windows installer/updater artifacts'],
            ['npm run typecheck', 'TypeScript only'],
            ['npm test', 'frontend tests + llama.cpp config tests'],
            ['npm run smoke:responsive', 'viewport smoke test for desktop/tablet/mobile'],
            ['npm run smoke:llamacpp', 'local llama.cpp smoke script'],
            ['npm run smoke:tauri', 'Tauri driver smoke script'],
            ['npm run probe:codex-llamacpp', 'probe the local llama.cpp Codex-compatible endpoint'],
          ]} />
        </DocSec>

        <DocSec id="troubleshooting" title="troubleshooting" subtitle="normal problems, non-dramatic fixes.">
          {[
            ['The first desktop run is slow', 'Expected: Tauri compiles the Rust backend the first time. Later runs are faster.'],
            ['Only the web UI opens', 'You probably ran npm run dev. Use npm run tauri dev for the desktop app.'],
            ['Ollama model is missing', 'Run ollama pull phi4-mini, then refresh model checks.'],
            ['Ollama is not reachable', 'Start the Ollama app or run ollama serve, then retry setup.'],
            ['OpenAI-compatible models don\'t appear', 'Start the provider, include /v1 in the base URL, verify /v1/models works.'],
            ['llama.cpp setup fails', 'Confirm llama-server exists, the .gguf path is real, and it exposes compatible /v1 endpoints.'],
            ['Update channel not configured', 'Expected in source builds unless updater public key and endpoint metadata were embedded.'],
            ['No license answer', 'There is no license file yet, so reuse rules aren\'t finalized.'],
          ].map(([q, a], i) => (
            <div key={i} style={{ padding: '8px 0', borderTop: i ? '1px solid var(--line-soft)' : 'none' }}>
              <div style={{ color: 'var(--fg)', fontSize: 12, marginBottom: 3 }}><span style={{ color: 'var(--warn)', marginRight: 6 }}>?</span>{q}</div>
              <div style={{ color: 'var(--dim)', fontSize: 11, lineHeight: 1.55, paddingLeft: 16 }}>{a}</div>
            </div>
          ))}
        </DocSec>

        <DocSec id="faq" title="faq" subtitle="answers before the issue tab gets involved.">
          {[
            ['Is Delyx finished?', 'No. It is active source-alpha software with a real product shape: easy entry first, depth when you ask for it.'],
            ['What platform is best tested?', 'Windows. Tauri should make macOS and Linux possible, but they\'re less exercised right now.'],
            ['Can I use a signed installer?', 'Yes when a signed Windows release is published. Source remains the dev path between builds.'],
            ['Do I have to use Ollama?', 'No, but Ollama plus phi4-mini is the documented first-run path.'],
            ['Can I use a remote model?', 'Yes. Use an OpenAI-compatible provider path and understand what data leaves the machine.'],
            ['Does Delyx support MCP?', 'Yes. The app manages MCP servers, with optional MCP over stdio.'],
            ['Why all the approval friction?', 'Because the app can touch files, commands, memory, and connectors. Useful things deserve visible brakes.'],
            ['What is the motto?', 'Local LLMs made easy. Maybe. Confidence with a built-in eyebrow raise.'],
          ].map(([q, a], i) => (
            <details key={i} style={{ padding: '7px 0', borderTop: i ? '1px solid var(--line-soft)' : 'none' }}>
              <summary style={{ color: 'var(--fg)', fontSize: 12, cursor: 'pointer', listStyle: 'none', display: 'flex', gap: 10 }}>
                <span style={{ color: 'var(--cyan)' }}>&gt;</span>{q}
              </summary>
              <div style={{ color: 'var(--dim)', fontSize: 11, lineHeight: 1.55, paddingLeft: 22, marginTop: 5 }}>{a}</div>
            </details>
          ))}
        </DocSec>

        <div style={{
          marginTop: 32, padding: 16, border: '1px solid var(--line)', borderRadius: 8,
          background: 'rgba(95,212,255,0.04)',
          display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16,
        }}>
          <div>
            <div style={{ color: 'var(--fg)', fontSize: 12, marginBottom: 2 }}>still stuck?</div>
            <div style={{ color: 'var(--dim)', fontSize: 11 }}>Open an issue with platform, install path, provider, command, and exact error text.</div>
          </div>
          <a href={ISSUE_URL} target="_blank" rel="noreferrer" style={ctaPrimary()}>open issue -&gt;</a>
        </div>
      </main>
    </div>
  );
}

function DocSec({ id, title, subtitle, children }) {
  return (
    <section id={'docsec-' + id} data-docsec style={{ paddingTop: 24, scrollMarginTop: 12 }}>
      <h2 style={{
        fontFamily: 'var(--mono)', fontSize: 20, fontWeight: 500,
        margin: 0, color: 'var(--fg)', lineHeight: 1.15,
      }}>
        <span style={{ color: 'var(--cyan)', marginRight: 10 }}>#</span>{title}
      </h2>
      {subtitle && <p style={{ fontSize: 12, color: 'var(--dim)', margin: '6px 0 14px', lineHeight: 1.55 }}>{subtitle}</p>}
      <div style={{ color: 'var(--fg-soft)', fontSize: 12, lineHeight: 1.7, fontFamily: 'var(--mono)' }}>
        {children}
      </div>
    </section>
  );
}

function DocH3({ children }) {
  return (
    <div style={{ fontFamily: 'var(--mono)', fontSize: 13, fontWeight: 600, color: 'var(--fg)', margin: '14px 0 6px' }}>
      {children}
    </div>
  );
}

function DocTable({ rows }) {
  return (
    <table style={{ width: '100%', borderCollapse: 'collapse', marginTop: 6, fontSize: 11, fontFamily: 'var(--mono)' }}>
      <tbody>
        {rows.map(([c, d], i) => (
          <tr key={i}>
            <td style={{
              padding: '7px 10px', borderTop: '1px solid var(--line)', color: 'var(--cyan)',
              fontFamily: 'var(--mono)', whiteSpace: 'nowrap', width: 200, verticalAlign: 'top',
            }}>{c}</td>
            <td style={{ padding: '7px 10px', borderTop: '1px solid var(--line)', color: 'var(--fg-soft)', lineHeight: 1.55 }}>{d}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function dsList() {
  return { color: 'var(--fg-soft)', paddingLeft: 20, lineHeight: 1.75, fontSize: 12, margin: '4px 0' };
}

// ────────── STATUS / CHANGELOG ──────────

function ClassicStatus() {
  const fallbackPulse = [
    ['source sync', 'origin/main add925a', 'local app fast-forwarded before this page was updated. the source is the map, and the map has fresh ink.'],
    ['reasoning', 'audits are live', 'active retrieval, claim audit, coherence, reroute, and conflict rendering are in the source tree.'],
    ['release path', 'windows-first', 'signed Windows installer/updater packaging is configured; source runs remain the dev path between public builds.'],
    ['mobile shell', 'responsive app pass', 'the app now has responsive nav, bottom navigation, a Now status surface, and a responsive smoke test.'],
  ];
  const fallbackReleases = [
    {
      ver: '0.1.0', tag: 'source alpha · current', date: 'May 16, 2026',
      note: 'The reasoning pass has landed. Evidence now has a clipboard, a tiny flashlight, and less patience for vibes.',
      current: true,
      changes: [
        ['new', 'active retrieval is wired into normal execution and can run up to three evidence-aware follow-up rounds.'],
        ['new', 'query decomposition supports general research, comparison, diagnostic, causal, temporal, and source-triangulation subtasks.'],
        ['new', 'claim audits check citation support, evidence ids, numeric/date support, and material contradictions.'],
        ['new', 'weak, empty, stale, near-match, missing-field, or conflicting evidence can trigger one focused post-evidence reroute.'],
        ['new', 'global coherence checks can surface user-visible Conflicts sections when sources disagree.'],
        ['new', 'context budgeting now names planning, composition, evidence-heavy, extraction, and chat profiles.'],
        ['new', 'eval graders cover semantic assertions, numeric tolerances, ranked lists, citation support, contradictions, opt-in LLM judge rubrics.'],
      ],
    },
    {
      ver: 'app', tag: 'desktop shell', date: 'Current source',
      note: 'The app is getting less like a pile of panels and more like a cockpit that knows where the cupholder is.',
      changes: [
        ['new', 'Control Center now gathers runs, approvals, connectors, session details, automations, logs, and recent tool state.'],
        ['new', 'responsive shell work added a mobile drawer, mobile bottom nav, collapsible desktop rail, Now status surface, and touch-size checks.'],
        ['new', 'Settings includes repair/update surfaces for signed release builds and privacy controls for masked local provider/search secrets.'],
        ['new', 'Automations are visible as Now, Upcoming, History, Failed, and Paused views.'],
        ['tech', 'npm run smoke:responsive runs a Chrome/Edge viewport sweep across overflow, nav, drawer, and status surfaces.'],
      ],
    },
    {
      ver: 'release', tag: 'windows packaging', date: 'Current source',
      note: 'Installer plumbing exists now. Glamorous in exactly the way plumbing usually is: crucial and best when uneventful.',
      changes: [
        ['new', 'Windows release workflow can build signed NSIS/MSI artifacts through GitHub Actions.'],
        ['new', 'in-app update checks are wired for signed builds when DELYX_UPDATER_PUBLIC_KEY and DELYX_UPDATER_ENDPOINT are embedded.'],
        ['tech', 'npm run tauri:build:windows prepares updater config and builds Windows installer/updater artifacts.'],
        ['tech', 'scripts/sign-windows.ps1 handles Authenticode signing when certificate secrets are available.'],
        ['tech', 'scripts/release-smoke-windows.ps1 verifies installer signatures and app launch behavior.'],
      ],
    },
    {
      ver: 'gaps', tag: 'honest bits', date: 'Current architecture tracker',
      note: 'The website still refuses to cosplay as a finished launch. Very rude. Very useful.',
      changes: [
        ['gap', 'Windows is the primary tested platform; macOS and Linux should be possible through Tauri but are less exercised.'],
        ['gap', 'source runs are still the development path between public signed release builds.'],
        ['gap', 'ReAct still follows one dominant trajectory; the next major reasoning upgrade is a small beam/tree controller for hard routes.'],
        ['gap', 'PRM scoring gates completed steps but does not yet score competing candidate tool plans before execution.'],
        ['gap', 'worker agents are bounded sidecar helpers, not independent hypothesis-search branches.'],
        ['gap', 'context budgets have named profiles, but token accounting is still approximate.'],
        ['gap', 'deeper temporal, arithmetic, unit, recommendation-criteria, and structured conflict checks are still pending.'],
        ['gap', 'there is no license file yet, so reuse rules are not finalized until a license is added.'],
      ],
    },
    {
      ver: 'stack', tag: 'technical notes', date: 'Repo facts',
      note: 'The tools under the floorboards, now with fewer mystery wires.',
      changes: [
        ['tech', 'frontend: React 19, TypeScript 5.8, Vite 7, Tailwind 4, lucide-react.'],
        ['tech', 'desktop/backend: Tauri 2, Rust 2021, Tauri command bridge, SQLite with WAL mode.'],
        ['tech', 'models: Ollama APIs, OpenAI-compatible /v1 APIs, optional llama.cpp GGUF serving.'],
        ['tech', 'tools: optional MCP over stdio, optional Discord bridge behind a Cargo feature, optional ONNX cross-encoder reranking.'],
        ['tech', 'app id: com.geaux.delyx; Windows local config path: %LOCALAPPDATA%\\Delyx\\local_config.json.'],
      ],
    },
  ];

  const [siteContent, setSiteContent] = React.useState(() => window.DelyxDefaultSiteContent || null);
  const [githubStatus, setGithubStatus] = React.useState(null);

  React.useEffect(() => {
    let mounted = true;
    if (window.DelyxCms?.getPublishedSiteContent) {
      window.DelyxCms.getPublishedSiteContent()
        .then((content) => { if (mounted && content) setSiteContent(content); })
        .catch(() => {});
    }
    if (window.DelyxCms?.getLatestReasoningStatus) {
      window.DelyxCms.getLatestReasoningStatus()
        .then((status) => { if (mounted && status) setGithubStatus(status); })
        .catch(() => {});
    }
    return () => { mounted = false; };
  }, []);

  const statusHero = window.DelyxCms?.getBlock(siteContent, 'status', 'status-hero');
  const statusPulse = window.DelyxCms?.getBlock(siteContent, 'status', 'status-pulse');
  const statusReleases = window.DelyxCms?.getBlock(siteContent, 'status', 'status-releases');
  const followSource = window.DelyxCms?.getBlock(siteContent, 'status', 'status-follow-source');
  const heroTitle = statusHero?.title || 'what is true,\nright now.';
  const heroParts = heroTitle.split('\n');
  const heroBody = statusHero?.body || 'Delyx is still source-alpha software, but the source moved: reasoning got stricter, Windows release plumbing is in place, and the desktop shell learned some mobile manners.';
  const cmsPulse = Array.isArray(statusPulse?.items)
    ? statusPulse.items.map((item) => [item.title || '', item.body || '', item.detail || item.text || '']).filter((item) => item[0] || item[1] || item[2])
    : [];
  const pulse = cmsPulse.length ? cmsPulse : fallbackPulse;
  const cmsReleases = Array.isArray(statusReleases?.items)
    ? statusReleases.items.map(normalizeStatusRelease).filter(Boolean)
    : [];
  const githubRelease = normalizeGithubStatusRelease(githubStatus);
  const releases = [
    ...(githubRelease ? [githubRelease] : []),
    ...(cmsReleases.length ? cmsReleases : fallbackReleases),
  ];

  const tagStyle = (k) => ({
    fontSize: 9, fontWeight: 600, padding: '2px 6px', borderRadius: 3,
    letterSpacing: 1, textTransform: 'uppercase', fontFamily: 'var(--mono)', marginRight: 10,
    background: ({ new: 'rgba(95,212,255,0.12)', gap: 'rgba(255,200,80,0.10)', tech: 'rgba(95,212,159,0.10)', ok: 'rgba(95,212,159,0.10)', warn: 'rgba(255,200,80,0.10)', bad: 'rgba(255,120,120,0.10)', note: 'rgba(255,255,255,0.06)' })[k] || 'rgba(255,255,255,0.04)',
    color: ({ new: 'var(--cyan)', gap: 'var(--warn)', tech: 'var(--good)', ok: 'var(--good)', warn: 'var(--warn)', bad: 'var(--bad)', note: 'var(--dim)' })[k] || 'var(--dim)',
    minWidth: 38, display: 'inline-block', textAlign: 'center',
  });
  const tagLabel = (k) => ({ new: 'now', gap: 'gap', tech: 'tech', ok: 'ok', warn: 'warn', bad: 'bad', note: 'note' })[k] || k;

  return (
    <div style={cpPageStyle()}>
      <section style={{ padding: '24px 28px 8px' }}>
        <CPLabel>./status</CPLabel>
        <h1 style={{ fontFamily: 'var(--mono)', fontSize: 36, lineHeight: 1, margin: 0, fontWeight: 500, color: 'var(--fg)', letterSpacing: 0 }}>
          {heroParts[0]}<br/>
          <span style={{ color: 'var(--dim)', fontStyle: 'italic' }}>{heroParts.slice(1).join(' ') || 'right now.'}</span>
        </h1>
        <p style={{ fontSize: 12, color: 'var(--dim)', lineHeight: 1.65, margin: '12px 0 0', maxWidth: 580 }}>
          {heroBody}
        </p>
        <div style={{ marginTop: 14, display: 'flex', gap: 14, fontSize: 11, color: 'var(--dim)', flexWrap: 'wrap', alignItems: 'center' }}>
          <span><span style={tagStyle('new')}>now</span>available in source</span>
          <span><span style={tagStyle('gap')}>gap</span>known gap</span>
          <span><span style={tagStyle('tech')}>tech</span>implementation note</span>
        </div>
      </section>

      <section style={{ padding: '18px 28px 0' }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
          {pulse.map(([k, v, detail]) => (
            <div key={k} style={{
              padding: '12px 14px', border: '1px solid var(--line)', borderRadius: 6,
              background: 'rgba(255,255,255,0.02)',
            }}>
              <div style={{ color: 'var(--cyan)', fontSize: 10, marginBottom: 6, letterSpacing: 1, textTransform: 'uppercase' }}>{k}</div>
              <div style={{ color: 'var(--fg)', fontSize: 12, lineHeight: 1.45, marginBottom: 6 }}>{v}</div>
              <div style={{ color: 'var(--dim)', fontSize: 10, lineHeight: 1.5 }}>{detail}</div>
            </div>
          ))}
        </div>
      </section>

      <section style={{ padding: '8px 28px 24px' }}>
        {releases.map((r, i) => (
          <article key={r.ver} style={{
            display: 'grid', gridTemplateColumns: '160px 1fr',
            padding: '20px 0', borderTop: '1px solid var(--line)',
          }}>
            <div style={{ paddingRight: 16 }}>
              <div style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6 }}>
                <span style={{ color: 'var(--cyan)', fontSize: 10 }}>&gt;</span>
                <span style={{ color: 'var(--fg)', fontSize: 20, fontWeight: 500 }}>
                  {r.ver === '0.1.0' ? 'v' + r.ver : r.ver}
                </span>
              </div>
              <div style={{ fontSize: 10, color: 'var(--dim)', marginTop: 4, letterSpacing: 1, textTransform: 'uppercase' }}>{r.tag}</div>
              <div style={{ fontSize: 11, color: 'var(--dimmer)', marginTop: 6 }}>{r.date}</div>
              {r.current && (
                <div style={{
                  display: 'inline-flex', alignItems: 'center', gap: 5,
                  marginTop: 10, padding: '3px 7px',
                  background: 'rgba(95,212,159,0.10)', border: '1px solid #5fd49f55',
                  borderRadius: 3, fontSize: 10, color: 'var(--good)',
                }}>
                  <span style={{ width: 5, height: 5, borderRadius: 3, background: 'var(--good)' }} />
                  current
                </div>
              )}
            </div>
            <div>
              {r.note && (
                <p style={{ fontSize: 12, color: 'var(--fg-soft)', fontStyle: 'italic', margin: '0 0 12px', lineHeight: 1.55, opacity: 0.85 }}>
                  - {r.note}
                </p>
              )}
              <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
                {r.changes.map(([k, t], j) => (
                  <li key={j} style={{
                    display: 'flex', alignItems: 'flex-start',
                    padding: '6px 0', borderTop: j ? '1px solid var(--line-soft)' : 'none',
                    fontSize: 12, color: 'var(--fg-soft)', lineHeight: 1.55,
                  }}>
                    <span style={tagStyle(k)}>{tagLabel(k)}</span>
                    <span style={{ flex: 1 }}>{t}</span>
                  </li>
                ))}
              </ul>
            </div>
          </article>
        ))}
      </section>

      <section style={{ padding: '8px 28px 28px' }}>
        <div style={{
          padding: '18px 22px', border: '1px solid var(--line)', borderRadius: 8,
          background: 'rgba(255,255,255,0.01)',
          display: 'grid', gridTemplateColumns: '1fr auto', gap: 16, alignItems: 'center',
        }}>
          <div>
            <div style={{ fontSize: 12, color: 'var(--cyan)', marginBottom: 6 }}><CPChev>follow the source</CPChev></div>
            <p style={{ fontSize: 11, color: 'var(--dim)', margin: 0, lineHeight: 1.55 }}>
              {followSource?.body || 'The README, docs folder, and main branch are the live truth until formal releases become routine.'}
            </p>
          </div>
          <a href={followSource?.href || GITHUB_URL} target="_blank" rel="noreferrer" style={ctaPrimary()}>{followSource?.cta || 'open github ->'}</a>
        </div>
      </section>
    </div>
  );
}

// ────────── CONTACT ──────────

function normalizeStatusRelease(item) {
  if (!item) return null;
  return {
    ver: item.version || item.ver || item.title || 'update',
    tag: item.tag || '',
    date: item.date || '',
    note: item.body || item.note || '',
    current: item.current === true,
    changes: Array.isArray(item.changes)
      ? item.changes.map((change) => [change.tone || change.kind || 'new', change.text || change.body || '']).filter((change) => change[1])
      : [],
  };
}

function normalizeGithubStatusRelease(status) {
  if (!status || !Array.isArray(status.bullets) || status.bullets.length === 0) return null;
  const generated = status.generatedAt ? new Date(status.generatedAt) : null;
  const date = generated && !Number.isNaN(generated.getTime())
    ? generated.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })
    : 'GitHub source feed';
  return {
    ver: 'github',
    tag: 'ai source feed',
    date,
    note: status.summary || status.headline || 'Generated from the latest README and reasoning docs.',
    current: false,
    changes: status.bullets.map((bullet) => [bullet.tone || 'new', bullet.text || String(bullet)]).filter((change) => change[1]),
  };
}

function ClassicContact() {
  const [form, setForm] = React.useState({ name: '', email: '', subject: 'bug', message: '' });
  const [sent, setSent] = React.useState(false);

  const send = (e) => {
    e.preventDefault();
    const labels = { bug: 'Bug report', feature: 'Feature request', docs: 'Docs / website note', install: 'Install problem', question: 'Question' };
    const title = '[' + (labels[form.subject] || 'Delyx') + '] ' + (form.message.split('\n')[0].slice(0, 72) || 'New issue');
    const body = [
      '## What happened', form.message || '_Describe the issue or request._', '',
      '## Contact',
      form.name ? 'Name: ' + form.name : 'Name: _not provided_',
      form.email ? 'Email: ' + form.email : 'Email: _not provided_', '',
      '## Context',
      'Category: ' + (labels[form.subject] || form.subject),
      'Opened from delyx website contact form.',
    ].join('\n');
    const url = ISSUE_URL + '?title=' + encodeURIComponent(title) + '&body=' + encodeURIComponent(body);
    window.open(url, '_blank', 'noopener,noreferrer');
    setSent(true);
    setTimeout(() => setSent(false), 2500);
  };

  const inp = {
    background: 'var(--ink-soft)', border: '1px solid var(--line)', borderRadius: 5,
    padding: '8px 11px', color: 'var(--fg)', fontFamily: 'var(--mono)', fontSize: 12,
    outline: 'none', width: '100%', boxSizing: 'border-box',
  };

  return (
    <div style={cpPageStyle()}>
      <section style={{ padding: '24px 28px 0' }}>
        <CPLabel>./contact</CPLabel>
        <h1 style={{ fontFamily: 'var(--mono)', fontSize: 36, lineHeight: 1, margin: 0, fontWeight: 500, color: 'var(--fg)' }}>
          say hi.<br/>
          <span style={{ color: 'var(--dim)', fontStyle: 'italic' }}>preferably with logs.</span>
        </h1>
        <p style={{ fontSize: 12, color: 'var(--dim)', lineHeight: 1.65, margin: '12px 0 0', maxWidth: 580 }}>
          Delyx is open-source and moving quickly. The best contact path is a GitHub issue with your platform, model provider, command, and exact error text. Yes, exact. Vibes are useful; logs are usefuler.
        </p>
      </section>

      <section style={{ padding: '20px 28px 0' }}>
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)',
          border: '1px solid var(--line)', borderRadius: 8, overflow: 'hidden',
          background: 'rgba(255,255,255,0.01)',
        }}>
          {[
            ['project', 'public repo', 'var(--good)', true],
            ['support', 'github issues', 'var(--cyan)'],
            ['release', 'windows-first alpha', 'var(--warn)'],
            ['tone', 'honest, not haunted', 'var(--dim)'],
          ].map(([label, value, c, dot], i) => (
            <div key={i} style={{
              padding: '12px 14px',
              borderRight: i !== 3 ? '1px solid var(--line)' : 'none',
            }}>
              <div style={{ fontSize: 10, color: 'var(--dim)', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 6 }}>{label}</div>
              <div style={{ fontSize: 12, color: c, display: 'flex', alignItems: 'center', gap: 6 }}>
                {dot && <span style={{ width: 6, height: 6, borderRadius: 3, background: c }} />}
                {value}
              </div>
            </div>
          ))}
        </div>
      </section>

      <section style={{ padding: '24px 28px 0', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20 }}>
        <div>
          <CPLabel>how to reach the project</CPLabel>
          {[
            { icon: '!', label: 'github issues', value: 'github.com/joshua-ivy/Delyx/issues', note: 'best for reproducible bugs, install trouble, docs fixes, and feature proposals.', href: GITHUB_URL + '/issues', cta: 'open issue ->' },
            { icon: '#', label: 'source', value: 'github.com/joshua-ivy/Delyx', note: 'best for README, package scripts, source layout, and current implementation details.', href: GITHUB_URL, cta: 'open repo ->' },
            { icon: 'P', label: 'readme', value: 'current source of truth', note: 'best for the latest setup path, docs map, release notes, and current caveats.', href: GITHUB_URL + '#readme', cta: 'read it ->' },
            { icon: '!', label: 'private reports', value: 'do not post secrets', note: 'the public repo does not list a private security channel yet. avoid posting tokens, keys, private logs, or sensitive local paths.', disabled: true, cta: 'not public' },
          ].map((m, i) => (
            <div key={i} style={{
              padding: '12px 14px', border: '1px solid var(--line)', borderRadius: 6, marginBottom: 8,
              background: m.disabled ? 'rgba(255,255,255,0.005)' : 'rgba(255,255,255,0.02)',
              opacity: m.disabled ? 0.7 : 1,
              display: 'grid', gridTemplateColumns: '32px 1fr auto', gap: 12, alignItems: 'center',
            }}>
              <div style={{
                width: 32, height: 32, borderRadius: 5, border: '1px solid var(--line)',
                background: 'var(--ink-soft)', display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--cyan)', fontSize: 14, fontWeight: 600,
              }}>{m.icon}</div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 10, color: 'var(--dim)', letterSpacing: 1, textTransform: 'uppercase' }}>{m.label}</div>
                <div style={{ fontSize: 12, color: 'var(--fg)', margin: '2px 0' }}>{m.value}</div>
                <div style={{ fontSize: 10, color: 'var(--dim)', lineHeight: 1.5 }}>{m.note}</div>
              </div>
              {m.href ? (
                <a href={m.href} target="_blank" rel="noreferrer" style={{ fontSize: 10, color: 'var(--cyan)', textDecoration: 'none', whiteSpace: 'nowrap' }}>{m.cta}</a>
              ) : (
                <span style={{ fontSize: 10, color: 'var(--dim)', whiteSpace: 'nowrap' }}>{m.cta}</span>
              )}
            </div>
          ))}

          <div style={{
            marginTop: 12, padding: '12px 14px',
            border: '1px dashed var(--line)', borderRadius: 6,
          }}>
            <div style={{ fontSize: 10, color: 'var(--warn)', letterSpacing: 1, textTransform: 'uppercase', marginBottom: 8 }}>
              <CPChev color="var(--warn)">before you open an issue</CPChev>
            </div>
            <ul style={{ margin: 0, paddingLeft: 16, color: 'var(--dim)', fontSize: 11, lineHeight: 1.7 }}>
              <li>check the docs and the README first.</li>
              <li>include your OS, Node version, Rust version, model provider, and command.</li>
              <li>paste exact error text — not a dramatic reenactment.</li>
              <li>do not post API keys, tokens, private logs, or sensitive local paths.</li>
            </ul>
          </div>
        </div>

        <div>
          <CPLabel>issue draft helper</CPLabel>
          <form onSubmit={send} style={{
            padding: '16px 16px', border: '1px solid var(--line)', borderRadius: 6,
            background: 'rgba(255,255,255,0.02)',
          }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 10 }}>
              <Field label="your name">
                <input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="optional" style={inp} />
              </Field>
              <Field label="email">
                <input type="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} placeholder="optional" style={inp} />
              </Field>
            </div>
            <Field label="what's this about">
              <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                {[
                  ['bug', 'bug'], ['feature', 'feature'], ['docs', 'docs'], ['install', 'install'], ['question', 'question'],
                ].map(([id, label]) => (
                  <button key={id} type="button" onClick={() => setForm({ ...form, subject: id })} style={{
                    padding: '5px 9px', borderRadius: 4, fontFamily: 'var(--mono)', fontSize: 11, cursor: 'pointer',
                    border: '1px solid ' + (form.subject === id ? 'var(--cyan)' : 'var(--line)'),
                    background: form.subject === id ? 'rgba(95,212,255,0.10)' : 'var(--ink-soft)',
                    color: form.subject === id ? 'var(--cyan)' : 'var(--dim)',
                  }}>{form.subject === id ? '> ' : ''}{label}</button>
                ))}
              </div>
            </Field>
            <Field label="message" required>
              <textarea value={form.message} onChange={(e) => setForm({ ...form, message: e.target.value })}
                placeholder="what happened, what you expected, exact error text, platform, provider..."
                rows={5} required style={{ ...inp, resize: 'vertical', lineHeight: 1.55 }} />
            </Field>
            <div style={{
              padding: '8px 10px', border: '1px solid var(--line)', borderRadius: 5,
              fontSize: 10, color: 'var(--dim)', marginBottom: 12, background: 'var(--ink-soft)', lineHeight: 1.55,
            }}>
              <span style={{ color: 'var(--cyan)' }}>&gt;</span> this opens a prefilled public GitHub issue. review before submitting, especially if you pasted logs.
            </div>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
              <div style={{ fontSize: 10, color: 'var(--dim)' }}>
                {sent ? <span style={{ color: 'var(--cyan)' }}>issue draft opened.</span> : 'opens on GitHub in a new tab'}
              </div>
              <button type="submit" style={ctaPrimary()}>{sent ? 'opened' : 'draft issue ->'}</button>
            </div>
          </form>
        </div>
      </section>

      <section style={{ padding: '24px 28px 28px' }}>
        <div style={{
          padding: '20px 22px', border: '1px solid var(--line)', borderRadius: 8,
          background: 'rgba(255,255,255,0.01)',
          display: 'grid', gridTemplateColumns: '80px 1fr', gap: 18, alignItems: 'flex-start',
        }}>
          <div style={{
            width: 80, height: 80, borderRadius: 8,
            background: '#000', border: '1px solid var(--line)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            overflow: 'hidden',
          }}>
            <img src="delyx.png" alt="" style={{ width: '150%', height: '150%', objectFit: 'cover' }} />
          </div>
          <div>
            <div style={{ fontSize: 12, color: 'var(--cyan)', marginBottom: 8 }}><CPChev>who owns the repo</CPChev></div>
            <p style={{ fontSize: 12, color: 'var(--fg-soft)', lineHeight: 1.65, margin: 0 }}>
              The public repository lives under <CPIC>joshua-ivy/Delyx</CPIC>. The README is written in a refreshingly direct voice, and this site follows that lead: useful first, honest always, a little weird where it helps the medicine go down.
            </p>
            <div style={{ marginTop: 12, display: 'flex', gap: 14, fontSize: 11, color: 'var(--dim)' }}>
              <a href={GITHUB_URL} target="_blank" rel="noreferrer" style={{ color: 'var(--cyan)', textDecoration: 'none', borderBottom: '1px solid var(--cyan)' }}>open repo</a>
              <span>read docs</span>
              <span>run from source</span>
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}

function Field({ label, required, children }) {
  return (
    <div style={{ marginBottom: 10 }}>
      <label style={{
        display: 'block', fontSize: 10, color: 'var(--dim)', letterSpacing: 1,
        textTransform: 'uppercase', marginBottom: 5, fontFamily: 'var(--mono)',
      }}>
        {label}{required && <span style={{ color: 'var(--cyan)', marginLeft: 4 }}>*</span>}
      </label>
      {children}
    </div>
  );
}

// ────────── Page shell helpers ──────────

function cpPageStyle() {
  return {
    height: '100%',
    overflowY: 'auto',
    background: 'var(--ink-soft)',
    color: 'var(--fg)',
    fontFamily: 'var(--mono)',
  };
}

function ctaPrimary() {
  return {
    fontSize: 12, color: 'var(--ink)', background: 'var(--cyan)',
    padding: '8px 14px', borderRadius: 5, fontWeight: 600,
    fontFamily: 'var(--mono)', textDecoration: 'none', cursor: 'pointer',
    display: 'inline-flex', alignItems: 'center', gap: 6, border: 'none',
    whiteSpace: 'nowrap',
  };
}

function ctaSecondary() {
  return {
    fontSize: 12, color: 'var(--fg)', padding: '8px 14px',
    border: '1px solid var(--line)', borderRadius: 5,
    fontFamily: 'var(--mono)', textDecoration: 'none', cursor: 'pointer',
    display: 'inline-flex', alignItems: 'center', gap: 6,
    whiteSpace: 'nowrap',
  };
}

Object.assign(window, { ClassicHome, ClassicDocs, ClassicStatus, ClassicContact });
