/* global React */
const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ---------- tiny icon set (lucide-style, 1.5px stroke) ----------
const Icon = ({ name, size = 16, className = "", ...rest }) => {
  const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round", className, ...rest };
  switch (name) {
    case "copy":   return <svg {...common}><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>;
    case "sun":    return <svg {...common}><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>;
    case "moon":   return <svg {...common}><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>;
    case "search": return <svg {...common}><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>;
    case "x":      return <svg {...common}><path d="M18 6 6 18M6 6l12 12"/></svg>;
    case "arrow-right": return <svg {...common}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case "sliders": return <svg {...common}><path d="M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6"/></svg>;
    case "chevron-down": return <svg {...common}><path d="m6 9 6 6 6-6"/></svg>;
    case "check":  return <svg {...common}><path d="M20 6 9 17l-5-5"/></svg>;
    case "play":   return <svg {...common}><polygon points="5 3 19 12 5 21 5 3"/></svg>;
    case "open":   return <svg {...common}><path d="M15 3h6v6M10 14 21 3M21 14v7h-7M3 3h7v7"/></svg>;
    case "zap":    return <svg {...common}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>;
    case "key":    return <svg {...common}><circle cx="7.5" cy="15.5" r="4.5"/><path d="m21 2-9.6 9.6M15.5 7.5 19 11"/></svg>;
    case "menu":   return <svg {...common}><path d="M3 12h18M3 6h18M3 18h18"/></svg>;
    case "list":   return <svg {...common}><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></svg>;
    case "grid":   return <svg {...common}><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>;
    case "plus":   return <svg {...common}><path d="M12 5v14M5 12h14"/></svg>;
    case "chevron-right": return <svg {...common}><path d="m9 6 6 6-6 6"/></svg>;
    default: return null;
  }
};

// ---------- theme toggle ----------
function useTheme() {
  const [theme, setTheme] = useState(() => {
    if (typeof window === "undefined") return "dark";
    return localStorage.getItem("snappy-theme") || "dark";
  });
  useEffect(() => {
    const el = document.documentElement;
    if (theme === "dark") el.classList.add("dark"); else el.classList.remove("dark");
    localStorage.setItem("snappy-theme", theme);
  }, [theme]);
  return [theme, setTheme];
}

// ---------- nav ----------
// Top-level tabs where URL path matters (Home, Skills) use real hrefs — full
// navigation so the URL reads `/` or `/skills`. AI/Settings/Linter/Docs stay
// on hash routing for now (they were already hash-mounted panes).
const PATH_TABS = { Home: "/", Skills: "/skills" };
function Nav({ theme, onTheme, activeTab, onTab, user }) {
  const tabs = ["Home", "Skills", "Files", "AI", "Settings", "Linter", "Docs"];
  const authed = user && user.name && user.name !== "Guest";
  const nextPath = typeof window !== "undefined"
    ? (window.location.pathname + window.location.search + window.location.hash)
    : "/";
  return (
    <header className="nav">
      <div className="nav-inner">
        <a href="/" className="nav-brand" aria-label="Snappy home">
          <span className="nav-brand-mark">s</span>
          <span className="nav-brand-word">snappy</span>
        </a>
        <nav className="nav-tabs" aria-label="Primary">
          {tabs.map(t => {
            const pathHref = PATH_TABS[t];
            if (pathHref) {
              return (
                <a key={t} href={pathHref}
                   className={"nav-tab" + (activeTab === t ? " active" : "")}>{t}</a>
              );
            }
            return (
              <a key={t} href={"#" + t.toLowerCase()} className={"nav-tab" + (activeTab === t ? " active" : "")}
                 onClick={e => { e.preventDefault(); onTab(t); }}>{t}</a>
            );
          })}
        </nav>
        <div className="nav-right">
          <button className="btn btn-outline btn-sm" title="OpenRouter key">
            <Icon name="key" size={14}/> OR key
          </button>
          <button className="btn btn-ghost-icon" title={theme === "dark" ? "Switch to light" : "Switch to dark"}
                  onClick={() => onTheme(theme === "dark" ? "light" : "dark")}>
            <Icon name={theme === "dark" ? "sun" : "moon"} size={16}/>
          </button>
          {authed ? (
            <>
              <span className="btn btn-outline btn-sm" title={"Signed in as " + user.name}>
                <span style={{ width:6, height:6, borderRadius:999, background:"oklch(0.62 0.15 145)", display:"inline-block" }} />
                <span style={{textTransform:"capitalize"}}>{user.name}</span>
                {user.email ? <span className="muted mono" style={{marginLeft:6, fontSize:11}}>{user.email}</span> : null}
              </span>
              <form method="POST" action="/logout" style={{margin:0, padding:0, display:"inline-flex"}}>
                <input type="hidden" name="next" value="/"/>
                <button type="submit" className="btn btn-outline btn-sm" title="Sign out">Sign out</button>
              </form>
            </>
          ) : (
            <a className="btn btn-outline btn-sm" href={"/login?next=" + encodeURIComponent(nextPath)} title="Sign in">
              Sign in
            </a>
          )}
        </div>
      </div>
    </header>
  );
}

