/* simple/core.jsx — the redesigned app's spine.
   ConfirmSheet is THE execution primitive: every money action — agent
   proposal or manual order — funnels into the same review → passkey →
   success flow. Two doors, one primitive.
   Also: the agent card library rendered inline in the Yoshi thread.
   Each card replaces a killed screen (Studio, Trade browse, Briefs). */

/* ---------- shared money rows ---------------------------------------------- */
const LegRow = ({ leg, last }) => {
  const [tag, label, detail, amount] = leg;
  const tagColor = tag === "SELL" ? "var(--signal-neg)" : tag === "BUY" ? "var(--accent-pos)" : "var(--ink-2)";
  // newer proposals put a security object in the label slot ({ ticker, price, change, name, valueLabel })
  const sec = label && typeof label === "object" ? label : null;
  return (
    <div style={{ display: "grid", gridTemplateColumns: "62px 1fr auto", gap: 8, alignItems: "center", padding: "9px 11px", borderBottom: last ? "none" : "1px dashed var(--rule)" }}>
      <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(9.5), fontWeight: 700, letterSpacing: "0.08em", color: tagColor }}>{tag}</span>
      <div style={{ minWidth: 0 }}>
        {sec ? (
          <>
            <div style={{ display: "flex", alignItems: "baseline", gap: 6, flexWrap: "wrap" }}>
              <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), fontWeight: 600 }}>{sec.ticker}</span>
              {sec.price ? <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(10.5), color: "var(--ink-3)" }}>{sec.price}</span> : null}
              {sec.change ? <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(10), color: sec.changeTone === "neg" ? "var(--signal-neg)" : "var(--accent-pos)" }}>{sec.change}</span> : null}
            </div>
            {(sec.name || sec.valueLabel) ? <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10.5), color: "var(--ink-3)" }}>{[sec.name, sec.valueLabel].filter(Boolean).join(" · ")}</div> : null}
          </>
        ) : (
          <>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), fontWeight: 500 }}>{label}</div>
            {detail ? <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10.5), color: "var(--ink-3)" }}>{detail}</div> : null}
          </>
        )}
      </div>
      <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(12), color: "var(--ink)", whiteSpace: "nowrap" }}>{amount}</span>
    </div>
  );
};

const StatCell = ({ label, value, color = "var(--ink)", border }) => (
  <div style={{ padding: "11px 13px", borderLeft: border ? "1px solid var(--rule)" : "none" }}>
    <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10), fontWeight: 600, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--ink-3)" }}>{label}</div>
    <div style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(15), fontWeight: 500, color, marginTop: 3, fontVariantNumeric: "tabular-nums" }}>{value}</div>
  </div>
);

/* ============================================================
   ConfirmSheet · the one execution primitive.
   `action` = { title, why, legs, net, settles, settlesVerb, kind, agent }
   agent falsy → a manual order (your own trade/move); truthy → a proposal.
   Both render identically: same review, same passkey, same success.
   ============================================================ */
const CONFIRM_DECLINES = ["Not now", "Too large", "I'll do it manually", "Don't trust the timing"];

