/* Claude Routine Planner — application styles (ZPARX brand) */

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; }

body {
  font-family: var(--font-body);
  background:
    radial-gradient(1100px 600px at 12% -10%, rgba(61, 90, 241, 0.18), transparent 60%),
    radial-gradient(900px 500px at 100% 0%, rgba(255, 106, 31, 0.10), transparent 55%),
    var(--bg-base);
  color: var(--text-hi);
  min-height: 100%;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--periwinkle); }

/* ── Layout shell ──────────────────────────────────
   One fixed top rail + a single scrolling body underneath (Claude Code shape):
   the chrome never scrolls away, and a view can choose to own the whole pane
   instead of the page scroll (see .content--flush / History). */
.app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;              /* exclude mobile browser chrome */
  height: var(--app-h, 100dvh); /* …and prefer the height JS actually measured */
  min-height: 0;
  overflow: hidden;
}
.content {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  padding:
    var(--sp-6)
    max(var(--sp-8), env(safe-area-inset-right))
    var(--sp-16)
    max(var(--sp-8), env(safe-area-inset-left));
}
/* Views that render their own full-height layout (History) take the pane raw —
   no page padding, no page scroll; their inner columns scroll instead.
   The chain from .app down to a scrolling column is flex the whole way, with
   min-height:0 at every link. It used to hand the pane a percentage height
   (#view { height: 100% }) — iPadOS Safari resolves that against a
   flex-derived parent height unreliably, and when it failed the panes grew past
   the viewport, the overflow:hidden here clipped them, and nothing scrolled at
   all. Never reintroduce a percentage height in this chain. */
.content--flush { padding: 0; overflow: hidden; position: relative; }
.content--flush > #view { position: absolute; inset: 0; display: flex; flex-direction: column; }

@media (min-width: 900px) {
  .content { padding-left: var(--sp-8); padding-right: max(var(--sp-12), env(safe-area-inset-right)); }
  .content--flush { padding: 0; }
}
/* The top rail keeps every tab reachable without scrolling. Above 1140px it is
   one row and sheds the widest optional chips as space runs out; below that the
   nav takes a full row of its own, which buys the chips back. (Measured widths:
   brand 186 · nav 612 · clock 206 · budget 144 · new 130.) Verified for overflow
   at 19 widths from 1920 down to 360 — an iPad in landscape keeps one row. */
@media (min-width: 1141px) and (max-width: 1500px) {
  .clock--time.clock--next .clock__now { display: none; }  /* keep "next in 12m" */
  .clock--time:not(.clock--next) { display: none; }        /* nothing queued → drop it */
}
@media (min-width: 1141px) and (max-width: 1420px) { .budget-chip { display: none !important; } }
@media (min-width: 1141px) and (max-width: 1300px) {
  .topbar { gap: var(--sp-3); }
  .fire-toggle__label { display: none; }
  .tab { padding-left: var(--sp-2); padding-right: var(--sp-2); }
}

/* ── Top bar (brand + navigation + actions) ────── */
.topbar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: nowrap; /* one rail on desktop; the narrow query wraps nav to row 2 */
  flex: 0 0 auto;
  padding:
    calc(var(--sp-3) + env(safe-area-inset-top))
    max(var(--sp-6), env(safe-area-inset-right))
    var(--sp-3)
    max(var(--sp-6), env(safe-area-inset-left));
  border-bottom: 1px solid var(--hairline);
  background: linear-gradient(180deg, rgba(20,27,46,0.72), rgba(12,17,31,0.88));
  backdrop-filter: blur(10px);
  z-index: 30;
}
.topbar__actions { margin-left: auto; }
.brand { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; padding: 0 var(--sp-2); min-width: 0; }
.brand--bar { flex-direction: row; align-items: center; gap: var(--sp-2); padding-left: 0; flex: 0 0 auto; }
.brand--bar .brand__logo { height: 22px; }
.brand--bar .brand__wordmark { font-size: 11px; }
.brand__logo { height: 26px; width: auto; max-width: 100%; display: block; }
.brand__wordmark {
  font-family: var(--font-pixel);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--orange-bright);
  line-height: 1;
}
.brand__divider {
  width: 1px; height: 30px; background: var(--hairline); margin: 0 var(--sp-1);
}
.brand__title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 22px;
  letter-spacing: -0.01em;
  line-height: 1.05;
}
.brand__title b { color: var(--lime); }
.brand__eyebrow {
  display: block;
  font-family: var(--font-pixel);
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--text-low);
  text-transform: uppercase;
  margin-bottom: 2px;
}
.topbar__spacer { flex: 1 1 auto; }
.topbar__actions { display: flex; align-items: center; gap: var(--sp-2); flex: 0 0 auto; }

/* ── Account menu (top-right popover) ──────────── */
.acctmenu { position: relative; }
.acctmenu__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-mid);
  background: var(--bg-surface);
  border: 1px solid var(--hairline);
  border-radius: 50%;
  cursor: pointer;
  text-transform: uppercase;
}
.acctmenu__btn:hover { color: var(--text-hi); border-color: var(--grey-700); }
.acctmenu.is-open .acctmenu__btn { color: var(--text-hi); border-color: var(--grey-700); }
.acctmenu__pop {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 172px;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  padding: var(--sp-1);
  z-index: 60;
}
.acctmenu.is-open .acctmenu__pop { display: block; }
.acctmenu__who {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-low);
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--hairline);
  margin-bottom: var(--sp-1);
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.acctmenu__item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-radius: var(--r-sm);
  color: var(--text-mid);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  text-decoration: none;
}
.acctmenu__item:hover { background: rgba(255,255,255,0.05); color: var(--text-hi); }
.acctmenu__item--danger:hover { color: var(--danger); }

.clock {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--text-mid);
  background: var(--bg-surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  padding: var(--sp-2) var(--sp-4);
  white-space: nowrap;
}
.clock b { color: var(--lime); font-weight: 600; }
.clock--block { display: block; text-align: center; }

