/* ESF Companion: main app, hero, sections, demos, footer.
 * Tweaks panel handles theme, accent, and density.
 */
const { useState: useStateA, useEffect: useEffectA } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "accent": "agent",
  "showHeroBeforeAfter": true
}/*EDITMODE-END*/;

const ACCENTS = {
  agent:   { name: "Agent violet (default)", swatch: "oklch(0.52 0.14 262)" },
  ink:     { name: "Ink black",              swatch: "oklch(0.21 0.005 270)" },
  blue:    { name: "Coordia blue",           swatch: "#1a56db" },
  green:   { name: "Quiet green",            swatch: "oklch(0.55 0.13 150)" },
};

function applyTweaks(t) {
  document.body.classList.toggle('dark', t.theme === 'dark');
  const accent = ACCENTS[t.accent] || ACCENTS.agent;
  document.documentElement.style.setProperty('--agent', accent.swatch);
}

function Topbar() {
  return (
    <header className="topbar">
      <div className="topbar__inner">
        <a href="#top" className="brand">
          <span className="brand__mark">E</span>
          <span className="brand__word">ESF Companion</span>
          <span className="brand__sub">v1 · cc by 4.0</span>
        </a>
        <nav className="nav">
          <a href="#process">Process</a>
          <a href="#example">Example</a>
          <a href="#demos">Demos</a>
          <a href="#install">Install</a>
          <a href="#faq">FAQ</a>
          <span className="nav__divider"/>
          <a className="btn btn--ghost" href="https://github.com/nmadrid27/esf-companion" target="_blank" rel="noreferrer"><Icon.github style={{width: 14, height: 14}}/> GitHub</a>
        </nav>
      </div>
    </header>
  );
}