const ConfirmSheet = ({ action, onClose, onApproved, onDeclined, onAsk }) => {
  const [phase, setPhase] = useState("review");
  const [authing, setAuthing] = useState(false);
  const [msg, setMsg] = useState("");
  const a = action;
  const manual = !a.agent;

  const doConfirm = () => { setAuthing(true); setTimeout(() => { setAuthing(false); setPhase("success"); }, 950); };

  return (
    <div className="push-enter" data-screen-label="Confirm" style={{ position: "absolute", inset: 0, zIndex: 320, background: "var(--bg)", display: "flex", flexDirection: "column" }}>
      {window.StatusBar && <window.StatusBar />}
      {phase !== "success" && (
        <div style={{ display: "flex", justifyContent: "flex-end", padding: "4px 20px 0", flex: "none" }}>
          <button className="press" onClick={onClose} aria-label="Close" style={{ background: "none", border: "none", padding: 0, color: "var(--ink-3)", display: "flex", cursor: "pointer" }}><Icon name="close" size={19} /></button>
        </div>
      )}

      {/* who initiated — the same header for both doors builds one habit */}
      {phase !== "success" && (
        <div style={{ padding: "8px 20px 0", flex: "none" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <span style={{ width: 7, height: 7, borderRadius: 999, flex: "none", background: manual ? "transparent" : "var(--accent)", border: manual ? "1.5px solid var(--ink-3)" : "none" }} />
            <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10), fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", color: manual ? "var(--ink-3)" : "var(--accent)" }}>{manual ? "Your order" : a.agent}</span>
          </div>
        </div>
      )}

      {phase === "review" && (
        <>
          <div className="scroll" style={{ padding: "0 20px" }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(22), fontWeight: 600, letterSpacing: "-0.025em", marginTop: 8 }}>{a.title}</div>
            {a.why && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13.5), color: "var(--ink-2)", marginTop: 7, lineHeight: 1.55 }}>{a.why}</div>}

            <Eyebrow style={{ margin: "16px 0 7px" }}>{manual ? "Order" : "Proposal"}</Eyebrow>
            <div style={{ border: "1px solid var(--rule-2)", borderRadius: 12, overflow: "hidden" }}>
              {a.legs.map((leg, i) => <LegRow key={i} leg={leg} last={i === a.legs.length - 1} />)}
            </div>

            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", marginTop: 14, border: "1px solid var(--rule)", borderRadius: 12, overflow: "hidden" }}>
              <StatCell label={a.kind === "automation" ? "Amount" : "Net effect"} value={signed(a.net)} color={a.net >= 0 ? "var(--accent-pos)" : "var(--ink)"} />
              <StatCell label={a.settlesVerb || "Settles"} value={a.settles} border />
            </div>

            <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 12, marginBottom: 8, padding: "10px 12px", background: "var(--bg-2)" }}>
              <Icon name="shield" size={16} color="var(--ink-3)" stroke={1.5} />
              <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", lineHeight: 1.45 }}>
                {a.kind === "automation" ? "Turns on only after you approve. Future runs follow these parameters and limits."
                  : manual ? "Executes immediately after your passkey. It lands in Activity like everything else."
                  : "Yoshi makes the move, only after you approve."}
              </span>
            </div>
          </div>

          <div style={{ flex: "none", padding: "0 20px" }}><Seam style={{ margin: "12px 0 0", background: "var(--rule-2)", opacity: 1 }} /></div>
          <div style={{ flex: "none", padding: "12px 20px 20px" }}>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
              {manual
                ? <Btn kind="ghost" onClick={onClose}>Cancel</Btn>
                : <Btn kind="danger" onClick={() => setPhase("decline")}>Decline</Btn>}
              <Btn onClick={() => setPhase("confirm")}>Approve</Btn>
            </div>
            {!manual && onAsk && (
              <div style={{ marginTop: 10 }}>
                <YoshiComposer value={msg} onChange={setMsg} onSend={() => { const t = msg.trim(); if (t) { setMsg(""); onAsk(a, t); } }} placeholder="Ask Yoshi about this…" />
              </div>
            )}
          </div>
        </>
      )}

      {phase === "confirm" && (
        <>
          <div style={{ padding: "8px 20px 0", flex: 1, display: "flex", flexDirection: "column" }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(20), fontWeight: 600, letterSpacing: "-0.02em" }}>{a.title}</div>
            <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 12, paddingBottom: 14, borderBottom: "1px solid var(--rule)" }}>
              <Eyebrow>Net effect</Eyebrow>
              <Money value={a.net} size={20} sign color={a.net >= 0 ? "var(--accent-pos)" : "var(--ink)"} style={{ marginLeft: "auto" }} />
            </div>
            <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 16, padding: "24px 0" }}>
              <div style={{ position: "relative", width: 72, height: 72, display: "grid", placeItems: "center" }}>
                {authing && <span style={{ position: "absolute", inset: 0, border: "1.5px solid var(--accent)", borderRadius: 16, animation: "ring-out 950ms ease-out infinite" }} />}
                <div style={{ width: 64, height: 64, border: `1.5px solid ${authing ? "var(--accent)" : "var(--rule-2)"}`, borderRadius: 16, display: "grid", placeItems: "center", transition: "border-color 200ms ease" }}>
                  <Icon name="shield" size={30} stroke={1.4} color={authing ? "var(--accent)" : "var(--ink-2)"} />
                </div>
              </div>
              <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), color: "var(--ink-2)", textAlign: "center" }}>
                {authing ? "Authenticating…" : a.kind === "automation" ? "Confirm with your passkey.\nYoshi schedules it and asks before the first run." : manual ? "Confirm with your passkey.\nYour order executes immediately." : "Confirm with your passkey.\nYoshi executes immediately."}
              </div>
            </div>
          </div>
          <div style={{ flex: "none", padding: "0 20px 20px" }}>
            <Btn full onClick={doConfirm} disabled={authing}>{authing ? "Confirming…" : "Confirm with passkey"}</Btn>
            <Btn kind="ghost" full onClick={() => setPhase("review")} style={{ marginTop: 8 }} disabled={authing}>Back</Btn>
          </div>
        </>
      )}

      {phase === "success" && (
        <div style={{ padding: "8px 20px 22px", display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center" }}>
          <div style={{ width: "100%", margin: "6px 0 22px" }}><Seam draw /></div>
          <div style={{ width: 66, height: 66, borderRadius: 999, border: "1.5px solid var(--accent)", display: "grid", placeItems: "center", marginBottom: 18 }}>
            <svg width="34" height="34" viewBox="0 0 24 24" style={{ display: "block" }}>
              <path d="M5 12.5 L10 17.5 L19 6.5" fill="none" stroke="var(--accent)" strokeWidth="2.2" strokeLinecap="square" />
            </svg>
          </div>
          <Eyebrow color="var(--accent)">{a.kind === "automation" ? "Approved" : "Executed"}</Eyebrow>
          <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(21), fontWeight: 600, letterSpacing: "-0.02em", marginTop: 6 }}>{a.title}</div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), color: "var(--ink-2)", marginTop: 7, lineHeight: 1.5, maxWidth: 280 }}>
            {a.kind === "automation" ? "Yoshi scheduled the automation. It asks before the first run." : <>Done. Net {signed(a.net)} · {a.settlesVerb || "settles"} {a.settles}. It's in your Activity.</>}
          </div>
          <div style={{ width: "100%", marginTop: 22 }}><Btn full onClick={() => onApproved(a)}>Done</Btn></div>
        </div>
      )}

      {phase === "decline" && (
        <DeclineBody a={a} onBack={() => setPhase("review")} onDeclined={onDeclined} />
      )}
    </div>
  );
};