/* ── Buttons ───────────────────────────────────── */
.btn {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  padding: var(--sp-3) var(--sp-6);
  cursor: pointer;
  transition: transform .08s ease, box-shadow .15s ease, background .15s ease, border-color .15s ease;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  line-height: 1;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn--brand { background: var(--blue); color: var(--white); }
.btn--brand:hover { background: var(--blue-bright); box-shadow: var(--glow-blue); }
.btn--primary { background: var(--lime); color: var(--ink); }
.btn--primary:hover { background: var(--lime-glow); box-shadow: var(--glow-lime); }
.btn--accent { background: var(--orange); color: var(--white); }
.btn--accent:hover { background: var(--orange-bright); }
.btn--secondary { background: var(--bg-elevated); color: var(--text-hi); border-color: var(--hairline); }
.btn--secondary:hover { border-color: var(--grey-700); background: #222c4d; }
.btn--ghost { background: transparent; color: var(--text-mid); border-color: var(--hairline); }
.btn--ghost:hover { color: var(--text-hi); border-color: var(--grey-700); }
.btn--sm { padding: var(--sp-2) var(--sp-3); font-size: 12px; font-weight: 600; }
/* Icon-only primary action: a plus, like the Claude app's new-chat button. */
.btn--icon {
  width: 34px;
  height: 34px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
  font-size: 20px;
  font-weight: 600;
  line-height: 1;
}

/* ── Master fire switch (top bar) ──────────────── */
.fire-switch {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--r-pill);
  padding: var(--sp-2) var(--sp-4);
  cursor: pointer;
  white-space: nowrap;
  border: 1px solid var(--hairline);
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease, color .15s ease;
}
.fire-switch.is-on { background: rgba(134, 224, 30, .12); color: var(--lime); border-color: rgba(134, 224, 30, .5); }
.fire-switch.is-on:hover { box-shadow: var(--glow-lime); }
.fire-switch.is-off { background: rgba(124, 135, 158, .12); color: var(--text-mid); border-color: var(--hairline); }
.fire-switch.is-off:hover { color: var(--text-hi); border-color: var(--grey-700); }
.btn--danger-ghost { background: transparent; color: var(--danger); border-color: transparent; }
.btn--danger-ghost:hover { background: rgba(255,77,94,0.12); }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn__icon { font-size: 15px; line-height: 1; }

/* ── Tabs (horizontal nav rail in the top bar) ─── */
.tabs {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 2px;
  flex: 1 1 0;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  color: var(--text-mid);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13.5px;
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-align: left;
  white-space: nowrap;
  flex: 0 0 auto;
}
.tab:hover { color: var(--text-hi); background: rgba(255,255,255,0.03); }
.tab.is-active {
  color: var(--lime);
  background: rgba(188,239,47,0.10);
  border-color: rgba(188,239,47,0.30);
}
.tab__count {
  font-family: var(--font-mono);
  font-size: 11px;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  padding: 1px 7px;
  color: var(--text-mid);
}
.tab.is-active .tab__count { background: rgba(188,239,47,0.14); color: var(--lime); border-color: transparent; }
/* The Log badge turns hot when there are failures to look at. */
.tab__count--alert.is-hot { background: rgba(255,77,94,0.14); color: var(--danger); border-color: rgba(255,77,94,0.4); }

/* ── Fire toggle (active / inactive) ───────────── */
.fire-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  cursor: pointer;
  user-select: none;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
}
.fire-toggle__label { color: var(--text-mid); transition: color .15s ease; }
.fire-toggle.is-on .fire-toggle__label { color: var(--lime); }
.fire-toggle__track {
  position: relative;
  width: 42px;
  height: 24px;
  border-radius: var(--r-pill);
  background: rgba(124,135,158,0.20);
  border: 1px solid var(--hairline);
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
  flex: 0 0 auto;
}
.fire-toggle__knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--text-mid);
  transition: transform .16s ease, background .15s ease;
}
.fire-toggle.is-on .fire-toggle__track {
  background: rgba(188,239,47,0.22);
  border-color: rgba(188,239,47,0.5);
  box-shadow: var(--glow-lime);
}
.fire-toggle.is-on .fire-toggle__knob { transform: translateX(18px); background: var(--lime); }

/* ── Cards grid ────────────────────────────────── */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
  gap: var(--sp-4);
}

/* ── Library filter row (shelf · done · all) ──────
   The Library shows what you keep; finished one-offs sit behind Done rather
   than in the shelf. The row is always present so the split is visible — a
   filter you cannot see reads as missing routines. */
.libbar { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.libbar__btns { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.libbar__n { font-family: var(--font-mono); font-size: 11px; opacity: 0.75; margin-left: 4px; }
.libbar__note { font-family: var(--font-body); font-size: 12.5px; color: var(--text-low); flex: 1 1 240px; min-width: 0; }
.libbar__note b { color: var(--text-mid); font-weight: 600; }

.card {
  background: linear-gradient(180deg, var(--bg-surface), #121829);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: var(--sp-5, 20px);
  padding: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  box-shadow: var(--shadow-sm);
  transition: border-color .15s ease, transform .1s ease;
}
.card:hover { border-color: var(--grey-700); }
.card__head { display: flex; align-items: flex-start; gap: var(--sp-3); }
.card__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  flex: 1;
  word-break: break-word;
}
.card__prompt {
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-mid);
  background: var(--bg-void);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  padding: var(--sp-3);
  max-height: 132px;
  overflow: auto;
  white-space: pre-wrap;
}
.card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: center;
  font-size: 12px;
  color: var(--text-mid);
}
.card__meta-item { display: inline-flex; align-items: center; gap: 5px; }
.card__meta-item b { color: var(--text-hi); font-weight: 600; font-family: var(--font-mono); }
.card__foot { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: auto; padding-top: var(--sp-1); }

/* ── Status / recurrence chips ─────────────────── */
.chip {
  font-family: var(--font-pixel);
  font-size: 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: var(--r-pill);
  padding: 4px 9px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.chip--scheduled { background: rgba(61,90,241,0.16); color: var(--periwinkle); border-color: rgba(61,90,241,0.4); }
.chip--library  { background: rgba(188,239,47,0.12); color: var(--lime); border-color: rgba(188,239,47,0.35); }
.chip--archived { background: rgba(124,135,158,0.14); color: var(--grey-300); border-color: var(--grey-700); }
.chip--recurring { background: rgba(255,106,31,0.14); color: var(--orange-bright); border-color: rgba(255,106,31,0.4); }
.chip--due { background: var(--lime); color: var(--ink); }
.chip--success { background: rgba(188,239,47,0.12); color: var(--lime); border-color: rgba(188,239,47,0.35); }
.chip--running { background: rgba(61,90,241,0.16); color: var(--periwinkle); border-color: rgba(61,90,241,0.4); }
.chip--error { background: rgba(255,77,94,0.14); color: var(--danger); border-color: rgba(255,77,94,0.4); }
.chip--missed { background: rgba(245,211,59,0.10); color: var(--yellow); border-color: rgba(245,211,59,0.3); }
.chip--dryrun { background: rgba(245,211,59,0.14); color: var(--yellow); border-color: rgba(245,211,59,0.4); }
.chip--ran { background: rgba(124,135,158,0.14); color: var(--grey-300); border-color: var(--grey-700); }

/* ── Auto-routing policy grid (Settings) ───────────── */
.pol-grid { width: 100%; border-collapse: collapse; margin: 8px 0; }
.pol-grid th, .pol-grid td { padding: 4px 6px; text-align: left; font-size: 12px; }
.pol-grid thead th { color: var(--grey-300); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.pol-grid .pol-th { color: var(--grey-200); font-weight: 600; white-space: nowrap; }
.select--sm { padding: 4px 6px; font-size: 12px; width: 100%; }
.pol-actions { display: flex; justify-content: flex-end; margin-top: 4px; }

/* ── Empty state ───────────────────────────────── */
.empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: var(--sp-16) var(--sp-6);
  border: 1px dashed var(--hairline);
  border-radius: var(--r-lg);
  color: var(--text-low);
}
.empty h3 { font-family: var(--font-display); color: var(--text-mid); font-weight: 600; margin-bottom: var(--sp-2); }
.empty p { font-size: 14px; max-width: 420px; margin: 0 auto var(--sp-4); }

/* ── Loading / boot state ──────────────────────────
   Shown by index.html before any JS runs, and again by showLoading() while the
   first fetch is in flight. It replaces what used to be an empty <main>, so a
   slow or failed start says so instead of looking like a broken page. */
.loadstate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  text-align: center;
  padding: var(--sp-16) var(--sp-6);
  color: var(--text-mid);
  font-size: 14px;
}
.loadstate__spin {
  width: 18px; height: 18px;
  border: 2px solid var(--hairline);
  border-top-color: var(--lime);
  border-radius: 50%;
  animation: hist-spin .7s linear infinite;
}
.loadstate__hint { font-size: 13px; color: var(--text-low); max-width: 420px; margin: 0 auto var(--sp-4); }
.loadstate .btn { min-width: 140px; justify-content: center; }
@media (prefers-reduced-motion: reduce) { .loadstate__spin { animation-duration: 2s; } }