// ---------- hero + install ----------
function Hero({ totals }) {
  const [copied, setCopied] = useState(false);
  const [variant, setVariant] = useState("pull");
  const commands = {
    pull:   "snappy-os pull --auto",
    verify: "snappy-os doctor",
    push:   "snappy-os push --auto",
  };
  const copy = () => {
    navigator.clipboard?.writeText(commands[variant]).catch(()=>{});
    setCopied(true); setTimeout(()=>setCopied(false), 1400);
  };
  return (
    <section className="hero container-tight">
      <h1>Snappy Skills</h1>
      <div className="hero-meta">
        <span>{totals.skills} skills</span><span className="dot"/>
        <span>{totals.runtimes} runtimes</span><span className="dot"/>
        <span>signed in as Robert</span>
      </div>
      <p className="hero-sub">
        Loaders + verbs any agentic CLI can pick up. Install once; every runtime on the
        machine inherits the same slash-verbs (e.g. <code>/snappy-fix</code>).
      </p>
      <div className="terminal">
        <span className="terminal-prompt">$</span>
        <span className="terminal-cmd mono">{commands[variant]}</span>
        <button className="terminal-copy" onClick={copy} aria-label="Copy install command">
          {copied ? <Icon name="check" size={14}/> : <Icon name="copy" size={14}/>}
        </button>
      </div>
      <div className="install-variants">
        <span className="chip-label">pull</span>
        <button className={"chip-cmd" + (variant==="pull"?" active":"")} onClick={()=>setVariant("pull")} style={variant==="pull"?{background:"var(--card)", color:"var(--foreground)", borderColor:"var(--border)"}:null}>snappy-os pull --auto</button>
        <span className="chip-label" style={{marginLeft:12}}>verify</span>
        <button className={"chip-cmd"} onClick={()=>setVariant("verify")} style={variant==="verify"?{background:"var(--card)", color:"var(--foreground)", borderColor:"var(--border)"}:null}>snappy-os doctor</button>
        <span className="chip-label" style={{marginLeft:12}}>push</span>
        <button className={"chip-cmd"} onClick={()=>setVariant("push")} style={variant==="push"?{background:"var(--card)", color:"var(--foreground)", borderColor:"var(--border)"}:null}>snappy-os push --auto</button>
        <span className="chip-label" style={{marginLeft:12}}>runtimes <Icon name="chevron-down" size={11}/></span>
      </div>
    </section>
  );
}

// ---------- pillars (kernel discipline / multi-runtime / gateway truth) ----------
function Pillars() {
  const items = [
    { kind: "01", title: "Kernel discipline",   body: "Every loader teaches itself. When an agent hits a gap — a missing flag, a wrong selector, a quirk — the loader is edited inline before the session ends. The next agent never re-learns the same lesson." },
    { kind: "02", title: "Multi-runtime reach", body: "One loader, five CLIs — four agentic (Claude, Codex, OpenClaw, Pi) plus context-only Gemini. Each fires the same verb through its native surface, no per-runtime rewrites." },
    { kind: "03", title: "Gateway truth",       body: "Push a loader once; every machine pulls it by SHA from the gateway. The manifest is the source of truth — not any one laptop. Cross-machine drift is measured, not hoped for." },
  ];
  return (
    <div className="pillars">
      {items.map(it => (
        <div className="pillar" key={it.title}>
          <div className="pillar-eyebrow">{it.kind}&nbsp;&nbsp;{it.title}</div>
          <p className="pillar-body">{it.body}</p>
        </div>
      ))}
    </div>
  );
}

