/* global React, Icon, Eyebrow, Serif, Rule, DATA,
   VehicleFork, BeliefRanker, AudienceDoorways, SuccessPasses, AssumptionRanker, OpeningQuestions */
/* =====================================================================
   THE STORY LAB — a companion working surface, reached from Narrative (09).
   Not a tenth stratum. A discovery instrument Alisa fills in and revisits.

   Persistence is keyed separately from the descent's position AND from the
   descent's capture store, mirroring the site's existing localStorage pattern
   (see primitives.jsx · useCapture / readStore / writeStore).
   ===================================================================== */
const { useState: uS, useEffect: uE, useRef: uR, useCallback: uCb,
        useContext: uCx, createContext: createCtx } = React;

/* ---- Lab store (own namespace) ------------------------------------ */
const LAB_KEY = "sounding-line.storylab.v1";
function readLab() {
  try { return JSON.parse(localStorage.getItem(LAB_KEY) || "{}"); }
  catch (e) { return {}; }
}
function writeLab(obj) {
  try { localStorage.setItem(LAB_KEY, JSON.stringify(obj)); } catch (e) {}
  window.dispatchEvent(new CustomEvent("lab-change"));
}
/* value hook — fallback used when the key was never written */
function useLab(id, fallback) {
  const [val, setVal] = uS(() => { const s = readLab(); return id in s ? s[id] : fallback; });
  const set = uCb((v) => { setVal(v); const s = readLab(); s[id] = v; writeLab(s); }, [id]);
  uE(() => {
    const sync = () => { const s = readLab(); setVal((cur) => { const nv = id in s ? s[id] : fallback; return nv === cur ? cur : nv; }); };
    window.addEventListener("lab-change", sync);
    return () => window.removeEventListener("lab-change", sync);
  }, [id]);
  return [val, set];
}
/* field hook — raw===null means the field was never touched (so seeds can show) */
function useLabField(id) {
  const [raw, setRaw] = uS(() => { const s = readLab(); return id in s ? s[id] : null; });
  const set = uCb((v) => { setRaw(v); const s = readLab(); s[id] = v; writeLab(s); }, [id]);
  uE(() => {
    const sync = () => { const s = readLab(); setRaw((cur) => { const nv = id in s ? s[id] : null; return nv === cur ? cur : nv; }); };
    window.addEventListener("lab-change", sync);
    return () => window.removeEventListener("lab-change", sync);
  }, [id]);
  return [raw, set];
}

/* ---- Context: which tweaks the fields respond to ------------------ */
const LabContext = createCtx({ showSeeds: true, serifQ: false });

/* ---- Marker + tags ------------------------------------------------ */
function TurnMarker() {
  return (
    <span style={{ width: 18, height: 18, border: "1px solid var(--signal)", display: "inline-flex",
      alignItems: "center", justifyContent: "center", flex: "0 0 auto" }}>
      <Icon name="arrowRight" size={11} />
    </span>
  );
}
function LabTag({ kind }) {
  const turn = kind === "turn";
  return (
    <span style={{ fontFamily: "var(--font-mono)", fontSize: 9, letterSpacing: "0.14em",
      textTransform: "uppercase", padding: "3px 7px", whiteSpace: "nowrap", lineHeight: 1,
      color: turn ? "var(--signal)" : "var(--fg2)",
      border: `1px solid ${turn ? "var(--signal)" : "var(--fog)"}` }}>
      {turn ? "Your turn" : "Seed"}
    </span>
  );
}

