
/* ── toolbar ──────────────────────────────────────────────────────────────
   The action buttons form a FLUSH, equal-size grid: cols across, dropping to 2
   across when narrow. Every button fills its cell so they're all identically
   sized and aligned (ActionGrid renders .dash-actions; graphs' JS builds the
   same markup). */
.dash-toolbar { display: flex; flex-direction: column; gap: .6rem; margin: .2rem 0 1.1rem; }
.dash-titlebar { display: flex; align-items: center; gap: .5rem; }
.dash-actions { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .5rem; margin: .4rem 0 .5rem; }
.dash-actions.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 760px) { .dash-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dash-actions .btn { width: 100%; min-width: 0; }
.dash-toolbar .dash-h { color: var(--text-hi); font-size: 1.05rem; }

/* Shared flat/square/outline button system (graphs' toolbar grammar, matches
   webui .btn): neutral by default, green outline for the import/primary action,
   fill+glow on hover. Both boards load this on their board page so their toolbars
   render identically. Buttons always carry a variant class alongside .btn. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .45rem; height: 36px; padding: 0 .9rem; font-weight: 500; font-size: .84rem; letter-spacing: .03em; line-height: 1; border: 1px solid var(--border2); background: var(--panel2); color: var(--text-hi); cursor: pointer; text-decoration: none; box-sizing: border-box; white-space: nowrap; transition: background .13s ease, border-color .13s ease, box-shadow .13s ease, color .13s ease; }
.btn:hover { border-color: var(--text-hi); background: var(--panel); }
.btn i { font-size: .85em; }
.btn-import { background: transparent; color: #2ea043; border-color: #2ea043; }
.btn-import:hover { background: #2ea043; color: #06210f; box-shadow: 0 0 14px -3px #2ea043; }
.btn-add { background: transparent; color: var(--text-hi); border-color: var(--border2); }
.btn-add:hover { border-color: var(--text-hi); background: var(--panel); }
.btn-ghost { background: transparent; color: var(--muted); border: 1px solid var(--border2); }
.btn-ghost:hover { background: var(--panel); color: var(--text-hi); border-color: var(--text-hi); }
.btn-pin.is-on { color: var(--link); border-color: var(--link); background: rgba(31,111,235,.10); }
.btn-pin i { transform: rotate(30deg); }

/* ── grid + panels ───────────────────────────────────────────────────────── */
.grid-stack { background: transparent; min-height: 340px; }
/* Editable board title (dash + graphs identical): the page h1 IS the rename
   control — click, type, blur/Enter saves, Escape reverts. Dashed underline on
   hover/focus is the affordance. */
.board-title { outline: none; border-bottom: 1px dashed transparent; cursor: text; }
.board-title:hover { border-bottom-color: var(--border2); }
.board-title:focus { border-bottom-color: var(--link); }

/* Full-bleed grid: gridstack pads every item 6px, so the grid pulls -6px into
   main's padding — panels visually reach the same edge on every board plug
   (dash had this, graphs didn't: a 12px mobile width skew). */
.grid-stack { margin-left: -6px; margin-right: -6px; width: auto; }
.grid-stack-item-content.panel { display: flex; flex-direction: column; background: var(--panel2); border: 1px solid var(--border); ; overflow: hidden; }
.panel-head { display: flex; align-items: center; gap: .4rem; padding: .35rem .5rem .35rem .7rem; border-bottom: 1px solid var(--border); cursor: move; background: var(--panel); flex: none; }
.panel-head .spacer { flex: 1; }
.panel-title { background: transparent; border: 1px solid transparent; color: var(--text-hi); font-weight: 600; font-size: .88rem; padding: .15rem .3rem; ; min-width: 3rem; max-width: 60%; }
.panel-title:hover, .panel-title:focus { border-color: var(--border2); background: var(--panel2); outline: none; }
/* Static (non-editable) panel title — a board whose titles are fixed uses this
   in place of the editable input, same weight/size so the chrome is identical. */
.panel-title-static { color: var(--text-hi); font-weight: 600; font-size: .88rem; padding: .15rem .3rem; }
.icon-btn { background: transparent; border: none; color: var(--muted); cursor: pointer; font-size: .9rem; padding: .2rem .4rem; ; line-height: 1; }
.icon-btn:hover { background: var(--row-hover); color: var(--text-hi); }
/* Some hosts still render the remove control as a bare ✕ form button — give it the
   same icon-button feel inside a panel header. */
.panel-head .del-icon { background: transparent; border: none; color: var(--muted); cursor: pointer; font-size: .95rem; line-height: 1; padding: .2rem .4rem; }
.panel-head .del-icon:hover { color: #f85149; background: var(--row-hover); }
.panel-head form { display: inline-flex; margin: 0; }

/* The body fills the remaining panel height; the ECharts canvas fills the body. */
.panel-body { flex: 1; min-height: 0; display: flex; overflow: hidden; padding: 2px 4px 2px; }
.echart { flex: 1; width: 100%; height: 100%; min-height: 0; }
.panel-body iframe { flex: 1; border: 0; width: 100%; height: 100%; }

.grid-stack > .grid-stack-item > .grid-stack-item-content { inset: 0; }
.grid-stack-item.ui-draggable-dragging .panel { box-shadow: 0 8px 28px rgba(0,0,0,.5); }
.grid-stack .grid-stack-placeholder > .placeholder-content { border: 1px dashed #347d39; ; background: rgba(63,185,80,.06); }

/* Empty board prompt (no panels yet). */
.dash-empty { text-align: center; color: var(--muted); padding: 3rem 1rem; }
.dash-empty p { margin: 0 0 .9rem; }

/* ── panels the build agent just proposed ────────────────────────────────────
   They fade/slide in with an accent ring that pulses until the user interacts. */
.grid-stack-item.agent-added .panel {
  outline: 2px solid #bc8cff; outline-offset: -2px;
  box-shadow: 0 0 0 1px rgba(188,140,255,.35), 0 10px 30px -12px rgba(137,87,229,.6);
  animation: ab-reveal .5s cubic-bezier(.2,.7,.3,1) 1, ab-glow 1.8s ease-in-out .5s 4;
}
@keyframes ab-reveal { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes ab-glow { 0%,100% { outline-color: #bc8cff; } 50% { outline-color: rgba(188,140,255,.2); } }
@media (prefers-reduced-motion: reduce) { .grid-stack-item.agent-added .panel { animation: none; } }

/* ── touch scroll-lock (boardkit.js) ─────────────────────────────────────────
   A locked panel's chart/iframe ignores touches so swipes scroll the PAGE
   instead of panning the chart; the hand button (coarse pointers only) unlocks
   one panel at a time, and while one is active the page itself stops
   scrolling/zooming so every gesture belongs to that panel. */
.grid-stack-item-content.touch-locked .echart,
.grid-stack-item-content.touch-locked iframe { pointer-events: none; }
.touch-lock-btn.unlocked { color: #3fb950; }
body.touch-capture { overflow: hidden; touch-action: none; overscroll-behavior: none; }
body.touch-capture .grid-stack-item-content:not(.touch-locked) { touch-action: auto; }

/* Muted footnote line under a panel (chart notes, entity-click info). */
.chart-notes { padding: .15rem .5rem .35rem; font-size: .72rem; color: var(--muted); font-style: italic; }
.dash-entity-info { padding: .3rem .6rem; border-top: 1px solid var(--border); font-size: .78rem; color: var(--muted); min-height: 1.4em; }

/* Static and live boards get their cross-filter controls from filterkit.CSS(),
   appended by CSS(). Keeping a second copy here previously let the two palettes
   drift and briefly exposed the obsolete blue active-filter border. */
/* zoom: the panel-header expand button + the shared modal's chart sizing */
.panel-head .bk-zoom{background:transparent;border:none;color:var(--muted);cursor:pointer;font-size:.8rem;line-height:1;padding:.2rem .4rem}
.panel-head .bk-zoom:hover{color:var(--text-hi);background:var(--row-hover)}
/* click-mode pill (Filter | Attribution) — mirrors dashCSS so the static
   board's bar matches the live board exactly. */
.dash-clickmode{display:inline-flex;height:1.85rem;box-sizing:border-box;border:1px solid var(--border);border-radius:var(--r-pill);overflow:hidden}
.dash-clickmode .dcm-opt{display:inline-flex;align-items:center;gap:var(--sp-1,.25rem);font-size:.74rem;padding:0 .6rem;background:transparent;color:var(--muted);border:none;cursor:pointer;white-space:nowrap}
.dash-clickmode .dcm-opt+.dcm-opt{border-left:1px solid var(--border)}
.dash-clickmode .dcm-opt.active{background:rgba(88,166,255,.18);color:var(--text-hi)}
.dash-clickmode .dcm-opt:hover:not(.active){color:var(--text)}
.bk-sb-modal-content{max-width:min(66rem,94vw);width:94vw}
#bk-sb-zoom{height:min(68vh,34rem);width:100%}

/* ── fixed top-right icon cluster (.bk-topicon) ───────────────────────────
   Flat 2.55rem squares pinned to the top-right so they add ZERO vertical
   height; hosts stack them right-to-left with an inline right: offset. This is
   the single definition of that size/shape — it used to live on the (now deleted) live
   toggle, and hosts' icon buttons copied the numbers from it by comment.
   .active / .on marks an engaged control (house green). */
.bk-topicon{position:fixed;top:.55rem;z-index:40;width:2.55rem;height:2.55rem;box-sizing:border-box;
  border:1px solid var(--border2);cursor:pointer;background:var(--panel);color:var(--muted);
  font-size:1rem;display:flex;align-items:center;justify-content:center;
  transition:color .13s ease,border-color .13s ease}
.bk-topicon:hover{color:var(--text);border-color:var(--green-soft)}
.bk-topicon.active,.bk-topicon.on{color:var(--green-soft);border-color:var(--green-soft)}

.dash-filter-bar{display:flex;flex-wrap:wrap;gap:var(--sp-2,.5rem);align-items:center;margin:.1rem 0 .7rem}
.dash-filter-lbl{font-size:.78rem;color:var(--muted);font-weight:600;margin-right:.1rem}
.dash-filter-chip{font-size:.78rem;height:1.85rem;box-sizing:border-box;padding:0 .5rem;border:1px solid var(--border,#30363d);background:var(--panel2);color:var(--text,#c9d1d9);border-radius:var(--r-pill);display:inline-flex;align-items:center;gap:var(--sp-1,.25rem);text-decoration:none}
.dash-filter-chip:hover{border-color:#6e7681;text-decoration:none}
.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;min-height:0;height:auto}
.dash-filter-chip .fc-btn:hover{opacity:1}
.dash-filter-add{display:inline-flex;align-items:center;gap:var(--sp-1,.25rem);height:1.85rem;min-height:1.85rem;box-sizing:border-box;font-size:.76rem;padding:0 .6rem;border:1px dashed var(--border);background:transparent;color:var(--muted);border-radius:var(--r-pill);cursor:pointer;white-space:nowrap}
.dash-filter-add:hover{color:var(--text-hi,#f0f6fc);border-color:var(--link,#58a6ff);background:transparent}
.dash-filter-add-wrap{display:inline-flex;align-items:center;gap:var(--sp-1,.25rem);flex-wrap:wrap}
.dash-filter-form{display:inline-flex;align-items:center;gap:var(--sp-2,.5rem);height:1.85rem;box-sizing:border-box;padding:0 .4rem;border:1px solid var(--border);background:var(--panel2)}
/* The global control system has a 38px minimum. Filter controls deliberately
   fit inside the 29.6px capsule, so both height and min-height are pinned. */
.dash-filter-form select,.dash-filter-form input.dff-val{font-size:.76rem;height:1.45rem;min-height:1.45rem;max-height:1.45rem;box-sizing:border-box;padding:0 .35rem;background:var(--panel);color:var(--text,#c9d1d9);border:1px solid var(--border);margin:0;line-height:1}
.dash-filter-form input.dff-val{width:9rem}
.dash-filter-form .dff-not{font-size:.72rem;color:var(--muted);display:inline-flex;align-items:center;gap:var(--sp-1,.25rem);white-space:nowrap;margin:0}
.dash-filter-form .dff-not input{margin:0;width:auto;height:auto;min-height:0;vertical-align:middle}
.dash-filter-form .dff-add,.dash-filter-form .dff-cancel{display:inline-flex;align-items:center;height:1.45rem;min-height:1.45rem;box-sizing:border-box;font-size:.74rem;padding:0 .45rem;border:1px solid var(--border);background:var(--panel);cursor:pointer;line-height:1}
.dash-filter-form .dff-add{color:var(--link,#58a6ff);border-color:#1f6feb}
.dash-filter-form .dff-cancel{color:var(--muted)}
.dash-filter-clear{display:inline-flex;align-items:center;height:1.85rem;min-height:1.85rem;box-sizing:border-box;font-size:.74rem;padding:0 .6rem;border:1px solid var(--border);background:transparent;color:var(--muted);border-radius:var(--r-pill);cursor:pointer}
.dash-filter-clear:hover{color:var(--text-hi,#f0f6fc);border-color:var(--muted);background:transparent}
html.fullscreen main{max-width:none;margin:0;padding-left:14px;padding-right:14px}html.fullscreen .dash-actions{display:flex;flex-wrap:wrap;justify-content:flex-start;gap:var(--sp-2,.5rem)}html.fullscreen .dash-actions .btn{width:auto}
/* 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}
}