const DeclineBody = ({ a, onBack, onDeclined }) => {
  const [r, setR] = useState(null);
  const [note, setNote] = useState("");
  return (
    <>
      <div style={{ padding: "8px 20px 0", flex: 1 }}>
        <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(18), fontWeight: 600, letterSpacing: "-0.018em" }}>Why decline?</div>
        <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), color: "var(--ink-2)", marginTop: 5, lineHeight: 1.5 }}>Yoshi learns from this. It won't run.</div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 16 }}>
          {CONFIRM_DECLINES.map((reason) => (
            <button key={reason} className="press" onClick={() => setR(reason)} style={{ padding: "9px 13px", borderRadius: 999, background: r === reason ? "var(--ink)" : "transparent", color: r === reason ? "var(--bg)" : "var(--ink)", border: "1px solid var(--rule-2)", fontFamily: "var(--f-display)", fontSize: typeSize(12.5), fontWeight: 500, cursor: "pointer" }}>{reason}</button>
          ))}
        </div>
        <textarea value={note} onChange={(e) => setNote(e.target.value)} placeholder="Or tell Yoshi why, in your own words…" rows={3}
          style={{ width: "100%", boxSizing: "border-box", marginTop: 14, padding: "12px 13px", background: "var(--bg-2)", border: "1px solid var(--rule-2)", borderRadius: 12, color: "var(--ink)", fontFamily: "var(--f-display)", fontSize: typeSize(13.5), lineHeight: 1.5, outline: "none", resize: "none" }} />
      </div>
      <div style={{ flex: "none", padding: "16px 20px 20px" }}>
        <Btn kind="danger" full onClick={() => onDeclined(a, note.trim() || r || "Not now")}>Decline proposal</Btn>
        <Btn kind="ghost" full onClick={onBack} style={{ marginTop: 8 }}>Back</Btn>
      </div>
    </>
  );
};