/* ── Modal / drawer ────────────────────────────── */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(7,10,20,0.72);
  backdrop-filter: blur(4px);
  display: none;
  align-items: stretch;
  justify-content: flex-end;
  z-index: 50;
}
.overlay.is-open { display: flex; }

.drawer {
  width: min(560px, 100%);
  height: 100%;
  background: var(--bg-surface);
  border-left: 1px solid var(--hairline);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  animation: slideIn .22s ease;
}
@keyframes slideIn { from { transform: translateX(28px); opacity: .4; } to { transform: none; opacity: 1; } }

.drawer__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-6);
  border-bottom: 1px solid var(--hairline);
}
.drawer__head h2 { font-family: var(--font-display); font-weight: 800; font-size: 19px; flex: 1; }
.drawer__close {
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  color: var(--text-mid);
  border-radius: var(--r-sm);
  width: 32px; height: 32px;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
}
.drawer__close:hover { color: var(--text-hi); }
.drawer__body { padding: var(--sp-6); overflow: auto; flex: 1; display: flex; flex-direction: column; gap: var(--sp-5, 20px); }
.drawer__foot {
  padding: var(--sp-4) var(--sp-6);
  border-top: 1px solid var(--hairline);
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  background: var(--bg-base);
}
.drawer__foot .btn { flex: 1 1 auto; justify-content: center; }
/* Destructive action drops to its own full-width row, apart from the primaries. */
.drawer__foot .drawer__del { flex-basis: 100%; }

/* ── Forms ─────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field__row { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.field__row > .field { flex: 1 1 160px; }
.label {
  font-family: var(--font-pixel);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-low);
}
.input, .textarea, .select {
  font-family: var(--font-body);
  font-size: 14px;
  background: var(--bg-void);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  color: var(--text-hi);
  padding: var(--sp-3);
  width: 100%;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(61,90,241,0.25);
}
.textarea { font-family: var(--font-mono); font-size: 13px; line-height: 1.55; min-height: 200px; resize: vertical; }
.select { appearance: none; cursor: pointer; }
.hint { font-size: 12px; color: var(--text-low); }
.hint--warn { color: var(--yellow); }

/* segmented control for "when to fire" */
.segmented { display: flex; gap: var(--sp-1); background: var(--bg-void); border: 1px solid var(--hairline); border-radius: var(--r-md); padding: 4px; }
.segmented label { flex: 1; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span {
  display: block;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-mid);
  padding: var(--sp-2) var(--sp-2);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.segmented input:checked + span { background: var(--blue); color: var(--white); }

/* ── Toast ─────────────────────────────────────── */
.toasts { position: fixed; bottom: var(--sp-6); left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: var(--sp-2); z-index: 80; align-items: center; }
/* History pins a reply box to the bottom — clear it so toasts never land on the
   box the reader is typing in. */
body[data-view="history"] .toasts { bottom: calc(104px + env(safe-area-inset-bottom)); }
.toast {
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--lime);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-5, 20px);
  box-shadow: var(--shadow-md);
  font-size: 14px;
  max-width: 90vw;
  animation: toastIn .2s ease;
}
.toast--error { border-left-color: var(--danger); }
.toast--info { border-left-color: var(--blue); }
@keyframes toastIn { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ── History rows ──────────────────────────────── */
.history { display: flex; flex-direction: column; gap: var(--sp-2); }
.run {
  background: var(--bg-surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.run__head { display: flex; align-items: center; gap: var(--sp-3); }
.run__title { font-weight: 600; flex: 1; }
.run__time { font-family: var(--font-mono); font-size: 12px; color: var(--text-low); }
.run__body {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-mid);
  background: var(--bg-void);
  border-radius: var(--r-sm);
  padding: var(--sp-3);
  white-space: pre-wrap;
  max-height: 240px;
  overflow: auto;
}
.run__body a { color: var(--accent); text-decoration: underline; word-break: break-all; }
.run__body strong { color: var(--text-high); font-weight: 600; }

/* ══════════════════════════════════════════════════
   History — flat two-pane workspace (Claude Code shape)
   Left rail = every run; right pane = that run's exchange, flush against the
   UI with a composer pinned to the bottom. No modal, no overlay.
   ══════════════════════════════════════════════════ */
.hx {
  position: relative;
  display: flex;          /* NOT grid — see the note above .content--flush */
  align-items: stretch;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
/* ── Left rail: the run list ── */
.hx__rail {
  display: flex;
  flex-direction: column;
  flex: 0 0 304px;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
  border-right: 1px solid var(--hairline);
  background: linear-gradient(180deg, rgba(20,27,46,0.55), rgba(7,10,20,0.35));
}
.hx__rail-head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
  padding-left: max(var(--sp-4), env(safe-area-inset-left));
  border-bottom: 1px solid var(--hairline);
  flex: 0 0 auto;
}
.hx__rail-title {
  font-family: var(--font-pixel);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-low);
}
/* Starting a chat is the rail's primary action, so it sits above the search box
   and reads as the one filled control in a column of muted ones. */
.hx__new { width: 100%; justify-content: center; }
.hx__search { font-size: 13px; padding: var(--sp-2) var(--sp-3); }
/* The instance picker rides in the pane header, so it must not push the title
   around on a narrow pane. */
.hx__instance { font-size: 12px; padding: 4px var(--sp-2); max-width: 46vw; }
.hx__list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sp-2);
  padding-left: max(var(--sp-2), env(safe-area-inset-left));
  padding-bottom: calc(var(--sp-4) + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.hx__none { padding: var(--sp-6) var(--sp-4); font-size: 13px; color: var(--text-low); text-align: center; }
/* ── Right pane: the exchange ── */
.hx__main {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
  background: var(--bg-base);
}
.hx__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5, 20px);
  padding-right: max(var(--sp-5, 20px), env(safe-area-inset-right));
  border-bottom: 1px solid var(--hairline);
  flex: 0 0 auto;
  min-height: 0;
}
.hx__title { font-family: var(--font-display); font-weight: 800; font-size: 16px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hx__time { font-family: var(--font-mono); font-size: 12px; color: var(--text-low); white-space: nowrap; }
.hx__head-actions { display: flex; gap: var(--sp-2); flex: 0 0 auto; }
/* Heads up: the vendored token scale has no `--sp-5`, so a bare var(--sp-5)
   makes the whole declaration invalid and the padding silently computes to 0.
   That is why this pane's content sat flush against the header and the left
   edge for so long. Always write var(--sp-5, 20px) — the rest of the sheet
   already does. */
/* No overscroll containment anywhere in this pane. `contain` swallows the
   gesture when a column has nothing to scroll — which is most [Leads] recaps,
   they're four lines long — so the pane felt dead rather than bottoming out
   with the usual rubber-band. Nothing outside these columns scrolls, so
   containment bought nothing and cost the bounce. */
.hx__thread {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sp-8) var(--sp-5, 20px) var(--sp-6);
  padding-right: max(var(--sp-5, 20px), env(safe-area-inset-right));
}
.hx__thread-inner { max-width: 860px; margin: 0 auto; display: flex; flex-direction: column; gap: var(--sp-3); }
.hx__thread .chatmsg { max-width: 88%; }
.hx__thread .chatmsg--busy { display: inline-flex; align-items: center; gap: 8px; align-self: flex-start; }
.hx__thread .chatmsg--bot a { color: var(--periwinkle); text-decoration: underline; word-break: break-all; }
.hx__thread .chatmsg--bot strong { color: var(--text-hi); font-weight: 600; }
.hx__compose {
  flex: 0 0 auto;
  border-top: 1px solid var(--hairline);
  background: linear-gradient(180deg, rgba(20,27,46,0.35), var(--bg-base));
  padding: var(--sp-3) var(--sp-5, 20px) calc(var(--sp-3) + env(safe-area-inset-bottom));
  padding-right: max(var(--sp-5, 20px), env(safe-area-inset-right));
}
.hx__compose-inner { max-width: 860px; margin: 0 auto; display: flex; gap: var(--sp-2); align-items: flex-end; }
.hx__compose .chat__input {
  min-height: 62px;
  max-height: 220px;
  flex: 1;
  font-family: var(--font-body);   /* prose, not a prompt editor */
  font-size: 14px;
  line-height: 1.5;
}
.hx__compose .btn { flex: 0 0 auto; }
/* Send, and — on a new chat — "Save to Library" under it: keeping the prompt is
   a second thing you can do with what you just typed, not a second send. */
