/* eslint-disable */
const { useState, useEffect, useRef, useMemo } = React;

// ───────────────────────────────────────────────── analytics helpers
// Renamed to avoid Babel Standalone hoisting `const` → top-level `var`,
// which would alias these onto window.track / window.identify and recurse.
const trk = (name, props) => {
  if (typeof window !== "undefined" && window.track) window.track(name, props || {});
};
const idn = (id, props) => {
  if (typeof window !== "undefined" && window.identify) window.identify(id, props || {});
};
const emailDomain = (e) => (typeof e === "string" && e.includes("@") ? e.split("@")[1].toLowerCase() : "");

// Discord webhook for signup notifications. Public by design (rotate via Discord
// channel settings if abused). Move to a Cloudflare Worker proxy once we're on CF.
const DISCORD_WEBHOOK = "https://discord.com/api/webhooks/1501891830197784756/6UypFWOQpX59_aR9Z219AK3EXxFtHx2vz7i58pqJVZLuJBZZtjWxDe4BxSz7Pk0Cw-3y";

const ROLE_LABELS = {
  founder: "technical founder", cto: "cto", lead: "engineering lead",
  ic: "individual contributor", pm: "product manager",
  designer: "designer", agency: "agency / dev shop",
};

async function sendSignupToDiscord({ email, company, role, building }) {
  const payload = {
    embeds: [{
      title: "new beta signup",
      color: 0xFBBF24,
      fields: [
        { name: "email", value: email || "—", inline: true },
        { name: "role", value: ROLE_LABELS[role] || role || "—", inline: true },
        { name: "company", value: company || "—", inline: false },
        { name: "what they ship", value: (building || "—").slice(0, 1000), inline: false },
      ],
      footer: { text: typeof location !== "undefined" ? location.host : "defract" },
      timestamp: new Date().toISOString(),
    }],
  };
  const res = await fetch(DISCORD_WEBHOOK, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
  if (!res.ok) {
    let detail = "";
    try { detail = (await res.text()).slice(0, 200); } catch (_) {}
    throw new Error(`webhook ${res.status} ${detail}`);
  }
}

// ───────────────────────────────────────────────── consent banner
function Consent() {
  const [state, setState] = useState(() => {
    if (typeof window === "undefined" || !window.consentState) return null;
    return window.consentState();
  });
  if (state) return null;
  const accept = () => { window.acceptConsent && window.acceptConsent(); trk("consent_accept"); setState("accepted"); };
  const decline = () => { window.optOut && window.optOut(); setState("rejected"); };
  const dismiss = () => { window.dismissConsent && window.dismissConsent(); trk("consent_dismiss"); setState("dismissed"); };
  return (
    <div className="consent" role="dialog" aria-label="cookie notice">
      <div className="consent-text">
        we use analytics cookies to understand how the site is used. essentials only otherwise.
      </div>
      <div className="consent-actions">
        <button className="consent-btn" onClick={decline}>decline</button>
        <button className="consent-btn primary" onClick={accept}>accept</button>
      </div>
      <button className="consent-close" onClick={dismiss} aria-label="dismiss">×</button>
    </div>
  );
}

// ───────────────────────────────────────────────── scroll depth
function useScrollDepth() {
  useEffect(() => {
    const marks = [25, 50, 75, 100];
    const fired = new Set();
    const onScroll = () => {
      const doc = document.documentElement;
      const height = doc.scrollHeight - doc.clientHeight;
      if (height <= 0) return;
      const pct = (window.scrollY / height) * 100;
      for (const m of marks) {
        if (pct >= m && !fired.has(m)) { fired.add(m); trk("scroll_depth", { pct: m }); }
      }
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
}

// ───────────────────────────────────────────────── primitives
const Chev = ({ size = 10, color = "#FBBF24", style }) => (
  <svg width={size} height={size} viewBox="0 0 10 10" fill="none" style={style}>
    <path d="M2 1 L8 5 L2 9" stroke={color} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

const ChevSmall = ({ size = 8, op = 1 }) => (
  <span style={{ display: "inline-flex", alignItems: "center", marginLeft: 6, opacity: op, position: "relative", top: "1px" }}>
    <Chev size={size}/>
  </span>
);

// ───────────────────────────────────────────────── nav
function Nav() {
  const [open, setOpen] = useState(false);
  useEffect(() => {
    if (!open) return;
    const onResize = () => { if (window.innerWidth > 768) setOpen(false); };
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, [open]);
  const close = () => setOpen(false);
  return (
    <nav className="nav">
      <a href="#" className="nav-brand" aria-label="defract">
        <span className="brand-text">defract</span>
        <span className="brand-chev">&gt;</span>
      </a>
      <div className="nav-links">
        {[["#how","how it works"],["#stages","pipeline"],["#see","screens"],["#modes","modes"],["#faq","faq"]].map(([h,l]) => (
          <a key={h} href={h} onClick={() => trk("nav_click", { target: h, device: "desktop" })}>{l}</a>
        ))}
      </div>
      <div className="nav-cta">
        <span className="status-pill">
          <span className="pulse-dot" />
          closed beta · invite only
        </span>
        <a href="https://discord.gg/aDyFmpXr" target="_blank" rel="noopener" className="btn-ghost"
           onClick={() => trk("discord_click", { location: "nav" })}>discord<ChevSmall/></a>
        <a href="#signup" className="btn-ghost"
           onClick={() => trk("cta_click", { location: "nav", label: "request access" })}>request access<ChevSmall/></a>
      </div>
      <button
        className="nav-mobile-toggle"
        aria-label={open ? "close menu" : "open menu"}
        aria-expanded={open}
        onClick={() => setOpen((v) => !v)}
      >
        <span/>
      </button>
      <div className={`nav-mobile-drawer ${open ? "open" : ""}`}>
        <span className="status-pill">
          <span className="pulse-dot" />
          closed beta · invite only
        </span>
        {[["#how","how it works"],["#stages","pipeline"],["#see","screens"],["#modes","modes"],["#faq","faq"]].map(([h,l]) => (
          <a key={h} href={h} onClick={() => { close(); trk("nav_click", { target: h, device: "mobile-drawer" }); }}>{l}</a>
        ))}
        <a href="https://discord.gg/aDyFmpXr" target="_blank" rel="noopener"
           onClick={() => { close(); trk("discord_click", { location: "nav-mobile" }); }}>discord</a>
        <a href="#signup"
           onClick={() => { close(); trk("cta_click", { location: "nav-mobile", label: "request access" }); }}>request access</a>
      </div>
    </nav>
  );
}

// ───────────────────────────────────────────────── animated terminal
// ───────────────────────────────────────────────── animated app simulation
const APP_SCRIPT = [
  { t: 0,    kind: "prompt", text: "" },
  { t: 600,  kind: "type",   text: "story new \"add stripe checkout to settings\"" },
  { t: 1700, kind: "log",    text: "→ grooming · pulling context from 47 files…", dim: true },
  { t: 2400, kind: "log",    text: "✓ STORY-142 scoped · 3 acceptance criteria", amber: true },
  { t: 3000, kind: "stage",  stage: "scope" },
  { t: 3700, kind: "stage",  stage: "design" },
  { t: 4400, kind: "log",    text: "  · 2 ux flows proposed", dim: true },
  { t: 5000, kind: "stage",  stage: "architecture" },
  { t: 5600, kind: "log",    text: "  · 4 files · 1 migration · 0 blast radius", dim: true },
  { t: 6300, kind: "stage",  stage: "implementation" },
  { t: 6900, kind: "log",    text: "  ⎇ worktree:STORY-142 · isolated", dim: true },
  { t: 7400, kind: "log",    text: "  + checkout.ts  + CheckoutButton.tsx", amber: true },
  { t: 7900, kind: "log",    text: "  ~ settings/page.tsx (+22 −4)", amber: true },
  { t: 8500, kind: "stage",  stage: "review" },
  { t: 9100, kind: "log",    text: "  · agents reviewed · 0 lint · 12/12 tests", dim: true },
  { t: 9700, kind: "stage",  stage: "release" },
  { t: 10300, kind: "log",   text: "✓ feature live · merged after agent sign-off", amber: true },
];
const STAGES = ["scope", "design", "architecture", "implementation", "review", "release"];

function AppSim() {
  const [tick, setTick] = useState(0);
  const [reset, setReset] = useState(0);
  const startRef = useRef(performance.now());
  const bodyRef = useRef(null);

  useEffect(() => {
    let raf;
    const loop = () => {
      const elapsed = performance.now() - startRef.current;
      setTick(elapsed);
      if (elapsed > 13000) {
        startRef.current = performance.now();
        setReset((r) => r + 1);
      }
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);

  useEffect(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  }, [tick]);

  const visible = APP_SCRIPT.filter((e) => e.t <= tick);
  const stageProgress = visible.filter((e) => e.kind === "stage").map((e) => e.stage);
  const currentStageIdx = Math.max(0, STAGES.indexOf(stageProgress[stageProgress.length - 1] || "scope"));
  const currentStage = STAGES[currentStageIdx];

  const sidebarTasks = [
    { id: "STORY-142", name: "add stripe checkout", state: currentStageIdx >= 5 ? "done" : "active" },
    { id: "STORY-141", name: "improve search ranking", state: "review" },
    { id: "STORY-140", name: "fix oauth redirect loop", state: "done" },
    { id: "STORY-139", name: "settings page polish", state: "done" },
  ];

  return (
    <div className="appsim" key={reset}>
      {/* mac chrome */}
      <div className="appsim-chrome">
        <div className="appsim-dots"><span/><span/><span/></div>
        <div className="appsim-title">defract<span className="brand-chev">&gt;</span></div>
      </div>

      {/* tab bar */}
      <div className="appsim-tabs">
        <div className="appsim-tab">
          <svg width="11" height="11" viewBox="0 0 16 16" fill="none"><rect x="2.5" y="3" width="11" height="10" rx="1.5" stroke="currentColor" strokeWidth="1.3"/><line x1="2.5" y1="6" x2="13.5" y2="6" stroke="currentColor" strokeWidth="1.3"/></svg>
          backlog
        </div>
        <div className="appsim-tab on">
          <Chev size={8}/>
          STORY-142
          <span className="appsim-tab-warn">⚠</span>
        </div>
        <div className="appsim-tab-spacer"/>
        <span className="appsim-icons">
          <span className="appsim-ic"/>
          <span className="appsim-ic"/>
          <span className="appsim-ic appsim-ic-plus">+</span>
        </span>
      </div>

      {/* main split */}
      <div className="appsim-main">
        {/* sidebar */}
        <aside className="appsim-side">
          <div className="appsim-side-brand">
            <span className="appsim-side-brand-text">defract</span>
            <span className="brand-chev">&gt;</span>
          </div>
          <div className="appsim-side-section">tasks</div>
          <div className="appsim-side-tasks">
            {sidebarTasks.map((task, i) => (
              <div key={i} className={`appsim-side-task ${task.state} ${i === 0 ? "current" : ""}`}>
                <Chev size={8} color={i === 0 ? "#FBBF24" : "#57534E"}/>
                <span className="appsim-side-task-name">{task.name}</span>
                {task.state === "review" && <span className="appsim-side-task-pill review">review</span>}
                {task.state === "done"   && <span className="appsim-side-task-pill done">done</span>}
                {task.state === "active" && <span className="appsim-side-task-pill active">{currentStage}</span>}
              </div>
            ))}
          </div>
          <div className="appsim-side-section">
            <span>active elsewhere</span>
            <span className="appsim-side-section-count">3</span>
          </div>
          <div className="appsim-team">
            {[
              { img: "maya.png",   name: "maya n.",   task: "auth · refresh tokens",     stage: "review" },
              { img: "jordan.png", name: "jordan k.", task: "billing · invoices export", stage: "implementation" },
              { img: "ravi.png",   name: "ravi p.",   task: "webhook retry rewrite",     stage: "architecture" },
            ].map((m, i) => (
              <div key={i} className="appsim-team-row">
                <img className="appsim-avatar-img" src={`assets/team/${m.img}`} alt=""/>
                <div className="appsim-team-meta">
                  <div className="appsim-team-name">{m.name}</div>
                  <div className="appsim-team-task">{m.task}</div>
                </div>
                <span className={`appsim-team-stage stage-${m.stage}`}>{m.stage}</span>
              </div>
            ))}
          </div>
          <div className="appsim-side-section">backlog · 45</div>
          <div className="appsim-side-tasks dim">
            {["update designer agent prompt", "add MCP tool for token-eff…", "live phase-progress bar sho…"].map((t, i) => (
              <div key={i} className="appsim-side-task ghost">
                <Chev size={8} color="#44403C"/>
                <span className="appsim-side-task-name">{t}</span>
              </div>
            ))}
          </div>
        </aside>

        {/* content */}
        <div className="appsim-content">
          {/* task header */}
          <div className="appsim-task-head">
            <div className="appsim-task-title">
              add stripe checkout to settings page
            </div>
            <div className="appsim-stages">
              {STAGES.map((s, i) => {
                const done = i < currentStageIdx;
                const active = i === currentStageIdx;
                return (
                  <span key={s} className={`appsim-stage ${done ? "done" : ""} ${active ? "active" : ""}`}>
                    {active && <span className="appsim-stage-pulse"/>}
                    {(done || active) && <Chev size={7}/>}
                    {s}
                  </span>
                );
              })}
            </div>
          </div>

          {/* intel + terminal side by side */}
          <div className="appsim-workspace">
            {/* dynamic intel pane */}
            <div className="appsim-intel" key={currentStage}>
            {currentStage === "scope" && (
              <div className="appsim-pane">
                <div className="appsim-pane-head">
                  <Chev size={9}/>
                  <span>scope preview</span>
                  <span className="appsim-pane-meta">12 criteria · 6 checks · 6 risks</span>
                </div>
                <h4 className="appsim-pane-title">what we're building</h4>
                <p className="appsim-pane-text">
                  add a one-click stripe checkout to the billing settings page. tied to the existing org-level customer record, gated behind <span className="appsim-mono">role:owner</span>. preview deploy → 5% → 25% → 100%.
                </p>
                <div className="appsim-grid-3">
                  <div className="appsim-tile"><div className="appsim-tile-l">criteria</div><div className="appsim-tile-v">12</div></div>
                  <div className="appsim-tile"><div className="appsim-tile-l">checks</div><div className="appsim-tile-v">6</div></div>
                  <div className="appsim-tile"><div className="appsim-tile-l">risks</div><div className="appsim-tile-v amber">6</div></div>
                </div>
              </div>
            )}

            {currentStage === "design" && (
              <div className="appsim-pane">
                <div className="appsim-pane-head">
                  <Chev size={9}/>
                  <span>design proposals</span>
                  <span className="appsim-pane-meta">2 routes · awaiting your pick</span>
                </div>
                <h4 className="appsim-pane-title">two ux flows</h4>
                <div className="appsim-routes">
                  <div className="appsim-route on">
                    <div className="appsim-route-name"><Chev size={8}/>option a · inline modal</div>
                    <div className="appsim-route-meta">stays on /settings/billing · less context loss · matches org-switcher pattern</div>
                  </div>
                  <div className="appsim-route">
                    <div className="appsim-route-name"><span className="appsim-route-x">·</span>option b · /billing/checkout page</div>
                    <div className="appsim-route-meta">deeper link · share-able url · more nav weight</div>
                  </div>
                </div>
              </div>
            )}

            {currentStage === "architecture" && (
              <div className="appsim-pane">
                <div className="appsim-pane-head">
                  <Chev size={9}/>
                  <span>architecture plan</span>
                  <span className="appsim-pane-meta">4 files · 1 migration · blast radius: low</span>
                </div>
                <h4 className="appsim-pane-title">files we'll touch</h4>
                <div className="appsim-files">
                  <div className="appsim-file"><span className="appsim-file-tag add">+</span><span className="appsim-mono">app/api/billing/checkout/route.ts</span><span className="appsim-file-meta">new</span></div>
                  <div className="appsim-file"><span className="appsim-file-tag add">+</span><span className="appsim-mono">components/CheckoutButton.tsx</span><span className="appsim-file-meta">new</span></div>
                  <div className="appsim-file"><span className="appsim-file-tag mod">~</span><span className="appsim-mono">app/settings/billing/page.tsx</span><span className="appsim-file-meta">+22 −4</span></div>
                  <div className="appsim-file"><span className="appsim-file-tag mod">~</span><span className="appsim-mono">db/schema.ts</span><span className="appsim-file-meta">+migration</span></div>
                </div>
              </div>
            )}

            {currentStage === "implementation" && (
              <div className="appsim-pane">
                <div className="appsim-pane-head">
                  <Chev size={9}/>
                  <span>implementation</span>
                  <span className="appsim-pane-meta">⎇ worktree:STORY-142 · isolated</span>
                </div>
                <h4 className="appsim-pane-title">building in parallel</h4>
                <div className="appsim-diff">
                  <div className="appsim-diff-hdr"><span className="appsim-mono">components/CheckoutButton.tsx</span><span className="appsim-diff-stat">+38 −0</span></div>
                  <div className="appsim-diff-line add"><span className="appsim-diff-mark">+</span><span className="appsim-mono">export function CheckoutButton({"{"} planId {"}"}: Props) {"{"}</span></div>
                  <div className="appsim-diff-line add"><span className="appsim-diff-mark">+</span><span className="appsim-mono">  const [loading, setLoading] = useState(false);</span></div>
                  <div className="appsim-diff-line add"><span className="appsim-diff-mark">+</span><span className="appsim-mono">  const onClick = async () =&gt; {"{"} </span></div>
                  <div className="appsim-diff-line add"><span className="appsim-diff-mark">+</span><span className="appsim-mono">    const {"{"} url {"}"} = await api.checkout(planId);</span></div>
                  <div className="appsim-diff-line dim"><span className="appsim-diff-mark"> </span><span className="appsim-mono">    …</span></div>
                </div>
              </div>
            )}

            {currentStage === "review" && (
              <div className="appsim-pane">
                <div className="appsim-pane-head">
                  <Chev size={9}/>
                  <span>review</span>
                  <span className="appsim-pane-meta">agents reviewed · ready to merge</span>
                </div>
                <h4 className="appsim-pane-title">agents signed off</h4>
                <div className="appsim-checks">
                  <div className="appsim-check"><Chev size={9}/><span>typecheck</span><span className="appsim-mono dim">0 errors</span></div>
                  <div className="appsim-check"><Chev size={9}/><span>lint</span><span className="appsim-mono dim">0 warnings</span></div>
                  <div className="appsim-check"><Chev size={9}/><span>tests</span><span className="appsim-mono dim">12 / 12 passing</span></div>
                  <div className="appsim-check"><Chev size={9}/><span>review-agent · architecture</span><span className="appsim-mono dim">approved</span></div>
                  <div className="appsim-check"><Chev size={9}/><span>review-agent · security</span><span className="appsim-mono dim">approved</span></div>
                  <div className="appsim-check"><Chev size={9}/><span>review-agent · ux</span><span className="appsim-mono dim">approved</span></div>
                </div>
              </div>
            )}

            {currentStage === "release" && (
              <div className="appsim-pane">
                <div className="appsim-pane-head">
                  <Chev size={9}/>
                  <span>release</span>
                  <span className="appsim-pane-meta">live · 1h 23m end-to-end</span>
                </div>
                <h4 className="appsim-pane-title">shipped.</h4>
                <p className="appsim-pane-text">stripe checkout is live in billing settings. 5% rollout active. memory updated — next billing story will start with this context.</p>
                <div className="appsim-grid-3">
                  <div className="appsim-tile"><div className="appsim-tile-l">time</div><div className="appsim-tile-v">1h 23m</div></div>
                  <div className="appsim-tile"><div className="appsim-tile-l">phases</div><div className="appsim-tile-v">1</div></div>
                  <div className="appsim-tile"><div className="appsim-tile-l">revisions</div><div className="appsim-tile-v amber">0</div></div>
                </div>
              </div>
            )}
          </div>

            {/* terminal as right column */}
            <div className="appsim-term">
              <div className="appsim-term-head">
                <span className="appsim-term-tab on">terminal</span>
                <span className="appsim-term-tab">activity</span>
                <span className="appsim-term-tab">diff</span>
                <span className="appsim-term-meta">claude code v2.1.126 · ⎇ STORY-142</span>
              </div>
              <div className="appsim-term-body" ref={bodyRef}>
                {visible.map((e, i) => {
                  if (e.kind === "prompt") {
                    return <div key={i} className="appsim-term-line"><span className="appsim-term-prompt">&gt;</span></div>;
                  }
                  if (e.kind === "type") {
                    return (
                      <div key={i} className="appsim-term-line">
                        <span className="appsim-term-prompt">&gt;</span>
                        <span className="appsim-term-cmd">{e.text}</span>
                      </div>
                    );
                  }
                  if (e.kind === "stage") {
                    return (
                      <div key={i} className="appsim-term-line stage">
                        <span className="appsim-term-prompt amber">&gt;</span>
                        <span className="appsim-term-stage">stage · <em>{e.stage}</em></span>
                      </div>
                    );
                  }
                  return (
                    <div key={i} className={`appsim-term-line ${e.dim ? "dim" : ""} ${e.amber ? "amber" : ""}`}>
                      <span>{e.text}</span>
                    </div>
                  );
                })}
                <div className="appsim-term-line">
                  <span className="appsim-term-prompt">&gt;</span>
                  <span className="appsim-term-caret">_</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ───────────────────────────────────────────────── hero
function Hero({ tagline, sub, scarcity, email, setEmail, scrollToSignup }) {
  return (
    <section className="hero">
      <div className="hero-glow" aria-hidden />
      <div className="hero-inner">
        <div className="hero-copy">
          {scarcity !== "none" && (
            <div className="overline">
              <Chev size={9}/>
              <span>{scarcity === "strong" ? "closed beta · invite only" : "closed beta"}</span>
              <span className="overline-sep">·</span>
              <span>opening soon</span>
            </div>
          )}
          <h1 className="hero-title">
            {tagline.split("\n").map((l, i) => (
              <span key={i} className="hero-line">{l}</span>
            ))}
          </h1>
          <p className="hero-sub">{sub}</p>

          <form className="hero-form" onSubmit={(e) => { e.preventDefault(); trk("cta_click", { location: "hero", label: "request access", email_domain: emailDomain(email) }); scrollToSignup(); }}>
            <div className="hero-input-wrap">
              <input className="hero-input" type="email" placeholder="you@yourteam.dev" value={email} onChange={(e) => setEmail(e.target.value)} />
              <button className="hero-submit" type="submit">request access<Chev size={9} color="#0C0C0F"/></button>
            </div>
            <div className="hero-meta">
              <span className="meta-item"><span className="dot-amber"/>closed beta · invite only</span>
              <span className="meta-sep">·</span>
              <span className="meta-item">replies within 48h</span>
            </div>
          </form>
        </div>

        <div className="hero-visual">
          <AppSim />
        </div>
      </div>

      <div className="hero-trust">
        <span className="trust-label">beta · today</span>
        <span className="trust-chip">claude code</span>
        <span className="trust-chip muted">macos</span>
        <span className="trust-sep">→</span>
        <span className="trust-label trust-label-soon">v1 · soon</span>
        <span className="trust-chip">+ codex</span>
        <span className="trust-chip">+ gemini</span>
        <span className="trust-chip">+ opencode</span>
        <span className="trust-chip muted">+ windows · linux</span>
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── value pillars
function Pillars() {
  const items = [
    { n: "01", t: "speed without the slop", d: "blazing fast parallel development. agents review agents — code only ships after it's been verified, typed and tested. quality is the floor, not the trade-off." },
    { n: "02", t: "lower cognitive load", d: "no more ending the day with your head hurting from context-switching. you weigh in on scope, design, architecture. agents handle the rest. you stay above the work, not buried in it." },
    { n: "03", t: "ship in parallel, never collide", d: "every story runs in its own git worktree. multiple agents, multiple humans, multiple features — at the same time, without stepping on each other's toes." },
    { n: "04", t: "one integrated UI", d: "agentic backlog grooming, scoping, design, architecture, implementation, review and release — in one place. no more stitching across six tools and twenty browser tabs." },
  ];
  return (
    <section id="why" className="pillars">
      <div className="section-head">
        <div className="overline overline-static"><Chev size={9}/><span>why defract</span></div>
        <h2 className="section-title">an agentic ide for ai-native teams.</h2>
        <p className="section-sub">defract gives your team a real workflow for working with agents — fast, parallel, and quiet inside your head.</p>
      </div>
      <div className="pillars-grid">
        {items.map((p) => (
          <div key={p.n} className="pillar">
            <div className="pillar-num">{p.n}</div>
            <h3 className="pillar-title">{p.t}</h3>
            <p className="pillar-body">{p.d}</p>
          </div>
        ))}
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── product gallery
const SHOTS = [
  {
    key: "backlog",
    label: "backlog",
    headline: "groomed by agents. shaped by you.",
    desc: "every paste is structured into a story with type, epic, module, size and labels — auto-deduped against the rest of your backlog.",
    src: "assets/screens/backlog.png",
    pos: "0% 0%",
    crop: "60%",
  },
  {
    key: "scope",
    label: "scope preview",
    headline: "see the plan before any code is written.",
    desc: "what we're building, what's out of scope, the workflow, the phase outcomes, the risks. you approve the shape; agents handle the rest.",
    src: "assets/screens/scope-preview.png",
    pos: "100% 0%",
    crop: "55%",
  },
  {
    key: "complete",
    label: "task complete",
    headline: "every story closes with a recap.",
    desc: "what changed, why it changed, time spent, phases run, files touched. shipped features, not pull request archaeology.",
    src: "assets/screens/task-complete.png",
    pos: "100% 0%",
    crop: "55%",
  },
];

function Gallery() {
  const [active, setActive] = useState(0);
  const s = SHOTS[active];
  return (
    <section id="see" className="gallery">
      <div className="section-head">
        <div className="overline overline-static"><Chev size={9}/><span>see it in action</span></div>
        <h2 className="section-title">three screens. one continuous flow.</h2>
        <p className="section-sub">peek at the actual ide. clicking through cohort 02.</p>
      </div>

      <div className="gallery-tabs">
        {SHOTS.map((shot, i) => (
          <button key={shot.key} className={`gallery-tab ${active === i ? "on" : ""}`} onClick={() => { setActive(i); trk("gallery_tab_change", { tab: shot.key }); }}>
            <span className="gallery-tab-num">{String(i + 1).padStart(2, "0")}</span>
            <span className="gallery-tab-label">{shot.label}</span>
          </button>
        ))}
      </div>

      <div className="gallery-stage">
        <div className="gallery-frame">
          <div className="gallery-chrome">
            <div className="shot-dots"><span/><span/><span/></div>
            <div className="shot-title">defract<span className="brand-chev">&gt;</span></div>
            <div className="gallery-chrome-meta">{s.label}</div>
          </div>
          <div className="gallery-img-wrap">
            {SHOTS.map((shot, i) => (
              <img
                key={shot.key}
                src={shot.src}
                alt={shot.label}
                className={`gallery-img ${active === i ? "on" : ""}`}
              />
            ))}
            <div className="gallery-fade" aria-hidden/>
          </div>
        </div>

        <div className="gallery-caption">
          <div className="gallery-caption-num">{String(active + 1).padStart(2, "0")} / {String(SHOTS.length).padStart(2, "0")}</div>
          <h3 className="gallery-caption-title">{s.headline}</h3>
          <p className="gallery-caption-desc">{s.desc}</p>
        </div>
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── stage pipeline section
const STAGE_DETAILS = [
  { key: "scope",          n: "01", verb: "groom",   desc: "agents groom your backlog and turn ideas into structured stories — acceptance criteria, edge cases, success metrics. you approve the shape." },
  { key: "design",         n: "02", verb: "draft",   desc: "ux flows, route choices, copy variants. defract proposes; you pick. this is where humans actually have leverage." },
  { key: "architecture",   n: "03", verb: "plan",    desc: "files to touch, contracts to honor, blast radius. surfaced before code is written, not after. you approve the plan." },
  { key: "implementation", n: "04", verb: "build",   desc: "agents build in an isolated git worktree. multiple stories run in parallel without colliding. battle-proven agents, embedded memory of your codebase." },
  { key: "review",         n: "05", verb: "verify",  desc: "agents review agents. lint · types · tests · diff. you don't hand-review boilerplate — code only progresses once it's signed off." },
  { key: "release",        n: "06", verb: "ship",    desc: "preview, stage, release. the story closes when it's live. memory updates so the next one is smarter." },
];

function StagePipeline() {
  const [active, setActive] = useState(0);
  return (
    <section id="stages" className="stages">
      <div className="section-head">
        <div className="overline overline-static"><Chev size={9}/><span>the pipeline</span></div>
        <h2 className="section-title">scope to release. one continuous flow.<br/><span className="muted-line">humans approve the decisions. agents do the work.</span></h2>
      </div>

      <div className="stage-rail">
        {STAGE_DETAILS.map((s, i) => (
          <button
            key={s.key}
            className={`stage-node ${i <= active ? "filled" : ""} ${i === active ? "current" : ""}`}
            onClick={() => { setActive(i); trk("pipeline_stage_view", { stage: s.key, source: "click" }); }}
            onMouseEnter={() => setActive(i)}
          >
            <span className="stage-node-dot"/>
            <span className="stage-node-num">{s.n}</span>
            <span className="stage-node-label">{s.key}</span>
          </button>
        ))}
        <div className="stage-rail-line" style={{ width: `calc(${(active / (STAGE_DETAILS.length - 1)) * 100}% * (5/6))` }}/>
      </div>

      <div className="stage-detail">
        <div className="stage-detail-num">{STAGE_DETAILS[active].n}<span className="stage-detail-verb">/{STAGE_DETAILS[active].verb}</span></div>
        <div className="stage-detail-body">
          <h3 className="stage-detail-title">{STAGE_DETAILS[active].key}</h3>
          <p className="stage-detail-desc">{STAGE_DETAILS[active].desc}</p>
        </div>
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── how defract works (mechanism)
function HowItWorks() {
  const items = [
    { n: "01", t: "deep claude code integration", d: "not a wrapper. defract speaks claude code's protocol natively — full tool access, full context, zero round-trip overhead. v1 adds codex, gemini, opencode the same way." },
    { n: "02", t: "battle-proven agents", d: "scoping, design, architecture, implementation, review — each role is a specialist agent, tuned and stress-tested across thousands of stories before they ever touch your repo." },
    { n: "03", t: "embedded memory & learnings", d: "defract remembers your codebase, your decisions, your conventions. every shipped story sharpens the next one. the system gets smarter the more you use it." },
    { n: "04", t: "git worktrees, orchestrated", d: "every story gets its own worktree. agents work in isolation, in parallel, without ai slop spilling into main. clean diffs. clean history. no collisions." },
    { n: "05", t: "you decide. agents execute.", d: "you weigh in on scope, design and architecture. agents implement, review and gate the merge. you see working features, not 800-line diffs to babysit." },
  ];
  return (
    <section id="how" className="how">
      <div className="section-head">
        <div className="overline overline-static"><Chev size={9}/><span>how it works</span></div>
        <h2 className="section-title">five ideas, working together.</h2>
      </div>
      <div className="how-grid how-grid-5">
        {items.map((s) => (
          <div key={s.n} className="how-card">
            <div className="how-num">{s.n}</div>
            <h3 className="how-title">{s.t}</h3>
            <p className="how-body">{s.d}</p>
          </div>
        ))}
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── modes
function Modes() {
  const [mode, setMode] = useState("autopilot");
  const data = {
    autopilot: {
      label: "autopilot",
      tag: "for velocity",
      title: "autopilot.",
      desc: "you set the destination. defract drives. agents groom, scope, design, build, review and merge — only stopping at the gates you choose. ideal for confident teams who trust the flow.",
      bullets: [
        "optional review gates at any stage",
        "agents merge after their own sign-off",
        "you ship features, not commits",
        "ideal for parallel, high-volume work",
      ],
      term: [
        { p: ">",  c: "story queue --auto" },
        { l: "✓ STORY-141 · live · 12m", amber: true },
        { l: "✓ STORY-142 · live · 18m", amber: true },
        { l: "⎇ STORY-143 · in review",  dim: true },
        { l: "⎇ STORY-144 · building",   dim: true },
      ],
    },
    hitl: {
      label: "human-in-the-loop",
      tag: "for control",
      title: "human-in-the-loop.",
      desc: "you control the flow. agents pause at every stage and hand you the wheel. approve scope, approve design, approve architecture, watch implementation, sign off the release. for the work where you want eyes on every step.",
      bullets: [
        "explicit approval at every stage",
        "agents wait for your green light",
        "diff you actually want to read",
        "ideal for risky, high-blast-radius work",
      ],
      term: [
        { p: ">",  c: "story open STORY-901 --review-each" },
        { l: "  scope · awaiting approval", dim: true },
        { l: "→ approved",                  amber: true },
        { l: "  architecture · awaiting approval", dim: true },
        { l: "→ approved",                  amber: true },
      ],
    },
  };
  const m = data[mode];
  return (
    <section id="modes" className="modes">
      <div className="section-head">
        <div className="overline overline-static"><Chev size={9}/><span>two modes</span></div>
        <h2 className="section-title">work the way you want to work.</h2>
        <p className="section-sub">every story can run on autopilot or with you in the loop. you decide the leash, story by story.</p>
      </div>

      <div className="modes-tabs">
        {Object.entries(data).map(([k, v]) => (
          <button key={k} className={`modes-tab ${mode === k ? "on" : ""}`} onClick={() => { setMode(k); trk("mode_change", { mode: k }); }}>
            <span className="modes-tab-tag">{v.tag}</span>
            <span className="modes-tab-label">{v.label}</span>
          </button>
        ))}
      </div>

      <div className="modes-card">
        <div className="modes-card-copy">
          <h3 className="modes-card-title">{m.title}</h3>
          <p className="modes-card-desc">{m.desc}</p>
          <ul className="modes-card-list">
            {m.bullets.map((b, i) => (
              <li key={i}><Chev size={9}/><span>{b}</span></li>
            ))}
          </ul>
        </div>
        <div className="modes-card-visual">
          <div className="mini-term">
            <div className="mini-term-chrome">
              <span/><span/><span/>
              <span className="mini-term-title">{m.label}</span>
            </div>
            <div className="mini-term-body">
              {m.term.map((line, i) => (
                <div key={i} className={`term-line ${line.dim ? "dim" : ""} ${line.amber ? "amber" : ""}`}>
                  {line.p && <span className="term-prompt">{line.p}</span>}
                  {line.c ? <span className="term-cmd">{line.c}</span> : <span>{line.l}</span>}
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── persona / who it's for
function ForWhom() {
  const fits = [
    "your team ships to production every week, not every quarter",
    "you want leverage per engineer — not more engineers",
    "you've outgrown chatting with a single agent in a single tab",
    "you want speed without giving up types, tests, and clean diffs",
    "you're tired of agents stepping on each other's branches",
  ];
  const notFits = [
    "you want a no-code builder",
    "your codebase is closed-source and air-gapped",
    "you want agents to merge into main without any oversight",
  ];
  return (
    <section className="for-whom">
      <div className="section-head">
        <div className="overline overline-static"><Chev size={9}/><span>built for</span></div>
        <h2 className="section-title">ai-native teams that want to ship fast.</h2>
      </div>
      <div className="fw-grid">
        <div className="fw-col">
          <div className="fw-col-head fw-yes">
            <Chev size={11}/>
            <span>you, if</span>
          </div>
          <ul className="fw-list">
            {fits.map((f, i) => <li key={i}><Chev size={9}/><span>{f}</span></li>)}
          </ul>
        </div>
        <div className="fw-col">
          <div className="fw-col-head fw-no">
            <span className="fw-x">×</span>
            <span>not yet, if</span>
          </div>
          <ul className="fw-list fw-list-muted">
            {notFits.map((f, i) => <li key={i}><span className="fw-x">×</span><span>{f}</span></li>)}
          </ul>
        </div>
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── faq
const FAQS = [
  { q: "what is defract, exactly?", a: "an agentic ide for ai-native teams. scoping, design, architecture, implementation, review and release — in a single integrated ui, with deep claude code integration and a memory system that learns your codebase." },
  { q: "how is it different from just using claude code in a terminal?", a: "claude code is a great cli. defract is the workflow on top — multi-stage, multi-agent, parallel, with embedded memory and git worktree orchestration. one agent is the engine; defract is the chassis." },
  { q: "do humans review code, or do agents?", a: "agents review code. humans approve scope, design and architecture, then see the working feature. code only merges after agents have signed it off — that's the whole point. you stay above the diff, not buried in it." },
  { q: "what stops agents from stepping on each other's work?", a: "every story runs in its own git worktree. parallel work is isolated by default — multiple agents, multiple humans, multiple features at the same time, with zero collisions and no slop bleeding into main." },
  { q: "what runs in the closed beta vs the full v1?", a: "beta: claude code on macos. v1: claude code + codex + gemini + opencode, on macos + windows + linux. the beta is for pressure-testing the workflow before we widen the surface." },
  { q: "what if i want to control every step?", a: "switch the story to human-in-the-loop. agents pause at every stage and hand you the wheel. perfect for high-blast-radius work." },
  { q: "where do you hang out?", a: "in our discord. that's where the team lives, where bugs get triaged, and where roadmap conversations happen." },
];

function FAQ() {
  const [open, setOpen] = useState(0);
  return (
    <section id="faq" className="faq">
      <div className="section-head">
        <div className="overline overline-static"><Chev size={9}/><span>faq</span></div>
        <h2 className="section-title">questions you'll ask anyway.</h2>
      </div>
      <div className="faq-list">
        {FAQS.map((f, i) => {
          const isOpen = open === i;
          return (
            <button key={i} className={`faq-item ${isOpen ? "open" : ""}`} onClick={() => { const willOpen = !isOpen; setOpen(willOpen ? i : -1); if (willOpen) trk("faq_open", { question: f.q }); }}>
              <div className="faq-q">
                <span className="faq-q-text">{f.q}</span>
                <span className={`faq-q-mark ${isOpen ? "rot" : ""}`}><Chev size={11}/></span>
              </div>
              <div className="faq-a-wrap">
                <div className="faq-a-inner">
                  <p className="faq-a">{f.a}</p>
                </div>
              </div>
            </button>
          );
        })}
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── signup
function SignupForm({ email, setEmail }) {
  const [submitted, setSubmitted] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState({ company: "", role: "", building: "" });
  const sectionRef = useRef(null);
  const startedRef = useRef(false);
  const viewedRef = useRef(false);
  const fieldsCompletedRef = useRef(new Set());

  // signup_view — fire once when the section enters the viewport
  useEffect(() => {
    if (!sectionRef.current || viewedRef.current) return;
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (e.isIntersecting && !viewedRef.current) {
          viewedRef.current = true;
          trk("signup_view");
          io.disconnect();
        }
      }
    }, { threshold: 0.3 });
    io.observe(sectionRef.current);
    return () => io.disconnect();
  }, []);

  const onFieldFocus = (field) => {
    if (!startedRef.current) {
      startedRef.current = true;
      trk("signup_start", { field });
    }
  };

  const onFieldBlur = (field, value) => {
    if (value && String(value).trim() && !fieldsCompletedRef.current.has(field)) {
      fieldsCompletedRef.current.add(field);
      trk("signup_field_complete", { field });
    }
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    if (submitting) return;
    const dom = emailDomain(email);
    trk("signup_submit", {
      email_domain: dom,
      role: data.role,
      has_company: !!data.company.trim(),
      building_len: data.building.trim().length,
    });
    idn(email, {
      email,
      email_domain: dom,
      company: data.company,
      role: data.role,
      building: data.building,
    });
    setSubmitting(true);
    setError(null);
    try {
      await sendSignupToDiscord({ email, ...data });
      setSubmitted(true);
    } catch (err) {
      trk("signup_error", { message: String(err && err.message || err).slice(0, 200) });
      setError("couldn't send right now. try again, or ping us on discord.");
    } finally {
      setSubmitting(false);
    }
  };

  useEffect(() => {
    if (submitted) {
      trk("signup_success", { email_domain: emailDomain(email), role: data.role });
      if (window.gtag) window.gtag("event", "generate_lead", { value: 1, currency: "USD" });
    }
  }, [submitted]);

  if (submitted) {
    return (
      <section id="signup" className="signup">
        <div className="signup-card signup-done">
          <div className="signup-mark"><Chev size={20}/></div>
          <h2 className="signup-done-title">request received.</h2>
          <p className="signup-done-sub">we'll email <strong>{email}</strong> within 48 hours. in the meantime, come say hi in <a href="https://discord.gg/aDyFmpXr" target="_blank" rel="noopener" onClick={() => trk("discord_click", { location: "signup-done" })}>discord</a>.</p>
          <div className="signup-done-meta">
            <span><Chev size={9}/>request received</span>
            <span><Chev size={9}/>queued for review</span>
          </div>
        </div>
      </section>
    );
  }
  return (
    <section id="signup" className="signup" ref={sectionRef}>
      <div className="signup-card">
        <div className="signup-head">
          <div className="overline overline-static"><Chev size={9}/><span>request access</span></div>
          <h2 className="signup-title">request access.</h2>
          <p className="signup-sub">tell us about your team. we'll get back within 48 hours.</p>
        </div>
        <form onSubmit={onSubmit} className="signup-form">
          <div className="field">
            <label>email</label>
            <input required type="email" value={email}
              onChange={(e) => setEmail(e.target.value)}
              onFocus={() => onFieldFocus("email")}
              onBlur={(e) => onFieldBlur("email", e.target.value)}
              placeholder="you@yourteam.dev"/>
          </div>
          <div className="field-row">
            <div className="field">
              <label>team / company</label>
              <input required value={data.company}
                onChange={(e) => setData({ ...data, company: e.target.value })}
                onFocus={() => onFieldFocus("company")}
                onBlur={(e) => onFieldBlur("company", e.target.value)}
                placeholder="acme inc."/>
            </div>
            <div className="field">
              <label>role</label>
              <select required value={data.role}
                onChange={(e) => { setData({ ...data, role: e.target.value }); onFieldBlur("role", e.target.value); }}
                onFocus={() => onFieldFocus("role")}
                className={data.role ? "" : "placeholder"}>
                <option value="" disabled hidden>select your role</option>
                <option value="founder">technical founder</option>
                <option value="cto">cto</option>
                <option value="lead">engineering lead</option>
                <option value="ic">individual contributor</option>
                <option value="pm">product manager</option>
                <option value="designer">designer</option>
                <option value="agency">agency / dev shop</option>
              </select>
            </div>
          </div>
          <div className="field">
            <label>what does your team ship?</label>
            <textarea required rows={3} value={data.building}
              onChange={(e) => setData({ ...data, building: e.target.value })}
              onFocus={() => onFieldFocus("building")}
              onBlur={(e) => onFieldBlur("building", e.target.value)}
              placeholder="one sentence is fine. seriously."/>
          </div>
          {error && (
            <div className="signup-error" role="alert">{error}</div>
          )}
          <div className="signup-actions">
            <span className="signup-fineprint">no spam. one email when your access opens.</span>
            <button type="submit" className="btn-amber" disabled={submitting}>
              {submitting ? "sending…" : <>request access<Chev size={10} color="#0C0C0F"/></>}
            </button>
          </div>
        </form>
      </div>
    </section>
  );
}

// ───────────────────────────────────────────────── footer
function Footer() {
  return (
    <footer className="footer">
      <div className="footer-row">
        <div className="footer-brand">
          <span>defract</span><span className="brand-chev">&gt;</span>
        </div>
        <div className="footer-links">
          <a href="https://discord.gg/aDyFmpXr" target="_blank" rel="noopener"
             onClick={() => trk("discord_click", { location: "footer" })}>discord</a>
        </div>
        <div className="footer-meta">© 2026 defract · agentic ide for ai-native teams</div>
      </div>
    </footer>
  );
}

// ───────────────────────────────────────────────── tweaks defaults
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "tagline": "ship at agent speed.\nwithout the slop.",
  "sub": "defract is the agentic ide for ai-native teams. you approve scope, design and architecture. agents groom, build, review and release — in parallel, in their own git worktrees, without stepping on each other's toes.",
  "scarcity": "strong",
  "showTerminal": true
}/*EDITMODE-END*/;

// ───────────────────────────────────────────────── app
function App() {
  const [t, setTweaks] = (window.useTweaks || ((d) => [d, () => {}]))(TWEAK_DEFAULTS);
  const Tw = window.TweaksPanel;
  const [email, setEmail] = useState("");
  useScrollDepth();
  const scrollToSignup = () => {
    const el = document.getElementById("signup");
    if (el) {
      const y = el.getBoundingClientRect().top + window.scrollY - 80;
      window.scrollTo({ top: y, behavior: "smooth" });
      setTimeout(() => {
        const inputs = el.querySelectorAll("input, select, textarea");
        let target = inputs[0];
        if (email && email.trim()) {
          for (const i of inputs) {
            if (i.type !== "email" && !i.value) { target = i; break; }
          }
          if (target === inputs[0]) target = inputs[1] || inputs[0];
        }
        target?.focus({ preventScroll: true });
      }, 600);
    }
  };

  return (
    <div className="page">
      <Nav />
      <Hero tagline={t.tagline} sub={t.sub} scarcity={t.scarcity} email={email} setEmail={setEmail} scrollToSignup={scrollToSignup}/>
      <Pillars />
      <Gallery />
      <StagePipeline />
      <HowItWorks />
      <Modes />
      <ForWhom />
      <FAQ />
      <SignupForm email={email} setEmail={setEmail}/>
      <Footer />
      <Consent />

      {Tw && (
        <Tw title="Tweaks">
          <window.TweakSection title="hero">
            <window.TweakText label="tagline (use \\n for break)" value={t.tagline.replace(/\n/g, "\\n")} onChange={(v) => setTweaks("tagline", v.replace(/\\n/g, "\n"))}/>
            <window.TweakText label="subhead" value={t.sub} onChange={(v) => setTweaks("sub", v)} multiline/>
          </window.TweakSection>
          <window.TweakSection title="tone">
            <window.TweakRadio label="scarcity" value={t.scarcity} onChange={(v) => setTweaks("scarcity", v)} options={[
              { value: "none",   label: "none"   },
              { value: "subtle", label: "subtle" },
              { value: "strong", label: "strong" },
            ]}/>
          </window.TweakSection>
        </Tw>
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