// ---------- per-runtime wiring tabs ----------
function Wiring({ runtimes }) {
  const [active, setActive] = useState(runtimes[0].id);
  const cur = runtimes.find(r => r.id === active);
  return (
    <div className="wiring">
      <div className="wiring-tabs" role="tablist">
        {runtimes.map(r => (
          <button key={r.id} role="tab" aria-selected={active===r.id}
                  className={"wiring-tab" + (active===r.id?" active":"")}
                  onClick={()=>setActive(r.id)}>{r.name}</button>
        ))}
      </div>
      <div className="wiring-panel">
        <div>
          <div className="wiring-kind">
            Pick a tab — same install, different wiring per runtime.
            <strong>{cur.tagline.toUpperCase()}</strong>
          </div>
        </div>
        <p className="wiring-body">{cur.body}</p>
      </div>
    </div>
  );
}

// ---------- three pillars (schema / catalog / runtime) ----------
function ThreeFiles() {
  const files = [
    { eyebrow: "SCHEMA",  name: "program.md",         what: "The shape of the system",
      body: "What snappy-os IS. Loops, verbs, evals, the PID contract — the file every agent reads first.", root: "ROOT" },
    { eyebrow: "CATALOG", name: "state/index.md",     what: "What exists and where",
      body: "Living index of 133 skills, libs, bins, lints, recipes — the pointer the agent consults after program.md.", root: "STATE/" },
    { eyebrow: "RUNTIME", name: "snappy-os/CLAUDE.md",what: "How to execute",
      body: "The repo-root CLAUDE.md for snappy-os itself — repo wiring, credential path, rules of operation. (Every project you work on has its own CLAUDE.md; this is the one for the OS.)", root: "REPO ROOT" },
  ];
  return (
    <div className="pillars">
      {files.map(f => (
        <div className="pillar" key={f.name}>
          <div className="pillar-eyebrow">{f.eyebrow}</div>
          <div className="pillar-title">{f.name}</div>
          <div className="pillar-what muted">{f.what}</div>
          <p className="pillar-body">{f.body}</p>
          <div style={{marginTop:14, paddingTop:12, borderTop:"1px solid var(--border)", display:"flex", justifyContent:"space-between", alignItems:"center"}}>
            <span className="mono" style={{fontSize:11, color:"var(--muted-foreground)"}}>{f.root}</span>
            <a href="#" className="btn btn-sm btn-outline">OPEN <Icon name="arrow-right" size={12}/></a>
          </div>
        </div>
      ))}
    </div>
  );
}