/* ============================================================
   Agent cards · rendered inline in the Yoshi thread (and on Home
   for pending proposals). Terminal or actionable — a card answers
   the question or carries ≤2 buttons that lead to ConfirmSheet.
   ============================================================ */

/* from→to route + amount pulled from a proposal's legs, so the card can state
   exactly what will happen instead of a vague "Net". */
const propRoute = (p) => {
  const find = (t) => p.legs && p.legs.find((l) => l[0] === t);
  const from = find("FROM"), to = find("TO") || find("PAY");
  const parts = [];
  if (from) parts.push("From " + from[1]);
  if (to) parts.push((from ? "to " : "To ") + to[1]);
  return parts.join(" ");
};
const propAmount = (p) => {
  const l = p.legs && (p.legs.find((x) => x[0] === "FROM") || p.legs.find((x) => x[0] === "PAY") || p.legs.find((x) => x[0] === "TO"));
  const cell = l && l[3];
  return (cell && /\d/.test(cell)) ? cell : (p.net ? usd(Math.abs(p.net)) : null);
};

/* proposal card — the only thing allowed to "pool", and it pools on Home */
const PCard = ({ p, onReview, compact }) => {
  const route = propRoute(p);
  const amount = propAmount(p);
  return (
    <div style={{ border: "1px solid var(--rule)", borderRadius: 12, overflow: "hidden", background: "var(--bg-card)" }}>
      <div style={{ padding: "13px 14px 14px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <span style={{ width: 6, height: 6, borderRadius: 999, flex: "none", background: "var(--accent)" }} />
          <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10), fontWeight: 600, color: "var(--ink-3)", letterSpacing: "0.04em" }}>{p.agent}</span>
        </div>
        {/* explicit action + amount */}
        <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 7 }}>
          <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(16), fontWeight: 600, letterSpacing: "-0.02em", minWidth: 0 }}>{p.title}</span>
          {amount && <span style={{ marginLeft: "auto", fontFamily: "var(--f-mono)", fontSize: typeSize(15), fontWeight: 600, color: "var(--ink)", whiteSpace: "nowrap" }}>{amount}</span>}
        </div>
        {/* details: from where to where */}
        {route && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12), color: "var(--ink-2)", marginTop: 5, lineHeight: 1.45 }}>{route}</div>}
        {!compact && p.why && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), color: "var(--ink-3)", marginTop: 6, lineHeight: 1.5 }}>{p.why}</div>}
        <Btn full onClick={onReview} style={{ marginTop: 12 }}>Review <Icon name="arrow" size={16} color="var(--accent-ink)" /></Btn>
      </div>
    </div>
  );
};

/* chat proposal card — compact, matches the web app (and main's InlineProposal):
   a "Proposal" eyebrow (accent), the title, the net + a settle/starts label, and
   a small Review button. No description paragraph — that lives in the review. */
