function mount(ctx) {
  if (!ctx || !ctx.el || !ctx.el.querySelectorAll) return;
  var root = ctx.el;
  var API = (typeof PREFIX === "string") ? PREFIX : "";  // PREFIX is the shell global
  var SCOPE_ID = (typeof SCOPE === "string" && SCOPE) ? SCOPE : "o4ec433b5.dac0f7b0d6b";
  var SCOPE_Q = "?scope=" + encodeURIComponent(SCOPE_ID);
  var KEY = "acsetra.site.v1";
  var SCREENS = ["home", "process", "build", "lot", "surgery", "racks", "investors", "pricing", "contact"];
  var timers = [];

  function later(fn, ms) {
    var id = setTimeout(fn, ms);
    timers.push(id);
    return id;
  }

  function one(sel) { return root.querySelector(sel); }
  function all(sel) { return Array.prototype.slice.call(root.querySelectorAll(sel)); }

  // === the visitor record ==================================================
  // Everything the site knows lives in ONE object, saved locally, and every
  // fact in it is shown back to the visitor in the ledger — except the two
  // steering weights (o, i), which are internal and never displayed.
  var storage = null;
  try {
    if (typeof window !== "undefined" && window.localStorage) storage = window.localStorage;
  } catch (e) { storage = null; }

  var now = Date.now();
  var state = null;
  if (storage) {
    try { state = JSON.parse(storage.getItem(KEY) || "null"); } catch (e) { state = null; }
  }
  if (!state || typeof state !== "object" || !state.v) {
    state = { v: "v-" + Math.random().toString(36).slice(2, 10), first: now, last: now,
              visits: 1, screens: {}, doors: [], biz: "", app: null, ops: null,
              recs: [], o: 0, i: 0 };
  } else {
    if (!state.screens || typeof state.screens !== "object") state.screens = {};
    if (!Array.isArray(state.recs)) state.recs = [];
    if (!Array.isArray(state.doors)) state.doors = [];
    if (now - (state.last || 0) > 1800000) state.visits = (state.visits || 1) + 1;
    state.last = now;
  }

  function save() {
    state.last = Date.now();
    if (!storage) return;
    try { storage.setItem(KEY, JSON.stringify(state)); } catch (e) {}
  }

  function bump(o, i) { state.o += o || 0; state.i += i || 0; save(); }

  // an arrival mark: a fund's or YC's link identifies the reader before a click
  try {
    var q = String(window.location.search || "");
    if (/[?&](from|utm_source)=(yc|investor|fund)/i.test(q)) bump(0, 3);
  } catch (e) {}

  // === server calls ========================================================
  function post(path, body) {
    return fetch(path, {
      method: "POST", credentials: "same-origin",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(body)
    }).then(function (r) {
      return r.json().catch(function () { return {}; }).then(function (data) {
        if (!r.ok) {
          var err = new Error((data && data.error) || ("HTTP " + r.status));
          err.status = r.status;
          throw err;
        }
        return data;
      });
    });
  }

  function waitRun(id, onDone, onFail) {
    var tries = 0;
    function poll() {
      if (tries++ > 70) { onFail(new Error("timeout")); return; }
      fetch(PREFIX + "/runs/" + id + SCOPE_Q, { credentials: "same-origin" })
        .then(function (r) { return r.json(); })
        .then(function (d) {
          var l = d && d.launch;
          if (!l) { onFail(new Error("lost run")); return; }
          if (l.status === "done") { onDone(l); return; }
          if (l.status === "error") { onFail(new Error(l.error || "run failed")); return; }
          if (l.status === "waiting_on_auth") { onFail(new Error("parked")); return; }
          later(poll, 500);
        })
        .catch(function (e) { onFail(e); });
    }
    poll();
  }

  function runPipe(code, input, onDone, onFail) {
    post(PREFIX + "/run" + SCOPE_Q, { pipeline: code, input: input })
      .then(function (d) { waitRun(d.launch, onDone, onFail); })
      .catch(function (e) { onFail(e); });
  }

  // === navigation ==========================================================
  var FORWARD_LABELS = {
    process: "Watch Runner build a working app →",
    build: "Watch Runner build a working app →",
    lot: "See the five-day event app →",
    surgery: "See a surgery center on one database →",
    racks: "See the rack system for 250 managers →",
    pricing: "What a deployment costs →",
    investors: "See the company numbers →",
    contact: "Talk to us →"
  };
  var FORWARD_DEFAULT = { lot: "surgery", surgery: "racks", racks: "pricing" };

  function seen(code) { return !!state.screens[code]; }

  function forwardTarget(from) {
    // The one adaptive choice per screen: an investor-leaning reader who has
    // not seen the numbers is pointed there; everyone else walks the operator
    // chain, skipping screens they have already opened.
    if (state.i > state.o && !seen("investors")) return "investors";
    var t = FORWARD_DEFAULT[from] || "pricing";
    var chain = [t, "surgery", "racks", "process", "pricing", "contact"];
    for (var k = 0; k < chain.length; k++) {
      var c = chain[k];
      // a visitor who already built skips the explainer and lands on the demo
      if (c === "process" && state.app) c = "build";
      if (c !== from && !seen(c)) return c;
    }
    return "contact";
  }

  function retargetForwards() {
    all("[data-forward]").forEach(function (btn) {
      var from = btn.getAttribute("data-forward") || "";
      var to = forwardTarget(from);
      btn.setAttribute("data-forward-to", to);
      btn.textContent = FORWARD_LABELS[to] || "Continue →";
    });
  }

  function showScreen(code, fromHash) {
    if (SCREENS.indexOf(code) < 0) code = "home";
    root.setAttribute("data-screen", code);
    all("[data-screen-section]").forEach(function (sec) {
      if (sec.getAttribute("data-screen-section") === code) sec.removeAttribute("hidden");
      else sec.setAttribute("hidden", "");
    });
    if (!state.screens[code]) {
      state.screens[code] = Date.now();
      if (code === "investors") bump(0, 3);
      if (code === "pricing") bump(2, 0);
      if (code === "lot" || code === "surgery" || code === "racks") bump(2, 0);
    }
    save();
    retargetForwards();
    renderThread();
    if (!fromHash) {
      try { window.location.hash = (code === "home") ? "" : code; } catch (e) {}
    }
    try { window.scrollTo(0, 0); } catch (e) {}
  }

  root.querySelectorAll("[data-nav]").forEach(function (el) {
    ctx.on(el, "click", function (ev) {
      if (ev && ev.preventDefault) ev.preventDefault();
      var door = el.getAttribute("data-door");
      if (door && state.doors.indexOf(door) < 0) {
        state.doors.push(door);
        if (door === "build") bump(1, 0);
        else bump(2, 0);
      }
      if (el.getAttribute("data-kind") === "investor") bump(0, 2);
      showScreen(el.getAttribute("data-nav") || "home");
    });
  });

  root.querySelectorAll("[data-forward]").forEach(function (btn) {
    ctx.on(btn, "click", function () {
      showScreen(btn.getAttribute("data-forward-to") || forwardTarget(""));
    });
  });

  ctx.on(root, "pointermove", function (ev) {
    if (!ev || !root.getBoundingClientRect) return;
    var rect = root.getBoundingClientRect();
    if (!rect.width || !rect.height) return;
    var px = Math.max(0, Math.min(100, ((ev.clientX - rect.left) / rect.width) * 100));
    var py = Math.max(0, Math.min(100, ((ev.clientY - rect.top) / rect.height) * 100));
    root.style.setProperty("--rf-px", px.toFixed(1) + "%");
    root.style.setProperty("--rf-py", py.toFixed(1) + "%");
  });

  ctx.on(window, "hashchange", function () {
    var h = String(window.location.hash || "").replace("#", "");
    showScreen(SCREENS.indexOf(h) >= 0 ? h : "home", true);
  });

  // === the build demo ======================================================
  var narrate = one("[data-narrate]");
  var rowstream = one("[data-rowstream]");
  var panel = one("[data-panel]");
  var built = one("[data-built]");
  var builtLine = one("[data-built-line]");
  var bizInput = one("[data-biz-input]");
  var buildBtn = one("[data-build-go]");
  var building = false;

  var sayTimer = null;
  function say(text) {
    if (!narrate) return;
    if (sayTimer) { clearTimeout(sayTimer); sayTimer = null; }
    if (!text) { narrate.setAttribute("hidden", ""); narrate.textContent = ""; return; }
    narrate.removeAttribute("hidden");
    var full = String(text);
    var at = 0;
    narrate.textContent = "";
    function type() {
      at = Math.min(full.length, at + 3);
      narrate.textContent = full.slice(0, at) + (at < full.length ? "▌" : "");
      if (at < full.length) { sayTimer = setTimeout(type, 16); timers.push(sayTimer); }
      else sayTimer = null;
    }
    type();
  }

  function chip(text, delay) {
    if (!rowstream) return;
    later(function () {
      var c = document.createElement("span");
      c.className = "rf-row-chip";
      c.textContent = text;
      rowstream.appendChild(c);
    }, delay);
  }

  function el(tag, cls, text) {
    var n = document.createElement(tag);
    if (cls) n.className = cls;
    if (text) n.textContent = text;
    return n;
  }

  function fieldInput(f, first, app) {
    var input;
    if (f.type === "select") {
      input = document.createElement("select");
      input.className = "rf-panel-input";
      (f.options || []).forEach(function (o) {
        var opt = document.createElement("option");
        opt.value = o; opt.textContent = o;
        input.appendChild(opt);
      });
    } else {
      input = document.createElement("input");
      input.className = "rf-panel-input";
      input.type = (f.type === "date") ? "date" : (f.type === "phone") ? "tel"
        : (f.type === "email") ? "email" : "text";
      if (first && app.placeholder) input.placeholder = app.placeholder;
    }
    input.setAttribute("data-field-key", f.key);
    return input;
  }

  var KIND_WORDS = {
    intake: "form", pipeline: "pipeline", booking: "booking sheet",
    inventory: "counter", approvals: "queue", tasks: "checklist",
    waitlist: "waitlist", feedback: "feedback card", quote: "quote builder",
    loyalty: "loyalty card"
  };

  // every interaction in a spawned app writes a row — that IS the demo
  function writeEvent(values, label, okMsg) {
    var rec = { values: values, label: label || "", created: Date.now() };
    state.recs.push(rec);
    save();
    renderLedger();
    say("writing the row…");
    runPipe("add-record", { visitor: state.v, noun: values.event || "record", values: values },
      function () { say(okMsg || "row written · it will be here when you come back"); },
      function () { say("the row write failed — it is kept on this device"); });
    return rec;
  }

  function renderEventLog(host, title) {
    host.appendChild(el("div", "rf-panel-list-title", title));
    var list = document.createElement("ul");
    list.className = "rf-panel-list";
    host.appendChild(list);
    var recs = state.recs.slice(-6).reverse();
    if (!recs.length) {
      list.appendChild(el("li", "rf-panel-list-item", "Nothing yet — touch the app above."));
      return list;
    }
    recs.forEach(function (r) {
      var li = el("li", "rf-panel-list-item");
      var text = r.label;
      if (!text) {
        var vals = r.values || {};
        for (var k in vals) { if (vals[k]) { text = vals[k]; break; } }
      }
      li.appendChild(el("span", "rf-panel-list-text", text || "row"));
      li.appendChild(el("span", "rf-panel-list-meta",
        new Date((r.created || 0)).toLocaleTimeString()));
      list.appendChild(li);
    });
    return list;
  }

  function mkBtn(label, accent, filled, small) {
    var b = el("button", "rf-mini-act", label);
    b.type = "button";
    b.style.cssText = "cursor:pointer;font-weight:700;border-radius:999px;transition:transform 120ms ease;"
      + (small ? "font-size:11px;padding:5px 12px;" : "font-size:13px;padding:8px 16px;");
    b.style.border = "1px solid " + accent;
    b.style.background = filled ? accent : "transparent";
    b.style.color = filled ? "#FFFFFF" : accent;
    return b;
  }

  function mkInput(placeholder, radius) {
    var i = document.createElement("input");
    i.type = "text";
    i.className = "rf-panel-input";
    i.placeholder = placeholder || "";
    i.style.borderRadius = Math.max(4, Math.round(radius * 0.6)) + "px";
    return i;
  }

  // --- intake: the classic form + records -------------------------------
  function renderIntake(app, d) {
    var subs = state.recs.filter(function (r) { return !(r.values || {}).event; });
    var todayN = subs.filter(function (r) { return sameDay(r.created); }).length;
    statStrip(panel, d, [
      [String(subs.length), (app.noun || "record") + "s"],
      [String(todayN), "today"],
      [String((app.fields || []).length), "fields"]
    ]);
    var form = el("div", "rf-panel-form");
    if (d.compact) form.style.gap = "8px";
    (app.fields || []).forEach(function (f, idx) {
      var wrap = el("label", "rf-panel-field");
      wrap.appendChild(el("span", "rf-panel-label", f.label));
      var inp = fieldInput(f, idx === 0, app);
      inp.style.borderRadius = Math.max(4, Math.round(d.radius * 0.6)) + "px";
      if (d.compact) inp.style.padding = "8px 11px";
      wrap.appendChild(inp);
      form.appendChild(wrap);
    });
    var noun = app.noun || "record";
    var submit = mkBtn("Add " + noun + " →", d.accent, true);
    submit.style.alignSelf = "flex-start";
    form.appendChild(submit);
    panel.appendChild(form);
    ctx.on(submit, "click", function () {
      var values = {};
      var any = false;
      Array.prototype.forEach.call(panel.querySelectorAll("[data-field-key]"), function (inp) {
        var v = String(inp.value || "").trim();
        if (v) any = true;
        values[inp.getAttribute("data-field-key")] = v;
      });
      if (!any) { say("give the " + noun + " at least one value"); return; }
      var first = "";
      for (var k in values) { if (values[k]) { first = values[k]; break; } }
      writeEvent(values, first);
      renderActive();
    });
    renderEventLog(panel, "RECORDS");
  }

  // --- pipeline: a mini CRM whose cards advance -------------------------
  function pipelineCards(app) {
    var stages = app.stages || [];
    var cards = {};
    (app.samples || []).forEach(function (s) {
      if (s && s.name) cards[s.name] = { stage: 0, detail: s.detail || "" };
    });
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "add" && v.card && !cards[v.card]) cards[v.card] = { stage: 0, detail: "" };
      if (v.event === "advance" && v.card && cards[v.card]) {
        var to = parseInt(v.to_index, 10);
        if (to >= 0 && to < stages.length) cards[v.card].stage = to;
      }
    });
    return cards;
  }

  function renderPipeline(app, d) {
    var stages = app.stages || [];
    var cards = pipelineCards(app);
    var noun = app.card_noun || "card";
    var totalC = 0, wonC = 0;
    for (var cn in cards) { totalC++; if (cards[cn].stage === stages.length - 1) wonC++; }
    statStrip(panel, d, [
      [String(totalC), noun + "s"],
      [String(wonC), "closed"],
      [totalC ? Math.round(wonC / totalC * 100) + "%" : "0%", "win rate"]
    ]);
    var addRow = el("div", "rf-panel-form");
    addRow.style.cssText = "flex-direction:row;gap:8px;margin-bottom:16px;";
    var addInp = mkInput("a new " + noun, d.radius);
    addInp.style.flex = "1";
    var addBtn = mkBtn("Add", d.accent, true, true);
    addRow.appendChild(addInp);
    addRow.appendChild(addBtn);
    panel.appendChild(addRow);
    ctx.on(addBtn, "click", function () {
      var name = String(addInp.value || "").trim().slice(0, 24);
      if (!name) { say("name the " + noun + " first"); return; }
      writeEvent({ event: "add", card: name }, "add · " + name);
      renderActive();
    });
    stages.forEach(function (stage, si) {
      var head = el("div", "rf-panel-list-title", stage.toUpperCase());
      head.style.borderTop = si === 0 ? "none" : "";
      head.style.paddingTop = si === 0 ? "0" : "";
      var count = 0;
      for (var n in cards) { if (cards[n].stage === si) count += 1; }
      head.textContent = stage.toUpperCase() + " · " + count;
      if (count) head.style.color = d.accent;
      panel.appendChild(head);
      for (var name in cards) {
        if (cards[name].stage !== si) continue;
        (function (cardName) {
          var li = el("div", "rf-panel-list-item");
          var left = el("span", "rf-panel-list-text", cardName
            + (cards[cardName].detail ? " — " + cards[cardName].detail : ""));
          li.appendChild(left);
          if (si < stages.length - 1) {
            var adv = mkBtn(stages[si + 1] + " →", d.accent, false, true);
            li.appendChild(adv);
            ctx.on(adv, "click", function () {
              writeEvent({ event: "advance", card: cardName, to: stages[si + 1],
                           to_index: String(si + 1) },
                "advance · " + cardName + " → " + stages[si + 1]);
              renderActive();
            });
          } else {
            var doneChip = el("span", "rf-panel-list-meta", "✓");
            doneChip.style.color = d.accent;
            li.appendChild(doneChip);
          }
          panel.appendChild(li);
        })(name);
      }
    });
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- booking: a slot grid you can actually book -----------------------
  function renderBooking(app, d) {
    var days = app.days || [];
    var times = app.times || [];
    var noun = app.slot_noun || "booking";
    var booked = {};
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "book" && v.day && v.time) booked[v.day + "|" + v.time] = v.name || "booked";
    });
    var totalSlots = days.length * times.length;
    var bookedN = Object.keys(booked).length;
    statStrip(panel, d, [
      [bookedN + "/" + totalSlots, "slots booked"],
      [(totalSlots ? Math.round(bookedN / totalSlots * 100) : 0) + "%", "utilization"],
      [String(totalSlots - bookedN), "open"]
    ]);
    var who = mkInput("who is this " + noun + " for?", d.radius);
    who.style.cssText += "width:100%;margin-bottom:12px;";
    panel.appendChild(who);
    var grid = el("div", "rf-book-grid");
    grid.style.cssText = "display:grid;gap:6px;margin-bottom:6px;"
      + "grid-template-columns:56px repeat(" + days.length + ", minmax(0, 1fr));";
    grid.appendChild(el("span", "rf-panel-list-meta", ""));
    days.forEach(function (day) {
      var h = el("span", "rf-panel-label", day);
      h.style.textAlign = "center";
      grid.appendChild(h);
    });
    times.forEach(function (time) {
      var t = el("span", "rf-panel-list-meta", time);
      t.style.alignSelf = "center";
      grid.appendChild(t);
      days.forEach(function (day) {
        var key = day + "|" + time;
        var slot = el("button", "rf-book-slot", booked[key] || "—");
        slot.type = "button";
        slot.style.cssText = "cursor:pointer;font-size:11px;padding:9px 4px;overflow:hidden;"
          + "text-overflow:ellipsis;white-space:nowrap;border-radius:"
          + Math.max(4, Math.round(d.radius * 0.5)) + "px;";
        if (booked[key]) {
          slot.style.background = d.accent;
          slot.style.border = "1px solid " + d.accent;
          slot.style.color = "#FFFFFF";
          slot.style.cursor = "default";
        } else {
          slot.style.background = "transparent";
          slot.style.border = "1px dashed " + hexToRgba(d.accent, 0.5);
          slot.style.color = "#64748B";
          ctx.on(slot, "click", function () {
            if (booked[key]) return;
            var name = String(who.value || "").trim().slice(0, 18);
            if (!name) { say("type a name above, then pick the slot"); return; }
            writeEvent({ event: "book", day: day, time: time, name: name },
              "book · " + day + " " + time + " · " + name);
            renderActive();
          });
        }
        grid.appendChild(slot);
      });
    });
    panel.appendChild(grid);
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- inventory: live counters ------------------------------------------
  function inventoryItems(app) {
    var items = (app.items || []).slice();
    var known = {};
    items.forEach(function (it) { known[it.name] = true; });
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "additem" && v.item && !known[v.item]) {
        known[v.item] = true;
        items.push({ name: v.item, qty: 5, unit: "units" });
      }
    });
    return items;
  }

  function inventoryQty(app) {
    var qty = {};
    inventoryItems(app).forEach(function (it) { qty[it.name] = it.qty; });
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "adjust" && v.item in qty) {
        qty[v.item] = Math.max(0, Math.min(99, qty[v.item] + (parseInt(v.delta, 10) || 0)));
      }
    });
    return qty;
  }

  function renderInventory(app, d) {
    var qty = inventoryQty(app);
    var units = 0, low = 0;
    for (var qn in qty) { units += qty[qn]; if (qty[qn] < 3) low++; }
    statStrip(panel, d, [
      [String(units), "units on hand"],
      [String(low), "low stock"],
      [String(state.recs.filter(function (r) { return (r.values || {}).event === "adjust"; }).length),
       "movements"]
    ]);
    inventoryItems(app).forEach(function (it) {
      var li = el("div", "rf-panel-list-item");
      li.style.alignItems = "center";
      var left = el("span", "rf-panel-list-text", it.name);
      var right = el("span", "rf-inv-controls");
      right.style.cssText = "display:flex;align-items:center;gap:8px;";
      var minus = mkBtn("−", d.accent, false, true);
      var count = el("span", "rf-panel-list-text", qty[it.name] + " " + it.unit);
      count.style.cssText = "min-width:72px;text-align:center;font-variant-numeric:tabular-nums;";
      if (qty[it.name] < 3) { count.style.color = d.accent; count.style.fontWeight = "700"; }
      var plus = mkBtn("+", d.accent, true, true);
      ctx.on(minus, "click", function () {
        if (inventoryQty(app)[it.name] <= 0) return;
        writeEvent({ event: "adjust", item: it.name, delta: "-1" }, "adjust · " + it.name + " −1");
        renderActive();
      });
      ctx.on(plus, "click", function () {
        writeEvent({ event: "adjust", item: it.name, delta: "1" }, "adjust · " + it.name + " +1");
        renderActive();
      });
      right.appendChild(minus);
      right.appendChild(count);
      right.appendChild(plus);
      li.appendChild(left);
      li.appendChild(right);
      panel.appendChild(li);
    });
    var invRow = el("div", "rf-panel-form");
    invRow.style.cssText = "flex-direction:row;gap:8px;margin-top:12px;";
    var invInp = mkInput("stock a new item", d.radius);
    invInp.style.flex = "1";
    var invBtn = mkBtn("Add", d.accent, true, true);
    invRow.appendChild(invInp);
    invRow.appendChild(invBtn);
    panel.appendChild(invRow);
    ctx.on(invBtn, "click", function () {
      var nm = String(invInp.value || "").trim().slice(0, 20);
      if (!nm) { say("name the item first"); return; }
      writeEvent({ event: "additem", item: nm }, "stock · " + nm);
      renderActive();
    });
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- approvals: decide things ------------------------------------------
  function approvalRequests(app) {
    var reqs = (app.requests || []).slice();
    var known = {};
    reqs.forEach(function (rq) { known[rq.title] = true; });
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "addreq" && v.request && !known[v.request]) {
        known[v.request] = true;
        reqs.push({ title: v.request, detail: "" });
      }
    });
    return reqs;
  }

  function renderApprovals(app, d) {
    var status = {};
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if ((v.event === "approve" || v.event === "deny") && v.request) status[v.request] = v.event;
    });
    var reqs = approvalRequests(app);
    var okN = 0, noN = 0;
    for (var st in status) { if (status[st] === "approve") okN++; else noN++; }
    statStrip(panel, d, [
      [String(okN), "approved"],
      [String(noN), "denied"],
      [String(reqs.length - okN - noN), "pending"]
    ]);
    reqs.forEach(function (rq) {
      var li = el("div", "rf-panel-list-item");
      li.style.alignItems = "center";
      var left = el("span", "rf-panel-list-text", rq.title
        + (rq.detail ? " — " + rq.detail : ""));
      li.appendChild(left);
      var decided = status[rq.title];
      if (decided) {
        var chipEl = el("span", "rf-panel-list-meta", decided === "approve" ? "APPROVED" : "DENIED");
        chipEl.style.fontWeight = "700";
        chipEl.style.color = decided === "approve" ? d.accent : "#9AA3B2";
        li.appendChild(chipEl);
      } else {
        var acts = el("span", "rf-appr-acts");
        acts.style.cssText = "display:flex;gap:6px;";
        var yes = mkBtn("Approve", d.accent, true, true);
        var no = mkBtn("Deny", d.accent, false, true);
        ctx.on(yes, "click", function () {
          writeEvent({ event: "approve", request: rq.title }, "approve · " + rq.title);
          renderActive();
        });
        ctx.on(no, "click", function () {
          writeEvent({ event: "deny", request: rq.title }, "deny · " + rq.title);
          renderActive();
        });
        acts.appendChild(yes);
        acts.appendChild(no);
        li.appendChild(acts);
      }
      panel.appendChild(li);
    });
    var rqRow = el("div", "rf-panel-form");
    rqRow.style.cssText = "flex-direction:row;gap:8px;margin-top:12px;";
    var rqInp = mkInput("raise a new " + (app.request_noun || "request"), d.radius);
    rqInp.style.flex = "1";
    var rqBtn = mkBtn("Raise", d.accent, true, true);
    rqRow.appendChild(rqInp);
    rqRow.appendChild(rqBtn);
    panel.appendChild(rqRow);
    ctx.on(rqBtn, "click", function () {
      var nm = String(rqInp.value || "").trim().slice(0, 26);
      if (!nm) { say("name the " + (app.request_noun || "request") + " first"); return; }
      writeEvent({ event: "addreq", request: nm }, "raise · " + nm);
      renderActive();
    });
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- tasks: a checklist with a progress bar ----------------------------
  function renderTasks(app, d) {
    var items = (app.tasks || []).map(function (t) { return t.title; });
    var done = {};
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "addtask" && v.task && items.indexOf(v.task) < 0) items.push(v.task);
      if (v.event === "check" && v.task) done[v.task] = true;
    });
    var total = items.length;
    var checked = items.filter(function (t) { return done[t]; }).length;
    statStrip(panel, d, [
      [checked + "/" + total, "done"],
      [(total ? Math.round(checked / total * 100) : 0) + "%", "complete"],
      [String(total - checked), "open"]
    ]);
    var barWrap = el("div", "rf-task-bar");
    barWrap.style.cssText = "height:6px;border-radius:999px;background:#F0F0F2;margin:0 0 14px;overflow:hidden;";
    var bar = el("div", "rf-task-fill");
    bar.style.cssText = "height:100%;border-radius:999px;transition:width 300ms ease;";
    bar.style.background = d.accent;
    bar.style.width = (total ? Math.round(checked / total * 100) : 0) + "%";
    barWrap.appendChild(bar);
    panel.appendChild(barWrap);
    items.forEach(function (t) {
      var li = el("div", "rf-panel-list-item");
      li.style.alignItems = "center";
      var label = el("span", "rf-panel-list-text", t);
      li.appendChild(label);
      if (done[t]) {
        label.style.textDecoration = "line-through";
        label.style.color = "#9AA3B2";
        var tick = el("span", "rf-panel-list-meta", "✓");
        tick.style.color = d.accent;
        li.appendChild(tick);
      } else {
        var check = mkBtn("Done", d.accent, false, true);
        ctx.on(check, "click", function () {
          writeEvent({ event: "check", task: t }, "check · " + t);
          renderActive();
        });
        li.appendChild(check);
      }
      panel.appendChild(li);
    });
    var addRow = el("div", "rf-panel-form");
    addRow.style.cssText = "flex-direction:row;gap:8px;margin-top:12px;";
    var addInp = mkInput("a new " + (app.task_noun || "task"), d.radius);
    addInp.style.flex = "1";
    var addBtn = mkBtn("Add", d.accent, true, true);
    addRow.appendChild(addInp);
    addRow.appendChild(addBtn);
    panel.appendChild(addRow);
    ctx.on(addBtn, "click", function () {
      var t = String(addInp.value || "").trim().slice(0, 28);
      if (!t) { say("name the " + (app.task_noun || "task") + " first"); return; }
      writeEvent({ event: "addtask", task: t }, "add · " + t);
      renderActive();
    });
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- waitlist: an ordered queue with a seat-next door -------------------
  function waitQueue(app) {
    var queue = (app.samples || []).slice();
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "join" && v.name && queue.indexOf(v.name) < 0) queue.push(v.name);
      if (v.event === "seat" && v.name) {
        var at = queue.indexOf(v.name);
        if (at >= 0) queue.splice(at, 1);
      }
    });
    return queue;
  }

  function renderWaitlist(app, d) {
    var noun = app.party_noun || "guest";
    var queue = waitQueue(app);
    var seatedN = state.recs.filter(function (r) { return (r.values || {}).event === "seat"; }).length;
    statStrip(panel, d, [
      [String(queue.length), "waiting"],
      ["~" + (queue.length * 5) + "m", "est. wait"],
      [String(seatedN), "seated"]
    ]);
    var addRow = el("div", "rf-panel-form");
    addRow.style.cssText = "flex-direction:row;gap:8px;margin-bottom:14px;";
    var addInp = mkInput("add a " + noun + " to the list", d.radius);
    addInp.style.flex = "1";
    var addBtn = mkBtn("Join", d.accent, true, true);
    addRow.appendChild(addInp);
    addRow.appendChild(addBtn);
    panel.appendChild(addRow);
    ctx.on(addBtn, "click", function () {
      var name = String(addInp.value || "").trim().slice(0, 18);
      if (!name) { say("type a name first"); return; }
      writeEvent({ event: "join", name: name }, "join · " + name);
      renderActive();
    });
    queue.forEach(function (name, i) {
      var li = el("div", "rf-panel-list-item");
      li.style.alignItems = "center";
      var pos = el("span", "rf-panel-list-meta", "#" + (i + 1));
      pos.style.minWidth = "28px";
      pos.style.fontWeight = "700";
      pos.style.color = i === 0 ? d.accent : "#9AA3B2";
      var label = el("span", "rf-panel-list-text", name);
      label.style.flex = "1";
      li.appendChild(pos);
      li.appendChild(label);
      if (i === 0) {
        var seat = mkBtn("Seat →", d.accent, true, true);
        ctx.on(seat, "click", function () {
          writeEvent({ event: "seat", name: name }, "seat · " + name);
          renderActive();
        });
        li.appendChild(seat);
      }
      panel.appendChild(li);
    });
    if (!queue.length) panel.appendChild(el("div", "rf-panel-list-item", "The list is clear."));
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- feedback: stars, a note, a running average -------------------------
  function feedbackCounts() {
    var counts = [0, 0, 0, 0, 0], sum = 0, n = 0;
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "rate") {
        var s = parseInt(v.stars, 10);
        if (s >= 1 && s <= 5) { counts[s - 1]++; sum += s; n++; }
      }
    });
    return { counts: counts, sum: sum, n: n };
  }

  function renderFeedback(app, d) {
    var fc = feedbackCounts();
    statStrip(panel, d, [
      [fc.n ? (fc.sum / fc.n).toFixed(1) + " ★" : "—", "average"],
      [String(fc.n), "responses"],
      [String(fc.counts[4]), "5-star"]
    ]);
    var q = el("div", "rf-feedback-q", app.question || "How was it?");
    q.style.cssText = "font-size:1.1rem;font-weight:600;margin:0 0 10px;";
    panel.appendChild(q);
    var picked = 0;
    var stars = [];
    var starRow = el("div", "rf-star-row");
    starRow.style.cssText = "display:flex;gap:4px;margin:0 0 12px;";
    for (var i = 1; i <= 5; i++) {
      (function (n) {
        var st = el("button", "rf-star", "★");
        st.type = "button";
        st.style.cssText = "font-size:28px;background:transparent;border:none;cursor:pointer;"
          + "padding:0 3px;color:#E4E4E7;transition:transform 120ms ease;";
        ctx.on(st, "click", function () {
          picked = n;
          stars.forEach(function (s, j) { s.style.color = j < n ? d.accent : "#E4E4E7"; });
        });
        stars.push(st);
        starRow.appendChild(st);
      })(i);
    }
    panel.appendChild(starRow);
    var comment = mkInput("a short note (optional)", d.radius);
    comment.style.width = "100%";
    comment.style.marginBottom = "10px";
    panel.appendChild(comment);
    var send = mkBtn("Send feedback →", d.accent, true);
    panel.appendChild(send);
    var sum = 0, n = 0;
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "rate") {
        var s = parseInt(v.stars, 10);
        if (s >= 1 && s <= 5) { sum += s; n += 1; }
      }
    });
    if (n) {
      var avg = el("div", "rf-panel-sub",
        (sum / n).toFixed(1) + " ★ average · " + n + " response" + (n === 1 ? "" : "s"));
      avg.style.marginTop = "12px";
      panel.appendChild(avg);
    }
    ctx.on(send, "click", function () {
      if (!picked) { say("tap a star first"); return; }
      writeEvent({ event: "rate", stars: String(picked),
                   comment: String(comment.value || "").trim().slice(0, 60) },
        "rate · " + picked + "★", (app.thanks || "Thank you.") + " · row written");
      renderActive();
    });
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- quote: line items you toggle, a total that answers -----------------
  function quoteItems(app) {
    var items = (app.items || []).slice();
    var known = {};
    items.forEach(function (it) { known[it.name] = true; });
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "additem2" && v.item && !known[v.item]) {
        known[v.item] = true;
        var pr = parseInt(v.price, 10);
        items.push({ name: v.item, price: (pr > 0 && pr < 100000) ? pr : 0 });
      }
    });
    return items;
  }

  function renderQuote(app, d) {
    var cur = app.currency || "$";
    var items = quoteItems(app);
    var on = {};
    items.forEach(function (it) { on[it.name] = true; });
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "toggle" && (v.item in on)) on[v.item] = v.on === "1";
    });
    var total = 0, onN = 0;
    items.forEach(function (it) { if (on[it.name]) { total += it.price; onN++; } });
    statStrip(panel, d, [
      [cur + total, "quote total"],
      [onN + "/" + items.length, "items on"]
    ]);
    items.forEach(function (it) {
      var li = el("div", "rf-panel-list-item");
      li.style.cursor = "pointer";
      li.style.alignItems = "center";
      var mark = el("span", "rf-panel-list-meta", on[it.name] ? "☑" : "☐");
      mark.style.fontSize = "15px";
      mark.style.minWidth = "20px";
      mark.style.color = on[it.name] ? d.accent : "#9AA3B2";
      var label = el("span", "rf-panel-list-text", it.name);
      label.style.flex = "1";
      if (!on[it.name]) label.style.color = "#9AA3B2";
      var price = el("span", "rf-panel-list-meta", cur + it.price);
      li.appendChild(mark);
      li.appendChild(label);
      li.appendChild(price);
      ctx.on(li, "click", function () {
        writeEvent({ event: "toggle", item: it.name, on: on[it.name] ? "0" : "1" },
          "toggle · " + it.name + (on[it.name] ? " off" : " on"));
        renderActive();
      });
      panel.appendChild(li);
    });
    var qRow = el("div", "rf-panel-form");
    qRow.style.cssText = "flex-direction:row;gap:8px;margin-top:12px;";
    var qName = mkInput("a custom line item", d.radius);
    qName.style.flex = "1";
    var qPrice = mkInput(cur, d.radius);
    qPrice.style.width = "72px";
    var qBtn = mkBtn("Add", d.accent, true, true);
    qRow.appendChild(qName);
    qRow.appendChild(qPrice);
    qRow.appendChild(qBtn);
    panel.appendChild(qRow);
    ctx.on(qBtn, "click", function () {
      var nm = String(qName.value || "").trim().slice(0, 22);
      var pr = parseInt(String(qPrice.value || "").replace(/[^0-9]/g, ""), 10);
      if (!nm) { say("name the line item first"); return; }
      if (!(pr > 0)) { say("give it a price"); return; }
      writeEvent({ event: "additem2", item: nm, price: String(Math.min(99999, pr)) },
        "line · " + nm + " " + cur + pr);
      renderActive();
    });
    var totalRow = el("div", "rf-quote-total");
    totalRow.style.cssText = "display:flex;justify-content:space-between;font-weight:700;"
      + "font-size:1.25rem;margin-top:12px;padding-top:12px;border-top:2px solid " + d.accent + ";";
    totalRow.appendChild(el("span", "rf-quote-label", "Total"));
    var amt = el("span", "rf-quote-amt", cur + total);
    amt.style.color = d.accent;
    totalRow.appendChild(amt);
    panel.appendChild(totalRow);
    renderEventLog(panel, "ROWS WRITTEN");
  }

  // --- loyalty: points toward a reward ------------------------------------
  function loyaltyState(app) {
    var pts = {};
    var order = [];
    (app.members || []).forEach(function (mm) { pts[mm.name] = mm.points; order.push(mm.name); });
    state.recs.forEach(function (r) {
      var v = r.values || {};
      if (v.event === "joinm" && v.name && !(v.name in pts)) { pts[v.name] = 0; order.push(v.name); }
      if (v.event === "points" && (v.name in pts)) {
        pts[v.name] = Math.max(0, Math.min(999, pts[v.name] + (parseInt(v.delta, 10) || 0)));
      }
    });
    return { pts: pts, order: order };
  }

  function renderLoyalty(app, d) {
    var noun = app.member_noun || "member";
    var reward = app.reward_at || 100;
    var ls = loyaltyState(app);
    var pts = ls.pts, order = ls.order;
    var totalPts = 0;
    order.forEach(function (nm) { totalPts += pts[nm]; });
    var redeems = state.recs.filter(function (r) {
      var v = r.values || {};
      return v.event === "points" && (parseInt(v.delta, 10) || 0) < 0;
    }).length;
    statStrip(panel, d, [
      [String(order.length), noun + "s"],
      [String(totalPts), "points held"],
      [String(redeems), "rewards used"]
    ]);
    order.forEach(function (name) {
      var li = el("div", "rf-panel-list-item");
      li.style.alignItems = "center";
      var label = el("span", "rf-panel-list-text", name);
      label.style.flex = "1";
      var meter = el("span", "rf-panel-list-meta", pts[name] + " / " + reward);
      meter.style.minWidth = "64px";
      meter.style.textAlign = "right";
      li.appendChild(label);
      li.appendChild(meter);
      if (pts[name] >= reward) {
        meter.textContent = "REWARD";
        meter.style.color = d.accent;
        meter.style.fontWeight = "700";
        var redeem = mkBtn("Redeem", d.accent, true, true);
        ctx.on(redeem, "click", function () {
          writeEvent({ event: "points", name: name, delta: String(-reward) },
            "redeem · " + name + " −" + reward);
          renderActive();
        });
        li.appendChild(redeem);
      } else {
        var plus = mkBtn("+10", d.accent, true, true);
        ctx.on(plus, "click", function () {
          writeEvent({ event: "points", name: name, delta: "10" }, "points · " + name + " +10");
          renderActive();
        });
        li.appendChild(plus);
      }
      panel.appendChild(li);
    });
    var addRow = el("div", "rf-panel-form");
    addRow.style.cssText = "flex-direction:row;gap:8px;margin-top:12px;";
    var addInp = mkInput("a new " + noun, d.radius);
    addInp.style.flex = "1";
    var addBtn = mkBtn("Add", d.accent, true, true);
    addRow.appendChild(addInp);
    addRow.appendChild(addBtn);
    panel.appendChild(addRow);
    ctx.on(addBtn, "click", function () {
      var name = String(addInp.value || "").trim().slice(0, 18);
      if (!name) { say("type a name first"); return; }
      writeEvent({ event: "joinm", name: name }, "join · " + name);
      renderActive();
    });
    renderEventLog(panel, "ROWS WRITTEN");
  }

  function kindCount(app) {
    if (app.kind === "quote") return (app.items || []).length + " line items";
    if (app.kind === "tasks") return (app.tasks || []).length + " jobs";
    if (app.kind === "waitlist") return "live queue";
    if (app.kind === "feedback") return "1 question";
    if (app.kind === "loyalty") return (app.members || []).length + " members";
    if (app.fields) return app.fields.length + " fields";
    if (app.stages) return app.stages.length + " stages";
    if (app.days) return (app.days.length * (app.times || []).length) + " slots";
    if (app.items) return app.items.length + " items";
    if (app.requests) return app.requests.length + " pending";
    return "live";
  }

  function hexToRgba(hex, alpha) {
    var m = /^#([0-9a-fA-F]{6})$/.exec(String(hex) || "");
    if (!m) return "rgba(11, 18, 32, " + alpha + ")";
    var n = parseInt(m[1], 16);
    return "rgba(" + ((n >> 16) & 255) + ", " + ((n >> 8) & 255) + ", " + (n & 255) + ", " + alpha + ")";
  }
  var FONT_STACKS = {
    sans: "Arial, 'Helvetica Neue', Helvetica, sans-serif",
    serif: "Georgia, 'Times New Roman', serif",
    mono: "ui-monospace, 'SF Mono', Menlo, Consolas, monospace"
  };

  function sameDay(ts) {
    var a = new Date(ts || 0), b = new Date();
    return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() &&
           a.getDate() === b.getDate();
  }

  function statStrip(host, d, pairs) {
    var strip = el("div", "rf-stat-strip");
    strip.style.cssText = "display:flex;gap:10px;flex-wrap:wrap;margin:0 0 16px;";
    pairs.forEach(function (pr) {
      var tile = el("div", "rf-stat-tile");
      tile.style.cssText = "flex:1;min-width:88px;padding:10px 14px;border-radius:12px;";
      tile.style.background = hexToRgba(d.accent, 0.07);
      var num = el("div", "rf-stat-num", pr[0]);
      num.style.cssText = "font-size:1.35rem;font-weight:700;font-variant-numeric:tabular-nums;";
      num.style.color = d.accent;
      var lab = el("div", "rf-stat-lab", pr[1]);
      lab.style.cssText = "font-size:10px;letter-spacing:0.08em;text-transform:uppercase;"
        + "color:#64748B;margin-top:2px;";
      tile.appendChild(num);
      tile.appendChild(lab);
      strip.appendChild(tile);
    });
    host.appendChild(strip);
  }

  function barRow(host, d, label, frac, valText) {
    var row = el("div", "rf-bar-row");
    row.style.cssText = "display:flex;align-items:center;gap:10px;margin:0 0 8px;";
    var lab = el("span", "rf-bar-label", label);
    lab.style.cssText = "min-width:86px;font-size:12px;color:#3C4657;overflow:hidden;"
      + "text-overflow:ellipsis;white-space:nowrap;";
    var track = el("span", "rf-bar-track");
    track.style.cssText = "flex:1;height:8px;border-radius:999px;background:#F0F0F2;"
      + "overflow:hidden;display:block;";
    var fill = el("span", "rf-bar-fill");
    fill.style.cssText = "display:block;height:100%;border-radius:999px;transition:width 400ms ease;";
    fill.style.width = Math.round(Math.max(0, Math.min(1, frac)) * 100) + "%";
    fill.style.background = d.accent;
    track.appendChild(fill);
    var val = el("span", "rf-bar-val", valText || "");
    val.style.cssText = "min-width:44px;text-align:right;font-size:11px;color:#64748B;"
      + "font-variant-numeric:tabular-nums;";
    row.appendChild(lab);
    row.appendChild(track);
    row.appendChild(val);
    host.appendChild(row);
  }

  function renderPanel(app) {
    if (!panel) return;
    panel.removeAttribute("hidden");
    panel.innerHTML = "";
    var design = app.design || {};
    var accent = /^#[0-9a-fA-F]{6}$/.test(design.accent || "") ? design.accent : "#0B1220";
    var radius = (design.radius >= 0 && design.radius <= 22) ? design.radius : 14;
    var d = { accent: accent, radius: radius, compact: design.density === "compact" };
    panel.style.borderRadius = (radius + 6) + "px";
    panel.style.fontFamily = FONT_STACKS[design.font] || FONT_STACKS.sans;
    panel.style.boxShadow = "0 18px 50px " + hexToRgba(accent, 0.12);
    panel.style.borderColor = hexToRgba(accent, 0.25);
    panel.style.background = "linear-gradient(180deg, " + hexToRgba(accent, 0.05) + ", #FFFFFF 140px)";
    var badgeNoun = app.noun || app.card_noun || app.slot_noun || app.request_noun || app.kind || "app";
    if (design.header === "badge") {
      var badge = el("div", "rf-panel-badge", String(badgeNoun).toUpperCase());
      badge.style.cssText = "display:inline-block;font-size:10px;font-weight:700;"
        + "letter-spacing:0.14em;padding:4px 10px;border-radius:999px;margin-bottom:10px;";
      badge.style.background = hexToRgba(accent, 0.12);
      badge.style.color = accent;
      panel.appendChild(badge);
    }
    var title = el("div", "rf-panel-title", app.title);
    if (design.header === "bar") {
      title.style.borderLeft = "4px solid " + accent;
      title.style.paddingLeft = "12px";
    } else if (design.header !== "badge") {
      title.style.display = "inline-block";
      title.style.borderBottom = "2px solid " + accent;
      title.style.paddingBottom = "4px";
    }
    panel.appendChild(title);
    panel.appendChild(el("div", "rf-panel-sub",
      kindCount(app) + " · " + (design.accent || accent) + " · " +
      (design.font || "sans") + " · live"));
    if (app.kind === "pipeline") renderPipeline(app, d);
    else if (app.kind === "booking") renderBooking(app, d);
    else if (app.kind === "inventory") renderInventory(app, d);
    else if (app.kind === "approvals") renderApprovals(app, d);
    else if (app.kind === "tasks") renderTasks(app, d);
    else if (app.kind === "waitlist") renderWaitlist(app, d);
    else if (app.kind === "feedback") renderFeedback(app, d);
    else if (app.kind === "quote") renderQuote(app, d);
    else if (app.kind === "loyalty") renderLoyalty(app, d);
    else renderIntake(app, d);
  }

  // === surfaces: collect, then visualize ===================================
  // The pitch in miniature: the app is surface ONE (it collects rows); any
  // number of further surfaces read the same rows. The second surface is
  // derived entirely client-side from the same replay — created in one click.
  var tabsHost = one("[data-surface-tabs]");
  var chooser = one("[data-chooser]");
  var activeSurface = "app";

  var OPS_TITLES = {
    intake: "Records desk", pipeline: "Deal desk", booking: "Front desk",
    inventory: "Stock control", approvals: "Decision log", tasks: "Team board",
    waitlist: "Host stand", feedback: "Insights", quote: "Sales desk",
    loyalty: "Program desk"
  };
  var VIEW_NAMES = { dashboard: "Dashboard", table: "Table", feed: "Live feed" };

  function renderActive() {
    if (!state.app) return;
    if (activeSurface === "ops" && state.ops) renderOps(state.app);
    else renderPanel(state.app);
  }

  function setSurface(which) {
    activeSurface = which;
    renderTabs();
    renderActive();
  }

  function renderTabs() {
    if (!tabsHost) return;
    tabsHost.innerHTML = "";
    if (!state.app) { tabsHost.setAttribute("hidden", ""); return; }
    tabsHost.removeAttribute("hidden");
    var word = KIND_WORDS[state.app.kind] || "app";
    var t1 = el("button", "rf-surface-tab" + (activeSurface === "app" ? " rf-surface-tab-on" : ""),
      "01 · Collect — " + word);
    t1.type = "button";
    ctx.on(t1, "click", function () { setSurface("app"); });
    tabsHost.appendChild(t1);
    if (state.ops) {
      var t2 = el("button", "rf-surface-tab" + (activeSurface === "ops" ? " rf-surface-tab-on" : ""),
        "02 · Visualize — " + (state.ops.title || VIEW_NAMES[state.ops.view] || "view"));
      t2.type = "button";
      ctx.on(t2, "click", function () { setSurface("ops"); });
      tabsHost.appendChild(t2);
    } else {
      var mk = el("button", "rf-make-surface", "Create a surface on this data →");
      mk.type = "button";
      ctx.on(mk, "click", openChooser);
      tabsHost.appendChild(mk);
    }
  }

  function openChooser() {
    if (!chooser) return;
    chooser.innerHTML = "";
    chooser.removeAttribute("hidden");
    var q = el("div", "rf-chooser-q", "How do you want to see this data?");
    q.style.cssText = "font-weight:700;font-size:1rem;margin:0 0 10px;";
    chooser.appendChild(q);
    var rowC = el("div", "rf-chooser-row");
    rowC.style.cssText = "display:flex;gap:8px;flex-wrap:wrap;margin:0 0 12px;";
    [["dashboard", "Dashboard"], ["table", "Table"], ["feed", "Live feed"]].forEach(function (v) {
      var chipB = el("button", "rf-view-chip", v[1]);
      chipB.type = "button";
      ctx.on(chipB, "click", function () { createOps(v[0], ""); });
      rowC.appendChild(chipB);
    });
    chooser.appendChild(rowC);
    var orLine = el("div", "rf-chooser-or", "or describe it —");
    orLine.style.cssText = "font-size:11px;color:#9AA3B2;margin:0 0 8px;"
      + "font-family:ui-monospace, 'SF Mono', Menlo, Consolas, monospace;";
    chooser.appendChild(orLine);
    var wrapRow = el("div", "rf-chooser-input-row");
    wrapRow.style.cssText = "display:flex;gap:8px;";
    var inp = document.createElement("input");
    inp.type = "text";
    inp.maxLength = 120;
    inp.className = "rf-panel-input";
    inp.placeholder = "“just a leaderboard of my regulars”";
    inp.style.flex = "1";
    var go = el("button", "rf-make-surface", "Shape it →");
    go.type = "button";
    function shape() {
      var want = String(inp.value || "").trim();
      if (!want) { inp.focus(); return; }
      go.setAttribute("disabled", "");
      go.textContent = "Luna is choosing…";
      runPipe("shape-surface",
        { want: want, kind: (state.app && state.app.kind) || "intake", visitor: state.v },
        function (launch) {
          go.removeAttribute("disabled");
          go.textContent = "Shape it →";
          var out = launch.output || {};
          if (out.refused) { say(String(out.refused).slice(0, 140)); return; }
          createOps((out.view === "table" || out.view === "feed") ? out.view : "dashboard",
            String(out.title || ""));
        },
        function (err) {
          go.removeAttribute("disabled");
          go.textContent = "Shape it →";
          if (err && err.status === 429) say("too many shapes this minute — pick a preset");
          else createOps("dashboard", "");
        });
    }
    ctx.on(go, "click", shape);
    ctx.on(inp, "keydown", function (ev) { if (ev && ev.key === "Enter") shape(); });
    wrapRow.appendChild(inp);
    wrapRow.appendChild(go);
    chooser.appendChild(wrapRow);
    try { inp.focus(); } catch (e) {}
  }

  function createOps(view, title) {
    state.ops = { view: view, title: title };
    save();
    if (chooser) { chooser.setAttribute("hidden", ""); chooser.innerHTML = ""; }
    writeEvent({ event: "surface", view: view }, "surface · " + view,
      "second surface live · reading the same rows");
    setSurface("ops");
    renderLedger();
  }

  function opsStats(app) {
    var k = app.kind;
    function evs(name) {
      return state.recs.filter(function (r) { return (r.values || {}).event === name; });
    }
    if (k === "pipeline") {
      var st = app.stages || [], cards = pipelineCards(app), tot = 0, won = 0;
      for (var n in cards) { tot++; if (cards[n].stage === st.length - 1) won++; }
      return [[String(tot), "cards"], [String(won), "closed"],
              [tot ? Math.round(won / tot * 100) + "%" : "0%", "win rate"]];
    }
    if (k === "booking") {
      var booked = {};
      evs("book").forEach(function (r) { var v = r.values; booked[v.day + "|" + v.time] = 1; });
      var totalS = (app.days || []).length * (app.times || []).length;
      var bn = Object.keys(booked).length;
      return [[bn + "/" + totalS, "booked"],
              [(totalS ? Math.round(bn / totalS * 100) : 0) + "%", "utilization"],
              [String(evs("book").length), "bookings taken"]];
    }
    if (k === "inventory") {
      var qty = inventoryQty(app), units = 0, low = 0;
      for (var qn in qty) { units += qty[qn]; if (qty[qn] < 3) low++; }
      return [[String(units), "units"], [String(low), "low stock"],
              [String(evs("adjust").length), "movements"]];
    }
    if (k === "approvals") {
      return [[String(evs("approve").length), "approved"],
              [String(evs("deny").length), "denied"],
              [String(evs("addreq").length), "raised"]];
    }
    if (k === "tasks") {
      var items = (app.tasks || []).map(function (t) { return t.title; });
      var done = {};
      state.recs.forEach(function (r) {
        var v = r.values || {};
        if (v.event === "addtask" && v.task && items.indexOf(v.task) < 0) items.push(v.task);
        if (v.event === "check" && v.task) done[v.task] = true;
      });
      var ck = items.filter(function (t) { return done[t]; }).length;
      return [[ck + "/" + items.length, "done"],
              [(items.length ? Math.round(ck / items.length * 100) : 0) + "%", "complete"],
              [String(evs("addtask").length), "added"]];
    }
    if (k === "waitlist") {
      var queue = waitQueue(app);
      return [[String(queue.length), "waiting"],
              ["~" + (queue.length * 5) + "m", "est. wait"],
              [String(evs("seat").length), "seated"]];
    }
    if (k === "feedback") {
      var fc = feedbackCounts();
      return [[fc.n ? (fc.sum / fc.n).toFixed(1) + " ★" : "—", "average"],
              [String(fc.n), "responses"], [String(fc.counts[4]), "5-star"]];
    }
    if (k === "quote") {
      var items2 = quoteItems(app), on = {};
      items2.forEach(function (it) { on[it.name] = true; });
      state.recs.forEach(function (r) {
        var v = r.values || {};
        if (v.event === "toggle" && (v.item in on)) on[v.item] = v.on === "1";
      });
      var total = 0, onN = 0;
      items2.forEach(function (it) { if (on[it.name]) { total += it.price; onN++; } });
      return [[(app.currency || "$") + total, "quote total"],
              [onN + "/" + items2.length, "items on"],
              [String(evs("toggle").length), "changes"]];
    }
    if (k === "loyalty") {
      var ls = loyaltyState(app), totalPts = 0;
      ls.order.forEach(function (nm) { totalPts += ls.pts[nm]; });
      return [[String(ls.order.length), "members"], [String(totalPts), "points held"],
              [String(evs("joinm").length), "joined here"]];
    }
    var subs = state.recs.filter(function (r) { return !(r.values || {}).event; });
    return [[String(subs.length), "records"],
            [String(subs.filter(function (r) { return sameDay(r.created); }).length), "today"],
            [String((app.fields || []).length), "fields"]];
  }

  function opsBars(app, d) {
    var k = app.kind;
    if (k === "pipeline") {
      var st = app.stages || [], cards = pipelineCards(app), tot = 0;
      for (var n in cards) tot++;
      st.forEach(function (s, i) {
        var c = 0;
        for (var n2 in cards) { if (cards[n2].stage === i) c++; }
        barRow(panel, d, s, tot ? c / tot : 0, String(c));
      });
      return true;
    }
    if (k === "booking") {
      var per = (app.times || []).length;
      (app.days || []).forEach(function (day) {
        var c = 0;
        state.recs.forEach(function (r) {
          var v = r.values || {};
          if (v.event === "book" && v.day === day) c++;
        });
        barRow(panel, d, day, per ? c / per : 0, c + "/" + per);
      });
      return true;
    }
    if (k === "inventory") {
      var qty = inventoryQty(app), mx = 1;
      for (var n3 in qty) mx = Math.max(mx, qty[n3]);
      inventoryItems(app).forEach(function (it) {
        barRow(panel, d, it.name, qty[it.name] / mx, String(qty[it.name]));
      });
      return true;
    }
    if (k === "approvals") {
      var reqs = approvalRequests(app), status = {};
      state.recs.forEach(function (r) {
        var v = r.values || {};
        if ((v.event === "approve" || v.event === "deny") && v.request) status[v.request] = v.event;
      });
      var ok = 0, no = 0;
      for (var s2 in status) { if (status[s2] === "approve") ok++; else no++; }
      var totR = Math.max(1, reqs.length);
      barRow(panel, d, "approved", ok / totR, String(ok));
      barRow(panel, d, "denied", no / totR, String(no));
      barRow(panel, d, "pending", (reqs.length - ok - no) / totR, String(reqs.length - ok - no));
      return true;
    }
    if (k === "feedback") {
      var fc = feedbackCounts();
      for (var s3 = 5; s3 >= 1; s3--) {
        barRow(panel, d, s3 + " ★", fc.n ? fc.counts[s3 - 1] / fc.n : 0, String(fc.counts[s3 - 1]));
      }
      return true;
    }
    if (k === "loyalty") {
      var ls = loyaltyState(app), reward = app.reward_at || 100;
      ls.order.slice().sort(function (a, b) { return ls.pts[b] - ls.pts[a]; }).slice(0, 6)
        .forEach(function (nm) {
          barRow(panel, d, nm, ls.pts[nm] / reward, String(ls.pts[nm]));
        });
      return true;
    }
    if (k === "quote") {
      var items = quoteItems(app), mx2 = 1;
      items.forEach(function (it) { mx2 = Math.max(mx2, it.price); });
      items.forEach(function (it) {
        barRow(panel, d, it.name, it.price / mx2, (app.currency || "$") + it.price);
      });
      return true;
    }
    if (k === "tasks") {
      var items3 = (app.tasks || []).map(function (t) { return t.title; });
      var done = {};
      state.recs.forEach(function (r) {
        var v = r.values || {};
        if (v.event === "addtask" && v.task && items3.indexOf(v.task) < 0) items3.push(v.task);
        if (v.event === "check" && v.task) done[v.task] = true;
      });
      var ck = items3.filter(function (t) { return done[t]; }).length;
      barRow(panel, d, "progress", items3.length ? ck / items3.length : 0,
        ck + "/" + items3.length);
      return true;
    }
    return false;
  }

  function opsRecRows(limit) {
    return state.recs.slice(-limit).reverse().map(function (r) {
      var text = r.label;
      if (!text) {
        var vals = r.values || {};
        for (var key in vals) { if (vals[key]) { text = vals[key]; break; } }
      }
      var parts = String(text || "row").split(" · ");
      return {
        what: parts[0] || "row",
        detail: parts.slice(1).join(" · "),
        when: new Date(r.created || 0).toLocaleTimeString()
      };
    });
  }

  function opsEmpty(word) {
    var em = el("div", "rf-panel-list-item",
      "Nothing yet — touch the " + word + " and watch this surface move.");
    panel.appendChild(em);
  }

  function renderOpsTable(app, d) {
    var rows2 = opsRecRows(14);
    if (!rows2.length) { opsEmpty(KIND_WORDS[app.kind] || "app"); return; }
    var head = el("div", "rf-ops-thead");
    head.style.cssText = "display:grid;grid-template-columns:1.1fr 1.6fr 74px;gap:10px;"
      + "font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:#9AA3B2;"
      + "padding:0 0 8px;border-bottom:2px solid " + d.accent + ";margin-bottom:2px;";
    ["What", "Detail", "When"].forEach(function (h) { head.appendChild(el("span", "", h)); });
    panel.appendChild(head);
    rows2.forEach(function (rr) {
      var tr = el("div", "rf-ops-tr");
      tr.style.cssText = "display:grid;grid-template-columns:1.1fr 1.6fr 74px;gap:10px;"
        + "padding:9px 0;border-bottom:1px solid #F0F0F2;font-size:13px;align-items:baseline;";
      var w = el("span", "", rr.what);
      w.style.fontWeight = "600";
      tr.appendChild(w);
      tr.appendChild(el("span", "", rr.detail || "—"));
      var t3 = el("span", "", rr.when);
      t3.style.cssText = "font-size:11px;color:#9AA3B2;font-variant-numeric:tabular-nums;";
      tr.appendChild(t3);
      panel.appendChild(tr);
    });
  }

  function renderOpsFeed(app, d) {
    var rows2 = opsRecRows(12);
    if (!rows2.length) { opsEmpty(KIND_WORDS[app.kind] || "app"); return; }
    rows2.forEach(function (rr, i) {
      var li = el("div", "rf-ops-feed-item");
      li.style.cssText = "display:flex;gap:12px;align-items:baseline;padding:10px 0;"
        + "border-bottom:1px solid #F0F0F2;";
      var dot = el("span", "rf-ops-dot");
      dot.style.cssText = "width:8px;height:8px;border-radius:999px;flex:none;align-self:center;";
      dot.style.background = i === 0 ? d.accent : hexToRgba(d.accent, 0.3);
      li.appendChild(dot);
      var body = el("span", "rf-ops-feed-text", rr.what + (rr.detail ? " — " + rr.detail : ""));
      body.style.cssText = "flex:1;font-size:14px;";
      if (i === 0) body.style.fontWeight = "600";
      li.appendChild(body);
      var t4 = el("span", "rf-ops-feed-time", rr.when);
      t4.style.cssText = "font-size:11px;color:#9AA3B2;font-variant-numeric:tabular-nums;";
      li.appendChild(t4);
      panel.appendChild(li);
    });
  }

  function renderOps(app) {
    if (!panel || !state.ops) return;
    panel.removeAttribute("hidden");
    panel.innerHTML = "";
    var design = app.design || {};
    var accent = /^#[0-9a-fA-F]{6}$/.test(design.accent || "") ? design.accent : "#0B1220";
    var radius = (design.radius >= 0 && design.radius <= 22) ? design.radius : 14;
    var d = { accent: accent, radius: radius };
    panel.style.borderRadius = (radius + 6) + "px";
    panel.style.fontFamily = FONT_STACKS[design.font] || FONT_STACKS.sans;
    panel.style.boxShadow = "0 18px 50px " + hexToRgba(accent, 0.12);
    panel.style.borderColor = hexToRgba(accent, 0.25);
    panel.style.background = "linear-gradient(180deg, " + hexToRgba(accent, 0.05) + ", #FFFFFF 140px)";
    var badge = el("div", "rf-panel-badge", "SECOND SURFACE · SAME ROWS");
    badge.style.cssText = "display:inline-block;font-size:10px;font-weight:700;"
      + "letter-spacing:0.14em;padding:4px 10px;border-radius:999px;margin-bottom:10px;";
    badge.style.background = hexToRgba(accent, 0.12);
    badge.style.color = accent;
    panel.appendChild(badge);
    var title = el("div", "rf-panel-title",
      state.ops.title || OPS_TITLES[app.kind] || "Ops view");
    title.style.borderLeft = "4px solid " + accent;
    title.style.paddingLeft = "12px";
    panel.appendChild(title);
    panel.appendChild(el("div", "rf-panel-sub",
      (VIEW_NAMES[state.ops.view] || "view") + " · reading the rows "
      + (app.title || "the app") + " writes · live"));
    statStrip(panel, d, opsStats(app));
    if (state.ops.view === "table") renderOpsTable(app, d);
    else if (state.ops.view === "feed") renderOpsFeed(app, d);
    else if (!opsBars(app, d)) renderOpsTable(app, d);
    var note = el("div", "rf-ops-note",
      "0 copies. 1 database. This surface reads the same rows the "
      + (KIND_WORDS[app.kind] || "app") + " writes.");
    note.style.cssText = "margin-top:14px;font-size:11px;color:#9AA3B2;"
      + "font-family:ui-monospace, 'SF Mono', Menlo, Consolas, monospace;";
    panel.appendChild(note);
  }

  function finishBuild(app, rows, secs) {
    state.recs = [];
    state.app = app;
    state.ops = null;
    activeSurface = "app";
    state.biz = app.business || state.biz;
    bump(2, 0);
    save();
    renderTabs();
    renderActive();
    if (built) built.removeAttribute("hidden");
    if (builtLine) {
      var word = KIND_WORDS[app.kind] || "app";
      builtLine.textContent = "This " + word + " didn't exist " + Math.max(secs, 2) +
        " seconds ago. It's " + rows + " row" + (rows === 1 ? "" : "s") +
        " in our database — no files, no deploy. Every click writes another; " +
        "it's here when you come back.";
    }
    renderLedger();
    renderThread();
  }

  function startBuild() {
      if (building) return;
      var biz = bizInput ? String(bizInput.value || "").trim() : "";
      if (!biz) { say("name the business first — anything real"); if (bizInput) bizInput.focus(); return; }
      building = true;
      buildBtn.setAttribute("disabled", "");
      if (rowstream) rowstream.innerHTML = "";
      if (panel) { panel.setAttribute("hidden", ""); panel.innerHTML = ""; }
      if (built) built.setAttribute("hidden", "");
      if (tabsHost) { tabsHost.setAttribute("hidden", ""); tabsHost.innerHTML = ""; }
      if (chooser) { chooser.setAttribute("hidden", ""); chooser.innerHTML = ""; }
      var t0 = Date.now();
      say("model call running…");
      runPipe("spawn-app", { business: biz, visitor: state.v },
        function (launch) {
          building = false;
          buildBtn.removeAttribute("disabled");
          var out = launch.output || {};
          if (out.refused) { say(String(out.refused).slice(0, 140)); return; }
          var rows = (out.rows && out.rows.length) ? out.rows : [];
          var meta = rows[0] && rows[0].meta ? rows[0].meta : null;
          if (!meta) { say("that build came back empty — try again"); return; }
          var secs = Math.round((Date.now() - t0) / 1000);
          say(rows.length + " row" + (rows.length === 1 ? "" : "s") +
            " written · rendering…");
                    var chipSrc = meta.fields ? meta.fields.map(function (f) { return f.key; })
            : meta.stages ? meta.stages
            : meta.items ? meta.items.map(function (i) { return i.name; })
            : meta.requests ? meta.requests.map(function (r) { return r.title; })
            : meta.tasks ? meta.tasks.map(function (t) { return t.title; })
            : meta.members ? meta.members.map(function (mm) { return mm.name; })
            : meta.samples ? meta.samples.map(function (x) { return x.name || x; })
            : meta.question ? [meta.question]
            : (meta.times || []);
          chipSrc.forEach(function (c, i) { chip(c, 120 + i * 110); });
          later(function () { finishBuild(meta, rows.length, secs); }, 650);
        },
        function (err) {
          building = false;
          buildBtn.removeAttribute("disabled");
          if (err && err.status === 429) say("too many builds this minute — try again shortly");
          else if (err && err.message === "parked") say("the model key is offline right now — try again in a bit");
          else say("that build failed — " + String((err && err.message) || "unknown error").slice(0, 120));
        });
  }

  root.querySelectorAll("[data-build-go]").forEach(function (btn) {
    ctx.on(btn, "click", startBuild);
  });
  root.querySelectorAll("[data-biz-input]").forEach(function (inp) {
    ctx.on(inp, "keydown", function (ev) {
      if (ev && ev.key === "Enter") startBuild();
    });
  });

  root.querySelectorAll("[data-built-contact]").forEach(function (btn) {
    ctx.on(btn, "click", function () { bump(2, 0); showScreen("contact"); });
  });

  // === copy threading ======================================================
  function renderThread() {
    var t = one("[data-thread]");
    if (!t) return;
    if (state.biz) {
      t.removeAttribute("hidden");
      t.textContent = "For a " + state.biz + ": the first deployment usually means one urgent workflow, live.";
    } else {
      t.setAttribute("hidden", "");
    }
  }

  // === contact =============================================================
  var sendBtn = one("[data-send]");
  function sendLead() {
      var name = String((one("[data-lead-name]") || {}).value || "").trim();
      var email = String((one("[data-lead-email]") || {}).value || "").trim();
      var note = String((one("[data-lead-note]") || {}).value || "").trim();
      if (!note) { var na = one("[data-lead-note]"); if (na) na.focus(); return; }
      sendBtn.setAttribute("disabled", "");
      sendBtn.textContent = "Sending…";
      runPipe("lead-submit", {
        visitor: state.v, name: name, email: email, note: note,
        business: state.biz, kind: (state.i > state.o) ? "investor" : "operator"
      }, function () {
        sendBtn.textContent = "Sent";
        var s = one("[data-success]");
        if (s) s.removeAttribute("hidden");
      }, function () {
        sendBtn.removeAttribute("disabled");
        sendBtn.textContent = "Send →";
        var s = one("[data-success]");
        if (s) {
          s.removeAttribute("hidden");
          var p = s.querySelector("p");
          if (p) p.textContent = "That send failed — email us instead and it still lands in the same database.";
        }
      });
  }
  root.querySelectorAll("[data-send]").forEach(function (btn) {
    ctx.on(btn, "click", sendLead);
  });

  // === the ledger ==========================================================
  var ledger = one("[data-ledger]");

  function renderLedger() {
    var list = one("[data-ledger-list]");
    if (!list) return;
    list.innerHTML = "";
    var items = [
      ["visitor", state.v],
      ["first seen", new Date(state.first).toLocaleDateString()],
      ["visits", String(state.visits)],
      ["screens opened", String(Object.keys(state.screens).length) + " of " + SCREENS.length]
    ];
    if (state.doors.length) items.push(["doors chosen", state.doors.join(", ")]);
    if (state.biz) items.push(["business named", state.biz]);
    if (state.app) items.push(["app built", state.app.title || "yes"]);
    if (state.app) items.push(["surfaces", state.ops ? "2 — collect + visualize" : "1 — collect"]);
    if (state.recs.length) items.push(["records added", String(state.recs.length)]);
    items.forEach(function (pair) {
      var li = el("li", "rf-ledger-item");
      li.appendChild(el("span", "rf-ledger-key", pair[0]));
      li.appendChild(el("span", "rf-ledger-val", pair[1]));
      list.appendChild(li);
    });
  }

  root.querySelectorAll("[data-ledger-open]").forEach(function (btn) {
    ctx.on(btn, "click", function () {
      if (!ledger) return;
      renderLedger();
      ledger.removeAttribute("hidden");
    });
  });
  root.querySelectorAll("[data-ledger-close]").forEach(function (btn) {
    ctx.on(btn, "click", function () { if (ledger) ledger.setAttribute("hidden", ""); });
  });
  root.querySelectorAll("[data-ledger-clear]").forEach(function (btn) {
    ctx.on(btn, "click", function () {
      if (storage) { try { storage.removeItem(KEY); } catch (e) {} }
      state = { v: "v-" + Math.random().toString(36).slice(2, 10), first: Date.now(),
                last: Date.now(), visits: 1, screens: {}, doors: [], biz: "", app: null,
                ops: null, recs: [], o: 0, i: 0 };
      save();
      activeSurface = "app";
      if (panel) { panel.setAttribute("hidden", ""); panel.innerHTML = ""; }
      if (built) built.setAttribute("hidden", "");
      if (rowstream) rowstream.innerHTML = "";
      if (tabsHost) { tabsHost.setAttribute("hidden", ""); tabsHost.innerHTML = ""; }
      if (chooser) { chooser.setAttribute("hidden", ""); chooser.innerHTML = ""; }
      say("");
      if (ledger) ledger.setAttribute("hidden", "");
      renderLedger();
      renderReturn();
      renderThread();
      showScreen("home");
    });
  });

  // === the return visit ====================================================
  function renderReturn() {
    var box = one("[data-return]");
    var line = one("[data-return-line]");
    if (!box || !line) return;
    if (state.app && state.visits > 1) {
      line.textContent = "Welcome back. Your " + (state.app.title || "app") +
        " is where you left it — " + state.recs.length + " record" +
        (state.recs.length === 1 ? "" : "s") + ".";
      box.removeAttribute("hidden");
    } else {
      box.setAttribute("hidden", "");
    }
  }

  // === boot ================================================================
  if (state.app) { renderTabs(); renderActive(); if (built) built.removeAttribute("hidden"); }
  if (state.app && builtLine && !builtLine.textContent) {
    builtLine.textContent = "Your " + (state.app.title || "app") +
      " — still here, still rows. Add a " + (state.app.noun || "record") + ".";
  }
  renderReturn();
  renderLedger();
  renderThread();
  retargetForwards();
  var h = "";
  try { h = String(window.location.hash || "").replace("#", ""); } catch (e) {}
  showScreen(SCREENS.indexOf(h) >= 0 ? h : "home", true);
  save();

  return function teardown() {
    timers.forEach(function (id) { clearTimeout(id); });
    timers = [];
  };
}