/* ---- Editable field (auto-grow textarea, seed/turn aware) --------- */
function LabField({ id, label, seed, placeholder, kind = "turn", minRows = 2 }) {
  const { showSeeds } = uCx(LabContext);
  const [raw, setRaw] = useLabField(id);
  const ref = uR(null);
  const touched = raw !== null && raw !== undefined;
  const value = touched ? raw : (kind === "seed" && showSeeds && seed ? seed : "");
  const ph = kind === "seed" ? (seed || placeholder) : (placeholder || "");
  const grow = () => { const el = ref.current; if (el) { el.style.height = "auto"; el.style.height = Math.max(el.scrollHeight, 22) + "px"; } };
  uE(() => { grow(); }, [value]);
  return (
    <div className={kind === "turn" ? "lab-turn" : "lab-seed"}>
      {label && (
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between",
          gap: 10, marginBottom: 8 }}>
          <span style={{ display: "flex", alignItems: "center", gap: 10,
            fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.1em",
            textTransform: "uppercase", color: kind === "turn" ? "var(--signal)" : "var(--fg2)" }}>
            {kind === "turn" && <TurnMarker />}{label}
          </span>
          <LabTag kind={kind} />
        </div>
      )}
      <textarea ref={ref} value={value} rows={minRows} placeholder={ph}
        onChange={(e) => setRaw(e.target.value)} onInput={grow}
        className="focus-ring lab-field" spellCheck={false} />
    </div>
  );
}

/* ---- Section shell ------------------------------------------------ */
function LabSection({ data, children, spine }) {
  const { serifQ } = uCx(LabContext);
  return (
    <section style={{ maxWidth: 1000, margin: "0 auto",
      padding: "clamp(48px,8vh,104px) clamp(24px,5vw,72px) clamp(28px,4vh,44px)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 18 }}>
        <Eyebrow style={{ color: spine ? "var(--signal)" : "var(--fg2)" }}>{data.eyebrow}</Eyebrow>
        {spine && (
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 9, letterSpacing: "0.14em",
            textTransform: "uppercase", color: "var(--signal)", border: "1px solid var(--signal)",
            padding: "3px 7px", lineHeight: 1 }}>The spine</span>
        )}
      </div>
      <h2 style={{
        fontFamily: serifQ ? "var(--font-serif)" : "var(--font-sans)",
        fontStyle: serifQ ? "italic" : "normal", fontWeight: serifQ ? 400 : 900,
        fontSize: serifQ ? "clamp(34px,5vw,62px)" : "clamp(28px,4vw,52px)",
        letterSpacing: serifQ ? 0 : "-0.03em", lineHeight: serifQ ? 1.04 : 1.0,
        color: "var(--ink)", margin: 0, maxWidth: "18ch" }}>{data.title}</h2>
      {data.lead && (
        <p style={{ color: "var(--ash)", fontSize: "clamp(16px,1.5vw,19px)", lineHeight: 1.55,
          margin: "22px 0 0", maxWidth: "60ch" }}>{data.lead}</p>
      )}
      <div style={{ marginTop: "clamp(26px,4vh,40px)" }}>{children}</div>
    </section>
  );
}

/* ============================ SECTIONS (light) ====================== */

/* STAGE 00 — Frame -------------------------------------------------- */
function LabFrame({ data }) {
  return (
    <LabSection data={data}>
      <div style={{ maxWidth: "64ch" }}>
        <p style={{ color: "var(--ink)", fontSize: "clamp(18px,1.8vw,22px)", lineHeight: 1.5,
          fontWeight: 500, margin: 0 }}>{data.job}</p>
      </div>
    </LabSection>
  );
}

/* STAGE 01 — What we heard (seed reference) ------------------------- */
function LabHeard({ data }) {
  return (
    <LabSection data={data}>
      <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.1em",
        color: "var(--fg2)", marginBottom: 18, display: "flex", alignItems: "center", gap: 10 }}>
        <LabTag kind="seed" /> {data.note}
      </div>
      <div style={{ borderTop: "1px solid var(--ink)" }}>
        {data.items.map((it, i) => (
          <div key={i} style={{ display: "flex", gap: 16, alignItems: "baseline", padding: "15px 0",
            borderBottom: "1px solid var(--fog)" }}>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--signal)",
              flex: "0 0 auto", paddingTop: 2 }}>{String(i + 1).padStart(2, "0")}</span>
            <span style={{ fontSize: 16, lineHeight: 1.5, color: "var(--ink)" }}>{it}</span>
          </div>
        ))}
      </div>
    </LabSection>
  );
}