.hx__compose-btns { display: flex; flex-direction: column; gap: var(--sp-2); align-items: stretch; flex: 0 0 auto; }
.hx__compose-btns .btn { width: 100%; white-space: nowrap; }
.hx__note {
  max-width: 860px; margin: 0 auto;
  font-size: 12.5px; color: var(--text-low);
  /* The note can carry an action (Run now on a routine that logged nothing),
     so it lays out as a row and wraps rather than squeezing the button. */
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
}
.hx__note .btn { flex: 0 0 auto; }
/* Nothing picked yet (or nothing to pick) */
.hx__blank { flex: 1; display: flex; align-items: center; justify-content: center; padding: var(--sp-8); }
/* Mobile-only rail controls */
.hx__railbtn { display: none; }
.hx__scrim { display: none; }

/* ── A run in the rail ── */
.hxrow {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;        /* the Delete panel hides behind the row */
  touch-action: pan-y;     /* vertical scrolling stays native; we own horizontal */
  /* Required, and easy to lose: `overflow: hidden` makes the row a scroll
     container, which drops its automatic minimum size to zero — so as a flex
     item in #hx-list it happily shrank to a fraction of its content and every
     row rendered as a clipped sliver. Rows never flex. */
  flex: 0 0 auto;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-left: 3px solid rgba(188,239,47,0.55);
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  font-family: var(--font-body);
  color: var(--text-mid);
  transition: background .12s ease, border-color .12s ease;
}
.hxrow:hover { background: rgba(255,255,255,0.035); }
.hxrow.is-active { background: rgba(188,239,47,0.10); border-color: rgba(188,239,47,0.30); border-left-color: var(--lime); }
.hxrow--bad { border-left-color: var(--danger); }
.hxrow--stale { border-left-color: var(--yellow); }
.hxrow--busy { border-left-color: var(--periwinkle); }
.hxrow:focus-visible { outline: 2px solid var(--periwinkle); outline-offset: 1px; }
/* The body slides; the Delete panel underneath it does not. */
.hxrow__body { display: block; position: relative; z-index: 1; transition: transform .18s ease; }
.hxrow.is-swiped .hxrow__body { transform: translateX(-88px); }
.hxrow__swipedel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 88px;
  border: 0;
  border-radius: 0;
  background: var(--danger);
  color: var(--white);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
}
.hxrow.is-swiped .hxrow__swipedel { opacity: 1; pointer-events: auto; }
.hxrow__top { display: flex; align-items: center; gap: var(--sp-2); }
.hxrow__title {
  font-family: var(--font-display); font-weight: 600; font-size: 13.5px; color: var(--text-hi);
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hxrow.is-active .hxrow__title { color: var(--lime); }
.hxrow__time { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-low); white-space: nowrap; transition: opacity .12s ease; }
/* Delete sits where the timestamp is — the stamp fades out on hover so the row
   doesn't get busier, and the control is only a pointer away. */
.hxrow__del {
  position: absolute;
  top: var(--sp-2);
  right: var(--sp-2);
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-low);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.hxrow:hover .hxrow__del, .hxrow__del:focus-visible { opacity: 1; }
.hxrow:hover .hxrow__time { opacity: 0; }
.hxrow__del:hover { background: rgba(255,77,94,0.14); color: var(--danger); }
/* iPadOS fakes :hover on tap and drops it on the next tap, so a hover-revealed
   trash works exactly once. Touch gets the swipe instead. */