function Hero({ showBeforeAfter }) {
  return (
    <section className="hero" id="top">
      <div className="container">
        <div className="hero__grid">
          <div className="stack">
            <h1 className="h-display">
              Direct AI from a position you can <em>defend</em>.
            </h1>
            <p className="lede">
              ESF Companion is a repeatable process for keeping AI-assisted work genuinely yours. Write your direction first. Capture every override. Ship with an honest disclosure. No institution or course required.
            </p>
            <div className="hero__cta-row">
              <a className="btn btn--lg" href="#install"><Icon.download style={{width: 14, height: 14}}/> Install in one command</a>
              <a className="btn btn--outline btn--lg" href="#demos">See it work →</a>
            </div>
            <div className="hero__bullets">
              <span>Tool-agnostic</span>
              <span>Local-only, nothing sent anywhere</span>
              <span>Works with Claude, ChatGPT, Gemini</span>
              <span>CC BY 4.0</span>
            </div>
          </div>
          {showBeforeAfter && (
            <div className="before-after">
              <div className="ba-row">
                <span className="ba-label">Without ESF</span>
                <div className="ba-cell ba-cell--danger">
                  <strong>You react to what the AI produced.</strong> Output arrives before your position does. Work drifts toward model defaults. Disclosure becomes guesswork.
                </div>
              </div>
              <div className="ba-divider">↓ Position Statement gate</div>
              <div className="ba-row">
                <span className="ba-label">With ESF</span>
                <div className="ba-cell ba-cell--ok">
                  <strong>You direct, AI extends.</strong> Your stance is on disk before AI enters. Drift is flagged in real time. Every override is documented. The work is yours.
                </div>
              </div>
              <div className="ba-row">
                <span className="ba-label">Phase 5</span>
                <div className="ba-cell">
                  <span className="muted mono" style={{fontSize: 11}}>five-questions.md</span><br/>
                  <strong>Can I defend this? Is this mine? Did I verify? Would I teach this? Is my disclosure honest?</strong>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

function ProcessSection() {
  const phases = [
    { num: '01', title: 'Inquire', mode: 'offline · no AI', body: 'Read the brief. Ask yourself what you know, what you don\'t, and what you\'re assuming. Capture instincts in any form.' },
    { num: '02', title: 'Position', mode: 'offline · no AI', body: 'Write your Position Statement: stance, what matters most, what you will not compromise. This is the gate. AI does not see the project until this exists.' },
    { num: '03', title: 'Explore', mode: 'with AI', body: 'Bring AI in to challenge your position, surface alternatives, ask questions, push on blind spots. You direct. AI responds. It does not originate direction.' },
    { num: '04', title: 'Make', mode: 'with AI', body: 'Build with the Companion\'s help. It monitors for drift against your Position Statement. Every reject or revise becomes a Record of Resistance.' },
    { num: '05', title: 'Reflect', mode: 'with AI', body: 'Run the Five Questions. Compare final work to your original position. Generate an honest Disclosure Statement from your session logs.' },
  ];
  return (
    <section className="section" id="process">
      <div className="container stack--xl">
        <div className="stack">
          <span className="eyebrow"><span className="dot"/>The process · five phases</span>
          <h2 className="h-section">Three stages. Five practices. Keep your thinking yours.</h2>
          <p className="lede">The first two phases happen offline. The last three happen with the Companion. The Position Statement is the gate. Everything downstream depends on it.</p>
        </div>
        <div className="phases">
          {phases.map(p => (
            <div className="phase" key={p.num}>
              <div className="phase__num">{p.num}</div>
              <div>
                <div>
                  <span className="phase__title">{p.title}</span>
                  <span className={"phase__mode " + (p.mode.includes('with AI') ? "phase__mode--ai" : "")}>· {p.mode}</span>
                </div>
                <p className="phase__body">{p.body}</p>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function DemosSection() {
  return (
    <section className="section section--sunk" id="demos">
      <div className="container stack--xl">
        <div className="stack">
          <span className="eyebrow"><span className="dot"/>Live demos · no install needed</span>
          <h2 className="h-section">Try the three core practices in the browser.</h2>
          <p className="lede">Working approximations of what the Companion does inside Claude, ChatGPT, or Gemini. Local state only. Nothing leaves your browser.</p>
        </div>

        <div className="stack">
          <div className="row" style={{alignItems: 'baseline'}}>
            <span className="eyebrow">01 · Position Statement Builder</span>
          </div>
          <PositionBuilder/>
          <p className="muted" style={{fontSize: 13}}>Three questions. A live preview of the file the Companion writes. In the real workflow, you commit this to <span className="mono">projects/&lt;name&gt;/position-statements/</span> before any AI session.</p>
        </div>

        <div className="stack">
          <div className="row" style={{alignItems: 'baseline'}}>
            <span className="eyebrow">02 · Drift Detection</span>
          </div>
          <DriftDemo/>
          <p className="muted" style={{fontSize: 13}}>The Companion compares conversation against your Position Statement. When the work drifts from what you stated, it asks. You decide: correct, pivot, or continue deliberately.</p>
        </div>

        <div className="stack">
          <div className="row" style={{alignItems: 'baseline'}}>
            <span className="eyebrow">03 · Record of Resistance</span>
          </div>
          <RecordOfResistance/>
          <p className="muted" style={{fontSize: 13}}>Every rejection or revision is captured with reasoning. The log is evidence of editorial judgment: the difference between authoring work and accepting output.</p>
        </div>
      </div>
    </section>
  );
}

function InstallSection() {
  const cmd = "curl -fsSL https://raw.githubusercontent.com/nmadrid27/esf-companion/main/install.sh | bash";
  function copy() {
    navigator.clipboard.writeText(cmd).then(() => {
      const el = document.getElementById('copy-btn');
      if (el) { const t = el.innerText; el.innerText = 'Copied'; setTimeout(() => el.innerText = t, 1400); }
    });
  }

  const paths = [
    { num: '01', title: 'Templates only', sub: 'Two markdown files. Any folder, any tool, no install.', list: ['Position Statement template', 'Record of Resistance template', 'Self-directed drift check'], featured: false, cta: 'Download templates' },
    { num: '02', title: 'Claude.ai · ChatGPT · Gemini', sub: 'Paste the companion prompt. AI follows the ESF process and gates work behind your Position Statement.', list: ['Quick-start single paste', 'Per-session PROJECT.md', 'Claude.ai Projects supported'], featured: true, cta: 'Read the prompt' },
    { num: '03', title: 'Claude Cowork', sub: 'Claude Desktop reads ESF files from your computer directly. No terminal needed.', list: ['Pro+ plan required', 'Desktop file access', 'Persistent context'], featured: false, cta: 'Download repo' },
    { num: '04', title: 'Claude Code', sub: 'Full agent: drift detection, session memory, six skills, slash commands.', list: ['/esf-onboarding', '/esf-project', 'Six skills bundled', 'Per-session AI Use Logs'], featured: false, cta: 'Run the installer' },
  ];

  return (
    <section className="section" id="install">
      <div className="container stack--xl">
        <div className="stack">
          <span className="eyebrow"><span className="dot"/>Install · pick your path</span>
          <h2 className="h-section">Four setups. Same practice. Nothing sent anywhere.</h2>
          <p className="lede">All paths run locally. The installer auto-commits Companion files to git, never modifies existing work, and asks before creating folders.</p>
        </div>

        <div className="stack">
          <div className="card card--sunk" style={{padding: 22, display: 'grid', gap: 14}}>
            <div className="row">
              <span className="eyebrow"><Icon.terminal style={{width: 12, height: 12}}/>One-line installer</span>
              <span className="pill" style={{marginLeft: 'auto'}}>macOS · Linux · WSL · Git Bash</span>
            </div>
            <div className="code"><span className="c">$ </span>{cmd}</div>
            <div className="row">
              <button id="copy-btn" className="btn btn--outline" onClick={copy}><Icon.code style={{width: 13, height: 13}}/> Copy command</button>
              <span className="muted" style={{fontSize: 12.5}}>Then choose option 1 (Claude Code) or option 2 (conversation tools) when prompted.</span>
            </div>
          </div>
          <div className="paths">
            {paths.map(p => (
              <div key={p.num} className={"path card--lift " + (p.featured ? "path--featured" : "")}>
                {p.featured && <span className="pill pill--agent" style={{position: 'absolute', top: -10, right: 14}}><span className="dot"/>most popular</span>}
                <span className="path__num">Path {p.num}</span>
                <div className="path__title">{p.title}</div>
                <div className="path__sub">{p.sub}</div>
                <ul className="path__list">{p.list.map(l => <li key={l}>{l}</li>)}</ul>
                <a className={"btn " + (p.featured ? "" : "btn--outline")} href="https://github.com/nmadrid27/esf-companion" target="_blank" rel="noreferrer">{p.cta} <Icon.arrow style={{width: 13, height: 13}}/></a>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function DomainsSection() {
  const uses = [
    { ico: Icon.pen,        title: 'Writers & researchers', copy: 'Drafting tools without losing your argument or voice.', pos: '"My argument is X, structured as Y."' },
    { ico: Icon.brush,      title: 'Designers',             copy: 'Generative AI without drifting into AI aesthetic defaults.', pos: '"My concept is X, constrained by Y."' },
    { ico: Icon.code,       title: 'Developers',            copy: 'AI coding assistants without inheriting model architecture habits.', pos: '"My architecture is X, optimized for Y."' },
    { ico: Icon.cog,        title: 'Prompt engineers',      copy: 'System-prompt design without softening your hard constraints.', pos: '"This AI must do X, must never do Y, optimized for Z."' },
    { ico: Icon.flask,      title: 'Researchers',           copy: 'Analysis assistants without your hypothesis shifting to fit AI framings.', pos: '"My hypothesis is X, grounded in Y."' },
    { ico: Icon.briefcase,  title: 'Consultants',           copy: 'Client deliverables you can defend in the room.', pos: '"My recommendation is X, based on Y."' },
  ];
  return (
    <section className="section section--sunk" id="domains">
      <div className="container stack--xl">
        <div className="stack">
          <span className="eyebrow"><span className="dot"/>Who it's for</span>
          <h2 className="h-section">One mechanism. Many domains.</h2>
          <p className="lede">Each Position Statement adapts to the work. The practice stays the same. The risk of unexamined AI use looks different in every field; the mechanism is the same.</p>
        </div>
        <div className="use-grid">
          {uses.map(u => (
            <div key={u.title} className="use">
              <div className="use__icon"><u.ico style={{width: 16, height: 16}}/></div>
              <div className="use__title">{u.title}</div>
              <div className="use__copy">{u.copy}</div>
              <div className="use__pos">{u.pos}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function FAQSection() {
  const faqs = [
    { q: "Do I need Claude Code?", a: "No. ESF Companion works with any AI tool. Claude Code gives the richest experience: drift detection, session memory, six skills. Claude.ai, ChatGPT, Gemini, and Codex CLI get the core process via the companion prompt." },
    { q: "Can I use this with existing work?", a: "Yes. Run the installer inside your existing project directory. It adds ESF files alongside your work without modifying anything you already have." },
    { q: "Does the Companion send data anywhere?", a: "No. Everything is local files in your project. The installer downloads templates and prompts; nothing about your work or sessions is reported anywhere. Works air-gapped after install." },
    { q: "How do I uninstall?", a: "Delete the .claude/, prompts/, and templates/ folders the installer added. There's no system-level state, no daemon, no cloud account. Your work files are untouched." },
    { q: "Can I customize it?", a: "Yes. Templates are markdown, the companion prompt is a single file, and the agent configuration is plain text. The Framework Evolution Protocol (v3) lets you propose ESF revisions and document deliberate deviations in esf/evolution-log.md." },
    { q: "What if my Position Statement is wrong?", a: "Tell the Companion. It saves your current statement as v1 and helps you write v2. Pivots are documented with reasoning. Statement evolution is a feature, not a failure." },
    { q: "Does this work for teams?", a: "Currently the practice is per-person; each collaborator writes their own Position Statement. Files are designed to be reviewed (markdown, version-controllable). A team-level dashboard is planned but not shipped." },
    { q: "Where do I go after install?", a: "Run /esf-onboarding (Claude Code) or paste the companion prompt (other tools). The Companion walks you through your first project. The repo's WALKTHROUGH.md has a 10-minute worked example." },
    { q: "Where does this come from?", a: "The Epistemic Stewardship Framework originated in education, where the stakes of cognitive drift are visible in student work. The same risks apply to any practitioner doing serious AI-assisted work. The mechanism is the same problem in different contexts." },
    { q: "What's the license actually allow?", a: "CC BY 4.0: use it commercially, modify it, redistribute it, build on it. Just credit Nathan Madrid and the project. No trademark, no patent, no warranty." },
  ];
  return (
    <section className="section" id="faq">
      <div className="container stack--xl">
        <div className="stack">
          <span className="eyebrow"><span className="dot"/>FAQ</span>
          <h2 className="h-section">Common questions.</h2>
        </div>
        <div className="stack">
          {faqs.map(f => (
            <div key={f.q} className="card">
              <div className="h-card" style={{marginBottom: 8}}>{f.q}</div>
              <p style={{margin: 0, color: 'var(--ink-2)', fontSize: 14, lineHeight: 1.6, maxWidth: '64ch'}}>{f.a}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function FinalCTA() {
  return (
    <section className="section section--ink">
      <div className="container stack" style={{textAlign: 'center', alignItems: 'center', justifyItems: 'center'}}>
        <span className="eyebrow" style={{color: 'color-mix(in oklch, white, transparent 50%)'}}><span className="dot" style={{background: 'var(--agent)'}}/>Just want to start with one thing?</span>
        <h2 className="h-section" style={{color: 'white', maxWidth: 720, textAlign: 'center'}}>Download the Position Statement template. Fill it in before your next AI session.</h2>
        <p className="lede" style={{textAlign: 'center'}}>One step changes the dynamic. Add the other practices when they feel useful.</p>
        <div className="row" style={{justifyContent: 'center', marginTop: 14}}>
          <a className="btn btn--lg btn--on-dark" href="https://github.com/nmadrid27/esf-companion/blob/main/templates/position-statement.md" target="_blank" rel="noreferrer">
            <Icon.download style={{width: 14, height: 14}}/> Get the template
          </a>
          <a className="btn btn--lg btn--outline btn--on-dark-outline" href="https://github.com/nmadrid27/esf-companion" target="_blank" rel="noreferrer">
            <Icon.github style={{width: 14, height: 14}}/> Repo & docs
          </a>
        </div>
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer className="footer">
      <div className="footer__inner">
        <span className="brand">
          <span className="brand__mark" style={{width: 22, height: 22, fontSize: 11}}>E</span>
          <span style={{fontSize: 13, fontWeight: 600, letterSpacing: '-0.01em'}}>ESF Companion</span>
        </span>
        <span className="muted">A toolkit for directed AI use · Nathan Madrid · Licensed CC BY 4.0</span>
        <div className="links">
          <a href="https://github.com/nmadrid27/esf-companion" target="_blank" rel="noreferrer">Repo</a>
          <a href="https://github.com/nmadrid27/esf-companion/blob/main/WALKTHROUGH.md" target="_blank" rel="noreferrer">Walkthrough</a>
          <a href="https://github.com/nmadrid27/esf-companion/blob/main/ROADMAP.md" target="_blank" rel="noreferrer">Roadmap</a>
          <a href="https://github.com/nmadrid27/esf-companion/blob/main/templates/position-statement.md" target="_blank" rel="noreferrer">Template</a>
        </div>
      </div>
    </footer>
  );
}

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  useEffectA(() => { applyTweaks(tweaks); }, [tweaks]);

  return (
    <>
      <Topbar/>
      <Hero showBeforeAfter={tweaks.showHeroBeforeAfter}/>
      <ProcessSection/>
      <WorkedExample/>
      <EffortStrip/>
      <DemosSection/>
      <InstallSection/>
      <DomainsSection/>
      <CompareSection/>
      <WhenNot/>
      <AuthorBlock/>
      <FAQSection/>
      <FinalCTA/>
      <Footer/>
      <TweaksPanel title="Tweaks">
        <TweakSection label="Theme"/>
        <TweakRadio
          label="Mode"
          value={tweaks.theme}
          options={['light', 'dark']}
          onChange={v => setTweak('theme', v)}
        />
        <TweakSection label="Accent"/>
        <TweakSelect
          label="Accent color"
          value={tweaks.accent}
          options={Object.keys(ACCENTS).map(k => ({value: k, label: ACCENTS[k].name}))}
          onChange={v => setTweak('accent', v)}
        />
        <TweakSection label="Hero"/>
        <TweakToggle
          label="Show before/after card"
          value={tweaks.showHeroBeforeAfter}
          onChange={v => setTweak('showHeroBeforeAfter', v)}
        />
      </TweaksPanel>
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<App/>);