/* STAGE 03 — Find the core ------------------------------------------ */
function LabCore({ data }) {
  return (
    <LabSection data={data}>
      <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.14em",
        textTransform: "uppercase", color: "var(--fg2)", marginBottom: 14,
        display: "flex", alignItems: "center", gap: 10 }}>
        Candidates <span style={{ flex: 1, height: 1, background: "var(--fog)" }} /> <LabTag kind="seed" />
      </div>
      <div style={{ border: "1px solid var(--ink)" }}>
        {data.seeds.map((s, i) => (
          <div key={s.id} style={{ display: "grid", gridTemplateColumns: "minmax(96px,120px) 1fr",
            gap: 18, padding: "14px 16px", alignItems: "start",
            borderBottom: i < data.seeds.length - 1 ? "1px solid var(--fog)" : "none" }} className="lab-core-row">
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.1em",
              textTransform: "uppercase", color: "var(--fg2)", paddingTop: 8 }}>{s.fmt}</div>
            <LabField id={"core.seed." + s.id} seed={s.body} kind="seed" minRows={1} />
          </div>
        ))}
      </div>
      <div style={{ marginTop: 30, border: "1px solid var(--signal)", padding: "clamp(20px,3vw,30px)",
        background: "rgba(214,74,31,0.05)" }}>
        <LabField id="core.her" kind="turn" label={data.turnLabel}
          placeholder={data.turnPlaceholder} minRows={2} />
      </div>
    </LabSection>
  );
}

/* STAGE 09 — Empty-room test ---------------------------------------- */
function LabEmptyRoom({ data }) {
  const Words = ({ words, fail }) => (
    <div style={{ display: "flex", flexWrap: "wrap", gap: 10 }}>
      {words.map((w) => (
        <span key={w} style={{ fontFamily: "var(--font-sans)", fontWeight: fail ? 500 : 900,
          fontSize: fail ? "clamp(18px,2.4vw,26px)" : "clamp(24px,3.6vw,44px)", letterSpacing: "-0.02em",
          color: fail ? "var(--fg2)" : "var(--ink)",
          textDecoration: fail ? "line-through" : "none",
          textDecorationColor: "var(--fog)" }}>{w}{fail ? "" : "."}</span>
      ))}
    </div>
  );
  return (
    <LabSection data={data}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(260px,1fr))",
        gap: "clamp(20px,4vw,48px)", alignItems: "start" }}>
        <div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.14em",
            textTransform: "uppercase", color: "var(--fg2)", marginBottom: 14 }}>It passes when</div>
          <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex",
            flexDirection: "column", gap: 12 }}>
            {data.passes.map((p, i) => (
              <li key={i} style={{ display: "flex", gap: 12, alignItems: "baseline" }}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--signal)",
                  flex: "0 0 auto" }}>{i + 1}</span>
                <span style={{ fontSize: 16.5, lineHeight: 1.45, color: "var(--ink)" }}>{p}</span>
              </li>
            ))}
          </ul>
        </div>
        <div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.14em",
            textTransform: "uppercase", color: "var(--signal)", marginBottom: 14 }}>The three-word target</div>
          <Words words={data.target} />
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.14em",
            textTransform: "uppercase", color: "var(--fg2)", margin: "26px 0 12px" }}>If they say this, it hasn't landed</div>
          <Words words={data.fail} fail />
        </div>
      </div>
      <div style={{ marginTop: 34, borderTop: "1px solid var(--fog)", paddingTop: 26, maxWidth: 640 }}>
        <LabField id="emptyroom.result" kind="turn" label={data.turnLabel}
          placeholder={data.turnPlaceholder} minRows={2} />
      </div>
    </LabSection>
  );
}