@media (hover: none) {
  .hxrow__del { display: none; }
  .hxrow:hover .hxrow__time { opacity: 1; }
}
/* Confirm strip — no undo, so deleting takes two deliberate taps. */
.hxrow--confirm { background: rgba(255,77,94,0.08); border-color: rgba(255,77,94,0.35); }
.hxrow__sub--confirm { gap: var(--sp-2); flex-wrap: wrap; }
.hxrow__ask { color: var(--text-mid); font-weight: 600; }
.hxrow__cbtn {
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  color: var(--text-mid);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  padding: 2px var(--sp-2);
  cursor: pointer;
}
.hxrow__cbtn:hover { color: var(--text-hi); border-color: var(--grey-700); }
.hxrow__cbtn--yes { color: var(--danger); border-color: rgba(255,77,94,0.45); }
.hxrow__cbtn--yes:hover { background: rgba(255,77,94,0.16); color: var(--danger); }
.hxrow__sub { display: flex; align-items: center; gap: 6px; margin-top: 3px; font-size: 11.5px; color: var(--text-low); }
.hxrow__status { font-weight: 700; display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto; }
.hxrow__snip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* ── History (shared row bits — status colors, spinner) ─── */
.hist--busy .hist__status.is-busy { color: var(--periwinkle); }
.hist__head { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.hist__title { font-family: var(--font-display); font-weight: 600; font-size: 15px; flex: 1; }
.hist__status { font-size: 12px; font-weight: 700; display: inline-flex; align-items: center; gap: 6px; }
.hist__status.is-ok { color: var(--lime); }
.hist__status.is-bad { color: var(--danger); }
.hist__status.is-warn { color: var(--yellow); }
.hist__status.is-busy { color: var(--periwinkle); }
.hist__time { font-family: var(--font-mono); font-size: 12px; color: var(--text-low); }
.hist__stop { flex: 0 0 auto; margin-left: auto; }
.hist__spin {
  display: inline-block;
  width: 11px; height: 11px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: hist-spin .7s linear infinite;
  vertical-align: -1px;
  flex-shrink: 0;
}
@keyframes hist-spin { to { transform: rotate(360deg); } }
/* ── Run-history filter (all / failures) ───────── */
.log__filter { display: flex; gap: var(--sp-2); }
.log__filter .btn { flex: 1 1 0; justify-content: center; }

/* ── Chat (model testing) ──────────────────────── */
.chat { max-width: 820px; margin: 0 auto; display: flex; flex-direction: column; gap: var(--sp-4); min-height: calc(100vh - 220px); }
.chat__bar { display: flex; align-items: center; gap: var(--sp-3); }
.chat__bar .label { margin: 0; }
.chat__model { max-width: 420px; }
.chat__thread {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  overflow-y: auto;
  background: var(--bg-base);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  min-height: 260px;
  max-height: calc(100vh - 340px);
}
.chatmsg {
  max-width: 82%;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md);
  font-size: 14px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
}
.chatmsg--user { align-self: flex-end; background: var(--blue); color: var(--white); border-bottom-right-radius: 4px; }
.chatmsg--bot { align-self: flex-start; background: var(--bg-elevated); color: var(--text-hi); border: 1px solid var(--hairline); border-bottom-left-radius: 4px; }
.chatmsg--error { border-color: rgba(255,77,94,0.5); color: var(--danger); }
.chatmsg--busy { color: var(--text-low); font-style: italic; }
.chat__compose { display: flex; gap: var(--sp-2); align-items: flex-end; }
.chat__input { min-height: 56px; max-height: 180px; flex: 1; }
.chat__compose .btn { flex: 0 0 auto; }

/* ── Run transcript pieces (shared by the History pane) ── */
/* The model's tool actions + their raw results, shown compactly in the thread. */
.transcript__tool {
  align-self: flex-start;
  font-family: var(--font-mono); font-size: 11.5px;
  color: var(--text-low);
  background: var(--bg-elevated);
  border: 1px dashed var(--hairline);
  border-radius: var(--r-sm);
  padding: 2px var(--sp-2);
}
.transcript__res { align-self: flex-start; max-width: 100%; font-size: 12px; }
.transcript__res summary { cursor: pointer; color: var(--text-low); font-family: var(--font-mono); }
.transcript__res pre {
  margin-top: var(--sp-2);
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  padding: var(--sp-3);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-mid);
}
/* The run's objective, pinned above the transcript. Not a chat bubble: it is
   current state, not something anyone said, and it is the one part of a run
   that never gets compacted away. */
