/* =================================================================
   tradingsmart.ai ⟨TERMINAL⟩ — Bloomberg-grade dense UI
   ================================================================= */

:root {
  /* surfaces */
  --bg-app: #05070a;
  --bg-base: #0a0d13;
  --bg-panel: #0e1218;
  --bg-elevated: #11161f;
  --bg-row: #141a23;
  --bg-hover: #1b2230;
  --bg-active: #243043;

  /* borders */
  --bd-1: #161c26;
  --bd-2: #1f2733;
  --bd-3: #2c3645;

  /* text */
  --tx-1: #e6e9ef;
  --tx-2: #a8b1bf;
  --tx-3: #6a7384;
  --tx-4: #485160;

  /* accents */
  --ac: #3a82f6;
  --ac-d: #1e5bc9;
  --orange: #f2a341; /* Bloomberg amber */
  --up: #1fcb6b;
  --up-bg: rgba(31, 203, 107, 0.1);
  --down: #f23e55;
  --down-bg: rgba(242, 62, 85, 0.1);
  --warn: #f2a341;
  --info: #18bfd9;
  --purple: #a78bfa;
  --teal: #14b8a6;

  --ff-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --ff-mn: "JetBrains Mono", "SF Mono", Menlo, monospace;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}
html,
body {
  height: 100%;
  margin: 0;
}
body {
  background: var(--bg-app);
  color: var(--tx-1);
  font-family: var(--ff-ui);
  font-size: 11px;
  font-feature-settings:
    "tnum" 1,
    "ss01" 1,
    "cv11" 1;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
.mono {
  font-family: var(--ff-mn);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.1px;
}
.up {
  color: var(--up);
}
.down {
  color: var(--down);
}
.r {
  text-align: right;
}
button {
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
}
input,
select,
textarea {
  font-family: inherit;
}

.terminal {
  display: grid;
  grid-template-rows: 46px 22px 1fr 22px;
  /* Clamp the column track to the viewport width. Without minmax(0, 1fr)
     the grid track expands to the max-content of its children (the cmd-bar
     fkeys + clocks + LEDs together are ~1570px wide), pushing the whole
     dashboard wider than the viewport. */
  grid-template-columns: minmax(0, 1fr);
  height: 100vh;
  background: var(--bg-app);
  overflow: hidden;
}
.terminal > * {
  min-width: 0;
}
/* Explicit row placement — without this, the strategy-detail overlay (which
   is also a child of .terminal) participates in auto-placement and pushes
   .grid into the 22px ticker-tape row instead of the 1fr main row,
   collapsing the dashboard to a thin strip. */
.terminal > .cmd-bar {
  grid-row: 1;
}
.terminal > .ticker-tape {
  grid-row: 2;
}
.terminal > .grid {
  grid-row: 3;
  min-height: 0;
}
.terminal > .status-bar {
  grid-row: 4;
}
/* strategy-detail is an overlay (position: absolute when visible); take it
   out of grid flow entirely so it doesn't claim a row track. */
.terminal > .strategy-detail {
  grid-row: 1 / -1;
  grid-column: 1;
}

/* =================================================================
   COMMAND BAR
   ================================================================= */
.cmd-bar {
  display: grid;
  grid-template-columns: auto auto 1fr auto auto auto;
  align-items: center;
  gap: 0;
  background: linear-gradient(180deg, #0e141c 0%, #080b11 100%);
  border-bottom: 1px solid var(--bd-2);
  padding: 0;
  height: 32px;
}
.brand {
  display: flex;
  align-items: baseline;
  gap: 2px;
  padding: 0 12px;
  height: 100%;
  border-right: 1px solid var(--bd-2);
  align-self: stretch;
  align-items: center;
}
.brand-mark {
  font-weight: 800;
  font-size: 13px;
  color: var(--orange);
  letter-spacing: -0.5px;
}
.brand-sup {
  font-weight: 700;
  font-size: 9px;
  color: var(--ac);
}
.brand-tag {
  font-size: 8px;
  color: var(--tx-3);
  margin-left: 8px;
  padding: 1px 5px;
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

.fkeys {
  display: flex;
  height: 100%;
  border-right: 1px solid var(--bd-2);
}
.fkeys button {
  background: transparent;
  border: 0;
  color: var(--tx-2);
  padding: 0 8px;
  font-size: 9px;
  font-weight: 600;
  border-right: 1px solid var(--bd-1);
  display: flex;
  align-items: center;
  gap: 4px;
  letter-spacing: 0.3px;
  position: relative;
}
.fkeys button:hover {
  color: var(--tx-1);
  background: var(--bg-hover);
}
.fkeys button.active {
  color: var(--orange);
  background: rgba(242, 163, 65, 0.08);
}
.fkeys button.active::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--orange);
}
.fkeys b {
  font-size: 9px;
  font-weight: 700;
  color: var(--orange);
  background: rgba(242, 163, 65, 0.1);
  padding: 1px 3px;
  border-radius: 2px;
  font-family: var(--ff-mn);
}

.cmd-input {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  border-right: 1px solid var(--bd-2);
  height: 100%;
}
.cmd-prompt {
  color: var(--orange);
  font-weight: 700;
  font-family: var(--ff-mn);
  font-size: 13px;
}
.cmd-input input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
}
.cmd-input input::placeholder {
  color: var(--tx-4);
}

.clocks {
  display: flex;
  height: 100%;
  border-right: 1px solid var(--bd-2);
}
.clk {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 8px;
  border-right: 1px solid var(--bd-1);
  font-size: 9px;
}
.clk:last-child {
  border-right: 0;
}
.clk-z {
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
}
.clk-t {
  color: var(--tx-1);
  font-size: 10px;
  font-weight: 600;
}
.mkt-led {
  font-size: 8px;
  line-height: 1;
}
.mkt-led.ny.open {
  color: var(--up);
}
.mkt-led.ldn.open {
  color: var(--up);
}
.mkt-led.tyo.open {
  color: var(--up);
}
.mkt-led.ist.open {
  color: var(--up);
}
.mkt-led {
  color: var(--tx-4);
}

.conn-leds {
  display: flex;
  height: 100%;
  border-right: 1px solid var(--bd-2);
  align-items: center;
  padding: 0 6px;
  gap: 8px;
}
.led {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
  font-weight: 700;
}
.led .d {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--tx-4);
  display: inline-block;
}
.led.ok .d {
  background: var(--up);
  box-shadow: 0 0 4px rgba(31, 203, 107, 0.6);
}
.led.warn .d {
  background: var(--warn);
  box-shadow: 0 0 4px rgba(242, 163, 65, 0.6);
}
.led.err .d {
  background: var(--down);
  box-shadow: 0 0 4px rgba(242, 62, 85, 0.6);
}
.led .ms {
  color: var(--tx-2);
  margin-left: 2px;
}

.user-cell {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  height: 100%;
}
.avatar {
  width: 20px;
  height: 20px;
  border-radius: 3px;
  background: linear-gradient(135deg, var(--orange), var(--ac));
  color: white;
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: 10px;
}
.user-meta {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
  font-size: 9px;
}
.user-meta div:first-child {
  font-weight: 700;
  color: var(--tx-1);
}
.user-sub {
  color: var(--tx-3);
  font-size: 8px;
  letter-spacing: 0.4px;
}

/* =================================================================
   TICKER TAPE
   ================================================================= */
.ticker-tape {
  height: 22px;
  background: var(--bg-base);
  border-bottom: 1px solid var(--bd-2);
  overflow: hidden;
  position: relative;
}
.ticker-tape::before,
.ticker-tape::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 24px;
  z-index: 2;
  pointer-events: none;
}
.ticker-tape::before {
  left: 0;
  background: linear-gradient(90deg, var(--bg-base), transparent);
}
.ticker-tape::after {
  right: 0;
  background: linear-gradient(-90deg, var(--bg-base), transparent);
}
.tt-track {
  display: inline-flex;
  align-items: center;
  gap: 0;
  white-space: nowrap;
  animation: tt-scroll 90s linear infinite;
  height: 22px;
  font-family: var(--ff-mn);
  font-size: 11px;
  padding-left: 100%;
}
.tt-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  border-right: 1px solid var(--bd-1);
  height: 22px;
}
.tt-sym {
  color: var(--tx-1);
  font-weight: 700;
}
.tt-px {
  color: var(--tx-2);
}
.tt-chg {
  font-weight: 600;
}
.tt-arrow {
  font-size: 9px;
}
@keyframes tt-scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

/* =================================================================
   GRID
   ================================================================= */
.grid {
  display: grid;
  grid-template-columns: 220px 1fr 280px 280px;
  gap: 1px;
  background: var(--bd-2);
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

/* New 2-col strategies-first dashboard */
.grid.grid-v2 {
  /* All right-rail docks (signals, heatmap, watchlist, news) are hidden
     for the bot-focused dashboard, so the layout collapses to a single
     full-width main column. */
  grid-template-columns: 1fr;
}
.grid.grid-v2 .col-main {
  display: grid;
  /* Row layout (top → bottom):
       1. dash-banners wrapper — auto, collapses to 0 when both child
          banners are display:none, expands when one becomes visible.
       2. dash-header strip    — auto, natural height of the user row.
       3. strategies dock      — 1fr
       4. bots dock            — 1fr
     The two `auto` rows up top are CRITICAL: dropping the second
     `auto` puts dash-header into a 1fr row, inflating it 200-300px
     even though its content is ~50px. */
  grid-template-rows: auto auto 1fr 1fr;
  grid-auto-rows: 1fr;
  gap: 1px;
  background: var(--bd-2);
  min-height: 0;
  overflow: hidden;
}
.grid.grid-v2 .col-right {
  display: none;
}
/* Right column is hidden everywhere; no responsive 2-col fallback needed. */
@media (max-width: 1024px) {
  .grid.grid-v2 .col-right {
    display: none;
  }
}
.col {
  display: flex;
  flex-direction: column;
  background: var(--bg-app);
  min-height: 0;
  overflow: hidden;
}
.col-2 {
  display: grid;
  grid-template-rows: 1.7fr 0.6fr 0.7fr;
  gap: 1px;
  background: var(--bd-2);
}
.col-1,
.col-3,
.col-4 {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  gap: 1px;
  background: var(--bd-2);
}
.col-3 {
  grid-template-rows: 1.4fr 0.7fr 0.9fr;
}
.col-4 {
  grid-template-rows: 1fr 1fr 1fr;
}

/* =================================================================
   DOCK (every panel)
   ================================================================= */
.dock {
  background: var(--bg-panel);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
.dock-h {
  height: 22px;
  background: linear-gradient(180deg, #131923 0%, #0d121b 100%);
  border-bottom: 1px solid var(--bd-2);
  padding: 0 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--orange);
  flex-shrink: 0;
}
.dock-h > span:first-child {
  display: flex;
  align-items: center;
  gap: 6px;
}
.d-count {
  font-family: var(--ff-mn);
  background: var(--bg-active);
  color: var(--tx-2);
  padding: 0 5px;
  border-radius: 2px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0;
}
.d-meta {
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 600;
  letter-spacing: 0.3px;
}
.d-act {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  font-size: 9px;
  padding: 0 4px;
  font-weight: 700;
  letter-spacing: 0.5px;
}
.d-act:hover {
  color: var(--orange);
}

.mini-tabs {
  display: flex;
  gap: 1px;
  background: var(--bd-2);
  border-radius: 2px;
}
.mini-tabs button {
  background: var(--bg-elevated);
  color: var(--tx-3);
  border: 0;
  padding: 1px 6px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
}
.mini-tabs button.active {
  background: var(--bg-active);
  color: var(--tx-1);
}

/* =================================================================
   COL 1 — STRATEGIES, WATCHLIST, MOVERS
   ================================================================= */
.strat-list {
  flex: 1;
  overflow-y: auto;
  padding: 2px;
}
.strat-card {
  height: 38px;
  padding: 4px 6px;
  cursor: pointer;
  display: grid;
  grid-template-columns: 8px 1fr auto;
  gap: 6px;
  align-items: center;
  border-bottom: 1px solid var(--bd-1);
}
.strat-card:hover {
  background: var(--bg-hover);
}
.strat-card.selected {
  background: var(--bg-active);
}
.strat-card.selected::before {
  content: "";
}
.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
.dot.running {
  background: var(--up);
  box-shadow: 0 0 5px rgba(31, 203, 107, 0.7);
}
.dot.paused {
  background: var(--warn);
}
.dot.errored {
  background: var(--down);
}
.sc-meta {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  min-width: 0;
}
.sc-name {
  font-size: 11px;
  font-weight: 600;
  color: var(--tx-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sc-sub {
  font-size: 9px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sc-pnl {
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  text-align: right;
}

.paste-zone {
  margin: 4px;
  padding: 8px 6px;
  background: linear-gradient(
    180deg,
    rgba(242, 163, 65, 0.06),
    rgba(242, 163, 65, 0.02)
  );
  border: 1px dashed var(--bd-3);
  color: var(--tx-2);
  border-radius: 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-size: 10px;
  flex-shrink: 0;
}
.paste-zone:hover {
  border-color: var(--orange);
  color: var(--orange);
  background: rgba(242, 163, 65, 0.1);
}
.pz-icon {
  font-size: 14px;
  color: var(--orange);
}
.pz-title {
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.5px;
}
.pz-sub {
  font-size: 8px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
}

.watchlist {
  flex: 1;
  overflow-y: auto;
  font-family: var(--ff-mn);
  font-size: 10px;
}
.wl-row {
  display: grid;
  grid-template-columns: 1fr 60px 50px;
  align-items: center;
  padding: 3px 8px;
  border-bottom: 1px solid var(--bd-1);
  cursor: pointer;
}
.wl-row:hover {
  background: var(--bg-hover);
}
.wl-row.selected {
  background: var(--bg-active);
}
.wl-sym {
  font-weight: 700;
  color: var(--tx-1);
}
.wl-mkt {
  font-size: 8px;
  color: var(--tx-3);
  margin-left: 4px;
  font-weight: 600;
  letter-spacing: 0.3px;
}
.wl-px {
  text-align: right;
  color: var(--tx-2);
  font-weight: 600;
  transition: color 0.2s;
}
.wl-px.flash-up {
  color: var(--up);
}
.wl-px.flash-down {
  color: var(--down);
}
.wl-chg {
  text-align: right;
  font-weight: 700;
}
.wl-spark {
  display: none;
} /* canvas later if needed */

.movers {
  flex: 1;
  overflow-y: auto;
  font-family: var(--ff-mn);
  font-size: 10px;
}
.mv-row {
  display: grid;
  grid-template-columns: 16px 1fr 60px;
  align-items: center;
  padding: 3px 8px;
  border-bottom: 1px solid var(--bd-1);
}
.mv-rank {
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 700;
}
.mv-sym {
  font-weight: 700;
  color: var(--tx-1);
}
.mv-chg {
  text-align: right;
  font-weight: 700;
}

/* =================================================================
   COL 2 — CHART + T&S + POSITIONS
   ================================================================= */
.chart-dock {
  min-height: 0;
}
.chart-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 8px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  height: 36px;
  flex-shrink: 0;
}
.sym-block {
  display: flex;
  align-items: center;
  gap: 12px;
}
.sym-pick {
  background: transparent;
  border: 0;
  color: var(--tx-1);
  display: flex;
  align-items: baseline;
  gap: 4px;
  padding: 0;
}
.sym-name {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.3px;
  color: var(--orange);
}
.sym-mkt {
  font-size: 8px;
  color: var(--tx-3);
  padding: 1px 4px;
  background: var(--bg-active);
  border-radius: 2px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

.bp-block {
  display: flex;
  align-items: baseline;
  gap: 4px;
  padding: 0 10px;
  border-left: 1px solid var(--bd-2);
  border-right: 1px solid var(--bd-2);
  font-family: var(--ff-mn);
  font-size: 11px;
}
.bp-px {
  color: var(--up);
  font-weight: 700;
}
.bp-px.ask {
  color: var(--down);
}
.bp-sz {
  color: var(--tx-3);
  font-size: 9px;
}
.bp-x {
  color: var(--tx-4);
}

.px-block {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding-right: 10px;
  border-right: 1px solid var(--bd-2);
}
.px {
  font-size: 16px;
  font-weight: 800;
  transition: color 0.2s;
  font-family: var(--ff-mn);
  letter-spacing: -0.4px;
}
.px.flash-up {
  color: var(--up);
  text-shadow: 0 0 8px rgba(31, 203, 107, 0.6);
}
.px.flash-down {
  color: var(--down);
  text-shadow: 0 0 8px rgba(242, 62, 85, 0.6);
}
.px-chg {
  font-size: 11px;
  font-weight: 600;
}

.src-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--ff-mn);
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.6px;
  padding: 1px 5px 1px 4px;
  border-radius: 2px;
  margin-left: 4px;
  border: 1px solid currentColor;
}
.src-badge .src-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}
.src-badge.live {
  color: var(--up);
  background: rgba(31, 203, 107, 0.1);
}
.src-badge.live .src-dot {
  animation: src-pulse 1.6s infinite;
  box-shadow: 0 0 5px currentColor;
}
.src-badge.delay {
  color: var(--warn);
  background: rgba(242, 163, 65, 0.1);
}
.src-badge.sim {
  color: var(--tx-3);
  background: rgba(106, 115, 132, 0.1);
  border-color: var(--bd-3);
}
@keyframes src-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.sb-feed-state.ok {
  color: var(--up);
}
.sb-feed-state.warn {
  color: var(--warn);
}
.sb-feed-state.err {
  color: var(--down);
}
.sb-feed-state.init {
  color: var(--tx-3);
}

.wl-row .wl-live {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  display: inline-block;
  margin-left: 4px;
  vertical-align: middle;
  background: var(--up);
  box-shadow: 0 0 4px var(--up);
}

.ohlc-block {
  display: flex;
  gap: 10px;
  font-size: 10px;
  padding-left: 4px;
}
.ohlc-block span {
  display: flex;
  align-items: baseline;
  gap: 3px;
}
.ohlc-block i {
  color: var(--tx-3);
  font-style: normal;
  font-weight: 700;
  font-size: 9px;
}
.ohlc-block b {
  color: var(--tx-1);
  font-weight: 600;
}

.cb-right {
  display: flex;
  align-items: center;
  gap: 4px;
}
.seg {
  display: flex;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  overflow: hidden;
}
.seg button {
  background: transparent;
  color: var(--tx-3);
  border: 0;
  padding: 3px 8px;
  font-weight: 600;
  font-size: 10px;
  border-right: 1px solid var(--bd-2);
  letter-spacing: 0.3px;
}
.seg button:last-child {
  border-right: 0;
}
.seg button:hover {
  color: var(--tx-1);
  background: var(--bg-hover);
}
.seg button.active {
  background: var(--bg-active);
  color: var(--orange);
}
.seg.sm button {
  padding: 1px 6px;
  font-size: 9px;
}

.chart-wrap {
  flex: 1;
  position: relative;
  min-height: 0;
  overflow: hidden;
}
.chart-wrap canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.ind-tags {
  position: absolute;
  top: 4px;
  left: 8px;
  display: flex;
  gap: 4px;
  pointer-events: none;
  flex-wrap: wrap;
  max-width: 60%;
}
.ind-tag {
  font-family: var(--ff-mn);
  font-size: 9px;
  padding: 1px 5px;
  border-radius: 2px;
  background: rgba(10, 13, 19, 0.85);
  border: 1px solid var(--bd-2);
  font-weight: 600;
}
.ind-tag.ema9 {
  color: var(--ac);
  border-color: var(--ac);
}
.ind-tag.ema21 {
  color: var(--orange);
  border-color: var(--orange);
}
.ind-tag.vwap {
  color: var(--purple);
  border-color: var(--purple);
}
.ind-tag.bb {
  color: var(--info);
  border-color: var(--info);
}
.ind-tag.strat {
  color: var(--up);
  border-color: var(--up);
  margin-left: 8px;
}

.crosshair-readout {
  position: absolute;
  top: 4px;
  right: 60px;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 2px;
  background: rgba(10, 13, 19, 0.92);
  border: 1px solid var(--bd-3);
  color: var(--tx-2);
  pointer-events: none;
  display: none;
  letter-spacing: 0.3px;
}
.crosshair-readout.show {
  display: block;
}
.crosshair-readout b {
  color: var(--tx-1);
  font-weight: 700;
}

/* time & sales */
.ts-dock {
  min-height: 0;
}
.ts-head,
.l2-head {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  padding: 3px 8px;
  font-size: 9px;
  background: var(--bg-elevated);
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
  border-bottom: 1px solid var(--bd-2);
  flex-shrink: 0;
}
.ts-rows {
  flex: 1;
  overflow-y: auto;
  font-family: var(--ff-mn);
  font-size: 10px;
}
.ts-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  padding: 1px 8px;
  border-bottom: 1px solid var(--bd-1);
  align-items: center;
}
.ts-row.up {
  color: var(--up);
}
.ts-row.down {
  color: var(--down);
}
.ts-row .px {
  font-weight: 700;
}
.ts-row .px.large {
  background: var(--up-bg);
}
.ts-row.down .px.large {
  background: var(--down-bg);
}
.ts-row.new {
  animation: ts-flash 0.4s ease-out;
}
@keyframes ts-flash {
  0% {
    background: var(--bg-active);
  }
  100% {
    background: transparent;
  }
}

/* positions */
.pos-dock {
  min-height: 0;
}
.pos-tabs {
  display: flex;
  gap: 0;
}
.pos-tabs button {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  padding: 0 8px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  height: 22px;
  border-right: 1px solid var(--bd-1);
  display: flex;
  align-items: center;
  gap: 4px;
}
.pos-tabs button:hover {
  color: var(--tx-1);
}
.pos-tabs button.active {
  color: var(--orange);
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 10px;
  table-layout: fixed;
}
.data-table thead {
  background: var(--bg-elevated);
  position: sticky;
  top: 0;
  z-index: 1;
}
.data-table th {
  text-align: left;
  padding: 3px 8px;
  font-size: 8px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
  border-bottom: 1px solid var(--bd-2);
}
.data-table th.r {
  text-align: right;
}
.pos-dock tbody {
  display: block;
  overflow-y: auto;
  height: calc(100% - 22px);
}
.pos-dock thead,
.pos-dock tbody tr {
  display: table;
  width: 100%;
  table-layout: fixed;
}
.data-table tbody tr {
  height: 22px;
  border-bottom: 1px solid var(--bd-1);
  font-family: var(--ff-mn);
}
.data-table tbody tr:hover {
  background: var(--bg-hover);
}
.data-table td {
  padding: 0 8px;
  vertical-align: middle;
}
.data-table td.r {
  text-align: right;
}
.data-table td.bold {
  font-weight: 700;
  color: var(--tx-1);
  font-family: var(--ff-ui);
}
.close-btn {
  background: transparent;
  border: 1px solid var(--bd-3);
  color: var(--down);
  padding: 1px 6px;
  border-radius: 2px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.3px;
}
.close-btn:hover {
  background: var(--down);
  color: white;
}
.empty-row td {
  text-align: center;
  color: var(--tx-3);
  padding: 16px 8px;
  font-size: 10px;
}
.row-flash {
  animation: row-flash 1s ease-out;
}
@keyframes row-flash {
  0% {
    background: rgba(58, 130, 246, 0.25);
  }
  100% {
    background: transparent;
  }
}
.side-tag {
  font-weight: 700;
  padding: 0 4px;
  border-radius: 2px;
  font-size: 9px;
}
.side-tag.buy {
  color: var(--up);
  background: var(--up-bg);
}
.side-tag.sell {
  color: var(--down);
  background: var(--down-bg);
}

/* =================================================================
   COL 3 — SIGNALS, HEATMAP, NEWS
   ================================================================= */
.signals-list {
  flex: 1;
  overflow-y: auto;
  padding: 2px;
}
.signal-card {
  position: relative;
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: 4px;
  padding: 4px 6px 4px 10px;
  border-bottom: 1px solid var(--bd-1);
  animation: sig-in 0.25s ease-out;
}
@keyframes sig-in {
  from {
    opacity: 0;
    transform: translateY(-6px);
    background: var(--bg-active);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    background: transparent;
  }
}
.signal-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
}
.signal-card.buy::before {
  background: var(--up);
  box-shadow: 0 0 6px var(--up);
}
.signal-card.sell::before {
  background: var(--down);
  box-shadow: 0 0 6px var(--down);
}
.sig-arrow {
  font-size: 11px;
  font-weight: 700;
}
.sig-arrow.up {
  color: var(--up);
}
.sig-arrow.down {
  color: var(--down);
}
.sig-mid {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.2;
}
.sig-top {
  display: flex;
  gap: 4px;
  align-items: baseline;
}
.sig-sym {
  font-weight: 700;
  font-size: 11px;
  color: var(--tx-1);
}
.sig-qp {
  font-family: var(--ff-mn);
  font-size: 9px;
  color: var(--tx-2);
}
.sig-bot {
  font-size: 9px;
  color: var(--tx-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sig-time {
  font-family: var(--ff-mn);
  font-size: 9px;
  color: var(--tx-3);
  text-align: right;
}
.sig-status {
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-align: right;
}
.sig-status.filled {
  color: var(--up);
}
.sig-status.pending {
  color: var(--warn);
  animation: pending-pulse 1.2s infinite;
}
@keyframes pending-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.4;
  }
}

/* heatmap */
.heatmap {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: 1px;
  padding: 1px;
  background: var(--bd-2);
  min-height: 0;
}
.hm-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-family: var(--ff-mn);
  padding: 2px;
  font-size: 9px;
  cursor: pointer;
  overflow: hidden;
}
.hm-cell .hm-sym {
  font-weight: 800;
  font-size: 10px;
  color: white;
  line-height: 1.1;
}
.hm-cell .hm-pct {
  font-weight: 700;
  font-size: 9px;
  color: rgba(255, 255, 255, 0.85);
}
.hm-cell:hover {
  outline: 1px solid white;
  z-index: 2;
}

/* news */
.news-list {
  flex: 1;
  overflow-y: auto;
}
.news-row {
  display: grid;
  grid-template-columns: 36px 1fr 36px;
  gap: 6px;
  align-items: center;
  padding: 4px 8px;
  border-bottom: 1px solid var(--bd-1);
  cursor: pointer;
  font-size: 10px;
}
.news-row:hover {
  background: var(--bg-hover);
}
.news-time {
  font-family: var(--ff-mn);
  font-size: 9px;
  color: var(--tx-3);
}
.news-title {
  color: var(--tx-1);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.news-src {
  font-size: 8px;
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.3px;
}
.news-tag {
  font-family: var(--ff-mn);
  font-size: 8px;
  padding: 1px 3px;
  border-radius: 2px;
  font-weight: 700;
  text-align: center;
}
.news-tag.bull {
  background: var(--up-bg);
  color: var(--up);
}
.news-tag.bear {
  background: var(--down-bg);
  color: var(--down);
}
.news-tag.neut {
  background: var(--bg-active);
  color: var(--tx-2);
}

/* Source row gets a flex layout so the bot-link chip can sit next to
   the source name without disturbing the title row above it. */
.news-src-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 1px;
}
.news-src-row .news-src {
  flex-shrink: 0;
}
/* Bot-count chip on news rows. Purple AI accent (matches AI Co-Pilot
   theme) so it telegraphs "this is a connection to your bots". Tiny
   footprint — these go on every matching row, so visual restraint
   matters more than discoverability (the popover does the explaining). */
.news-bot-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: auto;
  height: 14px;
  padding: 0 5px;
  background: rgba(168, 85, 247, 0.12);
  border: 1px solid rgba(168, 85, 247, 0.35);
  border-radius: 7px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: #c4b5fd;
  cursor: pointer;
  transition:
    background 0.12s,
    border-color 0.12s,
    transform 0.08s;
}
.news-bot-chip:hover {
  background: rgba(168, 85, 247, 0.22);
  border-color: rgba(168, 85, 247, 0.6);
  color: #ddd6fe;
}
.news-bot-chip:active {
  transform: scale(0.95);
}
.news-bot-chip-ico {
  font-size: 9px;
  line-height: 1;
}
.news-bot-chip-n {
  font-family: var(--ff-mn);
}

/* Headline preview inside the popover — lets the user confirm which
   row they clicked (the popover is detached from the row visually). */
.news-bot-headline {
  font-size: 10px;
  font-style: italic;
  color: var(--tx-3);
  padding: 6px 8px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 3px;
  margin-bottom: 8px;
  line-height: 1.4;
  max-height: 56px;
  overflow: hidden;
}

/* Bot list inside popover — vertical stack of clickable rows. Each
   row: persona icon · bot name · matched-symbols tag. */
.news-bot-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-height: 220px;
  overflow-y: auto;
}
.news-bot-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  cursor: pointer;
  font-size: 11px;
  text-align: left;
  width: 100%;
  color: var(--tx-1);
  transition:
    background 0.12s,
    border-color 0.12s;
}
.news-bot-row:hover {
  background: rgba(168, 85, 247, 0.1);
  border-color: rgba(168, 85, 247, 0.4);
}
.news-bot-row-pico {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
}
.news-bot-row-pico.empty {
  opacity: 0.3;
}
.news-bot-row-pico.empty::before {
  content: "·";
  color: var(--tx-3);
}
.news-bot-row-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 700;
}
.news-bot-row-tag {
  flex-shrink: 0;
  font-family: var(--ff-mn);
  font-size: 8px;
  font-weight: 700;
  padding: 2px 5px;
  background: rgba(168, 85, 247, 0.12);
  color: #c4b5fd;
  border-radius: 8px;
  letter-spacing: 0.3px;
  max-width: 110px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Macro/generic-match tag — softer styling because it's a weaker
   signal than a symbol-name match. */
.news-bot-row-tag.generic {
  background: var(--bg-active);
  color: var(--tx-3);
  font-style: italic;
}
.news-bot-more {
  margin-top: 8px;
  font-size: 9px;
  color: var(--tx-3);
  text-align: center;
  font-style: italic;
}
.news-bot-empty {
  padding: 10px;
  font-size: 11px;
  color: var(--tx-3);
  text-align: center;
}

/* =================================================================
   COL 4 — LEVEL II, ORDER TICKET, EQUITY
   ================================================================= */
.l2-dock {
  min-height: 0;
}
.l2-rows {
  flex: 1;
  overflow-y: auto;
  font-family: var(--ff-mn);
  font-size: 10px;
  position: relative;
}
.l2-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  padding: 1px 8px;
  align-items: center;
  position: relative;
}
.l2-row .bar-bid {
  position: absolute;
  right: 50%;
  top: 0;
  bottom: 0;
  background: rgba(31, 203, 107, 0.1);
}
.l2-row .bar-ask {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  background: rgba(242, 62, 85, 0.1);
}
.l2-row span {
  position: relative;
  z-index: 1;
}
.l2-row .bid-px {
  color: var(--up);
  font-weight: 700;
}
.l2-row .ask-px {
  color: var(--down);
  font-weight: 700;
  text-align: right;
}
.l2-row .sz {
  color: var(--tx-2);
}
.l2-spread-row {
  text-align: center;
  padding: 3px 0;
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 700;
  border-block: 1px dashed var(--bd-2);
  background: var(--bg-elevated);
  font-family: var(--ff-mn);
  letter-spacing: 0.4px;
}
.l2-foot {
  display: flex;
  gap: 8px;
  justify-content: space-between;
  padding: 3px 8px;
  background: var(--bg-elevated);
  border-top: 1px solid var(--bd-2);
  font-size: 9px;
  color: var(--tx-3);
  flex-shrink: 0;
}
.l2-foot span b {
  color: var(--tx-1);
  font-weight: 700;
}

/* order ticket */
.ot-dock {
  min-height: 0;
}
.order-ticket {
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-height: 0;
  overflow: auto;
}
.ot-side {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}
.ot-side button {
  padding: 6px 0;
  background: var(--bg-elevated);
  color: var(--tx-3);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  font-weight: 800;
  letter-spacing: 0.6px;
  font-size: 11px;
}
.ot-side button.active.ot-buy {
  background: var(--up);
  color: white;
  border-color: var(--up);
}
.ot-side button.active.ot-sell {
  background: var(--down);
  color: white;
  border-color: var(--down);
}
.ot-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}
.ot-grid label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 8px;
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
}
.ot-grid input,
.ot-grid select {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 4px 6px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 11px;
  outline: 0;
}
.ot-grid input:focus,
.ot-grid select:focus {
  border-color: var(--orange);
}
.ot-grid input:disabled {
  opacity: 0.4;
}
.ot-est {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 4px 6px;
  display: grid;
  gap: 2px;
  font-size: 10px;
}
.ot-est div {
  display: flex;
  justify-content: space-between;
  color: var(--tx-3);
}
.ot-est div span:last-child {
  color: var(--tx-1);
  font-weight: 700;
}
.ot-submit {
  background: var(--up);
  color: white;
  border: 0;
  padding: 8px 0;
  font-weight: 800;
  letter-spacing: 0.8px;
  font-size: 11px;
  border-radius: 2px;
}
.ot-submit.sell {
  background: var(--down);
}
.ot-submit:hover {
  filter: brightness(1.1);
}

/* equity dock */
.eq-dock {
  min-height: 0;
}
/* Equity curve is intentionally hidden everywhere. The mobile rule
   `.col-main > .dock { display: flex !important }` (specificity 0,2,0)
   beats a plain `.eq-dock` (0,1,0) even with !important — so we match
   the same shape with `.col-main > .dock.eq-dock` (0,3,0) to win.
   The bare `.eq-dock` covers anywhere the dock isn't a child of
   .col-main (no current path, but cheap insurance). */
.eq-dock,
.col-main > .dock.eq-dock {
  display: none !important;
}
.eq-wrap {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.eq-wrap canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.eq-stats {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  border-top: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  flex-shrink: 0;
}
.eq-stat {
  padding: 3px 6px;
  border-right: 1px solid var(--bd-1);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.eq-stat:last-child {
  border-right: 0;
}
.eq-stat-k {
  font-size: 8px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.eq-stat-v {
  font-size: 11px;
  font-weight: 700;
}

/* =================================================================
   STATUS BAR
   ================================================================= */
.status-bar {
  display: flex;
  align-items: center;
  background: linear-gradient(180deg, #0e141c 0%, #080b11 100%);
  border-top: 1px solid var(--bd-2);
  padding: 0 12px;
  font-size: 10px;
  color: var(--tx-2);
  height: 22px;
  font-family: var(--ff-mn);
  gap: 4px;
}
.sb-section {
  display: flex;
  align-items: center;
  gap: 6px;
}
.sb-section.center {
  justify-content: center;
}
.sb-grow {
  flex: 1;
}
.sb-led {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
  background: var(--tx-4);
  margin-right: 4px;
}
.sb-led.ok {
  background: var(--up);
  box-shadow: 0 0 6px var(--up);
  animation: sb-pulse 2.5s infinite;
}
@keyframes sb-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}
.sb-sep {
  color: var(--tx-4);
}
.status-bar b {
  color: var(--tx-1);
  font-weight: 700;
}
.status-bar b.up {
  color: var(--up);
}
.status-bar b.down {
  color: var(--down);
}

/* Collapsed status bar — hides everything tagged .sb-extra. The
   essentials (LED + CONNECTED + FEED + version + toggle) remain
   visible. Click the toggle to flip the .sb-collapsed class and
   reveal SESSION / BNCE / YHOO / EXEC / EQ / P&L / OPEN /
   BUYING POWER / MSGS / RTH / clock. */
.status-bar.sb-collapsed .sb-extra {
  display: none !important;
}
.sb-toggle {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--tx-3);
  padding: 0 2px;
  margin-left: 6px;
  font-size: 11px;
  line-height: 1;
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
}
.sb-toggle:hover {
  color: var(--tx-1);
  background: var(--bg-hover);
}
.status-bar.sb-collapsed .sb-toggle::before {
  content: "▸";
}
.status-bar:not(.sb-collapsed) .sb-toggle::before {
  content: "▾";
}

/* =================================================================
   COMMAND PALETTE
   ================================================================= */
.cmdk-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(4px);
  display: none;
  z-index: 100;
  align-items: flex-start;
  justify-content: center;
  padding-top: 14vh;
}
.cmdk-overlay.show {
  display: flex;
}
.cmdk {
  width: 640px;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.7);
}
.cmdk-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--bd-2);
}
.cmdk-prompt {
  color: var(--orange);
  font-weight: 700;
  font-family: var(--ff-mn);
  font-size: 14px;
}
.cmdk-header input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--tx-1);
  font-size: 13px;
}
.cmdk-hint {
  font-size: 9px;
  padding: 2px 6px;
  background: var(--bg-active);
  color: var(--tx-3);
  border-radius: 2px;
  font-weight: 700;
}
.cmdk-list {
  max-height: 360px;
  overflow-y: auto;
  padding: 4px;
}
.cmdk-section {
  font-size: 9px;
  color: var(--tx-3);
  padding: 8px 10px 4px;
  letter-spacing: 0.5px;
  font-weight: 700;
}
.cmdk-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  border-radius: 2px;
  cursor: pointer;
  font-size: 11px;
}
.cmdk-item:hover,
.cmdk-item.active {
  background: var(--bg-hover);
}
.cmdk-item .it-l {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cmdk-item .it-tag {
  font-family: var(--ff-mn);
  font-size: 8px;
  padding: 1px 4px;
  border-radius: 2px;
  background: var(--bg-active);
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.cmdk-item .it-r {
  font-family: var(--ff-mn);
  font-size: 10px;
  color: var(--tx-2);
}
.cmdk-foot {
  display: flex;
  gap: 14px;
  padding: 6px 14px;
  border-top: 1px solid var(--bd-2);
  background: var(--bg-panel);
  font-size: 9px;
  color: var(--tx-3);
}
.cmdk-foot kbd {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 1px 4px;
  font-family: var(--ff-mn);
  font-size: 9px;
  color: var(--tx-2);
  margin-right: 4px;
}

/* =================================================================
   MODAL
   ================================================================= */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.78);
  /* Removed `backdrop-filter: blur(4px)` — every frame painted behind the
     modal had to be blurred (whole viewport, expensive on integrated
     GPUs). The bumped opacity (0.75 → 0.78) keeps the focus effect with
     no GPU work. Bot Studio open felt like a 60–120ms hitch on
     mid-range MacBooks because the blur ran on the same frame as the
     huge form/code-editor first paint. */
  display: none;
  z-index: 90;
  align-items: center;
  justify-content: center;
}
.modal-overlay.show {
  display: flex;
}
/* Hide the floating WhatsApp button (injected by wa-float.js as
   .wa-float-wrap) while a modal is open. The float is fixed bottom-right
   at a high z-index, so it otherwise sits on top of a modal's action
   buttons — e.g. the Bot Studio wizard's NEXT / DEPLOY on mobile. */
body:has(.modal-overlay.show) .wa-float-wrap {
  display: none;
}
.modal {
  width: 760px;
  max-width: 92vw;
  /* The previous `max-height: 740px` was static — in shorter viewports
     (preview panes, embedded webviews, landscape mobile) the modal could
     extend below the visible area, hiding the action footer. Switch to
     a vh-relative cap so the modal always fits with a 24px margin and
     the deploy/cancel buttons stay visible without inner scrolling. */
  height: calc(100vh - 48px);
  max-height: calc(100vh - 48px);
  background: var(--bg-panel);
  border: 1px solid var(--bd-3);
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.8);
  /* Promote the modal to its own compositing layer so the browser GPU-
     accelerates the open paint instead of repainting the whole viewport
     when display:none → display:flex flips. Pairs with the removal of
     backdrop-filter on the overlay above — together they take Bot
     Studio open from "noticeable hitch" to "instant". */
  will-change: transform;
  transform: translateZ(0);
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  border-bottom: 1px solid var(--bd-2);
  background: var(--bg-elevated);
}
.modal-title {
  font-weight: 800;
  font-size: 12px;
  color: var(--orange);
  letter-spacing: 0.6px;
}
.step-dots {
  display: flex;
  gap: 4px;
}
.step-dot {
  width: 26px;
  height: 3px;
  border-radius: 2px;
  background: var(--bd-2);
}
.step-dot.done {
  background: var(--up);
}
.step-dot.active {
  background: var(--orange);
}
.modal-x {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  font-size: 14px;
}
.modal-x:hover {
  color: var(--tx-1);
}

.modal-step {
  display: none;
  flex: 1;
  padding: 14px 16px;
  min-height: 0;
  overflow: auto;
}
.modal-step.active {
  display: flex;
  flex-direction: column;
}

/* The phone-required modal is a single short form. The base .modal is
   locked to full-viewport height for big multi-step modals (Bot Studio,
   auth) — applied here it leaves a huge empty gap below the form. Size
   this one to its content; max-height from .modal still caps it. */
#phone-required-modal .modal {
  height: auto;
}

.strat-name-input {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 8px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 13px;
  padding: 8px 10px;
  outline: 0;
  border-radius: 2px;
}
.strat-name-input:focus {
  border-color: var(--orange);
}
.strat-name-input::placeholder {
  color: var(--tx-3);
}
#paste-area {
  flex: 1;
  min-height: 220px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  line-height: 1.5;
  padding: 10px;
  resize: none;
  outline: 0;
  border-radius: 2px;
}
#paste-area:focus {
  border-color: var(--orange);
}
.paste-helper {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
}
.paste-helper .link {
  color: var(--ac);
  cursor: pointer;
}
.paste-helper .link:hover {
  text-decoration: underline;
}
#detect-format.detected {
  color: var(--up);
  font-weight: 700;
}

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  flex: 1;
  min-height: 0;
}
.split-left,
.split-right {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.split-h {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  margin-bottom: 4px;
}
.src {
  flex: 1;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 8px;
  font-family: var(--ff-mn);
  font-size: 10px;
  line-height: 1.5;
  color: var(--tx-2);
  overflow: auto;
  margin: 0;
}
.ds-graph {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  overflow: auto;
}
.ds-node {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 6px 8px;
}
.ds-node.warn {
  border-color: var(--warn);
}
.ds-k {
  font-size: 8px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 2px;
}
.ds-v {
  font-family: var(--ff-mn);
  font-size: 11px;
  color: var(--tx-1);
}
.confirm-pill {
  background: var(--warn);
  color: black;
  padding: 1px 4px;
  border-radius: 2px;
  font-size: 7px;
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 14px;
}
/* `.form-row` mirrors a label's layout but isn't a `<label>` element — used
   for sections that wrap multi-button widgets (segment picker, scrip chips)
   where a `<label>` wrapper triggers iOS Safari to forward taps to the
   first focusable descendant, breaking segment switching on iPhone. */
.form-grid label,
.form-grid .form-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
}
.form-grid label.full,
.form-grid .form-row.full {
  grid-column: span 2;
}
.form-grid input,
.form-grid select {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 5px 7px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 11px;
  outline: 0;
}
.form-grid input:focus,
.form-grid select:focus {
  border-color: var(--orange);
}

/* =================================================================
   CHIP-MULTISELECT INPUT (used for symbol pickers in bot/strategy
   forms). Replaces the old comma-separated text field with chips +
   typeahead so users tap suggestions instead of typing punctuation.
   ================================================================= */
.chip-input {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  padding: 4px 5px;
  border-radius: 2px;
  min-height: 26px;
  cursor: text;
}
.chip-input:focus-within {
  border-color: var(--orange);
}
.chip-input .chip-list {
  display: contents;
}
.chip-input .sym-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(20, 184, 166, 0.1);
  border: 1px solid rgba(20, 184, 166, 0.35);
  color: #5fe8d6;
  padding: 1px 4px 1px 7px;
  border-radius: 3px;
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  line-height: 1.4;
  user-select: none;
}
.chip-input .sym-chip-x {
  background: transparent;
  border: 0;
  color: rgba(95, 232, 214, 0.6);
  cursor: pointer;
  padding: 0 2px;
  font-size: 12px;
  line-height: 1;
  border-radius: 2px;
  transition:
    color 0.15s,
    background 0.15s;
}
.chip-input .sym-chip-x:hover {
  color: var(--down);
  background: rgba(242, 62, 85, 0.12);
}
.chip-input .chip-typer {
  flex: 1 1 80px;
  min-width: 80px;
  background: transparent !important;
  border: 0 !important;
  outline: 0;
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  padding: 2px 4px !important;
}
.chip-input .chip-typer::placeholder {
  color: var(--tx-3);
  font-style: italic;
  opacity: 0.7;
}
.chip-suggest {
  /* In normal flow (was position:absolute). Opening the symbol dropdown
     now pushes the fields below it down instead of overlaying them, so
     the engine config fields stay visible while picking symbols.
     initChipInput() inserts it as a sibling after the input. */
  margin-top: 4px;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-radius: 3px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  max-height: 220px;
  overflow-y: auto;
  display: none;
}
.chip-suggest.show {
  display: block;
}
.chip-suggest-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  gap: 10px;
  background: transparent;
  border: 0;
  padding: 6px 10px;
  cursor: pointer;
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  text-align: left;
  border-bottom: 1px solid var(--bd-1);
  transition: background 0.12s;
}
.chip-suggest-item:last-child {
  border-bottom: 0;
}
.chip-suggest-item:hover,
.chip-suggest-item.active {
  background: rgba(20, 184, 166, 0.1);
  color: #5fe8d6;
}
.chip-suggest-item .ci-sym {
  font-weight: 700;
  letter-spacing: 0.5px;
}
.chip-suggest-item .ci-mkt {
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
}
.chip-suggest-item .ci-px {
  font-size: 10px;
  color: var(--tx-2);
  font-variant-numeric: tabular-nums;
}
.chip-suggest-empty {
  padding: 8px 10px;
  color: var(--tx-3);
  font-size: 10px;
  font-style: italic;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}
/* "↻ Reload from Zerodha" — appears in the empty state when an
   Indian segment has no rows. Click force-refetches the instruments
   universe so the user can recover from a botched initial fetch
   without a full page reload. Amber accent matches the market pills
   so it reads as an actionable recovery button, not decoration. */
.chip-suggest-reload {
  background: rgba(242, 163, 65, 0.12);
  border: 1px solid rgba(242, 163, 65, 0.55);
  border-radius: 10px;
  padding: 4px 10px;
  color: #ffc36e;
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  font-style: normal;
  cursor: pointer;
  transition:
    background 0.12s,
    border-color 0.12s;
}
.chip-suggest-reload:hover:not(:disabled) {
  background: rgba(242, 163, 65, 0.22);
  border-color: rgba(242, 163, 65, 0.85);
}
.chip-suggest-reload:disabled {
  opacity: 0.6;
  cursor: wait;
}
.chip-suggest-hint {
  padding: 4px 10px;
  background: var(--bg-base);
  color: var(--tx-3);
  font-size: 8px;
  letter-spacing: 0.5px;
  font-weight: 700;
  border-bottom: 1px solid var(--bd-1);
  text-transform: uppercase;
}
/* Market filter pills — top-level row in the suggestion dropdown.
   Amber accent so they read as the primary filter; segments below
   are teal/secondary. Both rows are sticky so they stay visible while
   the user scrolls the symbol list. */
.chip-suggest-markets {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 6px 8px;
  background: var(--bg-base);
  border-bottom: 1px solid var(--bd-1);
  position: sticky;
  top: 0;
  z-index: 2;
}
.chip-suggest-mkt {
  background: transparent;
  border: 1px solid var(--bd-2);
  border-radius: 12px;
  padding: 3px 9px;
  color: var(--tx-2);
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background 0.12s,
    border-color 0.12s,
    color 0.12s;
}
.chip-suggest-mkt:hover {
  border-color: rgba(242, 163, 65, 0.55);
  color: var(--orange);
}
.chip-suggest-mkt.active {
  background: rgba(242, 163, 65, 0.18);
  border-color: rgba(242, 163, 65, 0.85);
  color: #ffc36e;
}

/* Segment filter pills — second row, only visible when market = "All".
   Sticky so the user can switch category mid-scroll without losing
   the filter row. Compact rounded pills match the input language. */
.chip-suggest-segments {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 6px 8px;
  background: var(--bg-base);
  border-bottom: 1px solid var(--bd-1);
  /* Sit just below the market row when both are sticky. ~36px = market
     row height (padding + pill height). Small enough that a 1px overlap
     doesn't matter; large enough that the segment row never tucks under. */
  position: sticky;
  top: 36px;
  z-index: 1;
}
.chip-suggest-seg {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 1px solid var(--bd-2);
  border-radius: 12px;
  padding: 3px 9px;
  color: var(--tx-2);
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background 0.12s,
    border-color 0.12s,
    color 0.12s;
}
.chip-suggest-seg .cs-icon {
  font-size: 10px;
  opacity: 0.85;
  font-family: var(--ff-mn);
}
.chip-suggest-seg:hover {
  border-color: rgba(20, 184, 166, 0.55);
  color: #5fe8d6;
}
.chip-suggest-seg.active {
  background: rgba(20, 184, 166, 0.18);
  border-color: rgba(20, 184, 166, 0.8);
  color: #7df0e0;
}

/* Always-visible category strip beneath the chip-input. Lets users
   browse "Indian Equity / Indian Options / Crypto / etc." without
   having to focus the typer to surface the in-dropdown filter row. */
.chip-cats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 6px 0 2px;
  margin-top: 2px;
}
.chip-cat {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 1px solid var(--bd-2);
  border-radius: 12px;
  padding: 3px 9px;
  color: var(--tx-2);
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background 0.12s,
    border-color 0.12s,
    color 0.12s;
}
.chip-cat .cs-icon {
  font-size: 10px;
  opacity: 0.85;
  font-family: var(--ff-mn);
}
.chip-cat:hover {
  border-color: rgba(20, 184, 166, 0.55);
  color: #5fe8d6;
}
.chip-cat.active {
  background: rgba(20, 184, 166, 0.18);
  border-color: rgba(20, 184, 166, 0.8);
  color: #7df0e0;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.chip {
  display: flex;
  align-items: center;
  gap: 4px;
  background: var(--bg-elevated);
  padding: 3px 6px;
  border-radius: 2px;
  border: 1px solid var(--bd-2);
  font-size: 9px;
  cursor: pointer;
  letter-spacing: 0.3px;
  font-weight: 700;
}
.chip input {
  accent-color: var(--orange);
}

.dry-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
.dry-stat {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  padding: 6px 8px;
  border-radius: 2px;
}
.dry-k {
  font-size: 8px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.dry-v {
  font-size: 14px;
  font-weight: 700;
  margin-top: 2px;
}
.dry-chart-wrap {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  height: 180px;
  overflow: hidden;
  margin-bottom: 10px;
}
.dry-chart-wrap canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.dry-banner {
  padding: 8px 12px;
  border-radius: 2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
}
.dry-banner.ok {
  background: var(--up-bg);
  color: var(--up);
  border: 1px solid rgba(31, 203, 107, 0.3);
}
.dry-banner.warn {
  background: rgba(242, 163, 65, 0.1);
  color: var(--warn);
  border: 1px solid rgba(242, 163, 65, 0.3);
}
.dry-banner.run {
  background: rgba(58, 130, 246, 0.1);
  color: var(--ac);
  border: 1px solid rgba(58, 130, 246, 0.3);
}

.final-summary {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 14px;
}
.fs-h {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  margin-bottom: 10px;
}
.fs-row {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  border-bottom: 1px dashed var(--bd-2);
  font-size: 11px;
}
.fs-row span:first-child {
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.3px;
  font-size: 9px;
}
.fs-row:last-of-type {
  border-bottom: 0;
}
.paused-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  font-size: 10px;
  color: var(--tx-2);
  cursor: pointer;
  font-weight: 700;
  letter-spacing: 0.3px;
}

.modal-foot {
  display: flex;
  justify-content: space-between;
  padding: 10px 16px;
  border-top: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  /* Belt-and-suspenders: never shrink below natural height so the
     deploy/cancel buttons stay visible even when the body is tall. */
  flex-shrink: 0;
  position: relative;
  z-index: 2;
}
.ghost-btn {
  background: transparent;
  border: 1px solid var(--bd-2);
  color: var(--tx-2);
  border-radius: 2px;
  padding: 4px 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
}
.ghost-btn:hover {
  color: var(--tx-1);
  border-color: var(--bd-3);
}

/* =================================================================
   ALERTS MODAL — F6 / ALERTS top-nav tab
   Notification center: configure Telegram / WhatsApp / Email and
   pick which event types to forward.
   ================================================================= */
.modal.modal-wide {
  width: 920px;
}
.al-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 0;
}
.al-col {
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  background: var(--bg-base);
}
.al-col-channels {
  border-right: 1px solid var(--bd-2);
}
.al-section-h {
  padding: 10px 14px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.7px;
  color: var(--tx-2);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.al-section-h .al-h-hint {
  font-size: 9px;
  font-weight: 600;
  color: var(--tx-3);
  letter-spacing: 0.3px;
  text-transform: none;
}
.al-section-h .al-h-btn {
  background: transparent;
  border: 1px solid var(--bd-2);
  color: var(--tx-3);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 3px 8px;
  border-radius: 2px;
  cursor: pointer;
}
.al-section-h .al-h-btn:hover {
  color: var(--down);
  border-color: var(--down);
}

/* === CHANNEL CARDS === */
.al-channel {
  border-bottom: 1px solid var(--bd-1);
}
.al-channel.al-disabled .al-ch-body {
  display: none;
}
.al-ch-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  cursor: pointer;
  user-select: none;
  transition: background 0.12s;
}
.al-ch-head:hover {
  background: rgba(255, 255, 255, 0.02);
}
.al-ch-icon {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: 800;
  flex-shrink: 0;
  border: 1px solid;
}
/* Telegram channel icon — uses the inline SVG brand logo.
   Strip the chip background/border the WA + EM icons rely on,
   since the SVG already carries the blue circle itself. */
.al-ch-icon.tg {
  background: transparent;
  border: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.al-ch-icon.wa {
  background: rgba(37, 211, 102, 0.1);
  color: #5fe89c;
  border-color: rgba(37, 211, 102, 0.3);
}
.al-ch-icon.em {
  background: rgba(167, 139, 250, 0.1);
  color: #a78bfa;
  border-color: rgba(167, 139, 250, 0.3);
}
.al-ch-meta {
  flex: 1;
  min-width: 0;
}
.al-ch-name {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--tx-1);
}
.al-ch-status {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
  margin-top: 2px;
  font-family: var(--ff-mn);
}
.al-ch-status.ok {
  color: var(--up);
}
.al-ch-status.warn {
  color: var(--warn);
}

/* Toggle switch (iOS style) */
.al-toggle {
  position: relative;
  flex-shrink: 0;
}
.al-toggle input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.al-toggle-slider {
  display: block;
  width: 36px;
  height: 20px;
  background: var(--bd-3);
  border-radius: 20px;
  cursor: pointer;
  transition: background 0.15s;
  position: relative;
}
.al-toggle-slider::after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  background: var(--tx-1);
  border-radius: 50%;
  top: 2px;
  left: 2px;
  transition:
    transform 0.15s,
    background 0.15s;
}
.al-toggle input:checked + .al-toggle-slider {
  background: var(--teal);
}
.al-toggle input:checked + .al-toggle-slider::after {
  transform: translateX(16px);
  background: #0d1421;
}

/* Channel body (config fields) */
.al-ch-body {
  padding: 10px 14px 14px 14px;
  background: rgba(0, 0, 0, 0.18);
  border-top: 1px solid var(--bd-1);
}
.al-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 8px;
  font-size: 9px;
  font-weight: 700;
  color: var(--tx-3);
  letter-spacing: 0.4px;
}
.al-field input {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  padding: 6px 8px;
  outline: 0;
}
.al-field input:focus {
  border-color: var(--orange);
}
.al-field .al-select,
.al-select {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  padding: 6px 8px;
  outline: 0;
  cursor: pointer;
}
.al-select:focus {
  border-color: var(--orange);
}
/* Country code dropdown + local number input — flex row inside one
   .al-field. The country select is fixed-width, the input fills. */
.al-phone-row {
  display: flex;
  align-items: stretch;
  gap: 6px;
}
.al-phone-row .al-cc-select {
  flex: 0 0 auto;
  width: 130px;
  font-size: 11px;
  padding: 6px 6px;
  text-overflow: ellipsis;
}
.al-phone-row input {
  flex: 1;
  min-width: 0;
}
.al-field-hint {
  display: block;
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 500;
  letter-spacing: 0.2px;
  margin-top: 4px;
  font-style: italic;
}
/* WhatsApp managed mode is the only customer-facing path; the BYO
   AiSensy / webhook hints are not shown anymore. The managed hint
   uses a friendly teal accent since it's the default success path. */
.al-hint.al-wa-hint-aisensy,
.al-hint.al-wa-hint-webhook {
  display: none !important;
}
.al-hint.al-wa-hint-managed {
  background: rgba(20, 184, 166, 0.1);
  border-color: rgba(20, 184, 166, 0.35);
  color: #b9e8df;
}
.al-hint.al-wa-hint-managed b {
  color: #5fe8d6;
}
.al-hint {
  font-size: 9px;
  color: var(--tx-3);
  line-height: 1.5;
  font-weight: 500;
  letter-spacing: 0.2px;
  margin-top: 8px;
  padding: 7px 9px;
  background: rgba(20, 184, 166, 0.04);
  border: 1px solid rgba(20, 184, 166, 0.15);
  border-radius: 2px;
}
.al-hint code {
  background: rgba(255, 255, 255, 0.06);
  padding: 1px 4px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 9px;
  color: #5fe8d6;
}
.al-ch-body .ghost-btn.full {
  width: 100%;
  padding: 8px 10px;
  font-size: 10px;
  margin-top: 4px;
}

/* === ALERT TYPES (right column) === */
.al-types {
  padding: 8px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-bottom: 1px solid var(--bd-2);
}
.al-type {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 3px;
  cursor: pointer;
  border: 1px solid transparent;
  transition:
    background 0.1s,
    border-color 0.1s;
}
.al-type:hover {
  background: rgba(255, 255, 255, 0.02);
}
.al-type input[type="checkbox"] {
  flex-shrink: 0;
  margin-top: 2px;
  accent-color: var(--teal);
  width: 14px;
  height: 14px;
}
.al-type-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.al-type-label b {
  font-size: 11px;
  font-weight: 800;
  color: var(--tx-1);
  letter-spacing: 0.3px;
}
.al-type-label b .mono {
  color: var(--tx-3);
  font-weight: 600;
  font-size: 9px;
}
.al-type-label span {
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.2px;
}
.al-type input[type="checkbox"]:checked ~ .al-type-label b {
  color: #5fe8d6;
}

/* === RECENT ALERTS LOG === */
.al-log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 0;
}
.al-log-empty {
  padding: 16px 14px;
  font-size: 10px;
  color: var(--tx-3);
  font-style: italic;
  line-height: 1.5;
  text-align: center;
}
.al-log-row {
  display: grid;
  grid-template-columns: 56px 70px 1fr;
  gap: 8px;
  padding: 6px 14px;
  border-bottom: 1px solid var(--bd-1);
  font-size: 10px;
  align-items: start;
}
.al-log-row:hover {
  background: rgba(255, 255, 255, 0.02);
}
.al-log-row.al-log-failed {
  background: rgba(242, 62, 85, 0.06);
  border-left: 2px solid var(--down);
  padding-left: 12px;
}
.al-log-row.al-log-failed .al-log-msg {
  color: #ffb6c1;
}
.al-log-time {
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-size: 9px;
  letter-spacing: 0.2px;
  padding-top: 1px;
}
.al-log-type {
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 2px 5px;
  border-radius: 2px;
  text-align: center;
  height: fit-content;
  background: var(--bg-elevated);
  color: var(--tx-2);
  border: 1px solid var(--bd-2);
}
.al-log-type.deploy {
  background: rgba(20, 184, 166, 0.1);
  color: #5fe8d6;
  border-color: rgba(20, 184, 166, 0.3);
}
.al-log-type.kill {
  background: rgba(242, 62, 85, 0.1);
  color: var(--down);
  border-color: rgba(242, 62, 85, 0.3);
}
.al-log-type.dailyloss,
.al-log-type.dailyLoss {
  background: rgba(242, 163, 65, 0.1);
  color: var(--warn);
  border-color: rgba(242, 163, 65, 0.3);
}
.al-log-type.bigpnl,
.al-log-type.bigPnl {
  background: rgba(31, 203, 107, 0.1);
  color: var(--up);
  border-color: rgba(31, 203, 107, 0.3);
}
.al-log-type.error {
  background: rgba(242, 62, 85, 0.1);
  color: var(--down);
  border-color: rgba(242, 62, 85, 0.3);
}
.al-log-type.signal {
  background: rgba(58, 130, 246, 0.1);
  color: var(--ac);
  border-color: rgba(58, 130, 246, 0.3);
}
.al-log-type.test {
  background: rgba(167, 139, 250, 0.1);
  color: var(--purple);
  border-color: rgba(167, 139, 250, 0.3);
}
.al-log-msg {
  color: var(--tx-1);
  line-height: 1.4;
  word-break: break-word;
}
.al-log-msg b {
  color: var(--tx-1);
  font-weight: 700;
}
.al-log-msg .al-log-channels {
  display: inline-flex;
  gap: 4px;
  margin-left: 6px;
}
.al-log-msg .al-log-ch {
  font-size: 8px;
  padding: 1px 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
  font-family: var(--ff-mn);
}
.al-log-msg .al-log-ch.tg {
  color: #58b4e8;
  background: rgba(34, 158, 217, 0.1);
}
.al-log-msg .al-log-ch.wa {
  color: #5fe89c;
  background: rgba(37, 211, 102, 0.1);
}
.al-log-msg .al-log-ch.em {
  color: #a78bfa;
  background: rgba(167, 139, 250, 0.1);
}

/* Title-row layout — bold action sits on its own line above the body
   so the channel chips don't fight with the WHY callout below. */
.al-log-msg .al-log-title-line {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.al-log-msg .al-log-body-head {
  color: var(--tx-2);
  font-size: 11px;
  line-height: 1.45;
}
/* WHY callout — visually distinct so the user instantly sees the
   trigger rule and learns from it. Yellow accent reads as
   "explanation / hint" rather than "warning". */
.al-log-msg .al-log-why {
  margin-top: 4px;
  padding: 4px 8px;
  background: rgba(245, 158, 11, 0.08);
  border-left: 2px solid rgba(245, 158, 11, 0.55);
  border-radius: 2px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--tx-1);
}
.al-log-msg .al-log-why-label {
  display: inline-block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--orange);
  background: rgba(245, 158, 11, 0.12);
  padding: 1px 5px;
  border-radius: 2px;
  margin-right: 6px;
  vertical-align: 1px;
  font-family: var(--ff-mn);
}

/* Mobile — stack channels above events */
@media (max-width: 640px) {
  .modal.modal-wide {
    width: 100%;
  }
  .al-body {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    overflow-y: auto;
  }
  .al-col {
    overflow-y: visible;
  }
  .al-col-channels {
    border-right: 0;
    border-bottom: 1px solid var(--bd-2);
  }
  .al-log {
    max-height: 240px;
  }
}

/* =================================================================
   BROKER INTEGRATIONS MODAL (#brokers-modal)
   ================================================================= */
.brokers-modal {
  max-width: 920px;
}
.brokers-modal .br-modal-title {
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
}
.brokers-modal .br-modal-title-main {
  font-size: 12px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: 0.6px;
}
.brokers-modal .br-modal-title-sub {
  font-size: 10px;
  font-weight: 500;
  color: var(--tx-3);
  letter-spacing: 0.2px;
  text-transform: none;
  line-height: 1.35;
  max-width: 520px;
}

.brokers-modal .br-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(240px, 300px) minmax(0, 1fr);
  gap: 0;
  background: var(--bg-base);
}

.brokers-modal .br-aside {
  padding: 18px 16px;
  border-right: 1px solid var(--bd-2);
  background:
    radial-gradient(
      ellipse at top left,
      rgba(255, 111, 0, 0.06) 0%,
      transparent 55%
    ),
    var(--bg-panel);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.brokers-modal .br-aside-h {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.7px;
  color: var(--tx-2);
  text-transform: uppercase;
}
.brokers-modal .br-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.brokers-modal .br-steps li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 11px;
  line-height: 1.45;
  color: var(--tx-2);
}
.brokers-modal .br-step-n {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 111, 0, 0.12);
  border: 1px solid rgba(255, 152, 0, 0.35);
  color: #ffb04b;
  font-size: 11px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--ff-mn);
}
.brokers-modal .br-steps b {
  display: block;
  color: var(--tx-1);
  font-size: 11px;
  margin-bottom: 2px;
}
.brokers-modal .br-steps code {
  font-family: var(--ff-mn);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.06);
  padding: 1px 4px;
  border-radius: 2px;
  color: #ffb04b;
}

.brokers-modal .br-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.brokers-modal .br-badge {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.3px;
  padding: 4px 8px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--bd-2);
  color: var(--tx-2);
}

.brokers-modal .br-aside-note {
  font-size: 10px;
  line-height: 1.5;
  color: var(--tx-3);
  padding: 10px 12px;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
}
.brokers-modal .br-aside-note b {
  color: var(--tx-2);
}

.brokers-modal .br-aside-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: auto;
  padding: 8px 12px;
  background: rgba(255, 111, 0, 0.12);
  border: 1px solid rgba(255, 152, 0, 0.35);
  border-radius: 6px;
  color: #ffb04b;
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
  transition:
    background 0.12s,
    border-color 0.12s;
}
.brokers-modal .br-aside-link:hover {
  background: rgba(255, 111, 0, 0.2);
  border-color: rgba(255, 152, 0, 0.55);
}

.brokers-modal .br-main {
  min-width: 0;
  overflow-y: auto;
  padding: 16px;
}

.brokers-modal .br-card {
  border: 1px solid var(--bd-2);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-panel);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25);
}
.brokers-modal .br-card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: linear-gradient(180deg, rgba(255, 111, 0, 0.06), transparent);
  border-bottom: 1px solid var(--bd-2);
}
.brokers-modal .al-ch-icon.zr {
  width: 40px;
  height: 40px;
  background: linear-gradient(135deg, #ff6f00, #ff9800);
  color: #fff;
  font-weight: 800;
  font-size: 15px;
  border: 0;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(255, 111, 0, 0.35);
}
.brokers-modal .br-card-tag {
  margin-left: auto;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 3px 8px;
  border-radius: 20px;
  background: rgba(31, 203, 107, 0.12);
  border: 1px solid rgba(31, 203, 107, 0.3);
  color: var(--up);
  flex-shrink: 0;
}
.brokers-modal .br-card-body {
  padding: 16px !important;
  background: var(--bg-base) !important;
  border-top: 0 !important;
}

.brokers-modal .br-callout {
  padding: 12px 14px;
  margin-bottom: 16px;
  border-radius: 8px;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.22);
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-2);
}
.brokers-modal .br-callout-title {
  font-weight: 800;
  color: var(--tx-1);
  font-size: 12px;
  margin-bottom: 6px;
}
.brokers-modal .br-callout p {
  margin: 0 0 8px;
}
.brokers-modal .br-callout-meta {
  font-size: 10px;
  color: var(--tx-3);
  padding-top: 8px;
  border-top: 1px dashed rgba(245, 158, 11, 0.2);
}
.brokers-modal .br-callout code {
  font-family: var(--ff-mn);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.06);
  padding: 1px 5px;
  border-radius: 3px;
  color: #ffb04b;
}

.brokers-modal .br-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 12px;
  margin-bottom: 4px;
}
.brokers-modal .br-field-wide {
  grid-column: 1 / -1;
}
.brokers-modal .br-upper {
  text-transform: uppercase;
}
.brokers-modal .al-field input {
  border-radius: 4px;
  padding: 8px 10px;
  transition:
    border-color 0.12s,
    box-shadow 0.12s;
}
.brokers-modal .al-field input:focus {
  border-color: rgba(255, 152, 0, 0.6);
  box-shadow: 0 0 0 2px rgba(255, 152, 0, 0.12);
}

.brokers-modal .br-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}
.brokers-modal .br-connect-btn {
  padding: 10px 16px !important;
  font-size: 11px !important;
  background: linear-gradient(135deg, #ff6f00, #ff9800) !important;
  border-radius: 6px !important;
  letter-spacing: 0.4px;
}
.brokers-modal .br-connect-btn:hover {
  filter: brightness(1.08);
  box-shadow: 0 4px 14px rgba(255, 111, 0, 0.35);
}

.brokers-modal .br-manual {
  margin-top: 12px;
  border: 1px dashed var(--bd-2);
  border-radius: 6px;
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.02);
}
.brokers-modal .br-manual summary {
  cursor: pointer;
  font-size: 10px;
  font-weight: 600;
  color: var(--tx-3);
  user-select: none;
  list-style: none;
}
.brokers-modal .br-manual summary::-webkit-details-marker {
  display: none;
}
.brokers-modal .br-manual summary::before {
  content: "▸ ";
  color: var(--tx-3);
}
.brokers-modal .br-manual[open] summary::before {
  content: "▾ ";
}
.brokers-modal .br-manual-body {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.brokers-modal .br-msg {
  margin-top: 10px;
  padding: 10px 12px;
  border-radius: 6px;
  font-size: 11px;
  line-height: 1.4;
  border: 1px solid transparent;
}
.brokers-modal .br-msg.br-msg-ok {
  background: rgba(34, 197, 94, 0.12);
  color: #22c55e;
  border-color: rgba(34, 197, 94, 0.25);
}
.brokers-modal .br-msg.br-msg-err {
  background: rgba(239, 68, 68, 0.12);
  color: #ef4444;
  border-color: rgba(239, 68, 68, 0.25);
}
.brokers-modal .br-msg.br-msg-info {
  background: rgba(245, 158, 11, 0.12);
  color: #f59e0b;
  border-color: rgba(245, 158, 11, 0.25);
}

.brokers-modal .br-inst-panel {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--bd-2);
}
.brokers-modal .br-inst-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.brokers-modal .br-inst-title {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--tx-2);
  text-transform: uppercase;
}
.brokers-modal .br-inst-refresh {
  margin-left: auto;
  padding: 4px 10px !important;
  font-size: 10px !important;
}
.brokers-modal .br-inst-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}
.brokers-modal .br-stat-pill {
  font-family: var(--ff-mn);
  font-size: 11px;
  font-weight: 700;
  padding: 5px 12px;
  border-radius: 20px;
  border: 1px solid;
}
.brokers-modal .br-stat-pill.eq {
  background: rgba(99, 179, 237, 0.12);
  color: #63b3ed;
  border-color: rgba(99, 179, 237, 0.25);
}
.brokers-modal .br-stat-pill.fut {
  background: rgba(167, 139, 250, 0.12);
  color: #a78bfa;
  border-color: rgba(167, 139, 250, 0.25);
}
.brokers-modal .br-stat-pill.opt {
  background: rgba(245, 158, 11, 0.12);
  color: #f59e0b;
  border-color: rgba(245, 158, 11, 0.25);
}

.brokers-modal .br-inst-sub {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--tx-3);
  margin-bottom: 6px;
  text-transform: uppercase;
}
.brokers-modal .br-opt-preview {
  max-height: 220px;
  overflow-y: auto;
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  background: var(--bg-elevated);
  -webkit-overflow-scrolling: touch;
}
.brokers-modal .br-opt-empty {
  padding: 16px 12px;
  text-align: center;
  font-size: 11px;
  color: var(--tx-3);
  line-height: 1.45;
}

.brokers-modal .br-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.brokers-modal .br-foot-note {
  font-size: 10px;
  color: var(--tx-3);
  line-height: 1.4;
}

@media (max-width: 720px) {
  .brokers-modal .br-body {
    grid-template-columns: 1fr;
    overflow-y: auto;
  }
  .brokers-modal .br-aside {
    border-right: 0;
    border-bottom: 1px solid var(--bd-2);
    padding: 14px 12px;
  }
  .brokers-modal .br-aside-link {
    margin-top: 0;
  }
  .brokers-modal .br-main {
    padding: 12px;
  }
  .brokers-modal .br-form-grid {
    grid-template-columns: 1fr;
  }
  .brokers-modal .br-modal-title-sub {
    max-width: none;
  }
}

.primary-btn {
  background: var(--ac);
  border: 0;
  color: white;
  padding: 5px 14px;
  border-radius: 2px;
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.5px;
}
.primary-btn:hover {
  background: var(--ac-d);
}
.primary-btn.activate {
  background: var(--up);
  padding: 6px 18px;
  font-size: 11px;
}
.primary-btn.activate:hover {
  background: #15a35a;
}

/* =================================================================
   TOASTS
   ================================================================= */
.toast-stack {
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  pointer-events: none;
}
.toast {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-left: 3px solid var(--ac);
  border-radius: 2px;
  padding: 6px 10px;
  font-size: 10px;
  min-width: 240px;
  max-width: 320px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
  animation: toast-in 0.2s ease-out;
}
.toast.up {
  border-left-color: var(--up);
}
.toast.down {
  border-left-color: var(--down);
}
.toast.warn {
  border-left-color: var(--warn);
}
.toast-title {
  font-weight: 800;
  font-size: 10px;
  letter-spacing: 0.4px;
}
.toast-sub {
  color: var(--tx-3);
  font-size: 9px;
  margin-top: 1px;
  font-family: var(--ff-mn);
  line-height: 1.45;
}
.toast-sub .toast-why-label {
  display: inline-block;
  background: rgba(245, 158, 11, 0.15);
  color: var(--orange);
  font-weight: 800;
  font-size: 8px;
  padding: 1px 4px;
  border-radius: 2px;
  margin-right: 4px;
  letter-spacing: 0.5px;
}
@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* scrollbar */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--bd-2);
  border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--bd-3);
}

/* led dot mini */
.led-mini {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  margin-right: 4px;
}
.led-mini.ok {
  background: var(--up);
  box-shadow: 0 0 4px var(--up);
  animation: sb-pulse 2s infinite;
}

/* =================================================================
   KILL ALL — header button + persistent banner
   ================================================================= */
.kill-all-btn {
  background: linear-gradient(180deg, #2a0a10, #1a0509);
  border: 1px solid var(--down);
  color: var(--down);
  font-weight: 800;
  font-size: 9px;
  letter-spacing: 0.6px;
  padding: 0 10px;
  height: 22px;
  margin: 0 8px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  align-self: center;
  text-shadow: 0 0 8px rgba(242, 62, 85, 0.4);
  transition: all 0.15s;
}
.kill-all-btn:hover {
  background: var(--down);
  color: white;
  box-shadow: 0 0 10px rgba(242, 62, 85, 0.6);
}

/* DELETE button — sits next to KILL but visually heavier (this is
   permanent removal, not just a stop). Slate/charcoal with a hint of
   red on hover so the destruction nature is unambiguous. */
.delete-btn {
  background: transparent;
  border: 1px solid var(--bd-3);
  color: var(--tx-3);
  font-weight: 800;
  font-size: 9px;
  letter-spacing: 0.6px;
  padding: 0 10px;
  height: 22px;
  margin: 0 0 0 4px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  align-self: center;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s,
    border-color 0.15s,
    box-shadow 0.15s;
}
.delete-btn:hover {
  background: rgba(239, 68, 68, 0.15);
  border-color: var(--down);
  color: #fca5a5;
  box-shadow: 0 0 12px rgba(239, 68, 68, 0.25);
}
@media (max-width: 600px) {
  .delete-btn {
    padding: 5px 8px !important;
    font-size: 9px !important;
  }
}

.kill-banner {
  background: linear-gradient(180deg, #2a0a10, #1a0509);
  border-bottom: 1px solid var(--down);
  color: var(--down);
  font-family: var(--ff-mn);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 14px;
  animation: kill-pulse 2s infinite;
}
.kill-banner.hidden {
  display: none;
}
.kill-banner b {
  font-weight: 800;
  margin-right: 8px;
  text-shadow: 0 0 6px rgba(242, 62, 85, 0.6);
}
.kb-clear {
  background: transparent;
  border: 1px solid var(--down);
  color: var(--down);
  padding: 2px 10px;
  border-radius: 2px;
  font-weight: 700;
  font-size: 9px;
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
}
.kb-clear:hover {
  background: var(--down);
  color: white;
}
@keyframes kill-pulse {
  0%,
  100% {
    background: linear-gradient(180deg, #2a0a10, #1a0509);
  }
  50% {
    background: linear-gradient(180deg, #3a0d14, #220609);
  }
}

/* per-strategy KILL chip in strat card */
.strat-card {
  grid-template-columns: 8px 1fr auto auto !important;
}
.sc-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: 4px;
}
.sc-kill {
  background: transparent;
  border: 1px solid #4a1620;
  color: #c93a4a;
  padding: 0 4px;
  height: 16px;
  border-radius: 2px;
  font-weight: 800;
  font-size: 8px;
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
}
.sc-kill:hover {
  background: var(--down);
  color: white;
  border-color: var(--down);
}
.sc-pause,
.sc-edit {
  background: transparent;
  border: 1px solid var(--bd-2);
  color: var(--tx-2);
  padding: 0 4px;
  height: 16px;
  border-radius: 2px;
  font-weight: 800;
  font-size: 9px;
  font-family: var(--ff-mn);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sc-pause:hover,
.sc-edit:hover {
  color: var(--orange);
  border-color: var(--orange);
  background: rgba(242, 163, 65, 0.1);
}
.strat-card .dot.killed {
  background: #555;
  opacity: 0.5;
}

/* live P&L bar inside strat card */
.sc-pnl-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--bd-2);
  overflow: hidden;
}
.sc-pnl-bar > i {
  position: absolute;
  top: 0;
  bottom: 0;
  display: block;
  background: var(--up);
}
.sc-pnl-bar > i.down {
  background: var(--down);
}
.strat-card {
  position: relative;
}

/* =================================================================
   SEGMENT PICKER + PILL
   ================================================================= */
.seg-pick {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
}
.seg-pick button {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  color: var(--tx-2);
  padding: 4px 10px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  cursor: pointer;
}
.seg-pick button:hover {
  color: var(--tx-1);
  border-color: var(--bd-3);
}
.seg-pick button.active {
  /* color is set inline so each segment picks its own theme color */
  border-color: currentColor;
  background: rgba(255, 255, 255, 0.04);
  box-shadow: inset 0 0 0 1px currentColor;
}
.seg-hint {
  margin-top: 4px;
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
}

/* Segment pill — used on hero cards / detail page / side rail */
.seg-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: var(--ff-mn);
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  border-radius: 2px;
  border: 1px solid currentColor;
  background: rgba(255, 255, 255, 0.03);
  vertical-align: middle;
  white-space: nowrap;
}

/* Market-hours pill — surfaces when a running strategy/bot's market is
   currently closed. Same shape as .seg-pill but amber so it reads as a
   "waiting" / "warning" state, not a hard error. */
.mkt-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: var(--ff-mn);
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 1px 5px;
  border-radius: 2px;
  vertical-align: middle;
  white-space: nowrap;
  margin-left: 4px;
  cursor: help;
}
.mkt-pill.closed {
  color: #f2a341;
  border: 1px solid #f2a341;
  background: rgba(242, 163, 65, 0.08);
}
.mkt-pill.closed::before {
  content: "● ";
  color: #f2a341;
  margin-right: 1px;
}

/* =================================================================
   SCRIP SEARCH — search any symbol via Binance + Yahoo
   ================================================================= */
.sym-search-wrap {
  position: relative;
  margin-bottom: 6px;
}
.sym-search-wrap input {
  width: 100%;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 7px 10px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 11px;
  outline: 0;
}
.sym-search-wrap input:focus {
  border-color: var(--orange);
  box-shadow: 0 0 6px rgba(242, 163, 65, 0.3);
}
.sym-search-wrap input::placeholder {
  color: var(--tx-4);
}
.sym-search-results {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 5;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-radius: 2px;
  max-height: 280px;
  overflow-y: auto;
  display: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.sym-search-results.show {
  display: block;
}
.ssr-loading {
  padding: 10px;
  font-size: 10px;
  color: var(--tx-3);
  text-align: center;
}
.ssr-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  border-bottom: 1px solid var(--bd-1);
  cursor: pointer;
  font-family: var(--ff-mn);
}
.ssr-item:last-child {
  border-bottom: 0;
}
.ssr-item:hover {
  background: var(--bg-hover);
}
.ssr-l {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.ssr-sym {
  font-weight: 800;
  font-size: 11px;
  color: var(--tx-1);
}
.ssr-name {
  font-size: 9px;
  color: var(--tx-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 220px;
}
.ssr-r {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.ssr-mkt {
  font-size: 8px;
  color: var(--tx-3);
  padding: 1px 4px;
  background: var(--bg-active);
  border-radius: 2px;
  font-weight: 700;
  letter-spacing: 0.4px;
}
.ssr-src {
  font-size: 8px;
  padding: 1px 4px;
  border-radius: 2px;
  font-weight: 800;
  letter-spacing: 0.4px;
}
.ssr-src.crypto {
  background: rgba(242, 163, 65, 0.2);
  color: var(--orange);
}
.ssr-src.stock {
  background: rgba(58, 130, 246, 0.2);
  color: var(--ac);
}
/* Indian markets — surfaced via Zerodha BYOK connection. NSE = cash
   equity (Yahoo .NS feed), NFO_FUT/OPT = futures + options scrips. */
.ssr-src.nse {
  background: rgba(34, 197, 94, 0.2);
  color: var(--up);
}
.ssr-src.fno-fut {
  background: rgba(168, 85, 247, 0.2);
  color: #c084fc;
}
.ssr-src.fno-opt {
  background: rgba(245, 158, 11, 0.2);
  color: var(--orange);
}
.ssr-loaded {
  font-size: 8px;
  padding: 1px 4px;
  border-radius: 2px;
  font-weight: 800;
  letter-spacing: 0.4px;
  background: var(--up-bg);
  color: var(--up);
}
/* Multi-select feedback — when a row in the search dropdown has just
   been clicked + added to the chip strip, dim it slightly and show
   the green ✓ ADDED pill so the user can see at a glance which
   strikes/expiries they've already picked. Especially useful for
   F&O option chains where 5+ strikes of the same underlying are
   often added in one session. */
.ssr-item.ssr-added {
  background: var(--up-bg);
}
.ssr-item.ssr-added .ssr-sym {
  color: var(--up);
}
.ssr-item.ssr-added:hover {
  background: var(--up-bg);
  opacity: 0.85;
}

/* =================================================================
   CHIP MULTI-SELECT — grouped by market, all scrips visible
   ================================================================= */
.chip-multi {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 240px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  background: var(--bg-base);
}
.chip-group {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.chip-group-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  padding: 2px 2px 0;
}
.chip-select-all {
  background: transparent;
  border: 0;
  color: var(--ac);
  cursor: pointer;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
  padding: 0;
}
.chip-select-all:hover {
  color: var(--orange);
}
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
}
.chip-multi .chip {
  cursor: pointer;
  background: var(--bg-elevated);
  padding: 3px 7px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
  font-family: var(--ff-mn);
  color: var(--tx-2);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  transition: all 0.1s;
  user-select: none;
}
.chip-multi .chip:hover {
  color: var(--tx-1);
  border-color: var(--bd-3);
}
.chip-multi .chip.selected {
  background: var(--orange);
  color: black;
  border-color: var(--orange);
  text-shadow: none;
}
.chip-summary {
  margin-top: 4px;
  padding: 4px 8px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--warn);
  background: rgba(242, 163, 65, 0.1);
  border: 1px solid rgba(242, 163, 65, 0.3);
  border-radius: 2px;
  font-family: var(--ff-mn);
}
.chip-summary.ok {
  color: var(--up);
  background: rgba(31, 203, 107, 0.1);
  border-color: rgba(31, 203, 107, 0.3);
}

/* Per-scrip allocation panel inside the deploy modal */
.alloc-block {
  margin-top: 10px;
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  background: var(--bg-base);
  font-family: var(--ff-mn);
}
.alloc-block:empty {
  display: none;
}
.alloc-h {
  padding: 6px 10px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--orange);
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
}
.alloc-rows {
  padding: 4px 8px;
}
.alloc-row {
  display: grid;
  grid-template-columns: 110px 130px 60px 1fr;
  gap: 8px;
  align-items: center;
  padding: 3px 4px;
  font-size: 11px;
}
.alloc-row + .alloc-row {
  border-top: 1px dashed var(--bd-1);
}
.alloc-sym {
  font-weight: 800;
  color: var(--tx-1);
}
.alloc-input-wrap {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--tx-3);
}
.alloc-input-wrap input {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 3px 6px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 11px;
  width: 90px;
  outline: 0;
}
.alloc-input-wrap input:focus {
  border-color: var(--orange);
}
.alloc-pct {
  color: var(--tx-2);
  text-align: right;
}
.alloc-qty {
  color: var(--tx-3);
  font-size: 10px;
}
.alloc-total {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--bg-elevated);
  border-top: 1px solid var(--bd-2);
  font-size: 11px;
  font-weight: 700;
  color: var(--tx-2);
}
.alloc-total b {
  color: var(--tx-1);
  font-size: 12px;
}
.alloc-target {
  color: var(--tx-3);
}
.alloc-status {
  margin-left: auto;
  padding: 1px 6px;
  border-radius: 2px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.4px;
}
.alloc-status.ok {
  background: var(--up-bg);
  color: var(--up);
}
.alloc-status.warn {
  background: rgba(242, 163, 65, 0.1);
  color: var(--warn);
  border: 1px solid rgba(242, 163, 65, 0.3);
}

.dc-alloc-row {
  color: var(--tx-2);
}
.dc-alloc {
  white-space: nowrap;
}

/* "About to deploy" confirmation panel above the modal button */
.deploy-confirm {
  margin-top: 10px;
  padding: 10px 12px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 10px;
  line-height: 1.6;
  border: 1px solid var(--bd-2);
}
.deploy-confirm.ok {
  background: var(--up-bg);
  color: var(--tx-1);
  border-color: rgba(31, 203, 107, 0.4);
}
.deploy-confirm.warn {
  background: rgba(242, 163, 65, 0.08);
  color: var(--tx-1);
  border-color: rgba(242, 163, 65, 0.4);
}
.deploy-confirm.arm {
  background: rgba(242, 62, 85, 0.08);
  color: var(--tx-1);
  border: 1px solid rgba(242, 62, 85, 0.45);
  box-shadow: 0 0 12px rgba(242, 62, 85, 0.2);
}
.deploy-confirm .dc-h {
  font-weight: 800;
  font-size: 10px;
  letter-spacing: 0.6px;
  margin-bottom: 6px;
  color: var(--orange);
}
.deploy-confirm.arm .dc-h {
  color: var(--down);
  animation: kill-pulse 2s infinite;
}
.deploy-confirm.ok .dc-h {
  color: var(--up);
}
.deploy-confirm .dc-body {
  color: var(--tx-2);
}
.deploy-confirm .dc-body b {
  color: var(--tx-1);
}

/* =================================================================
   PASTE MODAL — DSL block
   ================================================================= */
.dsl-block {
  margin-top: 8px;
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  background: var(--bg-base);
}
.dsl-block summary {
  padding: 6px 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--tx-2);
  cursor: pointer;
  font-family: var(--ff-ui);
}
.dsl-block summary:hover {
  color: var(--orange);
}
.dsl-block textarea {
  width: 100%;
  min-height: 110px;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--bd-2);
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  line-height: 1.5;
  padding: 8px 10px;
  resize: vertical;
  outline: 0;
}

/* =================================================================
   POSITIONS — inline editable target/stop
   ================================================================= */
.edit-cell {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 4px;
  border-radius: 2px;
  cursor: pointer;
}
.edit-cell:hover {
  background: var(--bg-active);
}
.edit-cell .pencil {
  font-size: 9px;
  opacity: 0.4;
}
.edit-cell:hover .pencil {
  opacity: 1;
  color: var(--orange);
}
.edit-input {
  width: 64px;
  background: var(--bg-base);
  border: 1px solid var(--orange);
  color: var(--tx-1);
  padding: 1px 4px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 10px;
  outline: 0;
  text-align: right;
}

/* =================================================================
   SETTINGS DRAWER
   ================================================================= */
.drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px);
  z-index: 88;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s;
}
.drawer-overlay.show {
  opacity: 1;
  pointer-events: auto;
}
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 380px;
  max-width: 90vw;
  background: var(--bg-panel);
  border-left: 1px solid var(--bd-3);
  z-index: 89;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.22s ease-out;
  box-shadow: -10px 0 30px rgba(0, 0, 0, 0.5);
}
.drawer.show {
  transform: translateX(0);
}
.drawer-head {
  height: 36px;
  padding: 0 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
}
.drawer-title {
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.6px;
  color: var(--orange);
}
.drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 14px;
}
.drawer-section {
  border: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  border-radius: 2px;
  padding: 10px;
  margin-bottom: 12px;
}
.drawer-section .dr-h {
  font-size: 9px;
  letter-spacing: 0.6px;
  font-weight: 800;
  color: var(--orange);
  margin-bottom: 8px;
}
.dr-label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 9px;
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
  margin-bottom: 8px;
}
.dr-label input {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 5px 7px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 11px;
  outline: 0;
}
.dr-label input:focus {
  border-color: var(--orange);
}
.dr-row {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--tx-3);
  margin-bottom: 8px;
}
.dr-row span:last-child {
  color: var(--tx-1);
  font-weight: 700;
}
.dr-hint {
  font-size: 9px;
  color: var(--tx-3);
  margin-top: 6px;
  line-height: 1.4;
}
.dr-hint code {
  background: var(--bg-base);
  padding: 0 4px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  color: var(--orange);
  font-size: 9px;
}
.ghost-btn.full {
  width: 100%;
  padding: 6px 10px;
}
.drawer-foot {
  display: flex;
  justify-content: space-between;
  padding: 10px 14px;
  background: var(--bg-elevated);
  border-top: 1px solid var(--bd-2);
}

/* =================================================================
   STRATEGY DETAIL PAGE — full-overlay "separate page"
   ================================================================= */
.strategy-detail {
  position: fixed;
  /* Cover everything below the top nav. Was offset by an extra 22px
     for the legacy ticker-tape row (hidden but allocated), which left
     a strip where the dashboard sub-header (M MAHIN.K + price ticker)
     peeked through above the strategy detail header — looked like a
     z-index bug on mobile. Top nav stays visible for navigation. */
  top: 46px;
  left: 0;
  right: 0;
  bottom: 22px;
  background: var(--bg-app);
  z-index: 50;
  display: flex;
  flex-direction: row;
  overflow: hidden;
  border-top: 1px solid var(--bd-2);
}
.strategy-detail.hidden {
  display: none;
}

.sd-side {
  width: 220px;
  flex-shrink: 0;
  background: var(--bg-panel);
  border-right: 1px solid var(--bd-2);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.sd-side-h {
  height: 22px;
  background: linear-gradient(180deg, #131923 0%, #0d121b 100%);
  border-bottom: 1px solid var(--bd-2);
  padding: 0 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--orange);
  flex-shrink: 0;
}
.sd-side-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px;
}
.sd-side-card {
  position: relative;
  display: grid;
  grid-template-columns: 8px 1fr;
  column-gap: 6px;
  row-gap: 1px;
  padding: 6px 8px;
  cursor: pointer;
  border-bottom: 1px solid var(--bd-1);
  align-items: center;
}
.sd-side-card:hover {
  background: var(--bg-hover);
}
.sd-side-card.active {
  background: var(--bg-active);
  border-left: 2px solid var(--orange);
  padding-left: 6px;
}
.sd-side-card .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  align-self: start;
  margin-top: 5px;
}
.sd-side-card .ssc-name {
  font-size: 11px;
  font-weight: 700;
  color: var(--tx-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  grid-column: 2;
}
.sd-side-card .ssc-sub {
  grid-column: 2;
  font-size: 9px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sd-side-card .ssc-pnl {
  grid-column: 2;
  font-size: 10px;
  font-family: var(--ff-mn);
  font-weight: 700;
  margin-top: 2px;
}
.sd-side-card .ssc-status {
  grid-column: 2;
  font-size: 8px;
  font-family: var(--ff-mn);
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--tx-3);
  margin-top: 1px;
}
/* Plain-English description on bot cards (Fix #6) — gives non-coders
   a one-line summary of what each bot actually does. Truncated to 2
   lines to keep card heights consistent. */
.sd-side-card .ssc-desc {
  grid-column: 2;
  font-size: 10px;
  color: var(--tx-2);
  line-height: 1.35;
  margin-top: 3px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* Persona chip on bot cards. Uses purple AI-Co-Pilot accent so it
   visually telegraphs "this bot has an AI brain attached" without
   needing the user to read the label. Inline-flex sized to its
   content rather than full-width so it reads as a tag, not a
   field — keeps the card looking like a bot, not a settings page. */
.sd-side-card .bh-card-persona {
  grid-column: 2;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
  padding: 2px 7px;
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.14),
    rgba(168, 85, 247, 0.14)
  );
  border: 1px solid rgba(168, 85, 247, 0.35);
  border-radius: 9px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: #c4b5fd;
  width: fit-content;
  max-width: 100%;
  overflow: hidden;
}
.sd-side-card .bh-card-persona-ico {
  font-size: 11px;
  line-height: 1;
}
.sd-side-card .bh-card-persona-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Custom-persona variant — softer purple, generic robot icon. The
   label is "Custom AI" rather than the bot's custom prompt text
   (which can be paragraphs long). */
.sd-side-card .bh-card-persona.custom {
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.06),
    rgba(168, 85, 247, 0.06)
  );
  border-color: rgba(168, 85, 247, 0.22);
  color: #a78bfa;
}
/* Active-card variant: brighten so the chip pops against the
   highlighted card background. */
.sd-side-card.active .bh-card-persona {
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.22),
    rgba(168, 85, 247, 0.22)
  );
  border-color: rgba(168, 85, 247, 0.55);
  color: #ddd6fe;
}

.sd-side-card.unconfigured .ssc-status {
  color: var(--orange);
  background: rgba(242, 163, 65, 0.12);
  border: 1px solid rgba(242, 163, 65, 0.3);
  display: inline-block;
  padding: 1px 5px;
  border-radius: 2px;
  width: fit-content;
}
.sd-back-bottom {
  background: var(--bg-elevated);
  border: 0;
  border-top: 1px solid var(--bd-2);
  color: var(--tx-2);
  padding: 8px 10px;
  text-align: left;
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  flex-shrink: 0;
}
.sd-back-bottom:hover {
  color: var(--orange);
  background: var(--bg-hover);
}

.sd-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* Mobile-only back arrows in detail / list headers. Hidden on
   desktop (the sidebar is always visible there + a labeled
   "← BACK TO DASHBOARD" sits at the sidebar bottom). */
.sd-mobile-back,
.bh-mobile-back,
.sd-list-back,
.bh-list-back {
  display: none;
  background: transparent;
  border: 0;
  color: var(--tx-1);
  font-size: 22px;
  line-height: 1;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  cursor: pointer;
  flex-shrink: 0;
  margin-right: 4px;
}
.sd-mobile-back:hover,
.bh-mobile-back:hover,
.sd-list-back:hover,
.bh-list-back:hover {
  background: rgba(255, 255, 255, 0.06);
}
/* Top-left back arrow inside the LIST headers (sidebar) on mobile.
   Smaller height-friendly variant. */
.sd-list-back,
.bh-list-back {
  width: 28px;
  height: 22px;
  font-size: 16px;
  color: var(--orange);
}

.sd-header {
  background: linear-gradient(180deg, #131923 0%, #0d121b 100%);
  border-bottom: 1px solid var(--bd-2);
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 14px;
}
.sd-back {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  color: var(--tx-2);
  padding: 5px 12px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
}
.sd-back:hover {
  color: var(--orange);
  border-color: var(--orange);
}
.sd-title-block {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
}
.sd-status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--tx-3);
  margin-top: 2px;
}
.sd-status-dot.running {
  background: var(--up);
  box-shadow: 0 0 6px var(--up);
}
.sd-status-dot.paused {
  background: var(--warn);
}
.sd-status-dot.killed {
  background: var(--down);
  opacity: 0.6;
}
.sd-status-dot.unconfigured {
  background: var(--tx-3);
}
.sd-title-stack {
  line-height: 1.2;
}
.sd-title {
  font-size: 16px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: -0.2px;
}
.sd-sub {
  font-size: 10px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  letter-spacing: 0.2px;
}
.sd-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}

.sd-stats {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
}
.sd-stat {
  padding: 10px 14px;
  border-right: 1px solid var(--bd-1);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sd-stat:last-child {
  border-right: 0;
}
.sd-stat-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
}
.sd-stat-v {
  font-size: 18px;
  font-weight: 800;
  font-family: var(--ff-mn);
}

.sd-tabs {
  display: flex;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--bd-2);
  padding: 0 12px;
}
.sd-tabs button {
  background: transparent;
  border: 0;
  /* Was --tx-3 (#6A7384). At ~3.2:1 against the panel bg the inactive
     tab labels read as washed-out, and once the active tab lights up in
     bright orange they fade out of perception entirely — users reported
     "I can't see the other tabs after clicking AI ACTIVITY". --tx-2
     (#A8B1BF) keeps inactive labels comfortably legible while leaving
     plenty of contrast headroom for the active orange to still stand
     out as the selected tab. */
  color: var(--tx-2);
  padding: 8px 16px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.6px;
  position: relative;
  font-family: var(--ff-mn);
  cursor: pointer;
}
.sd-tabs button:hover {
  color: var(--tx-1);
}
.sd-tabs button.active {
  color: var(--orange);
}
.sd-tabs button.active::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 0;
  height: 2px;
  background: var(--orange);
}

.sd-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: var(--bg-app);
}
.sd-pane {
  display: none;
  padding: 12px 16px;
}
.sd-pane.active {
  display: block;
}

.sd-empty {
  text-align: center;
  color: var(--tx-3);
  font-size: 11px;
  padding: 60px 12px;
  font-family: var(--ff-mn);
}

/* Tile scrip cards so charts stay square instead of stretching */
.sd-scrip-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
  gap: 10px;
  align-items: start;
}

/* Per-scrip card with header + mini chart inside the detail page LIVE tab */
.sd-scrip-card {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto auto auto;
  max-width: 560px;
}
.sd-scrip-head {
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  padding: 6px 12px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px;
}
.sd-scrip-tf {
  justify-self: center;
}
.sd-scrip-tf button {
  padding: 2px 8px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
}
.sd-scrip-h-l {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.sd-scrip-sym {
  font-size: 14px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: -0.2px;
}
.sd-scrip-mkt {
  font-size: 8px;
  color: var(--tx-3);
  padding: 1px 4px;
  background: var(--bg-active);
  border-radius: 2px;
  font-weight: 700;
  letter-spacing: 0.4px;
}
.sd-scrip-name {
  font-size: 9px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
}
.sd-scrip-h-r {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: var(--ff-mn);
}
.sd-scrip-px {
  font-size: 14px;
  font-weight: 800;
  color: var(--tx-1);
  transition: color 0.2s;
}
.sd-scrip-px.flash-up {
  color: var(--up);
}
.sd-scrip-px.flash-down {
  color: var(--down);
}
.sd-scrip-chg {
  font-size: 11px;
  font-weight: 700;
}
.sd-scrip-pos-pill {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 1px 6px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  background: var(--bg-active);
  color: var(--tx-2);
}
.sd-scrip-pos-pill.has {
  background: rgba(58, 130, 246, 0.15);
  color: var(--ac);
}

.sd-scrip-chart {
  position: relative;
  aspect-ratio: 1 / 1;
  width: 100%;
  background: var(--bg-base);
}
.sd-scrip-chart canvas {
  display: block;
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0;
}
.sd-scrip-chart .sd-chart-tags {
  position: absolute;
  top: 4px;
  left: 8px;
  display: flex;
  gap: 4px;
  pointer-events: none;
}
.sd-scrip-chart .sd-chart-tags .ind-tag {
  font-family: var(--ff-mn);
  font-size: 9px;
  padding: 1px 5px;
  border-radius: 2px;
  background: rgba(10, 13, 19, 0.85);
  border: 1px solid var(--bd-2);
  font-weight: 600;
}

.sd-scrip-pos-row {
  border-top: 1px solid var(--bd-1);
  background: var(--bg-elevated);
  padding: 4px 12px;
  font-family: var(--ff-mn);
  font-size: 10px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.sd-scrip-pos-row.empty {
  color: var(--tx-3);
}
.sd-scrip-pos-row .pos-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--bg-base);
  padding: 2px 6px;
  border-radius: 2px;
  border: 1px solid var(--bd-2);
}
.sd-scrip-pos-row .pos-chip.buy {
  border-left: 3px solid var(--up);
}
.sd-scrip-pos-row .pos-chip.sell {
  border-left: 3px solid var(--down);
}
.sd-scrip-pos-row .pos-chip b {
  color: var(--tx-1);
  font-weight: 700;
}

/* ARMED / PAUSED / KILLED status banner inside the detail page LIVE tab */
.sd-arm {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 2px;
  margin-bottom: 12px;
  background: var(--up-bg);
  border: 1px solid rgba(31, 203, 107, 0.4);
}
.sd-arm-led {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--up);
  box-shadow: 0 0 8px var(--up);
  animation: sb-pulse 1.4s infinite;
}
.sd-arm-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.4;
}
.sd-arm-line {
  font-size: 11px;
  color: var(--tx-1);
  font-family: var(--ff-mn);
}
.sd-arm-line b {
  color: var(--up);
  font-weight: 800;
}
.sd-arm-sub {
  font-size: 9px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  letter-spacing: 0.3px;
}

.sd-arm.paused {
  background: rgba(242, 163, 65, 0.1);
  border-color: rgba(242, 163, 65, 0.4);
}
.sd-arm.paused .sd-arm-led {
  background: var(--warn);
  box-shadow: 0 0 8px var(--warn);
  animation: none;
}
.sd-arm.paused .sd-arm-line b {
  color: var(--warn);
}

.sd-arm.killed {
  background: rgba(242, 62, 85, 0.1);
  border-color: rgba(242, 62, 85, 0.4);
}
.sd-arm.killed .sd-arm-led {
  background: var(--down);
  box-shadow: 0 0 8px var(--down);
  animation: none;
}
.sd-arm.killed .sd-arm-line b {
  color: var(--down);
}

/* table inside detail page */
.sd-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
}
.sd-table thead {
  background: var(--bg-elevated);
}
.sd-table th {
  text-align: left;
  padding: 6px 10px;
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  border-bottom: 1px solid var(--bd-2);
}
.sd-table th.r {
  text-align: right;
}
.sd-table tbody tr {
  border-bottom: 1px solid var(--bd-1);
  font-family: var(--ff-mn);
}
.sd-table tbody tr:hover {
  background: var(--bg-hover);
}
.sd-table td {
  padding: 6px 10px;
  vertical-align: middle;
}
.sd-table td.r {
  text-align: right;
}
.sd-table td.bold {
  font-weight: 700;
  color: var(--tx-1);
  font-family: var(--ff-ui);
}

.sd-section-h {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.6px;
  font-weight: 800;
  margin: 14px 4px 6px;
}
.sd-section-h:first-child {
  margin-top: 0;
}

.sd-config-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--bd-2);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
}
.sd-cfg-row {
  background: var(--bg-panel);
  padding: 8px 12px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
}
.sd-cfg-row .k {
  color: var(--tx-3);
  font-size: 9px;
  letter-spacing: 0.5px;
  font-weight: 700;
}
.sd-cfg-row .v {
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-weight: 700;
}

/* unconfigured strategy card P&L cell */
.sc-pnl.deploy-tag {
  color: var(--orange);
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  background: rgba(242, 163, 65, 0.1);
  padding: 1px 5px;
  border-radius: 2px;
  border: 1px solid rgba(242, 163, 65, 0.4);
  text-align: center;
}
.strat-card.status-unconfigured .dot {
  background: var(--tx-3);
}
.strat-card.status-unconfigured {
  opacity: 0.92;
}

.sc-deploy {
  background: var(--orange);
  border: 0;
  color: black;
  padding: 0 8px;
  height: 18px;
  border-radius: 2px;
  font-weight: 800;
  font-size: 9px;
  letter-spacing: 0.5px;
  font-family: var(--ff-mn);
}
.sc-deploy:hover {
  background: #ffba5a;
  box-shadow: 0 0 8px rgba(242, 163, 65, 0.5);
}

/* =================================================================
   HERO DASHBOARD — strategy grid + portfolio bar
   ================================================================= */
.hero-dock {
  min-height: 0;
}
.hero-dock .dock-h .d-meta {
  color: var(--tx-3);
}
.hero-dock .dock-h .d-meta #strat-running-count {
  color: var(--up);
  font-weight: 800;
}
.hero-dock .dock-h .d-meta #strat-unconf-count {
  color: var(--orange);
  font-weight: 800;
}
.hero-dock .d-act {
  background: var(--orange);
  color: black;
  padding: 2px 10px;
  border-radius: 2px;
  font-weight: 800;
  font-size: 9px;
  letter-spacing: 0.5px;
  margin-left: 6px;
}
.hero-dock .d-act:hover {
  background: #ffb04b;
  box-shadow: 0 0 8px rgba(242, 163, 65, 0.5);
}

.strat-hero-grid {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  /* Was 8px gap + 8px padding which made cards visually crowd each
     other. Bumped both so each card stands on its own and reads as a
     distinct unit, not a tile in a tightly-packed grid. */
  gap: 14px;
  padding: 12px;
  background: var(--bg-app);
  align-content: start;
  /* Smoother scroll: GPU layer + iOS momentum + contained overscroll so the
     dock doesn't bounce-chain the page when reaching top/bottom */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* Promote to its own composited layer so scrolling doesn't repaint
     the cards behind it on the main thread. */
  will-change: scroll-position;
  transform: translateZ(0);
}
/* Scroll-perf containment for cards.
   - `contain: layout style` keeps scroll-induced layout/style work
     inside the card without paint-clipping (which previously hid the
     KILL button when the card couldn't grow tall enough).
   - Do NOT use `content-visibility: auto` here — during fast wheel /
     trackpad scroll the browser defers painting card contents and
     leaves empty bordered shells visible until scroll fully settles. */
.strat-hero-card {
  contain: layout style;
}

.strat-hero-card {
  background: var(--bg-panel);
  /* Thicker, lighter-grey border so each card reads as a distinct
     panel instead of blending into the surrounding grid. */
  border: 2px solid var(--bd-3);
  border-radius: 10px;
  padding: 14px 16px;
  /* 3-column × 2-row grid (the redesigned "more aligned" layout):
       Row 1: [icon-box 44px] [name+pills 1fr] [pnl     ]
       Row 2: [    icon-box  ] [   name+pills ] [actions ]
     icon-box and name span both rows + center-align, while pnl and
     actions stack in the rightmost cell (pnl on top, actions below).
     This is the change that bought the name column ~60px of horizontal
     space — previously pnl + actions sat side-by-side in 4 cols and
     the right edge ate ~140px, squeezing names like
     "VWAP+STOCH MEAN-REVERSION (BNB)" to 4-line wraps on tablet width. */
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 12px;
  row-gap: 8px;
  cursor: pointer;
  /* Hover transition only on devices with a real mouse — on touch
     screens, hover state is "sticky" and gets re-applied as the
     finger drags across cards during scroll, triggering box-shadow
     repaints on every frame. Stripping the transition for touch
     devices is the difference between buttery and glitchy. */
  transition: border-color 0.12s;
  position: relative;
  /* Roomier floor (was 80) so even the simplest card has breathing
     room around the 44px icon, the name+pills column, and the
     stacked pnl + actions on the right. Cards still auto-grow if
     the name wraps to a 3rd line. */
  min-height: 110px;
}
@media (hover: hover) and (pointer: fine) {
  .strat-hero-card {
    transition:
      border-color 0.12s,
      box-shadow 0.12s;
  }
  .strat-hero-card:hover {
    border-color: var(--bd-3);
    box-shadow: 0 0 14px rgba(58, 130, 246, 0.1);
  }
}
/* Status accent on the left edge — kept as the colored stripe so
   the status reads from peripheral vision when scanning the grid.
   The icon-box (col 1) further reinforces it with a colored glyph. */
.strat-hero-card.status-running {
  border-left: 4px solid var(--up);
}
.strat-hero-card.status-paused {
  border-left: 4px solid var(--warn);
}
.strat-hero-card.status-killed {
  border-left: 4px solid var(--down);
  opacity: 0.7;
}
.strat-hero-card.status-unconfigured {
  border-left: 4px dashed var(--orange);
  background: linear-gradient(
    180deg,
    rgba(242, 163, 65, 0.04),
    var(--bg-panel)
  );
}

/* ICON BOX — the new 44×44 rounded square at col 1. Replaces the
   tiny 8px shc-dot. Status-themed background tint + matching
   border + glyph color, like the reference design. */
.shc-icon-box {
  grid-column: 1;
  /* Span both rows + self-align center so the icon-box stays
     vertically centered next to the name, regardless of whether the
     right column is taller (pnl + actions stacked) or shorter. */
  grid-row: 1 / -1;
  align-self: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid currentColor;
  background: rgba(255, 255, 255, 0.02);
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}
.shc-icon-box.status-running {
  color: var(--up);
  background: rgba(20, 184, 166, 0.1);
  box-shadow: inset 0 0 12px rgba(20, 184, 166, 0.1);
}
.shc-icon-box.status-paused {
  color: var(--warn);
  background: rgba(242, 163, 65, 0.1);
}
.shc-icon-box.status-killed {
  color: var(--down);
  background: rgba(242, 62, 85, 0.08);
  opacity: 0.7;
}
.shc-icon-box.status-unconfigured {
  color: var(--orange);
  background: rgba(242, 163, 65, 0.1);
  border-style: dashed;
  animation: shc-pulse 1.8s infinite;
}
.shc-icon-glyph {
  font-weight: 800;
}
@keyframes shc-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.55;
  }
}

/* Legacy .shc-dot — kept as a no-op so any stray references don't
   error. The actual status indicator is now the .shc-icon-box. */
.shc-dot {
  display: none;
}

/* NAME CELL — col 2. Name + status/segment/market pills flow
   inline with wrapping so long names push the pills onto the next
   line instead of overflowing the column. */
.shc-name {
  grid-column: 2;
  /* Span both rows so the name + pills can use the full card height
     (and stays vertically centered against the icon-box and the
     stacked pnl/actions on the right). */
  grid-row: 1 / -1;
  align-self: center;
  /* min-width:0 lets the column actually shrink below the name's
     longest-word intrinsic width — without it, grid auto-sizes col 2
     to the longest unbreakable atom (e.g. "REVERSION") and squeezes
     col 3 to overflow. */
  min-width: 0;
  font-size: 14px;
  font-weight: 800;
  color: var(--tx-1);
  letter-spacing: -0.1px;
  line-height: 1.35;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  /* break-word (vs the more aggressive `anywhere`) only breaks
     long unbreakable strings if there's truly no other option,
     so words like "DONCHIAN" stay intact while "VWAP+STOCH"
     can break at the + if needed. */
  overflow-wrap: break-word;
}

/* PILLS — bordered/outlined chips matching the reference. Larger
   than the previous tiny inline labels, with a colored border that
   makes the status read at a glance even when colors are dim. */
.shc-name .shc-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  padding: 3px 7px;
  border-radius: 4px;
  border: 1px solid currentColor;
  background: rgba(255, 255, 255, 0.02);
  line-height: 1;
}
.shc-name .shc-status-pill::before {
  content: "●";
  font-size: 7px;
  margin-right: 1px;
}
.shc-name .shc-status-pill.running {
  color: var(--up);
  background: rgba(20, 184, 166, 0.1);
}
.shc-name .shc-status-pill.paused {
  color: var(--warn);
  background: rgba(242, 163, 65, 0.1);
}
.shc-name .shc-status-pill.killed {
  color: var(--down);
  background: rgba(242, 62, 85, 0.1);
}
.shc-name .shc-status-pill.unconfigured {
  color: var(--orange);
  background: rgba(242, 163, 65, 0.12);
}

/* PNL CELL — col 3. Sized to the content so the actions group can
   sit hard against the right edge of the card. */
.shc-pnl {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
  align-self: end;
  text-align: right;
  font-family: var(--ff-mn);
  font-size: 17px;
  font-weight: 800;
  white-space: nowrap;
}
.shc-pnl.up {
  color: var(--up);
}
.shc-pnl.down {
  color: var(--down);
}
.shc-pnl.unconf {
  color: var(--orange);
  font-size: 12px;
  letter-spacing: 0.4px;
}

/* ACTIONS GROUP — col 4. Two same-size square icon buttons sitting
   side-by-side. Matches the reference design where edit + trash
   are visually paired pills, not asymmetric (one labeled, one
   icon-only). */
.shc-actions-group {
  grid-column: 3;
  grid-row: 2;
  justify-self: end;
  align-self: start;
  display: flex;
  align-items: center;
  gap: 6px;
}
.shc-icon-btn {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(13, 18, 28, 0.85);
  border: 1px solid var(--bd-2);
  color: var(--tx-3);
  border-radius: 6px;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition:
    background 0.12s,
    color 0.12s,
    border-color 0.12s,
    transform 0.12s,
    filter 0.12s;
  filter: opacity(0.85);
}
.shc-icon-btn:hover {
  filter: opacity(1);
  transform: scale(1.06);
}
.shc-icon-btn:active {
  transform: scale(0.95);
}
.shc-edit-btn:hover {
  background: rgba(20, 184, 166, 0.18);
  border-color: var(--up);
  color: var(--up);
  box-shadow: 0 0 8px rgba(20, 184, 166, 0.25);
}
.shc-del-btn:hover {
  background: rgba(242, 62, 85, 0.2);
  border-color: var(--down);
  color: var(--down);
  box-shadow: 0 0 8px rgba(242, 62, 85, 0.3);
}
/* Bot-card variant: cyan tint for the edit hover to match palette */
.bot-hero-card .shc-edit-btn:hover {
  background: rgba(24, 191, 217, 0.18);
  border-color: var(--info);
  color: var(--info);
  box-shadow: 0 0 8px rgba(24, 191, 217, 0.25);
}

/* "24/7" engine toggle — server-execution Phase 3. Off = engine runs in
   this browser tab; On = engine runs 24/7 on the server. Auto-width pill
   (not a 32px square) so the "24/7" label fits. */
.shc-247-btn {
  width: auto;
  padding: 0 8px;
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
}
.shc-247-btn:hover:not(:disabled) {
  background: rgba(24, 191, 217, 0.18);
  border-color: var(--info);
  color: var(--info);
  box-shadow: 0 0 8px rgba(24, 191, 217, 0.25);
}
/* On = currently running 24/7 on the server — solid cyan so it reads as
   an active state, not just a hoverable button. */
.shc-247-btn.on {
  background: rgba(24, 191, 217, 0.16);
  border-color: var(--info);
  color: var(--info);
  filter: opacity(1);
}
/* Disabled = Zerodha engine, server execution not available yet. */
.shc-247-btn:disabled {
  cursor: not-allowed;
  filter: opacity(0.4);
}
.shc-247-btn:disabled:hover {
  transform: none;
}

.shc-sub {
  grid-column: 2 / 4;
  font-family: var(--ff-mn);
  font-size: 10px;
  color: var(--tx-3);
  line-height: 1.4;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.shc-sub-tag {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  padding: 1px 5px;
  border-radius: 2px;
  color: var(--tx-2);
}
.shc-sub-tag.tf {
  color: var(--ac);
  border-color: rgba(58, 130, 246, 0.4);
}
.shc-sub-tag.kind {
  color: var(--orange);
  border-color: rgba(242, 163, 65, 0.4);
}

/* Card stats — used to be 4 boxed label-on-top cells (OPEN / CLOSED /
   SIGNALS / WIN%) with borders + backgrounds, which made the dashboard
   feel busy. Switched to a single tight inline row: small grey label
   sitting beside its value, no boxes, separated by a subtle bullet.
   Same data, ~60% less vertical space, far less visual weight. */
.shc-stats {
  grid-column: 2 / 4;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  margin-top: 4px;
}
.shc-stat {
  background: transparent;
  border: 0;
  padding: 0;
  display: inline-flex;
  flex-direction: row;
  align-items: baseline;
  gap: 4px;
  line-height: 1;
}
.shc-stat-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
  font-weight: 600;
  text-transform: uppercase;
}
.shc-stat-v {
  font-size: 12px;
  font-weight: 700;
  font-family: var(--ff-mn);
  color: var(--tx-1);
  margin-top: 0;
}
.shc-stat-v.up {
  color: var(--up);
}
.shc-stat-v.down {
  color: var(--down);
}
.shc-stat-v.muted {
  color: var(--tx-3);
}

.shc-actions {
  grid-column: 2 / 4;
  display: flex;
  gap: 4px;
  margin-top: 2px;
  flex-wrap: wrap;
  /* No right-padding reservation needed — the trash icon now lives in the
     card's dedicated bottom lane (44px padding-bottom on .strat-hero-card)
     which sits below this action row, not next to it. */
}
.shc-actions .shc-btn {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  color: var(--tx-2);
  padding: 4px 10px;
  border-radius: 2px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
  cursor: pointer;
}
.shc-actions .shc-btn:hover {
  color: var(--tx-1);
  border-color: var(--bd-3);
  background: var(--bg-hover);
}
.shc-actions .shc-btn.primary {
  background: var(--orange);
  color: black;
  border-color: var(--orange);
}
.shc-actions .shc-btn.primary:hover {
  background: #ffb04b;
  box-shadow: 0 0 6px rgba(242, 163, 65, 0.5);
}
.shc-actions .shc-btn.kill {
  color: var(--down);
  border-color: rgba(242, 62, 85, 0.3);
}
.shc-actions .shc-btn.kill:hover {
  background: var(--down);
  color: white;
  border-color: var(--down);
}
/* Delete — subdued grey by default, hover red. Positioned at the end of
   the action row so it can't be hit accidentally. flex-wrap on the
   parent ensures it drops to a new line if the card is too narrow. */
.shc-actions .shc-btn.del {
  color: var(--tx-3);
  border-color: var(--bd-2);
  background: var(--bg-elevated);
  flex: 0 0 auto;
  margin-left: auto; /* push to the far right of the action row */
}
.shc-actions .shc-btn.del:hover {
  background: rgba(242, 62, 85, 0.2);
  color: #fca5a5;
  border-color: var(--down);
  box-shadow: 0 0 8px rgba(242, 62, 85, 0.3);
}

/* "Add new" hero card */
.strat-hero-add {
  background: linear-gradient(
    180deg,
    rgba(242, 163, 65, 0.06),
    rgba(242, 163, 65, 0.02)
  );
  /* Match the new 2px / 10px-radius weight on regular cards so the
     "add" tile reads as a peer, not a smaller decorative stub. */
  border: 2px dashed var(--bd-3);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  cursor: pointer;
  border-radius: 10px;
  /* Padding so the icon + title + subtitle stack doesn't hug the
     border (the .primary-add variant uses overflow: hidden for its
     radial-gradient backdrop — without padding here, the subtitle
     gets clipped). */
  padding: 14px;
  /* Floor card height — needs to clear the icon (32px) + margin
     (6px) + title (~16px) + gap (4px) + subtitle (~13px) + 28px
     padding ≈ 99px. 100 keeps content visible without cropping. */
  min-height: 100px;
  transition: all 0.12s;
}
.strat-hero-add:hover {
  border-color: var(--orange);
  background: rgba(242, 163, 65, 0.1);
}
.strat-hero-add .sha-icon {
  font-size: 20px;
  color: var(--orange);
}
.strat-hero-add .sha-title {
  font-weight: 800;
  font-size: 12px;
  color: var(--orange);
  letter-spacing: 0.5px;
}
.strat-hero-add .sha-sub {
  font-size: 9px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  letter-spacing: 0.3px;
}

/* Demo-strategies toggle (Fix #8) — full-width pill at the bottom of
   the strategy grid. Subtle by default so the user's own strategies
   stay the headline; reveals on hover. */
.demo-toggle-wrap {
  grid-column: 1 / -1;
  display: flex;
  justify-content: center;
  padding: 10px 8px 4px;
}
.demo-toggle {
  background: rgba(255, 255, 255, 0.02);
  border: 1px dashed var(--bd-2);
  color: var(--tx-3);
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 10.5px;
  font-family: var(--ff-mn);
  letter-spacing: 0.4px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: all 0.12s;
}
.demo-toggle:hover {
  border-color: var(--orange);
  color: var(--tx-1);
  background: rgba(242, 163, 65, 0.06);
}
.demo-toggle .dt-ico {
  font-size: 12px;
  opacity: 0.8;
}
.demo-toggle[data-state="on"] {
  border-style: solid;
  border-color: var(--bd-3);
  color: var(--tx-2);
}

/* Portfolio bar (single-row dock) */
.portfolio-dock {
  min-height: 0;
}
.portfolio-bar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  background: var(--bg-elevated);
}
.pb-cell {
  padding: 10px 14px;
  border-right: 1px solid var(--bd-1);
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.15;
}
.pb-cell:last-child {
  border-right: 0;
}
.pb-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.pb-sub {
  font-size: 8.5px;
  font-weight: 500;
  color: var(--tx-4);
  letter-spacing: 0.2px;
  text-transform: none;
  opacity: 0.85;
}
.pb-v {
  font-size: 16px;
  font-weight: 800;
}
.pb-v.up {
  color: var(--up);
}
.pb-v.down {
  color: var(--down);
}

/* =========================================================================
   AUTH MODAL — gates the app on first load + after sign-out
   ========================================================================= */
.auth-modal-overlay {
  position: fixed;
  inset: 0;
  /* Solid background — when the user is signed out, we hide the
     dashboard entirely (via body.is-signed-out below), so we don't
     need a translucent backdrop to "see" the app. A solid panel
     looks more like a real sign-in page and is less unsettling than
     ghosted strategy cards bleeding through. */
  background:
    radial-gradient(
      ellipse at center top,
      rgba(24, 191, 217, 0.06) 0%,
      transparent 50%
    ),
    radial-gradient(
      ellipse at center bottom,
      rgba(167, 139, 250, 0.04) 0%,
      transparent 50%
    ),
    var(--bg-app);
  display: none;
  z-index: 200;
  /* `safe center` keeps the modal vertically centered when it fits,
     but falls back to top-aligned when the content is taller than
     the viewport — so the modal's header never clips off-screen.
     The overflow-y:auto + padding gives a scrollbar with breathing
     room when needed. Without this, signup mode (email + password +
     confirm + phone + 56-option country select) overflowed on
     laptop-height viewports and the "← Back to homepage" link plus
     logo got cut off above the fold. */
  align-items: safe center;
  justify-content: center;
  overflow-y: auto;
  padding: 24px 16px;
}
.auth-modal-overlay.show {
  display: flex;
}

/* Hide the dashboard chrome when the user isn't signed in. Without
   this, the auth modal's backdrop ghosts strategy cards / top nav
   through itself which makes the signed-out state confusing. */
body.is-signed-out .terminal,
body.is-signed-out .kill-banner,
body.is-signed-out #ls-account-menu {
  display: none !important;
}
.auth-modal {
  /* Desktop default: ~520px wide so the form actually fills the
     screen on a laptop or monitor instead of looking like a mobile
     widget centered in the middle of nowhere. The mobile media
     query below tightens it back to 92vw on phones. */
  width: 520px;
  max-width: 92vw;
  background:
    radial-gradient(
      ellipse at top,
      rgba(24, 191, 217, 0.08) 0%,
      transparent 60%
    ),
    var(--bg-panel);
  border: 1px solid rgba(24, 191, 217, 0.3);
  border-radius: 10px;
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.8),
    0 0 40px rgba(24, 191, 217, 0.18);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Anchor for the absolute-positioned auth-back chip below */
  position: relative;
}

/* "Back to homepage" link — top-left corner of the auth card.
   Discreet by default (low-contrast text + transparent bg) so it
   doesn't compete with the SIGN IN CTA, escalates on hover. */
.auth-back,
.auth-back:link,
.auth-back:visited {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: transparent;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 4px;
  transition:
    background 0.15s,
    border-color 0.15s,
    color 0.15s;
}
.auth-back:hover,
.auth-back:focus {
  background: rgba(24, 191, 217, 0.08);
  border-color: rgba(24, 191, 217, 0.35);
  color: var(--tx-1);
  text-decoration: none;
  outline: none;
}
.auth-back-arrow {
  font-size: 13px;
  line-height: 1;
}
.auth-back-label {
  line-height: 1;
}
@media (max-width: 480px) {
  /* Collapse to icon-only on narrow viewports — saves header room. */
  .auth-back {
    padding: 6px 8px;
  }
  .auth-back-label {
    display: none;
  }
}
.auth-h {
  padding: 28px 32px 18px;
  text-align: center;
  border-bottom: 1px solid var(--bd-2);
  background: linear-gradient(180deg, rgba(24, 191, 217, 0.06), transparent);
}
/* Full logo with wordmark — there's room here unlike the 36px
   nav square. Bumped to 168px on the wider desktop modal so it
   reads as a proper hero element, not a thumbnail. */
.auth-logo {
  display: block;
  width: 168px;
  height: auto;
  margin: 0 auto 10px;
  filter: drop-shadow(0 0 14px rgba(24, 191, 217, 0.35));
}
.auth-title {
  font-family: var(--ff-mn);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 1.2px;
  color: var(--info);
  text-shadow: 0 0 12px rgba(24, 191, 217, 0.6);
}
.auth-sub {
  font-size: 11px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  margin-top: 8px;
}
/* Roomier padding + gap at desktop width so the wider modal doesn't
   feel hollow. The mobile media query below collapses these back. */
.auth-body {
  padding: 24px 32px 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.auth-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.6px;
  font-weight: 700;
}
.auth-field input {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 12px 14px;
  border-radius: 4px;
  font-family: var(--ff-mn);
  font-size: 13px;
  outline: 0;
}
.auth-field input:focus {
  border-color: var(--info);
  box-shadow: 0 0 0 2px rgba(24, 191, 217, 0.2);
}
/* Phone row: country-code select + national-number input side by side.
   The select is given a fixed width so the +91 / +1 / +44 codes stay
   visually aligned and the phone input stretches to fill the rest.
   Both share the same height + border treatment as a plain .auth-field
   input so the row reads as a single combined field. */
.auth-phone-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.auth-phone-row select {
  flex: 0 0 auto;
  max-width: 168px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 12px 10px;
  border-radius: 4px;
  font-family: var(--ff-mn);
  font-size: 13px;
  outline: 0;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='%236A7384' d='M0 0l5 6 5-6z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 26px;
  cursor: pointer;
}
.auth-phone-row select:focus {
  border-color: var(--info);
  box-shadow: 0 0 0 2px rgba(24, 191, 217, 0.2);
}
.auth-phone-row input {
  flex: 1 1 auto;
  min-width: 0;
  /* inherit base auth-field input styling — already defined above */
}
/* Dropdown options render in the OS native color scheme, but force
   dark to match the rest of the modal (Chromium honors color-scheme
   on the select element). */
.auth-phone-row select {
  color-scheme: dark;
}
/* Auth status surface — error / info / busy / ok states. Used to
   only render errors; now also shows post-signup confirmations and
   inline-resend prompts so the user always knows what to do next. */
.auth-err {
  min-height: 16px;
  font-size: 12px;
  color: var(--down);
  background: rgba(242, 62, 85, 0.08);
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 8px 10px;
  font-family: var(--ff-ui);
  line-height: 1.45;
  display: none;
}
.auth-err:not(:empty) {
  display: block;
  border-color: rgba(242, 62, 85, 0.3);
}
.auth-err.auth-err-info {
  color: var(--tx-1);
  background: rgba(24, 191, 217, 0.1);
  border-color: rgba(24, 191, 217, 0.4);
}
.auth-err.auth-err-info b {
  color: #5eead4;
}
.auth-err.auth-err-ok {
  color: var(--tx-1);
  background: rgba(74, 222, 128, 0.1);
  border-color: rgba(74, 222, 128, 0.4);
}
.auth-err.auth-err-ok b {
  color: #4ade80;
}
.auth-err.auth-err-busy {
  color: var(--tx-2);
  background: rgba(245, 158, 11, 0.08);
  border-color: rgba(245, 158, 11, 0.3);
}
.auth-err a {
  color: #5eead4;
  text-decoration: underline;
  font-weight: 600;
}
.auth-err a:hover {
  color: #99f6e4;
}

.auth-submit-btn {
  width: 100%;
  padding: 14px 0;
  margin-top: 6px;
  font-size: 13px;
  letter-spacing: 0.8px;
  border-radius: 6px;
}

/* Forgot-password link sits inside .auth-field below the password
   input, right-aligned, dim by default. Always one click reach. */
.auth-forgot {
  display: inline-block;
  margin-top: 4px;
  align-self: flex-end;
  font-size: 11px;
  color: var(--tx-3);
  text-decoration: none;
  font-family: var(--ff-mn);
}
.auth-forgot:hover {
  color: var(--info);
  text-decoration: underline;
}

/* Big mode-switch CTA — replaces the tiny "Create one" link new
   users were missing. Sits as a visual peer to SIGN IN, separated
   by an "or" divider so the user always knows the alternative path
   exists. */
.auth-mode-switch {
  margin-top: 14px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}
.auth-switch-divider {
  position: relative;
  text-align: center;
  font-size: 10px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  letter-spacing: 1.2px;
  text-transform: uppercase;
}
.auth-switch-divider::before,
.auth-switch-divider::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 38%;
  height: 1px;
  background: var(--bd-2);
}
.auth-switch-divider::before {
  left: 0;
}
.auth-switch-divider::after {
  right: 0;
}
.auth-switch-divider span {
  background: var(--bg-panel);
  padding: 0 10px;
  position: relative;
  z-index: 1;
}
.auth-switch-btn {
  width: 100%;
  padding: 11px 14px;
  background: transparent;
  color: var(--tx-1);
  border: 1px solid rgba(94, 234, 212, 0.45);
  border-radius: 4px;
  font-family: var(--ff-mn);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.7px;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s,
    transform 0.05s;
}
.auth-switch-btn:hover {
  background: rgba(94, 234, 212, 0.1);
  border-color: rgba(94, 234, 212, 0.75);
}
.auth-switch-btn:active {
  transform: translateY(1px);
}

/* Auth-flow modals (forgot password / set new password) need to
   stack ABOVE the auth modal itself (z:200) so the user can see
   them when they're triggered from the auth flow. */
#forgot-modal,
#set-pw-modal {
  z-index: 250;
}

/* Compact auth dialogs (reset password, set new password) */
.auth-dialog {
  background: var(--bg-panel);
  border: 1px solid var(--bd-3);
  border-radius: 10px;
  width: 420px;
  max-width: 92vw;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.7);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.auth-dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  font-size: 12px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: 0.5px;
}
.auth-dialog-body {
  padding: 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.auth-dialog-desc {
  font-size: 13px;
  color: var(--tx-2);
  line-height: 1.55;
  margin: 0;
}
.auth-dialog-foot {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 14px 20px;
  border-top: 1px solid var(--bd-2);
  background: var(--bg-elevated);
}

/* Legacy .auth-toggle kept for back-compat; the new layout uses
   .auth-mode-switch above. */
.auth-toggle {
  text-align: center;
  font-size: 10px;
  color: var(--tx-3);
  margin-top: 4px;
}
.auth-toggle a {
  color: var(--info);
  margin-left: 5px;
  cursor: pointer;
}
.auth-toggle a:hover {
  text-decoration: underline;
}
.auth-oauth-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  color: var(--tx-3);
  letter-spacing: 0.04em;
  margin: 2px 0 4px;
}
.auth-oauth-divider::before,
.auth-oauth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--bd-2);
}
.auth-oauth-row {
  display: flex;
  gap: 10px;
}
.auth-oauth-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--bg-2);
  border: 1px solid var(--bd-2);
  border-radius: 8px;
  color: var(--tx-1);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.auth-oauth-btn:hover {
  background: var(--bg-3);
  border-color: var(--info);
}
.auth-oauth-btn svg {
  flex-shrink: 0;
}

.auth-foot {
  text-align: center;
  font-size: 8px;
  color: var(--tx-3);
  letter-spacing: 0.6px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--bd-2);
}

/* Reverse-trial banner — shown above the email field during signup so
   the prospect knows they get Pro for 14 days BEFORE typing anything.
   Hidden in sign-in mode so it's not misleading to returning users. */
.auth-trial-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  margin-bottom: 14px;
  background: linear-gradient(
    135deg,
    rgba(245, 158, 11, 0.1),
    rgba(168, 85, 247, 0.08)
  );
  border: 1px solid rgba(245, 158, 11, 0.45);
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--tx-1);
}
.auth-trial-ico {
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}
.auth-trial-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.auth-trial-text b {
  color: var(--orange);
}
.auth-trial-sub {
  font-size: 10px;
  color: var(--tx-2);
  line-height: 1.45;
}

/* Disabled button state — make it obvious so users don't keep clicking */
.primary-btn:disabled,
.ghost-btn:disabled,
.kill-all-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  filter: grayscale(0.5);
  pointer-events: none;
}

/* =========================================================================
   CONFIRM-ACTIVATION MODAL
   ========================================================================= */
.ca-bot-summary {
  background: linear-gradient(
    135deg,
    rgba(34, 211, 238, 0.1),
    rgba(167, 139, 250, 0.06)
  );
  border: 1px solid rgba(34, 211, 238, 0.3);
  border-radius: 4px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 4px;
}
.ca-summary-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
}
.ca-summary-row > span {
  color: var(--tx-3);
  font-size: 9px;
  letter-spacing: 0.6px;
  font-weight: 700;
}
.ca-summary-row > b {
  color: var(--info);
  font-family: var(--ff-mn);
  font-weight: 800;
}

.ca-impact {
  display: grid;
  grid-template-columns: auto 1fr auto 1fr;
  gap: 6px 12px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px dashed var(--bd-2);
  border-radius: 3px;
  font-size: 11px;
  align-items: center;
  margin-top: 4px;
}
.ca-impact > span {
  color: var(--tx-3);
  font-size: 9px;
  letter-spacing: 0.5px;
  font-weight: 700;
}
.ca-impact > b {
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-weight: 800;
  font-size: 12px;
}
.ca-impact > b.up {
  color: var(--up);
}
.ca-impact > b.down {
  color: var(--down);
}
.ca-impact > b.warn {
  color: var(--warn);
}

/* Multi-symbol position rows. One row per symbol so a 4-symbol
   engine shows BTC AND EUR AND NZD AND CHF position sizes, not
   just the first. align-items:start so the cell pushes labels up. */
.ca-impact > b.bsi-positions {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-weight: 700;
  align-self: flex-start;
}
.bsi-pos-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 8px;
  align-items: baseline;
  font-size: 11px;
}
.bsi-pos-sym {
  color: var(--info);
  font-weight: 800;
  font-size: 10px;
}
.bsi-pos-qty {
  color: var(--tx-1);
  font-weight: 800;
}
.bsi-pos-px {
  color: var(--tx-3);
  font-weight: 500;
  font-size: 10px;
}
.bsi-split-note {
  display: block;
  margin-top: 2px;
  font-family: var(--ff-mn);
  font-size: 9.5px;
  font-weight: 500;
  color: var(--tx-3);
  letter-spacing: 0;
}

/* responsive — hide cols on small screens */
@media (max-width: 1500px) {
  .grid {
    grid-template-columns: 200px 1fr 260px 260px;
  }
}
@media (max-width: 1280px) {
  .grid {
    grid-template-columns: 200px 1fr 260px;
  }
  .col-4 {
    display: none;
  }
}
@media (max-width: 1024px) {
  .grid {
    grid-template-columns: 200px 1fr;
  }
  .col-3 {
    display: none;
  }
}

/* Mobile / tablet responsive layout has been moved to the END of this file
   so its rules win source-order ties against base rules defined later. */

/* =========================================================================
   BOT INTEGRATION HUB
   ========================================================================= */
.bot-hub {
  position: fixed;
  /* Cover everything below the top nav (was offset by 22px for the
     hidden ticker-tape row, which let the dash-header peek through). */
  top: 46px;
  left: 0;
  right: 0;
  bottom: 22px;
  background: var(--bg-app);
  z-index: 60;
  display: flex;
  flex-direction: row;
  overflow: hidden;
  border-top: 1px solid var(--bd-2);
}
.bot-hub.hidden {
  display: none;
}

.bh-side {
  width: 240px;
  flex-shrink: 0;
  background: var(--bg-panel);
  border-right: 1px solid var(--bd-2);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.bh-side-h {
  height: 26px;
  background: linear-gradient(180deg, #131923 0%, #0d121b 100%);
  border-bottom: 1px solid var(--bd-2);
  padding: 0 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--orange);
  flex-shrink: 0;
}
.bh-side-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px;
}
.bh-side-list .bh-card {
  cursor: pointer;
}
.bh-empty-side {
  padding: 12px;
  font-size: 11px;
  color: var(--tx-3);
  line-height: 1.5;
}
/* ----------------------------------------------------------------- */
/* Aspirational empty state for the bot-hub left rail.               */
/*                                                                   */
/* The previous empty state was a single one-liner that read like    */
/* an error ("No bots yet — pick a template..."). It told the user   */
/* what was missing, not what they were about to build.              */
/*                                                                   */
/* This variant shows a *preview* of what their bot rail will look   */
/* like once they deploy: 3 dimmed ghost cards with realistic names, */
/* personas, and modest P&L. The point is to make the right-hand     */
/* template column feel like the next step in a story they've        */
/* already started, not a blank-slate decision.                      */
/*                                                                   */
/* Realism guardrails:                                               */
/*   - Ghost P&L is modest ($23, $67, -$8). Inflated numbers would   */
/*     read as marketing and erode trust.                            */
/*   - One ghost card is at a loss + paused. Real bot rails aren't   */
/*     all green; pretending otherwise is a tell.                    */
/*   - aria-hidden on the cards keeps screen readers focused on the  */
/*     CTA text, not the decorative preview.                         */
/* ----------------------------------------------------------------- */
.bh-empty-aspire {
  padding: 14px 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bh-empty-aspire-h {
  font-size: 13px;
  font-weight: 800;
  color: #ddd6fe;
  letter-spacing: 0.2px;
  line-height: 1.3;
}
.bh-empty-aspire-p {
  font-size: 11px;
  line-height: 1.55;
  color: var(--tx-3);
}
.bh-empty-aspire-label {
  margin-top: 4px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.7px;
  color: rgba(168, 85, 247, 0.75);
  text-transform: uppercase;
}
.bh-empty-aspire-ghosts {
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: none;
}
/* Ghost card variant. Reuses .sd-side-card layout but greys it out
   so users instinctively read it as a preview, not a live bot they
   can click. cursor:default + pointer-events:none on the parent
   container kill any accidental hover/click affordance. */
.sd-side-card.bh-card-ghost {
  opacity: 0.55;
  cursor: default;
  filter: saturate(0.75);
  background: rgba(255, 255, 255, 0.015);
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.12);
}
.sd-side-card.bh-card-ghost:hover {
  background: rgba(255, 255, 255, 0.015);
  border-color: rgba(255, 255, 255, 0.12);
  transform: none;
}
.bh-empty-aspire-foot {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.1),
    rgba(168, 85, 247, 0.06)
  );
  border: 1px solid rgba(168, 85, 247, 0.3);
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  color: #c4b5fd;
  letter-spacing: 0.2px;
}
.bh-empty-aspire-arrow {
  display: inline-block;
  font-size: 14px;
  line-height: 1;
  color: #ddd6fe;
  animation: bh-empty-aspire-nudge 1.6s ease-in-out infinite;
}
@keyframes bh-empty-aspire-nudge {
  0%,
  100% {
    transform: translateX(0);
  }
  50% {
    transform: translateX(3px);
  }
}
.bh-side-actions {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-shrink: 0;
}
.bh-side-actions .d-act {
  white-space: nowrap;
} /* never let the CTA wrap "+ NEW \n BOT" */
/* Icon-only secondary actions in the bot-hub left-rail header (REPAIR,
   AI USAGE). The 240-px rail can't fit three labeled buttons + the
   "BOTS [12] [✨ AI]" title, so the secondary actions collapse to
   their emoji glyph and rely on the tooltip / aria-label for meaning. */
.bh-side-actions .bh-icon-act {
  padding: 0;
  width: 22px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0; /* override .d-act 0.5px tracking — meaningless on a single emoji */
}
/* Primary CTA — the "+ NEW BOT" button. Same compact footprint as the
   default .d-act so the header still fits in 240 px; what makes it
   the visual anchor is the teal tint, not extra padding. */
.bh-side-actions .bh-new-cta {
  background: rgba(20, 184, 166, 0.16);
  border: 1px solid rgba(20, 184, 166, 0.5);
  color: #5eead4;
}
.bh-side-actions .bh-new-cta:hover {
  background: rgba(20, 184, 166, 0.3);
  border-color: #5eead4;
  color: #ccfbf1;
}
/* Title side: keep "BOTS [12] [✨AI]" on one line. Without nowrap the
   AI chip wraps under the count when the count grows to 3 digits. */
.bh-list-title {
  white-space: nowrap;
  flex-shrink: 1;
  min-width: 0;
}
.bh-list-title .ai-hint-chip {
  flex-shrink: 0;
}
/* Repair banner inside the bot-hub left rail. Lights up when one or
   more bots have a name vs code mismatch (e.g. "VWAP Snapper" running
   EMA boilerplate). Click → walks through and upgrades each. */
.bh-repair-banner {
  margin: 6px;
  padding: 8px 10px;
  background: rgba(242, 163, 65, 0.1);
  border: 1px solid rgba(242, 163, 65, 0.4);
  border-radius: 3px;
  font-size: 10px;
  color: #ffd599;
  line-height: 1.5;
  letter-spacing: 0.2px;
}
.bh-repair-banner.hidden {
  display: none;
}
.bh-repair-banner b {
  color: var(--warn);
}
.bh-repair-banner .bh-rb-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  flex-wrap: wrap;
}
.bh-repair-banner button {
  flex: 1;
  min-width: 0;
  padding: 6px 8px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.4px;
  background: var(--warn);
  color: #1a0e00;
  border: 0;
  border-radius: 2px;
  cursor: pointer;
}
.bh-repair-banner button.ghost {
  background: transparent;
  color: var(--tx-2);
  border: 1px solid var(--bd-2);
}
.bh-repair-banner button:hover {
  filter: brightness(1.1);
}

.bh-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  background: var(--bg-app);
}
.bh-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 28px 24px 40px;
  text-align: center;
  gap: 14px;
  overflow: auto;
}
.bh-empty-h {
  font-size: 22px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: 1px;
}
.bh-empty-p {
  font-size: 13px;
  color: var(--tx-2);
}
.bh-empty-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  max-width: 720px;
  margin: 12px 0;
}
.bh-empty-card {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  padding: 16px;
  text-align: left;
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-2);
}
.bh-empty-card b {
  color: var(--orange);
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  letter-spacing: 0.6px;
}

/* ---------- Template-first empty state (Bot Hub) ---------- */
.bh-tpl-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  max-width: 720px;
  margin-bottom: 4px;
}
.bh-tpl-hero-h {
  font-size: 22px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: 1.2px;
}
.bh-tpl-hero-p {
  font-size: 13px;
  color: var(--tx-2);
  line-height: 1.55;
  max-width: 560px;
}
.bh-tpl-hero-p b {
  color: var(--up);
}

.bh-tpl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  width: 100%;
  max-width: 980px;
  margin: 6px 0 10px;
}
.bh-tpl-card {
  position: relative;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition:
    border-color 120ms ease,
    transform 120ms ease,
    box-shadow 120ms ease;
  font: inherit;
  color: var(--tx-1);
}
.bh-tpl-card:hover {
  border-color: var(--orange);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}
.bh-tpl-icon {
  font-size: 22px;
  line-height: 1;
}
.bh-tpl-name {
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  letter-spacing: 0.4px;
}
.bh-tpl-desc {
  font-size: 11px;
  color: var(--tx-2);
  line-height: 1.45;
  flex: 1;
}
.bh-tpl-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px dashed var(--bd-2);
}
.bh-tpl-sym {
  font-family: var(--mono, monospace);
  font-size: 10px;
  color: var(--tx-3);
  background: var(--bg-elevated);
  padding: 2px 6px;
  border-radius: 3px;
  letter-spacing: 0.3px;
}
.bh-tpl-cta {
  font-size: 10px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: 0.6px;
}
.bh-tpl-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  max-width: 720px;
  margin: 18px 0 8px;
  color: var(--tx-3);
  font-size: 10px;
  letter-spacing: 1.2px;
  font-weight: 700;
}
.bh-tpl-divider::before,
.bh-tpl-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--bd-2);
}

.bh-detail {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}
.bh-h {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  flex-shrink: 0;
  gap: 12px;
}
/* The title block must be allowed to shrink (min-width: 0) AND it must
   not push the action buttons off-screen. flex: 1 1 auto + min-width: 0
   lets the long sym list (".bh-sub-meta") truncate with ellipsis instead
   of overflowing into the IMPROVE / EDIT / RUNNING buttons on the right. */
.bh-title-block {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1 1 auto;
  min-width: 0;
}
.bh-title {
  font-size: 16px;
  font-weight: 800;
  color: var(--tx-1);
  letter-spacing: 0.4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bh-sub {
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.bh-sub-meta {
  color: var(--tx-3);
  letter-spacing: 0.3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Plain-English "what this bot does" line in the bot detail header
   (Fix #6) — sits below the techy meta row and reads in normal English. */
.bh-sub-desc {
  color: var(--tx-2);
  font-size: 11px;
  letter-spacing: 0;
  line-height: 1.4;
  max-width: 640px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bh-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

/* "Show more" toggle below the header sub-lines. Lets the user expand the
   ellipsis-truncated title / sym list / description to read the full text
   inline, without having to hover for the title-attribute tooltip. The
   toggle is only rendered when at least one line is actually overflowing
   (see _bhSyncShowMore in app.js); CSS keeps it visually unobtrusive. */
.bh-show-more {
  align-self: flex-start;
  margin-top: 2px;
  padding: 2px 6px;
  background: transparent;
  border: 1px dashed var(--bd-3);
  border-radius: 2px;
  color: var(--tx-2);
  font: 600 9.5px/1.2 var(--ff-mn);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background-color 120ms ease,
    color 120ms ease,
    border-color 120ms ease;
}
.bh-show-more:hover {
  background: var(--bg-hover);
  color: var(--tx-1);
  border-color: var(--bd-3);
  border-style: solid;
}
.bh-show-more[hidden] {
  display: none !important;
}

/* When expanded, every truncated line in the header un-clips so the user
   sees the full content. We allow wrapping ONLY in expanded mode so the
   default state stays single-line and the IMPROVE/EDIT buttons remain
   reachable on narrow viewports. */
.bh-title-block.expanded .bh-title,
.bh-title-block.expanded .bh-sub-meta,
.bh-title-block.expanded .bh-sub-desc {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  word-break: break-word;
}
.bh-title-block.expanded .bh-sub-meta {
  line-height: 1.5;
}
.bh-title-block.expanded .bh-sub-desc {
  max-width: none;
  line-height: 1.5;
}

.bh-metrics {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--bd-2);
  background: var(--bg-panel);
  flex-shrink: 0;
}
.bhm-cell {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  padding: 6px 10px;
  border-radius: 2px;
}
.bhm-k {
  font-size: 8px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.bhm-v {
  font-size: 14px;
  font-weight: 800;
  margin-top: 2px;
}
.bhm-v.up {
  color: var(--up);
}
.bhm-v.down {
  color: var(--down);
}

.bh-body {
  flex: 1;
  overflow: hidden;
  min-height: 0;
  min-width: 0;
  display: flex;
}
.bh-pane {
  display: none;
  flex: 1;
  padding: 12px 16px;
  min-width: 0;
  overflow-x: hidden;
  overflow-y: auto;
}
.bh-pane.active {
  display: block;
}
.bh-empty-pane {
  padding: 30px;
  text-align: center;
  color: var(--tx-3);
  font-size: 11px;
}

.bh-codebar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  margin-bottom: 8px;
}
.bh-repo-tag {
  color: var(--ac);
}
.bh-code-view {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 12px;
  font-family: var(--ff-mn);
  font-size: 11px;
  line-height: 1.6;
  color: var(--tx-1);
  overflow: auto;
  margin: 0;
  white-space: pre-wrap;
  max-height: calc(100vh - 320px);
}
.bh-log-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  max-width: 100%;
}
.bh-log-row {
  display: grid;
  grid-template-columns: 70px 60px minmax(0, 1fr);
  gap: 8px;
  padding: 4px 8px;
  font-size: 11px;
  line-height: 1.4;
  border-bottom: 1px solid var(--bd-1);
  min-width: 0;
}
.bh-log-row.error {
  background: rgba(220, 80, 80, 0.06);
}
.bh-log-row.warn {
  background: rgba(242, 163, 65, 0.06);
}
.bh-log-t {
  color: var(--tx-3);
  flex-shrink: 0;
  white-space: nowrap;
}
.bh-log-l {
  font-weight: 800;
  letter-spacing: 0.4px;
  font-size: 9px;
  padding-top: 2px;
  flex-shrink: 0;
  white-space: nowrap;
}
.bh-log-row.info .bh-log-l {
  color: var(--ac);
}
.bh-log-row.warn .bh-log-l {
  color: var(--warn);
}
.bh-log-row.error .bh-log-l {
  color: var(--down);
}
.bh-log-m {
  color: var(--tx-1);
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* =====================================================================
   🤖 AI ACTIVITY pane (Bot Detail · per-bot LLM call history)
   ---------------------------------------------------------------------
   Header strip = configured persona/model/limits (always shown so the
   user sees what the bot is set up to do, even before any calls).
   Below that = list of <details> rows, one per LLM call. Click to
   expand the full system + prompt + response. Newest first.
   ===================================================================== */
.bh-llm-header {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  margin-bottom: 12px;
  background: var(--bd-1);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  overflow: hidden;
}
.bh-llm-h-cell {
  padding: 8px 10px;
  background: var(--bg-panel);
}
.bh-llm-h-k {
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--tx-3);
  text-transform: uppercase;
  margin-bottom: 3px;
}
.bh-llm-h-v {
  font-size: 12px;
  font-weight: 700;
  color: var(--tx-1);
}
.bh-llm-h-v.mono {
  font-family: var(--ff-mn);
  font-size: 11px;
}

.bh-empty-pane code {
  font-family: var(--ff-mn);
  background: var(--bg-base);
  padding: 1px 4px;
  border-radius: 2px;
  color: var(--ac);
}
.bh-empty-pane-sub {
  margin-top: 6px;
  color: var(--tx-3);
  font-size: 10.5px;
  max-width: 540px;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.5;
}

.bh-llm-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.bh-llm-row {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
}
.bh-llm-row > summary {
  display: grid;
  grid-template-columns: 70px 56px 1fr 70px 60px;
  gap: 10px;
  align-items: center;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 11px;
  list-style: none;
  outline: none;
}
.bh-llm-row > summary::-webkit-details-marker {
  display: none;
}
.bh-llm-row[open] > summary {
  border-bottom: 1px solid var(--bd-2);
  background: var(--bg-base);
}
.bh-llm-t {
  color: var(--tx-3);
  font-family: var(--ff-mn);
}
.bh-llm-badge {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 2px;
  text-align: center;
}
.bh-llm-badge.ok {
  color: var(--up);
  background: rgba(38, 200, 140, 0.12);
}
.bh-llm-badge.cache {
  color: #5fe8d6;
  background: rgba(20, 184, 166, 0.14);
}
.bh-llm-badge.mock {
  color: var(--tx-3);
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
}
.bh-llm-badge.err {
  color: var(--down);
  background: rgba(220, 80, 80, 0.12);
}
.bh-llm-model {
  color: var(--tx-2);
  font-family: var(--ff-mn);
  font-size: 10px;
}
.bh-llm-tok {
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-size: 10px;
  text-align: right;
}
.bh-llm-ms {
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-size: 10px;
  text-align: right;
}

.bh-llm-body {
  padding: 8px 10px;
}
.bh-llm-sec {
  margin-bottom: 8px;
}
.bh-llm-sec:last-child {
  margin-bottom: 0;
}
.bh-llm-sec-k {
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--tx-3);
  margin-bottom: 3px;
}
.bh-llm-sec-v {
  margin: 0;
  padding: 6px 8px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--tx-1);
  white-space: pre-wrap;
  word-break: break-word;
  font-family: var(--ff-mn);
  max-height: 200px;
  overflow-y: auto;
}
.bh-llm-sec-v.err {
  color: var(--down);
}

/* ─── AI USAGE DASHBOARD MODAL ────────────────────────────────────
   Aggregate Co-Pilot consumption panel. Reuses the platform's modal
   shell (.modal-overlay, .modal, .modal-head, .modal-x) and adds its
   own body layout: a compact header row of stat cards, a per-bot
   table, and a recent-failures table. Designed to fit comfortably in
   the 920px modal-wide width without horizontal scroll. */
.llm-usage-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 16px;
  background: var(--bg-app);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.llm-usage-loading {
  text-align: center;
  color: var(--tx-3);
  font-size: 11px;
  padding: 40px 0;
  font-family: var(--ff-mn);
}
.llm-usage-err {
  padding: 10px 12px;
  background: rgba(220, 80, 80, 0.08);
  border: 1px solid rgba(220, 80, 80, 0.4);
  border-radius: 2px;
  color: var(--down);
  font-size: 11px;
  font-family: var(--ff-mn);
}
.llm-usage-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 16px;
  border-top: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  flex-shrink: 0;
}
.llm-usage-foot-meta {
  font-size: 9.5px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  letter-spacing: 0.4px;
}

/* Stat cards row (Calls This Hour / Calls Today / Tokens In / Tokens Out) */
.llm-usage-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.llm-usage-card {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.llm-usage-card-k {
  font-size: 9px;
  font-weight: 700;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.llm-usage-card-v {
  font-size: 18px;
  font-weight: 800;
  color: var(--tx-1);
  font-family: var(--ff-mn);
}
.llm-usage-card-sub {
  font-size: 10px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
}
/* Progress bar inside cards. Width is set inline by JS. */
.llm-usage-bar {
  height: 4px;
  background: var(--bd-2);
  border-radius: 2px;
  overflow: hidden;
  margin-top: 2px;
}
.llm-usage-bar-fill {
  height: 100%;
  background: var(--up);
  transition: width 0.3s ease;
}
.llm-usage-bar-fill.warn {
  background: var(--orange);
}
.llm-usage-bar-fill.crit {
  background: var(--down);
}

/* Plan-tier upsell row under the cap cards */
.llm-usage-upsell {
  margin: 10px 0 14px;
  padding: 8px 12px;
  background: linear-gradient(
    135deg,
    rgba(168, 85, 247, 0.08),
    rgba(245, 158, 11, 0.08)
  );
  border: 1px solid rgba(168, 85, 247, 0.4);
  border-radius: 4px;
  font-size: 11px;
  color: var(--tx-1);
}
.llm-usage-upsell a {
  color: var(--orange);
  font-weight: 800;
  text-decoration: underline;
  margin-left: 4px;
}

/* Section header (BY BOT, RECENT FAILURES) */
.llm-usage-h {
  font-size: 9.5px;
  font-weight: 700;
  color: var(--tx-3);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.llm-usage-h-count {
  font-size: 9px;
  color: var(--tx-2);
  font-weight: 700;
  background: var(--bg-base);
  padding: 1px 6px;
  border-radius: 8px;
}

/* Per-bot + per-failure table */
.llm-usage-tbl {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  overflow: hidden;
  font-size: 10.5px;
  font-family: var(--ff-mn);
}
.llm-usage-tbl th {
  text-align: left;
  padding: 6px 10px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  font-size: 9px;
  font-weight: 700;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.llm-usage-tbl th.num {
  text-align: right;
}
.llm-usage-tbl td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--bd-2);
  color: var(--tx-1);
}
.llm-usage-tbl tr:last-child td {
  border-bottom: 0;
}
.llm-usage-tbl tr:hover td {
  background: var(--bg-base);
}
.llm-usage-tbl td.num {
  text-align: right;
  color: var(--tx-2);
}
.llm-usage-tbl td.muted {
  color: var(--tx-3);
}
.llm-usage-tbl td.fail {
  color: var(--down);
}
.llm-usage-tbl td.fail.zero {
  color: var(--tx-3);
}

/* Error-code chip — matches the bh-llm-badge palette but slightly
   larger so it's readable in the failure table. Each error class gets
   a distinct hue so the user can scan and group at a glance. */
.llm-err-chip {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 2px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
}
.llm-err-chip.parse {
  color: var(--orange);
  background: rgba(242, 163, 65, 0.14);
}
.llm-err-chip.safety {
  color: #d973e3;
  background: rgba(217, 115, 227, 0.14);
}
.llm-err-chip.rate {
  color: var(--orange);
  background: rgba(242, 163, 65, 0.14);
}
.llm-err-chip.model {
  color: var(--down);
  background: rgba(220, 80, 80, 0.12);
}
.llm-err-chip.net {
  color: var(--down);
  background: rgba(220, 80, 80, 0.12);
}
.llm-err-chip.http {
  color: var(--down);
  background: rgba(220, 80, 80, 0.12);
}
.llm-err-chip.other {
  color: var(--tx-2);
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
}

.llm-usage-empty {
  text-align: center;
  color: var(--tx-3);
  font-size: 10.5px;
  padding: 18px 0;
  font-family: var(--ff-mn);
}

/* Mobile / narrow viewports — collapse stat cards 4×1 → 2×2 so they
   stay readable. The tables already fit on phones via overflow. */
@media (max-width: 600px) {
  .llm-usage-cards {
    grid-template-columns: 1fr 1fr;
  }
}

/* =====================================================================
   🔍 EXPLAIN TRADE MODAL
   ---------------------------------------------------------------------
   Two-card layout (trade summary on top, AI explanation below) with a
   sticky bot-attribution row in between. The body is set to a max-height
   so the AI explanation can scroll independently while the trade summary
   stays anchored. Verdict badges reuse the same color tokens as the rest
   of the app — green/orange/red mean the same thing here as on PnL chips.
   ===================================================================== */
.explain-trade-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 18px;
  max-height: 70vh;
  overflow: auto;
}
.explain-trade-loading,
.explain-trade-error {
  text-align: center;
  padding: 28px 0;
  font-family: var(--ff-mn);
  font-size: 11px;
  letter-spacing: 0.4px;
  color: var(--tx-3);
}
.explain-trade-error {
  color: var(--down);
  background: var(--down-bg);
  border: 1px solid rgba(242, 62, 85, 0.3);
  border-radius: 4px;
  padding: 16px;
}

/* TRADE SUMMARY — top card, mirrors the order-row schema so the user
   can correlate the modal back to the row they clicked. The big PnL
   chip on the right side is the headline number. */
.explain-trade-summary {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  padding: 12px 14px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
}
.explain-trade-sum-l {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.explain-trade-sum-sym {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
  color: var(--tx-1);
  display: flex;
  align-items: center;
  gap: 8px;
}
.explain-trade-sum-side {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  padding: 2px 6px;
  border-radius: 2px;
}
.explain-trade-sum-side.long {
  background: var(--up-bg);
  color: var(--up);
}
.explain-trade-sum-side.short {
  background: var(--down-bg);
  color: var(--down);
}
.explain-trade-sum-meta {
  font-size: 10px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.explain-trade-sum-meta b {
  color: var(--tx-2);
  font-weight: 700;
}
.explain-trade-sum-pnl {
  text-align: right;
  font-family: var(--ff-mn);
}
.explain-trade-sum-pnl-v {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.3px;
}
.explain-trade-sum-pnl-pct {
  font-size: 10px;
}
.explain-trade-sum-pnl.up {
  color: var(--up);
}
.explain-trade-sum-pnl.down {
  color: var(--down);
}
.explain-trade-sum-pnl.neutral {
  color: var(--tx-2);
}

/* BOT CARD — middle row attributing the trade to a specific bot +
   persona, with a hint of the strategy code. Hover reveals it as a
   single-line summary; expand details to see source preview. */
.explain-trade-bot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--bg-panel);
  border: 1px solid var(--bd);
  border-radius: 4px;
  font-size: 10.5px;
  font-family: var(--ff-mn);
  color: var(--tx-2);
}
.explain-trade-bot-name {
  font-weight: 800;
  color: var(--tx-1);
}
.explain-trade-bot-persona {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 2px;
  background: rgba(124, 58, 237, 0.12);
  color: rgba(167, 139, 250, 1);
  border: 1px solid rgba(124, 58, 237, 0.3);
}
.explain-trade-bot-persona.none {
  background: var(--bg-elevated);
  color: var(--tx-3);
  border-color: var(--bd-2);
}
.explain-trade-bot-status {
  margin-left: auto;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--tx-3);
}
.explain-trade-bot-status.running {
  color: var(--up);
}

/* NEWS CONTEXT CARD — sits between the bot card and the AI card.
   Shows the same headlines that get injected into the AI prompt
   (or "no news" when the symbol/window has no matches). The point
   is transparency — the user sees what macro context the model
   reasoned over, so the verdict isn't a black box. */
.explain-trade-news {
  background: var(--bg-panel);
  border: 1px solid var(--bd);
  border-left: 3px solid rgba(245, 158, 11, 0.5);
  border-radius: 4px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.explain-trade-news-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 1px;
  color: rgba(245, 158, 11, 0.95);
  text-transform: uppercase;
}
.explain-trade-news-sub {
  font-weight: 600;
  letter-spacing: 0.3px;
  text-transform: none;
  color: var(--tx-3);
  font-size: 9.5px;
}
.explain-trade-news-empty {
  font-size: 10.5px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-style: italic;
  padding: 4px 0 2px;
}
.explain-trade-news-row {
  display: grid;
  grid-template-columns: 44px 56px 1fr;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  border-top: 1px solid var(--bd-2);
  font-size: 10.5px;
  font-family: var(--ff-mn);
  color: var(--tx-2);
}
.explain-trade-news-row:first-of-type {
  border-top: none;
  padding-top: 6px;
}
.explain-trade-news-time {
  color: var(--tx-3);
  font-size: 10px;
  font-weight: 700;
}
.explain-trade-news-tag {
  display: inline-block;
  text-align: center;
  padding: 1px 4px;
  border-radius: 2px;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.5px;
  background: var(--bg-elevated);
  color: var(--tx-3);
  border: 1px solid var(--bd-2);
}
.explain-trade-news-tag.bull {
  background: rgba(34, 197, 94, 0.12);
  color: rgba(74, 222, 128, 1);
  border-color: rgba(34, 197, 94, 0.3);
}
.explain-trade-news-tag.bear {
  background: rgba(239, 68, 68, 0.12);
  color: rgba(248, 113, 113, 1);
  border-color: rgba(239, 68, 68, 0.3);
}
.explain-trade-news-title {
  color: var(--tx-1);
  font-family: var(--ff-sn);
  line-height: 1.35;
}
.explain-trade-news-title a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--bd-2);
}
.explain-trade-news-title a:hover {
  color: rgba(245, 158, 11, 1);
  border-bottom-color: rgba(245, 158, 11, 0.6);
}
.explain-trade-news-src {
  color: var(--tx-3);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.3px;
  margin-left: 4px;
}

/* AI EXPLANATION CARD — the headline reads as a one-line takeaway,
   followed by labeled k/v rows (trigger, context, lesson). Verdict
   badge floats to the right of the headline. */
.explain-trade-ai {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-left: 3px solid rgba(124, 58, 237, 0.6);
  border-radius: 4px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.explain-trade-ai-h {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.7px;
  color: rgba(167, 139, 250, 1);
  font-family: var(--ff-mn);
  text-transform: uppercase;
}
.explain-trade-ai-headline {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.45;
  color: var(--tx-1);
}
.explain-trade-row {
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: 10px;
  font-size: 11px;
  line-height: 1.55;
}
.explain-trade-row-k {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  text-transform: uppercase;
  padding-top: 2px;
}
.explain-trade-row-v {
  color: var(--tx-1);
}
.explain-trade-row-v.muted {
  color: var(--tx-3);
  font-style: italic;
}

/* Verdict badge — colored chip in the AI card header. WELL_TIMED is
   green, MARGINAL orange, POOR red. OPEN is neutral (open positions
   have no outcome to judge yet). UNCLEAR is muted. */
.explain-trade-verdict {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.7px;
  padding: 3px 8px;
  border-radius: 2px;
  white-space: nowrap;
  font-family: var(--ff-mn);
}
.explain-trade-verdict.well_timed {
  background: var(--up-bg);
  color: var(--up);
}
.explain-trade-verdict.marginal {
  background: var(--warn-bg);
  color: var(--warn);
}
.explain-trade-verdict.poor {
  background: var(--down-bg);
  color: var(--down);
}
.explain-trade-verdict.open {
  background: var(--bg-base);
  color: var(--tx-2);
  border: 1px solid var(--bd-2);
}
.explain-trade-verdict.unclear {
  background: var(--bg-base);
  color: var(--tx-3);
  border: 1px solid var(--bd-2);
}

/* Footer meta line — model/cache/latency badge + retry */
.explain-trade-foot-meta {
  flex: 1;
  font-size: 9px;
  font-family: var(--ff-mn);
  color: var(--tx-3);
  letter-spacing: 0.4px;
}

/* =====================================================================
   IMPROVE BOT MODAL
   ---------------------------------------------------------------------
   Same vertical-rhythm as Explain Trade (header card + content cards),
   but the AI card is broken into a top-line diagnosis + a list of
   suggestion cards. Each suggestion has impact/confidence chips so the
   user can scan for the high-leverage / high-confidence picks first.
   ===================================================================== */
.improve-bot-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 18px;
  max-height: 70vh;
  overflow-y: auto;
}
.improve-bot-loading,
.improve-bot-error {
  padding: 24px 12px;
  text-align: center;
  color: var(--tx-3);
  font-style: italic;
  font-size: 11px;
}
.improve-bot-error {
  color: var(--down);
}
.improve-bot-empty {
  padding: 24px 12px;
  text-align: center;
  color: var(--tx-3);
  font-size: 11px;
  line-height: 1.5;
}
.improve-bot-empty b {
  color: var(--tx-1);
}

/* Header card — bot name, persona, key perf metrics. Mirrors the
   trade-summary card on Explain Trade so the two modals feel like
   siblings. */
.improve-bot-summary {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 16px;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
}
.improve-bot-sum-l {
  flex: 1;
  min-width: 0;
}
.improve-bot-sum-name {
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.improve-bot-sum-persona {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 2px;
  background: rgba(124, 58, 237, 0.12);
  color: rgba(167, 139, 250, 1);
  border: 1px solid rgba(124, 58, 237, 0.3);
}
.improve-bot-sum-persona.none {
  background: var(--bg-panel);
  color: var(--tx-3);
  border-color: var(--bd-2);
}
.improve-bot-sum-meta {
  font-size: 10px;
  font-family: var(--ff-mn);
  color: var(--tx-2);
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.improve-bot-sum-meta b {
  color: var(--tx-1);
  font-weight: 800;
}
.improve-bot-sum-pnl {
  text-align: right;
  font-family: var(--ff-mn);
  min-width: 90px;
}
.improve-bot-sum-pnl-v {
  font-size: 16px;
  font-weight: 800;
}
.improve-bot-sum-pnl-pct {
  font-size: 10px;
  opacity: 0.7;
}
.improve-bot-sum-pnl.up {
  color: var(--up);
}
.improve-bot-sum-pnl.down {
  color: var(--down);
}
.improve-bot-sum-pnl.neutral {
  color: var(--tx-2);
}

/* Diagnosis card — one short paragraph summarizing what the model
   thinks is the dominant performance issue. Purple accent matches
   the AI card on Explain Trade. */
.improve-bot-diag {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-left: 3px solid rgba(124, 58, 237, 0.6);
  border-radius: 4px;
  padding: 12px 14px;
}
.improve-bot-diag-h {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 1px;
  color: rgba(167, 139, 250, 1);
  text-transform: uppercase;
  margin-bottom: 6px;
}
.improve-bot-diag-text {
  font-size: 12px;
  line-height: 1.5;
  color: var(--tx-1);
}
.improve-bot-caveat {
  margin-top: 8px;
  padding: 6px 10px;
  background: rgba(245, 158, 11, 0.08);
  border-left: 2px solid rgba(245, 158, 11, 0.5);
  font-size: 10.5px;
  line-height: 1.4;
  color: var(--tx-2);
  font-style: italic;
}

/* Suggestions list — each card is a labeled change with reasoning */
.improve-bot-sugs-h {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 1px;
  color: var(--tx-3);
  text-transform: uppercase;
  margin-top: 4px;
}
.improve-bot-sug {
  background: var(--bg-panel);
  border: 1px solid var(--bd);
  border-left: 3px solid var(--orange);
  border-radius: 4px;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.improve-bot-sug-h {
  display: flex;
  align-items: center;
  gap: 10px;
}
.improve-bot-sug-num {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--tx-3);
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 2px 6px;
}
.improve-bot-sug-title {
  font-size: 12px;
  font-weight: 800;
  color: var(--tx-1);
  flex: 1;
}
.improve-bot-sug-badges {
  display: flex;
  gap: 4px;
}
.improve-bot-sug-badge {
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 2px;
  background: var(--bg-elevated);
  color: var(--tx-3);
  border: 1px solid var(--bd-2);
}
.improve-bot-sug-badge.high {
  background: var(--up-bg);
  color: var(--up);
  border-color: rgba(34, 197, 94, 0.3);
}
.improve-bot-sug-badge.medium {
  background: var(--warn-bg);
  color: var(--warn);
  border-color: rgba(245, 158, 11, 0.3);
}
.improve-bot-sug-badge.low {
  background: var(--bg-elevated);
  color: var(--tx-3);
}
.improve-bot-sug-row {
  display: grid;
  grid-template-columns: 70px 1fr;
  gap: 10px;
  font-size: 11px;
  line-height: 1.5;
}
.improve-bot-sug-k {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--tx-3);
  text-transform: uppercase;
  padding-top: 2px;
}
.improve-bot-sug-v {
  color: var(--tx-1);
}

.improve-bot-foot-meta {
  flex: 1;
  font-size: 9px;
  font-family: var(--ff-mn);
  color: var(--tx-3);
  letter-spacing: 0.4px;
}

/* =====================================================================
   ✨ AI HINT CHIPS — small inline "what does AI do here?" affordance
   ---------------------------------------------------------------------
   Chip itself is intentionally subtle: small, purple-on-dark, only
   draws attention via the ✨ emoji. Hover lifts saturation. Active
   (popover open) gets a faint glow.

   Popover is a small fixed-position card (no overlay backdrop — we
   want it to feel like a tooltip, not a modal). Arrow pseudo-element
   on .ai-hint-arrow is positioned in JS to point at the source chip.
   ===================================================================== */
.ai-hint-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 18px;
  padding: 0 7px;
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.12),
    rgba(168, 85, 247, 0.12)
  );
  border: 1px solid rgba(168, 85, 247, 0.35);
  border-radius: 9px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: #c4b5fd;
  cursor: pointer;
  user-select: none;
  transition:
    background 0.15s,
    border-color 0.15s,
    transform 0.1s;
  vertical-align: middle;
  margin-left: 6px;
}
.ai-hint-chip:hover {
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.22),
    rgba(168, 85, 247, 0.22)
  );
  border-color: rgba(168, 85, 247, 0.6);
  color: #ddd6fe;
}
.ai-hint-chip:active {
  transform: scale(0.96);
}
.ai-hint-chip[aria-expanded="true"] {
  background: linear-gradient(
    135deg,
    rgba(139, 92, 246, 0.3),
    rgba(168, 85, 247, 0.3)
  );
  border-color: rgba(168, 85, 247, 0.8);
  box-shadow: 0 0 0 2px rgba(168, 85, 247, 0.15);
}
.ai-hint-chip .ai-hint-spark {
  font-size: 10px;
  line-height: 1;
}

.ai-hint-popover {
  position: fixed;
  z-index: 200;
  width: 280px;
  background: linear-gradient(180deg, #1a1530 0%, #14111f 100%);
  border: 1px solid rgba(168, 85, 247, 0.45);
  border-radius: 4px;
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(168, 85, 247, 0.15);
  padding: 10px 12px 12px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-1);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-2px);
  transition:
    opacity 0.12s ease,
    transform 0.12s ease;
}
.ai-hint-popover.show {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.ai-hint-arrow {
  position: absolute;
  width: 12px;
  height: 12px;
  background: #1a1530;
  border: 1px solid rgba(168, 85, 247, 0.45);
  transform: rotate(45deg);
}
/* arrow pointing UP (popover is below the chip) */
.ai-hint-popover[data-arrow="top"] .ai-hint-arrow {
  top: -7px;
  border-right: none;
  border-bottom: none;
}
/* arrow pointing DOWN (popover flipped above the chip) */
.ai-hint-popover[data-arrow="bottom"] .ai-hint-arrow {
  bottom: -7px;
  border-left: none;
  border-top: none;
}
.ai-hint-h {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
.ai-hint-title {
  font-size: 11px;
  font-weight: 800;
  color: #ddd6fe;
  letter-spacing: 0.2px;
  flex: 1;
}
.ai-hint-x {
  background: transparent;
  border: none;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  padding: 0 2px;
  transition: color 0.15s;
}
.ai-hint-x:hover {
  color: var(--tx-1);
}
.ai-hint-body {
  color: var(--tx-2);
  font-size: 11px;
  line-height: 1.55;
  margin-bottom: 10px;
}
.ai-hint-cta {
  display: block;
  width: 100%;
  background: linear-gradient(135deg, #8b5cf6, #a855f7);
  color: white;
  border: none;
  border-radius: 3px;
  padding: 7px 10px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
  text-transform: uppercase;
  transition:
    filter 0.15s,
    transform 0.1s;
}
.ai-hint-cta:hover {
  filter: brightness(1.1);
}
.ai-hint-cta:active {
  transform: scale(0.98);
}

/* Flash animation used by AI_HINTS.bot_list to draw the eye to the
   IMPROVE button after the user clicks "SHOW ME". */
@keyframes ai-hint-flash {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(168, 85, 247, 0);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(168, 85, 247, 0.55);
  }
}
.ai-hint-flash {
  animation: ai-hint-flash 0.6s ease-in-out 3;
  border-color: rgba(168, 85, 247, 0.8) !important;
}

.bh-ver-upsell {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: linear-gradient(
    135deg,
    rgba(168, 85, 247, 0.1),
    rgba(245, 158, 11, 0.1)
  );
  border: 1px solid rgba(168, 85, 247, 0.5);
  border-radius: 4px;
  padding: 10px 14px;
  margin-bottom: 10px;
  font-size: 11px;
  color: var(--tx-1);
}
.bh-ver-upsell b {
  color: var(--orange);
}
.bh-ver-upsell .primary-btn.sm {
  font-size: 10px;
  padding: 6px 12px;
  flex-shrink: 0;
}
.bh-ver-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.bh-ver-row {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
}
.bh-ver-h {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  font-size: 10px;
}
.bh-ver-h > span:first-child {
  font-weight: 800;
  color: var(--orange);
  letter-spacing: 0.3px;
}
.bh-ver-t {
  color: var(--tx-3);
  flex: 1;
}
.bh-ver-note {
  color: var(--tx-2);
  font-style: italic;
}
.bh-ver-cur {
  background: var(--up-bg);
  color: var(--up);
  padding: 2px 6px;
  border-radius: 2px;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.4px;
}
.bh-ver-src {
  margin: 0;
  padding: 8px 10px;
  font-family: var(--ff-mn);
  font-size: 10px;
  line-height: 1.5;
  color: var(--tx-2);
  white-space: pre-wrap;
  max-height: 200px;
  overflow: auto;
}

.bh-met-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 16px;
}
.bh-met-cell {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 10px 14px;
}
.bh-met-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.bh-met-v {
  font-size: 18px;
  font-weight: 800;
  margin-top: 4px;
}
.bh-met-v.up {
  color: var(--up);
}
.bh-met-v.down {
  color: var(--down);
}
.bh-met-h {
  font-size: 10px;
  font-weight: 800;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  margin: 14px 0 6px;
}

/* =========================================================================
   BOT LIVE DASHBOARD (the rich per-bot view)
   ========================================================================= */
/* Scope `display: grid` to .active so the inactive state from
   .bh-pane { display: none } can win. ID-vs-class specificity
   was making this pane visible even after switching to LOGS /
   CODE / etc., so both panes rendered side-by-side on mobile. */
#bh-pane-dashboard.active {
  display: grid;
}
#bh-pane-dashboard {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: auto;
  gap: 12px;
  padding: 14px;
  background:
    radial-gradient(
      ellipse at top right,
      rgba(167, 139, 250, 0.04) 0%,
      transparent 60%
    ),
    radial-gradient(
      ellipse at bottom left,
      rgba(24, 191, 217, 0.04) 0%,
      transparent 60%
    ),
    var(--bg-app);
  align-content: start;
  min-width: 0;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
}
#bh-pane-dashboard > * {
  min-width: 0;
}

/* Top metric tiles */
.bd-metric {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent),
    var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  min-height: 184px;
  max-height: 220px;
  min-width: 0;
  position: relative;
  overflow: hidden;
}
.bd-metric-h {
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  margin-bottom: 6px;
}
.bd-metric-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.bd-metric-v {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.4px;
  font-family: var(--ff-mn);
}
.bd-metric-v.up {
  color: var(--up);
}
.bd-metric-v.down {
  color: var(--down);
}
.bd-metric-pct {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 14px;
  background: rgba(31, 203, 107, 0.15);
  color: var(--up);
}
.bd-metric-pct.down {
  background: rgba(242, 62, 85, 0.15);
  color: var(--down);
}
.bd-metric-sym {
  font-size: 11px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  margin-bottom: 2px;
}
.bd-spark {
  width: 100%;
  height: 60px;
  flex: 1;
  min-height: 50px;
}
.bd-metric-foot {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 8px;
  font-size: 10px;
}
.bd-metric-foot > div {
  line-height: 1.4;
  color: var(--tx-2);
}
.bd-metric-foot > div b {
  display: block;
  color: var(--tx-1);
  font-size: 12px;
  font-weight: 700;
  font-family: var(--ff-mn);
}
.bd-metric-foot > div.up b {
  color: var(--up);
}
.bd-metric-foot > div.down b {
  color: var(--down);
}
.bd-metric-foot-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
}

/* STATUS card with big robot */
.bd-metric-status {
  align-items: center;
  text-align: center;
  padding: 10px 14px 14px;
  max-height: 240px;
}
.bd-metric-status .bd-metric-h {
  align-self: flex-start;
}
.bd-big-robot {
  width: 110px;
  height: 110px;
  position: relative;
  margin: 4px auto 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bd-robot-rings {
  position: absolute;
  inset: 0;
}
.bd-ring {
  position: absolute;
  inset: 0;
  border: 1px solid rgba(31, 203, 107, 0.4);
  border-radius: 50%;
}
.bd-big-robot.status-running .bd-ring.r1 {
  animation: bdRingPulse 2.4s ease-out infinite;
}
.bd-big-robot.status-running .bd-ring.r2 {
  animation: bdRingPulse 2.4s ease-out 0.6s infinite;
}
.bd-big-robot.status-running .bd-ring.r3 {
  animation: bdRingPulse 2.4s ease-out 1.2s infinite;
}
.bd-big-robot.status-paused .bd-ring {
  border-color: rgba(242, 163, 65, 0.4);
}
.bd-big-robot.status-killed .bd-ring {
  border-color: rgba(106, 115, 132, 0.3);
}
@keyframes bdRingPulse {
  0% {
    transform: scale(0.6);
    opacity: 0.9;
  }
  100% {
    transform: scale(1.05);
    opacity: 0;
  }
}
.bd-robot-large {
  position: relative !important;
  top: auto !important;
  right: auto !important;
  width: 56px !important;
  transform: scale(2);
  z-index: 1;
}
.bd-status-label {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 1px;
  margin-top: 6px;
}
.bd-status-label.running {
  color: var(--up);
  text-shadow: 0 0 8px rgba(31, 203, 107, 0.5);
}
.bd-status-label.paused {
  color: var(--warn);
}
.bd-status-label.killed {
  color: var(--tx-3);
}
/* Single-line ellipsis: the parent .bd-metric-status is fixed at 200px
   tall with overflow:hidden (to contain the robot ring animation). When
   the sub copy wraps to 2 lines (~28px) the bottom line gets clipped
   behind the next dashboard tile. Truncate cleanly and let the title
   attribute carry the full string on hover. */
.bd-status-sub {
  font-size: 10px;
  color: var(--tx-3);
  margin-top: 4px;
  line-height: 1.4;
  max-width: 92%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Stats card with progress bar */
.bd-metric-stats {
  gap: 8px;
}
.bd-stat-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11px;
  color: var(--tx-2);
  padding: 4px 0;
  border-bottom: 1px dashed var(--bd-2);
}
.bd-stat-line:last-child {
  border-bottom: 0;
}
.bd-stat-line b {
  color: var(--tx-1);
  font-weight: 800;
  font-size: 13px;
  font-family: var(--ff-mn);
}
.bd-stat-line b.up {
  color: var(--up);
}
.bd-stat-line b.down {
  color: var(--down);
}
.bd-stat-side {
  font-size: 10px;
  color: var(--tx-3);
}
.bd-progress {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.04);
  border-radius: 3px;
  overflow: hidden;
  margin: 2px 0;
}
.bd-progress > i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--up), #1fcb6bcc);
  box-shadow: 0 0 8px rgba(31, 203, 107, 0.5);
  transition: width 0.4s ease;
}
.bd-progress.conf > i {
  background: linear-gradient(90deg, var(--info), var(--up));
  box-shadow: 0 0 8px rgba(24, 191, 217, 0.5);
}

/* HERO scanning panel — span 3 cols */
.bd-hero-panel {
  grid-column: 1 / span 3;
  grid-row: 2;
  background:
    linear-gradient(180deg, rgba(24, 191, 217, 0.04), transparent 50%),
    var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  position: relative;
  min-width: 0;
  /* Explicit min-height so the grid row accommodates the radar (400px) +
     header (~30px) + footer (~60px) + padding (28px). Without this the
     row collapses and the radar overflows behind the positions panel. */
  min-height: 520px;
  overflow: hidden;
}
.bd-hero-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  margin-bottom: 12px;
  min-width: 0;
}
.bd-hero-h > span:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bd-hero-info {
  color: var(--tx-3);
  cursor: help;
}
.bd-hero-body {
  display: grid;
  grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  gap: 16px;
  align-items: stretch;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.bd-hero-stats {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 4px 0;
}
.bd-hs {
  padding-left: 12px;
  border-left: 2px solid var(--bd-2);
}
.bd-hs-k {
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.bd-hs-v {
  font-size: 24px;
  font-weight: 800;
  color: var(--tx-1);
  margin: 2px 0;
  line-height: 1.1;
  font-family: var(--ff-mn);
}
.bd-hs-sub {
  font-size: 11px;
  color: var(--tx-2);
}

/* =========================================================================
   "Bot is Scanning" radar/visualization
   Ports the framer-motion BotScanner spec to vanilla CSS animations:
   conic laser sweep, 4 pulsing light beams, expanding pulse rings,
   particle field, orbiting market chips, breathing SVG bot core,
   status pill. Animations preserve their timeline across dashboard
   refreshes (the .bd-radar element is detached and reattached, not
   re-created, in renderBotPaneDashboard).
   ========================================================================= */
.bd-radar {
  position: relative;
  background: #0a1020;
  border: 1px solid rgba(34, 211, 238, 0.18);
  border-radius: 12px;
  min-height: 400px;
  overflow: hidden;
  isolation: isolate;
}

/* Radial haze sitting at the back */
.bd-haze {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    circle at 50% 60%,
    rgba(56, 189, 248, 0.18) 0%,
    rgba(168, 85, 247, 0.1) 35%,
    transparent 70%
  );
}

/* Faint grid overlay */
.bd-radar-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    linear-gradient(rgba(34, 211, 238, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(34, 211, 238, 0.04) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* 36 random particles — rise + fade lifecycle */
.bd-particle-field {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.bd-particle {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(103, 232, 249, 0.7);
  box-shadow: 0 0 4px rgba(103, 232, 249, 0.6);
  --delay: 0s;
  --dur: 5s;
  --scale: 1;
  animation: bdParticle var(--dur) var(--delay) ease-in-out infinite;
}
@keyframes bdParticle {
  0% {
    opacity: 0;
    transform: scale(0) translateY(0);
  }
  50% {
    opacity: 1;
    transform: scale(var(--scale)) translateY(-20px);
  }
  100% {
    opacity: 0;
    transform: scale(0) translateY(-40px);
  }
}

/* Conic laser sweep — rotates 6s, masked to fade at edges */
.bd-laser-sweep {
  position: absolute;
  left: 50%;
  top: 60%;
  width: 140%;
  height: 140%;
  transform: translate(-50%, -50%);
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    rgba(34, 211, 238, 0.35) 30deg,
    transparent 60deg,
    transparent 360deg
  );
  filter: blur(6px);
  -webkit-mask-image: radial-gradient(circle, black 30%, transparent 70%);
  mask-image: radial-gradient(circle, black 30%, transparent 70%);
  pointer-events: none;
  z-index: 1;
}
.bd-radar.status-running .bd-laser-sweep {
  animation: bdLaserSweep 6s linear infinite;
}
@keyframes bdLaserSweep {
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}

/* 4 pulsing light beams at 0°, 45°, 90°, 135° — origin-bottom so they radiate
   outward from the robot center. */
.bd-light-beam {
  position: absolute;
  left: 50%;
  top: 60%;
  width: 2px;
  height: 90%;
  background: linear-gradient(
    to top,
    rgba(34, 211, 238, 0) 0%,
    rgba(34, 211, 238, 0.7) 50%,
    rgba(168, 85, 247, 0) 100%
  );
  transform-origin: 50% 100%;
  transform: translate(-50%, -100%) rotate(var(--ang, 0deg));
  filter: blur(1px);
  pointer-events: none;
  z-index: 1;
  opacity: 0.2;
}
.bd-radar.status-running .bd-light-beam {
  animation: bdLightBeam 2.4s ease-in-out infinite;
}
@keyframes bdLightBeam {
  0%,
  100% {
    opacity: 0.2;
  }
  50% {
    opacity: 0.9;
  }
}

/* Concentric pulse rings — 4 expanding from 80px to 320px (scale 1→4),
   staggered by 0.75s each, total cycle 3s */
.bd-pulse-ring {
  position: absolute;
  left: 50%;
  top: 75%;
  width: 80px;
  height: 80px;
  margin-left: -40px;
  margin-top: -40px;
  border: 1px solid rgba(34, 211, 238, 0.4);
  border-radius: 50%;
  pointer-events: none;
  transform-origin: center;
  z-index: 1;
  opacity: 0;
}
.bd-radar.status-running .bd-pulse-ring {
  animation: bdPulseRing 3s var(--delay, 0s) ease-out infinite;
}
@keyframes bdPulseRing {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  100% {
    transform: scale(4);
    opacity: 0;
  }
}

/* Base ellipse glow — sits at top:78% to anchor the ground plane */
.bd-base-ellipse {
  position: absolute;
  left: 50%;
  top: 80%;
  transform: translate(-50%, -50%);
  width: 320px;
  height: 70px;
  border-radius: 50%;
  background: radial-gradient(
    ellipse at center,
    rgba(34, 211, 238, 0.4) 0%,
    rgba(168, 85, 247, 0.2) 40%,
    transparent 70%
  );
  filter: blur(10px);
  pointer-events: none;
  z-index: 1;
}

/* Orbiting market chips
   .bd-orbit          — 0×0 anchor at center, rotates 360°
   .bd-orbit-cancel   — positioned at radius, rotates -360° to hold chip upright
   .bd-chip           — the visible pill, bobs up/down */
.bd-orbit {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  z-index: 3;
  --r: 150px;
  --dur: 12s;
  --stagger: 0s;
}
.bd-radar.status-running .bd-orbit {
  animation: bdOrbitFwd var(--dur) linear infinite;
  animation-delay: var(--stagger);
}
.bd-orbit-cancel {
  position: absolute;
  left: var(--r);
  top: 0;
  width: 0;
  height: 0;
}
.bd-radar.status-running .bd-orbit-cancel {
  animation: bdOrbitBack var(--dur) linear infinite;
  animation-delay: var(--stagger);
}
.bd-chip {
  position: absolute;
  left: 0;
  top: 0;
  white-space: nowrap;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid rgba(125, 211, 252, 0.4);
  background: rgba(15, 23, 42, 0.7);
  color: #e0f7fa;
  font-family: var(--ff-mn);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.6px;
  backdrop-filter: blur(2px);
  box-shadow:
    0 0 16px rgba(34, 211, 238, 0.4),
    inset 0 0 8px rgba(34, 211, 238, 0.2);
  transform: translate(-50%, -50%);
}
.bd-radar.status-running .bd-chip {
  animation:
    bdChipBob 2.5s ease-in-out infinite,
    bdChipLockPulse var(--scan-cycle, 4s) ease-in-out infinite;
  animation-delay: 0s, var(--scan-delay, 0s);
}
@keyframes bdOrbitFwd {
  to {
    transform: rotate(360deg);
  }
}
@keyframes bdOrbitBack {
  to {
    transform: rotate(-360deg);
  }
}
@keyframes bdChipBob {
  0%,
  100% {
    transform: translate(-50%, -50%);
  }
  50% {
    transform: translate(-50%, calc(-50% - 6px));
  }
}
/* "Lock-on" highlight: chip flares brighter when this chip is being scanned.
   Brief peak window (3-12% of cycle) so only one chip is highlighted at a time. */
@keyframes bdChipLockPulse {
  0%,
  100% {
    box-shadow:
      0 0 16px rgba(34, 211, 238, 0.4),
      inset 0 0 8px rgba(34, 211, 238, 0.2);
  }
  3% {
    box-shadow:
      0 0 18px rgba(34, 211, 238, 0.6),
      inset 0 0 10px rgba(34, 211, 238, 0.3);
  }
  7% {
    box-shadow:
      0 0 38px rgba(34, 211, 238, 0.95),
      0 0 70px rgba(168, 85, 247, 0.55),
      inset 0 0 14px rgba(255, 255, 255, 0.4);
  }
  12% {
    box-shadow:
      0 0 22px rgba(34, 211, 238, 0.55),
      inset 0 0 10px rgba(34, 211, 238, 0.25);
  }
}

/* Targeting reticle — corner brackets fade in around the active chip */
.bd-chip::before,
.bd-chip::after {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  border-color: var(--info);
  border-style: solid;
  pointer-events: none;
  opacity: 0;
  filter: drop-shadow(0 0 4px rgba(34, 211, 238, 0.7));
}
.bd-chip::before {
  top: -7px;
  left: -7px;
  border-width: 2px 0 0 2px;
}
.bd-chip::after {
  bottom: -7px;
  right: -7px;
  border-width: 0 2px 2px 0;
}
.bd-radar.status-running .bd-chip::before,
.bd-radar.status-running .bd-chip::after {
  animation: bdChipReticle var(--scan-cycle, 4s) ease-in-out infinite;
  animation-delay: var(--scan-delay, 0s);
}
@keyframes bdChipReticle {
  0%,
  100% {
    opacity: 0;
    transform: scale(1.4);
  }
  3% {
    opacity: 0.6;
    transform: scale(1.2);
  }
  7% {
    opacity: 1;
    transform: scale(1);
  }
  12% {
    opacity: 0.5;
    transform: scale(1.05);
  }
  18% {
    opacity: 0;
    transform: scale(1.1);
  }
}

/* Lock-on beam: thin laser line from robot center to the chip's anchor.
   Sits inside .bd-orbit so it inherits the orbit's rotation (always aligned
   with the chip). Brightness pulses when this orbit is the active scan. */
.bd-orbit-beam {
  position: absolute;
  left: 0;
  top: -1px;
  width: var(--r, 150px);
  height: 2px;
  transform-origin: 0 50%;
  background: linear-gradient(
    to right,
    rgba(34, 211, 238, 0) 0%,
    rgba(34, 211, 238, 0.18) 30%,
    rgba(34, 211, 238, 0.45) 70%,
    rgba(168, 85, 247, 0.7) 100%
  );
  filter: drop-shadow(0 0 3px rgba(34, 211, 238, 0.5));
  pointer-events: none;
  opacity: 0.18;
  z-index: 2;
}
.bd-radar.status-running .bd-orbit-beam {
  animation: bdScanBeam var(--scan-cycle, 4s) ease-in-out infinite;
  animation-delay: var(--scan-delay, 0s);
}
@keyframes bdScanBeam {
  0%,
  100% {
    opacity: 0.18;
    filter: drop-shadow(0 0 3px rgba(34, 211, 238, 0.4));
  }
  3% {
    opacity: 0.5;
  }
  7% {
    opacity: 1;
    filter: drop-shadow(0 0 8px rgba(34, 211, 238, 0.85))
      drop-shadow(0 0 14px rgba(168, 85, 247, 0.6));
  }
  12% {
    opacity: 0.65;
  }
  18% {
    opacity: 0.22;
  }
}

/* Sonar pulses — secondary, faster set of expanding rings emitted from the
   robot center every 1.5s. Gives a sense of constant active probing. */
.bd-sonar {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 60px;
  height: 60px;
  margin-left: -30px;
  margin-top: -30px;
  border: 1.5px solid rgba(34, 211, 238, 0.6);
  border-radius: 50%;
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  transform-origin: center;
  --delay: 0s;
}
.bd-radar.status-running .bd-sonar {
  animation: bdSonarPulse 1.5s var(--delay) ease-out infinite;
}
@keyframes bdSonarPulse {
  0% {
    transform: scale(0.4);
    opacity: 0;
    border-color: rgba(34, 211, 238, 0.85);
  }
  20% {
    opacity: 0.9;
  }
  60% {
    opacity: 0.4;
    border-color: rgba(168, 85, 247, 0.5);
  }
  100% {
    transform: scale(3.2);
    opacity: 0;
    border-color: rgba(168, 85, 247, 0.2);
  }
}

/* Analysis ticker — cycles through 6 messages, one visible at a time.
   Sits at the bottom of the radar above the status pill. */
.bd-analysis-ticker {
  position: absolute;
  bottom: 50px;
  left: 50%;
  transform: translateX(-50%);
  width: 320px;
  height: 18px;
  text-align: center;
  font-family: var(--ff-mn);
  font-size: 11px;
  font-weight: 600;
  color: #b8e8ff;
  letter-spacing: 0.7px;
  text-shadow: 0 0 8px rgba(34, 211, 238, 0.65);
  pointer-events: none;
  z-index: 5;
}
.bd-analysis-ticker > span {
  position: absolute;
  inset: 0;
  opacity: 0;
  white-space: nowrap;
}
/* IMPORTANT: use longhand `animation-*` properties here, NOT the `animation:`
   shorthand. The shorthand would reset animation-delay to 0 and override the
   per-span :nth-child delays below, causing all 6 messages to play at once. */
.bd-radar.status-running .bd-analysis-ticker > span {
  animation-name: bdTicker;
  animation-duration: 18s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.bd-radar.status-running .bd-analysis-ticker > span:nth-child(1) {
  animation-delay: 0s;
}
.bd-radar.status-running .bd-analysis-ticker > span:nth-child(2) {
  animation-delay: 3s;
}
.bd-radar.status-running .bd-analysis-ticker > span:nth-child(3) {
  animation-delay: 6s;
}
.bd-radar.status-running .bd-analysis-ticker > span:nth-child(4) {
  animation-delay: 9s;
}
.bd-radar.status-running .bd-analysis-ticker > span:nth-child(5) {
  animation-delay: 12s;
}
.bd-radar.status-running .bd-analysis-ticker > span:nth-child(6) {
  animation-delay: 15s;
}
@keyframes bdTicker {
  0%,
  1% {
    opacity: 0;
    transform: translateY(6px);
  }
  3% {
    opacity: 1;
    transform: translateY(0);
  }
  14% {
    opacity: 1;
    transform: translateY(0);
  }
  16.6%,
  100% {
    opacity: 0;
    transform: translateY(-6px);
  }
}

/* Bot core: ultra-futuristic SVG robot.
   The SVG carries its own SMIL animations (bob, eye pulse, scan sweep,
   glowing accents, outer aura), so no CSS bob/blink is applied here. */
.bd-bot-core {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 4;
  width: 200px;
  height: 200px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bd-bot-halo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 240px;
  height: 240px;
  margin-left: -120px;
  margin-top: -120px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(56, 189, 248, 0.55) 0%,
    transparent 65%
  );
  filter: blur(16px);
  pointer-events: none;
  transform-origin: center;
}
.bd-radar.status-running .bd-bot-halo {
  animation: bdBotHalo 2.4s ease-in-out infinite;
}
@keyframes bdBotHalo {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.6;
  }
  50% {
    transform: scale(1.25);
    opacity: 1;
  }
}
.bd-bot-svg {
  position: relative;
  display: block;
  filter: drop-shadow(0 0 16px rgba(0, 213, 255, 0.55));
}
/* When paused/killed, freeze SVG SMIL animations via animation-play-state
   on the outer SVG; SMIL doesn't honor that, so we just dim instead. */
.bd-radar.status-paused .bd-bot-svg {
  opacity: 0.65;
}
.bd-radar.status-killed .bd-bot-svg {
  opacity: 0.4;
  filter: grayscale(0.7) drop-shadow(0 0 10px rgba(106, 115, 132, 0.5));
}

/* Status pill — bottom of the panel */
.bd-status-pill {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid rgba(34, 211, 238, 0.5);
  background: rgba(15, 23, 42, 0.85);
  color: #b8e8ff;
  font-size: 11px;
  font-family: var(--ff-mn);
  letter-spacing: 0.6px;
  backdrop-filter: blur(4px);
  z-index: 5;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0.7;
}
.bd-radar.status-running .bd-status-pill {
  animation: bdStatusPulse 2s ease-in-out infinite;
}
@keyframes bdStatusPulse {
  0%,
  100% {
    opacity: 0.7;
  }
  50% {
    opacity: 1;
  }
}

/* Quiet states */
.bd-radar.status-paused .bd-laser-sweep,
.bd-radar.status-paused .bd-light-beam {
  opacity: 0.15;
}
.bd-radar.status-killed {
  filter: grayscale(0.6) brightness(0.8);
}

/* =========================================================================
   ENTRY-SIGNAL ANIMATION
   When the bot fires a BUY/SELL signal and its dashboard is visible:
   - The radar flashes brightly with a green/red border pulse
   - The matching orbit chip explodes briefly
   - A big banner overlays the radar with entry details
   ========================================================================= */
.bd-radar.signal-firing {
  animation: bdSignalRadarFlash 4.5s ease-out;
}
@keyframes bdSignalRadarFlash {
  0% {
    filter: brightness(1);
  }
  3% {
    filter: brightness(2.4) saturate(1.5);
  }
  10% {
    filter: brightness(1.4);
  }
  100% {
    filter: brightness(1);
  }
}
/* Glowing rim around the radar in signal color */
.bd-radar.signal-firing::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 12px;
  border: 3px solid;
  pointer-events: none;
  z-index: 50;
  opacity: 0;
  animation: bdSignalRimFlash 1.6s ease-out;
}
.bd-radar.signal-firing.firing-buy::before {
  border-color: var(--up);
  box-shadow:
    0 0 50px rgba(31, 203, 107, 0.7),
    inset 0 0 50px rgba(31, 203, 107, 0.4);
}
.bd-radar.signal-firing.firing-sell::before {
  border-color: var(--down);
  box-shadow:
    0 0 50px rgba(242, 62, 85, 0.7),
    inset 0 0 50px rgba(242, 62, 85, 0.4);
}
@keyframes bdSignalRimFlash {
  0% {
    opacity: 0;
    transform: scale(0.94);
  }
  20% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(1.05);
  }
}

/* Chip explosion — the chip that fired the signal scales up and glows */
.bd-orbit.orbit-firing .bd-chip {
  animation: bdChipExplode 1.2s ease-out 2 !important;
  z-index: 12;
}
@keyframes bdChipExplode {
  0% {
    transform: translate(-50%, -50%) scale(1);
    box-shadow: 0 0 16px rgba(34, 211, 238, 0.4);
  }
  25% {
    transform: translate(-50%, -50%) scale(2.6);
    box-shadow:
      0 0 90px rgba(31, 203, 107, 1),
      0 0 160px rgba(255, 255, 255, 0.7),
      inset 0 0 16px rgba(255, 255, 255, 0.5);
  }
  60% {
    transform: translate(-50%, -50%) scale(1.2);
    box-shadow: 0 0 40px rgba(31, 203, 107, 0.6);
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
    box-shadow: 0 0 16px rgba(34, 211, 238, 0.4);
  }
}
.bd-radar.firing-sell .bd-orbit.orbit-firing .bd-chip {
  animation: bdChipExplodeSell 1.2s ease-out 2 !important;
}
@keyframes bdChipExplodeSell {
  0% {
    transform: translate(-50%, -50%) scale(1);
    box-shadow: 0 0 16px rgba(34, 211, 238, 0.4);
  }
  25% {
    transform: translate(-50%, -50%) scale(2.6);
    box-shadow:
      0 0 90px rgba(242, 62, 85, 1),
      0 0 160px rgba(255, 255, 255, 0.7),
      inset 0 0 16px rgba(255, 255, 255, 0.5);
  }
  60% {
    transform: translate(-50%, -50%) scale(1.2);
    box-shadow: 0 0 40px rgba(242, 62, 85, 0.6);
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
    box-shadow: 0 0 16px rgba(34, 211, 238, 0.4);
  }
}

/* Big BUY/SELL banner */
.bd-signal-banner {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 100;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0);
  padding: 18px 32px;
  border-radius: 10px;
  text-align: center;
  font-family: var(--ff-mn);
  color: #08110a;
  border: 2px solid;
  min-width: 280px;
  animation:
    bdBannerIn 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) forwards,
    bdBannerHold 4s 0.55s forwards;
}
.bd-signal-banner.buy {
  background: linear-gradient(
    135deg,
    rgba(0, 255, 154, 0.95),
    rgba(31, 203, 107, 0.95)
  );
  border-color: #00ffaa;
  box-shadow:
    0 0 60px rgba(31, 203, 107, 0.85),
    0 0 120px rgba(31, 203, 107, 0.45);
}
.bd-signal-banner.sell {
  background: linear-gradient(
    135deg,
    rgba(255, 90, 110, 0.95),
    rgba(242, 62, 85, 0.95)
  );
  border-color: #ff7d8a;
  box-shadow:
    0 0 60px rgba(242, 62, 85, 0.85),
    0 0 120px rgba(242, 62, 85, 0.45);
  color: #1a0b0f;
}
.bd-signal-banner.fading {
  animation: bdBannerOut 0.5s ease-in forwards;
}
.bd-sb-arrow {
  font-size: 36px;
  font-weight: 900;
  line-height: 1;
  margin-bottom: 4px;
  text-shadow: 0 0 12px rgba(255, 255, 255, 0.6);
}
.bd-sb-side {
  font-size: 18px;
  font-weight: 900;
  letter-spacing: 1.6px;
  line-height: 1.1;
}
.bd-sb-pair {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.8px;
  margin-top: 4px;
  opacity: 0.85;
}
.bd-sb-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px 14px;
  margin: 12px 0 8px;
  text-align: left;
}
.bd-sb-grid > div {
  line-height: 1.2;
}
.bd-sb-grid span {
  display: block;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  opacity: 0.7;
}
.bd-sb-grid b {
  display: block;
  font-size: 13px;
  font-weight: 800;
}
.bd-sb-reason {
  font-size: 10px;
  opacity: 0.75;
  margin-top: 4px;
  letter-spacing: 0.3px;
}
@keyframes bdBannerIn {
  0% {
    transform: translate(-50%, -50%) scale(0) rotate(-8deg);
    opacity: 0;
  }
  60% {
    transform: translate(-50%, -50%) scale(1.12) rotate(2deg);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(1) rotate(0deg);
    opacity: 1;
  }
}
@keyframes bdBannerHold {
  0%,
  88% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(0.92) translateY(-6px);
    opacity: 0.9;
  }
}
@keyframes bdBannerOut {
  0% {
    transform: translate(-50%, -50%) scale(0.92) translateY(-6px);
    opacity: 0.9;
  }
  100% {
    transform: translate(-50%, -50%) scale(0.7) translateY(-30px);
    opacity: 0;
  }
}

.bd-hero-foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
  padding: 8px 10px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  font-size: 11px;
  color: var(--tx-2);
  min-width: 0;
  flex-shrink: 0;
}
.bd-hero-foot > span.mono {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bd-conf {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--tx-3);
}
.bd-conf b {
  color: var(--info);
  font-family: var(--ff-mn);
  font-weight: 800;
  font-size: 13px;
}
.bd-hero-foot .bd-progress {
  grid-column: 1 / span 2;
}

/* ACTIVITY panel — col 4, row 2 (aligned with hero scanner) */
.bd-activity-panel {
  grid-column: 4;
  grid-row: 2;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 200px;
  max-height: 520px;
  overflow: hidden;
  /* Stretch to fill the full row-2 height next to the (taller) hero
     panel. With align-self:start the short/empty activity list left a
     tall black bg-app void beside the hero. */
  align-self: stretch;
}
.bd-activity-h {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  margin-bottom: 10px;
  flex-shrink: 0;
  min-width: 0;
}
.bd-link {
  font-size: 10px;
  color: var(--ac);
  cursor: pointer;
  flex-shrink: 0;
}
.bd-link:hover {
  text-decoration: underline;
}
.bd-activity-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.bd-act-row {
  display: grid;
  grid-template-columns: 14px 52px minmax(0, 1fr) 16px;
  align-items: start;
  gap: 6px;
  padding: 8px 2px;
  border-bottom: 1px dashed var(--bd-2);
  font-size: 11px;
  min-width: 0;
}
.bd-act-row:last-child {
  border-bottom: 0;
}
.bd-act-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ac);
  margin-top: 4px;
  box-shadow: 0 0 6px currentColor;
  flex-shrink: 0;
}
.bd-act-dot.warn {
  background: var(--warn);
  color: var(--warn);
}
.bd-act-dot.error {
  background: var(--down);
  color: var(--down);
}
.bd-act-dot.info {
  background: var(--info);
  color: var(--info);
}
.bd-act-time {
  color: var(--tx-3);
  font-family: var(--ff-mn);
  flex-shrink: 0;
}
.bd-act-text {
  min-width: 0;
  overflow: hidden;
}
.bd-act-title {
  font-weight: 700;
  color: var(--tx-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bd-act-sub {
  font-size: 10px;
  color: var(--tx-3);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bd-act-icon {
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 9px;
  font-weight: 800;
}
.bd-act-icon.info {
  background: rgba(31, 203, 107, 0.15);
  color: var(--up);
}
.bd-act-icon.warn {
  background: rgba(242, 163, 65, 0.15);
  color: var(--warn);
}
.bd-act-icon.error {
  background: rgba(242, 62, 85, 0.15);
  color: var(--down);
}
.bd-empty-pane {
  padding: 20px;
  text-align: center;
  color: var(--tx-3);
  font-size: 11px;
}

/* WATCHLIST panel — span 3 cols, full live market data per symbol */
.bd-watchlist-panel {
  grid-column: span 3;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
}
.bd-section-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  margin-bottom: 10px;
  letter-spacing: 0.2px;
}
.bd-watchlist-meta {
  font-size: 10px;
  color: var(--tx-3);
  font-weight: 600;
  letter-spacing: 0.4px;
}
.bd-watchlist-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
}
.bd-watchlist-table thead th {
  background: rgba(255, 255, 255, 0.03);
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
  font-size: 10px;
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--bd-2);
}
.bd-watchlist-table thead th.r {
  text-align: right;
}
.bd-watchlist-table tbody td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--bd-2);
  color: var(--tx-1);
  vertical-align: middle;
}
.bd-watchlist-table tbody tr:last-child td {
  border-bottom: 0;
}
.bd-watchlist-table .r {
  text-align: right;
}
.bd-watchlist-table .up {
  color: var(--up);
}
.bd-watchlist-table .down {
  color: var(--down);
}
.bd-watchlist-table .bd-scan-age {
  color: var(--info);
  font-weight: 700;
}

/* INDICATORS panel — col 4 */
.bd-indicators-panel {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.bd-ind-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-bottom: 10px;
}
.bd-ind-cell {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  padding: 6px 10px;
}
.bd-ind-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.bd-ind-v {
  font-size: 14px;
  font-weight: 800;
  color: var(--info);
  margin-top: 2px;
  font-family: var(--ff-mn);
  text-shadow: 0 0 6px rgba(34, 191, 217, 0.4);
}
.bd-cond-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.bd-cond {
  display: grid;
  grid-template-columns: 18px 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  border-radius: 3px;
  border: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  font-size: 11px;
}
.bd-cond.met {
  border-color: rgba(31, 203, 107, 0.4);
  background: rgba(31, 203, 107, 0.06);
}
.bd-cond.wait {
  border-color: rgba(34, 191, 217, 0.3);
  background: rgba(34, 191, 217, 0.04);
}
.bd-cond-icon {
  font-size: 14px;
  font-weight: 800;
}
.bd-cond.met .bd-cond-icon {
  color: var(--up);
}
.bd-cond.wait .bd-cond-icon {
  color: var(--info);
}
.bd-cond-label {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--tx-3);
}
.bd-cond.met .bd-cond-label {
  color: var(--up);
}
.bd-cond.wait .bd-cond-label {
  color: var(--info);
}
.bd-cond-desc {
  color: var(--tx-1);
  font-size: 11px;
  margin-top: 2px;
}
.bd-cond-pill {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  padding: 2px 7px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.3);
  color: var(--tx-2);
}
.bd-cond.met .bd-cond-pill {
  background: rgba(31, 203, 107, 0.2);
  color: var(--up);
}
.bd-cond.wait .bd-cond-pill {
  background: rgba(34, 191, 217, 0.15);
  color: var(--info);
}

/* ACCOUNT & RISK strip — span 4 cols */
.bd-account-strip {
  grid-column: span 4;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
}
.bd-acc-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 8px;
}
.bd-acc-cell {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  padding: 8px 12px;
}
.bd-acc-cell.wide {
  grid-column: span 4;
}
.bd-acc-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  font-weight: 700;
}
.bd-acc-v {
  font-size: 15px;
  font-weight: 800;
  color: var(--tx-1);
  margin-top: 3px;
  font-family: var(--ff-mn);
}
.bd-acc-v.up {
  color: var(--up);
}
.bd-acc-v.down {
  color: var(--down);
}
.bd-acc-progress {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 3px;
  overflow: hidden;
  margin-top: 6px;
}
.bd-acc-progress > i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--up), #1fcb6bcc);
  transition:
    width 0.4s ease,
    background 0.3s;
}
.bd-acc-progress > i.warn {
  background: linear-gradient(90deg, var(--warn), #f2a341cc);
}
.bd-acc-progress > i.crit {
  background: linear-gradient(90deg, var(--down), #f23e55cc);
}

/* POSITIONS panel — col 1-3 */
.bd-positions-panel {
  grid-column: span 3;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
}
.bd-pos-h {
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  margin-bottom: 10px;
}
.bd-pos-tabs {
  display: inline-flex;
  gap: 4px;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  padding: 3px;
}
.bd-pos-tabs button {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--tx-3);
  padding: 5px 14px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
  border-radius: 3px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bd-pos-tabs button:hover {
  color: var(--tx-1);
}
.bd-pos-tabs button.active {
  background: var(--info);
  color: #03131a;
  text-shadow: 0 0 4px rgba(255, 255, 255, 0.4);
}
.bd-pos-tabs button.active .bd-count {
  background: rgba(0, 0, 0, 0.25);
  color: #03131a;
}
.bd-pos-reason {
  display: inline-block;
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.4px;
  padding: 2px 6px;
  border-radius: 2px;
  text-transform: uppercase;
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-2);
}
.bd-pos-reason.r-target {
  background: rgba(31, 203, 107, 0.15);
  color: var(--up);
}
.bd-pos-reason.r-stop {
  background: rgba(242, 62, 85, 0.15);
  color: var(--down);
}
.bd-pos-reason.r-trail {
  background: rgba(167, 139, 250, 0.15);
  color: var(--purple);
}
.bd-pos-reason.r-reverse {
  background: rgba(34, 191, 217, 0.15);
  color: var(--info);
}
.bd-pos-reason.r-kill {
  background: rgba(242, 62, 85, 0.1);
  color: var(--down);
}
.bd-pos-reason.r-orphan_cleanup {
  background: rgba(106, 115, 132, 0.2);
  color: var(--tx-2);
}
.bd-count {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-2);
  padding: 1px 8px;
  border-radius: 12px;
  font-size: 10px;
  margin-left: 6px;
  font-family: var(--ff-mn);
}
.bd-pos-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
}
.bd-pos-table thead th {
  background: rgba(255, 255, 255, 0.03);
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.4px;
  font-size: 10px;
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--bd-2);
}
.bd-pos-table tbody td {
  padding: 10px;
  border-bottom: 1px solid var(--bd-2);
  color: var(--tx-1);
  vertical-align: middle;
}
.bd-pos-table .small {
  font-size: 9px;
  color: var(--tx-3);
  margin-top: 2px;
}
.bd-pos-table .up {
  color: var(--up);
}
.bd-pos-table .down {
  color: var(--down);
}

/* Orders modal — cap each section's table so a long list doesn't bury
   the sections below it. Previously SIGNALS / OPEN POSITIONS / RECENT
   FILLS shared one long scroll; with 15 open positions, RECENT FILLS
   was pushed ~1,500px down and looked empty ("can't see closed trades").
   Each section now scrolls internally with a sticky column header. */
#om-signals-table,
#om-pos-table,
#om-fills-table {
  max-height: 220px;
  overflow: auto;
}
#om-signals-table thead th,
#om-pos-table thead th,
#om-fills-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-elevated);
}
.bd-pos-pair {
  display: flex;
  align-items: center;
  gap: 8px;
}
.bd-pos-glyph {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--orange), #ffb04b);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  color: black;
  font-size: 11px;
}
.bd-pos-side {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 3px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.4px;
}
.bd-pos-side.long {
  background: rgba(31, 203, 107, 0.15);
  color: var(--up);
  border: 1px solid rgba(31, 203, 107, 0.3);
}
.bd-pos-side.short {
  background: rgba(242, 62, 85, 0.15);
  color: var(--down);
  border: 1px solid rgba(242, 62, 85, 0.3);
}
.bd-pos-btn {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  font-size: 14px;
  cursor: pointer;
  padding: 0 6px;
  letter-spacing: 1px;
}
.bd-pos-btn:hover {
  color: var(--tx-1);
}
.bd-empty-cell {
  text-align: center !important;
  color: var(--tx-3);
  padding: 20px !important;
}

/* STRATEGY panel — col 4 */
.bd-strategy-panel {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 14px;
}
.bd-strat-h {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  margin-bottom: 10px;
}
.bd-strat-icon {
  color: var(--purple);
  font-size: 18px;
  text-shadow: 0 0 8px rgba(167, 139, 250, 0.5);
}
.bd-strat-name {
  color: var(--purple);
  font-weight: 800;
  font-size: 13px;
  margin-bottom: 12px;
  letter-spacing: 0.3px;
}
.bd-strat-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 7px 0;
  border-bottom: 1px dashed var(--bd-2);
  font-size: 11px;
  color: var(--tx-2);
}
.bd-strat-row:last-child {
  border-bottom: 0;
}
.bd-strat-row b {
  color: var(--tx-1);
  font-weight: 800;
  font-family: var(--ff-mn);
}

/* STATUS FOOTER */
.bd-status-footer {
  grid-column: span 4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  font-size: 11px;
  color: var(--tx-3);
}
.bd-status-footer b {
  color: var(--tx-1);
  font-weight: 700;
  margin-left: 4px;
}
.bd-status-footer .up {
  color: var(--up);
}
.bd-status-footer .down {
  color: var(--down);
}
.bd-conn {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--up);
}
.bd-conn-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--up);
  box-shadow: 0 0 6px var(--up);
  animation: bdConnPulse 1.6s ease-in-out infinite;
}
@keyframes bdConnPulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

/* When the dashboard pane is the active hub pane, hide the bh-metrics strip
   above (the 6-cell metric strip) since the dashboard renders its own. */
#bh-pane-dashboard.active ~ * {
} /* placeholder for sibling rules */
.bh-detail:has(#bh-pane-dashboard.active) > .bh-metrics {
  display: none;
}

/* =========================================================================
   BOT STUDIO MODAL
   ========================================================================= */
.modal-wide {
  width: 1040px;
  max-width: 96vw;
  height: calc(100vh - 60px);
  max-height: 880px;
}
/* ─── 4-step wizard chrome ─────────────────────────────────────
   .bs-stepper sits below the modal head; .bs-wstep wraps each
   step's content. Hidden by default; .bs-wstep-show makes one
   step visible. The .bs-method-tabs is itself a step-1-only
   element (it disappears on steps 2-4). */
.bs-stepper {
  list-style: none;
  margin: 0;
  padding: 14px 18px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  counter-reset: bs-step;
}
.bs-step-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--bd-2);
  font-family: var(--ff-mn);
  font-size: 11px;
  font-weight: 700;
  color: var(--tx-3);
  letter-spacing: 0.4px;
  cursor: default;
  position: relative;
  transition:
    background 0.15s,
    border-color 0.15s,
    color 0.15s;
}
.bs-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--bd-3);
  color: var(--tx-3);
  font-size: 11px;
  font-weight: 800;
  flex-shrink: 0;
}
.bs-step-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bs-step-item.bs-step-current {
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.5);
  color: var(--orange);
}
.bs-step-item.bs-step-current .bs-step-num {
  background: var(--orange);
  border-color: var(--orange);
  color: #1a0a00;
}
.bs-step-item.bs-step-done {
  color: var(--tx-1);
  border-color: rgba(74, 222, 128, 0.4);
  cursor: pointer;
}
.bs-step-item.bs-step-done .bs-step-num {
  background: rgba(74, 222, 128, 0.2);
  border-color: rgba(74, 222, 128, 0.6);
  color: #4ade80;
}
.bs-step-item.bs-step-done .bs-step-num::before {
  content: "✓";
}
.bs-step-item.bs-step-done .bs-step-num > * {
  display: none;
}
.bs-step-item.bs-step-done:hover {
  background: rgba(74, 222, 128, 0.06);
}
@media (max-width: 640px) {
  .bs-stepper {
    padding: 10px;
    gap: 4px;
  }
  .bs-step-name {
    display: none;
  }
  .bs-step-item {
    justify-content: center;
    padding: 8px;
  }
}

/* Step content visibility — only one .bs-wstep shows at a time. */
.bs-wstep {
  display: none;
}
.bs-wstep-show {
  display: block;
}
/* When a wstep wraps the bs-method-tabs (step 1), preserve its flex
   layout when shown. */
nav.bs-method-tabs.bs-wstep-show {
  display: flex;
}

/* Footer additions: progress text + back/next buttons */
.bs-foot {
  gap: 8px;
  align-items: center;
}
.bs-step-progress {
  margin-left: auto;
  margin-right: 8px;
  font-family: var(--ff-mn);
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
}

/* Step-4 finish summary card — recap of what the user configured */
.bs-finish-summary {
  margin-top: 16px;
  padding: 14px 16px;
  background: linear-gradient(
    135deg,
    rgba(94, 234, 212, 0.06),
    rgba(168, 85, 247, 0.06)
  );
  border: 1px solid rgba(94, 234, 212, 0.4);
  border-radius: 6px;
  font-size: 12px;
  color: var(--tx-1);
  line-height: 1.55;
}
.bs-finish-summary h4 {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 800;
  color: #5eead4;
  letter-spacing: 0.3px;
}
.bs-finish-summary table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--ff-mn);
  font-size: 11px;
}
.bs-finish-summary td {
  padding: 4px 0;
  vertical-align: top;
}
.bs-finish-summary td:first-child {
  color: var(--tx-3);
  width: 35%;
  padding-right: 10px;
}
.bs-finish-summary td:last-child {
  color: var(--tx-1);
  font-weight: 700;
}

.bs-method-tabs {
  display: flex;
  gap: 4px;
  padding: 8px 16px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  flex-shrink: 0;
}
.bs-method-tabs button {
  background: transparent;
  border: 1px solid var(--bd-2);
  color: var(--tx-2);
  padding: 6px 14px;
  border-radius: 2px;
  cursor: pointer;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
}
.bs-method-tabs button.active {
  background: var(--orange);
  color: black;
  border-color: var(--orange);
}
.bs-method-tabs button:hover:not(.active) {
  color: var(--tx-1);
  border-color: var(--bd-3);
}

.bs-body {
  flex: 1;
  min-height: 0;
  padding: 14px 16px;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
.bs-pane {
  display: none;
  flex: 1;
  min-height: 0;
  flex-direction: column;
}
.bs-pane.active {
  display: flex;
}

#bs-paste-area {
  flex: 1;
  min-height: 200px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  line-height: 1.5;
  padding: 10px;
  resize: none;
  outline: 0;
  border-radius: 2px;
  tab-size: 2;
}
#bs-paste-area:focus {
  border-color: var(--orange);
}
/* Strategy template picker above the paste area — lets users load a
   vetted, real strategy implementation instead of pasting boilerplate
   from elsewhere. */
.bs-template-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.bs-template-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--tx-3);
  flex: 1;
  min-width: 280px;
}
.bs-template-select {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 11px;
  padding: 6px 8px;
  outline: 0;
  cursor: pointer;
}
.bs-template-select:focus {
  border-color: var(--orange);
}
.bs-template-row .ghost-btn {
  align-self: flex-end;
  padding: 7px 14px;
  font-size: 11px;
  height: 30px;
}
.bs-template-hint {
  flex-basis: 100%;
  font-size: 9px;
  color: var(--tx-3);
  line-height: 1.5;
  font-style: italic;
}

/* "What goes here?" primer panel — sits between the template-row and
   the paste textarea. Default-open so a confused user lands on the
   contract immediately; collapses to a single summary row once they
   know it. Styled like a docs box (subtle indigo tint, thin border)
   to read as "reference" not "warning". */
.bs-paste-help {
  margin-bottom: 8px;
  border: 1px solid rgba(99, 102, 241, 0.3);
  background: rgba(99, 102, 241, 0.05);
  border-radius: 4px;
  font-size: 11px;
  color: var(--tx-2);
}
.bs-paste-help-summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.bs-paste-help-summary::-webkit-details-marker {
  display: none;
}
.bs-paste-help-summary > span:first-child {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--tx-1);
}
.bs-paste-help-summary > span:first-child b {
  color: var(--tx-1);
  font-weight: 700;
}
/* The literal "click to collapse" label inside the summary is hidden
   in CSS — we replace it with an arrow that reflects open/closed
   state via ::before. Avoids JS to manage the toggle text and keeps
   the markup simple. */
.bs-paste-help-hint {
  font-size: 0;
  color: var(--tx-3);
}
.bs-paste-help-hint::before {
  font-size: 11px;
  color: var(--tx-3);
  content: "▸";
}
.bs-paste-help[open] .bs-paste-help-hint::before {
  content: "▾";
}
.bs-paste-help-body {
  padding: 4px 12px 12px;
  border-top: 1px solid rgba(99, 102, 241, 0.2);
}
.bs-paste-help-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 10px;
}
.bs-paste-help-col {
  min-width: 0;
}
.bs-paste-help-col-full {
  grid-column: 1 / -1;
}
.bs-paste-help-h {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  margin-bottom: 4px;
}
.bs-paste-help-p {
  font-size: 11px;
  line-height: 1.55;
  color: var(--tx-2);
  margin: 2px 0;
}
.bs-paste-help-p code,
.bs-paste-help-summary code {
  font-family: var(--ff-mn, ui-monospace, monospace);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  padding: 1px 5px;
  border-radius: 2px;
  color: var(--tx-1);
}
.bs-paste-help-code {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 8px 10px;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--tx-1);
  white-space: pre;
  overflow-x: auto;
  margin: 0;
}
.bs-paste-help-helpers {
  font-size: 10.5px;
  color: var(--tx-1);
  letter-spacing: 0.2px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 6px 9px;
  line-height: 1.7;
}
/* Muted side-text inside the API reference summary. */
.bs-paste-help-mut {
  font-weight: 400;
  color: var(--tx-3);
  font-size: 10px;
}

/* 🌱 BEGINNER PATH PICKER — the "what's the easiest way to get a
   bot?" cards that replaced the API-reference wall. Friendly tone,
   colorful icons, hover lifts. Default state for every new bot. */
.bs-start-here {
  margin-bottom: 10px;
  padding: 12px 14px;
  background: linear-gradient(
    180deg,
    rgba(99, 102, 241, 0.08) 0%,
    rgba(99, 102, 241, 0.03) 100%
  );
  border: 1px solid rgba(99, 102, 241, 0.3);
  border-radius: 4px;
}
.bs-start-here-h {
  font-size: 12px;
  font-weight: 700;
  color: var(--tx-1);
  margin-bottom: 10px;
  letter-spacing: 0.2px;
}
.bs-start-here-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 8px;
}
.bs-start-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 10px 12px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: var(--tx-2);
  transition:
    border-color 0.12s ease,
    transform 0.12s ease,
    background 0.12s ease;
}
.bs-start-card:hover {
  border-color: rgba(99, 102, 241, 0.65);
  background: rgba(99, 102, 241, 0.06);
  transform: translateY(-1px);
}
.bs-start-icon {
  font-size: 18px;
  line-height: 1;
}
.bs-start-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--tx-1);
  letter-spacing: 0.2px;
}
.bs-start-desc {
  font-size: 10.5px;
  line-height: 1.45;
  color: var(--tx-2);
}

/* Brief flash on the strategy-template row when "Use a preset" is
   clicked, so the user's eye is drawn to where the dropdown is. */
@keyframes bs-flash-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.45);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(99, 102, 241, 0.15);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(99, 102, 241, 0);
  }
}
.bs-flash {
  border-radius: 4px;
  animation: bs-flash-pulse 1.2s ease-out;
}

/* "← Back to Quick Start" link rendered at the top of MANUAL BUILDER
   and AI CONVERT panes. Subdued so it doesn't compete with the pane
   content, but always-visible so a routed user has a clear undo. */
.bs-back-to-start {
  align-self: flex-start;
  margin-bottom: 8px;
  padding: 4px 10px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--tx-2);
  background: transparent;
  border: 1px solid var(--bd-2);
  border-radius: 12px;
  cursor: pointer;
  font-family: inherit;
  transition:
    border-color 0.12s ease,
    color 0.12s ease,
    background 0.12s ease;
}
.bs-back-to-start:hover {
  color: var(--tx-1);
  border-color: rgba(99, 102, 241, 0.65);
  background: rgba(99, 102, 241, 0.08);
}

/* 🔄 INLINE DETECT-AND-CONVERT BANNER — pops up under the CODE PASTE
   textarea when non-JS code is detected. Indigo accent matches the
   path-picker (same "AI helping you" surface), pulses softly on
   appear so the user notices it without it screaming. */
@keyframes bs-paste-detect-pop {
  0% {
    transform: translateY(-4px);
    opacity: 0;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}
.bs-paste-detect {
  margin-top: 8px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: linear-gradient(
    180deg,
    rgba(99, 102, 241, 0.14) 0%,
    rgba(99, 102, 241, 0.06) 100%
  );
  border: 1px solid rgba(99, 102, 241, 0.5);
  border-radius: 4px;
  font-size: 11.5px;
  color: var(--tx-1);
  animation: bs-paste-detect-pop 0.18s ease-out;
}
.bs-paste-detect-icon {
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}
.bs-paste-detect-text {
  flex: 1;
  line-height: 1.4;
  color: var(--tx-2);
}
.bs-paste-detect-text b {
  color: var(--tx-1);
}
.bs-paste-detect-btn {
  flex-shrink: 0;
  padding: 6px 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
  background: rgba(99, 102, 241, 0.85);
  border: 1px solid rgba(99, 102, 241, 1);
  border-radius: 3px;
  color: #fff;
  cursor: pointer;
  font-family: inherit;
  box-shadow: 0 0 8px rgba(99, 102, 241, 0.4);
  transition:
    background 0.12s ease,
    box-shadow 0.12s ease;
}
.bs-paste-detect-btn:hover {
  background: rgba(124, 58, 237, 0.95);
  box-shadow: 0 0 12px rgba(124, 58, 237, 0.55);
}
.bs-paste-detect-btn:disabled {
  /* When the button is mid-fix it hosts the .ai-loader markup —
     keep the button at full opacity so the loader's own animations
     read clearly. The cursor still shows wait state. */
  cursor: wait;
}
.bs-paste-detect-btn:disabled.is-loading {
  opacity: 1;
}

/* ===========================================================
   AI LOADER — used while the AI Co-Pilot is repairing/writing
   pasted code. Three layered animations combined into a single
   inline element:
     1. Spinning gradient ring (transform: rotate — GPU)
     2. Shimmering text with sliding gradient highlight
     3. Three staggered bouncing dots (transform — GPU)
   Designed so animation is GPU-composited where possible — no
   layout / no big paint regions, so the page stays responsive
   even while the LLM round-trip is in flight.
   =========================================================== */
.ai-loader {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--ff-mn);
  font-weight: 700;
  letter-spacing: 0.4px;
  white-space: nowrap;
}
/* The ring uses conic-gradient + radial mask to create a thin
   arc that rotates. Pure transform animation = GPU layer. */
.ai-loader-ring {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    rgba(245, 158, 11, 0) 0deg,
    rgba(245, 158, 11, 0.1) 90deg,
    rgba(245, 158, 11, 0.6) 220deg,
    rgba(245, 158, 11, 1) 320deg,
    rgba(245, 158, 11, 0) 360deg
  );
  -webkit-mask: radial-gradient(circle, transparent 5px, black 6px);
  mask: radial-gradient(circle, transparent 5px, black 6px);
  animation: ai-loader-spin 0.9s linear infinite;
  flex-shrink: 0;
}
@keyframes ai-loader-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Sliding gradient highlight on the text. Tiny element (~80px),
   so animating background-position here is essentially free. */
.ai-loader-text {
  background-image: linear-gradient(
    90deg,
    var(--orange) 0%,
    var(--orange) 35%,
    #fcd34d 50%,
    var(--orange) 65%,
    var(--orange) 100%
  );
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: ai-loader-shine 1.4s linear infinite;
}
@keyframes ai-loader-shine {
  from {
    background-position: 200% 0;
  }
  to {
    background-position: -120% 0;
  }
}

/* Three staggered bouncing dots. Pure transform + opacity = GPU. */
.ai-loader-dots {
  display: inline-flex;
  gap: 3px;
  align-items: center;
}
.ai-loader-dots span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--orange);
  display: inline-block;
  animation: ai-loader-dot 0.95s ease-in-out infinite;
}
.ai-loader-dots span:nth-child(2) {
  animation-delay: 0.18s;
}
.ai-loader-dots span:nth-child(3) {
  animation-delay: 0.36s;
}
@keyframes ai-loader-dot {
  0%,
  100% {
    transform: translateY(0) scale(0.7);
    opacity: 0.4;
  }
  50% {
    transform: translateY(-5px) scale(1);
    opacity: 1;
  }
}

/* Subtle border pulse on the parent button so even if the user's
   eyes are off the loader they see "this is working". */
.bs-paste-detect-btn.is-loading {
  border-color: rgba(245, 158, 11, 0.55);
  animation: ai-loader-button-pulse 1.6s ease-in-out infinite;
}
@keyframes ai-loader-button-pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.3);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(245, 158, 11, 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ai-loader-ring,
  .ai-loader-text,
  .ai-loader-dots span,
  .bs-paste-detect-btn.is-loading {
    animation: none;
  }
  .ai-loader-text {
    -webkit-text-fill-color: var(--orange);
    color: var(--orange);
  }
}
.bs-paste-detect-x {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--bd-2);
  border-radius: 50%;
  color: var(--tx-3);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  transition:
    color 0.12s ease,
    border-color 0.12s ease;
}
.bs-paste-detect-x:hover {
  color: var(--tx-1);
  border-color: var(--tx-3);
}

.bs-paste-foot {
  margin-top: 12px;
}
/* New 2-column row: status + helper text on the left, big button right */
.bs-validate-row {
  display: flex;
  align-items: stretch;
  gap: 14px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  padding: 12px 14px;
}
.bs-validate-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.bs-validate-help {
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-3);
}
.bs-validate-help b {
  color: var(--tx-2);
  font-weight: 700;
}
.bs-validate-help code {
  font-family: var(--ff-mn);
  font-size: 10px;
  padding: 1px 4px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--tx-2);
}
.bs-validate-help i {
  font-style: normal;
  color: var(--tx-2);
}
.bs-validate {
  font-size: 12px;
  color: var(--tx-2);
  font-weight: 600;
}
.bs-validate.ok {
  color: var(--up);
  font-weight: 800;
}
.bs-validate.warn {
  color: var(--warn);
  font-weight: 800;
}
.bs-validate.err {
  color: var(--down);
  font-weight: 800;
}

/* The big validate button — peer to the textarea, not a tiny ghost */
.bs-validate-btn-big {
  flex-shrink: 0;
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 22px;
  background: linear-gradient(
    135deg,
    rgba(74, 222, 128, 0.18),
    rgba(94, 234, 212, 0.18)
  );
  border: 1px solid rgba(94, 234, 212, 0.55);
  border-radius: 6px;
  color: var(--tx-1);
  font-family: var(--ff-mn);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s,
    transform 0.05s;
  min-width: 160px;
}
.bs-validate-btn-big:hover {
  background: linear-gradient(
    135deg,
    rgba(74, 222, 128, 0.28),
    rgba(94, 234, 212, 0.28)
  );
  border-color: rgba(94, 234, 212, 0.85);
}
.bs-validate-btn-big:active {
  transform: translateY(1px);
}
.bs-validate-btn-ico {
  font-size: 16px;
  line-height: 1;
  color: #5eead4;
}
.bs-validate-btn-label {
  white-space: nowrap;
}

/* Mobile — stack vertically; button goes full width */
@media (max-width: 720px) {
  .bs-validate-row {
    flex-direction: column;
    gap: 10px;
  }
  .bs-validate-btn-big {
    width: 100%;
  }
}
/* AI auto-fix in flight — animated dots so the user knows the
   button isn't frozen. Used by bsDeploy + bsBacktest. */
.bs-validate.busy {
  color: var(--orange);
  font-weight: 700;
  animation: bsValidatePulse 1.2s ease-in-out infinite;
}
@keyframes bsValidatePulse {
  0%,
  100% {
    opacity: 0.85;
  }
  50% {
    opacity: 1;
  }
}

.bs-git-tree {
  margin-top: 10px;
}
.bs-git-h {
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
  margin-bottom: 6px;
}
.bs-git-section {
  margin-bottom: 10px;
}
.bs-git-sh {
  font-size: 9px;
  color: var(--orange);
  letter-spacing: 0.5px;
  font-weight: 800;
  margin-bottom: 4px;
}
.bs-git-item {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  padding: 6px 10px;
  margin-bottom: 2px;
  border-radius: 2px;
  font-size: 11px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.bs-git-item:hover {
  background: var(--bg-hover);
  border-color: var(--bd-3);
}
.bs-git-item.selected {
  border-color: var(--orange);
  background: rgba(242, 163, 65, 0.1);
}
.bs-git-sz {
  font-size: 9px;
  color: var(--tx-3);
}
.bs-git-loading,
.bs-git-empty {
  font-size: 10px;
  color: var(--tx-3);
  padding: 8px;
}
.bs-git-err {
  background: rgba(220, 80, 80, 0.1);
  color: var(--down);
  padding: 8px 12px;
  border-radius: 2px;
  font-size: 11px;
  border: 1px solid rgba(220, 80, 80, 0.3);
  margin-top: 6px;
}

.bsb-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  flex: 1;
  min-height: 0;
}
.bsb-col,
.bsb-preview-col {
  display: flex;
  flex-direction: column;
  min-height: 0;
  gap: 10px;
}
.bsb-section {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  padding: 8px;
}
.bsb-h {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 9px;
  color: var(--orange);
  letter-spacing: 0.5px;
  font-weight: 800;
  margin-bottom: 6px;
}
.bsb-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  font-size: 11px;
}
.bsb-tag {
  background: var(--orange);
  color: black;
  padding: 1px 5px;
  border-radius: 2px;
  font-weight: 800;
  font-size: 9px;
  letter-spacing: 0.4px;
  min-width: 22px;
  text-align: center;
}
.bsb-row select,
.bsb-row input,
.bsb-rule select,
.bsb-rule input {
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 4px 6px;
  border-radius: 2px;
  font-family: var(--ff-mn);
  font-size: 11px;
  outline: 0;
}
.bsb-row select:focus,
.bsb-row input:focus,
.bsb-rule select:focus,
.bsb-rule input:focus {
  border-color: var(--orange);
}
.bsb-row input {
  width: 70px;
}
.bsb-rule {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 11px;
}
.bsb-rule input {
  width: 90px;
}
.bsb-mut {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.3px;
  font-weight: 700;
}
.bsb-hint {
  font-size: 10px;
  color: var(--tx-3);
  padding: 4px 0;
}
.bsb-preview {
  flex: 1;
  margin: 0;
  padding: 8px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  font-size: 10px;
  line-height: 1.5;
  color: var(--tx-2);
  overflow: auto;
  white-space: pre-wrap;
}
.ghost-btn.sm {
  padding: 2px 6px;
  font-size: 9px;
}

.bs-config {
  border-top: 1px solid var(--bd-2);
  padding: 10px 16px;
  background: var(--bg-panel);
  flex-shrink: 0;
  /* Cap the deploy panel and let it scroll internally. The AI CO-PILOT
     hero now defaults COLLAPSED (just a single-row CTA bar) so the
     panel stays compact unless the user expands it. When expanded,
     the contents flow into this scroll area instead of pushing the
     code editor + validate button out of view above.
     45vh balances: code editor (.bs-body) gets the larger share, but
     the AI CO-PILOT controls + bot fundamentals + telegram remain
     reachable when the user opens the section. */
  max-height: 45vh;
  overflow-y: auto;
}
.form-grid-tight {
  gap: 6px 10px;
}
.form-grid-tight label {
  font-size: 8px;
}

/* ===== LLM CONFIG section in Bot Studio (collapsible) ==================
   Goal: keep the section invisible-until-needed for non-LLM bots, but
   discoverable + clean when expanded. Uses native <details> for the
   collapse mechanic so we don't carry custom open/close state. */
.bs-llm-section {
  margin-top: 14px;
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  background: rgba(
    124,
    58,
    237,
    0.04
  ); /* faint purple tint, matches LLM iconography */
}
.bs-llm-summary {
  list-style: none;
  cursor: pointer;
  padding: 8px 12px;
  user-select: none;
}
.bs-llm-summary::-webkit-details-marker {
  display: none;
}
.bs-llm-summary::before {
  content: "▸ ";
  color: var(--tx-3);
  font-size: 10px;
  margin-right: 4px;
}
.bs-llm-section[open] > .bs-llm-summary::before {
  content: "▾ ";
}
.bs-llm-summary code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.04);
  padding: 0 4px;
  border-radius: 2px;
}
.bs-llm-body {
  padding: 4px 12px 12px;
  border-top: 1px solid var(--bd-2);
}
.bs-llm-grid {
  margin-top: 8px;
}
.bs-llm-fm-hint {
  margin-top: 6px;
  padding: 6px 9px;
  font-size: 10px;
  line-height: 1.4;
  color: var(--tx-2);
  background: rgba(
    242,
    163,
    65,
    0.08
  ); /* faint orange, matches "info" iconography */
  border: 1px solid rgba(242, 163, 65, 0.25);
  border-radius: 3px;
}
.bs-llm-fm-hint code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.06);
  padding: 0 4px;
  border-radius: 2px;
}
.bs-llm-hint {
  font-size: 9px;
  color: var(--tx-3);
  margin-top: 6px;
  line-height: 1.4;
}
.bs-llm-hint code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 9px;
  background: rgba(255, 255, 255, 0.04);
  padding: 0 3px;
  border-radius: 2px;
}
.bs-llm-test {
  margin-top: 12px;
  padding: 10px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
}
.bs-llm-test-h {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--tx-2);
  margin-bottom: 6px;
}
.bs-llm-test-h code {
  font-size: 10px;
  font-family: var(--font-mono, ui-monospace, monospace);
  background: rgba(255, 255, 255, 0.06);
  padding: 0 4px;
  border-radius: 2px;
}
.bs-llm-test textarea,
.bs-llm-test input[type="text"] {
  width: 100%;
  margin-bottom: 6px;
  padding: 6px 8px;
  font-size: 11px;
  font-family: var(--font-mono, ui-monospace, monospace);
  background: var(--bg-panel);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  box-sizing: border-box;
  resize: vertical;
}
.bs-llm-test textarea:focus,
.bs-llm-test input[type="text"]:focus {
  outline: none;
  border-color: var(--accent, #7c3aed);
}
.bs-llm-test-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}
.bs-llm-test-status {
  font-size: 10px;
  color: var(--tx-3);
}
.bs-llm-test-status.ok {
  color: var(--up);
  font-weight: 700;
}
.bs-llm-test-status.err {
  color: var(--down);
  font-weight: 700;
}
.bs-llm-test-status.busy {
  color: var(--warn);
  font-weight: 700;
}
.bs-llm-test-result {
  margin: 8px 0 0;
  padding: 8px;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  font-size: 10px;
  line-height: 1.4;
  color: var(--tx-2);
  max-height: 240px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* =====================================================================
   🤖 AI CO-PILOT section (replaces the old "LLM config" details block)
   ---------------------------------------------------------------------
   Visual idiom: cards instead of dropdowns/numbers. The choice should
   feel like staffing a role on the bot's team, not configuring an API.
   Purple-tinted container (matches LLM iconography) with role cards,
   engine radio cards, and an activity dial. Locked engine cards show
   a desaturated state with a "Coming soon" tag — not clickable.
   ===================================================================== */
.bs-copilot-section {
  margin-top: 14px;
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  background: rgba(124, 58, 237, 0.04); /* faint purple tint */
}
/* HERO variant — when AI CO-PILOT sits at the top of the deploy panel
   it is the marquee feature, so it gets a louder treatment: bigger
   margin, brighter purple border, soft gradient, and a glow that
   announces "this is the special part of the product". The plain
   .bs-copilot-section variant is kept for any non-hero usages. */
.bs-copilot-hero {
  margin-top: 0;
  margin-bottom: 16px;
  border: 1px solid rgba(124, 58, 237, 0.55);
  border-radius: 6px;
  background: linear-gradient(
    180deg,
    rgba(124, 58, 237, 0.14) 0%,
    rgba(124, 58, 237, 0.05) 100%
  );
  box-shadow:
    0 0 0 1px rgba(124, 58, 237, 0.18),
    0 8px 24px -10px rgba(124, 58, 237, 0.45);
}
.bs-copilot-summary {
  list-style: none;
  cursor: pointer;
  padding: 8px 12px;
  user-select: none;
}
/* HERO SUMMARY — when collapsed, this is a single horizontal bar:
     [icon] [title + subtitle stack]                    [+ ADD pill]
   It carries all the visual weight (purple gradient, glow, big icon)
   so the section reads as the marquee feature WITHOUT expanding by
   default — that was eating the entire deploy panel and pushing the
   code editor + validate button out of view. The arrow ▸/▾ toggle
   from .bs-copilot-summary::before is hidden in hero mode because the
   "+ ADD" / "✕ HIDE" CTA pill carries that affordance instead. */
.bs-copilot-hero > .bs-copilot-summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
}
.bs-copilot-hero > .bs-copilot-summary::before {
  content: none;
}
.bs-copilot-hero-icon {
  font-size: 22px;
  line-height: 1;
  flex-shrink: 0;
  filter: drop-shadow(0 0 6px rgba(124, 58, 237, 0.55));
}
.bs-copilot-hero-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.bs-copilot-hero-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--tx-1);
  display: flex;
  align-items: center;
  gap: 8px;
}
.bs-copilot-hero-badge {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  padding: 2px 6px;
  border-radius: 10px;
  background: rgba(124, 58, 237, 0.4);
  color: #fff;
  border: 1px solid rgba(124, 58, 237, 0.65);
}
.bs-copilot-hero-sub {
  font-size: 11px;
  color: var(--tx-2);
  letter-spacing: 0.1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bs-copilot-hero-cta {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  padding: 6px 12px;
  border-radius: 14px;
  background: rgba(124, 58, 237, 0.85);
  color: #fff;
  border: 1px solid rgba(124, 58, 237, 1);
  box-shadow: 0 0 10px rgba(124, 58, 237, 0.5);
  white-space: nowrap;
}
.bs-copilot-section[open] > .bs-copilot-summary .bs-copilot-hero-cta::before {
  content: "✕ HIDE";
}
.bs-copilot-section[open] > .bs-copilot-summary .bs-copilot-hero-cta {
  font-size: 0; /* hide the "+ ADD" text; ::before above replaces it */
  padding: 6px 10px;
  background: rgba(124, 58, 237, 0.3);
  box-shadow: none;
}
.bs-copilot-section[open] > .bs-copilot-summary .bs-copilot-hero-cta::before {
  font-size: 10px;
}
.bs-copilot-summary::-webkit-details-marker {
  display: none;
}
.bs-copilot-summary::before {
  content: "▸ ";
  color: var(--tx-3);
  font-size: 10px;
  margin-right: 4px;
}
.bs-copilot-section[open] > .bs-copilot-summary::before {
  content: "▾ ";
}
.bs-copilot-summary code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.04);
  padding: 0 4px;
  border-radius: 2px;
}
.bs-copilot-body {
  padding: 4px 12px 12px;
  border-top: 1px solid var(--bd-2);
}
.bs-copilot-fm-hint {
  margin-top: 6px;
  padding: 6px 9px;
  font-size: 10px;
  line-height: 1.4;
  color: var(--tx-2);
  background: rgba(242, 163, 65, 0.08);
  border: 1px solid rgba(242, 163, 65, 0.25);
  border-radius: 3px;
}
.bs-copilot-fm-hint code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.06);
  padding: 0 4px;
  border-radius: 2px;
}
/* Pitch banner — sells the value of picking a role. Purple accent
   matches the section background tint so it reads as part of the
   AI surface rather than a warning. */
.bs-copilot-banner {
  margin-top: 10px;
  padding: 9px 12px;
  background: rgba(124, 58, 237, 0.08);
  border: 1px solid rgba(124, 58, 237, 0.3);
  border-radius: 3px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-2);
}
/* In hero mode the banner is the headline copy — bigger, brighter,
   so it reads as a value prop not a tooltip. */
.bs-copilot-hero .bs-copilot-banner {
  padding: 12px 14px;
  font-size: 12px;
  line-height: 1.55;
  background: rgba(124, 58, 237, 0.12);
  border: 1px solid rgba(124, 58, 237, 0.4);
  border-radius: 4px;
}
.bs-copilot-banner b {
  color: var(--tx-1);
}
/* Bot fundamentals header — the secondary section now sitting BELOW
   the AI CO-PILOT hero. Subdued so it doesn't compete for attention. */
.bs-fundamentals-h {
  margin-top: 6px;
  margin-bottom: 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  text-transform: uppercase;
}
.bs-copilot-banner code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.06);
  padding: 0 4px;
  border-radius: 2px;
}
/* Mini-section headers ("PICK A ROLE", "ENGINE", "ACTIVITY"). */
.bs-copilot-section-h {
  margin-top: 14px;
  margin-bottom: 6px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--tx-3);
}
.bs-copilot-section-h .cfg-section-sub {
  font-weight: 500;
  letter-spacing: 0.2px;
  color: var(--tx-3);
  text-transform: none;
}

/* ROLE CARDS — six tiles in a responsive grid. Active card glows
   purple (the AI accent). Click toggles activeness via JS. */
.bs-copilot-roles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 6px;
}
.bs-role-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 9px 10px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition:
    border-color 0.12s,
    background 0.12s,
    transform 0.06s;
}
.bs-role-card:hover {
  border-color: rgba(124, 58, 237, 0.45);
  background: rgba(124, 58, 237, 0.06);
}
.bs-role-card:active {
  transform: translateY(1px);
}
.bs-role-card.active {
  border-color: rgba(124, 58, 237, 0.75);
  background: rgba(124, 58, 237, 0.12);
  box-shadow: 0 0 0 1px rgba(124, 58, 237, 0.25);
}
.bs-role-icon {
  font-size: 18px;
  line-height: 1;
  margin-bottom: 2px;
}
.bs-role-name {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2px;
  color: var(--tx-1);
}
.bs-role-tag {
  font-size: 9.5px;
  line-height: 1.35;
  color: var(--tx-3);
}
.bs-role-card.active .bs-role-tag {
  color: var(--tx-2);
}

/* PERSONA DETAIL PANEL — appears below the role cards once a persona
   is picked. The point is to make the choice feel concrete: this is
   what you just hired, when to pick it, and which other features now
   behave differently because of this pick. Purple accent matches the
   AI Co-Pilot hero so the panel reads as part of the same module. */
.bs-copilot-persona-detail {
  margin-top: 10px;
  padding: 12px 14px;
  background: linear-gradient(
    180deg,
    rgba(124, 58, 237, 0.08) 0%,
    rgba(124, 58, 237, 0.03) 100%
  );
  border: 1px solid rgba(124, 58, 237, 0.3);
  border-left: 3px solid rgba(124, 58, 237, 0.7);
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bs-pp-h {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.bs-pp-icon {
  font-size: 24px;
  line-height: 1;
  flex-shrink: 0;
}
.bs-pp-h-text {
  flex: 1;
  min-width: 0;
}
.bs-pp-name {
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  letter-spacing: 0.2px;
  margin-bottom: 4px;
}
.bs-pp-desc {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--tx-2);
}
.bs-pp-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.bs-pp-section-h {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.8px;
  color: rgba(167, 139, 250, 1);
  text-transform: uppercase;
}
.bs-pp-section-sub {
  font-weight: 600;
  letter-spacing: 0.3px;
  text-transform: none;
  color: var(--tx-3);
  font-size: 9px;
}
.bs-pp-list {
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.bs-pp-list li {
  font-size: 10.5px;
  line-height: 1.45;
  color: var(--tx-2);
}
/* The "What it changes" list gets a green accent dot — it's the
   most important section because it's the one that connects the
   persona pick to the rest of the AI features. */
.bs-pp-list-affects li::marker {
  color: rgba(34, 197, 94, 0.85);
  font-weight: 800;
}

/* Custom system prompt textarea — only shown when "Custom" picked.
   Matches the LLM test block's textarea styling for consistency. */
.bs-copilot-custom {
  margin-top: 8px;
  padding: 8px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
}
.bs-copilot-custom textarea {
  width: 100%;
  margin-top: 4px;
  padding: 6px 8px;
  font-size: 11px;
  font-family: var(--font-mono, ui-monospace, monospace);
  background: var(--bg-panel);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  box-sizing: border-box;
  resize: vertical;
  min-height: 60px;
}
.bs-copilot-custom textarea:focus {
  outline: none;
  border-color: rgba(124, 58, 237, 0.6);
}

/* ENGINE CARDS — radio inputs styled as cards. Locked variant for
   "Coming soon" engines is desaturated and not clickable. */
.bs-copilot-engines {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 6px;
}
.bs-engine-opt {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 8px 10px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  cursor: pointer;
  font-family: inherit;
  transition:
    border-color 0.12s,
    background 0.12s;
}
.bs-engine-opt:hover:not(.locked) {
  border-color: rgba(124, 58, 237, 0.45);
  background: rgba(124, 58, 237, 0.06);
}
.bs-engine-opt input[type="radio"] {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
}
.bs-engine-opt.active {
  border-color: rgba(124, 58, 237, 0.75);
  background: rgba(124, 58, 237, 0.12);
  box-shadow: 0 0 0 1px rgba(124, 58, 237, 0.25);
}
.bs-engine-opt.locked {
  opacity: 0.42;
  cursor: not-allowed;
  background: var(--bg-panel);
}
.bs-engine-opt.locked:hover {
  border-color: var(--bd-2);
  background: var(--bg-panel);
}
.bs-engine-icon {
  font-size: 14px;
  line-height: 1;
  margin-bottom: 2px;
}
.bs-engine-name {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2px;
  color: var(--tx-1);
}
.bs-engine-tag {
  font-size: 9.5px;
  color: var(--tx-3);
}
.bs-engine-opt.locked .bs-engine-tag {
  color: var(--warn);
  font-weight: 700;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  font-size: 9px;
}

/* ACTIVITY DIAL — three-button segmented row. Click sets active. */
.bs-copilot-activity {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 6px;
}
.bs-activity-opt {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 8px 10px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition:
    border-color 0.12s,
    background 0.12s;
}
.bs-activity-opt:hover {
  border-color: rgba(124, 58, 237, 0.45);
  background: rgba(124, 58, 237, 0.06);
}
.bs-activity-opt.active {
  border-color: rgba(124, 58, 237, 0.75);
  background: rgba(124, 58, 237, 0.12);
  box-shadow: 0 0 0 1px rgba(124, 58, 237, 0.25);
}
.bs-activity-icon {
  font-size: 14px;
  line-height: 1;
}
.bs-activity-name {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2px;
  color: var(--tx-1);
}
.bs-activity-tag {
  font-size: 9.5px;
  color: var(--tx-3);
}
.bs-activity-opt.active .bs-activity-tag {
  color: var(--tx-2);
}
/* Concrete numbers — what the dial actually MEANS in machine terms.
   Mono so the digits align across the three options when stacked. */
.bs-activity-rate {
  font-family: var(--ff-mn);
  font-size: 9px;
  letter-spacing: 0.4px;
  color: var(--tx-3);
  margin-top: 1px;
}
.bs-activity-rate b {
  color: var(--tx-2);
  font-weight: 700;
}
.bs-activity-opt.active .bs-activity-rate b {
  color: #c4a4ff;
}

/* TEST block — same shape as the old .bs-llm-test, alias names so the
   test prompt area still uses the existing input/textarea styles. */
.bs-copilot-test {
  margin-top: 14px;
  padding: 10px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
}
.bs-copilot-test-h {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--tx-2);
  margin-bottom: 6px;
}
.bs-copilot-test textarea,
.bs-copilot-test input[type="text"] {
  width: 100%;
  margin-bottom: 6px;
  padding: 6px 8px;
  font-size: 11px;
  font-family: var(--font-mono, ui-monospace, monospace);
  background: var(--bg-panel);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  box-sizing: border-box;
  resize: vertical;
}
.bs-copilot-test textarea:focus,
.bs-copilot-test input[type="text"]:focus {
  outline: none;
  border-color: rgba(124, 58, 237, 0.6);
}
.bs-copilot-test-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}
/* MOCK toggle next to the TEST button. Border (not fill) when off so
   the row's height is stable as it toggles. When checked, picks up the
   persona-purple accent used elsewhere in AI CO-PILOT — at a glance,
   the row reads "you're in mock mode, the next click won't burn quota". */
.bs-llm-mock-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 1px solid var(--bd);
  border-radius: 4px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--tx-2);
  font-family: var(--ff-mn);
  cursor: pointer;
  user-select: none;
  transition:
    border-color 0.12s,
    color 0.12s,
    background-color 0.12s;
}
.bs-llm-mock-toggle:hover {
  border-color: var(--tx-2);
  color: var(--tx-1);
}
.bs-llm-mock-toggle input[type="checkbox"] {
  margin: 0;
  accent-color: rgba(124, 58, 237, 0.9);
  cursor: pointer;
}
.bs-llm-mock-toggle:has(input:checked) {
  border-color: rgba(124, 58, 237, 0.6);
  color: rgba(167, 139, 250, 1);
  background: rgba(124, 58, 237, 0.08);
}
/* Sample-prompt insert chips — one click pre-fills the prompt + schema
   with a realistic bar-tick scenario so the author doesn't have to
   invent one. Compact pills that don't compete with the test button. */
.bs-copilot-test-samples {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: -2px 0 6px;
}
.bs-copilot-test-samples-h {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--tx-3);
}
.bs-copilot-test-sample {
  background: transparent;
  border: 1px solid var(--bd-2);
  border-radius: 12px;
  padding: 2px 8px;
  color: var(--tx-2);
  font-family: var(--ff-mn);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition:
    border-color 0.12s,
    background 0.12s,
    color 0.12s;
}
.bs-copilot-test-sample:hover {
  border-color: rgba(124, 58, 237, 0.55);
  background: rgba(124, 58, 237, 0.08);
  color: #c4a4ff;
}
/* "What the AI sees" — collapsible preview of the persona-merged
   system prompt + user prompt before/after the call. Lets the author
   verify the role applied without trusting the response alone. */
.bs-llm-prompt-preview {
  margin-top: 8px;
  background: rgba(124, 58, 237, 0.05);
  border: 1px solid rgba(124, 58, 237, 0.25);
  border-radius: 3px;
  padding: 6px 10px;
}
.bs-llm-prompt-preview > summary {
  cursor: pointer;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--tx-2);
  list-style: none;
  outline: none;
}
.bs-llm-prompt-preview > summary::-webkit-details-marker {
  display: none;
}
.bs-llm-pp-meta {
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 600;
  color: var(--tx-3);
  margin-left: 6px;
}
.bs-llm-pp-row {
  margin-top: 8px;
}
.bs-llm-pp-k {
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--tx-3);
  margin-bottom: 3px;
}
.bs-llm-pp-v {
  margin: 0;
  padding: 6px 8px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  font-size: 10px;
  line-height: 1.45;
  color: var(--tx-1);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 180px;
  overflow-y: auto;
}

/* =====================================================================
   ✨ AI CONVERT pane (Bot Studio · 4th method tab)
   ---------------------------------------------------------------------
   Paste Pine / Python / MQL / plain-English → LLM rewrites as JS →
   user reviews and copies into CODE PASTE for normal validate+deploy.
   Visual idiom matches the LLM-test block above (faint accent banner,
   bordered preview, status chip with .ok/.err/.busy variants).
   ===================================================================== */
.bs-method-langs {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  font-size: 8px;
  letter-spacing: 0.3px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
  vertical-align: 1px;
}
.bs-method-tabs button.active .bs-method-langs {
  background: rgba(0, 0, 0, 0.18);
}

/* Loud info banner — orange because this is a "be careful" surface */
.bs-convert-banner {
  padding: 10px 12px;
  margin-bottom: 10px;
  background: rgba(242, 163, 65, 0.1);
  border: 1px solid rgba(242, 163, 65, 0.32);
  border-radius: 3px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-2);
  flex-shrink: 0;
}
.bs-convert-banner b {
  color: var(--tx-1);
}
.bs-convert-banner code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  background: rgba(255, 255, 255, 0.06);
  padding: 0 4px;
  border-radius: 2px;
}

/* Top row: detected-language chip on the left, model selector on the right */
.bs-convert-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
  flex-shrink: 0;
}
.bs-convert-detected {
  flex: 1;
  padding: 5px 9px;
  font-size: 10px;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  color: var(--tx-3);
}
/* Detection-specific tints — same palette as the legacy strategies modal
   so users who recognised it there get the same visual cue. */
.bs-convert-detected.detected-pine-script {
  color: #38bdf8;
  border-color: rgba(56, 189, 248, 0.4);
  background: rgba(56, 189, 248, 0.08);
}
.bs-convert-detected.detected-python {
  color: #3776ab;
  border-color: rgba(55, 118, 171, 0.4);
  background: rgba(55, 118, 171, 0.1);
}
.bs-convert-detected.detected-mql {
  color: #eab308;
  border-color: rgba(234, 179, 8, 0.4);
  background: rgba(234, 179, 8, 0.1);
}
.bs-convert-detected.detected-plain-english {
  color: var(--up);
  border-color: rgba(31, 203, 107, 0.4);
  background: rgba(31, 203, 107, 0.08);
}
.bs-convert-detected.detected-unknown {
  color: var(--warn);
  border-color: rgba(242, 163, 65, 0.4);
  background: rgba(242, 163, 65, 0.08);
}

.bs-convert-model-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--tx-3);
}
.bs-convert-model-label select {
  padding: 4px 8px;
  font-size: 10px;
  background: var(--bg-panel);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
}

/* Source textarea — flex-grows to fill the pane like #bs-paste-area */
#bs-convert-source {
  flex: 1;
  min-height: 200px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12px;
  line-height: 1.5;
  padding: 10px 12px;
  border-radius: 2px;
  box-sizing: border-box;
  resize: vertical;
  margin-bottom: 8px;
}
#bs-convert-source:focus {
  outline: none;
  border-color: rgba(242, 163, 65, 0.6);
}

.bs-convert-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  flex-shrink: 0;
}
.bs-convert-status {
  flex: 1;
  font-size: 10px;
  color: var(--tx-3);
}
.bs-convert-status.ok {
  color: var(--up);
  font-weight: 700;
}
.bs-convert-status.err {
  color: var(--down);
  font-weight: 700;
}
.bs-convert-status.busy {
  color: var(--warn);
  font-weight: 700;
}

/* Result block — header with copy button + scrollable preview */
.bs-convert-result {
  display: flex;
  flex-direction: column;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  flex-shrink: 0;
}
.bs-convert-result-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--bd-2);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--tx-2);
}
.bs-convert-result-pre {
  margin: 0;
  padding: 10px 12px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-1);
  max-height: 320px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  background: var(--bg-base);
}

/* =====================================================================
   ✨ AI BUILD — sits at the top of the MANUAL BUILDER pane.
   Same visual language as the AI CONVERT banner (orange "be careful"
   accent) so users register that this is also LLM-generated output and
   the builder fields below are about to mutate. The input row uses the
   builder pane's own bg so it doesn't fight with .bsb-grid below it.
   ===================================================================== */
.bsb-ai-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px dashed var(--bd-2);
  flex-shrink: 0;
}
.bsb-ai-banner {
  padding: 9px 12px;
  background: rgba(242, 163, 65, 0.1);
  border: 1px solid rgba(242, 163, 65, 0.32);
  border-radius: 3px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--tx-2);
}
.bsb-ai-banner b {
  color: var(--tx-1);
}
.bsb-ai-input {
  display: flex;
  gap: 8px;
  align-items: center;
}
.bsb-ai-input input {
  flex: 1;
  padding: 7px 10px;
  font-size: 12px;
  background: var(--bg-base);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 2px;
  font-family: var(--font-sans, system-ui, sans-serif);
}
.bsb-ai-input input:focus {
  outline: none;
  border-color: rgba(242, 163, 65, 0.6);
}
.bsb-ai-status {
  font-size: 10px;
  color: var(--tx-3);
  min-height: 14px;
}
.bsb-ai-status.ok {
  color: var(--up);
  font-weight: 700;
}
.bsb-ai-status.err {
  color: var(--down);
  font-weight: 700;
}
.bsb-ai-status.busy {
  color: var(--warn);
  font-weight: 700;
}
.bsb-ai-status.warn {
  color: var(--warn);
  font-weight: 700;
}
/* Infeasible-fallback button — appears next to status when LLM says
   the description can't fit the builder schema. */
.bsb-ai-fallback-btn {
  margin-left: 8px;
  font-size: 10px;
  padding: 3px 8px;
  background: rgba(242, 163, 65, 0.12);
  border: 1px solid rgba(242, 163, 65, 0.45);
  color: var(--warn);
  border-radius: 2px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 700;
  letter-spacing: 0.3px;
}
.bsb-ai-fallback-btn:hover {
  background: rgba(242, 163, 65, 0.22);
}

/* hub-button styling: orange accent */
#bot-hub-btn,
#new-bot-btn {
  background: rgba(242, 163, 65, 0.12);
  color: var(--orange);
  border: 1px solid rgba(242, 163, 65, 0.4);
}
#bot-hub-btn:hover,
#new-bot-btn:hover {
  background: rgba(242, 163, 65, 0.2);
}

/* =========================================================================
   BOTS DOCK — futuristic / neon HUD aesthetic
   Bots are distinct from strategies: glassy gradient backgrounds, corner
   HUD brackets, neon cyan accents, animated pulse for running bots.
   ========================================================================= */
.bots-dock {
  position: relative;
  background:
    radial-gradient(
      ellipse at top left,
      rgba(24, 191, 217, 0.05) 0%,
      transparent 60%
    ),
    radial-gradient(
      ellipse at bottom right,
      rgba(167, 139, 250, 0.04) 0%,
      transparent 60%
    ),
    var(--bg-panel);
}
.bots-dock::before {
  /* faint grid pattern */
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(24, 191, 217, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(24, 191, 217, 0.04) 1px, transparent 1px);
  background-size: 24px 24px;
  pointer-events: none;
  z-index: 0;
}
.bots-dock > * {
  position: relative;
  z-index: 1;
}
.bots-dock .dock-h {
  background: linear-gradient(
    90deg,
    rgba(24, 191, 217, 0.1) 0%,
    rgba(167, 139, 250, 0.06) 100%
  );
  border-bottom: 1px solid rgba(24, 191, 217, 0.25);
}
.bots-dock .dock-h > span:first-child {
  color: var(--info);
  text-shadow: 0 0 8px rgba(24, 191, 217, 0.55);
  font-weight: 800;
}
.bots-dock .dock-h .d-count {
  background: rgba(24, 191, 217, 0.18);
  color: var(--info);
  border: 1px solid rgba(24, 191, 217, 0.35);
  box-shadow: 0 0 6px rgba(24, 191, 217, 0.25);
}
.bots-dock .dock-h #bots-running-count {
  color: var(--info);
  font-weight: 800;
}
.bots-dock .dock-h #bots-paused-count {
  color: var(--warn);
  font-weight: 800;
}

#bot-hub-btn,
#new-bot-btn {
  background: linear-gradient(
    135deg,
    rgba(24, 191, 217, 0.2) 0%,
    rgba(167, 139, 250, 0.2) 100%
  );
  color: var(--info);
  border: 1px solid rgba(24, 191, 217, 0.5);
  text-shadow: 0 0 6px rgba(24, 191, 217, 0.5);
  letter-spacing: 0.6px;
}
#bot-hub-btn:hover,
#new-bot-btn:hover {
  background: linear-gradient(
    135deg,
    rgba(24, 191, 217, 0.35) 0%,
    rgba(167, 139, 250, 0.35) 100%
  );
  box-shadow: 0 0 12px rgba(24, 191, 217, 0.5);
}

/* ---- CARD ---- */
.bot-hero-card {
  position: relative;
  background:
    linear-gradient(
      135deg,
      rgba(24, 191, 217, 0.05) 0%,
      transparent 30%,
      rgba(167, 139, 250, 0.04) 80%
    ),
    linear-gradient(180deg, rgba(255, 255, 255, 0.02) 0%, transparent 100%),
    #0a0f18;
  /* Thicker, slightly brighter cyan border so each bot card reads as
     a substantial panel, matching the strategy-card weight. */
  border: 2px solid rgba(24, 191, 217, 0.45);
  border-radius: 10px;
  overflow: hidden;
  /* Hover transition only on real-mouse devices — see note on
     .strat-hero-card. Touch-screen scroll fires repeated hover
     repaints across the cards under the finger which causes
     stuttering on the box-shadow + transform. */
  transition: border-color 0.18s;
  /* Floor was 235→130→80→88→118px as the card content evolved.
     Bumped to 118px in the height-up redesign so the 44×44 icon
     and the stacked pnl + 32×32 actions sit comfortably with the
     decorative watermark robot in the corner — gives the whole
     card real "panel" weight instead of the previous compact strip. */
  min-height: 118px;
  /* Local stacking context so the .bot-robot-watermark with z-index:-1
     renders behind the card's content but inside the card's own layer. */
  isolation: isolate;
  /* layout+style only — paint containment + content-visibility:auto
     caused empty card shells during fast scroll (border/background
     painted, inner content deferred). */
  contain: layout style;
}
@media (hover: hover) and (pointer: fine) {
  .bot-hero-card {
    transition:
      border-color 0.18s,
      box-shadow 0.18s,
      transform 0.18s;
  }
}

/* Watermark robot — behind all content, low opacity, decorative only.
   Lives in the bottom-right corner. drop-shadow filters were removed —
   the icon already has its own SVG glow paths and the filter was forcing
   a per-frame paint that made scrolling janky on cards with running
   SMIL animations. */
.bot-hero-card .bot-robot-watermark {
  position: absolute;
  /* Tucked just past the card edge so it reads as a corner flourish
     rather than a competing element next to the action buttons. */
  bottom: -8px;
  right: -8px;
  /* Card grew 88→118px in the height-up redesign — bumped the
     watermark 48→62px to keep its presence proportional to the
     card without overpowering the foreground content. */
  width: 62px;
  height: 62px;
  opacity: 0.12;
  pointer-events: none;
  z-index: -1;
  /* Cheaper than drop-shadow: contain paint so the SVG doesn't trigger
     re-layout in siblings during scroll. */
  contain: layout paint;
}
.bot-hero-card.status-paused .bot-robot-watermark {
  opacity: 0.08;
}
.bot-hero-card.status-killed .bot-robot-watermark {
  opacity: 0.04;
  filter: grayscale(0.7);
}
@media (hover: hover) and (pointer: fine) {
  .bot-hero-card:hover {
    border-color: rgba(24, 191, 217, 0.65);
    box-shadow:
      0 0 18px rgba(24, 191, 217, 0.25),
      inset 0 0 24px rgba(24, 191, 217, 0.04);
    transform: translateY(-1px);
  }
}
/* HUD corner brackets */
.bot-hero-card::before,
.bot-hero-card::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border-color: var(--info);
  border-style: solid;
  pointer-events: none;
  opacity: 0.85;
  transition: opacity 0.2s;
}
/* Pushed inward 2px from the previous 4px to clear the new 10px
   border-radius — sitting flush against the rounder corner the
   brackets read as deliberate accents, not as overshooting decoration. */
.bot-hero-card::before {
  top: 6px;
  left: 6px;
  border-width: 1px 0 0 1px;
}
.bot-hero-card::after {
  bottom: 6px;
  right: 6px;
  border-width: 0 1px 1px 0;
}
@media (hover: hover) and (pointer: fine) {
  .bot-hero-card:hover::before,
  .bot-hero-card:hover::after {
    opacity: 1;
  }
}

/* Running state — solid cyan border, status dot pulses (cheaper than the
   previous box-shadow animation that fired a full repaint twice per cycle
   on every running card and hurt scroll performance). */
.bot-hero-card.status-running {
  border-color: rgba(24, 191, 217, 0.55);
  box-shadow: 0 0 0 1px rgba(24, 191, 217, 0.1);
}
.bot-hero-card.status-running > .shc-dot::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid rgba(24, 191, 217, 0.6);
  animation: botDotRing 1.8s ease-out infinite;
  /* Confine the ring's repaint scope so it doesn't dirty the parent card */
  contain: layout paint;
}
@keyframes botDotRing {
  0% {
    transform: scale(0.8);
    opacity: 1;
  }
  100% {
    transform: scale(2);
    opacity: 0;
  }
}

/* Paused state — magenta accent */
.bot-hero-card.status-paused {
  border-color: rgba(242, 163, 65, 0.4);
  background:
    linear-gradient(135deg, rgba(242, 163, 65, 0.04) 0%, transparent 60%),
    #0a0f18;
}
.bot-hero-card.status-paused::before,
.bot-hero-card.status-paused::after {
  border-color: var(--warn);
}

/* Killed state — desaturated */
.bot-hero-card.status-killed {
  border-color: rgba(106, 115, 132, 0.35);
  background: #0a0d13;
  opacity: 0.65;
}
.bot-hero-card.status-killed::before,
.bot-hero-card.status-killed::after {
  border-color: var(--tx-3);
}

/* Tighten the inner card typography (overrides .strat-hero-card defaults).
   Most of the per-element overrides moved up into the redesigned shared
   .strat-hero-card rules; what remains here are bot-only flourishes
   (cyan/neon palette swaps for running, monospace name, glow PNLs).

   Legacy .shc-dot is now display:none in the shared rules — the status
   indicator is the .shc-icon-box. The old .bot-hero-card .shc-dot rules
   are gone with it. */
.bot-hero-card .shc-name {
  font-family: var(--ff-mn);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--tx-1);
}
/* Bot icon-box — overrides the strategy status colors with the cyan
   identity color for running bots, since the bot palette is cyan/neon
   (vs strategies' teal/orange/red). Running bots get a glowing cyan
   square; paused/killed inherit the shared status colors. */
.bot-hero-card .shc-icon-box.status-running {
  color: var(--info);
  background: rgba(24, 191, 217, 0.12);
  box-shadow:
    inset 0 0 14px rgba(24, 191, 217, 0.18),
    0 0 8px rgba(24, 191, 217, 0.2);
}
/* SVG bot mascot inside the 44×44 icon-box: scale to fit, center, and
   inherit the box's currentColor for the SVG strokes/glows. */
.bot-hero-card .shc-icon-box .shc-bot-icon {
  width: 26px;
  height: 26px;
  display: block;
}
.bot-hero-card .shc-status-pill.running {
  color: var(--info);
  background: linear-gradient(
    90deg,
    rgba(24, 191, 217, 0.18),
    rgba(24, 191, 217, 0.06)
  );
  border-color: rgba(24, 191, 217, 0.55);
  text-shadow: 0 0 6px rgba(24, 191, 217, 0.7);
}
.bot-hero-card .shc-pnl {
  font-family: var(--ff-mn);
  letter-spacing: 0.5px;
}
.bot-hero-card .shc-pnl.up {
  color: var(--info);
  text-shadow: 0 0 10px rgba(24, 191, 217, 0.5);
}
.bot-hero-card .shc-pnl.down {
  color: #ff6e91;
  text-shadow: 0 0 10px rgba(255, 110, 145, 0.4);
}

/* Sub-tags styled as data chips */
.bot-hero-card .shc-sub-tag {
  background: rgba(24, 191, 217, 0.08);
  border: 1px solid rgba(24, 191, 217, 0.25);
  color: var(--info);
  padding: 1px 6px;
  font-family: var(--ff-mn);
  font-size: 9px;
  letter-spacing: 0.4px;
  border-radius: 2px;
}
.bot-hero-card .shc-sub-tag.kind {
  background: rgba(167, 139, 250, 0.1);
  border-color: rgba(167, 139, 250, 0.35);
  color: var(--purple);
}
.bot-hero-card .shc-sub-tag.tf {
  background: transparent;
  border-color: rgba(106, 115, 132, 0.4);
  color: var(--tx-2);
}

/* Stats — flat inline row (was a cyan-tinted box; stripped to match
   the simplified strategy-card stats — same data, less chrome). */
.bot-hero-card .shc-stats {
  background: transparent;
  border: 0;
  padding: 0;
}
.bot-hero-card .shc-stat-k {
  color: var(--info);
  text-shadow: 0 0 4px rgba(24, 191, 217, 0.4);
  font-size: 9px;
}
.bot-hero-card .shc-stat-v {
  color: var(--tx-1);
}

/* Buttons — cyan/neon, more compact so all 4 fit on one row */
.bot-hero-card .shc-btn {
  background: rgba(24, 191, 217, 0.06);
  border: 1px solid rgba(24, 191, 217, 0.3);
  color: var(--info);
  letter-spacing: 0.4px;
  font-family: var(--ff-mn);
  text-transform: uppercase;
  transition: all 0.15s;
  padding: 4px 7px;
  font-size: 9px;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}
.bot-hero-card .shc-actions {
  flex-wrap: nowrap;
  gap: 3px;
  min-width: 0;
}
.bot-hero-card .shc-btn {
  text-overflow: ellipsis;
  overflow: hidden;
}
.bot-hero-card .shc-btn:hover {
  background: rgba(24, 191, 217, 0.15);
  border-color: var(--info);
  box-shadow: 0 0 10px rgba(24, 191, 217, 0.35);
}
.bot-hero-card .shc-btn.primary {
  background: linear-gradient(
    135deg,
    rgba(24, 191, 217, 0.3),
    rgba(167, 139, 250, 0.2)
  );
  color: #e6f9fc;
  border-color: var(--info);
  text-shadow: 0 0 6px rgba(24, 191, 217, 0.6);
}
.bot-hero-card .shc-btn.primary:hover {
  background: linear-gradient(
    135deg,
    rgba(24, 191, 217, 0.5),
    rgba(167, 139, 250, 0.35)
  );
  box-shadow: 0 0 14px rgba(24, 191, 217, 0.55);
}
.bot-hero-card .shc-btn.kill {
  background: rgba(242, 62, 85, 0.08);
  border-color: rgba(242, 62, 85, 0.35);
  color: #ff6e91;
}
.bot-hero-card .shc-btn.kill:hover {
  background: rgba(242, 62, 85, 0.2);
  border-color: var(--down);
  box-shadow: 0 0 10px rgba(242, 62, 85, 0.4);
}

/* "+ NEW BOT" add card — matching HUD aesthetic */
.bot-hero-add {
  position: relative;
  background:
    linear-gradient(
      135deg,
      rgba(24, 191, 217, 0.04),
      transparent 50%,
      rgba(167, 139, 250, 0.04)
    ),
    #0a0f18 !important;
  border: 1px dashed rgba(24, 191, 217, 0.4) !important;
  color: var(--info);
  transition: all 0.18s;
}
.bot-hero-add::before,
.bot-hero-add::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border-color: var(--info);
  border-style: solid;
  opacity: 0.6;
}
.bot-hero-add::before {
  top: 4px;
  left: 4px;
  border-width: 1px 0 0 1px;
}
.bot-hero-add::after {
  bottom: 4px;
  right: 4px;
  border-width: 0 1px 1px 0;
}
.bot-hero-add:hover {
  border-color: var(--info) !important;
  background:
    linear-gradient(
      135deg,
      rgba(24, 191, 217, 0.12),
      transparent 50%,
      rgba(167, 139, 250, 0.12)
    ),
    #0a0f18 !important;
  box-shadow: 0 0 16px rgba(24, 191, 217, 0.3);
}
.bot-hero-add .sha-icon {
  color: var(--info);
  text-shadow: 0 0 12px rgba(24, 191, 217, 0.7);
  filter: drop-shadow(0 0 6px rgba(24, 191, 217, 0.5));
  animation: botSpark 3s ease-in-out infinite;
}
@keyframes botSpark {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.85;
  }
  50% {
    transform: scale(1.08);
    opacity: 1;
  }
}
.bot-hero-add .sha-title {
  color: var(--info);
  text-shadow: 0 0 8px rgba(24, 191, 217, 0.5);
  letter-spacing: 0.8px;
}
.bot-hero-add .sha-sub {
  color: rgba(167, 139, 250, 0.85);
  letter-spacing: 1px;
}

/* =========================================================================
   BOTS empty-state template strip (Fix #10) — when there are no deployed
   bots yet, the dashboard BOTS peer dock shows a mini template grid
   instead of a lonely "+ NEW BOT" card. Mirrors the Bot Hub empty state
   in compressed form.
   ========================================================================= */
.bots-empty-hero {
  grid-column: 1 / -1;
  background:
    linear-gradient(
      135deg,
      rgba(24, 191, 217, 0.05),
      transparent 60%,
      rgba(167, 139, 250, 0.05)
    ),
    rgba(10, 15, 24, 0.6);
  border: 1px dashed rgba(24, 191, 217, 0.35);
  border-radius: 6px;
  padding: 18px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bots-empty-hero .beh-h {
  font-weight: 800;
  font-size: 13px;
  color: var(--info);
  letter-spacing: 0.6px;
  text-shadow: 0 0 10px rgba(24, 191, 217, 0.4);
}
.bots-empty-hero .beh-p {
  font-size: 11.5px;
  color: var(--tx-2);
  line-height: 1.45;
  max-width: 540px;
}
.bots-tpl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  margin-top: 4px;
}
.bots-tpl-card {
  background: rgba(10, 15, 24, 0.85);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  padding: 10px 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  cursor: pointer;
  text-align: left;
  transition: all 0.14s;
  color: var(--tx-1);
  font-family: inherit;
}
.bots-tpl-card:hover {
  border-color: var(--info);
  background: rgba(24, 191, 217, 0.06);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(24, 191, 217, 0.18);
}
.bots-tpl-card .btc-icon {
  font-size: 16px;
}
.bots-tpl-card .btc-name {
  font-weight: 700;
  font-size: 10.5px;
  color: var(--tx-1);
  letter-spacing: 0.3px;
  line-height: 1.25;
}
.bots-tpl-card .btc-sym {
  font-size: 9.5px;
  font-family: var(--ff-mn);
  color: var(--tx-3);
  letter-spacing: 0.6px;
  margin-top: 2px;
}
.bots-empty-hero .beh-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 14px;
  border-top: 1px solid var(--bd-1);
  padding-top: 18px;
  align-items: center;
}
/* New users see this as one of their two main paths (template OR
   custom code), so the buttons need to read like real CTAs, not
   inline footnotes. Bumped from 10px / 6px-padding to 13px / 12-20-padding,
   and the "write your own" gets a distinct purple accent so it
   stands as a peer to the cyan "see all templates" button rather
   than disappearing as muted gray. */
.beh-see-all,
.beh-write-own {
  font-size: 13px;
  font-family: var(--ff-ui);
  font-weight: 600;
  letter-spacing: 0.2px;
  padding: 12px 20px;
  border-radius: 6px;
  cursor: pointer;
  transition:
    background 0.18s,
    border-color 0.18s,
    color 0.18s,
    transform 0.18s;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.beh-see-all {
  background: rgba(24, 191, 217, 0.1);
  border: 1px solid rgba(24, 191, 217, 0.4);
  color: var(--info);
}
.beh-see-all:hover {
  background: rgba(24, 191, 217, 0.2);
  border-color: var(--info);
  color: var(--tx-1);
  transform: translateY(-1px);
}
.beh-write-own {
  background: rgba(167, 139, 250, 0.1);
  border: 1px solid rgba(167, 139, 250, 0.4);
  color: rgba(196, 181, 253, 1);
}
.beh-write-own:hover {
  background: rgba(167, 139, 250, 0.22);
  border-color: rgba(167, 139, 250, 0.85);
  color: var(--tx-1);
  transform: translateY(-1px);
}

/* =========================================================================
   BOT ROBOT MASCOT — pure CSS, animated, state-aware
   ========================================================================= */
.bot-robot {
  position: absolute;
  top: 34px;
  right: 12px;
  width: 28px;
  pointer-events: none;
  z-index: 2;
  filter: drop-shadow(0 0 5px rgba(24, 191, 217, 0.45));
  animation: brBob 3.5s ease-in-out infinite;
}
@keyframes brBob {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-2px);
  }
}
.br-antenna {
  width: 1px;
  height: 5px;
  background: var(--info);
  margin: 0 auto;
  position: relative;
}
.br-antenna::after {
  content: "";
  position: absolute;
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #00ff9a;
  box-shadow:
    0 0 7px #00ff9a,
    0 0 12px rgba(0, 255, 154, 0.6);
  animation: brTip 1.3s ease-in-out infinite;
}
@keyframes brTip {
  0%,
  100% {
    opacity: 1;
    transform: translateX(-50%) scale(1);
  }
  50% {
    opacity: 0.45;
    transform: translateX(-50%) scale(0.7);
  }
}
.br-head {
  position: relative;
  width: 28px;
  height: 20px;
  border-radius: 5px 5px 4px 4px;
  background:
    linear-gradient(
      180deg,
      rgba(24, 191, 217, 0.25) 0%,
      rgba(24, 191, 217, 0.05) 100%
    ),
    #0a0f18;
  border: 1px solid rgba(24, 191, 217, 0.65);
  overflow: hidden;
}
/* Scanline inside head — convey "thinking/processing" */
.br-head::before {
  content: "";
  position: absolute;
  left: 2px;
  right: 2px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--info), transparent);
  top: 0;
  animation: brHeadScan 1.6s linear infinite;
  opacity: 0.85;
}
@keyframes brHeadScan {
  0% {
    top: 2px;
    opacity: 0;
  }
  10% {
    opacity: 0.9;
  }
  90% {
    opacity: 0.9;
  }
  100% {
    top: 18px;
    opacity: 0;
  }
}
.br-eyes {
  position: absolute;
  top: 6px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 6px;
}
.br-eye {
  display: block;
  width: 4px;
  height: 4px;
  background: var(--info);
  border-radius: 50%;
  box-shadow:
    0 0 5px var(--info),
    0 0 8px rgba(24, 191, 217, 0.5);
  animation: brEyeBlink 4.6s ease-in-out infinite;
  transform-origin: center;
}
.br-eye:last-child {
  animation-delay: 0.05s;
}
@keyframes brEyeBlink {
  0%,
  88%,
  100% {
    transform: scaleY(1);
  }
  91%,
  95% {
    transform: scaleY(0.1);
  }
}
.br-mouth {
  position: absolute;
  bottom: 3px;
  left: 50%;
  transform: translateX(-50%);
  width: 9px;
  height: 1px;
  background: rgba(24, 191, 217, 0.7);
  border-radius: 1px;
  animation: brMouth 5s ease-in-out infinite;
}
@keyframes brMouth {
  0%,
  80%,
  100% {
    width: 9px;
    height: 1px;
  }
  85% {
    width: 5px;
    height: 2px;
    border-radius: 50%;
  }
  90% {
    width: 9px;
    height: 1px;
  }
}
/* Decorative scan strip under the head — like a status readout LED bar */
.br-scan {
  height: 1px;
  margin: 1px auto 0;
  width: 22px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--info) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: brBarScan 1.8s linear infinite;
  opacity: 0.7;
}
@keyframes brBarScan {
  0% {
    background-position: 100% 0;
  }
  100% {
    background-position: -100% 0;
  }
}

/* PAUSED — robot freezes in amber, no animations */
.bot-hero-card.status-paused .bot-robot {
  animation: none;
  filter: drop-shadow(0 0 4px rgba(242, 163, 65, 0.4));
}
.bot-hero-card.status-paused .br-antenna {
  background: var(--warn);
}
.bot-hero-card.status-paused .br-antenna::after {
  background: var(--warn);
  box-shadow: 0 0 6px var(--warn);
  animation: none;
}
.bot-hero-card.status-paused .br-head {
  border-color: rgba(242, 163, 65, 0.55);
  background:
    linear-gradient(180deg, rgba(242, 163, 65, 0.18), rgba(242, 163, 65, 0.04)),
    #0a0f18;
}
.bot-hero-card.status-paused .br-head::before {
  animation: none;
  opacity: 0;
}
.bot-hero-card.status-paused .br-eye {
  background: var(--warn);
  box-shadow: 0 0 4px var(--warn);
  animation: none;
}
.bot-hero-card.status-paused .br-mouth {
  background: rgba(242, 163, 65, 0.6);
  animation: none;
}
.bot-hero-card.status-paused .br-scan {
  animation: none;
  opacity: 0.3;
  background: linear-gradient(90deg, transparent, var(--warn), transparent);
}

/* KILLED — robot is dim/dead, no light, slight tilt */
.bot-hero-card.status-killed .bot-robot {
  animation: none;
  filter: none;
  opacity: 0.35;
  transform: rotate(8deg);
}
.bot-hero-card.status-killed .br-antenna {
  background: var(--tx-3);
}
.bot-hero-card.status-killed .br-antenna::after {
  background: var(--tx-3);
  box-shadow: none;
  animation: none;
}
.bot-hero-card.status-killed .br-head {
  border-color: rgba(106, 115, 132, 0.5);
  background: #0a0d13;
}
.bot-hero-card.status-killed .br-head::before {
  animation: none;
  opacity: 0;
}
.bot-hero-card.status-killed .br-eye {
  background: var(--tx-3);
  box-shadow: none;
  animation: none;
  /* X-ed out eyes for a "dead" look */
  width: 5px;
  height: 1px;
  border-radius: 0;
  transform: rotate(45deg);
}
.bot-hero-card.status-killed .br-eye:last-child {
  transform: rotate(-45deg);
}
.bot-hero-card.status-killed .br-mouth {
  background: var(--tx-3);
  animation: none;
}
.bot-hero-card.status-killed .br-scan {
  animation: none;
  opacity: 0;
}

/* =========================================================================
   PRIMARY ADD CARDS — "+ NEW STRATEGY" / "+ NEW BOT"
   Promoted to first position in each grid; bumped visual weight so users
   see the create-action before the existing cards.
   ========================================================================= */
.strat-hero-add.primary-add {
  border-width: 2px !important;
  border-style: solid !important;
  position: relative;
  overflow: hidden;
}
.strat-hero-add.primary-add .sha-icon {
  font-size: 32px !important;
  margin-bottom: 6px;
}
.strat-hero-add.primary-add .sha-title {
  font-size: 13px !important;
  font-weight: 800 !important;
  letter-spacing: 1px !important;
}
.strat-hero-add.primary-add .sha-sub {
  font-size: 9px;
  opacity: 0.85;
}

/* Strategy add — amber/orange neon (static, no animation) */
#hero-add.primary-add {
  border-color: var(--orange) !important;
  background:
    radial-gradient(
      ellipse at center,
      rgba(242, 163, 65, 0.1) 0%,
      transparent 75%
    ),
    linear-gradient(
      135deg,
      rgba(242, 163, 65, 0.06) 0%,
      rgba(242, 163, 65, 0.02) 100%
    ),
    var(--bg-panel) !important;
  box-shadow:
    0 0 14px rgba(242, 163, 65, 0.18),
    inset 0 0 16px rgba(242, 163, 65, 0.04);
  transition:
    box-shadow 0.2s,
    transform 0.18s,
    background 0.2s;
}
#hero-add.primary-add .sha-icon {
  color: var(--orange);
  text-shadow: 0 0 10px rgba(242, 163, 65, 0.55);
}
#hero-add.primary-add .sha-title {
  color: var(--orange);
}
#hero-add.primary-add .sha-sub {
  color: rgba(242, 163, 65, 0.7);
  letter-spacing: 1px;
}
#hero-add.primary-add:hover {
  background:
    radial-gradient(
      ellipse at center,
      rgba(242, 163, 65, 0.2) 0%,
      transparent 75%
    ),
    linear-gradient(
      135deg,
      rgba(242, 163, 65, 0.14) 0%,
      rgba(242, 163, 65, 0.04) 100%
    ),
    var(--bg-panel) !important;
  transform: translateY(-2px);
  box-shadow:
    0 0 24px rgba(242, 163, 65, 0.4),
    inset 0 0 20px rgba(242, 163, 65, 0.08);
}

/* Bot add — cyan + violet neon (static, no animation) */
#bot-hero-add.primary-add {
  border-color: var(--info) !important;
  border-style: solid !important;
  background:
    radial-gradient(
      ellipse at center,
      rgba(24, 191, 217, 0.12) 0%,
      transparent 70%
    ),
    linear-gradient(
      135deg,
      rgba(24, 191, 217, 0.08) 0%,
      rgba(167, 139, 250, 0.08) 100%
    ),
    #0a0f18 !important;
  box-shadow:
    0 0 16px rgba(24, 191, 217, 0.22),
    inset 0 0 18px rgba(24, 191, 217, 0.05);
  transition:
    box-shadow 0.2s,
    transform 0.18s,
    background 0.2s;
}
#bot-hero-add.primary-add .sha-icon {
  color: var(--info);
  text-shadow: 0 0 12px rgba(24, 191, 217, 0.65);
  animation: none; /* override the .bot-hero-add botSpark inheritance */
}
#bot-hero-add.primary-add .sha-title {
  color: var(--info);
}
#bot-hero-add.primary-add .sha-sub {
  color: rgba(167, 139, 250, 0.85);
  letter-spacing: 1.2px;
}
#bot-hero-add.primary-add:hover {
  background:
    radial-gradient(
      ellipse at center,
      rgba(24, 191, 217, 0.24) 0%,
      transparent 70%
    ),
    linear-gradient(
      135deg,
      rgba(24, 191, 217, 0.16) 0%,
      rgba(167, 139, 250, 0.16) 100%
    ),
    #0a0f18 !important;
  transform: translateY(-2px);
  box-shadow:
    0 0 28px rgba(24, 191, 217, 0.45),
    0 0 14px rgba(167, 139, 250, 0.3),
    inset 0 0 22px rgba(24, 191, 217, 0.1);
}

/* =========================================================================
   SHARED FUTURISTIC ROBOT SVG — sizing/positioning per context
   ========================================================================= */
.bot-robot-svg {
  display: block;
  pointer-events: none;
}

/* Variant: top-right mascot on each bot card */
.bot-robot-card {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 2;
  filter: drop-shadow(0 0 6px rgba(0, 213, 255, 0.45));
}
.bot-hero-card.status-paused .bot-robot-card {
  opacity: 0.65;
  filter: drop-shadow(0 0 4px rgba(242, 163, 65, 0.45));
}
.bot-hero-card.status-killed .bot-robot-card {
  opacity: 0.35;
  filter: grayscale(0.7) drop-shadow(0 0 4px rgba(106, 115, 132, 0.35));
  transform: rotate(8deg);
}

/* Variant: centered in the Bot Status metric tile (with concentric rings around) */
.bd-robot-tile {
  position: relative;
  z-index: 1;
  filter: drop-shadow(0 0 12px rgba(0, 213, 255, 0.6));
}
.bd-big-robot.status-paused .bd-robot-tile {
  opacity: 0.65;
  filter: drop-shadow(0 0 8px rgba(242, 163, 65, 0.5));
}
.bd-big-robot.status-killed .bd-robot-tile {
  opacity: 0.4;
  filter: grayscale(0.7);
}

/* Bot pill (the small "⚡ BOT" badge inside name row) */
.bot-pill {
  background: linear-gradient(
    90deg,
    rgba(24, 191, 217, 0.2),
    rgba(167, 139, 250, 0.2)
  );
  color: var(--info) !important;
  border: 1px solid rgba(24, 191, 217, 0.4);
  padding: 1px 6px;
  border-radius: 2px;
  font-size: 8px;
  letter-spacing: 0.6px;
  font-weight: 800;
  text-shadow: 0 0 4px rgba(24, 191, 217, 0.6);
}

/* =========================================================================
   REDESIGNED MAIN DASHBOARD — top nav, left sidebar, dashboard header
   ========================================================================= */

/* TOP NAV BAR (replaces cmd-bar) ---------------------------------------- */
.cmd-bar.top-nav-bar {
  display: flex !important;
  align-items: center;
  height: 46px;
  padding: 0 16px;
  gap: 14px;
  background: linear-gradient(180deg, #0d1421 0%, #080d17 100%);
  border-bottom: 1px solid rgba(20, 184, 166, 0.18);
  grid-template-columns: none;
}

/* MOBILE NAVIGATION ----------------------------------------------------
   Hamburger button + slide-in drawer. Hidden on desktop, shown on
   mobile (≤640px). The drawer mirrors the left-sidebar nav items
   with finger-friendly text labels and includes a sign-out item so
   the whole signed-in chrome lives behind one tap. */
.mobile-menu-btn {
  display: none; /* enabled on mobile via media query */
  background: transparent;
  border: 0;
  color: var(--tx-1);
  font-size: 22px;
  line-height: 1;
  width: 36px;
  height: 36px;
  cursor: pointer;
  border-radius: 6px;
  transition: background 0.12s;
  flex: 0 0 auto;
  padding: 0;
}
.mobile-menu-btn:hover,
.mobile-menu-btn:focus-visible {
  background: rgba(255, 255, 255, 0.06);
  outline: 0;
}
.mobile-nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
  z-index: 199;
  opacity: 0;
  transition: opacity 0.18s;
}
.mobile-nav-backdrop.show {
  display: block;
  opacity: 1;
}
.mobile-nav-drawer {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 280px;
  max-width: 80vw;
  background: var(--bg-panel);
  border-right: 1px solid var(--bd-2);
  box-shadow: 4px 0 24px rgba(0, 0, 0, 0.5);
  z-index: 220;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform 0.22s ease-out;
}
.mobile-nav-drawer.show {
  display: flex;
  transform: translateX(0);
}
.mnav-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--bd-2);
  background: var(--bg-elevated);
  flex-shrink: 0;
}
.mnav-user {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.mnav-avatar {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}
.mnav-logo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
}
.mnav-meta {
  min-width: 0;
}
.mnav-name {
  font-size: 12px;
  font-weight: 800;
  color: var(--tx-1);
  letter-spacing: 0.4px;
}
.mnav-email {
  font-size: 10px;
  color: var(--tx-3);
  margin-top: 2px;
  word-break: break-all;
}
.mnav-close {
  background: transparent;
  border: 0;
  color: var(--tx-2);
  font-size: 16px;
  cursor: pointer;
  width: 28px;
  height: 28px;
  border-radius: 4px;
  flex-shrink: 0;
}
.mnav-close:hover {
  background: rgba(255, 255, 255, 0.05);
  color: var(--tx-1);
}
.mnav-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.mnav-item {
  display: flex;
  align-items: center;
  gap: 14px;
  background: transparent;
  border: 0;
  color: var(--tx-1);
  text-align: left;
  padding: 12px 18px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background 0.12s,
    color 0.12s;
  letter-spacing: 0.2px;
  min-height: 44px;
}
.mnav-item:hover {
  background: rgba(255, 255, 255, 0.04);
}
.mnav-item.active {
  background: rgba(20, 184, 166, 0.1);
  color: #5eead4;
  box-shadow: inset 3px 0 0 #5eead4;
}
.mnav-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  font-size: 16px;
  color: rgba(255, 255, 255, 0.55);
  flex-shrink: 0;
}
.mnav-item.active .mnav-icon {
  color: #5eead4;
}
.mnav-foot {
  border-top: 1px solid var(--bd-2);
  padding: 10px 12px;
  flex-shrink: 0;
}
.mnav-signout {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: transparent;
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  color: var(--tx-2);
  padding: 10px 14px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition:
    background 0.12s,
    color 0.12s,
    border-color 0.12s;
  letter-spacing: 0.3px;
}
.mnav-signout:hover {
  background: rgba(220, 38, 38, 0.1);
  color: #f87171;
  border-color: rgba(220, 38, 38, 0.4);
}
.mnav-signout .mnav-icon {
  color: rgba(248, 113, 113, 0.7);
}
.mnav-signout:hover .mnav-icon {
  color: #f87171;
}
.cmd-bar.top-nav-bar .brand {
  border-right: 0;
  padding: 0;
  flex: 0 0 auto;
}
.cmd-bar.top-nav-bar .brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: transparent;
  border-radius: 8px;
  overflow: hidden;
  text-decoration: none;
  flex-shrink: 0;
  transition:
    filter 0.12s,
    transform 0.12s;
}
.cmd-bar.top-nav-bar .brand-mark:hover {
  filter: drop-shadow(0 0 6px rgba(20, 184, 166, 0.55));
  transform: scale(1.05);
}
/* Show only the icon portion of the full logo (top ~75%) — the
   1024x1024 source has the "tradingsmart.ai" wordmark in the bottom
   25% which would be unreadable at 36px. object-fit: cover with
   object-position: top crops the wordmark cleanly. */
.cmd-bar.top-nav-bar .brand-logo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
  /* The source has black background; keep it as-is so the brain +
     chart icon glows on the dark nav. No bg color needed. */
}
.top-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 100%;
  border-right: 0;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.top-nav::-webkit-scrollbar {
  display: none;
}
.top-nav .tnav-tab {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--tx-1);
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-family: var(--ff-ui);
  border-radius: 6px;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition:
    color 0.15s,
    background 0.15s;
  flex-shrink: 0;
  white-space: nowrap;
  -webkit-font-smoothing: antialiased;
}
.top-nav .tnav-tab > b {
  display: none;
}
.top-nav .tnav-tab strong {
  font-weight: inherit;
}
.top-nav .tnav-tab:hover {
  background: rgba(255, 255, 255, 0.04);
}
.top-nav .tnav-tab:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.04);
}
.top-nav .tnav-tab {
  background: rgba(255, 255, 255, 0.04);
}
.top-nav .tnav-tab.active,
.top-nav .tnav-tab.active strong {
  color: #5eead4;
  font-weight: 800;
  background: rgba(20, 184, 166, 0.1);
  text-shadow: 0 0 8px rgba(20, 184, 166, 0.4);
}
.top-nav .tnav-tab.active::after {
  content: "";
  position: absolute;
  bottom: -8px;
  left: 14px;
  right: 14px;
  height: 2px;
  background: linear-gradient(90deg, transparent, #14b8a6 50%, transparent);
  box-shadow: 0 0 6px rgba(20, 184, 166, 0.6);
}
.tnav-spacer {
  flex: 0 0 8px;
}
.tnav-kill {
  background: rgba(220, 38, 38, 0.1);
  border: 1px solid rgba(220, 38, 38, 0.4);
  color: #f87171;
  font-family: var(--ff-mn);
  padding: 6px 12px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
  border-radius: 6px;
  cursor: pointer;
}
.tnav-kill:hover {
  background: rgba(220, 38, 38, 0.2);
  border-color: #ef4444;
}
.tnav-clocks {
  display: flex;
  gap: 10px;
  align-items: center;
  border-right: 0;
  flex-shrink: 0;
}
.tnav-clk {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  font-family: var(--ff-mn);
  line-height: 1.1;
}
.tnav-clk .clk-z {
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: rgba(255, 255, 255, 0.45);
}
.tnav-clk .clk-t {
  font-size: 12px;
  color: var(--tx-1);
  font-weight: 700;
}
.tnav-feed {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--ff-mn);
  font-size: 10px;
  color: var(--up);
  font-weight: 800;
  letter-spacing: 0.5px;
}
.tnav-feed .led {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0;
  background: transparent;
  border: 0;
}
.tnav-feed .led .d {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--up);
  box-shadow: 0 0 6px var(--up);
  animation: feedPulse 1.5s ease-in-out infinite;
}
@keyframes feedPulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

/* LEFT SIDEBAR ---------------------------------------------------------- */
/* The vertical icon rail (avatar / dashboard / terminal / bots / orders /
   portfolio / analytics / alerts / settings / power) is hidden globally.
   All of its navigation is duplicated in the top nav (STRATEGIES, BOTS,
   ORDERS, PORTFOLIO, ANALYTICS, ALERTS, NEWS) and settings remains
   reachable via the drawer + F10 hotkey, so the rail was redundant chrome
   eating 56px of horizontal real-estate the dashboard needs to fit on
   smaller laptop screens.
   To re-enable, restore `grid-template-columns: 56px 1fr` and remove the
   `display: none` on `.left-sidebar`. */
.grid.grid-v2 {
  grid-template-columns: 1fr;
}
.grid.grid-v2 .col-right {
  display: none;
}
.left-sidebar {
  display: none;
  background: linear-gradient(180deg, #0a1018 0%, #050810 100%);
  border-right: 1px solid rgba(20, 184, 166, 0.1);
  flex-direction: column;
  align-items: center;
  padding: 10px 0;
  gap: 8px;
  min-height: 0;
}
.ls-avatar {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: linear-gradient(135deg, #5eead4, #818cf8);
  color: #0d1421;
  font-weight: 800;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 12px rgba(94, 234, 212, 0.3);
  margin-bottom: 6px;
  flex-shrink: 0;
  border: 0; /* avatar is now a <button> for the account menu */
  cursor: pointer;
  position: relative;
  transition:
    filter 0.12s,
    box-shadow 0.12s;
}
.ls-avatar:hover {
  filter: brightness(1.1);
  box-shadow: 0 0 16px rgba(94, 234, 212, 0.45);
}
.ls-avatar[aria-expanded="true"] {
  box-shadow:
    0 0 0 2px #5eead4,
    0 0 16px rgba(94, 234, 212, 0.45);
}
/* Tiny chevron at the bottom right tells users the avatar is clickable
   (helps discovery). Hidden until hover so it doesn't add visual noise. */
.ls-avatar::after {
  content: "▾";
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 14px;
  height: 14px;
  background: var(--bg-base);
  color: var(--tx-2);
  border-radius: 4px;
  font-size: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--bd-2);
  opacity: 0;
  transition: opacity 0.15s;
}
.ls-avatar:hover::after,
.ls-avatar[aria-expanded="true"]::after {
  opacity: 1;
}

/* ACCOUNT MENU — popover anchored next to the sidebar avatar.
   Position: fixed (escapes the 56px-wide sidebar), shown by toggling
   the .hidden class. Includes the email + Sign Out item.            */
.ls-account-menu {
  position: fixed;
  left: 64px; /* 56px sidebar + 8px gap */
  top: 80px; /* matches main grid offset */
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-radius: 6px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  padding: 8px 0;
  min-width: 220px;
  z-index: 200; /* above the rest of the chrome */
  font-size: 11px;
  animation: ls-am-pop 0.14s ease-out;
}
.ls-account-menu.hidden {
  display: none;
}
@keyframes ls-am-pop {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.ls-am-h {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  padding: 0 14px 4px 14px;
  text-transform: uppercase;
}
.ls-am-email {
  padding: 0 14px 8px 14px;
  font-size: 11px;
  color: var(--tx-1);
  font-weight: 600;
  word-break: break-all;
}
.ls-am-divider {
  height: 1px;
  background: var(--bd-2);
  margin: 4px 0;
}
/* Plan row in the account dropdown — badge + usage counter */
.ls-am-plan {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px 12px;
  font-size: 11px;
}
.ls-am-plan-l {
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.6px;
}
.ls-am-plan-badge {
  padding: 2px 7px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.4px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-2);
}
.ls-am-plan-badge.plan-free {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-3);
}
.ls-am-plan-badge.plan-pro {
  background: rgba(245, 158, 11, 0.15);
  color: #fbbf24;
}
.ls-am-plan-badge.plan-quant {
  background: rgba(168, 85, 247, 0.15);
  color: #c084fc;
}
.ls-am-plan-usage {
  margin-left: auto;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-size: 10px;
}
.ls-am-upgrade {
  text-decoration: none !important;
  color: #fbbf24 !important;
}
.ls-am-upgrade:hover {
  background: rgba(245, 158, 11, 0.08) !important;
}
.ls-am-upgrade .ls-am-icon {
  color: #fbbf24 !important;
}
.ls-am-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: transparent;
  border: 0;
  color: var(--tx-1);
  text-align: left;
  padding: 8px 14px;
  font-size: 12px;
  cursor: pointer;
  transition:
    background 0.12s,
    color 0.12s;
}
.ls-am-item:hover {
  background: rgba(220, 38, 38, 0.1);
  color: #f87171;
}
.ls-am-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  font-size: 13px;
  color: rgba(248, 113, 113, 0.8);
}
.ls-am-item:hover .ls-am-icon {
  color: #f87171;
}
.ls-icons {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  align-items: center;
}
.ls-icon {
  width: 36px;
  height: 36px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: rgba(255, 255, 255, 0.45);
  font-size: 16px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
}
.ls-icon:hover {
  color: var(--tx-1);
  background: rgba(255, 255, 255, 0.05);
}
.ls-icon.active {
  color: #5eead4;
  background: rgba(20, 184, 166, 0.1);
  box-shadow: inset 0 0 0 1px rgba(20, 184, 166, 0.3);
}
.ls-power {
  width: 36px;
  height: 36px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: rgba(248, 113, 113, 0.55);
  font-size: 16px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.ls-power:hover {
  color: #f87171;
  background: rgba(220, 38, 38, 0.1);
}

/* DASHBOARD HEADER STRIP (user + symbol ticker + counts + new btn) ------ */
.dash-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  background: linear-gradient(
    180deg,
    rgba(13, 20, 33, 0.6),
    rgba(8, 13, 23, 0.6)
  );
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  flex-shrink: 0;
  flex-wrap: nowrap;
  overflow-x: auto;
  white-space: nowrap;
  scrollbar-width: thin;
}
.dh-user {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-right: 12px;
  border-right: 1px solid rgba(255, 255, 255, 0.08);
  flex-shrink: 0;
  /* Anchor for the absolute-positioned dropdown menu */
  position: relative;
}
/* Whole avatar+name+caret block is now a clickable button */
.dh-user-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 3px 8px 3px 4px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 100px;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.dh-user-pill:hover {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--bd-2);
}
.dh-user-pill[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--bd-3);
}
.dh-user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, #5eead4, #818cf8);
  color: #0d1421;
  font-weight: 800;
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.dh-user-name {
  font-family: var(--ff-mn);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--tx-1);
}
.dh-user-caret {
  font-size: 10px;
  color: var(--tx-3);
  margin-left: 2px;
  transition: transform 0.15s;
}
.dh-user-pill[aria-expanded="true"] .dh-user-caret {
  transform: rotate(180deg);
}

/* Account dropdown menu — anchored to the bottom-left of the
   user pill. Three menu items + an email header at the top.
   Sign-out gets a danger color on hover. */
.dh-user-menu {
  /* position:fixed escapes any ancestor's stacking context. JS sets
     left/top from the pill's getBoundingClientRect on each open. */
  position: fixed;
  z-index: 9000;
  min-width: 260px;
  background: #1a2030;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  box-shadow:
    0 16px 40px rgba(0, 0, 0, 0.7),
    0 4px 12px rgba(0, 0, 0, 0.4),
    0 0 0 1px rgba(255, 255, 255, 0.04);
  padding: 6px;
  animation: dh-um-fade 0.12s ease-out;
}
.dh-user-menu.hidden {
  display: none;
}
@keyframes dh-um-fade {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.dh-user-menu-h {
  font-family: var(--ff-mn);
  font-size: 10px;
  color: var(--tx-3);
  padding: 8px 10px 6px;
  border-bottom: 1px solid var(--bd-2);
  margin-bottom: 4px;
  word-break: break-all;
}
.dh-user-menu-item {
  display: grid;
  grid-template-columns: 18px 1fr;
  grid-template-rows: auto auto;
  column-gap: 10px;
  row-gap: 1px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: var(--tx-1);
  text-align: left;
  cursor: pointer;
  transition: background 0.12s;
}
.dh-user-menu-item:hover {
  background: rgba(255, 255, 255, 0.06);
}
.dh-user-menu-item .dh-um-ico {
  grid-row: 1 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--tx-2);
}
.dh-user-menu-item .dh-um-label {
  font-size: 12px;
  font-weight: 700;
  color: var(--tx-1);
  line-height: 1.2;
}
.dh-user-menu-item .dh-um-sub {
  font-size: 10px;
  color: var(--tx-3);
  line-height: 1.3;
}
.dh-user-menu-sep {
  height: 1px;
  background: var(--bd-2);
  margin: 4px 6px;
}
.dh-user-menu-item.dh-um-danger:hover {
  background: rgba(239, 68, 68, 0.1);
}
.dh-user-menu-item.dh-um-danger:hover .dh-um-ico,
.dh-user-menu-item.dh-um-danger:hover .dh-um-label {
  color: #ff8585;
}

/* ─── Edit Profile modal ─────────────────────────────────────── */
.prof-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.prof-label {
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  text-transform: uppercase;
}
#profile-modal input[type="text"],
#profile-modal input[type="email"],
#profile-modal input[type="password"] {
  width: 100%;
  padding: 9px 11px;
  background: var(--bg-base);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  font-family: var(--ff-mn);
  font-size: 12px;
}
#profile-modal input:focus {
  outline: none;
  border-color: var(--info);
  box-shadow: 0 0 0 2px rgba(24, 191, 217, 0.15);
}
#profile-modal input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
/* Phone row inside profile modal: country-code <select> + national-
   number <input> side by side. Matches the signup-form .auth-phone-row
   styling so users see consistent UI between signup and profile edit. */
.prof-phone-row {
  display: flex;
  gap: 6px;
  align-items: stretch;
}
.prof-phone-row select {
  flex: 0 0 auto;
  max-width: 142px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  color: var(--tx-1);
  padding: 9px 8px;
  border-radius: 4px;
  font-family: var(--ff-mn);
  font-size: 12px;
  outline: 0;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='%236A7384' d='M0 0l5 6 5-6z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  padding-right: 22px;
  cursor: pointer;
  color-scheme: dark;
}
.prof-phone-row select:focus {
  border-color: var(--info);
  box-shadow: 0 0 0 2px rgba(24, 191, 217, 0.15);
}
.prof-phone-row input {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--bg-base);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  padding: 9px 11px;
  font-family: var(--ff-mn);
  font-size: 12px;
  outline: 0;
  color-scheme: dark;
}
.prof-phone-row input:focus {
  border-color: var(--info);
  box-shadow: 0 0 0 2px rgba(24, 191, 217, 0.15);
}
.prof-hint {
  font-size: 10px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  line-height: 1.4;
}
.prof-pw-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  background: var(--bg-base);
  border: 1px dashed var(--bd-2);
  border-radius: 4px;
}
.prof-status {
  font-size: 11px;
  font-family: var(--ff-mn);
  min-height: 16px;
  color: var(--tx-2);
}
.prof-status.ok {
  color: var(--up);
  font-weight: 700;
}
.prof-status.warn {
  color: var(--orange);
}
.prof-status.err {
  color: #ff8585;
  font-weight: 700;
}

/* ─── Help & Support modal ─────────────────────────────────── */
.sup-tabs {
  display: flex;
  gap: 4px;
  padding: 8px 16px 0;
  border-bottom: 1px solid var(--bd-2);
  flex-shrink: 0;
}
.sup-tab {
  padding: 10px 16px;
  background: transparent;
  border: 0;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.sup-tab:hover {
  color: var(--tx-1);
}
.sup-tab.active {
  color: var(--orange);
  border-bottom-color: var(--orange);
}
.sup-tab-count {
  font-size: 9px;
  padding: 1px 6px;
  border-radius: 10px;
  background: rgba(245, 158, 11, 0.18);
  color: var(--orange);
}
.sup-body {
  flex: 1;
  overflow: hidden;
  display: flex;
  min-height: 0;
}
.sup-pane {
  display: none;
  width: 100%;
  overflow-y: auto;
  padding: 16px 18px;
}
.sup-pane.active {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.sup-empty {
  text-align: center;
  padding: 40px 20px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
  font-size: 12px;
  line-height: 1.5;
}
.sup-empty.err {
  color: #ff8585;
}
.sup-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sup-row {
  padding: 12px 14px;
  background: var(--bg-base);
  border: 1px solid var(--bd-2);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.15s;
}
.sup-row:hover {
  border-color: var(--bd-3);
}
.sup-row-h {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.sup-row-subject {
  font-size: 13px;
  font-weight: 700;
  color: var(--tx-1);
  margin-bottom: 4px;
}
.sup-row-replies {
  font-size: 11px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
}
.sup-row-cat,
.sup-row-pri,
.sup-row-time {
  font-size: 9px;
  font-family: var(--ff-mn);
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 3px;
}
.sup-row-cat {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-2);
}
.sup-row-time {
  background: transparent;
  color: var(--tx-3);
  margin-left: auto;
  padding: 0;
}
.sup-row-pri.pri-low {
  background: rgba(120, 144, 156, 0.18);
  color: #94a3b8;
}
.sup-row-pri.pri-normal {
  background: rgba(56, 189, 248, 0.15);
  color: #38bdf8;
}
.sup-row-pri.pri-high {
  background: rgba(245, 158, 11, 0.18);
  color: var(--orange);
}
.sup-row-pri.pri-urgent {
  background: rgba(239, 68, 68, 0.2);
  color: #ff8585;
}
.sup-status-pill {
  font-size: 9px;
  font-family: var(--ff-mn);
  font-weight: 800;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 10px;
}
.sup-status-pill.open {
  background: rgba(245, 158, 11, 0.18);
  color: var(--orange);
}
.sup-status-pill.in_progress {
  background: rgba(168, 85, 247, 0.2);
  color: #c084fc;
}
.sup-status-pill.waiting_user {
  background: rgba(56, 189, 248, 0.18);
  color: #38bdf8;
}
.sup-status-pill.resolved {
  background: rgba(74, 222, 128, 0.18);
  color: #4ade80;
}
.sup-status-pill.closed {
  background: rgba(120, 144, 156, 0.18);
  color: #94a3b8;
}
.sup-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sup-label {
  font-family: var(--ff-mn);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--tx-3);
  text-transform: uppercase;
}
.sup-hint {
  font-size: 10px;
  color: var(--tx-3);
  font-family: var(--ff-mn);
}
#support-modal input[type="text"],
#support-modal textarea,
#support-modal select {
  width: 100%;
  padding: 9px 11px;
  background: var(--bg-base);
  color: var(--tx-1);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  font-family: var(--ff-mn);
  font-size: 12px;
}
#support-modal textarea {
  resize: vertical;
  font-family: var(--ff-ui);
  line-height: 1.5;
}
#support-modal input:focus,
#support-modal textarea:focus,
#support-modal select:focus {
  outline: none;
  border-color: var(--info);
  box-shadow: 0 0 0 2px rgba(24, 191, 217, 0.15);
}
.sup-status {
  font-size: 11px;
  font-family: var(--ff-mn);
  min-height: 16px;
  color: var(--tx-2);
}
.sup-status.ok {
  color: #4ade80;
  font-weight: 700;
}
.sup-status.busy {
  color: var(--orange);
}
.sup-status.err {
  color: #ff8585;
  font-weight: 700;
}
.sup-back {
  background: transparent;
  border: 0;
  color: var(--info);
  font-family: var(--ff-mn);
  font-size: 11px;
  cursor: pointer;
  padding: 4px 0;
  align-self: flex-start;
}
.sup-back:hover {
  text-decoration: underline;
}
.sup-thread {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.sup-th-head {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--bd-2);
}
.sup-th-subject {
  font-size: 16px;
  font-weight: 800;
  color: var(--tx-1);
  margin-bottom: 8px;
}
.sup-th-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.sup-th-msg {
  padding: 12px 14px;
  border-radius: 6px;
  border: 1px solid var(--bd-2);
}
.sup-th-msg-user {
  background: var(--bg-base);
}
.sup-th-msg-admin {
  background: rgba(245, 158, 11, 0.06);
  border-color: rgba(245, 158, 11, 0.3);
}
.sup-th-author {
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 800;
  color: var(--tx-2);
  margin-bottom: 6px;
}
.sup-th-msg-admin .sup-th-author {
  color: var(--orange);
}
.sup-th-time {
  color: var(--tx-3);
  font-weight: 500;
  margin-left: 6px;
}
.sup-th-body {
  font-size: 13px;
  color: var(--tx-1);
  line-height: 1.55;
  word-break: break-word;
}
.sup-reply {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--bd-2);
}
.sup-reply-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
/* Plan chip — always visible in the dashboard header. Click to upgrade. */
.dh-plan-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  margin-left: 4px;
  border-radius: 100px;
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-decoration: none;
  border: 1px solid var(--bd-2);
  background: var(--bg-2);
  color: var(--tx-2);
  transition:
    background 0.15s,
    border-color 0.15s,
    transform 0.1s;
  white-space: nowrap;
}
.dh-plan-chip:hover {
  background: var(--bg-3);
  border-color: var(--bd-3);
  transform: translateY(-1px);
}
.dh-plan-chip .dh-plan-name {
  font-weight: 800;
  letter-spacing: 0.6px;
}
.dh-plan-chip .dh-plan-usage {
  color: var(--tx-3);
  font-weight: 600;
}
.dh-plan-chip.plan-free {
  background: rgba(255, 255, 255, 0.04);
}
.dh-plan-chip.plan-free .dh-plan-name {
  color: var(--tx-2);
}
.dh-plan-chip.plan-pro {
  background: linear-gradient(
    135deg,
    rgba(245, 158, 11, 0.15),
    rgba(234, 88, 12, 0.08)
  );
  border-color: rgba(245, 158, 11, 0.4);
  box-shadow: 0 0 16px rgba(245, 158, 11, 0.15);
}
.dh-plan-chip.plan-pro .dh-plan-name {
  color: #fbbf24;
}
.dh-plan-chip.plan-quant {
  background: linear-gradient(
    135deg,
    rgba(168, 85, 247, 0.15),
    rgba(236, 72, 153, 0.08)
  );
  border-color: rgba(168, 85, 247, 0.4);
  box-shadow: 0 0 16px rgba(168, 85, 247, 0.15);
}
.dh-plan-chip.plan-quant .dh-plan-name {
  color: #c084fc;
}
/* Trial variant — pulse to draw attention */
.dh-plan-chip.trial {
  background: linear-gradient(
    135deg,
    rgba(34, 197, 94, 0.18),
    rgba(245, 158, 11, 0.1)
  );
  border-color: rgba(34, 197, 94, 0.45);
  box-shadow: 0 0 18px rgba(34, 197, 94, 0.18);
  animation: chip-trial-pulse 2.5s ease-in-out infinite;
}
.dh-plan-chip.trial .dh-plan-name {
  color: #4ade80;
}
.dh-plan-chip.trial .dh-plan-usage {
  color: #4ade80;
  opacity: 0.85;
}
@keyframes chip-trial-pulse {
  0%,
  100% {
    box-shadow: 0 0 12px rgba(34, 197, 94, 0.18);
  }
  50% {
    box-shadow: 0 0 26px rgba(34, 197, 94, 0.35);
  }
}
.ls-am-plan-badge.trial {
  background: rgba(34, 197, 94, 0.18) !important;
  color: #4ade80 !important;
}
@media (max-width: 600px) {
  .dh-plan-chip {
    padding: 3px 8px;
    font-size: 9px;
  }
  .dh-plan-chip .dh-plan-usage {
    display: none;
  }
}

/* =================================================================
   BANNER WRAPPER — single grid row that collapses to 0 when both
   children are display:none. Without this, .col-main's grid was
   allocating a separate 1fr row to each banner div even when hidden,
   inflating the dash-header row.
   ================================================================= */
.dash-banners {
  display: flex;
  flex-direction: column;
  /* No padding/gap when both children are hidden — flex collapses
     correctly because display:none children don't count. */
}
.dash-banners:has(> :not([style*="display: none"])) {
  padding: 8px 16px 0;
}

/* =================================================================
   TRIAL BANNER — slim, single line, only shown when urgent (≤3 days)
   or the trial has expired. Day-to-day trial state is conveyed by
   the chip in the header instead.
   ================================================================= */
.trial-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  margin: 0 0 8px;
  border-radius: 6px;
  font-size: 12px;
  line-height: 1.4;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.25);
  color: var(--tx-2);
}
.trial-banner.urgent {
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.35);
}
.trial-banner.expired {
  background: rgba(239, 68, 68, 0.08);
  border-color: rgba(239, 68, 68, 0.3);
}
/* Positive welcome state (4-14 days into trial) — orange + purple
   gradient + brain emoji vibe so it doesn't feel scoldy like .urgent. */
.trial-banner.welcome {
  background: linear-gradient(
    135deg,
    rgba(245, 158, 11, 0.1),
    rgba(168, 85, 247, 0.1)
  );
  border-color: rgba(168, 85, 247, 0.4);
}
.trial-banner .tb-ico {
  font-size: 13px;
  flex-shrink: 0;
}
.trial-banner .tb-msg {
  flex: 1;
  min-width: 0;
  color: var(--tx-2);
}
.trial-banner .tb-msg b {
  color: var(--tx-1);
  font-weight: 700;
}
.trial-banner .tb-cta {
  padding: 3px 10px;
  background: var(--orange);
  color: #1a0a00;
  border-radius: 4px;
  text-decoration: none;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  transition: background 0.15s;
}
.trial-banner.expired .tb-cta {
  background: var(--red);
  color: #fff;
}
.trial-banner .tb-cta:hover {
  filter: brightness(1.1);
}
.trial-banner .tb-x {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 13px;
  padding: 0 4px;
  border-radius: 3px;
  line-height: 1;
}
.trial-banner .tb-x:hover {
  color: var(--tx-1);
}

/* =================================================================
   PRE-WALL NUDGE — slim single-line strip, dismissible per-day
   ================================================================= */
.prewall-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  margin: 0 0 8px;
  border-radius: 6px;
  font-size: 12px;
  line-height: 1.4;
  background: rgba(245, 158, 11, 0.06);
  border: 1px solid rgba(245, 158, 11, 0.2);
  color: var(--tx-2);
}
.prewall-banner.at-cap {
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.35);
}
.prewall-banner .pw-ico {
  font-size: 13px;
  flex-shrink: 0;
}
.prewall-banner .pw-body {
  flex: 1;
  min-width: 0;
}
.prewall-banner .pw-body b {
  color: var(--tx-1);
  font-weight: 700;
}
.prewall-banner .pw-cta {
  padding: 3px 10px;
  background: var(--orange);
  color: #1a0a00;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.prewall-banner .pw-cta:hover {
  filter: brightness(1.1);
}
.prewall-banner .pw-x {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 13px;
  padding: 0 4px;
  border-radius: 3px;
  line-height: 1;
}
.prewall-banner .pw-x:hover {
  color: var(--tx-1);
}

@media (max-width: 600px) {
  .trial-banner,
  .prewall-banner {
    flex-wrap: wrap;
    gap: 6px;
  }
  .trial-banner .tb-cta,
  .prewall-banner .pw-cta {
    order: 99;
  }
}

/* =================================================================
   TRUST STRIP (Fix #7) — social proof + safety badges
   Sits inside #dash-banners, only shown to free users.
   ================================================================= */
.trust-strip {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 14px;
  margin: 0 0 8px;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    rgba(16, 185, 129, 0.05),
    rgba(96, 165, 250, 0.05)
  );
  border: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 11px;
  color: var(--tx-2);
  position: relative;
  flex-wrap: wrap;
}
.trust-strip .ts-item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
}
.trust-strip .ts-num {
  font-size: 13px;
  font-weight: 800;
  color: var(--tx-1);
  letter-spacing: 0.2px;
}
.trust-strip .ts-num .ts-shield {
  color: #10b981;
  margin-right: 1px;
}
.trust-strip .ts-lbl {
  font-size: 10px;
  color: var(--tx-3);
  letter-spacing: 0.2px;
}
.trust-strip .ts-sep {
  width: 1px;
  height: 18px;
  background: rgba(255, 255, 255, 0.08);
  flex-shrink: 0;
}
.trust-strip .ts-x {
  position: absolute;
  top: 4px;
  right: 6px;
  background: transparent;
  border: 0;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 3px;
  line-height: 1;
  opacity: 0.5;
  transition:
    opacity 0.15s,
    color 0.15s;
}
.trust-strip .ts-x:hover {
  opacity: 1;
  color: var(--tx-1);
}

@media (max-width: 720px) {
  .trust-strip {
    gap: 10px;
    padding: 8px 10px 8px 12px;
  }
  .trust-strip .ts-sep {
    display: none;
  }
  .trust-strip .ts-item {
    font-size: 10px;
  }
  .trust-strip .ts-num {
    font-size: 12px;
  }
}

/* =================================================================
   PRO FEATURE TEASER — pill with PRO tag inside, click → upgrade modal
   ================================================================= */
.pro-feature {
  position: relative;
  cursor: pointer;
}
.pro-feature .pro-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  background: linear-gradient(135deg, var(--orange), var(--orange-3, #ea580c));
  color: #1a0a00;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.4px;
  border-radius: 3px;
  vertical-align: 1px;
}
/* Hide the PRO tag for Pro/Quant users (toggled via body class set by app.js).
   For now, we just gray out the tag while still leaving the click handler in
   place; the gate code returns early when the user already has Pro. */
body.has-pro-plan .pro-feature .pro-tag {
  display: none;
}

/* =================================================================
   TOAST CTA — for the profit-nudge upsell
   ================================================================= */
.toast-cta {
  display: inline-block;
  margin-top: 8px;
  padding: 6px 12px;
  background: linear-gradient(135deg, var(--orange), var(--orange-3, #ea580c));
  color: #1a0a00;
  text-decoration: none;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.3px;
}
.toast-cta:hover {
  transform: translateY(-1px);
}
.dh-symbols {
  display: flex;
  align-items: center;
  gap: 18px;
  flex: 1 1 auto;
  font-family: var(--ff-mn);
  flex-wrap: nowrap;
  overflow-x: hidden;
  min-width: 0;
}
.dh-sym {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  white-space: nowrap;
}
.dh-sym-name {
  color: rgba(255, 255, 255, 0.55);
  font-weight: 700;
  letter-spacing: 0.4px;
}
.dh-sym-px {
  color: var(--tx-1);
  font-weight: 800;
}
.dh-sym-pct {
  font-weight: 700;
  font-size: 10px;
}
.dh-sym-pct.up {
  color: var(--up);
}
.dh-sym-pct.down {
  color: #f87171;
}
.dh-stats {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-left: 12px;
  border-left: 1px solid rgba(255, 255, 255, 0.08);
}
.dh-stat {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--ff-mn);
  font-size: 11px;
}
.dh-stat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tx-3);
}
.dh-stat-dot.run {
  background: var(--up);
  box-shadow: 0 0 6px var(--up);
}
.dh-stat-k {
  color: rgba(255, 255, 255, 0.55);
  font-weight: 700;
  letter-spacing: 0.4px;
  font-size: 10px;
}
.dh-stat-v {
  color: var(--tx-1);
  font-weight: 800;
  font-size: 13px;
}
.dh-new-btn {
  background: linear-gradient(135deg, #14b8a6 0%, #0891b2 100%);
  color: #ffffff;
  font-family: var(--ff-mn);
  border: 0;
  padding: 8px 14px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
  border-radius: 6px;
  cursor: pointer;
  box-shadow: 0 0 14px rgba(20, 184, 166, 0.4);
  transition: all 0.15s;
}
.dh-new-btn:hover {
  box-shadow: 0 0 22px rgba(20, 184, 166, 0.65);
  transform: translateY(-1px);
}

/* SIGN OUT button on the dashboard header. Previously styled as a
   tiny ghost button (11px / 7×12 padding / transparent bg) — users
   reported it as "not visible". Bumped to a real CTA-weight button
   while keeping it secondary to + NEW STRATEGY. Red-tinted border
   + subtle red bg signal the destructive nature without screaming
   for attention. Hover escalates to a clear red affordance. */
.dh-signout-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: rgba(239, 68, 68, 0.08);
  color: #ffb4b4;
  font-family: var(--ff-ui);
  border: 1px solid rgba(239, 68, 68, 0.4);
  padding: 10px 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.3px;
  border-radius: 6px;
  cursor: pointer;
  transition:
    background 0.18s,
    border-color 0.18s,
    color 0.18s,
    transform 0.18s;
}
.dh-signout-btn:hover {
  background: rgba(239, 68, 68, 0.2);
  border-color: rgba(239, 68, 68, 0.85);
  color: #ffffff;
  transform: translateY(-1px);
}
.dh-signout-ico {
  font-size: 14px;
  line-height: 1;
}
.dh-signout-label {
  letter-spacing: 0.3px;
}
@media (max-width: 768px) {
  /* Collapse to icon-only on narrow viewports — the button stays
     accessible without forcing a wrap. */
  .dh-signout-btn {
    padding: 10px 12px;
  }
  .dh-signout-label {
    display: none;
  }
}

/* SECTION HEADERS — STRATEGIES + BOTS ----------------------------------- */
.dock.hero-dock .dock-h.section-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 38px;
  padding: 0 18px;
  background: transparent;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.8px;
  color: var(--tx-1);
}
/* Small (i) info button next to the section title — opens the
   strategy-vs-bot comparison popover. */
.section-info {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-3);
  font-family: serif;
  font-style: italic;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border: 1px solid var(--bd-2);
  transition:
    background 0.15s,
    color 0.15s,
    border-color 0.15s;
}
.section-info:hover {
  background: rgba(245, 158, 11, 0.12);
  color: var(--orange);
  border-color: rgba(245, 158, 11, 0.3);
}
/* One-line description right under the section header */
.section-desc {
  padding: 4px 16px 8px;
  color: var(--tx-3);
  font-size: 11px;
  line-height: 1.45;
  border-bottom: 1px solid var(--bd-1);
  background: rgba(255, 255, 255, 0.01);
}

/* Help text on the empty-state "+ NEW STRATEGY/BOT" cards */
.strat-hero-add .sha-help {
  font-size: 10px;
  color: var(--tx-3);
  margin-top: 8px;
  padding: 0 12px;
  text-align: center;
  line-height: 1.45;
  font-family: var(--ff-ui);
  letter-spacing: 0.2px;
  max-width: 220px;
}
#hero-add.primary-add .sha-help {
  color: rgba(242, 163, 65, 0.65);
}
#bot-hero-add.primary-add .sha-help {
  color: rgba(167, 139, 250, 0.7);
}

/* Strategy-vs-Bot info popover */
.info-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(8px);
  padding: 24px;
  animation: u-fade 0.2s ease;
}
.info-overlay.hidden {
  display: none !important;
}
.info-card {
  width: 100%;
  max-width: 580px;
  background: linear-gradient(
    180deg,
    var(--bg-2, #11151c),
    var(--bg-1, #0a0d12)
  );
  border: 1px solid var(--bd-2);
  border-radius: 16px;
  padding: 32px 28px 26px;
  position: relative;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  animation: u-pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}
.info-card .info-x {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 16px;
  border-radius: 7px;
}
.info-card .info-x:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-1);
}
.info-card .info-h {
  color: var(--tx-1);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-bottom: 6px;
}
.info-card .info-sub {
  color: var(--tx-3);
  font-size: 13px;
  margin-bottom: 22px;
  line-height: 1.5;
}
.info-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  margin-bottom: 18px;
}
.info-tbl thead th {
  text-align: left;
  padding: 10px 12px;
  color: var(--tx-3);
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  font-size: 10px;
  border-bottom: 1px solid var(--bd-2);
}
.info-tbl thead th:nth-child(2) {
  color: rgba(242, 163, 65, 0.95);
}
.info-tbl thead th:nth-child(3) {
  color: rgba(167, 139, 250, 0.95);
}
.info-tbl tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--bd-1);
  color: var(--tx-2);
  vertical-align: top;
}
.info-tbl tbody tr:last-child td {
  border-bottom: 0;
}
.info-tbl tbody td:first-child {
  color: var(--tx-3);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  width: 30%;
}
.info-tbl tbody td b {
  color: var(--tx-1);
  font-weight: 700;
}
.info-tip {
  padding: 12px 14px;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.25);
  border-radius: 8px;
  color: var(--tx-2);
  font-size: 12px;
  line-height: 1.5;
}
.info-tip b {
  color: var(--orange);
  font-weight: 700;
}
@media (max-width: 600px) {
  .info-card {
    padding: 24px 18px 18px;
  }
  .info-tbl {
    font-size: 11px;
  }
  .info-tbl tbody td {
    padding: 8px 10px;
  }
}

/* =================================================================
   TELEGRAM ADOPTION (Phase 1)
   1.1 Header chip
   1.2 Banner above strategies
   1.4 Missed-signal nudge toast
   1.5 QR connect modal
   ================================================================= */

/* 1.1 Header CONNECT button — visible only for not-connected users.
   Connected users see nothing (button is display:none). */
.dh-tg-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  margin-left: 4px;
  border-radius: 100px;
  font-family: var(--ff-mn);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.4px;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid rgba(245, 158, 11, 0.4);
  background: linear-gradient(
    135deg,
    rgba(245, 158, 11, 0.18),
    rgba(234, 88, 12, 0.1)
  );
  color: #fbbf24;
  transition:
    filter 0.15s,
    transform 0.1s,
    box-shadow 0.2s;
  white-space: nowrap;
}
.dh-tg-chip:hover {
  filter: brightness(1.15);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(245, 158, 11, 0.25);
}
.dh-tg-chip .dh-tg-ico {
  font-size: 11px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.dh-tg-chip .dh-tg-ico .tg-logo-svg {
  width: 16px;
  height: 16px;
  display: block;
}
.dh-tg-chip .dh-tg-label {
  font-weight: 800;
}
.dh-tg-chip.dh-tg-off {
  /* default styling above already covers this */
}
/* LOCKED (Free, no trial) — gray + lock-feel, routes to upgrade modal */
.dh-tg-chip.dh-tg-locked {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--bd-2);
  color: var(--tx-3);
}
.dh-tg-chip.dh-tg-locked .dh-tg-ico {
  filter: grayscale(1);
  opacity: 0.6;
}

/* Reusable Telegram brand-logo SVG sizes — inline SVG so it stays
   crisp at every viewport. Default is small chip size; .tg-logo-lg
   bumps it for the QR-state hero card. */
.tg-logo-svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
}
.tg-logo-svg.tg-logo-lg {
  width: 48px;
  height: 48px;
}
.al-ch-icon.tg .tg-logo-svg {
  width: 22px;
  height: 22px;
}
@media (max-width: 600px) {
  .dh-tg-chip {
    padding: 4px 10px;
    font-size: 9px;
  }
}

/* 1.2 Banner above strategies — slim line, dismissable */
.tg-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  margin: 0 0 8px;
  border-radius: 6px;
  font-size: 12px;
  line-height: 1.4;
  background: rgba(34, 197, 94, 0.06);
  border: 1px solid rgba(34, 197, 94, 0.25);
  color: var(--tx-2);
}
.tg-banner .tgb-ico {
  font-size: 13px;
  flex-shrink: 0;
}
.tg-banner .tgb-body {
  flex: 1;
  min-width: 0;
}
.tg-banner .tgb-body b {
  color: var(--tx-1);
  font-weight: 700;
}
.tg-banner .tgb-cta {
  padding: 3px 10px;
  background: #10b981;
  color: #04130c;
  border: 0;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: filter 0.15s;
}
.tg-banner .tgb-cta:hover {
  filter: brightness(1.1);
}
.tg-banner .tgb-x {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 13px;
  padding: 0 4px;
  border-radius: 3px;
  line-height: 1;
}
.tg-banner .tgb-x:hover {
  color: var(--tx-1);
}
@media (max-width: 600px) {
  .tg-banner {
    flex-wrap: wrap;
    gap: 6px;
  }
  .tg-banner .tgb-cta {
    order: 99;
  }
}

/* 1.4 Missed-signal nudge — slim toast in the toast stack */
.tg-missed-nudge {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  margin-top: 6px;
  background: var(--bg-2);
  border: 1px solid rgba(239, 68, 68, 0.25);
  border-radius: 8px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.4);
  font-size: 12px;
  max-width: 380px;
  animation: tgmn-slide 0.3s ease;
}
@keyframes tgmn-slide {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.tg-missed-nudge .tgmn-icon {
  font-size: 18px;
  flex-shrink: 0;
  line-height: 1;
}
.tg-missed-nudge .tgmn-body {
  flex: 1;
  min-width: 0;
}
.tg-missed-nudge .tgmn-title {
  color: var(--tx-1);
  font-weight: 700;
  font-size: 12px;
  line-height: 1.3;
}
.tg-missed-nudge .tgmn-sub {
  color: var(--tx-3);
  font-size: 11px;
  margin-top: 2px;
  line-height: 1.4;
}
.tg-missed-nudge .tgmn-cta {
  padding: 5px 10px;
  background: linear-gradient(135deg, #10b981, #059669);
  color: #04130c;
  border: 0;
  border-radius: 5px;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.tg-missed-nudge .tgmn-cta:hover {
  filter: brightness(1.1);
}
.tg-missed-nudge .tgmn-x {
  background: transparent;
  border: 0;
  color: var(--tx-4);
  cursor: pointer;
  font-size: 13px;
  padding: 0 4px;
  border-radius: 3px;
}
.tg-missed-nudge .tgmn-x:hover {
  color: var(--tx-1);
}

/* 1.5 QR connect modal */
.tg-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(8px);
  padding: 24px;
  animation: u-fade 0.2s ease;
}
.tg-modal-overlay.hidden {
  display: none !important;
}
.tg-modal-card {
  width: 100%;
  max-width: 480px;
  background: linear-gradient(180deg, var(--bg-2), var(--bg-1));
  border: 1px solid var(--bd-2);
  border-radius: 16px;
  padding: 32px 28px;
  text-align: center;
  position: relative;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  animation: u-pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}
.tg-modal-x {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  background: transparent;
  border: 0;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 16px;
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tg-modal-x:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-1);
}

.tg-state h2 {
  color: var(--tx-1);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-bottom: 8px;
}
.tg-state p {
  color: var(--tx-3);
  font-size: 13px;
  line-height: 1.5;
}

.tg-state-loading {
  padding: 60px 0;
}
.tg-spinner {
  width: 36px;
  height: 36px;
  border: 3px solid var(--bd-2);
  border-top-color: var(--orange);
  border-radius: 50%;
  margin: 0 auto 14px;
  animation: spin 0.7s linear infinite;
}
.tg-loading-text {
  color: var(--tx-3);
  font-size: 13px;
}

.tg-h .tg-emoji {
  font-size: 36px; /* fallback for any legacy emoji content */
  margin-bottom: 12px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tg-h .tg-emoji .tg-logo-svg {
  width: 56px;
  height: 56px;
}
.tg-h h2 {
  margin-bottom: 6px;
}
.tg-h p {
  margin-bottom: 22px;
}

.tg-qr-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 20px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px dashed var(--bd-2);
  border-radius: 12px;
  margin-bottom: 18px;
}
.tg-qr-box {
  background: #fff;
  padding: 12px;
  border-radius: 8px;
  line-height: 0;
}
.tg-poll-status {
  color: var(--tx-3);
  font-size: 11px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--ff-mono);
  letter-spacing: 0.3px;
}
.tg-pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--orange);
  animation: tg-pulse 1.5s infinite;
}
@keyframes tg-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.6);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(245, 158, 11, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0);
  }
}

.tg-steps {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: var(--tx-2);
  margin-bottom: 18px;
}
.tg-steps .tg-step b {
  display: inline-block;
  color: var(--orange);
  font-weight: 800;
  width: 16px;
}

.tg-mobile-cta {
  display: block;
  padding: 12px;
  background: linear-gradient(135deg, #229ed9, #1976d2);
  color: #fff;
  text-decoration: none;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 700;
  transition:
    filter 0.15s,
    transform 0.1s;
}
.tg-mobile-cta:hover {
  filter: brightness(1.1);
  transform: translateY(-1px);
}

.tg-state-success {
  padding: 20px 0;
  position: relative;
}
.tg-success-burst {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
}
@keyframes tg-burst {
  to {
    transform: translate(var(--dx), var(--dy)) rotate(360deg);
    opacity: 0;
  }
}
.tg-success-check {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: linear-gradient(135deg, #10b981, #059669);
  color: #04130c;
  font-size: 36px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 16px;
  box-shadow: 0 12px 30px rgba(16, 185, 129, 0.35);
  position: relative;
  z-index: 2;
  animation: tg-check-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes tg-check-pop {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}

.tg-success-cta,
.tg-state-error .tg-success-cta {
  margin-top: 18px;
  padding: 12px 24px;
  background: linear-gradient(135deg, var(--orange), var(--orange-3, #ea580c));
  color: #1a0a00;
  border: 0;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
  transition:
    transform 0.1s,
    box-shadow 0.2s;
}
.tg-success-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(245, 158, 11, 0.35);
}

.tg-state-error {
  padding: 30px 0;
}
.tg-state-error .tg-error-ico {
  font-size: 36px;
  margin-bottom: 14px;
}
.tg-state-error h2 {
  color: #fca5a5;
}

@media (max-width: 600px) {
  .tg-modal-card {
    padding: 26px 20px;
  }
  .tg-h h2 {
    font-size: 19px;
  }
}

/* =================================================================
   FEATURED TELEGRAM OPT-IN CARD inside strategy/bot creation modals
   Lives in #cfg-tg-optin (paste-strategy modal step 3) and
   #bs-tg-optin (Bot Studio). Three states:
     .tg-locked        — Pro feature teaser (free user)
     .tg-disconnected  — eligible but not bound; inline Connect CTA
     .tg-connected     — green, with checkbox to enable on this bot
   ================================================================= */
.cfg-section-h {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--tx-2);
  margin-bottom: 6px;
}
.cfg-section-h .cfg-section-sub {
  color: var(--tx-3);
  font-weight: 500;
  letter-spacing: 0;
  font-size: 10px;
}

.cfg-tg-optin {
  margin-bottom: 10px;
}
.cfg-tg-optin .cfg-tg-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 9px;
  font-size: 12px;
  line-height: 1.4;
  border: 1px solid var(--bd-2);
  background: rgba(255, 255, 255, 0.02);
}
.cfg-tg-optin.tg-disconnected .cfg-tg-row {
  background: linear-gradient(
    135deg,
    rgba(34, 158, 217, 0.06),
    rgba(25, 118, 210, 0.04)
  );
  border-color: rgba(34, 158, 217, 0.25);
}
.cfg-tg-optin.tg-connected .cfg-tg-row {
  background: linear-gradient(
    135deg,
    rgba(16, 185, 129, 0.08),
    rgba(5, 150, 105, 0.04)
  );
  border-color: rgba(16, 185, 129, 0.3);
}
.cfg-tg-optin.tg-locked .cfg-tg-row {
  background: rgba(255, 255, 255, 0.03);
  border-color: var(--bd-2);
  opacity: 0.85;
}

.cfg-tg-optin .cfg-tg-icon {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  background: rgba(255, 255, 255, 0.06);
}
.cfg-tg-optin.tg-connected .cfg-tg-icon {
  background: linear-gradient(135deg, #10b981, #059669);
  color: #04130c;
  font-weight: 800;
}
.cfg-tg-optin.tg-disconnected .cfg-tg-icon {
  background: rgba(34, 158, 217, 0.18);
  color: #229ed9;
}
.cfg-tg-optin.tg-locked .cfg-tg-icon {
  opacity: 0.5;
}

.cfg-tg-optin .cfg-tg-body {
  flex: 1;
  min-width: 0;
}
.cfg-tg-optin .cfg-tg-title {
  color: var(--tx-1);
  font-weight: 700;
  font-size: 13px;
}
.cfg-tg-optin .cfg-tg-sub {
  color: var(--tx-3);
  font-size: 11px;
  margin-top: 2px;
}

.cfg-tg-optin .cfg-tg-cta {
  padding: 7px 14px;
  background: linear-gradient(135deg, #229ed9, #1976d2);
  color: #fff;
  border: 0;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition:
    filter 0.15s,
    transform 0.1s;
}
.cfg-tg-optin .cfg-tg-cta:hover {
  filter: brightness(1.1);
  transform: translateY(-1px);
}
.cfg-tg-optin .cfg-tg-cta-pro {
  background: linear-gradient(135deg, var(--orange), var(--orange-3, #ea580c));
  color: #1a0a00;
}

.cfg-tg-optin.tg-connected input[type="checkbox"] {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  accent-color: var(--up, #10b981);
  margin: 0;
}

/* =================================================================
   DEPLOYMENT SUCCESS MODAL — shown after a strategy/bot is deployed.
   Confirms what was created + explains what happens next + surfaces
   the Telegram opt-in at the moment of intent.
   ================================================================= */
.ds-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(8px);
  padding: 24px;
  animation: u-fade 0.2s ease;
}
.ds-overlay.show {
  display: flex;
}
.ds-card {
  width: 100%;
  max-width: 540px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  background: linear-gradient(
    180deg,
    var(--bg-2, #11151c),
    var(--bg-1, #0a0d12)
  );
  border: 1px solid rgba(16, 185, 129, 0.3);
  border-radius: 18px;
  padding: 32px 28px 24px;
  position: relative;
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.6),
    0 0 60px rgba(16, 185, 129, 0.1);
  animation: u-pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.ds-x {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  color: var(--tx-3);
  cursor: pointer;
  font-size: 18px;
  border-radius: 7px;
}
.ds-x:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-1);
}

.ds-h {
  text-align: center;
  margin-bottom: 22px;
}
.ds-emoji {
  font-size: 44px;
  line-height: 1;
  margin-bottom: 10px;
  display: inline-block;
  animation: ds-bounce 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes ds-bounce {
  0% {
    transform: scale(0);
  }
  60% {
    transform: scale(1.15);
  }
  100% {
    transform: scale(1);
  }
}
.ds-h h2 {
  color: var(--tx-1);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-bottom: 4px;
}
.ds-name {
  color: var(--up, #10b981);
  font-weight: 700;
  font-size: 15px;
  font-family: var(--ff-mn);
  letter-spacing: 0.3px;
}

/* Configuration confirmation grid */
.ds-config {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--bd-2);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 22px;
}
.ds-cfg-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  font-size: 13px;
  border-bottom: 1px dashed var(--bd-1);
}
.ds-cfg-row:last-child {
  border-bottom: 0;
}
.ds-cfg-l {
  color: var(--tx-3);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.ds-cfg-v {
  color: var(--tx-1);
  font-weight: 700;
  font-family: var(--ff-mn);
  font-size: 13px;
}

/* "What happens now" explainer */
.ds-flow {
  margin-bottom: 22px;
  padding: 16px;
  background: rgba(245, 158, 11, 0.04);
  border: 1px solid rgba(245, 158, 11, 0.2);
  border-radius: 10px;
}
.ds-flow-h {
  color: var(--orange, #f59e0b);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  margin-bottom: 10px;
}
.ds-flow-list {
  list-style: none;
  padding: 0;
  margin: 0;
  counter-reset: ds-step;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ds-flow-list li {
  counter-increment: ds-step;
  position: relative;
  padding-left: 28px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--tx-2);
}
.ds-flow-list li::before {
  content: counter(ds-step);
  position: absolute;
  left: 0;
  top: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--orange, #f59e0b);
  color: #1a0a00;
  font-size: 11px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--ff-mn);
}
.ds-flow-list b {
  color: var(--tx-1);
  font-weight: 700;
}

/* Telegram CTA — three states */
.ds-tg {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 10px;
  margin-bottom: 22px;
  border: 1px solid;
}
.ds-tg.ds-tg-on {
  background: linear-gradient(
    135deg,
    rgba(16, 185, 129, 0.1),
    rgba(5, 150, 105, 0.05)
  );
  border-color: rgba(16, 185, 129, 0.3);
}
.ds-tg.ds-tg-off {
  background: linear-gradient(
    135deg,
    rgba(34, 158, 217, 0.08),
    rgba(25, 118, 210, 0.04)
  );
  border-color: rgba(34, 158, 217, 0.3);
}
.ds-tg.ds-tg-locked {
  background: rgba(255, 255, 255, 0.03);
  border-color: var(--bd-2);
}
.ds-tg .ds-tg-ico {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
}
.ds-tg.ds-tg-on .ds-tg-ico {
  background: linear-gradient(135deg, #10b981, #059669);
  color: #04130c;
  font-weight: 800;
}
.ds-tg.ds-tg-off .ds-tg-ico {
  background: rgba(34, 158, 217, 0.18);
  color: #229ed9;
}
.ds-tg.ds-tg-locked .ds-tg-ico {
  background: rgba(255, 255, 255, 0.06);
  opacity: 0.7;
}
.ds-tg .ds-tg-body {
  flex: 1;
  min-width: 0;
}
.ds-tg .ds-tg-body b {
  display: block;
  color: var(--tx-1);
  font-weight: 700;
  font-size: 13px;
  margin-bottom: 3px;
}
.ds-tg .ds-tg-body span {
  color: var(--tx-3);
  font-size: 12px;
  line-height: 1.5;
}
.ds-tg .ds-tg-cta {
  padding: 8px 14px;
  background: linear-gradient(135deg, #229ed9, #1976d2);
  color: #fff;
  border: 0;
  border-radius: 7px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition:
    filter 0.15s,
    transform 0.1s;
}
.ds-tg .ds-tg-cta:hover {
  filter: brightness(1.1);
  transform: translateY(-1px);
}
.ds-tg .ds-tg-cta-pro {
  background: linear-gradient(
    135deg,
    var(--orange, #f59e0b),
    var(--orange-3, #ea580c)
  );
  color: #1a0a00;
}

/* Action buttons */
.ds-actions {
  display: flex;
  gap: 10px;
  flex-direction: column;
}
.ds-cta-pri {
  padding: 13px 20px;
  background: linear-gradient(135deg, #10b981, #059669);
  color: #04130c;
  border: 0;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
  transition:
    transform 0.1s,
    box-shadow 0.2s,
    filter 0.15s;
}
.ds-cta-pri:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 24px rgba(16, 185, 129, 0.35);
  filter: brightness(1.05);
}
.ds-cta-sec {
  padding: 11px 20px;
  background: transparent;
  color: var(--tx-3);
  border: 1px solid var(--bd-2);
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s,
    border-color 0.15s;
}
.ds-cta-sec:hover {
  background: var(--bg-3);
  color: var(--tx-1);
  border-color: var(--bd-3);
}

@media (max-width: 600px) {
  .ds-card {
    padding: 26px 20px;
  }
  .ds-h h2 {
    font-size: 19px;
  }
  .ds-emoji {
    font-size: 36px;
  }
}

/* Inline success view inside step 5 of the new-strategy modal —
   reuses the .ds-* tokens but lives in the modal flow instead of a
   separate overlay. The wrapper just provides padding so the success
   card has breathing room inside the modal-step container. */
.step5-success {
  padding: 8px 0 16px;
}
.ds-card-inline {
  padding: 0; /* the modal-step itself already has padding */
}
.section-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  background: linear-gradient(
    135deg,
    rgba(20, 184, 166, 0.2),
    rgba(8, 145, 178, 0.2)
  );
  color: #5eead4;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  box-shadow: inset 0 0 0 1px rgba(20, 184, 166, 0.3);
}
.section-count {
  font-family: var(--ff-mn);
  background: rgba(255, 255, 255, 0.06);
  color: var(--tx-2);
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 800;
}
.section-count.cyan {
  background: rgba(20, 184, 166, 0.15);
  color: #5eead4;
  box-shadow: inset 0 0 0 1px rgba(20, 184, 166, 0.25);
}
.section-meta {
  font-family: var(--ff-mn);
  font-size: 10px;
  color: rgba(255, 255, 255, 0.55);
  letter-spacing: 0.5px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.section-meta .d-act {
  background: rgba(20, 184, 166, 0.1);
  color: #5eead4;
  border: 1px solid rgba(20, 184, 166, 0.3);
  padding: 5px 10px;
  font-size: 10px;
  border-radius: 5px;
  font-family: var(--ff-mn);
  font-weight: 800;
  letter-spacing: 0.4px;
  cursor: pointer;
}
.section-meta .d-act:hover {
  background: rgba(20, 184, 166, 0.2);
}
.section-meta #strat-running-count,
.section-meta #bots-running-count {
  color: var(--up);
  font-weight: 800;
}
.section-meta #strat-unconf-count,
.section-meta #bots-paused-count {
  color: var(--warn);
  font-weight: 800;
}

/* Hide elements moved/replaced by redesign */
.cmd-bar.top-nav-bar .cmd-input.hidden,
.cmd-bar.top-nav-bar .user-cell.hidden {
  display: none !important;
}
.cmd-bar.top-nav-bar .led.hidden {
  display: none !important;
}
.top-nav .tnav-tab.hidden {
  display: none !important;
}

/* =========================================================================
   STRATEGY CARDS — restyled to match the mockup (subtle borders,
   small kind-icon avatar, teal deploy button instead of amber)
   ========================================================================= */

/* Override the legacy amber dashed border on unconfigured strategies */
.strat-hero-card.status-unconfigured {
  border-left: 3px dashed rgba(242, 163, 65, 0.55) !important;
  background: linear-gradient(
    180deg,
    rgba(242, 163, 65, 0.03),
    var(--bg-panel)
  );
}
.strat-hero-card.status-running {
  border-left: 3px solid var(--up);
}
.strat-hero-card.status-paused {
  border-left: 3px solid var(--warn);
}
.strat-hero-card.status-killed {
  border-left: 3px solid var(--down);
  opacity: 0.65;
}

/* (Removed) Legacy 24×24 .shc-dot kind-icon avatar + 3-column
   `grid-template-columns: 26px 1fr auto` override. Both were
   superseded by the redesigned 4-column layout (see ~L2436):
   the new .shc-icon-box (44×44) handles status indication, and
   the grid is now `44px 1fr auto auto` with a dedicated actions
   cell for the edit + delete icon-buttons. The .shc-dot element
   is hidden in the base rules — keeping the kind-* glyph mapping
   alive here would have rendered nothing while still overriding
   the new grid. */

/* DEPLOY button — teal gradient to match mockup */
.strat-hero-card .shc-btn.primary,
.shc-deploy-btn {
  background: linear-gradient(135deg, #14b8a6 0%, #0891b2 100%) !important;
  color: #ffffff !important;
  border: 0 !important;
  box-shadow: 0 0 10px rgba(20, 184, 166, 0.3);
}
.strat-hero-card .shc-btn.primary:hover,
.shc-deploy-btn:hover {
  filter: brightness(1.1);
  box-shadow: 0 0 14px rgba(20, 184, 166, 0.5);
}

/* Subtle hover for cards */
.strat-hero-card:hover {
  border-color: rgba(20, 184, 166, 0.3);
  box-shadow: 0 0 14px rgba(20, 184, 166, 0.1);
}

/* "+ NEW STRATEGY" big add card — match the mockup's prominent style */
.strat-hero-add.primary-add {
  border-color: rgba(242, 163, 65, 0.4);
}

/* Strategies modal filter chips */
.sm-filter-chips {
  display: inline-flex;
  gap: 4px;
  margin-left: 8px;
  vertical-align: middle;
}
.sm-filter-chip {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  color: var(--tx-3);
  padding: 4px 10px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  border-radius: 12px;
  cursor: pointer;
  font-family: var(--ff-mn);
}
.sm-filter-chip:hover {
  color: var(--tx-1);
  border-color: var(--bd-3);
}
.sm-filter-chip.active {
  background: rgba(20, 184, 166, 0.15);
  color: #5eead4;
  border-color: rgba(20, 184, 166, 0.4);
}
.bd-sm-actions {
  white-space: nowrap;
}
.bd-sm-actions .ghost-btn.sm {
  padding: 3px 7px;
  font-size: 9px;
  margin-right: 2px;
}
.bd-sm-actions .ghost-btn.sm.kill {
  color: var(--down);
  border-color: rgba(242, 62, 85, 0.4);
}

/* Bot card icon — replace the geometric glyph with the animated robot SVG.
   The .shc-dot wrapper is sized to fit the grid column (24px); the SVG
   carries its own animations (bob/eye-blink/scan/aura). */
.bot-hero-card .shc-dot.bot-shc-icon {
  width: 24px;
  height: 24px;
  background: transparent !important;
  border: 0 !important;
  transform: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
  box-shadow: none !important;
  animation: none !important;
}
.bot-hero-card .shc-dot.bot-shc-icon::after,
.bot-hero-card .shc-dot.bot-shc-icon::before {
  display: none;
}
.bot-hero-card .shc-bot-icon {
  width: 26px;
  height: 26px;
  pointer-events: none;
  filter: drop-shadow(0 0 4px rgba(20, 184, 166, 0.45));
}
.bot-hero-card.status-paused .shc-bot-icon {
  opacity: 0.65;
  filter: drop-shadow(0 0 3px rgba(242, 163, 65, 0.4));
}
.bot-hero-card.status-killed .shc-bot-icon {
  opacity: 0.4;
  filter: grayscale(0.7);
}

/* =========================================================================
   MOBILE / TABLET RESPONSIVE LAYOUT (placed at end of file so these rules
   win source-order ties against base styles defined throughout the file)
   ========================================================================= */

/* Bot live dashboard — 2-column tablet layout before stacking on phone */
@media (max-width: 1200px) {
  #bh-pane-dashboard {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .bd-hero-panel {
    grid-column: 1 / span 2;
    grid-row: auto;
    max-height: none;
    min-height: 480px;
  }
  .bd-activity-panel {
    grid-column: 1 / span 2;
    grid-row: auto;
    max-height: 320px;
  }
  .bd-watchlist-panel {
    grid-column: 1 / span 2;
  }
  .bd-indicators-panel {
    grid-column: 1 / span 2;
  }
  .bd-account-strip {
    grid-column: 1 / span 2;
  }
  .bd-positions-panel {
    grid-column: 1 / span 2;
  }
  .bd-strategy-panel {
    grid-column: 1 / span 2;
  }
  .bd-status-footer {
    grid-column: 1 / span 2;
  }
}

/* TABLET (≤980px): hide cmd-bar widgets that overflow narrow widths */
@media (max-width: 980px) {
  .cmd-bar:not(.top-nav-bar) {
    grid-template-columns: auto 1fr auto auto;
    height: 40px;
  }
  .fkeys,
  .clocks,
  .conn-leds {
    display: none;
  }
  .cmd-input input {
    font-size: 13px;
    padding: 8px 10px;
  }
  .ticker-tape {
    display: none;
  }
  /* New top-nav-bar — show only the essential bits at tablet width.
     Drop the LDN/TYO/IST clocks (keep just NY) and the feed LEDs to
     give the scrolling tab nav room to breathe. */
  .cmd-bar.top-nav-bar .tnav-clocks .tnav-clk:not(:first-child) {
    display: none;
  }
  .cmd-bar.top-nav-bar .tnav-feed {
    display: none;
  }
  .cmd-bar.top-nav-bar .tnav-spacer {
    display: none;
  }
}

/* MOBILE (≤640px) */
@media (max-width: 640px) {
  /* ----- TOP NAV (new redesign) ------------------------------------- */
  /* The redesigned top-nav-bar is `display: flex` already; just trim
     the right-side widgets and shrink the brand/kill so the scrolling
     tab nav fits the rest of the row. */
  .cmd-bar.top-nav-bar {
    height: 46px;
    padding: 0 8px;
    gap: 6px;
  }
  .cmd-bar.top-nav-bar .brand-mark {
    width: 28px;
    height: 28px;
    font-size: 11px;
  }
  .cmd-bar.top-nav-bar .tnav-clocks,
  .cmd-bar.top-nav-bar .tnav-feed,
  .cmd-bar.top-nav-bar .tnav-spacer {
    display: none !important;
  }
  .cmd-bar.top-nav-bar .tnav-kill {
    padding: 5px 8px;
    font-size: 9px;
    gap: 3px;
    flex: 0 0 auto;
  }
  .top-nav .tnav-tab {
    padding: 6px 8px;
    font-size: 11px;
    font-weight: 700;
  }
  /* Legacy cmd-bar (without .top-nav-bar) — keep old fallback behaviour */
  .cmd-bar:not(.top-nav-bar) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 0 8px;
    height: 40px;
    grid-template-columns: none;
  }
  .cmd-input {
    display: none;
  }
  .brand-tag {
    display: none;
  }
  .user-meta {
    display: none;
  }
  .user-cell {
    padding-right: 0;
    padding-left: 0;
  }
  .avatar {
    width: 32px;
    height: 32px;
    font-size: 13px;
  }
  .kill-all-btn {
    padding: 6px 10px;
    font-size: 10px;
    flex: 0 0 auto;
  }

  /* ----- TERMINAL GRID --------------------------------------------- */
  /* Three rows: top-nav (46px) · main grid (1fr) · status bar (26px).
     Override the explicit grid-row: N assignments from the desktop
     base rules so children land in the right tracks even though the
     redesign introduced a `.left-sidebar` and merged the ticker. */
  .terminal {
    grid-template-rows: 46px 1fr 26px;
  }
  .terminal > .cmd-bar {
    grid-row: 1;
  }
  .terminal > .ticker-tape {
    display: none;
  }
  .terminal > .grid {
    grid-row: 2;
  }
  .terminal > .status-bar {
    grid-row: 3;
  }

  /* ----- MAIN GRID + LEFT SIDEBAR ---------------------------------- */
  /* On phones the left sidebar shrinks to a 44px icon column; the
     right rail is hidden entirely (it was already empty in the new
     design but display:none keeps the grid from allocating space).
     The left sidebar (icon column) is also hidden — its job is taken
     over by the hamburger drawer below, which gives users 80vw of
     real estate with text labels instead of icons in a 44px strip. */
  .grid.grid-v2 {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .grid.grid-v2 .col-right {
    display: none !important;
  }
  .left-sidebar {
    display: none !important;
  }
  /* Show the mobile hamburger + (when toggled) the slide-in drawer */
  .mobile-menu-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* Account-menu popover (anchored to .ls-avatar) is also useless when
     the avatar is hidden — drawer's sign-out button replaces it. */
  #ls-account-menu {
    display: none !important;
  }

  /* col-main: stack content and scroll the whole column. The desktop
     rule pins the 2 docks to 1fr each (50/50 split inside the cell);
     on mobile that hides everything past 2-3 cards because the dock
     itself becomes the scroll container at a tiny height. Switch to
     block layout so each dock sizes to its actual content and the
     COLUMN scrolls — feels far more natural on a phone. */
  .grid.grid-v2 .col-main {
    display: block !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    min-height: 0;
    height: 100%;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  .col-main > .dock {
    display: flex !important;
    flex-direction: column;
    min-height: 0;
    overflow: visible !important;
  }
  /* Inner dock grids no longer need their own scroll on mobile — the
     whole col-main scrolls instead. flex: 0 0 auto ensures they size
     to the natural total card height, not flex-fill an unsized parent. */
  .strat-hero-grid,
  .bots-hero-grid {
    overflow: visible !important;
    flex: 0 0 auto !important;
    max-height: none !important;
  }

  .kill-banner {
    padding: 4px 8px;
    font-size: 10px;
    gap: 6px;
    line-height: 1.2;
  }
  .kill-banner .kb-text {
    white-space: normal;
  }
  .kill-banner .kb-clear {
    padding: 4px 8px;
    font-size: 10px;
  }

  /* ----- DASHBOARD SUB-HEADER -------------------------------------- */
  .dash-header {
    flex-wrap: wrap;
    padding: 8px 10px;
    gap: 8px;
  }
  .dh-symbols {
    order: 99;
    flex-basis: 100%;
    overflow-x: auto;
    white-space: nowrap;
    gap: 8px;
    padding-bottom: 2px;
  }
  .dh-stats {
    gap: 8px;
    flex-wrap: wrap;
  }
  .dh-new-btn {
    padding: 6px 10px;
    font-size: 10px;
  }

  /* ----- SECTION HEADERS ------------------------------------------- */
  /* Override the fixed 38px height so wrapped action buttons (BOT HUB,
     NEW BOT) don't overflow into the card grid below. */
  .dock.hero-dock .dock-h.section-h {
    height: auto !important;
    min-height: 38px;
    padding: 6px 10px;
    flex-wrap: wrap;
    gap: 6px;
  }
  .section-h .section-title {
    font-size: 10px;
    gap: 6px;
  }
  .section-h .section-meta {
    font-size: 9px;
    flex-wrap: wrap;
    gap: 6px;
    row-gap: 4px;
  }
  .section-h .section-meta .d-act {
    padding: 4px 8px;
    font-size: 9px;
  }

  /* Status bar */
  .status-bar {
    height: 26px;
    font-size: 9px;
    padding: 0 8px;
    gap: 6px;
    flex-wrap: nowrap;
    overflow-x: auto;
    white-space: nowrap;
  }
  .sb-section {
    gap: 4px;
  }
  /* Mobile-only force-hides for the OLD wall-of-stats are gone —
     the bar is now collapsed by default everywhere via .sb-extra,
     and toggling it expands gracefully on mobile too. */

  /* Strategies + Bots dock — single column, condensed cards */
  /* Mobile gap matched to desktop's spacing intent — gives each card
     enough breathing room that they don't feel stacked together. */
  .strat-hero-grid {
    grid-template-columns: 1fr !important;
    padding: 10px;
    gap: 12px;
  }
  .bots-hero-grid {
    grid-template-columns: 1fr !important;
    padding: 10px;
    gap: 12px;
  }
  /* Mobile padding stays a touch tighter than desktop's 14×16 to
     save ~6px per card across a long scrolling list, while still
     leaving the 44px icon-box and 32px action buttons clear of
     the card edges. */
  .strat-hero-card {
    padding: 12px 14px;
    column-gap: 10px;
  }
  /* Stats are now an inline flex row — on the narrow mobile width
     they wrap naturally to 2-3 lines, no manual grid override needed. */
  .strat-hero-card .shc-stats {
    gap: 4px 10px;
  }
  /* The "+ NEW STRATEGY" / "+ NEW BOT" placeholder cards were
     inheriting the desktop's tall min-height and consuming half the
     viewport on mobile. Tighten so users see real cards above the
     fold. */
  .strat-hero-add,
  .bot-hero-card.bhc-new {
    min-height: 0 !important;
    padding: 18px !important;
  }
  .strat-hero-add .sha-icon {
    font-size: 28px;
    margin-bottom: 4px;
  }
  .strat-hero-add .sha-title {
    font-size: 14px;
  }
  .strat-hero-add .sha-sub {
    font-size: 9px;
  }
  .dock-h {
    padding: 0 10px;
    flex-wrap: wrap;
  }
  .dock-h .d-meta {
    font-size: 9px;
  }
  .dock-h .d-act {
    padding: 4px 8px;
    font-size: 9px;
  }
  /* Top nav: subtle fade gradient at the right edge so users
     realize the tab strip scrolls horizontally when there are more
     tabs than fit (otherwise PORTFOLIO / ANALYTICS / ALERTS look
     cut off, not scrollable). */
  .top-nav {
    -webkit-mask-image: linear-gradient(
      to right,
      #000 calc(100% - 24px),
      transparent 100%
    );
    mask-image: linear-gradient(
      to right,
      #000 calc(100% - 24px),
      transparent 100%
    );
  }
  /* Dash-header on really narrow viewports (≤390px iPhone SE / 14):
     give stats their own row so the new-strategy button never gets
     clipped on the right edge. */
  .dh-stats {
    flex-basis: 100%;
    justify-content: space-between;
  }
  .dh-new-btn {
    padding: 6px 10px;
    font-size: 10px;
    white-space: nowrap;
  }

  /* Strategy detail page — mobile master-detail pattern.
     Default: sidebar (list of strategies) takes full screen.
     When user taps a strategy, .strategy-detail.mobile-detail-open
     is added — sidebar hides, main detail takes full screen. The
     ← back button in the header removes the class to return to
     the list. Mirrors iOS Settings / Mail-app navigation. */
  .strategy-detail {
    flex-direction: row; /* still row, but only one pane shown at a time */
  }
  .strategy-detail .sd-side {
    width: 100% !important;
    border-right: 0;
  }
  .strategy-detail .sd-main {
    display: none;
  }
  .strategy-detail.mobile-detail-open .sd-side {
    display: none;
  }
  .strategy-detail.mobile-detail-open .sd-main {
    display: flex;
    width: 100%;
  }
  /* Show the back arrow only when a detail is being viewed on mobile */
  .strategy-detail.mobile-detail-open .sd-mobile-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* When viewing the LIST (sidebar full-screen), show the top-left
     back arrow + hide the bulky bottom "BACK TO DASHBOARD" button.
     The arrow is the canonical iOS-style back affordance. */
  .strategy-detail .sd-list-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .strategy-detail .sd-back-bottom {
    display: none !important;
  }
  /* Tighten the detail header so the back button + title + actions
     fit on a 390px viewport without wrapping awkwardly. */
  .sd-header {
    padding: 8px 12px !important;
    gap: 8px !important;
    flex-wrap: wrap;
  }
  .sd-title {
    font-size: 15px !important;
  }
  .sd-sub {
    font-size: 9px !important;
  }
  .sd-actions {
    gap: 4px !important;
    flex-wrap: wrap;
  }
  .sd-actions .ghost-btn,
  .sd-actions .kill-all-btn {
    padding: 5px 8px !important;
    font-size: 9px !important;
  }

  /* Bot Hub overlay — master-detail pattern, parallels strategy-detail.
     Default: bot list (.bh-side) takes the full screen.
     When .bot-hub.mobile-detail-open is set (added by tapping a bot
     card / by openBotHub(id)), list hides and detail (.bh-main)
     takes full screen. Back arrow returns to list. */
  .bot-hub {
    flex-direction: row;
  }
  .bh-side {
    width: 100% !important;
    max-height: none !important;
    border-right: 0;
    border-bottom: 0;
  }
  .bh-main {
    display: none;
    flex: 1;
    min-height: 0;
  }
  .bot-hub.mobile-detail-open .bh-side {
    display: none;
  }
  .bot-hub.mobile-detail-open .bh-main {
    display: flex;
    width: 100%;
  }
  /* Back arrow visible only when detail is open */
  .bot-hub.mobile-detail-open .bh-mobile-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* List header gets a top-left back arrow that returns to the
     dashboard. Hides the bulky bottom button (was forcing users to
     scroll past 10+ bots to find a back affordance). */
  .bot-hub .bh-list-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .bot-hub .sd-back-bottom {
    display: none !important;
  }

  .bh-side-list {
    padding: 4px;
  }
  .bh-h {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
  }
  .bh-actions {
    width: 100%;
    flex-wrap: wrap;
    gap: 4px;
  }
  .bh-actions button {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 10px;
    font-size: 11px;
  }
  .bh-metrics {
    grid-template-columns: 1fr 1fr;
    padding: 8px 12px;
    gap: 6px;
  }
  .bhm-cell {
    padding: 6px 8px;
  }
  .bhm-v {
    font-size: 13px;
  }
  .sd-tabs {
    overflow-x: auto;
    white-space: nowrap;
  }
  .sd-tabs button {
    padding: 8px 10px;
    font-size: 10px;
  }
  .bh-pane {
    padding: 8px 10px;
    overflow-x: hidden;
  }
  .bh-log-row {
    grid-template-columns: 58px 48px minmax(0, 1fr);
    gap: 6px;
    padding: 6px 4px;
    font-size: 10px;
  }

  /* Live dashboard pane — single column */
  #bh-pane-dashboard {
    grid-template-columns: 1fr;
    gap: 8px;
    padding: 8px;
  }
  /* Was `min-height: auto` — combined with the desktop's
     `overflow: hidden` and `display: flex column`, this caused the
     grid track to shrink to min-content (22px = the heading line
     alone), clipping the value + sub-stats and making the cards
     visually overlap each other.
     Fix: explicit min-height generous enough for the tallest card
     (Bot Status renders an animated mini-bot ~190px tall), AND
     overflow: visible so anything still slightly bigger doesn't
     get clipped. height: auto lets grid honor the content size. */
  .bd-metric {
    min-height: 200px;
    height: auto;
    padding: 12px;
    overflow: visible;
  }
  .bd-metric-v {
    font-size: 22px;
  }
  .bd-metric-foot {
    grid-template-columns: 1fr 1fr 1fr;
    gap: 4px;
    font-size: 9px;
  }
  .bd-metric-foot > div b {
    font-size: 11px;
  }
  /* Bot Hub dashboard pane is itself a grid — force its grid columns
     down to the viewport too, otherwise min-content children push it
     wider than 375px and the radar gets clipped (~70% visible). */
  #bh-pane-dashboard {
    min-width: 0;
  }
  #bh-pane-dashboard > * {
    min-width: 0;
  }
  /* Hero scanning panel — needs enough height to fit:
       header (~40px) + 2x2 stats (~140px) + radar (620px) + footer
     Bumped to 880 so the bot scanner shows completely without
     vertical clipping of orbit chips / pulse ring / base ellipse. */
  .bd-hero-panel {
    grid-column: span 1;
    min-height: 880px;
    padding: 10px;
    min-width: 0; /* allow the column to shrink below content min-content */
    overflow: hidden; /* clip any sub-element that still tries to overflow */
  }
  .bd-hero-body {
    grid-template-columns: 1fr;
    gap: 8px;
    min-height: 700px;
    min-width: 0;
  }
  .bd-hero-body > * {
    min-width: 0;
  }
  .bd-hero-stats {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px;
    min-width: 0;
  }
  .bd-hs {
    flex: 1 1 calc(50% - 4px);
    padding-left: 8px;
    min-width: 0;
  }
  .bd-hs-v {
    font-size: 18px;
    word-break: break-word;
  }
  /* Radar must be shrinkable horizontally — its absolute children
     (orbit chips, sonar, status pills) sit relative to it, any one
     with intrinsic width could re-inflate the box.
     min-height generous (started 280 → 460 → 620) so the full
     scanner — bot core, base ellipse, pulse ring, AND orbit chips
     orbiting at radius 110 — fits without vertical clipping. */
  .bd-radar {
    min-height: 620px;
    min-width: 0;
    overflow: hidden;
  }
  .bd-bot-core {
    width: 140px;
    height: 140px;
  }
  .bd-robot-mega,
  .bd-bot-svg {
    width: 140px;
    height: 140px;
  }
  .bd-bot-halo {
    width: 170px;
    height: 170px;
    margin-left: -85px;
    margin-top: -85px;
  }
  .bd-orbit {
    --r: 110px;
  }
  .bd-pulse-ring {
    left: 50%;
    top: 75%;
  }
  .bd-base-ellipse {
    width: 220px;
    height: 50px;
  }
  .bd-radar-sym,
  .bd-chip {
    font-size: 10px;
    padding: 3px 8px;
  }
  .bd-activity-panel,
  .bd-positions-panel,
  .bd-strategy-panel,
  .bd-watchlist-panel,
  .bd-indicators-panel,
  .bd-account-strip {
    grid-column: span 1;
    grid-row: auto;
    padding: 10px;
    max-height: none;
  }
  .bd-activity-panel {
    min-height: 160px;
    max-height: 280px;
  }
  .bd-activity-list {
    max-height: 220px;
  }
  .bd-acc-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 6px;
  }
  .bd-acc-cell.wide {
    grid-column: span 2;
  }
  .bd-acc-v {
    font-size: 13px;
  }
  .bd-status-footer {
    grid-column: span 1;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 10px;
  }

  /* Tables: horizontally scroll instead of wrapping/overlapping.
     Without `white-space: nowrap` on cells, the table tried to fit
     10 columns into a 430px viewport by shrinking and wrapping
     each cell — text from adjacent columns overlapped (e.g.
     "76,51..." colliding with "$42..." in P&L).
     With nowrap on every cell, columns reach their natural width,
     the table content exceeds 100% of the container, and the
     `overflow-x: auto` produces a clean horizontal scrollbar. */
  /* Tables on mobile — undo the desktop "fake-table" layout that forced
     thead/tbody/tr to render as fixed-layout sub-tables sized to 100%
     of their container. With 10–11 columns and the parent only ~360px
     wide, that hack made every cell ~30px wide and `nowrap` content
     overflowed sideways on top of its neighbour (the screenshot shows
     "76,46…", "$56", "440.01%" all crashing into each other).
     The fix: restore native HTML table semantics (`display: table*`)
     so the browser computes column widths from natural cell content,
     then make the OUTER <table> a horizontally-scrollable block. The
     parent dock also needs `overflow: hidden` cleared so the scroll
     container isn't clipped. */
  .pos-dock {
    overflow-x: hidden;
  }
  .pos-dock > table.data-table,
  .bd-pos-table,
  .bd-watchlist-table {
    display: block;
    overflow-x: auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
    width: 100%;
    font-size: 11px;
    table-layout: auto;
  }
  /* Reset the desktop fake-table rules — thead / tbody / tr go back
     to their native display values so the browser sizes columns from
     content. Without this, .pos-dock tbody { display: block } and
     .pos-dock thead, .pos-dock tbody tr { display: table; width: 100% }
     keep forcing the broken 100%-fit layout. */
  .pos-dock thead,
  .bd-pos-table thead,
  .bd-watchlist-table thead {
    display: table-header-group !important;
    width: auto !important;
    position: static !important;
    white-space: nowrap;
  }
  .pos-dock tbody,
  .bd-pos-table tbody,
  .bd-watchlist-table tbody {
    display: table-row-group !important;
    width: auto !important;
    height: auto !important;
    overflow: visible !important;
    white-space: nowrap;
  }
  .pos-dock tr,
  .bd-pos-table tr,
  .bd-watchlist-table tr {
    display: table-row !important;
    width: auto !important;
    table-layout: auto !important;
  }
  .bd-pos-table td,
  .bd-pos-table th,
  .bd-watchlist-table td,
  .bd-watchlist-table th,
  .pos-dock .data-table td,
  .pos-dock .data-table th {
    padding: 8px 10px;
    white-space: nowrap;
  }

  /* Modals — full-screen on mobile.
     iOS Safari's `100vh` is the LARGEST viewport (when the bottom
     URL bar is collapsed), so when the bar is showing, the modal
     extends below the visible area and the footer's SAVE / BACK /
     NEXT buttons get hidden behind it. `100dvh` (dynamic vh)
     adjusts as Safari's chrome shows/hides — falls back to `100vh`
     on browsers that don't support dvh. */
  .modal {
    width: 100%;
    max-width: 100vw;
    height: 100vh;
    max-height: 100vh;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
  }
  /* Header: pad for iPhone safe-area (notch/Dynamic Island) so the
     title + ✕ aren't jammed under the status bar. The default 10px
     vertical padding made the X feel pinned to the very top corner.
     env(safe-area-inset-top) adds the device-specific inset, with a
     12px floor for non-notched browsers. The header also gets a
     min-height so the ✕ tap target is never tiny. */
  .modal-head {
    padding: max(env(safe-area-inset-top), 12px) 14px 10px 14px;
    min-height: 56px;
    gap: 10px;
  }
  /* On iPhone the head can overflow — strategy names like "GBP/USD
     RSI Reversal 7" + 5 step dots + close button push past the
     viewport width. Truncate the title with ellipsis instead of
     letting it wrap to two rows, and shrink the step dots a touch. */
  .modal-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    letter-spacing: 0.4px;
  }
  .step-dot {
    width: 16px;
  }
  /* Bigger, easier-to-hit close button — 40x40 instead of a 14px glyph
     with no padding (was below Apple's 44pt recommendation). The flex
     container in .modal-head already aligns it center-vertically. */
  .modal-x {
    font-size: 22px;
    line-height: 1;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    margin-right: -6px; /* pull flush to edge so the visual sits in the corner */
  }
  .modal-x:active {
    background: var(--bg-hover);
  }
  .modal-step {
    padding: 10px 12px;
  }
  /* Keep the 2-column grid on mobile so 7 short numeric fields
     (TF / INVESTMENT / MARGIN / LOT / MAX LOTS / TARGET / STOP)
     don't stack into a 7-row tall scroll. .full sections still span
     both columns. Tighter row gap so the page isn't stretched.
     minmax(0, 1fr) is critical here — plain `1fr` resolves to the
     intrinsic min-content width of the grid items (which can be
     wider than the container when a child has a long unbroken
     element like a sym chip-multi or a wide input), causing
     horizontal overflow. minmax(0, …) allows the column to shrink
     below content min-width and clip/wrap inside instead. */
  .form-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 8px 10px;
  }
  .form-grid input,
  .form-grid select {
    /* font-size: 16px keeps iOS from auto-zooming the page on focus
       (Safari zooms any input < 16px). Slim padding so the inputs
       don't dominate the page. min-width: 0 lets the input shrink
       to its grid cell instead of pushing it wider. */
    padding: 7px 10px;
    font-size: 16px;
    line-height: 1.2;
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
  }
  /* Same shrinkability for label/form-row wrappers and any inner
     containers that might otherwise hold the grid open. */
  .form-grid label,
  .form-grid .form-row {
    min-width: 0;
  }
  .form-grid .seg-pick,
  .form-grid .seg-hint,
  .form-grid .sym-search-wrap,
  .form-grid .chips.chip-multi {
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
  }
  .form-grid .chips.chip-multi {
    flex-wrap: wrap;
  }
  /* Pad the bottom for the iPhone home-indicator safe area —
     without this, on Face-ID iPhones the ~34px home-indicator
     bar covers the bottom of the SAVE CHANGES / BACK buttons.
     12px floor for non-notched browsers. */
  .modal-foot {
    padding: 10px 12px max(env(safe-area-inset-bottom), 12px) 12px;
    gap: 8px;
  }
  .modal-foot button {
    flex: 1 1 auto;
    padding: 12px 16px;
    font-size: 12px;
  }

  /* Auth modal — tighten the desktop's wider padding for phones so
     the form doesn't lose horizontal space inside its already-narrow
     viewport (92vw). */
  .auth-modal {
    width: 92vw;
  }
  .auth-h {
    padding: 22px 20px 14px;
  }
  .auth-logo {
    width: 140px;
    margin-bottom: 6px;
  }
  .auth-body {
    padding: 18px 20px 22px;
    gap: 12px;
  }
  .auth-field input {
    padding: 12px 14px;
    font-size: 14px;
  }
  .auth-phone-row select {
    padding: 12px 10px;
    font-size: 14px;
    max-width: 138px;
    padding-right: 24px;
  }
  .auth-submit-btn {
    padding: 14px 0;
    font-size: 13px;
  }

  /* Confirm-activation impact strip */
  .ca-impact {
    grid-template-columns: auto 1fr;
    gap: 4px 10px;
    padding: 8px;
    font-size: 10px;
  }

  /* Bot Studio */
  .bs-method-tabs {
    padding: 6px 8px;
    flex-wrap: wrap;
    gap: 3px;
  }
  .bs-method-tabs button {
    flex: 1 1 calc(33% - 2px);
    padding: 8px 6px;
    font-size: 9px;
  }
  .bs-body {
    padding: 10px;
  }
  #bs-paste-area {
    font-size: 12px;
    min-height: 220px;
  }
  .bsb-grid {
    grid-template-columns: 1fr;
    gap: 8px;
  }
  .bsb-preview {
    max-height: 160px;
  }

  /* Touch sizing */
  .shc-btn {
    padding: 8px 8px;
    font-size: 10px;
    min-height: 36px;
  }
  .shc-actions {
    gap: 4px;
  }
  .ghost-btn,
  .primary-btn,
  .kill-all-btn {
    min-height: 36px;
    padding: 8px 12px;
  }

  /* Decorative scanner bits — dim but keep */
  .bd-particle-field,
  .bd-laser-sweep {
    opacity: 0.5;
  }
}

/* Very small phones (≤380px) */
@media (max-width: 380px) {
  .bd-metric-v {
    font-size: 18px;
  }
  .bd-hs-v {
    font-size: 15px;
  }
  .bd-bot-core {
    width: 110px;
    height: 110px;
  }
  .bd-robot-mega,
  .bd-bot-svg {
    width: 110px;
    height: 110px;
  }
  .bd-orbit {
    --r: 90px;
  }
  .bs-method-tabs button {
    font-size: 8px;
    padding: 6px 4px;
  }
}

/* =================================================================
   UPGRADE MODAL — shown when a user hits a plan limit.
   Routes them to /checkout/ with the recommended plan pre-selected.
   ================================================================= */
.upgrade-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(8px);
  padding: 24px;
  animation: u-fade 0.2s ease;
}
.upgrade-overlay.show {
  display: flex;
}
@keyframes u-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.upgrade-card {
  width: 100%;
  max-width: 460px;
  background: linear-gradient(180deg, #11161e 0%, #0a0d12 100%);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-radius: 18px;
  padding: 36px 32px 28px;
  text-align: center;
  position: relative;
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.6),
    0 0 60px rgba(245, 158, 11, 0.08);
  animation: u-pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes u-pop {
  from {
    transform: scale(0.92);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}
.upgrade-x {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  color: #8a96a8;
  cursor: pointer;
  font-size: 18px;
  border-radius: 7px;
  transition:
    background 0.15s,
    color 0.15s;
}
.upgrade-x:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
}
.upgrade-emoji {
  font-size: 44px;
  margin-bottom: 14px;
}
.upgrade-h {
  color: #fff;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-bottom: 10px;
  font-family: var(--ff-ui, system-ui);
}
.upgrade-body {
  color: #8a96a8;
  font-size: 14px;
  line-height: 1.55;
  margin-bottom: 22px;
}
.upgrade-body b {
  color: #fff;
  font-weight: 600;
}
.upgrade-plan {
  background: rgba(245, 158, 11, 0.05);
  border: 1px solid rgba(245, 158, 11, 0.25);
  border-radius: 12px;
  padding: 16px 18px;
  margin-bottom: 22px;
  text-align: left;
}
.upgrade-plan-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 12px;
}
.upgrade-plan-name {
  color: #d6dee8;
  font-size: 13px;
  font-weight: 500;
}
.upgrade-plan-name b {
  color: #f59e0b;
  font-weight: 800;
  letter-spacing: 0.3px;
}
.upgrade-plan-price {
  font-size: 24px;
  font-weight: 800;
  color: #fff;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: -1px;
}
.upgrade-plan-price span {
  color: #8a96a8;
  font-size: 12px;
  font-weight: 500;
  margin-left: 2px;
}
.upgrade-features {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.upgrade-features li {
  font-size: 13px;
  color: #d6dee8;
  padding-left: 22px;
  position: relative;
}
.upgrade-features li::before {
  content: "✓";
  color: #10b981;
  font-weight: 800;
  position: absolute;
  left: 4px;
}
.upgrade-actions {
  display: flex;
  gap: 10px;
  flex-direction: column;
  margin-bottom: 14px;
}
.upgrade-cta {
  display: block;
  padding: 14px 20px;
  background: linear-gradient(135deg, #f59e0b, #ea580c);
  color: #0a0a0a;
  text-decoration: none;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.3px;
  box-shadow: 0 8px 24px rgba(245, 158, 11, 0.35);
  transition:
    transform 0.1s,
    box-shadow 0.2s;
}
.upgrade-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 32px rgba(245, 158, 11, 0.45);
}
.upgrade-cancel {
  padding: 11px 20px;
  background: transparent;
  color: #8a96a8;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s,
    border-color 0.15s;
}
.upgrade-cancel:hover {
  background: rgba(255, 255, 255, 0.04);
  color: #d6dee8;
  border-color: rgba(255, 255, 255, 0.18);
}
.upgrade-foot {
  font-size: 12px;
  color: #5b6578;
  margin: 0;
}
@media (max-width: 480px) {
  .upgrade-card {
    padding: 28px 20px 22px;
  }
  .upgrade-h {
    font-size: 19px;
  }
}

/* ===========================================================
   Upgrade modal v2 — trial-first paywall
   =========================================================== */
.upgrade-card-v2 {
  max-width: 560px;
  text-align: left;
  padding: 24px 26px 22px;
}
.upgrade-card-v2 .upgrade-x {
  top: 10px;
  right: 10px;
}

.upgrade-reason {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 12px;
  background: rgba(245, 158, 11, 0.06);
  border: 1px solid rgba(245, 158, 11, 0.18);
  border-radius: 8px;
  margin-bottom: 18px;
}
.upgrade-reason-ico {
  font-size: 18px;
  line-height: 1.2;
}
.upgrade-reason-h {
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.3px;
  margin-bottom: 2px;
}
.upgrade-reason-b {
  color: #8a96a8;
  font-size: 11px;
  line-height: 1.5;
}
.upgrade-reason-b b {
  color: #d6dee8;
  font-weight: 700;
}

.upgrade-hero {
  text-align: center;
  margin-bottom: 16px;
}
.upgrade-hero-eyebrow {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.4px;
  color: #f59e0b;
  margin-bottom: 6px;
}
.upgrade-hero-h {
  color: #fff;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin: 0 0 8px;
  line-height: 1.15;
}
.upgrade-hero-p {
  color: #8a96a8;
  font-size: 13px;
  line-height: 1.5;
  max-width: 420px;
  margin: 0 auto;
}

.upgrade-compare {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 18px;
  background: rgba(255, 255, 255, 0.015);
}
.upgrade-compare-row {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  align-items: center;
  padding: 10px 14px;
  font-size: 12px;
  color: #d6dee8;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.upgrade-compare-row:last-child {
  border-bottom: 0;
}
.upgrade-compare-head {
  background: rgba(255, 255, 255, 0.04);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.2px;
  color: #8a96a8;
  text-transform: uppercase;
  padding: 8px 14px;
}
.upgrade-compare-feat {
  color: #d6dee8;
}
.upgrade-compare-col {
  text-align: center;
  font-weight: 600;
}
.upgrade-compare-col.free {
  color: #6b7589;
}
.upgrade-compare-col.pro {
  color: #fff;
  position: relative;
}
.upgrade-compare-col.pro b {
  color: #f59e0b;
  font-weight: 800;
}
.upgrade-compare-badge {
  display: inline-block;
  margin-left: 6px;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: #0a0a0a;
  background: linear-gradient(135deg, #f59e0b, #ea580c);
  padding: 2px 5px;
  border-radius: 3px;
  vertical-align: middle;
}
.upgrade-compare-head .upgrade-compare-col.pro {
  color: #f59e0b;
}

.upgrade-card-v2 .upgrade-actions {
  margin-bottom: 14px;
}
.upgrade-card-v2 .upgrade-cta {
  font-size: 15px;
  padding: 15px 20px;
}

.upgrade-trust {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.upgrade-trust-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  color: #8a96a8;
}
.upgrade-trust-k {
  color: #6b7589;
  font-weight: 600;
  min-width: 76px;
}
.upgrade-trust-v {
  color: #d6dee8;
  font-weight: 600;
}
.upgrade-pay-icons {
  display: flex;
  gap: 6px;
  align-items: center;
}
.pay-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.upgrade-trust-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 6px;
}
.upgrade-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 700;
  color: #10b981;
  background: rgba(16, 185, 129, 0.08);
  border: 1px solid rgba(16, 185, 129, 0.2);
  padding: 4px 8px;
  border-radius: 4px;
  letter-spacing: 0.3px;
}
.upgrade-badge:nth-child(2) {
  color: #60a5fa;
  background: rgba(96, 165, 250, 0.08);
  border-color: rgba(96, 165, 250, 0.2);
}
@media (max-width: 540px) {
  .upgrade-card-v2 {
    padding: 20px 16px 18px;
  }
  .upgrade-hero-h {
    font-size: 21px;
  }
  .upgrade-compare-row {
    grid-template-columns: 1.4fr 0.8fr 0.8fr;
    padding: 8px 10px;
    font-size: 11px;
  }
}

/* ===========================================================
   First-time product tour (3-step welcome modal)
   =========================================================== */
.tour-overlay {
  position: fixed;
  inset: 0;
  z-index: 9998;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(10px);
  padding: 20px;
  animation: u-fade 0.2s ease;
}
.tour-overlay.show {
  display: flex;
}
.tour-card {
  width: 100%;
  max-width: 520px;
  background: linear-gradient(180deg, #11161e 0%, #0a0d12 100%);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-radius: 16px;
  position: relative;
  overflow: hidden;
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.6),
    0 0 60px rgba(245, 158, 11, 0.08);
  animation: u-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.tour-skip {
  position: absolute;
  top: 12px;
  right: 14px;
  background: transparent;
  border: 0;
  color: #8a96a8;
  cursor: pointer;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 6px 10px;
  border-radius: 6px;
  transition:
    background 0.15s,
    color 0.15s;
  z-index: 2;
}
.tour-skip:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
}

.tour-hero {
  height: 160px;
  background: linear-gradient(
    135deg,
    rgba(245, 158, 11, 0.12),
    rgba(234, 88, 12, 0.06)
  );
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid rgba(245, 158, 11, 0.2);
}
.tour-art {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  padding: 12px;
}
.tour-art-templates .tour-tpl {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(245, 158, 11, 0.25);
  border-radius: 8px;
  font-size: 22px;
  animation: tour-pop 0.4s ease both;
}
.tour-art-templates .tour-tpl:nth-child(1) {
  animation-delay: 0.05s;
}
.tour-art-templates .tour-tpl:nth-child(2) {
  animation-delay: 0.1s;
}
.tour-art-templates .tour-tpl:nth-child(3) {
  animation-delay: 0.15s;
}
.tour-art-templates .tour-tpl:nth-child(4) {
  animation-delay: 0.2s;
}
.tour-art-templates .tour-tpl:nth-child(5) {
  animation-delay: 0.25s;
}
.tour-art-templates .tour-tpl:nth-child(6) {
  animation-delay: 0.3s;
}
@keyframes tour-pop {
  from {
    opacity: 0;
    transform: scale(0.6) translateY(8px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.tour-art-deploy {
  width: 100%;
  padding: 0 24px;
}
.tour-bot-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
  padding: 12px 14px;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-radius: 8px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 12px;
  color: #d6dee8;
}
.tour-bot-row > span:first-child {
  flex: 1;
  font-weight: 700;
  letter-spacing: 0.3px;
}
.tour-status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #10b981;
  box-shadow: 0 0 8px #10b981;
  animation: tour-pulse 1.6s ease-in-out infinite;
}
@keyframes tour-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.6;
    transform: scale(1.2);
  }
}
.tour-deploy-btn {
  background: linear-gradient(135deg, #f59e0b, #ea580c);
  color: #0a0a0a;
  font-weight: 800;
  letter-spacing: 0.4px;
  padding: 6px 12px;
  border-radius: 5px;
  font-size: 11px;
  animation: tour-deploy-bounce 1.4s ease-in-out infinite;
}
@keyframes tour-deploy-bounce {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-3px);
  }
}

/* Step 4 — personas grid. 2x2 mini-cards with icon + name, animated
   in with a stagger (uses the same `tour-pop` keyframe as templates).
   Uses purple accents instead of orange to telegraph "this is the AI
   layer" — matches the AI Co-Pilot section in Bot Studio. */
.tour-art-personas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 0 24px;
  width: 100%;
  max-width: 380px;
  margin: 0 auto;
}
.tour-persona {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: rgba(139, 92, 246, 0.08);
  border: 1px solid rgba(168, 85, 247, 0.3);
  border-radius: 6px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  animation: tour-pop 0.4s ease both;
}
.tour-persona:nth-child(1) {
  animation-delay: 0.05s;
}
.tour-persona:nth-child(2) {
  animation-delay: 0.15s;
}
.tour-persona:nth-child(3) {
  animation-delay: 0.25s;
}
.tour-persona:nth-child(4) {
  animation-delay: 0.35s;
}
.tour-persona-ico {
  font-size: 18px;
}
.tour-persona-name {
  font-size: 11px;
  font-weight: 700;
  color: #ddd6fe;
  letter-spacing: 0.3px;
}

/* Step 5 — Explain Trade + Improve Bot mock cards. Uses tour-slide-in
   stagger from the signals art. Each card mocks the actual UI: title
   row + 1-line preview of what AI would say. */
.tour-art-aitools {
  flex-direction: column;
  align-items: stretch;
  padding: 0 24px;
  gap: 8px;
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
}
.tour-aitool {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(168, 85, 247, 0.3);
  border-left: 3px solid #a855f7;
  border-radius: 5px;
  animation: tour-slide-in 0.4s ease both;
}
.tour-aitool:nth-child(1) {
  animation-delay: 0.1s;
}
.tour-aitool:nth-child(2) {
  animation-delay: 0.3s;
}
.tour-aitool-ico {
  font-size: 22px;
}
.tour-aitool-text {
  flex: 1;
  min-width: 0;
}
.tour-aitool-h {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #ddd6fe;
  margin-bottom: 2px;
}
.tour-aitool-p {
  font-size: 11px;
  color: #d6dee8;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tour-art-signals {
  flex-direction: column;
  align-items: stretch;
  padding: 0 28px;
  gap: 6px;
  width: 100%;
}
.tour-sig {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
  padding: 7px 10px;
  background: rgba(0, 0, 0, 0.4);
  border-left: 3px solid #888;
  border-radius: 3px;
  animation: tour-slide-in 0.4s ease both;
}
.tour-sig.up {
  color: #10b981;
  border-left-color: #10b981;
}
.tour-sig.down {
  color: #ef4444;
  border-left-color: #ef4444;
}
.tour-sig:nth-child(1) {
  animation-delay: 0.1s;
}
.tour-sig:nth-child(2) {
  animation-delay: 0.3s;
}
.tour-sig:nth-child(3) {
  animation-delay: 0.5s;
}
@keyframes tour-slide-in {
  from {
    opacity: 0;
    transform: translateX(-12px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.tour-body {
  padding: 22px 26px 8px;
  text-align: center;
}
.tour-eyebrow {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.4px;
  color: #f59e0b;
  margin-bottom: 10px;
}
.tour-h {
  color: #fff;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.3px;
  margin: 0 0 12px;
  line-height: 1.2;
}
.tour-h-ico {
  font-size: 22px;
  vertical-align: middle;
  margin-right: 4px;
}
.tour-p {
  color: #8a96a8;
  font-size: 13px;
  line-height: 1.6;
  margin: 0;
  max-width: 420px;
  margin-left: auto;
  margin-right: auto;
}
.tour-p b {
  color: #f59e0b;
  font-weight: 700;
}

.tour-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 26px 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  margin-top: 14px;
}
.tour-dots {
  display: flex;
  gap: 6px;
}
.tour-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  transition:
    background 0.2s,
    width 0.2s;
}
.tour-dot.active {
  background: #f59e0b;
  width: 22px;
  border-radius: 4px;
}
.tour-actions {
  display: flex;
  gap: 8px;
}
.tour-back,
.tour-next {
  border: 0;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.3px;
  padding: 10px 16px;
  border-radius: 8px;
  transition:
    transform 0.1s,
    box-shadow 0.2s,
    background 0.15s;
}
.tour-back {
  background: transparent;
  color: #8a96a8;
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.tour-back:hover {
  color: #d6dee8;
  border-color: rgba(255, 255, 255, 0.22);
}
.tour-next {
  background: linear-gradient(135deg, #f59e0b, #ea580c);
  color: #0a0a0a;
  box-shadow: 0 6px 16px rgba(245, 158, 11, 0.3);
}
.tour-next:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(245, 158, 11, 0.4);
}

@media (max-width: 540px) {
  .tour-card {
    max-width: 100%;
  }
  .tour-hero {
    height: 130px;
  }
  .tour-body {
    padding: 18px 18px 4px;
  }
  .tour-h {
    font-size: 18px;
  }
  .tour-foot {
    padding: 14px 18px 18px;
    flex-direction: column;
    gap: 14px;
  }
}

/* ============= BACKTEST RESULTS MODAL =============
   Pops after clicking 📊 BACKTEST in Bot Studio. Shows the worker's
   one-shot fast-forward sim: equity curve, stat grid, last 20 trades,
   honest disclaimers about sample size / multi-symbol.
   Reuses .modal-overlay / .modal / .modal-wide base. */
.bt-body {
  padding: 18px 22px;
  overflow-y: auto;
}
.bt-status {
  font-size: 11px;
  color: var(--tx-3);
  margin-bottom: 10px;
  padding: 8px 12px;
  background: var(--bg-elevated);
  border-radius: 4px;
  border: 1px solid var(--bd-2);
}
.bt-spin {
  display: flex;
  gap: 8px;
  justify-content: center;
  padding: 32px 0;
  align-items: center;
}
.bt-spin.hidden {
  display: none;
}
.bt-spin-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--orange);
  opacity: 0.4;
  animation: btSpinDot 1.2s ease-in-out infinite;
}
.bt-spin-dot:nth-child(2) {
  animation-delay: 0.15s;
}
.bt-spin-dot:nth-child(3) {
  animation-delay: 0.3s;
}
@keyframes btSpinDot {
  0%,
  80%,
  100% {
    opacity: 0.4;
    transform: scale(0.85);
  }
  40% {
    opacity: 1;
    transform: scale(1.15);
  }
}
.bt-err {
  padding: 12px 16px;
  background: rgba(220, 80, 80, 0.1);
  color: var(--down);
  border: 1px solid rgba(220, 80, 80, 0.3);
  border-radius: 4px;
  font-size: 12px;
}
.bt-result.hidden,
.bt-err.hidden,
.bt-warnings.hidden {
  display: none;
}

.bt-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 16px;
}
.bt-stat {
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  padding: 10px 12px;
  border-radius: 4px;
}
.bt-stat-k {
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 700;
  margin-bottom: 4px;
}
.bt-stat-v {
  font-size: 16px;
  font-weight: 700;
  font-family: "JetBrains Mono", monospace;
}
.bt-stat-v.up {
  color: var(--up);
}
.bt-stat-v.down {
  color: var(--down);
}

.bt-chart-wrap {
  margin-bottom: 16px;
}
.bt-chart-h {
  font-size: 9px;
  color: var(--orange);
  letter-spacing: 0.6px;
  font-weight: 800;
  margin-bottom: 6px;
}
#bt-equity-canvas {
  width: 100%;
  height: 180px;
  display: block;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
}

.bt-warnings {
  margin-bottom: 14px;
  padding: 8px 12px;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-radius: 4px;
}
.bt-warn-line {
  font-size: 11px;
  color: var(--warn);
  padding: 2px 0;
}

.bt-trades-wrap {
  margin-bottom: 8px;
}
.bt-trades-scroll {
  max-height: 240px;
  overflow-y: auto;
  border: 1px solid var(--bd-2);
  border-radius: 4px;
}
table.bt-trades {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
}
table.bt-trades thead {
  position: sticky;
  top: 0;
  background: var(--bg-elevated);
  z-index: 1;
}
table.bt-trades th {
  text-align: left;
  padding: 8px 10px;
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.5px;
  font-weight: 800;
  border-bottom: 1px solid var(--bd-2);
}
table.bt-trades td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--bd-1);
}
table.bt-trades tr:hover td {
  background: var(--bg-hover);
}
.bt-empty {
  text-align: center;
  color: var(--tx-3);
  padding: 20px !important;
  font-style: italic;
}
.bt-side {
  display: inline-block;
  padding: 2px 8px;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.5px;
  border-radius: 2px;
}
.bt-side.buy {
  background: rgba(34, 197, 94, 0.15);
  color: var(--up);
}
.bt-side.sell {
  background: rgba(239, 68, 68, 0.15);
  color: var(--down);
}
table.bt-trades td.tp {
  color: var(--up);
  font-weight: 700;
}
table.bt-trades td.sl {
  color: var(--down);
  font-weight: 700;
}
table.bt-trades td.up {
  color: var(--up);
}
table.bt-trades td.down {
  color: var(--down);
}
table.bt-trades td.dim {
  color: var(--text-dim);
}

/* Per-symbol breakdown table (Sprint 1.5 multi-symbol) — same look-and-feel
   as bt-trades but a tighter max height since N is usually small. */
.bt-breakdown-wrap {
  margin-bottom: 8px;
}
.bt-breakdown-wrap.hidden {
  display: none;
}

/* Provenance badge inside the symbol cell — DEEP = full historical fetch
   succeeded, LIVE = fell back to in-memory live-feed buffer. */
.bt-prov {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
  margin-left: 6px;
  vertical-align: middle;
  letter-spacing: 0.5px;
}
.bt-prov.deep {
  background: rgba(56, 189, 248, 0.18);
  color: #38bdf8;
}
.bt-prov.live {
  background: rgba(234, 179, 8, 0.18);
  color: #eab308;
}

th.hidden {
  display: none;
}

@media (max-width: 720px) {
  .bt-stats {
    grid-template-columns: repeat(2, 1fr);
  }
  #bt-equity-canvas {
    height: 140px;
  }
}

/* =====================================================================
   FEATURE FLAG — HIDE STRATEGIES UI (Option A, 2026-05-04)
   ---------------------------------------------------------------------
   The product is being refocused on automated bots. The legacy
   "strategies" surface (paste-modal Pine/Python/MQL/DSL parsing,
   strategy hero grid, F7 modal, etc.) is being hidden from the UI but
   left fully intact in app.js + Supabase so the existing 16 strategies
   keep ticking and nothing destructive happens. A future migration
   (Option B) can offer to convert/kill them; full code+data removal
   (Option C) would come after that.

   To revert: delete this block. All hidden surfaces become visible
   again, all behaviour is preserved.

   What's hidden:
     - Top-nav STRATEGIES tab (data-k="F7")
     - Mobile-nav Strategies item (data-ls="strategies")
     - Dashboard hero "STRATEGIES" section (#strategies-section)
     - Dashboard "+ NEW STRATEGY" button (#new-strat-btn)
     - F7 STRATEGIES modal (#strategies-modal)
     - Modal "+ NEW STRATEGY" buttons (#sm-new, #om-new-strat)
     - Dashboard header RUNNING / UNCONFIGURED pills (.dh-stat) — these
       count strategies, not bots, so they read 0/0 once strategies are
       hidden. The bots dock has its own counts.
   What stays visible:
     - All bot UI (Bot Hub, bot cards, Bot Studio modal, etc.)
     - The cmdk palette can still find strategies if a user types one;
       that's fine — the data still exists and is query-able.
   ===================================================================== */
.tnav-tab[data-k="F7"],
.mnav-item[data-ls="strategies"],
#strategies-section,
#new-strat-btn,
#strategies-modal,
#sm-new,
#om-new-strat,
.dash-header .dh-stats .dh-stat {
  display: none !important;
}

/* Reclaim the empty row left behind by the hidden strategies dock.
   Original template (line ~270) is `auto auto 1fr 1fr` — one 1fr row
   for strategies, one for bots. With strategies hidden, the bots dock
   only fills the first 1fr and the second 1fr renders as a giant
   empty gray void below the bot grid. Drop that row so bots fill the
   full remaining viewport. Reverts cleanly when this whole block is
   deleted. */
.grid.grid-v2 .col-main {
  grid-template-rows: auto auto 1fr !important;
}

/* Escape hatch: a power-user cmdk search on a strategy name still routes
   into the strategy-detail overlay — leave that path alive. The overlay
   starts with .hidden in HTML; openStrategyDetail() removes it.        */

/* ---------------------------------------------------------------------
   Hide the GIT IMPORT tab in Bot Studio.

   Why: most users land on Bot Studio with a strategy idea, not a git
   repo full of bot files. The CODE PASTE / MANUAL BUILDER / AI CONVERT
   trio covers ~all real authoring paths. GIT IMPORT was useful while
   we were dogfooding from a private bot repo, but in the user-facing
   flow it adds a "what do I put here?" friction tab that distracts
   from the obvious starting point (paste or build).

   Same Option-A discipline as the strategies hide above: the tab
   button + its pane are hidden visually; bsGitFetch / parseGitUrl /
   the entire git import code path stays intact. Nothing auto-routes
   to 'git' (BS_METHOD defaults to 'paste'; edit-existing maps to
   'builder' or 'paste' based on bot.kind), so hiding the tab is
   sufficient — no JS changes needed.

   To revert: delete the two selectors below. The tab returns. */
/* Hide GIT IMPORT, MANUAL BUILDER, and AI CONVERT tabs + panes.
   Bot Studio is collapsed into a single CODE PASTE flow:
   - Pine / Python / MQL / English / JS all paste into the same
     textarea
   - The inline detect-and-convert banner offers one-click conversion
     for non-JS sources
   - Plain-English descriptions go through the same path
   - Manual no-code form removed (didn't earn its tab — three of the
     three other paths reach JS faster)
   To revert any tab: delete its selector below. */
.bs-method-tabs button[data-bs-method="git"],
.bs-pane[data-bs-pane="git"],
.bs-method-tabs button[data-bs-method="builder"],
.bs-pane[data-bs-pane="builder"],
.bs-method-tabs button[data-bs-method="convert"],
.bs-pane[data-bs-pane="convert"] {
  display: none !important;
}
/* With only CODE PASTE remaining, the tab strip is a one-button row
   that just adds visual noise. Hide the whole nav. */
.bs-method-tabs {
  display: none !important;
}

/* =====================================================================
   AI VISIBILITY FEATURES — added with the AI Co-Pilot rollout.
   =====================================================================
   What's in this block:
     - Bot card chips: saves counter, persona presence dot, hire-CTA
     - Closed-trade verdict pill (well-timed / marginal / poor)
     - Hire Co-Pilot modal + FOMO replay banner
     - Pre-deployment review modal
     - Portfolio-level AI watchdog banner
     - Daily session brief modal

   Style guide:
     - Pull colors from CSS vars (--up, --down, --warn, --teal, --purple).
     - Compact rails (bot list, watchdog) use 11px; modals can go to 13px.
     - All overlays share the same backdrop fade for visual consistency.
   ===================================================================== */

/* ---------- 1) Bot card: saves chip ----------------------------------
   .bh-card is `display: grid` with columns "8px 195px" (col 1 = the
   status dot, col 2 = body). Every existing card child explicitly sets
   `grid-column: 2`. Without that, our chip falls into col 1 (8px) and
   gets crushed to 16px wide. */
.bh-card-saves {
  display: inline-flex;
  grid-column: 2;
  width: max-content;
  max-width: 100%;
  justify-self: start;
  align-items: center;
  gap: 4px;
  padding: 2px 6px 2px 5px;
  border-radius: 3px;
  background: rgba(31, 203, 107, 0.1);
  border: 1px solid rgba(31, 203, 107, 0.32);
  color: var(--up);
  font: 600 10px/1.2 var(--ff-mn);
  white-space: nowrap;
  cursor: help;
}
.bh-card-saves-ico {
  font-size: 10px;
  line-height: 1;
}
.bh-card-saves-n {
  font-variant-numeric: tabular-nums;
}
.bh-card-saves-$ {
  color: var(--up);
  opacity: 0.9;
}
.bh-card-saves.pending {
  background: rgba(168, 177, 191, 0.06);
  border-color: rgba(168, 177, 191, 0.22);
  color: var(--tx-3);
}
.bh-card-saves.pending .bh-card-saves-$ {
  color: var(--tx-3);
}

/* ---------- 4) Persona presence dot --------------------------------- */
.bh-card-persona-presence-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin-right: 4px;
  vertical-align: middle;
  background: var(--tx-4);
  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
  transition:
    background-color 220ms ease,
    box-shadow 220ms ease;
}
.bh-card-persona.presence-thinking .bh-card-persona-presence-dot {
  background: var(--info);
  box-shadow: 0 0 6px rgba(24, 191, 217, 0.55);
  animation: bh-presence-pulse 1.1s ease-in-out infinite;
}
.bh-card-persona.presence-veto .bh-card-persona-presence-dot,
.bh-card-persona.presence-gate .bh-card-persona-presence-dot {
  background: var(--down);
  box-shadow: 0 0 6px rgba(242, 62, 85, 0.55);
}
.bh-card-persona.presence-approve .bh-card-persona-presence-dot {
  background: var(--up);
  box-shadow: 0 0 6px rgba(31, 203, 107, 0.55);
}
.bh-card-persona.presence-size_down .bh-card-persona-presence-dot {
  background: var(--warn);
  box-shadow: 0 0 6px rgba(242, 163, 65, 0.55);
}
@keyframes bh-presence-pulse {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 1;
  }
}

/* ---------- 10) Hire-Co-Pilot CTA on persona-less cards --------------
   Important: the parent .bh-card is `display: grid`, which sizes children
   to their grid cell rather than to content. We use `width: max-content`
   so the chip is exactly as wide as its label, and `justify-self: start`
   (grid equivalent of align-self) so it doesn't stretch across the cell.
   nowrap on every layer keeps the label on one line — without it the
   narrow rail wrapped "Hire Co-Pilot" word-by-word, stacking vertically.
*/
.bh-card-copilot-cta {
  display: inline-flex;
  grid-column: 2;
  width: max-content;
  max-width: 100%;
  justify-self: start;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  border-radius: 3px;
  background: rgba(167, 139, 250, 0.1);
  border: 1px solid rgba(167, 139, 250, 0.4);
  color: var(--purple);
  font: 600 10px/1.2 var(--ff-ui);
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 120ms ease,
    border-color 120ms ease;
}
.bh-card-copilot-cta:hover {
  background: rgba(167, 139, 250, 0.18);
  border-color: rgba(167, 139, 250, 0.65);
}
.bh-card-copilot-ico {
  font-size: 10px;
  line-height: 1;
  flex-shrink: 0;
}
.bh-card-copilot-text {
  letter-spacing: 0.2px;
  white-space: nowrap;
}

/* ---------- 3) Closed-trade verdict pill ----------------------------- */
.trade-verdict-pill {
  display: inline-block;
  padding: 1px 5px;
  border-radius: 2px;
  font: 700 9px/1.2 var(--ff-mn);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  vertical-align: middle;
  border: 1px solid transparent;
}
.trade-verdict-pill.verdict-well_timed {
  background: rgba(31, 203, 107, 0.12);
  color: var(--up);
  border-color: rgba(31, 203, 107, 0.4);
}
.trade-verdict-pill.verdict-marginal {
  background: rgba(242, 163, 65, 0.12);
  color: var(--warn);
  border-color: rgba(242, 163, 65, 0.4);
}
.trade-verdict-pill.verdict-poor {
  background: rgba(242, 62, 85, 0.12);
  color: var(--down);
  border-color: rgba(242, 62, 85, 0.4);
}
.trade-verdict-pill.verdict-open,
.trade-verdict-pill.verdict-unclear {
  background: rgba(168, 177, 191, 0.1);
  color: var(--tx-3);
  border-color: rgba(168, 177, 191, 0.3);
}

/* ---------- 10) Hire Co-Pilot modal --------------------------------- */
.hire-cp-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 7, 10, 0.78);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: ai-overlay-in 140ms ease-out;
}
@keyframes ai-overlay-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.hire-cp-modal {
  position: relative;
  width: 720px;
  max-width: 92vw;
  max-height: 86vh;
  overflow: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-radius: 6px;
  padding: 22px 22px 18px;
  box-shadow:
    0 20px 60px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(167, 139, 250, 0.1);
}
.hire-cp-x {
  position: absolute;
  top: 8px;
  right: 10px;
  width: 26px;
  height: 26px;
  background: transparent;
  border: none;
  color: var(--tx-3);
  font-size: 18px;
  border-radius: 3px;
  cursor: pointer;
}
.hire-cp-x:hover {
  background: var(--bg-hover);
  color: var(--tx-1);
}
.hire-cp-title {
  font: 700 16px/1.3 var(--ff-ui);
  color: var(--tx-1);
  margin: 0 24px 6px 0;
}
.hire-cp-title-spark {
  color: var(--purple);
  margin-right: 4px;
}
.hire-cp-sub {
  font: 400 12px/1.55 var(--ff-ui);
  color: var(--tx-2);
  margin: 0 0 14px 0;
}
.hire-cp-sub code {
  font: 500 11px/1 var(--ff-mn);
  background: var(--bg-row);
  padding: 1px 4px;
  border-radius: 2px;
  color: var(--tx-1);
}
.hire-cp-fomo {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(242, 62, 85, 0.06);
  border: 1px dashed rgba(242, 62, 85, 0.4);
  border-radius: 4px;
  padding: 10px 12px;
  margin: 0 0 14px 0;
}
.hire-cp-fomo-ico {
  font-size: 18px;
  line-height: 1;
}
.hire-cp-fomo-text {
  flex: 1;
  font: 400 12px/1.5 var(--ff-ui);
  color: var(--tx-1);
}
.hire-cp-fomo-$ {
  color: var(--up);
  font-variant-numeric: tabular-nums;
}
.hire-cp-fomo-tag {
  font: 600 9px/1 var(--ff-mn);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--tx-3);
  padding: 3px 5px;
  background: var(--bg-row);
  border-radius: 2px;
}
.hire-cp-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 14px;
}
.hire-cp-card {
  position: relative;
  text-align: left;
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 4px;
  padding: 12px 12px 11px;
  cursor: pointer;
  transition:
    background-color 120ms ease,
    border-color 120ms ease,
    transform 60ms ease;
}
.hire-cp-card:hover {
  background: var(--bg-row);
  border-color: var(--bd-3);
}
.hire-cp-card:active {
  transform: translateY(1px);
}
.hire-cp-card.recommended {
  border-color: rgba(167, 139, 250, 0.55);
  box-shadow: inset 0 0 0 1px rgba(167, 139, 250, 0.18);
}
.hire-cp-rec-badge {
  position: absolute;
  top: -8px;
  left: 10px;
  background: var(--purple);
  color: #08060f;
  padding: 2px 6px;
  border-radius: 2px;
  font: 700 8.5px/1.2 var(--ff-mn);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.hire-cp-h {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}
.hire-cp-ico {
  font-size: 14px;
}
.hire-cp-name {
  font: 700 12px/1.2 var(--ff-ui);
  color: var(--tx-1);
}
.hire-cp-desc {
  font: 400 11px/1.5 var(--ff-ui);
  color: var(--tx-2);
}
.hire-cp-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 4px;
}
.hire-cp-cancel {
  background: transparent;
  border: 1px solid var(--bd-3);
  color: var(--tx-2);
  padding: 6px 12px;
  border-radius: 3px;
  font: 600 11px/1 var(--ff-ui);
}
.hire-cp-cancel:hover {
  background: var(--bg-hover);
  color: var(--tx-1);
}
.hire-cp-hint {
  font: 400 10.5px/1.3 var(--ff-ui);
  color: var(--tx-3);
}

/* ---------- 9) Pre-deployment review modal -------------------------- */
.pdr-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 7, 10, 0.78);
  z-index: 1001;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: ai-overlay-in 140ms ease-out;
}
.pdr-modal {
  position: relative;
  width: 640px;
  max-width: 92vw;
  max-height: 86vh;
  overflow: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-radius: 6px;
  padding: 20px 20px 16px;
  box-shadow:
    0 20px 60px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(58, 130, 246, 0.1);
}
.pdr-x {
  position: absolute;
  top: 8px;
  right: 10px;
  width: 26px;
  height: 26px;
  background: transparent;
  border: none;
  color: var(--tx-3);
  font-size: 18px;
  border-radius: 3px;
  cursor: pointer;
}
.pdr-x:hover {
  background: var(--bg-hover);
  color: var(--tx-1);
}
.pdr-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font: 700 15px/1.3 var(--ff-ui);
  color: var(--tx-1);
  margin: 0 26px 8px 0;
}
.pdr-title-ico {
  font-size: 16px;
}
.pdr-title-bot {
  margin-left: auto;
  font: 600 11px/1 var(--ff-mn);
  color: var(--tx-3);
  background: var(--bg-row);
  padding: 3px 7px;
  border-radius: 2px;
}
.pdr-headline {
  font: 600 12px/1.4 var(--ff-ui);
  padding: 8px 10px;
  border-radius: 3px;
  margin: 0 0 12px 0;
}
.pdr-headline-block {
  background: rgba(242, 62, 85, 0.1);
  border: 1px solid rgba(242, 62, 85, 0.35);
  color: var(--down);
}
.pdr-headline-warn {
  background: rgba(242, 163, 65, 0.1);
  border: 1px solid rgba(242, 163, 65, 0.35);
  color: var(--warn);
}
.pdr-headline-ok {
  background: rgba(168, 177, 191, 0.06);
  border: 1px solid rgba(168, 177, 191, 0.22);
  color: var(--tx-2);
}
.pdr-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}
.pdr-row {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-left-width: 3px;
  border-radius: 3px;
  padding: 9px 11px;
}
.pdr-sev-error {
  border-left-color: var(--down);
}
.pdr-sev-warn {
  border-left-color: var(--warn);
}
.pdr-sev-info {
  border-left-color: var(--info);
}
.pdr-row-h {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 3px;
}
.pdr-row-ico {
  font-size: 11px;
}
.pdr-row-sev {
  font: 700 9px/1 var(--ff-mn);
  letter-spacing: 0.5px;
  padding: 2px 4px;
  border-radius: 2px;
  text-transform: uppercase;
}
.pdr-sev-error .pdr-row-sev {
  color: var(--down);
  background: rgba(242, 62, 85, 0.12);
}
.pdr-sev-warn .pdr-row-sev {
  color: var(--warn);
  background: rgba(242, 163, 65, 0.12);
}
.pdr-sev-info .pdr-row-sev {
  color: var(--info);
  background: rgba(24, 191, 217, 0.12);
}
.pdr-row-title {
  font: 600 12px/1.3 var(--ff-ui);
  color: var(--tx-1);
}
.pdr-row-detail {
  font: 400 11px/1.55 var(--ff-ui);
  color: var(--tx-2);
  margin: 2px 0 4px;
}
.pdr-row-fix {
  font: 400 11px/1.45 var(--ff-ui);
  color: var(--tx-2);
}
.pdr-row-fix-k {
  font: 700 9px/1 var(--ff-mn);
  letter-spacing: 0.4px;
  color: var(--teal);
  margin-right: 4px;
}
.pdr-foot {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: flex-end;
}
.pdr-fix {
  background: var(--bg-row);
  border: 1px solid var(--bd-3);
  color: var(--tx-1);
  padding: 7px 14px;
  border-radius: 3px;
  font: 600 11px/1 var(--ff-ui);
}
.pdr-fix:hover {
  background: var(--bg-hover);
}
.pdr-proceed {
  background: var(--up);
  border: 1px solid var(--up);
  color: #061a0e;
  padding: 7px 14px;
  border-radius: 3px;
  font: 700 11px/1 var(--ff-ui);
}
.pdr-proceed:hover {
  filter: brightness(1.08);
}
.pdr-proceed-risky {
  background: rgba(242, 62, 85, 0.18);
  border-color: var(--down);
  color: var(--down);
}
.pdr-proceed-risky:hover {
  background: rgba(242, 62, 85, 0.28);
}
.pdr-foot-hint {
  text-align: right;
  font: 400 10px/1.3 var(--ff-ui);
  color: var(--tx-3);
  margin-top: 6px;
}

/* ---------- 8) Portfolio-level AI watchdog banner -------------------- */
.ai-watchdog-banner {
  background: rgba(24, 191, 217, 0.06);
  border: 1px solid rgba(24, 191, 217, 0.3);
  border-radius: 3px;
  padding: 6px 8px;
  margin: 0 0 6px 0;
  font: 400 11px/1.4 var(--ff-ui);
  color: var(--tx-1);
}
.ai-watchdog-banner.hidden {
  display: none;
}
.ai-wd-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 0;
}
.ai-wd-row + .ai-wd-row {
  border-top: 1px dashed var(--bd-2);
  padding-top: 5px;
  margin-top: 3px;
}
.ai-wd-ico {
  font-size: 12px;
  flex-shrink: 0;
}
.ai-wd-text {
  flex: 1;
  min-width: 0;
}
.ai-wd-more {
  background: rgba(24, 191, 217, 0.14);
  border: 1px solid rgba(24, 191, 217, 0.35);
  color: var(--info);
  padding: 1px 6px;
  border-radius: 2px;
  font: 600 9.5px/1.4 var(--ff-mn);
  letter-spacing: 0.3px;
}
.ai-wd-more:hover {
  background: rgba(24, 191, 217, 0.22);
}
.ai-wd-x {
  background: transparent;
  border: none;
  color: var(--tx-3);
  padding: 0 4px;
  font-size: 12px;
  line-height: 1;
  border-radius: 2px;
}
.ai-wd-x:hover {
  background: var(--bg-hover);
  color: var(--tx-1);
}

/* ---------- 7) Daily session brief modal ----------------------------- */
.session-brief-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 7, 10, 0.78);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: ai-overlay-in 140ms ease-out;
}
.session-brief-modal {
  position: relative;
  width: 700px;
  max-width: 92vw;
  max-height: 86vh;
  overflow: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--bd-3);
  border-radius: 6px;
  padding: 22px 22px 18px;
  box-shadow:
    0 20px 60px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(31, 203, 107, 0.1);
}
.session-brief-x {
  position: absolute;
  top: 8px;
  right: 10px;
  width: 26px;
  height: 26px;
  background: transparent;
  border: none;
  color: var(--tx-3);
  font-size: 18px;
  border-radius: 3px;
}
.session-brief-x:hover {
  background: var(--bg-hover);
  color: var(--tx-1);
}
.session-brief-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font: 700 16px/1.3 var(--ff-ui);
  color: var(--tx-1);
  margin: 0 26px 12px 0;
}
.session-brief-date {
  margin-left: auto;
  font: 600 11px/1 var(--ff-mn);
  color: var(--tx-3);
  background: var(--bg-row);
  padding: 3px 7px;
  border-radius: 2px;
}
.brief-headline {
  background: rgba(31, 203, 107, 0.08);
  border: 1px solid rgba(31, 203, 107, 0.32);
  border-radius: 4px;
  padding: 12px 14px;
  margin: 0 0 14px 0;
  text-align: center;
}
.brief-headline-h {
  display: block;
  font: 800 26px/1.2 var(--ff-mn);
  color: var(--up);
  font-variant-numeric: tabular-nums;
}
.brief-headline-sub {
  display: block;
  font: 400 11px/1.4 var(--ff-ui);
  color: var(--tx-2);
  margin-top: 3px;
}
.brief-headline.brief-headline-quiet {
  background: rgba(168, 177, 191, 0.06);
  border-color: rgba(168, 177, 191, 0.22);
}
.brief-headline-quiet .brief-headline-h {
  color: var(--tx-2);
  font-size: 16px;
}
.brief-stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  margin: 0 0 14px 0;
}
.brief-stat {
  background: var(--bg-panel);
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  padding: 8px 6px;
  text-align: center;
}
.brief-stat-k {
  font: 700 9px/1 var(--ff-mn);
  letter-spacing: 0.5px;
  color: var(--tx-3);
  text-transform: uppercase;
  margin-bottom: 4px;
}
.brief-stat-v {
  font: 700 14px/1.2 var(--ff-mn);
  color: var(--tx-1);
  font-variant-numeric: tabular-nums;
}
.brief-section-h {
  font: 700 10px/1.4 var(--ff-mn);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--tx-3);
  margin: 6px 0 6px 0;
}
.brief-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--bd-2);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 14px;
}
.brief-row {
  display: grid;
  grid-template-columns: 52px 22px 1fr 90px 1.6fr auto;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  font: 400 11px/1.3 var(--ff-ui);
  background: var(--bg-panel);
}
.brief-row + .brief-row {
  border-top: 1px solid var(--bd-1);
}
.brief-row-time {
  font: 500 10px/1 var(--ff-mn);
  color: var(--tx-3);
}
.brief-row-ico {
  font-size: 13px;
  text-align: center;
}
.brief-row-bot {
  color: var(--tx-1);
  font-weight: 600;
}
.brief-row-verb {
  font: 700 9px/1 var(--ff-mn);
  letter-spacing: 0.5px;
  padding: 2px 5px;
  border-radius: 2px;
  text-transform: uppercase;
  text-align: center;
  background: var(--bg-row);
  color: var(--tx-2);
}
.brief-row-verb.verb-veto {
  color: var(--down);
  background: rgba(242, 62, 85, 0.12);
}
.brief-row-verb.verb-size_down {
  color: var(--warn);
  background: rgba(242, 163, 65, 0.12);
}
.brief-row-verb.verb-gate {
  color: var(--down);
  background: rgba(242, 62, 85, 0.1);
}
.brief-row-verb.verb-approve {
  color: var(--up);
  background: rgba(31, 203, 107, 0.12);
}
.brief-row-verb.verb-explain {
  color: var(--info);
  background: rgba(24, 191, 217, 0.12);
}
.brief-row-verb.verb-hire {
  color: var(--purple);
  background: rgba(167, 139, 250, 0.12);
}
.brief-row-reason {
  color: var(--tx-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.brief-row-$ {
  font: 700 11px/1 var(--ff-mn);
  color: var(--up);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.brief-empty {
  text-align: center;
  padding: 24px 16px;
  color: var(--tx-3);
  font: 400 11.5px/1.5 var(--ff-ui);
  background: var(--bg-panel);
}
.brief-foot {
  display: flex;
  justify-content: flex-end;
}
.brief-dismiss {
  background: var(--up);
  border: 1px solid var(--up);
  color: #061a0e;
  padding: 7px 16px;
  border-radius: 3px;
  font: 700 11px/1 var(--ff-ui);
}
.brief-dismiss:hover {
  filter: brightness(1.08);
}

/* =====================================================================
   ACTIVATION MODAL — beginner safety surfaces
   ---------------------------------------------------------------------
   - .ca-paper-pill: top banner that says "PAPER TRADING" so a beginner
     never thinks the simulated $5k is real money. First thing inside
     the modal body, can't be missed.
   - .ca-help / .ca-help-sm: small "?" buttons inline with form labels
     (.ca-help) and impact-strip rows (.ca-help-sm). Click toggles a
     floating .ca-tip-pop with a 1-sentence translation of the jargon.
   - .ca-lev-warn: appears when leverage >= 10×. Severity ramps from
     "med" (yellow) at 10-14× to "high" (red) at 15+×.
   - .ca-tip-pop: absolute-positioned tooltip body. JS positions it
     above the icon (or below if no room). Single tip at a time.
   ===================================================================== */
.ca-paper-pill {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-radius: 4px;
  font: 600 11px/1.4 var(--ff-ui);
  color: color-mix(in srgb, var(--accent) 90%, var(--text));
  letter-spacing: 0.04em;
}
.ca-paper-ico {
  font-size: 14px;
  flex-shrink: 0;
}
.ca-paper-text {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  line-height: 1.35;
}
.ca-paper-text b {
  font-weight: 800;
  letter-spacing: 0.06em;
}
.ca-paper-sub {
  font-weight: 500;
  opacity: 0.78;
  font-size: 10.5px;
  text-transform: none;
  letter-spacing: 0;
}

.ca-help,
.ca-help-sm {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--text) 35%, transparent);
  color: color-mix(in srgb, var(--text) 70%, transparent);
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
  margin-left: 5px;
  font: 700 9px/1 var(--ff-ui);
  vertical-align: middle;
  transition:
    border-color 0.15s,
    color 0.15s,
    transform 0.1s;
}
.ca-help {
  width: 13px;
  height: 13px;
}
.ca-help-sm {
  width: 11px;
  height: 11px;
  font-size: 8px;
}
.ca-help::before,
.ca-help-sm::before {
  content: "?";
}
.ca-help:hover,
.ca-help-sm:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: scale(1.1);
}

.ca-tip-pop {
  position: fixed;
  z-index: 10000;
  padding: 9px 11px;
  background: #0a0e15;
  border: 1px solid color-mix(in srgb, var(--accent) 50%, var(--border));
  border-radius: 4px;
  color: var(--text);
  font: 500 11.5px/1.45 var(--ff-ui);
  letter-spacing: 0.005em;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}

/* Inline plan-cap hint under the INVESTMENT field — shows the user
   their per-engine cap so they see the constraint while typing.
   Goes red when the input exceeds the cap (mirrors the leverage
   warn semantics, but inline + smaller). */
.ca-field-hint,
.bs-field-hint {
  display: block;
  margin-top: 4px;
  font: 500 9.5px/1.35 var(--ff-mn);
  letter-spacing: 0.02em;
  color: var(--tx-3);
}
.ca-field-hint.over-cap,
.bs-field-hint.over-cap {
  color: #ff8585;
  font-weight: 700;
}
.ca-field-hint b,
.bs-field-hint b {
  color: var(--tx-1);
  font-weight: 700;
}
.ca-field-hint.over-cap b,
.bs-field-hint.over-cap b {
  color: #ffb6b6;
}
/* Bot Studio investment input — red border when over the plan cap */
#bs-invest.over-cap {
  border-color: rgba(239, 68, 68, 0.55) !important;
  background: rgba(239, 68, 68, 0.06) !important;
}
/* NEXT button blocked state — disabled style + cursor cue */
.bs-foot button.bs-next-blocked,
.bs-foot button.bs-next-blocked:hover {
  opacity: 0.55;
  cursor: not-allowed;
  filter: grayscale(0.4);
}

.ca-lev-warn {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 11px;
  border-radius: 4px;
  font: 600 11px/1.4 var(--ff-ui);
  letter-spacing: 0.01em;
}
.ca-lev-warn[data-severity="med"] {
  background: color-mix(in srgb, var(--warn, #e8a13a) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn, #e8a13a) 60%, transparent);
  color: color-mix(in srgb, var(--warn, #e8a13a) 92%, var(--text));
}
.ca-lev-warn[data-severity="high"] {
  background: color-mix(in srgb, var(--down, #e25555) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--down, #e25555) 70%, transparent);
  color: color-mix(in srgb, var(--down, #e25555) 92%, var(--text));
}
.ca-lev-warn-ico {
  font-size: 14px;
  flex-shrink: 0;
  line-height: 1.1;
}
.ca-lev-warn-text {
  line-height: 1.45;
}
.ca-lev-warn-text b {
  font-weight: 800;
}

/* Make sure form labels with a help button align cleanly */
#ca-form label {
  position: relative;
}
#ca-form label > .ca-help {
  position: relative;
  top: -1px;
}

/* Impact strip help icons should sit flush with the dimension label */
.ca-impact > span {
  display: inline-flex;
  align-items: center;
}

/* =====================================================================
   UPGRADE MODAL — honesty chips
   ---------------------------------------------------------------------
   .upgrade-soon: small "rolling out" badge for Quant features that
     don't ship yet. Avoids selling vaporware.
   .upgrade-na: "current only" subtle text for Free-tier limited Pro
     features (e.g. snapshots — Free gets head only, Pro gets 20).
   .upgrade-beta-note: full-width banner inside Quant upsell explaining
     which features are live vs. rolling out, before the compare grid.
   ===================================================================== */
.upgrade-soon {
  display: inline-block;
  padding: 1px 6px;
  margin-left: 4px;
  font: 600 9px/1.4 var(--ff-ui);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--accent) 95%, var(--text));
  border: 1px solid color-mix(in srgb, var(--accent) 50%, transparent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-radius: 2px;
  vertical-align: middle;
}
.upgrade-na {
  font: 500 11px/1.3 var(--ff-ui);
  color: color-mix(in srgb, var(--text) 55%, transparent);
  font-style: italic;
}
.upgrade-beta-note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 13px;
  margin: 0 0 14px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 4px;
  font: 500 12px/1.45 var(--ff-ui);
  color: color-mix(in srgb, var(--text) 88%, transparent);
}
.upgrade-beta-ico {
  font-size: 14px;
  flex-shrink: 0;
  line-height: 1.1;
}
.upgrade-beta-note b {
  color: var(--text);
  font-weight: 700;
}

/* =====================================================================
   Glittery profit green
   =====================================================================
   Live profit values get a sliding gradient highlight + soft glow so
   green P&L feels alive without churning the layout (animation is
   pure paint — no reflow, GPU-accelerated). Targets the P&L-specific
   classes only; small percent ticks, status pills, etc. keep flat
   green so the dashboard doesn't shimmer everywhere.
   The animation respects prefers-reduced-motion.
   ===================================================================== */
.shc-pnl.up,
.ssc-pnl.up,
.bd-metric-v.up,
.bh-met-v.up,
.bd-acc-v.up,
.bd-pos-table .up,
.bd-watchlist-table .up,
.bd-stat-line b.up,
.bhm-v.up,
.shc-stat-v.up,
.pb-v.up,
.bt-stat-v.up,
table.bt-trades td.up,
.explain-trade-sum-pnl.up,
.improve-bot-sum-pnl.up,
.bd-status-footer .up,
.dh-sym-pct.up {
  background-image: linear-gradient(
    100deg,
    #1fcb6b 0%,
    #1fcb6b 30%,
    #5cf299 45%,
    #b8fbcf 50%,
    #5cf299 55%,
    #1fcb6b 70%,
    #1fcb6b 100%
  );
  background-size: 240% 100%;
  background-position: 200% 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: #1fcb6b; /* fallback when text-fill-color isn't supported */
  text-shadow:
    0 0 6px rgba(31, 203, 107, 0.35),
    0 0 14px rgba(31, 203, 107, 0.18);
  /* Default to paused. The IntersectionObserver in app.js adds
     `.glitter-on` to elements when they enter the viewport and removes
     it when they leave — so we never burn paint cycles animating a
     gradient on an off-screen .dh-sym-pct that the user can't see.
     With ~17 of those on the dashboard alone, this is a major win. */
  animation: glitter-up 3.6s linear infinite paused;
}
.shc-pnl.up.glitter-on,
.ssc-pnl.up.glitter-on,
.bd-metric-v.up.glitter-on,
.bh-met-v.up.glitter-on,
.bd-acc-v.up.glitter-on,
.bd-pos-table .up.glitter-on,
.bd-watchlist-table .up.glitter-on,
.bd-stat-line b.up.glitter-on,
.bhm-v.up.glitter-on,
.shc-stat-v.up.glitter-on,
.pb-v.up.glitter-on,
.bt-stat-v.up.glitter-on,
table.bt-trades td.up.glitter-on,
.explain-trade-sum-pnl.up.glitter-on,
.improve-bot-sum-pnl.up.glitter-on,
.bd-status-footer .up.glitter-on,
.dh-sym-pct.up.glitter-on {
  animation-play-state: running;
}

@keyframes glitter-up {
  from {
    background-position: 200% 0;
  }
  to {
    background-position: -100% 0;
  }
}

/* The bot grid card had a cyan special-case override — keep its glow
   strength but recolor to the same green so profit reads consistently. */
.bot-hero-card .shc-pnl.up,
.strat-hero-card .shc-pnl.up {
  background-image: linear-gradient(
    100deg,
    #1fcb6b 0%,
    #1fcb6b 30%,
    #5cf299 45%,
    #b8fbcf 50%,
    #5cf299 55%,
    #1fcb6b 70%,
    #1fcb6b 100%
  );
  color: #1fcb6b;
  text-shadow:
    0 0 8px rgba(31, 203, 107, 0.45),
    0 0 18px rgba(31, 203, 107, 0.22);
}

/* Scroll-pause backstop — when the user is actively scrolling, pause
   all glitter animations so the compositor can dedicate paint budget
   to the scroll. The .is-scrolling class is toggled in app.js by a
   passive scroll listener with a 200ms debounce. */
body.is-scrolling .shc-pnl.up,
body.is-scrolling .ssc-pnl.up,
body.is-scrolling .bd-metric-v.up,
body.is-scrolling .bh-met-v.up,
body.is-scrolling .bd-acc-v.up,
body.is-scrolling .bd-pos-table .up,
body.is-scrolling .bd-watchlist-table .up,
body.is-scrolling .bd-stat-line b.up,
body.is-scrolling .bhm-v.up,
body.is-scrolling .shc-stat-v.up,
body.is-scrolling .pb-v.up,
body.is-scrolling .bt-stat-v.up,
body.is-scrolling table.bt-trades td.up,
body.is-scrolling .explain-trade-sum-pnl.up,
body.is-scrolling .improve-bot-sum-pnl.up,
body.is-scrolling .bd-status-footer .up,
body.is-scrolling .dh-sym-pct.up,
body.is-scrolling .bot-hero-card .shc-pnl.up,
body.is-scrolling .strat-hero-card .shc-pnl.up {
  animation-play-state: paused;
}

/* Engine detail page has a heavy animation budget — 36 particles +
   conic-gradient laser sweep with 6px blur + light beams + pulse rings
   + orbit dots + the AI bot SVG. All running infinite animations,
   all GPU-painting every frame. While scrolling, freeze the lot —
   pure paint, no DOM impact, animations resume the moment scroll idles. */
body.is-scrolling .bd-radar *,
body.is-scrolling .bd-radar,
body.is-scrolling .bot-robot-watermark,
body.is-scrolling .bot-robot-svg {
  animation-play-state: paused !important;
}

@media (prefers-reduced-motion: reduce) {
  .shc-pnl.up,
  .ssc-pnl.up,
  .bd-metric-v.up,
  .bh-met-v.up,
  .bd-acc-v.up,
  .bd-pos-table .up,
  .bd-watchlist-table .up,
  .bd-stat-line b.up,
  .bhm-v.up,
  .shc-stat-v.up,
  .pb-v.up,
  .bt-stat-v.up,
  table.bt-trades td.up,
  .explain-trade-sum-pnl.up,
  .improve-bot-sum-pnl.up,
  .bd-status-footer .up,
  .dh-sym-pct.up,
  .bot-hero-card .shc-pnl.up,
  .strat-hero-card .shc-pnl.up {
    animation: none;
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--up);
  }
}

/* =================================================================
   THEMED CONFIRM DIALOG
   Replaces native browser confirm() with a Bloomberg-dark modal so the
   sign-out / destructive prompts match the rest of the terminal UI
   instead of dropping in a system white box.
   ================================================================= */
.tsai-cf-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.78);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  animation: tsai-cf-fade 120ms ease-out;
}
.tsai-cf-overlay.show {
  display: flex;
}
@keyframes tsai-cf-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.tsai-cf-card {
  width: 440px;
  max-width: calc(100vw - 32px);
  background: var(--bg-panel);
  border: 1px solid var(--bd-3);
  border-radius: 6px;
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.85),
    0 0 0 1px rgba(255, 255, 255, 0.02) inset;
  overflow: hidden;
  font-family: var(--ff-ui);
  animation: tsai-cf-pop 160ms cubic-bezier(0.2, 0.9, 0.3, 1);
  transform: translateZ(0);
}
@keyframes tsai-cf-pop {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
.tsai-cf-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--bd-2);
  background: var(--bg-elevated);
}
.tsai-cf-title {
  font-size: 11px;
  font-weight: 800;
  color: var(--orange);
  letter-spacing: 0.6px;
  text-transform: uppercase;
}
.tsai-cf-x {
  background: transparent;
  border: 0;
  color: var(--tx-3);
  font-size: 14px;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 3px;
  transition:
    color 120ms,
    background 120ms;
}
.tsai-cf-x:hover {
  color: var(--tx-1);
  background: var(--bg-hover);
}
.tsai-cf-body {
  padding: 18px 18px 20px;
  color: var(--tx-1);
  font-size: 13px;
  line-height: 1.55;
}
.tsai-cf-body p {
  margin: 0 0 8px;
}
.tsai-cf-body p:last-child {
  margin-bottom: 0;
}
.tsai-cf-body p.tsai-cf-sub {
  color: var(--tx-2);
  font-size: 12px;
  line-height: 1.5;
}
.tsai-cf-foot {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 12px 16px;
  background: var(--bg-base);
  border-top: 1px solid var(--bd-2);
}
.tsai-cf-btn {
  font-family: var(--ff-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 8px 16px;
  border-radius: 3px;
  border: 1px solid var(--bd-3);
  background: var(--bg-elevated);
  color: var(--tx-1);
  cursor: pointer;
  transition:
    background 120ms,
    border-color 120ms,
    color 120ms,
    transform 80ms;
}
.tsai-cf-btn:hover {
  background: var(--bg-hover);
  border-color: var(--bd-3);
}
.tsai-cf-btn:active {
  transform: translateY(1px);
}
.tsai-cf-btn.cancel {
  color: var(--tx-2);
}
.tsai-cf-btn.confirm {
  background: var(--down);
  border-color: var(--down);
  color: #fff;
}
.tsai-cf-btn.confirm:hover {
  background: #ff5066;
  border-color: #ff5066;
}
.tsai-cf-btn.confirm.kind-primary {
  background: var(--ac);
  border-color: var(--ac);
}
.tsai-cf-btn.confirm.kind-primary:hover {
  background: #5a99ff;
  border-color: #5a99ff;
}

/* App shell — prevent horizontal bleed on small viewports */
@media (max-width: 640px) {
  html,
  body {
    overflow-x: clip;
    max-width: 100vw;
  }
  .terminal {
    min-width: 0;
    overflow-x: clip;
  }
  .grid.grid-v2,
  .col-main,
  .bot-hub,
  .strategy-detail {
    min-width: 0;
    max-width: 100%;
  }
  .status-bar {
    padding-left: max(8px, env(safe-area-inset-left));
    padding-right: max(8px, env(safe-area-inset-right));
  }
}