/* ============================ THE SHELL ============================= */
const LAB_CSS = `
  .lab-field{width:100%;box-sizing:border-box;background:transparent;border:0;
    border-bottom:1px solid var(--ink);border-radius:0;color:var(--ink);
    font-family:var(--font-sans);font-size:17px;line-height:1.5;resize:none;
    outline:none;overflow:hidden;padding:8px 2px;display:block;}
  .lab-field::placeholder{color:var(--fog);}
  .lab-field:focus{border-bottom-color:var(--signal);}
  .lab-turn .lab-field{min-height:22px;}
  .lab-railbtn{transition:background var(--dur-fast) var(--ease);}
  .lab-railbtn:hover{background:var(--bone);}
  .lab-drag-over{box-shadow:inset 0 2px 0 0 var(--signal);}
  .lab-drag-ghost{opacity:.35;}
  .lab-grip{cursor:grab;}
  .lab-grip:active{cursor:grabbing;}
  @media (max-width:940px){
    .lab-rail{display:none !important;}
    .lab-topbar{display:flex !important;}
    .lab-scroll{padding-top:55px;}
    .lab-core-row{grid-template-columns:1fr !important;gap:6px !important;}
  }
  @media (min-width:941px){ .lab-topbar{display:none !important;} }
`;

function StoryLabView({ onExit, narrow, tweaks }) {
  const L = DATA.storylab;
  const scrollRef = uR(null);
  const sectionRefs = uR({});
  const [active, setActive] = uS(L.frame.id);

  const SECTIONS = [
    { data: L.frame, Comp: LabFrame },
    { data: L.heard, Comp: LabHeard },
    { data: L.vehicles, Comp: VehicleFork },
    { data: L.core, Comp: LabCore },
    { data: L.beliefs, Comp: BeliefRanker },
    { data: L.doorways, Comp: AudienceDoorways },
    { data: L.success, Comp: SuccessPasses },
    { data: L.assumptions, Comp: AssumptionRanker },
    { data: L.openings, Comp: OpeningQuestions },
    { data: L.emptyRoom, Comp: LabEmptyRoom },
  ];

  uE(() => { if (scrollRef.current) scrollRef.current.scrollTop = 0; }, []);
  uE(() => {
    const root = scrollRef.current; if (!root) return;
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) setActive(e.target.dataset.labId); });
    }, { root, rootMargin: "-45% 0px -45% 0px", threshold: 0 });
    Object.values(sectionRefs.current).forEach((el) => el && obs.observe(el));
    return () => obs.disconnect();
  }, []);

  const jump = (id) => {
    const el = sectionRefs.current[id], root = scrollRef.current;
    if (el && root) root.scrollTo({ top: root.scrollTop + (el.getBoundingClientRect().top - root.getBoundingClientRect().top) - 20, behavior: "smooth" });
  };

  const ctx = { showSeeds: tweaks ? tweaks.labSeeds !== false : true, serifQ: !!(tweaks && tweaks.serifQ) };

  return (
    <LabContext.Provider value={ctx}>
      <style>{LAB_CSS}</style>
      <div role="region" aria-label="The Story Lab" style={{ position: "fixed", inset: 0, zIndex: 70,
        background: "var(--paper)", display: "flex", animation: "sl-fade var(--dur) var(--ease)" }}>
        <div style={{ position: "absolute", top: 0, left: 0, right: 0, height: 3, background: "var(--ink)", zIndex: 3 }} />

        {/* ---- left rail (wide; hidden ≤940 via CSS so it can't desync from JS) ---- */}
        <nav className="lab-rail" aria-label="Story Lab sections" style={{ width: 250, flex: "0 0 250px",
            borderRight: "1px solid var(--ink)", background: "var(--paper)", display: "flex",
            flexDirection: "column", paddingTop: 26, position: "relative", height: "100%" }}>
            <div style={{ padding: "0 22px 16px" }}>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.16em",
                color: "var(--fg2)", textTransform: "uppercase" }}>The Sounding Line</div>
              <div style={{ fontFamily: "var(--font-sans)", fontWeight: 900, fontSize: 16,
                letterSpacing: "-0.02em", marginTop: 4 }}>The Story Lab</div>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.06em",
                color: "var(--signal)", textTransform: "uppercase", marginTop: 5 }}>A working surface</div>
            </div>
            <div style={{ height: 1, background: "var(--fog)" }} />
            <div style={{ flex: 1, overflowY: "auto", padding: "8px 0" }}>
              {SECTIONS.map((s) => {
                const on = active === s.data.id;
                return (
                  <button key={s.data.id} onClick={() => jump(s.data.id)} className="focus-ring lab-railbtn"
                    style={{ all: "unset", cursor: "pointer", display: "flex", alignItems: "baseline", gap: 12,
                      width: "100%", boxSizing: "border-box", padding: "9px 22px",
                      borderLeft: `2px solid ${on ? "var(--signal)" : "transparent"}` }}>
                    <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.1em",
                      color: on ? "var(--signal)" : "var(--fg2)", flex: "0 0 auto" }}>{s.data.coord}</span>
                    <span style={{ fontFamily: "var(--font-sans)", fontSize: 13.5, lineHeight: 1.2,
                      fontWeight: on ? 700 : 500, color: on ? "var(--ink)" : "var(--ash)",
                      letterSpacing: "-0.01em" }}>{s.data.nav}{s.data.spine && <span style={{ color: "var(--signal)" }}> ·</span>}</span>
                  </button>
                );
              })}
            </div>
            <div style={{ borderTop: "1px solid var(--fog)", padding: "14px 22px 18px" }}>
              <button onClick={onExit} className="focus-ring" style={{ all: "unset", cursor: "pointer",
                display: "flex", alignItems: "center", justifyContent: "center", gap: 10, width: "100%",
                boxSizing: "border-box", border: "1px solid var(--ink)", padding: "10px 12px",
                fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase" }}>
                <Icon name="arrowLeft" size={14} /> Back to the descent
              </button>
            </div>
          </nav>

        {/* ---- compact top bar (narrow) ---- */}
        <div className="lab-topbar" style={{ display: "none", position: "fixed", top: 3, left: 0, right: 0,
          zIndex: 4, background: "var(--paper)", borderBottom: "1px solid var(--ink)",
          alignItems: "center", gap: 12, padding: "10px 16px" }}>
          <button onClick={onExit} className="focus-ring" style={{ all: "unset", cursor: "pointer",
            width: 34, height: 34, display: "inline-flex", alignItems: "center", justifyContent: "center",
            border: "1px solid var(--ink)" }} aria-label="Back to the descent"><Icon name="arrowLeft" size={16} /></button>
          <div style={{ fontFamily: "var(--font-sans)", fontWeight: 900, fontSize: 14,
            letterSpacing: "-0.01em" }}>The Story Lab</div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.12em",
            color: "var(--signal)", textTransform: "uppercase", marginLeft: "auto" }}>Working surface</div>
        </div>

        {/* ---- scroll area ---- */}
        <div ref={scrollRef} className="lab-scroll" style={{ flex: 1, overflowY: "auto", position: "relative" }}>
          {/* header */}
          <header style={{ maxWidth: 1000, margin: "0 auto",
            padding: "clamp(44px,7vh,92px) clamp(24px,5vw,72px) 0" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: "clamp(28px,4vh,44px)" }}>
              <span style={{ fontFamily: "var(--font-sans)", fontWeight: 900, fontSize: 13,
                letterSpacing: "0.02em" }}>DARK HORSE WORKS</span>
              <span style={{ width: 5, height: 5, background: "var(--fg2)" }} />
              <Eyebrow style={{ color: "var(--signal)" }}>{L.meta.eyebrow}</Eyebrow>
            </div>
            <h1 style={{ fontFamily: "var(--font-sans)", fontWeight: 900,
              fontSize: "clamp(44px,7vw,104px)", letterSpacing: "-0.04em", lineHeight: 0.92,
              color: "var(--ink)", margin: 0 }}>{L.meta.title}</h1>
            <p style={{ color: "var(--ash)", fontSize: "clamp(17px,1.7vw,21px)", lineHeight: 1.55,
              margin: "clamp(24px,4vh,36px) 0 0", maxWidth: "62ch" }}>{L.meta.lead}</p>
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 26,
              fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.06em", color: "var(--fg2)" }}>
              <span style={{ width: 18, height: 18, border: "1px solid var(--fg2)", display: "inline-flex",
                alignItems: "center", justifyContent: "center" }}><Icon name="check" size={11} /></span>
              {L.meta.persist}
            </div>
          </header>

          {/* sections */}
          {SECTIONS.map((s) => (
            <div key={s.data.id} data-lab-id={s.data.id}
              ref={(el) => { sectionRefs.current[s.data.id] = el; }}>
              <s.Comp data={s.data} />
            </div>
          ))}

          {/* footer — preserve the confidential / IP notice */}
          <footer style={{ maxWidth: 1000, margin: "0 auto",
            padding: "12px clamp(24px,5vw,72px) clamp(56px,9vh,120px)" }}>
            <div style={{ borderTop: "3px solid var(--ink)", paddingTop: 16 }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center",
                flexWrap: "wrap", gap: 12 }}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.14em",
                  textTransform: "uppercase", color: "var(--fg2)" }}>The Story Lab · a working surface for Alisa Ellis</span>
                <button onClick={onExit} className="focus-ring" style={{ all: "unset", cursor: "pointer",
                  display: "inline-flex", alignItems: "center", gap: 8, fontFamily: "var(--font-mono)",
                  fontSize: 10, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--ink)" }}>
                  <Icon name="arrowLeft" size={13} /> Return to Narrative · 09
                </button>
              </div>
              <p style={{ fontFamily: "var(--font-mono)", fontSize: 10, lineHeight: 1.6,
                color: "var(--fg2)", margin: "12px 0 0", maxWidth: "78ch" }}>
                © 2026 Dark Horse Works. All rights reserved. Confidential and proprietary. This material and the
                ideas, frameworks, and methods within it are the intellectual property of Dark Horse Works and may
                not be reproduced, distributed, or used without written permission.
              </p>
            </div>
          </footer>
        </div>
      </div>
    </LabContext.Provider>
  );
}