.hx__goal {
  align-self: stretch;
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--text-low);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  padding: var(--sp-3) var(--sp-4);
  font-size: 13px;
}
.hx__goal--blocked { border-left-color: var(--danger, #FF4D5E); }
.hx__goal--complete { border-left-color: var(--success, #22c55e); }
.hx__goal-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.hx__goal-label {
  font-family: var(--font-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: .08em; color: var(--text-low);
}
.hx__goal-obj { margin: 0; color: var(--text-high); font-weight: 500; }
.hx__goal-blocked { margin: var(--sp-2) 0 0; color: var(--text-mid); }
.hx__goal-list { margin: var(--sp-2) 0 0; padding-left: var(--sp-3); list-style: none; }
.hx__goal-list li { color: var(--text-mid); line-height: 1.5; }
.hx__goal-list--done li { color: var(--text-low); }

/* Machine-injected turns (auto-continue, repeat guard). Deliberately NOT a user
   bubble: the human did not say this, and rendering it as though they had made
   the transcript misleading about who drove the run. */
.transcript__notice { align-self: flex-start; max-width: 100%; font-size: 12px; }
.transcript__notice summary {
  cursor: pointer;
  color: var(--text-low);
  font-family: var(--font-mono);
  font-size: 11.5px;
}
.transcript__notice pre {
  margin-top: var(--sp-2);
  background: var(--bg-elevated);
  border: 1px dashed var(--hairline);
  border-radius: var(--r-sm);
  padding: var(--sp-3);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-mid);
}
/* Model thoughts: collapsible, muted — separate from the answer bubble (Claude-style). */
.transcript__thought {
  align-self: stretch;
  max-width: 100%;
  font-size: 12.5px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: rgba(124, 135, 158, 0.08);
  padding: var(--sp-2) var(--sp-3);
}
.transcript__thought summary {
  cursor: pointer;
  color: var(--text-low);
  font-weight: 600;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  user-select: none;
}
.transcript__thought summary::-webkit-details-marker { display: none; }
.transcript__thought-icon { opacity: 0.85; }
.transcript__thought[open] summary { margin-bottom: var(--sp-2); color: var(--text-mid); }
.transcript__thought-body {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-mid);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 280px;
  overflow-y: auto;
}
.chip .hist__spin { margin-right: 4px; }

/* ── Budget chip + forecast panel ──────────────── */
.budget-chip { cursor: pointer; transition: border-color .15s ease, color .15s ease; }
.budget-chip:hover { color: var(--text-hi); border-color: var(--grey-700); }
.budget-chip b { color: var(--yellow); }
.fc__tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--sp-2); }
.fc__tile { background: var(--bg-void); border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--sp-3); text-align: center; }
.fc__tile-v { font-family: var(--font-mono); font-weight: 600; font-size: 16px; color: var(--text-hi); }
.fc__tile-l { font-family: var(--font-pixel); font-size: 8px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-low); margin-top: 3px; }
.fc__chart { display: flex; align-items: stretch; gap: 2px; height: 150px; padding: var(--sp-2) 0; }
.fc__col { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.fc__val { font-family: var(--font-mono); font-size: 10px; color: var(--text-mid); text-align: center; height: 14px; white-space: nowrap; overflow: visible; }
.fc__barwrap { flex: 1; display: flex; align-items: flex-end; justify-content: center; }
.fc__bar { width: 70%; min-width: 10px; background: var(--blue-bright); border-radius: 4px 4px 0 0; }
.fc__lbl { font-family: var(--font-mono); font-size: 10px; color: var(--text-low); text-align: center; margin-top: 4px; }
.fc__rows { display: flex; flex-direction: column; gap: var(--sp-2); }
.fc__row { display: flex; align-items: center; gap: var(--sp-2); font-size: 13px; padding: var(--sp-2) var(--sp-3); background: var(--bg-void); border: 1px solid var(--hairline); border-radius: var(--r-sm); }
.fc__row-title { flex: 1; font-weight: 600; color: var(--text-hi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fc__row-model { font-family: var(--font-mono); font-size: 11px; color: var(--text-low); }
.fc__row-cost { font-family: var(--font-mono); font-size: 12px; color: var(--yellow); white-space: nowrap; }

/* ── Settings note ─────────────────────────────── */
.notice {
  background: rgba(61,90,241,0.10);
  border: 1px solid rgba(61,90,241,0.35);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  font-size: 13px;
  color: var(--text-mid);
}
.notice b { color: var(--text-hi); }

.section-head { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.section-head h2 { font-family: var(--font-display); font-weight: 800; font-size: 18px; }
.section-head .hint { margin-left: auto; }

/* ── Auth screen ───────────────────────────────── */
.auth {
  max-width: 420px;
  margin: var(--sp-16) auto 0;
  background: linear-gradient(180deg, var(--bg-surface), #121829);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: var(--sp-8);
  box-shadow: var(--shadow-md);
}
.auth h2 { font-family: var(--font-display); font-weight: 800; font-size: 22px; margin-bottom: var(--sp-2); }
.auth p.sub { color: var(--text-mid); font-size: 14px; margin-bottom: var(--sp-6); }
.auth .field { margin-bottom: var(--sp-4); }
.auth .btn { width: 100%; justify-content: center; }
.auth__alt { text-align: center; margin-top: var(--sp-4); font-size: 13px; color: var(--text-mid); }
.auth__alt a { cursor: pointer; font-weight: 600; }
.auth__msg { font-size: 13px; margin-bottom: var(--sp-4); padding: var(--sp-3); border-radius: var(--r-sm); display: none; }
.auth__msg.is-err { display: block; background: rgba(255,77,94,0.12); border: 1px solid rgba(255,77,94,0.4); color: var(--danger); }
.auth__msg.is-ok { display: block; background: rgba(188,239,47,0.10); border: 1px solid rgba(188,239,47,0.35); color: var(--lime); }

/* ══════════════════════════════════════════════════
   Narrow / mobile — the top rail wraps to two rows and the History run list
   becomes an off-canvas panel that slides over the transcript (Claude Code).
   ══════════════════════════════════════════════════ */
/* Two-row rail: nav drops to its own full-width row under the brand + actions
   rather than scrolling itself out of reach. */
@media (max-width: 1140px) {
  .topbar { flex-wrap: wrap; gap: var(--sp-2); padding-bottom: var(--sp-2); }
  .tabs { order: 3; flex: 1 1 100%; }
}
/* Row one still has to fit: shed the same chips, in the same order. */
@media (max-width: 900px) { .clock--time { display: none; } .fire-toggle__label { display: none; } }
@media (max-width: 820px) { .budget-chip { display: none !important; } }
/* Phone: the nav row itself runs out of width — tighten the tabs before letting
   them scroll, and drop the count badges last. */
@media (max-width: 780px) {
  .tab { font-size: 12.5px; padding: 6px var(--sp-2); gap: 4px; }
  .tab__count { font-size: 10px; padding: 1px 5px; }
}
@media (max-width: 620px) { .tab__count { display: none; } }
/* Narrower than this the nav genuinely cannot fit; it scrolls, and the fade on
   the trailing edge says so. */
@media (max-width: 520px) {
  .tabs {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent 100%);
  }
}
@media (max-width: 560px) {
  .brand--bar .brand__wordmark { display: none; }
}

@media (max-width: 900px) {
  .content { padding: var(--sp-6) max(var(--sp-6), env(safe-area-inset-right)) var(--sp-16) max(var(--sp-6), env(safe-area-inset-left)); }
  .content--flush { padding: 0; }
  .brand__title { font-size: 18px; }

  /* History: single pane, rail slides in over it. */
  .hx__rail { flex: 0 0 auto; }  /* off-canvas below — see the absolute rule */
  .hx__rail {
    position: absolute;
    top: 0; bottom: 0; left: 0;
    width: min(320px, 86vw);
    z-index: 40;
    background: var(--bg-surface);
    transform: translateX(-100%);
    transition: transform .24s cubic-bezier(.3, .7, .3, 1);
    will-change: transform;
  }
  .hx.is-rail-open .hx__rail { transform: none; box-shadow: var(--shadow-lg); }
  .hx__scrim {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 39;
    background: rgba(7,10,20,0.66);
    backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity .24s ease;
  }
  .hx.is-rail-open .hx__scrim { opacity: 1; pointer-events: auto; }
  .hx__railbtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    background: transparent;
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm);
    color: var(--text-mid);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 12px;
    padding: 6px var(--sp-2);
    cursor: pointer;
  }
  .hx__railbtn:hover { color: var(--text-hi); border-color: var(--grey-700); }
  .hx__head { padding: var(--sp-3) var(--sp-4); gap: var(--sp-2); }
  .hx__title { font-size: 14px; }
  .hx__time { display: none; }
  .hx__thread { padding: var(--sp-5, 20px) var(--sp-4) var(--sp-4); }
  .hx__compose { padding-left: var(--sp-4); padding-right: var(--sp-4); }
}

@media (prefers-reduced-motion: reduce) {
  .hx__rail, .hx__scrim { transition: none; }
}

/* ============================================================
   Calendar — week plan (color = Claude account)
   ============================================================ */
.acct-dot { display: inline-block; width: 9px; height: 9px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; }

.cal { background: var(--bg-base); border: 1px solid var(--hairline); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); overflow: hidden; }

.cal__bar { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-bottom: 1px solid var(--hairline); flex-wrap: wrap; }
.cal__range { font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--text-hi); letter-spacing: -0.02em; }
.cal__nav { display: flex; gap: 4px; }
.cal__navbtn { width: 28px; height: 28px; border: 1px solid var(--hairline); border-radius: 8px; background: transparent; color: var(--text-mid); font-family: var(--font-mono); font-size: 14px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.cal__navbtn:hover { color: var(--text-hi); border-color: var(--grey-700); }
.cal__navbtn:disabled { opacity: 0.35; cursor: not-allowed; }
.cal__navbtn:disabled:hover { color: var(--text-mid); border-color: var(--hairline); }
.cal__today { font-family: var(--font-body); font-weight: 600; font-size: 12px; color: var(--text-mid); background: transparent; border: 1px solid var(--hairline); border-radius: var(--r-pill); padding: 5px 13px; cursor: pointer; }
.cal__today:hover { color: var(--text-hi); border-color: var(--grey-700); }
.cal__count { font-family: var(--font-pixel); font-size: 10px; letter-spacing: 0.06em; color: var(--text-low); text-transform: uppercase; }
/* The color key used to live here as a permanent row of account/trigger
   swatches. Blocks are colored by their model now, and the key is in
   Settings → Models — this is the one-word way back to it. */
.cal__key { margin-left: auto; font-family: var(--font-body); font-weight: 600; font-size: 12px; color: var(--text-mid); background: transparent; border: 1px solid var(--hairline); border-radius: var(--r-pill); padding: 5px 13px; cursor: pointer; }
.cal__key:hover { color: var(--text-hi); border-color: var(--grey-700); }

.cal__head { display: grid; grid-template-columns: 56px repeat(7, 1fr); border-bottom: 1px solid var(--hairline); }
.cal__dh { padding: 8px 0; text-align: center; border-left: 1px solid #1f2740; }
.cal__dow { font-family: var(--font-pixel); font-size: 10px; color: var(--text-low); }
.cal__dnum { font-family: var(--font-body); font-weight: 700; font-size: 15px; color: var(--text-mid); margin-top: 2px; }
.cal__dh--today .cal__dow { color: var(--lime); }
.cal__dh--today .cal__dnum { color: var(--text-hi); }

.cal__scroll { max-height: calc(100vh - 300px); overflow-y: auto; }
.cal__body { display: grid; grid-template-columns: 56px repeat(7, 1fr); position: relative; padding-top: 8px; }
.cal__gutter { position: relative; }
.cal__hr { position: absolute; right: 7px; font-family: var(--font-mono); font-size: 9px; color: var(--text-low); transform: translateY(-50%); white-space: nowrap; }
.cal__day { position: relative; border-left: 1px solid #1f2740; background: repeating-linear-gradient(to bottom, rgba(42,52,84,0.30) 0 1px, transparent 1px 44px); cursor: pointer; transition: box-shadow .12s ease; }
.cal__day:hover { box-shadow: inset 0 0 0 100vmax rgba(188,239,47,0.04); }

.cal__ev { position: absolute; border-radius: 8px; padding: 4px 7px; overflow: hidden; cursor: grab; box-sizing: border-box; border-left: 3px solid; touch-action: none; user-select: none; -webkit-user-select: none; transition: filter .12s ease, box-shadow .12s ease; }
.cal__ev:hover { filter: brightness(1.07); z-index: 5; box-shadow: var(--shadow-md); }
.cal__ev--dragging { z-index: 50; cursor: grabbing; opacity: 0.92; box-shadow: 0 10px 26px rgba(0,0,0,0.5); transition: none; filter: brightness(1.08); }
.cal__ev--past { opacity: 0.5; }
.cal__ev--past:hover { opacity: 0.9; }
.cal__ev--past:focus-within { opacity: 1; }  /* stays lit while you're renaming it */
.cal__ev-title { font-family: var(--font-body); font-weight: 600; font-size: 11px; line-height: 1.1; overflow: hidden; text-overflow: ellipsis; }
.cal__ev--past .cal__ev-title { padding-right: 18px; }

/* Rename a past block in place — the pencil sits in its corner, the input takes
   the title's spot. */
.cal__ev-edit {
  position: absolute;
  top: 2px; right: 2px;
  width: 17px; height: 17px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: rgba(0,0,0,0.20);
  color: inherit;
  font-size: 10px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s ease, background .12s ease;
}
.cal__ev:hover .cal__ev-edit { opacity: 1; }
.cal__ev-edit:hover { background: rgba(0,0,0,0.34); }
.cal__ev-edit:focus-visible { opacity: 1; outline: 2px solid var(--white); outline-offset: 1px; }
/* No hover on touch — keep it visible so it's reachable at all. */
@media (hover: none) { .cal__ev-edit { opacity: 0.6; } }
.cal__ev-input {
  width: 100%;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 11px;
  line-height: 1.15;
  color: inherit;
  background: rgba(0,0,0,0.22);
  border: 1px solid rgba(0,0,0,0.35);
  border-radius: 4px;
  padding: 1px 3px;
}
.cal__ev-input:focus { outline: 2px solid rgba(255,255,255,0.65); outline-offset: 0; }
.cal__ev-time { font-family: var(--font-mono); font-weight: 600; font-size: 9px; margin-top: 2px; opacity: 0.72; }

.cal__now { position: absolute; left: 0; right: 0; height: 0; border-top: 2px solid var(--lime); box-shadow: 0 0 12px rgba(188,239,47,0.6); z-index: 6; pointer-events: none; }
.cal__now-dot { position: absolute; left: -5px; width: 9px; height: 9px; border-radius: 50%; background: var(--lime); box-shadow: 0 0 10px rgba(188,239,47,0.8); z-index: 6; pointer-events: none; }

.cal__hint { padding: 16px 20px; font-family: var(--font-body); font-size: 13px; color: var(--text-mid); border-top: 1px solid var(--hairline); }

@media (max-width: 760px) {
  .cal__key { margin-left: 0; }
  .cal__dnum { font-size: 13px; }
}

/* ── Settings: the master fire switch ──────────── */
.fire-row {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: rgba(20,27,46,0.5);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
}
.fire-row__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.fire-row__text b { font-size: 13px; color: var(--text-hi); }
.fire-row .fire-toggle { flex: 0 0 auto; }
.fire-row .fire-toggle__label { display: inline; }

/* ── Settings: per-account trigger + token ─────── */
.cfg-sep { font-family: var(--font-pixel); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-low); margin: var(--sp-5, 20px) 0 var(--sp-3); padding-top: var(--sp-4); border-top: 1px solid var(--hairline); }
.acct-cfg { border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4) var(--sp-1); margin-bottom: var(--sp-3); background: rgba(20,27,46,0.5); }
.acct-cfg__head { display: flex; align-items: center; font-family: var(--font-body); font-size: 13px; color: var(--text-hi); margin-bottom: var(--sp-2); }
.acct-cfg__head b { font-weight: 700; }
.cfg-adv { margin-top: var(--sp-4); border-top: 1px solid var(--hairline); padding-top: var(--sp-3); }
.cfg-adv summary { cursor: pointer; font-family: var(--font-body); font-weight: 600; font-size: 13px; color: var(--text-mid); list-style: revert; }
.cfg-adv summary:hover { color: var(--text-hi); }
.cfg-adv[open] summary { margin-bottom: var(--sp-3); }

/* ── Settings: accounts & triggers manager ─────── */
.acct-cfg__head { gap: var(--sp-2); }
.acct-cfg__head .cfg-aname { flex: 1; font-weight: 700; font-family: var(--font-body); }
.iconbtn { background: transparent; border: 1px solid var(--hairline); color: var(--text-mid); border-radius: var(--r-sm); width: 28px; height: 28px; flex: 0 0 auto; cursor: pointer; font-size: 13px; line-height: 1; }
.iconbtn:hover { color: var(--danger); border-color: var(--danger); }
.trig-list { display: flex; flex-direction: column; gap: var(--sp-2); margin: var(--sp-2) 0; }
.trig-cfg { background: rgba(7,10,20,0.5); border: 1px solid var(--hairline); border-radius: var(--r-sm); padding: var(--sp-2); display: flex; flex-direction: column; gap: var(--sp-2); }
.trig-cfg__top { display: flex; align-items: center; gap: var(--sp-2); }
.trig-cfg__top .cfg-tlabel { flex: 1; font-weight: 600; }
.trig-cfg .input { font-size: 12px; padding: var(--sp-2) var(--sp-3); }
.cfg-addacct { width: 100%; justify-content: center; margin-top: var(--sp-2); }
.cfg-addacct-row { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }
.cfg-addacct-row .cfg-addacct { margin-top: 0; }
.acct-cfg > .btn--ghost { width: 100%; justify-content: center; }
/* ── Settings: OpenRouter agent instances ──────── */
.acct-cfg > .cfg-akey { margin-bottom: var(--sp-2); font-size: 12px; padding: var(--sp-2) var(--sp-3); }
.trig-cfg .cfg-tmodel { font-size: 12px; padding: var(--sp-2) var(--sp-3); }
.trig-tools { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.tool-chk { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-body); font-size: 12px; color: var(--text-mid); cursor: pointer; }
.tool-chk input { cursor: pointer; }

/* ── Settings: models, colors & slugs ───────────
   The calendar's color key, made editable. One block per lab so the three tiers
   read as a set; the swatch is a native color input (no picker to build) and
   the slug is a plain text field because that is exactly what it is. */
.mdl-lab { border: 1px solid var(--hairline); border-radius: var(--r-md); background: rgba(20,27,46,0.5); padding: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-2); }
.mdl-lab__head { display: flex; align-items: baseline; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.mdl-lab__name { font-family: var(--font-body); font-weight: 700; font-size: 13px; color: var(--text-hi); }
.mdl-lab__origin { font-family: var(--font-pixel); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-low); }
/* Two lines, not one wrapping row: the drawer is narrow, and a name / rate /
   slug that reflow into each other at 500px are unreadable. The swatch spans
   both lines so the color reads as belonging to the whole entry. */