const ChatProposal = ({ p, onReview, done }) => (
  <div style={{ width: "min(184px, 100%)", border: "1px solid " + (done ? "var(--rule)" : "var(--accent)"), background: "var(--bg-card)", borderRadius: 12, boxSizing: "border-box" }}>
    <div style={{ padding: "8px 10px 10px", display: "flex", flexDirection: "column" }}>
      <Eyebrow color={done ? "var(--ink-3)" : "var(--accent)"}>{done ? "● Executed" : "Proposal"}</Eyebrow>
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), fontWeight: 600, letterSpacing: "-0.012em", marginTop: 4, lineHeight: 1.2 }}>{p.title}</div>
      <div style={{ display: "flex", alignItems: "baseline", gap: 5, marginTop: 5 }}>
        <Money value={p.net} size={11.5} sign color={p.net >= 0 ? "var(--accent-pos)" : "var(--ink)"} dim="var(--ink-3)" />
        <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(8.5), color: "var(--ink-3)", marginLeft: "auto" }}>{p.settlesVerb || "settles"} {p.settles}</span>
      </div>
      {!done && <Btn full size="sm" onClick={onReview} style={{ marginTop: 9 }}>Review</Btn>}
    </div>
  </div>
);

/* quote card — replaces the Trade browse surface. Ask about a ticker, get
   the price and the two buttons that matter. */
const QuoteCard = ({ id, nav }) => {
  const m = MARKET.find((x) => x.id === id || x.ticker === String(id).toUpperCase());
  if (!m) return null;
  const h = securityHolding(m.id);
  const data = series(m.id.length * 7 + 13, 34, m.last * (1 - m.dch / 100), m.last, 0.012);
  return (
    <div style={{ border: "1px solid var(--rule)", borderRadius: 12, overflow: "hidden", background: "var(--bg-card)" }}>
      <button className="press" onClick={() => nav.security(m.id)} style={{ width: "100%", textAlign: "left", background: "none", border: "none", padding: "13px 14px 4px", cursor: "pointer" }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
          <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(13), fontWeight: 700, color: "var(--accent)" }}>{m.ticker}</span>
          <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12), color: "var(--ink-3)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{m.name}</span>
        </div>
        <div style={{ display: "flex", alignItems: "baseline", gap: 9, marginTop: 6 }}>
          <Money value={m.last} size={20} weight={600} />
          <Delta pct={m.dch} size={12} showAbs={false} />
          {h && <span style={{ marginLeft: "auto", fontFamily: "var(--f-display)", fontSize: typeSize(10.5), color: "var(--ink-3)" }}>You hold {compactUsd(h.value)}</span>}
        </div>
      </button>
      <div style={{ padding: "2px 8px 0" }}>
        <Chart data={data} height={56} showAxisLabels={false} baseline={false} accent={m.dch >= 0 ? "var(--accent-pos)" : "var(--signal-neg)"} />
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, padding: "10px 12px 12px" }}>
        <Btn onClick={() => nav.sheet({ type: "trade", id: m.id, side: "BUY" })} style={{ padding: "10px" }}>Buy</Btn>
        <Btn kind="ghost" onClick={() => nav.sheet({ type: "trade", id: m.id, side: "SELL" })} style={{ padding: "10px" }}>Sell</Btn>
      </div>
    </div>
  );
};

/* comparison card — replaces Studio's analyze workspace. Rendered on request. */
const CompareCard = ({ aLabel = "Your portfolio", bLabel = "S&P 500", aRet = 18.9, bRet = 14.2 }) => {
  const A = series(7, 40, 100, 100 + aRet, 0.02);
  const B = series(8, 40, 100, 100 + bRet, 0.014);
  const all = [...A, ...B];
  const min = Math.min(...all), max = Math.max(...all), R = max - min || 1;
  const W = 320, H = 96;
  const path = (d) => d.map((v, i) => `${i === 0 ? "M" : "L"}${((i / (d.length - 1)) * W).toFixed(1)},${(8 + (1 - (v - min) / R) * (H - 16)).toFixed(1)}`).join(" ");
  return (
    <div style={{ border: "1px solid var(--rule)", borderRadius: 12, overflow: "hidden", background: "var(--bg-card)", padding: "13px 14px" }}>
      <Eyebrow>Past year · indexed</Eyebrow>
      <svg width="100%" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{ display: "block", marginTop: 10 }}>
        <line x1="0" y1={H - 8} x2={W} y2={H - 8} stroke="var(--rule)" strokeWidth="1" strokeDasharray="2 3" vectorEffect="non-scaling-stroke" />
        <path d={path(B)} fill="none" stroke="var(--ink-3)" strokeWidth="1.4" vectorEffect="non-scaling-stroke" />
        <path d={path(A)} fill="none" stroke="var(--accent)" strokeWidth="1.6" vectorEffect="non-scaling-stroke" />
      </svg>
      <div style={{ display: "flex", gap: 16, marginTop: 10 }}>
        {[[aLabel, aRet, "var(--accent)"], [bLabel, bRet, "var(--ink-3)"]].map(([l, r, c]) => (
          <span key={l} style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
            <span style={{ width: 14, height: 2, background: c, flex: "none" }} />
            <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-2)" }}>{l}</span>
            <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(11), fontWeight: 600, color: c === "var(--accent)" ? "var(--accent-pos)" : "var(--ink-2)" }}>{pct(r)}</span>
          </span>
        ))}
      </div>
    </div>
  );
};