/* ---- Entry affordance (rendered on the Narrative stop) ------------ */
function StoryLabEntry() {
  const L = DATA.storylab;
  const enter = () => window.dispatchEvent(new CustomEvent("enter-storylab"));
  return (
    <div style={{ marginTop: 48, border: "1px solid var(--ink)", background: "var(--bone)",
      padding: "clamp(24px,4vw,40px)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 18, flexWrap: "wrap" }}>
        <Eyebrow style={{ color: "var(--signal)" }}>The companion surface</Eyebrow>
        <span style={{ width: 5, height: 5, background: "var(--fg2)" }} />
        <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.14em",
          textTransform: "uppercase", color: "var(--fg2)" }}>You fill this one in</span>
      </div>
      <div style={{ fontFamily: "var(--font-serif)", fontStyle: "italic",
        fontSize: "clamp(24px,3.4vw,40px)", lineHeight: 1.14, color: "var(--ink)", maxWidth: "20ch" }}>
        The descent found the story. The Story Lab is where you make it yours.
      </div>
      <p style={{ color: "var(--ash)", fontSize: 16.5, lineHeight: 1.55, margin: "20px 0 0", maxWidth: "56ch" }}>
        A working surface, not a finished pitch. Choose the vehicle, find the core, rank the beliefs, and design the
        first door. The seeds are only a place to push against. Corrections are the currency.
      </p>
      <button onClick={enter} className="focus-ring" style={{ all: "unset", cursor: "pointer",
        display: "inline-flex", alignItems: "center", gap: 12, marginTop: 28,
        background: "var(--ink)", color: "var(--paper)", padding: "16px 24px",
        fontFamily: "var(--font-sans)", fontSize: 15, fontWeight: 500, letterSpacing: "0.01em" }}>
        Enter the Story Lab <Icon name="arrowRight" size={17} />
      </button>
    </div>
  );
}

Object.assign(window, {
  LAB_KEY, readLab, writeLab, useLab, useLabField, LabContext,
  TurnMarker, LabTag, LabField, LabSection,
  LabFrame, LabHeard, LabCore, LabEmptyRoom,
  StoryLabView, StoryLabEntry,
});