.mdl-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto 14px;
  grid-template-areas: "sw name meta check" "sw slug slug slug";
  align-items: center; gap: 3px var(--sp-2);
  padding: var(--sp-2) 0; border-top: 1px solid rgba(42,52,84,0.5);
}
.mdl-lab .mdl-row:first-of-type { border-top: 0; }
.mdl-color { grid-area: sw; width: 26px; height: 44px; padding: 0; border: 1px solid var(--hairline); border-radius: var(--r-sm); background: transparent; cursor: pointer; }
.mdl-row__name { grid-area: name; font-family: var(--font-body); font-size: 12.5px; color: var(--text-hi); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mdl-row__meta { grid-area: meta; display: flex; align-items: baseline; gap: var(--sp-2); white-space: nowrap; }
.mdl-row__tier { font-family: var(--font-pixel); font-size: 9px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-low); }
.mdl-row .mdl-slug { grid-area: slug; min-width: 0; font-family: var(--font-mono); font-size: 11.5px; padding: var(--sp-1) var(--sp-2); }
.mdl-row__rate { font-family: var(--font-mono); font-size: 11px; color: var(--text-low); }
.mdl-row__check { grid-area: check; font-family: var(--font-mono); font-size: 12px; color: var(--text-low); text-align: center; }
.mdl-row__check.is-ok { color: var(--lime); }
.mdl-row__check.is-err { color: var(--danger); }
.pol-actions { gap: var(--sp-2); }