/* insight card — replaces the Briefs "insights" tab. Pushed, never pooled. */
const InsightChip = ({ label, stat, read }) => (
  <div style={{ border: "1px solid var(--rule)", borderRadius: 12, background: "var(--bg-card)", padding: "13px 14px" }}>
    <div style={{ display: "flex", alignItems: "baseline", gap: 10 }}>
      <Eyebrow>{label}</Eyebrow>
      <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(16), fontWeight: 600, color: "var(--accent-pos)" }}>{stat}</span>
    </div>
    <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), color: "var(--ink-2)", marginTop: 6, lineHeight: 1.5 }}>{read}</div>
  </div>
);

/* document card — replaces the Docs hub. Ask, receive, done. */
const DocCard = ({ name, sub, flash }) => (
  <div style={{ border: "1px solid var(--rule)", borderRadius: 12, background: "var(--bg-card)", padding: "13px 14px", display: "flex", alignItems: "center", gap: 12 }}>
    <span style={{ width: 34, height: 34, flex: "none", border: "1px solid var(--rule-2)", borderRadius: 9, display: "grid", placeItems: "center", color: "var(--ink-2)" }}><Icon name="doc" size={17} /></span>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13.5), fontWeight: 600 }}>{name}</div>
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", marginTop: 2 }}>{sub}</div>
    </div>
    <Btn kind="quiet" onClick={() => flash && flash("Sent to your email")} style={{ padding: "9px 14px" }}>Share</Btn>
  </div>
);

/* automations card — replaces the automations tab. The agent manages the
   rules; this is the glanceable list, conversational management. */
const AutosCard = ({ flash }) => (
  <div style={{ border: "1px solid var(--rule)", borderRadius: 12, background: "var(--bg-card)", overflow: "hidden" }}>
    {AUTOMATIONS.slice(0, 5).map((au, i) => (
      <div key={au.id} style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 10, alignItems: "center", padding: "11px 14px", borderTop: i ? "1px solid var(--rule)" : "none" }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <span style={{ width: 5, height: 5, borderRadius: 999, flex: "none", background: au.status === "active" ? "var(--accent)" : "var(--ink-3)" }} />
            <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{au.name}</span>
          </div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10.5), color: "var(--ink-3)", marginTop: 2 }}>{au.cadence}</div>
        </div>
        <span style={{ fontFamily: "var(--f-mono)", fontSize: typeSize(12), color: au.measure.startsWith("+") ? "var(--accent-pos)" : "var(--ink-2)" }}>{au.measure}</span>
      </div>
    ))}
    <div style={{ padding: "10px 14px", borderTop: "1px solid var(--rule)", fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", lineHeight: 1.45 }}>
      Tell me to pause, change, or add a rule — in plain words.
    </div>
  </div>
);

Object.assign(window, { LegRow, StatCell, ConfirmSheet, PCard, QuoteCard, CompareCard, InsightChip, DocCard, AutosCard });
