button.danger,button.delete,button.del,.btn-danger{background:var(--danger,#da3633);color:#fff;border:1px solid rgba(0,0,0,.18)}
button.danger:hover,button.delete:hover,button.del:hover,.btn-danger:hover{filter:none;background:#f85149;box-shadow:0 3px 10px rgba(218,54,51,.3)}
/* Compact inline delete (dense table rows): a bare red trash/✕ glyph, no box. */
button.del-icon,.del-icon{background:none;border:none;color:var(--red,#f85149);box-shadow:none;cursor:pointer;font-weight:600;font-size:1rem;padding:.1rem .4rem;line-height:1}
button.del-icon:hover,.del-icon:hover{filter:none;background:none;color:#ff7b72;box-shadow:none}
.stat-grid{display:flex;flex-wrap:wrap;gap:var(--sp-2,.5rem)}
.stat{flex:1 1 8rem;min-width:8rem;border:1px solid var(--border);background:var(--panel2);padding:.5rem .6rem}
.stat .s-lbl{color:var(--muted);font-size:.72rem;text-transform:uppercase;letter-spacing:.02em}
.stat .s-val{color:var(--text-hi);font-size:1.25rem;font-weight:600;font-variant-numeric:tabular-nums;margin:.1rem 0}
.stat .s-hint{color:var(--muted);font-size:.72rem}
.stat .s-val.pnl-pos{color:#3fb950}
.stat .s-val.pnl-neg{color:#f85149}
.stat .s-val.pnl-warn{color:#d29922}

/* The wider shell (owner 2026-07-10) is flowweb.WidthWide now — set on the Page in
   page(), not written here. Same reason as before: the positions/backtests ListView
   tables are ~1000px natural and horizontal-scrolled INSIDE their wrapper at EVERY
   window size against the 56rem house column. Wide is 88rem/96vw, which is more room
   than the 76rem this used to hard-code, so the scrollbar goes away sooner. */
/* .fisk-card grid: the homepage overview converged to the shared dark webui.StatGrid
   (the calmer look the owner prefers), but backtest/optimise/strategy-view pages still
   use these cards, so the styling stays. */
.fisk-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:var(--sp-3,.75rem);margin:.8rem 0}
.fisk-card h4{margin:.1rem 0 .4rem;color:var(--text-hi)}
.fisk-card .big{font-size:1.5rem;color:var(--text-hi)}
.fisk-card small{color:var(--muted)}
.pill.long{border-color:#3fb950;color:#3fb950}
.pill.short{border-color:#f85149;color:#f85149}
.pill.open{border-color:#58a6ff;color:#58a6ff}
.pill.protected{border-color:#3fb950;color:#3fb950}
.pill.unprotected{border-color:#f85149;color:#f85149;font-weight:600}
.pill.best{border-color:#a371f7;color:#a371f7}
/* originating-app chip on the unified backtest surface — same square .pill,
   colour-coded per app so fisk /backtests and replay /runs read as one list. */
.pill.app-fisk{border-color:#f0883e;color:#f0883e}
.pill.app-replay{border-color:#a371f7;color:#a371f7}
.pill.app-premade{border-color:#3fb950;color:#3fb950}
.pill.app i{margin-right:.25rem}
.fk-premade-link{display:flex;align-items:center;gap:var(--sp-2,.5rem);margin:.2rem 0 .6rem}
.pnl-pos{color:#3fb950}
.pnl-neg{color:#f85149}
.pnl-flat{color:var(--muted)}
.field{margin:.6rem 0}
.field label{display:block;color:var(--muted);font-size:.82rem;margin-bottom:.25rem}
.field input,.field select{max-width:22rem}
.form-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:0 1rem}
.fk-listhead{display:flex;justify-content:flex-start;margin:.2rem 0 .6rem}
.fk-listhead.split{justify-content:space-between;align-items:center;gap:var(--sp-5,1.5rem);flex-wrap:wrap}
.fk-acts{display:inline-flex;align-items:center;justify-content:flex-end;gap:var(--sp-2,.5rem)}
.fk-acts form{margin:0;display:inline}
/* Size parity in the actions column: the view is an icon-only .btn-icon (square)
   and the Close is a .btn text button; the shell sizes them differently (the view
   rendered smaller than Close). Pin BOTH to the same height + vertical centring so
   they read as one consistent control size, open row or closed. */
.fk-acts .btn{min-height:1.9rem;height:1.9rem;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;line-height:1}
.fk-acts .btn-icon{width:1.9rem;height:1.9rem;min-height:1.9rem;padding:0}
.fk-back{margin:.2rem 0 .4rem}
.fk-back a{color:var(--muted);font-size:.85rem;text-decoration:none}
.fk-back a:hover{color:var(--text-hi)}
.notice{background:rgba(88,166,255,.1);border:1px solid var(--border2);padding:.5rem .8rem;margin:.6rem 0;color:var(--text-hi)}
.opt-bar{height:.5rem;background:var(--panel2,#0d1117);border:1px solid var(--border);margin:.45rem 0 .2rem}
.opt-fill{height:100%;background:#a371f7;transition:width .3s ease}
.dash-filter-chip{font-size:.78rem;height:1.85rem;box-sizing:border-box;padding:0 .5rem;border:1px solid #1f6feb;background:rgba(88,166,255,.16);color:var(--text,#c9d1d9);border-radius:var(--r-pill);display:inline-flex;align-items:center;gap:var(--sp-1,.25rem)}
.dash-filter-chip .fc-txt{margin-right:.15rem}
.dash-filter-chip.negate{border-color:#f85149;background:rgba(248,81,73,.14)}
.dash-filter-chip.disabled{opacity:.5;border-style:dashed}
.dash-filter-chip.disabled .fc-txt{text-decoration:line-through}
.dash-filter-chip.pinned{border-color:#d29922}
.dash-filter-chip .fc-pin-ic{font-size:.66rem;margin-right:.2rem}
.dash-filter-chip .fc-btn{border:none;background:transparent;color:inherit;cursor:pointer;font-size:.72rem;line-height:1;padding:0 .1rem;opacity:.55}
.dash-filter-chip .fc-btn:hover{opacity:1}
.chip-row{display:flex;gap:var(--sp-2,.5rem);flex-wrap:wrap;margin:.4rem 0 .8rem}
.book-picker{display:flex;align-items:center;gap:var(--sp-2,.5rem);flex-wrap:wrap}
.book-picker label{font-size:.82rem;color:var(--muted);font-weight:600}.book-picker select{min-width:12rem}.book-picker a{margin-left:auto;font-size:.82rem;color:var(--muted)}
.book-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:var(--sp-3,.75rem);margin:.65rem 0 1rem}
.book-card{display:block;color:inherit;text-decoration:none}
.book-card:hover,.book-card.selected{border-color:var(--primary)}.book-card-head{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-2,.5rem)}
.book-equity{font-size:1.35rem;font-weight:650;color:var(--text-hi);margin:.45rem 0 .1rem}.book-equity small{font-size:.7rem;color:var(--muted);font-weight:400}
.book-return{font-variant-numeric:tabular-nums;font-weight:600}/* auto-fit, not a hard 1fr 1fr. A book card is min 15rem wide, so two fixed columns
   left each cell ~100px and the facts wrapped inside them at different points --
   "4 open . all protected" over two lines beside a one-line "balance", and "191
   trades . 45% win" breaking after "45%". That is the reported misalignment: the
   two columns stopped being rows. With a 9rem floor the meta drops to ONE column
   whenever two would not fit, and every fact gets a full line at a uniform 18.6px. */
.book-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));gap:var(--sp-1,.25rem) var(--sp-3,.75rem);margin-top:.5rem;color:var(--muted);font-size:.75rem}
.book-panel{--w-1:.25rem;--w-2:.5rem;--w-4:1rem}.book-panel-head{display:flex;flex-direction:column;gap:var(--w-2)}.book-panel-head>*{margin:0}
.book-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));align-items:end;gap:var(--w-4);margin:var(--w-4) 0 0}.book-form-field{display:flex;flex-direction:column;gap:var(--w-2);min-width:0;margin:0}.book-form-field label{display:block;color:var(--muted);font-size:.82rem;margin:0}.book-form-field input{width:100%;max-width:none;margin:0}.book-form-actions{display:flex;align-items:stretch;min-height:var(--control-h)}.book-form-actions>.btn{align-self:stretch}
input[type=number]{-moz-appearance:textfield;appearance:textfield}input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.book-fund-form{margin-bottom:var(--w-4)}.book-ledger{display:grid;gap:var(--sp-1,.25rem);margin-top:var(--w-2)}.book-ledger>div{display:flex;justify-content:space-between;gap:var(--sp-4,1rem);border-top:1px solid var(--border);padding:.45rem 0}.book-ledger small{color:var(--muted);font-weight:400}.book-archive{margin-top:1rem}.book-destination .book-picker{margin-bottom:0}.book-destination>.sub{margin:.25rem 0 .8rem}
@media(max-width:680px){.book-picker a{margin-left:0}.book-form{grid-template-columns:1fr}}
a.dash-filter-chip{text-decoration:none}

.sv-actions{display:flex;gap:var(--sp-2,.5rem);flex-wrap:wrap;margin:.2rem 0 .6rem}
.sv-panel h3{margin:.1rem 0 .3rem;color:var(--text-hi)}
.sv-panel .sub{color:var(--muted);font-size:.84rem;margin:.1rem 0 .7rem}
.sv-panel h4{margin:.9rem 0 .4rem;color:var(--text-hi);font-size:.9rem}
.sv-bt-form{display:flex;align-items:center;gap:var(--sp-3,.75rem);flex-wrap:wrap}
.sv-bt-form label{margin:0;color:var(--muted);font-size:.85rem;display:inline-flex;align-items:center;gap:var(--sp-1,.25rem)}
/* Match the native select height so the Run button lines up with the boxes
   (native selects are taller than a .btn by default → the button sat higher). */
.sv-bt-form select,.sv-bt-form .btn{height:2.35rem;box-sizing:border-box}
.sv-bt-form select{max-width:12rem}
.sv-opt{gap:var(--sp-2,.5rem)}
.sv-pairs{display:flex;flex-wrap:wrap;gap:var(--sp-2,.5rem);margin:.2rem 0 .8rem}
/* Per-coin order-settings grid: coin name on its own line, then labelled fields that
   wrap responsively (never a horizontal scroll). */
.sv-co-grid{display:flex;flex-direction:column;gap:var(--sp-1,.25rem);margin:.3rem 0 .7rem}
.sv-co-row{display:flex;flex-wrap:wrap;gap:var(--sp-2,.5rem);align-items:flex-end;padding:.45rem 0;border-bottom:1px solid var(--border)}
.sv-co-coin{flex:0 0 100%;font-weight:600;color:var(--text-hi);font-size:.85rem}
.sv-co-cell{display:flex;flex-direction:column;gap:var(--sp-0,.15rem);flex:1 1 6rem;min-width:0}
.sv-co-lbl{color:var(--muted);font-size:.7rem;text-transform:uppercase;letter-spacing:.02em}
.sv-co-cell input{width:100%;box-sizing:border-box;height:2rem;background:var(--panel2);color:var(--text-hi);border:1px solid var(--border);padding:0 .4rem;font:inherit}
/* Orange "Collect/Collecting"-style coin toggles (monolith pattern; shared with alpha).
   Uniform TILED GRID so every pair toggle is the SAME size (they don't shrink to their
   text) — they tile organically into even rows on any width. */
.coin-toggles{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:var(--sp-2,.5rem);margin:.2rem 0 .8rem}
.coin-toggle{display:flex;align-items:center;gap:var(--sp-2,.5rem);padding:.4rem .7rem;width:100%;box-sizing:border-box;border:1px solid var(--border2);background:var(--panel2);color:var(--muted);font-size:.82rem;font-weight:500;cursor:pointer;user-select:none;transition:border-color .12s ease,background .12s ease,color .12s ease}
.coin-toggle:hover{border-color:#db6d28;color:#f0883e}
.coin-toggle i{font-size:.8rem}
.coin-toggle.on{border-color:#db6d28;background:rgba(219,109,40,.16);color:#f0883e}
.coin-toggle input{display:none}
@media(max-width:600px){.sv-bt-form{flex-direction:column;align-items:stretch}.sv-bt-form select{max-width:none}}

.tv-open{margin:.2rem 0 .6rem}
.tv-preview{padding:.4rem;margin:.2rem 0 1rem}
.tv-pv-svg{display:block;width:100%;height:auto}
.tv-pv-axis{stroke:var(--border2,#30363d);stroke-width:1}
.tv-pv-line{stroke-dasharray:4 3}
.tv-pv-line.cur{stroke-dasharray:none}
.tv-pv-line.tp{stroke:#3fb950}.tv-pv-line.sl{stroke:#f85149}.tv-pv-line.entry{stroke:var(--muted,#8b949e)}.tv-pv-line.cur{stroke:#58a6ff}
/* Shaded TP zone (imbalance FVG box): translucent green fill + dashed green edge. */
.tv-pv-zone{fill:rgba(63,185,80,.13);stroke:#3fb950;stroke-width:1;stroke-dasharray:4 3}
.tv-pv-tag{font-size:9px;text-anchor:end;fill:var(--muted,#8b949e)}
.tv-pv-tag.tp{fill:#3fb950}.tv-pv-tag.sl{fill:#f85149}.tv-pv-tag.cur{fill:#58a6ff}
.tv-pv-val{font-size:9px;text-anchor:end;fill:var(--text,#c9d1d9)}
.tv-pv-val.tp{fill:#3fb950}.tv-pv-val.sl{fill:#f85149}.tv-pv-val.cur{fill:#58a6ff}
.tv-pv-cur-dot{fill:#58a6ff}
.tv-graph{margin:.6rem 0 1rem}
.tv-chart{padding:.4rem .4rem 0}
.tv-svg{display:block;width:100%;height:240px}
.tv-zero{stroke:var(--border2,#30363d);stroke-width:1;stroke-dasharray:3 3}
.tv-axis{display:flex;justify-content:space-between;color:var(--muted);font-size:.72rem;padding:.15rem .3rem .35rem}
.tv-axis .tv-peak{color:var(--muted,#8b949e)}
.tv-empty{color:var(--muted);border:1px dashed var(--border);padding:1rem;text-align:center}
.tv-facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(11rem,1fr));gap:var(--sp-2,.5rem) var(--sp-4,1rem);margin:.4rem 0 1.1rem}
.tv-fact{display:flex;flex-direction:column;min-width:0}
.tv-k{color:var(--muted);font-size:.72rem;text-transform:uppercase;letter-spacing:.03em;margin-bottom:.15rem}
/* overflow-wrap:anywhere so a long unbroken value (e.g. a 24-char strategy id) wraps
   inside its cell instead of running off the page (owner 2026-07-11). */
.tv-v{color:var(--text-hi);font-size:.95rem;overflow-wrap:anywhere}
.tv-muted{color:var(--muted);font-size:.8rem}
.tv-notes{margin:.4rem 0 1rem}
.tv-notes h3{margin:.2rem 0 .3rem}
.tv-notehint{color:var(--muted);font-size:.82rem;margin:0 0 .5rem}
.tv-notes textarea{width:100%;max-width:44rem;box-sizing:border-box;background:var(--panel2);color:var(--text-hi);border:1px solid var(--border);padding:.6rem .7rem;font:inherit;resize:vertical}
.tv-noteact{margin-top:.5rem}

/* THE SIDEBAR'S OWN TOKENS.
   Everything with a house equivalent now uses it: --panel2 --panel --border
   --border2 --muted --text --text-hi --blue --green-soft --red. Each of those
   house tokens' DARK value is byte-identical to the literal it replaced, so dark
   mode is unchanged by construction rather than by eye.

   These nine have NO house token with that dark value, so rather than round them
   to the nearest one — which would silently shift dark mode — the sidebar
   declares its own. The dark column below is the EXACT literal that was there
   before; only the light column is new.

   --ab-ink/-line/-glow/-sky/-icon are the AI identity, not theme chrome, and
   they stay purple in both themes. But they could not stay LITERAL: --ab-ink was
   #d2a8ff used as TEXT (the title sweep, the Build label, the live step), and a
   pale lilac on a white page is unreadable. So the hue is kept and the lightness
   is flipped — GitHub Primer's purple-600/500 against white, which is the same
   accent at the same brand, legible.

   Scoped to the two roots (.ab-sidebar, .ab-toggle) so nothing leaks into a host
   page, and mirrored on :root[data-theme="light"] — the same attribute
   webui.ThemeLightVars keys on, set before first paint by ThemeBootHead. */
.ab-sidebar,.ab-toggle{
  --ab-top:#111826;        /* gradient crown, above --panel2 */
  --ab-inset:#0a0e14;      /* recessed field/log wells, below --bg */
  --ab-field-ink:#e6edf3;  /* textarea text: brighter than --text, dimmer than --text-hi */
  --ab-chip-line:#2b3a55;  /* chip hairline, a blue-tinted --border */
  --ab-line:#8957e5;       /* AI purple: borders and the filled hover */
  --ab-ink:#d2a8ff;        /* AI purple as TEXT */
  --ab-glow:#bc8cff;       /* AI purple for glows and the live blip */
  --ab-sky:#79c0ff;        /* the blue half of the identity sweep */
  --ab-icon:#8b7bd8;       /* the wand glyph on a chip */
}
:root[data-theme="light"] .ab-sidebar,:root[data-theme="light"] .ab-toggle{
  --ab-top:#ffffff;
  --ab-inset:#f6f8fa;
  --ab-field-ink:#1f2328;
  --ab-chip-line:#d0d7de;
  --ab-line:#8250df;
  --ab-ink:#6639ba;
  --ab-glow:#8250df;
  --ab-sky:#0969da;
  --ab-icon:#8250df;
}
/* Visibility model (plug-api hamburger, mirrored right): the sidebar is ALWAYS
   rendered but OFF-CANVAS (translateX) until body.ab-open — transform-based
   hiding avoids the display-cascade bug that once made it full-screen and
   uncloseable on phones. The hamburger (.ab-toggle) is the only way in; the
   header ✕ closes. Desktop: 360px right panel. Below the breakpoint: the SAME
   panel is a full-screen bar. */
.ab-sidebar{position:fixed;top:0;right:0;bottom:0;width:360px;max-width:100vw;box-sizing:border-box;
  background:linear-gradient(180deg,var(--ab-top) 0%,var(--panel2) 42%);
  border-left:1px solid var(--border);padding:1rem 1rem 1.4rem;z-index:41;overflow-y:auto;
  display:flex;flex-direction:column;gap:var(--sp-3,.75rem);
  transform:translateX(105%);transition:transform .22s ease}
body.ab-open .ab-sidebar{transform:translateX(0)}
@media (max-width:1099px){.ab-sidebar{width:100vw;border-left:0}}
/* The sidebar OVERLAYS the page — it must not push content aside (the board is
   visible anyway; the padding shove caused a visual jump on every open/close). */
/* Accent gradient edge — the AI identity sweep. */
.ab-sidebar::before{content:"";position:absolute;top:0;left:0;bottom:0;width:3px;
  background:linear-gradient(180deg,var(--blue),var(--ab-glow));opacity:.9}
.ab-head{display:flex;align-items:center;justify-content:space-between;min-height:2.55rem;padding-right:3.4rem}
.ab-title{display:inline-flex;align-items:center;gap:var(--sp-2,.5rem);font-weight:650;font-size:1.15rem;letter-spacing:-.01em}
.ab-title-text{background:linear-gradient(90deg,var(--ab-sky),var(--ab-ink));-webkit-background-clip:text;background-clip:text;color:transparent}
.ab-spark{color:var(--ab-ink);filter:drop-shadow(0 0 6px rgba(188,140,255,.55))}
.ab-collapse{background:none;border:1px solid var(--border2);color:var(--muted);
  cursor:pointer;width:2.55rem;height:2.55rem;display:flex;align-items:center;
  justify-content:center;padding:0;font-size:1.4rem;line-height:1;
  position:absolute;top:.55rem;right:1rem}
.ab-collapse:hover{border-color:var(--ab-line);color:var(--ab-ink)}
.ab-intro{color:var(--muted);font-size:.78rem;line-height:1.5}
.ab-instruction{width:100%;box-sizing:border-box;resize:vertical;min-height:4.6rem;
  background:var(--ab-inset);border:1px solid var(--border2);color:var(--ab-field-ink);padding:.55rem .7rem;font:inherit;font-size:.95rem;
  transition:border-color .15s ease,box-shadow .15s ease}
.ab-instruction:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(88,166,255,.18)}
.ab-build{align-self:stretch;display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2,.5rem);
  background:transparent;border:1px solid var(--ab-line);color:var(--ab-ink);
  padding:.62rem .8rem;cursor:pointer;font-weight:600;font-size:.84rem;letter-spacing:.03em;
  transition:background .13s ease,color .13s ease,border-color .13s ease}
.ab-build:hover{background:var(--ab-line);color:#fff}
.ab-build:disabled{opacity:.65;cursor:default}
.ab-build.ab-busy{opacity:.8}
/* suggested-prompt chips */
.ab-chips-wrap{display:flex;flex-direction:column;gap:var(--sp-1,.25rem)}
.ab-chips-lbl{font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--faint)}
.ab-chips{display:flex;flex-wrap:wrap;gap:var(--sp-1,.25rem)}
.ab-chip{display:inline-flex;align-items:center;gap:var(--sp-1,.25rem);max-width:100%;text-align:left;
  background:rgba(88,166,255,.07);border:1px solid var(--ab-chip-line);color:var(--text);
  padding:.28rem .6rem;font-size:.78rem;cursor:pointer;line-height:1.2;
  transition:border-color .13s ease,background .13s ease,color .13s ease}
.ab-chip:hover{border-color:var(--ab-line);background:rgba(188,140,255,.12);color:var(--text-hi)}
.ab-chip .fa-wand-magic-sparkles{color:var(--ab-icon);font-size:.7rem}
/* progress + live step trace */
.ab-progress{font-size:.85rem;color:var(--muted);min-height:1.1em;font-weight:500}
.ab-progress.ab-run{background:linear-gradient(90deg,var(--ab-sky),var(--ab-ink),var(--ab-sky));background-size:200% auto;
  -webkit-background-clip:text;background-clip:text;color:transparent;animation:ab-shimmer 2s linear infinite}
.ab-progress.ab-ok{color:var(--green-soft)}
.ab-progress.ab-err{color:var(--red)}
.ab-steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-1,.25rem)}
.ab-steps li{position:relative;padding-left:1.15rem;font-size:.78rem;color:var(--muted);line-height:1.3}
.ab-steps li::before{content:"";position:absolute;left:.15rem;top:.42em;width:.42rem;height:.42rem;border-radius:50%;
  background:var(--green-soft);box-shadow:0 0 0 2px rgba(63,185,80,.18)}
.ab-steps li.ab-step-live{color:var(--ab-ink)}
.ab-steps li.ab-step-live::before{background:var(--ab-glow);box-shadow:0 0 8px 1px rgba(188,140,255,.8);animation:ab-blip .9s ease-in-out infinite}
/* the run log: steps carrying an input/outcome preview expand on tap */
.ab-steps li.ab-has-io{cursor:pointer}
.ab-steps li.ab-has-io .ab-step-nm{border-bottom:1px dotted var(--border2)}
.ab-steps li.ab-has-io:hover .ab-step-nm{color:var(--text);border-bottom-color:var(--muted)}
.ab-step-t{margin-left:.45rem;font-size:.72rem;color:var(--faint)}
.ab-step-io{display:none;margin:.35rem 0 .2rem;flex-direction:column;gap:var(--sp-1,.25rem)}
.ab-steps li.ab-step-open .ab-step-io{display:flex}
/* one styled element per direction: sent (blue) / received (green) */
.ab-io{background:var(--ab-inset);border:1px solid var(--border);padding:.4rem .55rem .45rem}
.ab-io-in{border-left:3px solid var(--blue)}
.ab-io-out{border-left:3px solid var(--green-soft)}
.ab-io-tag{display:block;font-size:.62rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.08em;color:var(--faint);margin-bottom:.25rem}
.ab-io-in .ab-io-tag{color:var(--blue)}
.ab-io-out .ab-io-tag{color:var(--green-soft)}
.ab-io pre{margin:0;color:var(--text);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.72rem;line-height:1.5;white-space:pre-wrap;word-break:break-word;
  max-height:10rem;overflow-y:auto}
.ab-summary{color:var(--text);font-size:.85rem;margin:.3rem 0;line-height:1.55}
.ab-applied{display:inline-flex;align-items:center;gap:var(--sp-1,.25rem);color:var(--green-soft);font-size:.78rem;font-weight:600}
.ab-err{color:var(--red);font-size:.85rem}
/* the right hamburger — the one-and-only way in; pulses once on load */
.ab-toggle{position:fixed;top:.55rem;right:1rem;z-index:40;width:2.55rem;height:2.55rem;
  border:1px solid var(--border2);cursor:pointer;
  background:var(--panel);color:var(--ab-ink);font-size:1.15rem;
  display:flex;align-items:center;justify-content:center}
body.ab-open .ab-toggle{display:none}
.ab-toggle:hover{color:#fff;border-color:var(--ab-line)}
@keyframes ab-shimmer{0%{background-position:0 0}100%{background-position:200% 0}}
@keyframes ab-blip{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.5);opacity:.55}}
@media (prefers-reduced-motion:reduce){
  .ab-build.ab-busy,.ab-progress.ab-run,.ab-steps li.ab-step-live::before,.ab-sidebar{animation:none;transition:none}
}

main{max-width:min(88rem,96vw)}