/* ── Settings: per-trigger test fire ───────────── */
.trig-test { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-top: 2px; }
.trig-status { font-family: var(--font-body); font-size: 12px; color: var(--text-mid); }
.trig-status.is-ok { color: var(--lime); }
.trig-status.is-err { color: var(--danger); }

/* ── Board (comment board / intake) ────────────── */
.board { max-width: 760px; margin: 0 auto; }
.board__compose { background: linear-gradient(180deg, var(--bg-surface), #121829); border: 1px solid var(--hairline); border-radius: var(--r-lg); padding: var(--sp-4); margin-bottom: var(--sp-6); box-shadow: var(--shadow-sm); }
.board__input { min-height: 92px; }
.board__compose-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-3); flex-wrap: wrap; }
.board__feed { display: flex; flex-direction: column; gap: var(--sp-3); }
.board__compose-btns { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.note { background: var(--bg-surface); border: 1px solid var(--hairline); border-left: 3px solid var(--lime); border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4); }
.note--active { border-left-color: var(--lime); box-shadow: inset 2px 0 0 rgba(188,239,47,0.25); }
.note--brainstorm { border-left-style: dashed; border-left-color: var(--grey-500); opacity: 0.92; }
.note--done, .note--dismissed { opacity: 0.55; border-left-color: var(--grey-700); }
.note--planned { border-left-color: var(--blue-bright); }
.note__body { font-family: var(--font-body); font-size: 14px; line-height: 1.5; color: var(--text-hi); white-space: pre-wrap; word-break: break-word; }
.note__foot { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-3); flex-wrap: wrap; }
.note__time { font-family: var(--font-mono); font-size: 11px; color: var(--text-low); }
.note__actions { margin-left: auto; display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.chip--note-active { background: rgba(188,239,47,0.14); color: var(--lime); border-color: rgba(188,239,47,0.4); }
.chip--note-brainstorm { background: rgba(124,135,158,0.12); color: var(--grey-300); border-color: var(--grey-700); }
.chip--note-planned { background: rgba(61,90,241,0.16); color: var(--periwinkle); border-color: rgba(61,90,241,0.4); }
.chip--note-done { background: rgba(124,135,158,0.14); color: var(--grey-300); border-color: var(--grey-700); }
.chip--note-dismissed { background: rgba(124,135,158,0.10); color: var(--grey-500); border-color: var(--grey-700); }