// ---------- analyzer ----------
function Analyzer() {
  const [key, setKey] = useState("");
  const [repo, setRepo] = useState("");
  const [fileName, setFileName] = useState("");
  return (
    <div className="analyzer">
      <div className="analyzer-key">
        <div className="analyzer-key-label">OpenRouter key</div>
        <input className="input input-mono" placeholder="sk-or-v1..." value={key} onChange={e=>setKey(e.target.value)} />
        <button className="btn btn-primary btn-sm">Save</button>
        <button className="btn btn-outline btn-sm">Clear</button>
        <span className="mono" style={{fontSize:11, color:"var(--muted-foreground)"}}>{key ? "Saved" : "Not set"}</span>
      </div>
      <div className="analyzer-lanes">
        <div className="analyzer-lane">
          <div className="analyzer-lane-eyebrow">Analyze a GitHub repo</div>
          <p className="analyzer-lane-title">Paste a URL; get a snappy-os configuration proposal.</p>
          <div className="analyzer-row">
            <div className="analyzer-row-label">GitHub repo</div>
            <input className="input input-mono" placeholder="github.com/owner/repo" value={repo} onChange={e=>setRepo(e.target.value)} />
            <button className="btn btn-primary btn-sm">Analyze <Icon name="arrow-right" size={12}/></button>
          </div>
        </div>
        <div className="analyzer-lane">
          <div className="analyzer-lane-eyebrow">Drop a skill file</div>
          <p className="analyzer-lane-title">See how the canonical schema would parse it.</p>
          <div className="analyzer-row">
            <div className="analyzer-row-label">SKILL.md</div>
            <label className="input-file">
              <span className="input-file-btn">Choose file</span>
              <span className="input-file-name">{fileName || "No file chosen"}</span>
              <input type="file" accept=".md" style={{display:"none"}} onChange={e => setFileName(e.target.files?.[0]?.name || "")} />
            </label>
            <span className="mono" style={{fontSize:11, color:"var(--muted-foreground)"}}>{fileName || "No file selected"}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// ---------- search + controls ----------
function Controls({ query, onQuery, lens, onLens, view, onView, totalCount, onNew }) {
  const searchRef = useRef(null);
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "/" && document.activeElement?.tagName !== "INPUT" && document.activeElement?.tagName !== "TEXTAREA") {
        e.preventDefault(); searchRef.current?.focus();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);
  return (
    <div className="catalog-controls">
      <div className="search">
        <span className="search-icon"><Icon name="search" size={16}/></span>
        <input ref={searchRef} className="search-input"
               placeholder={`Search ${totalCount} skills…`}
               value={query} onChange={e => onQuery(e.target.value)} />
        <span className="search-kbd">/</span>
      </div>
      <div className="lens-group" role="radiogroup" aria-label="Sort skills by">
        <span className="lens-btn" style={{cursor:"default"}}>LENS</span>
        {["Importance","Maturity","Usage"].map(v => (
          <button key={v} className={"lens-btn" + (lens===v?" active":"")} role="radio" aria-checked={lens===v} onClick={()=>onLens(v)}>
            <span style={{width:6, height:6, borderRadius:999, background: lens===v ? "var(--primary)" : "var(--border)"}}/>
            {v}
          </button>
        ))}
      </div>
      {onView && (
        <div className="view-toggle" role="radiogroup" aria-label="Catalog view">
          <button className={"view-btn" + (view==="list"?" active":"")} role="radio" aria-checked={view==="list"} onClick={()=>onView("list")} title="Dense list view">
            <Icon name="list" size={13}/><span>List</span>
          </button>
          <button className={"view-btn" + (view==="grid"?" active":"")} role="radio" aria-checked={view==="grid"} onClick={()=>onView("grid")} title="Card grid view">
            <Icon name="grid" size={13}/><span>Grid</span>
          </button>
        </div>
      )}
      <button className="btn btn-primary btn-lg" onClick={onNew}>
        <span style={{fontSize:14, marginRight:2}}>+</span> New skill
      </button>
    </div>
  );
}

// ---------- rail ----------
function CategoryRail({ categories, counts, active, onJump, totals }) {
  return (
    <div className="rail">
      <div className="rail-inner">
        <button className={"rail-btn" + (active==="all"?" active":"")} onClick={()=>onJump("all")}>
          All <span className="count">{totals.skills}</span>
        </button>
        {categories.map(c => (
          counts[c.id] ? (
            <button key={c.id} className={"rail-btn" + (active===c.id?" active":"")} onClick={()=>onJump(c.id)}>
              {c.label} <span className="count">{counts[c.id]}</span>
            </button>
          ) : null
        ))}
      </div>
    </div>
  );
}

// ---------- skill card ----------
function SkillCard({ s, skill, lens, onOpen, active, onRemove }) {
  skill = skill || s;
  const metric = lens === "Importance" ? skill.imp : lens === "Maturity" ? (skill.evals ? 85 : 45) : (50 + (skill.id.length * 3) % 50);
  const evalsClass = skill.evals ? (skill.evals.startsWith("0")?"warn":"ok") : "";
  const handleClick = () => {
    if (typeof onOpen === "function") {
      // Legacy callers pass a function expecting (skill); new callers pass a 0-arg function.
      if (onOpen.length === 0) onOpen();
      else onOpen(skill);
    }
  };
  return (
    <button className={"skill skill-card" + (active?" skill-active":"") + (skill.userAdded?" skill-user":"")} data-cat={skill.cat} data-skill-id={skill.id} onClick={handleClick}>
      <div className="skill-head">
        <span className="skill-icon">{skill.icon}</span>
        <span className="skill-name">{skill.id}</span>
        {skill.userAdded && <span className="skill-user-tag mono">NEW</span>}
        <span className={"skill-health h-" + skill.health} aria-label={skill.health}/>
      </div>
      <p className="skill-blurb">{skill.blurb}</p>
      <div className="skill-foot">
        <span className="skill-size">{skill.size}</span>
        <span>·</span>
        <span className="skill-age">{skill.age}</span>
        {skill.evals && <span className={"skill-evals " + evalsClass}>{skill.evals}</span>}
        {onRemove && (
          <span className="skill-remove"
                onClick={(e) => { e.stopPropagation(); onRemove(); }}
                title="Remove this markdown file"
                role="button" aria-label="Remove">✕</span>
        )}
      </div>
      <div className="skill-bar"><div className="skill-bar-fill" style={{ width: metric + "%" }}/></div>
    </button>
  );
}

// ---------- category section ----------
function CategorySection({ cat, skills, lens, onOpen, collapsed, onToggle }) {
  const sorted = useMemo(() => [...skills].sort((a,b) => {
    if (lens === "Importance") return b.imp - a.imp;
    if (lens === "Maturity")   return (b.evals?1:0) - (a.evals?1:0);
    return a.id.localeCompare(b.id);
  }), [skills, lens]);
  const visible = collapsed ? sorted.slice(0, 6) : sorted;
  return (
    <section className="cat-section" id={"cat-"+cat.id}>
      <header className="cat-header">
        <span className="cat-eyebrow">{cat.label}</span>
        <span className="cat-blurb">{cat.blurb}</span>
        <span className="cat-count">{sorted.length}</span>
      </header>
      <div className="grid">
        {visible.map(s => <SkillCard key={s.id} skill={s} lens={lens} onOpen={onOpen}/>)}
      </div>
      {sorted.length > 6 && (
        <div style={{display:"flex", justifyContent:"center", marginTop: 14}}>
          <button className="btn btn-outline btn-sm" onClick={()=>onToggle(cat.id)}>
            {collapsed ? `Show all ${sorted.length} ${cat.label.toLowerCase()}` : `Show less`}
          </button>
        </div>
      )}
    </section>
  );
}

// ---------- drawer ----------
function SkillDrawer({ skill, onClose }) {
  const open = Boolean(skill);
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    if (open) window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);
  return (
    <>
      <div className="drawer-scrim" data-open={open ? "true" : "false"} onClick={onClose}/>
      <aside className="drawer" data-open={open ? "true" : "false"} aria-hidden={!open}>
        {skill && (
          <>
            <div className="drawer-head">
              <div style={{display:"flex", alignItems:"center", gap:10}}>
                <span className="skill-icon" style={{fontSize:14}}>{skill.icon}</span>
                <span className="drawer-name">{skill.id}</span>
                <span className={"skill-health h-" + skill.health}/>
              </div>
              <button className="btn btn-ghost-icon" onClick={onClose} aria-label="Close">
                <Icon name="x" size={16}/>
              </button>
            </div>
            <div className="drawer-body">
              <div className="drawer-section">
                <div className="drawer-section-label">What it does</div>
                <p>{skill.blurb}</p>
              </div>
              <div className="drawer-section">
                <div className="drawer-section-label">Manifest</div>
                <dl className="drawer-meta">
                  <dt>Category</dt><dd>{skill.cat}</dd>
                  <dt>Size</dt><dd>{skill.size}</dd>
                  <dt>Updated</dt><dd>{skill.age}</dd>
                  <dt>Importance</dt><dd>{skill.imp}/100</dd>
                  <dt>Evals (pass/total)</dt><dd>{skill.evals || "—"}</dd>
                  <dt>Health</dt><dd>{skill.health}</dd>
                </dl>
              </div>
              <div className="drawer-section">
                <div className="drawer-section-label">Trigger phrase</div>
                <div className="drawer-code">{`state/skills/${skill.id}.md\n---\ntrigger: ${skill.id.replace(/-/g,' ')}\ninjects: program.md, state/index.md\n---`}</div>
              </div>
              <div className="drawer-section" style={{display:"flex", gap:8}}>
                <a className="btn btn-primary btn-sm" href="#"><Icon name="play" size={12}/> Run</a>
                <a className="btn btn-outline btn-sm" href="#"><Icon name="open" size={12}/> Open in repo</a>
              </div>
            </div>
          </>
        )}
      </aside>
    </>
  );
}

// ---------- how it works ----------
function HowItWorks() {
  const steps = [
    { n: 1, t: "You type a prompt", b: <>Any runtime: Claude Code, Codex, Gemini CLI, openclaw. The <code>UserPromptSubmit</code> hook reads it before the model does.</> },
    { n: 2, t: "Hook matches trigger phrases", b: <>Scans the prompt for any <code>state/skills/{"<"}name{">"}.agents.md</code> whose frontmatter says <em>triggers on prompt mention of '…'</em>. Up to 2 loaders splice in per turn, plus a one-line pointer to <code>program.md</code> + <code>state/index.md</code>.</> },
    { n: 3, t: "The loader carries the skill's rules", b: <>Critical pitfalls, shape of the inputs, how to eval the result. The full skill body <code>state/skills/{"<"}name{">"}.md</code> is <em>referenced</em>, not injected — the agent opens it only if it needs to.</> },
    { n: 4, t: "Run, score, append", b: <>The verb runs; the Stop hook writes one line to <code>state/log/evals.ndjson</code>. Trend-down scores land the skill in a regen queue. That's the self-healing loop.</> },
  ];
  return (
    <>
      <div className="steps">
        {steps.map(s => (
          <div className="step" key={s.n}>
            <span className="step-num">{s.n}</span>
            <div className="step-title">{s.t}</div>
            <p className="step-body">{s.b}</p>
          </div>
        ))}
      </div>
      <div className="three-things">
        <div className="three-things-cell">
          <span className="eyebrow" style={{color:"var(--primary)"}}>Three things must exist on the machine</span>
          <div style={{marginTop:10}}>
            <strong>hooks</strong>
            <span>~/.claude/hooks/ · ~/.codex/hooks.json</span>
          </div>
        </div>
        <div className="three-things-cell" style={{display:"flex", flexDirection:"column", justifyContent:"flex-end"}}>
          <strong>gateway</strong>
          <span>skills.snappy.ai · one worker, DO Spaces-canonical</span>
        </div>
        <div className="three-things-cell" style={{display:"flex", flexDirection:"column", justifyContent:"flex-end"}}>
          <strong>env</strong>
          <span>env.cache at repo root</span>
        </div>
      </div>
    </>
  );
}

// ---------- stats ----------
function Stats({ totals }) {
  return (
    <>
      <div className="stats">
        <div className="stat">
          <div className="stat-num">{totals.skills}</div>
          <div className="stat-label">skills</div>
        </div>
        <div className="stat">
          <div className="stat-num">{totals.categories}</div>
          <div className="stat-label">categories</div>
        </div>
        <div className="stat">
          <div className="stat-num accent">{totals.loaders}</div>
          <div className="stat-label">with loaders</div>
          <div className="stat-note">auto-injected on trigger</div>
        </div>
        <div className="stat">
          <div className="stat-num">{totals.dormant}</div>
          <div className="stat-label">dormant</div>
          <div className="stat-note">run only when invoked explicitly</div>
        </div>
      </div>
      <div className="paths-row">
        <span className="mono" style={{fontSize:11, color:"var(--muted-foreground)", letterSpacing:"0.08em", textTransform:"uppercase"}}>alongside</span>
        <span className="path-item"><code>state/skills/</code><span>— the rest of <code>state/</code></span></span>
        <span className="path-item"><code>state/lib/</code><span>typescript libs the skills import</span></span>
        <span className="path-item"><code>state/bin/</code><span>sidecars + PID loop engine</span></span>
        <span className="path-item"><code>state/lint/</code><span>structural + contract checks</span></span>
        <span className="path-item"><code>state/log/</code><span>ndjson telemetry (evals, chain, dispatches)</span></span>
        <span className="path-item"><code>state/wiki/</code><span>phase docs — the "why" behind decisions</span></span>
      </div>
    </>
  );
}

// ---------- simulator ----------
function Simulator() {
  const [verb, setVerb] = useState("");
  const [out, setOut] = useState(null);
  const pipeline = [
    { txt: "skill run", accent: true },
    { txt: "state/lib/eval.ts" },
    { txt: "state/log/evals.ndjson" },
    { txt: "state/bin/pid-detect.ts" },
    { txt: "state/log/regen-pending.txt" },
    { txt: "state/bin/pid-drain.ts" },
    { txt: "POST /_push", accent: true },
    { txt: "DO Spaces" },
  ];
  return (
    <div className="simulator">
      <div className="sim-row">
        <input className="input input-mono" placeholder="e.g. image · meeting-followup · content-polish"
               value={verb} onChange={e=>setVerb(e.target.value)} />
        <button className="btn btn-primary btn-sm" onClick={()=>setOut(verb || "image")}>Simulate <Icon name="arrow-right" size={12}/></button>
        <button className="btn btn-outline btn-sm">Lint all 133</button>
        <span className="mono" style={{fontSize:11, color:"var(--muted-foreground)"}}>{out ? `Verb: ${out} — traced 8 steps` : "No verb selected"}</span>
      </div>
      <div className="sim-pipe">
        {pipeline.map((s,i) => (
          <React.Fragment key={i}>
            <span className={"sim-step" + (s.accent?" accent":"")}>{s.txt}</span>
            {i < pipeline.length-1 && <span className="sim-arrow">→</span>}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { Icon, Nav, Hero, Pillars, Wiring, ThreeFiles, Analyzer, Controls, CategoryRail, SkillCard, CategorySection, SkillDrawer, HowItWorks, Stats, Simulator, useTheme });
