/* tradinghub.cc — live trade tape + liquidations sidebar (Crypto terminal panel) */

/* ---------- Bloomberg/Aggr-style flat redesign ----------
   Retargets the shared color tokens for everything under .live-term only
   (custom properties cascade to every descendant that reads var(--line)
   etc.), and kills border-radius across the panel. Circular status dots
   are restored to round further down so they still read as indicator
   lights rather than tiny squares. No markup, IDs or classes changed. */
.live-term{
  --void: #000000;
  --panel: #090909;
  --panel-hover: #121212;
  --surface-header: #1A1A1A;
  --line: #1A1A1A;
  --line-soft: #141414;
  --ink: #CCCCCC;
  --mute: #8F8F8F;
  --mute-dim: #5A5A5A;
  --signal: #FFC857;
  --signal-soft: rgba(255,200,87,0.12);
  --pulse: #00FF88;
  --pulse-soft: rgba(0,255,136,0.12);
  --danger: #FF4D4D;
  --danger-soft: rgba(255,77,77,0.12);
  --exch-binance: #4CC2FF;
  --exch-bybit: #35D0A7;
  background:var(--void);
}
.live-term, .live-term *{ border-radius:0 !important; }
/* Dynamic terminal lists manage their own scroll anchors in JS. Prevent the
   browser from selecting rapidly-changing trade/whale rows as the document
   scroll anchor, which otherwise can move the whole page during busy bursts. */
.live-term, .live-term__main, .live-term__tape-frame, .whale-card{ overflow-anchor:none; }
.live-term .term-identity-bar__dot,
.live-term .live-tape-idle__dot,
.live-term .dot{ border-radius:50% !important; }

.live-term{
  /* Volume/Terminal uses 40% and Live Chart uses 60%.
     Both columns stay responsive across desktop
     resolutions. --live-side-w is only set (as a fixed px value) once a
     user drags the gutter or has a saved width in layout-persistence.js —
     until then the 4fr/6fr fallback keeps the requested 40/60 split. */
  display:grid;
  /* Two-panel layout: Volume (trade tape + Whales + Market Overview,
     under the TRADINGHUB TERMINAL header) on the left, resizable via the
     gutter, and Chart (Live Chart + the rest of the widget stack) on the
     right. */
  grid-template-columns:minmax(0,4fr) 6px minmax(0,var(--live-side-w,6fr));
  gap:0;
  align-items:start;
  /* the ~160px accounts for the identity bar + asset/exchange selectors +
     toolbar + heatmap strip above the tape list, so the tape list itself
     (not just this outer container) clears 70% of the viewport height */
  min-height:calc(70vh + 160px);
}
@media (max-width:980px){
  .live-term{ grid-template-columns:1fr; min-height:0; }
  .live-term__gutter{ display:none; }
}

/* ---------- resizable sidebar gutter (drag to resize, remembered) ---------- */
.live-term__gutter{
  align-self:stretch;
  width:10px;
  margin:0 -5px;
  cursor:col-resize;
  position:relative;
  z-index:3;
  background:transparent;
  touch-action:none;
}
.live-term__gutter::after{
  content:''; position:absolute; top:0; bottom:0; left:4px; width:1px;
  background:var(--line);
  transition:left .12s ease, width .12s ease, background .12s ease;
}
.live-term__gutter::before{
  content:'';
  position:absolute; top:50%; left:50%;
  width:3px; height:34px;
  transform:translate(-50%,-50%);
  border-radius:3px;
  background:repeating-linear-gradient(to bottom, var(--mute-dim) 0, var(--mute-dim) 3px, transparent 3px, transparent 7px);
  opacity:.55;
  transition:opacity .12s ease, background .12s ease;
}
.live-term__gutter:hover::after,
.live-term__gutter--active::after{ left:3px; width:3px; background:var(--signal); }
.live-term__gutter:hover::before,
.live-term__gutter--active::before{ opacity:1; background:repeating-linear-gradient(to bottom, var(--signal) 0, var(--signal) 3px, transparent 3px, transparent 7px); }
.live-term--fullscreen .live-term__gutter{ align-self:stretch; }

/* ---------- sidebar panel drag-to-reorder ---------- */
.panel-drag-handle{
  flex:none; color:var(--mute-dim); font-size:14.5px; line-height:1;
  margin-right:2px; user-select:none;
  cursor:grab;
}
.panel-drag-handle:active{ cursor:grabbing; }
.live-term__side .widget-card--drag-ghost{ opacity:.35; }
.live-term__side .widget-card--drag-over{ box-shadow:inset 0 2px 0 var(--signal); }

.live-term__main{
  min-width:0;
  display:flex; flex-direction:column;
  position:relative;
  background:var(--void);
  border:1px solid var(--line);
  /* Auto-height, not fixed: this panel also carries Large Trades + Market
     Overview below the tape, so it needs to grow to fit them
     instead of clipping them off — the tape itself keeps a bounded,
     independently-scrollable box via .live-term__tape-frame below. */
  height:auto;
}
.live-term__tape-frame{
  display:flex; flex-direction:column;
  min-width:0;
  overflow:hidden;
  /* Fixed, not just inherited from the grid's min-height: the grid uses
     align-items:start (so the shorter sidebar column isn't stretched
     into a lot of empty space), which means this box was otherwise sized
     purely by its own content — as trade rows streamed in/out, or just
     changed height (large-trade rows get extra padding), it visibly grew
     and shrank. With an explicit height here, .live-tape below (flex:1)
     has something definite to size against and scrolls inside a constant
     box instead. Matches the same 70vh+160px the grid's min-height
     already targets, so nothing shifts on first load either. */
  height:calc(70vh + 160px);
}

/* ---------- terminal identity bar ---------- */
.term-identity-bar{
  display:flex; align-items:center; gap:10px;
  padding:4px 10px;
  background:var(--surface-header);
  border-bottom:1px solid var(--line);
  font-family:var(--font-mono);
  overflow-x:auto;
  white-space:nowrap;
}
.term-identity-bar__brand{
  font-size:12.5px; font-weight:700; letter-spacing:.06em;
  color:var(--signal);
  flex:none;
}
.term-identity-bar__brand span{ color:var(--ink); font-weight:600; }
.term-identity-bar__version{ color:var(--mute-dim) !important; font-weight:500 !important; }
.term-identity-bar__sep{
  flex:none; width:1px; align-self:stretch; background:var(--line-soft);
}
.term-identity-bar__item{
  display:flex; align-items:baseline; gap:5px;
  font-size:12px; letter-spacing:.04em;
  flex:none;
}
.term-identity-bar__label{ color:var(--mute-dim); text-transform:uppercase; }
.term-identity-bar__value{
  color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums;
}
.term-identity-bar__value.term-identity--good{ color:var(--pulse); }
.term-identity-bar__value.term-identity--warn{ color:var(--ink); }
.term-identity-bar__value.term-identity--bad{ color:var(--danger); }
.term-identity-bar__dot{
  width:6px; height:6px; border-radius:50%; flex:none;
  background:var(--mute-dim);
}
.term-identity-bar__dot--live{ background:var(--pulse); box-shadow:0 0 6px rgba(0,255,136,.6); }
.term-identity-bar__dot--reconnecting{ background:var(--ink); }
.term-identity-bar__dot--offline{ background:var(--danger); }
@media (max-width:640px){
  .term-identity-bar__item:not(#term-identity-ws){ display:none; }




  .term-identity-bar__version{ display:none; }
  .term-identity-bar{ padding:3px 10px; }
  .term-identity-bar__brand{ font-size:11.5px; }
  .term-identity-bar__item{ font-size:11px; }
}
/* The chart column is resizable on desktop. Secondary controls always live in
   one real popover (defined with the main toolbar below), so reducing the card
   width cannot spill hidden controls back into the row. */
.livechart-card--compact-tools .livechart-toolbar{ gap:5px; }
.livechart-card--compact-tools .livechart-toolbar .livechart-controls-group{
  flex:0 0 auto; width:auto; min-width:0; margin-left:auto;
}
.livechart-card--compact-tools .livechart-toolbar > .tape-toolbar__group--right{
  flex:0 0 auto; margin-left:0;
}
.livechart-card--compact-tools #livechart-add-second-btn{ width:30px; min-width:30px; padding:3px; }
/* The on-demand second chart has no More wrapper. Its top controls still
   reflow compactly and its drawing suite moves into its mobile trigger. */
.livechart-card--compact-tools #livechart2-toolbar{ gap:4px; }
.livechart-card--compact-tools #livechart2-toolbar .toolbar-btn__label{ display:none; }
.livechart-card--compact-tools #livechart2-toolbar .toolbar-btn{ min-width:30px; padding:4px 6px; justify-content:center; }

/* ---------- compact local clock (identity bar, upper-right) ---------- */
.term-clock-chip{
  display:flex; align-items:baseline;
  margin-left:auto; padding:2px 8px;
  border:1px solid var(--line);
  background:var(--panel);
  font-family:var(--font-mono); font-size:12px; letter-spacing:.04em;
  flex:none; white-space:nowrap;
}
.term-clock-chip__item{ display:flex; align-items:baseline; }
.term-clock-chip__value{ color:var(--ink); font-weight:700; font-variant-numeric:tabular-nums; }
@media (max-width:640px){ .term-clock-chip{ display:none; } }

/* Desktop-only: compact connection/latency/live state and local clock.
   Mobile keeps its own
   sizing from the max-width:640px rules above, untouched. */
@media (min-width:641px){
  .term-identity-bar{ padding:2px 10px; gap:8px; }
  .term-identity-bar__item{ font-size:11px; }
  .term-identity-bar__brand{ font-size:11.5px; }
  .term-clock-chip{ padding:1px 7px; font-size:11px; }
}

/* ---------- asset selector ---------- */
.asset-select{
  display:flex; align-items:center; gap:0; flex-wrap:wrap;
  padding:6px 10px;
  border-bottom:1px solid var(--line);
  background:var(--panel);
}
.asset-pill{
  font-family:var(--font-mono);
  font-size:13px; font-weight:600;
  letter-spacing:.03em;
  color:var(--mute);
  background:transparent;
  border:1px solid var(--line);
  margin-right:-1px;
  padding:4px 12px;
  cursor:pointer;
  display:inline-flex; align-items:baseline; gap:7px;
  transition:color .15s ease, border-color .15s ease, background .15s ease;
}
.asset-pill:hover{ color:var(--ink); border-color:var(--mute-dim); }
.asset-pill--active{
  color:#000000;
  background:var(--signal);
  border-color:var(--signal);
}
.asset-pill__chg{
  font-size:12px; font-weight:600;
  font-variant-numeric:tabular-nums;
  color:var(--mute-dim);
}
.asset-pill__chg--up{ color:var(--pulse); }
.asset-pill__chg--down{ color:var(--danger); }
.asset-pill--active .asset-pill__chg--up{ color:#0a5c30; }
.asset-pill--active .asset-pill__chg--down{ color:#7a1518; }

/* Market Display Mode: "Both" stacks label above price+change on each pill */
.asset-select--stacked .asset-pill{
  flex-direction:column; align-items:flex-start; gap:2px;
  padding:5px 12px 6px;
}
.asset-select--stacked .asset-pill__chg{ font-size:12px; }

/* Phones: smaller text/padding, and the 3 pills now split the row equally
   (flex:1) instead of scrolling — always one static line, no sideways
   sliding, no wrap. min-width:0 + ellipsis on the label/change text is
   just a safety net if a future 4th asset or a long negative % ever makes
   things too tight; the sizing below is chosen to fit comfortably as-is. */
@media (max-width:640px){
  .asset-select{
    padding:4px 4px;
    flex-wrap:nowrap;
  }
  .asset-pill{
    flex:1 1 0; min-width:0;
    font-size:10.5px;
    padding:5px 4px;
    gap:4px;
    justify-content:center;
    overflow:hidden;
  }
  .asset-pill__label{
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;
  }
  .asset-pill__chg{ font-size:10px; flex:none; }
  .asset-select--stacked .asset-pill{ padding:4px 4px 5px; }
}

/* ---------- exchange toggles + tape toolbar, combined into one row ----------
   Was two full-width bars stacked on top of each other (exch-select, then
   tape-toolbar) — same content, just sharing a single border-bottom/background
   now so Settings/Cluster/Pause/Clear/Fullscreen sit inline with Binance/
   Bybit/OKX instead of costing an extra row. flex-wrap lets the toolbar drop
   to its own line on narrow phones if the two groups don't both fit. */
.exch-toolbar-row{
  display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:4px 10px;
  border-bottom:1px solid var(--line);
  background:var(--panel);
}
.exch-toolbar-row .exch-select,
.exch-toolbar-row .tape-toolbar{
  border-bottom:none; background:transparent;
}
.exch-toolbar-row .exch-select{ padding-right:0; }
.exch-toolbar-row .tape-toolbar{ padding-left:0; }
/* Desktop: the collapsible wrapper is transparent to layout so
   .exch-select/.tape-toolbar behave exactly as if they were direct
   children of .exch-toolbar-row, same as before this wrapper existed. */
.exch-toolbar-row__collapsible{ display:contents; }
.exch-toolbar-row__toggle{ display:none; }
@media (max-width:640px){
  /* Collapsed by default on phones — hidden until the "More" bar
     (below) is tapped, to save vertical space. Full-width slim bar with
     a visible label + chevron so it actually reads as tappable, instead
     of a small icon-only button that's easy to miss. */
.exch-toolbar-row__collapsible{
    display:none;
    width:100%;
    flex-wrap:wrap; align-items:center; gap:4px 10px;
  }
  .exch-toolbar-row__collapsible--open{ display:flex; }
  .exch-toolbar-row__toggle{
    display:flex; align-items:center; justify-content:center; gap:6px;
    width:100%;
    padding:4px 8px;
    font-family:var(--font-mono); font-size:11px; font-weight:600;
    letter-spacing:.04em; text-transform:uppercase;
    color:var(--mute);
    background:transparent;
    border:none;
    cursor:pointer;
  }
  .exch-toolbar-row__toggle-chevron{ font-size:10px; line-height:1; transition:transform .15s ease; }
  .exch-toolbar-row__toggle[aria-expanded="true"]{ color:var(--signal); }
  .exch-toolbar-row__toggle[aria-expanded="true"] .exch-toolbar-row__toggle-chevron{ transform:rotate(180deg); }
}
/* ---------- exchange toggle chips ---------- */
.exch-select{
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  padding:5px 10px;
  border-bottom:1px solid var(--line);
  background:var(--panel);
}
.exch-pill{
  display:flex; align-items:center; gap:6px;
  font-family:var(--font-mono); font-size:12px; font-weight:600;
  letter-spacing:.03em;
  color:var(--mute-dim);
  background:transparent;
  border:none;
  padding:2px 0;
  cursor:pointer;
  opacity:.55;
  transition:opacity .15s ease, color .15s ease;
}
.exch-pill:hover{ opacity:.8; }
.exch-pill--active{ opacity:1; color:var(--ink); }
.exch-pill__dot{ width:13px; height:13px; border-radius:4px !important; flex:none; display:inline-flex; overflow:hidden; }
.exch-pill__dot svg{ display:block; }

/* ---------- Tape toolbar ---------- */
.tape-toolbar{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:5px 10px;
  border-bottom:1px solid var(--line);
  background:var(--panel);
}
.tape-toolbar__group{ display:flex; align-items:center; gap:6px; }
.tape-toolbar__group--right{ margin-left:auto; gap:8px; }
.tape-toolbar__label{
  font-family:var(--font-mono); font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--mute-dim);
}
.tape-toolbar__select{
  font-family:var(--font-mono); font-size:12px;
  background:var(--void); color:var(--ink);
  border:1px solid var(--line);
  padding:2px 5px; cursor:pointer;
}
.toolbar-btn{
  display:inline-flex; align-items:center; gap:5px;
  font-family:var(--font-mono); font-size:12px; font-weight:600;
  letter-spacing:.02em;
  color:var(--mute);
  background:transparent;
  border:1px solid var(--line);
  padding:3px 8px;
  cursor:pointer;
  transition:color .15s ease, border-color .15s ease, background .15s ease;
}
.toolbar-btn:hover{ color:var(--ink); border-color:var(--mute-dim); }
.toolbar-btn:disabled{ opacity:.35; cursor:default; }
.toolbar-btn:disabled:hover{ color:var(--mute); border-color:var(--line); }
.toolbar-btn--sq{ padding:3px 7px; }
/* Subtle outline+tint instead of a solid, glowing gold fill — same
   language already used for .liq-filter--active/.whale-tab--active
   below, just applied consistently to toolbar buttons (Cluster, Pause,
   chart-type toggles, etc.) so "active" reads as a quiet state change
   rather than a bright illuminated control. */
.toolbar-btn--active{ color:var(--signal); background:var(--signal-soft); border-color:var(--signal); }
.toolbar-btn--active:hover{ color:var(--signal); background:rgba(255,200,87,.2); }
.toolbar-btn--active:active{ background:rgba(255,200,87,.28); }
.toolbar-btn:not(.toolbar-btn--active):active{ background:var(--panel-hover); }
.toolbar-btn__icon{ font-size:13.5px; line-height:1; }
/* Auto Scroll toggle — a small status dot instead of a glyph, echoing the
   ws-status dot language elsewhere (.term-identity-bar__dot). Green +
   glow while actively tracking the live edge (toolbar-btn--active, same
   class every other toolbar toggle uses); dimmed to a plain grey dot the
   moment the user pans/zooms away — signals "will resume", not "off".
   Fully off (aria-pressed=false, user explicitly disabled it) falls back
   to the ordinary --mute dot color from .toolbar-btn's own text color. */
.livechart-autoscroll-btn__dot{
  width:6px; height:6px; border-radius:50%; flex:none;
  background:currentColor;
}
.livechart-autoscroll-btn.toolbar-btn--active .livechart-autoscroll-btn__dot{
  background:var(--pulse); box-shadow:0 0 6px rgba(0,255,136,.6);
}
.livechart-autoscroll-btn--paused .livechart-autoscroll-btn__dot{
  background:var(--mute-dim); box-shadow:none;
}
@media (max-width:640px){
  .toolbar-btn__label{ display:none; }
  .toolbar-btn{ padding:5px 8px; min-width:36px; min-height:36px; justify-content:center; }
  .toolbar-btn--sq{ min-width:36px; }
  .exch-pill{ padding:8px 4px; min-height:32px; }
}

/* live-term--paused: subtle cue that the tape is frozen while connections stay live */
.live-term--paused .live-tape{ opacity:.6; }

/* fullscreen mode: fill the viewport and let the tape column claim the extra height.
   Both panels are given an explicit height + their own overflow so they scroll
   independently (Trade Tape on the left, sidebar cards on the right) instead of
   the browser's default :fullscreen overflow:auto turning the whole grid into a
   single page-level scroll surface, which is what made the sidebar uncrollable. */
.live-term--fullscreen{
  background:var(--panel);


  padding:0;
  margin:0;
  box-sizing:border-box;
  width:100%;
  max-width:none;
  height:100vh;
  height:100dvh;
  grid-template-rows:minmax(0,1fr);
  align-items:stretch;
  /* Ignore a dragged/saved sidebar pixel width in fullscreen. A large saved
     right column can otherwise squeeze the terminal column until its
     TRADINGHUB / connection / latency header is visibly clipped. */
  grid-template-columns:minmax(460px,4fr) 6px minmax(0,6fr);
  overflow:hidden;
}
.live-term--fullscreen .live-term__main{
  min-width:0; min-height:0; width:100%; height:100%;
  overflow-y:auto; -webkit-overflow-scrolling:touch;
}



.live-term--fullscreen .live-term__main,
.live-term--fullscreen .live-term__side{
  scrollbar-gutter:auto;
  scrollbar-width:thin;
  scrollbar-color:var(--line) transparent;
}
.live-term--fullscreen .live-term__main::-webkit-scrollbar,
.live-term--fullscreen .live-term__side::-webkit-scrollbar{ width:6px; }
.live-term--fullscreen .live-term__main::-webkit-scrollbar-thumb,
.live-term--fullscreen .live-term__side::-webkit-scrollbar-thumb{ background:var(--line); }
.live-term--fullscreen .term-identity-bar{
  position:sticky;
  top:0;
  z-index:25;
  min-height:27px;
  width:100%;
  box-sizing:border-box;
  flex-wrap:wrap;
  align-content:center;
  row-gap:3px;
  white-space:normal;
  overflow-x:hidden;
  flex:none;
  scrollbar-width:none;
}
.live-term--fullscreen .term-identity-bar__brand,
.live-term--fullscreen .term-identity-bar__item,
.live-term--fullscreen .term-clock-chip{ white-space:nowrap; }
.live-term--fullscreen .term-identity-bar::-webkit-scrollbar{ display:none; }
.live-term--fullscreen .live-term__side{
  width:100%; height:100%; min-width:0; min-height:0;
  overflow-y:auto; -webkit-overflow-scrolling:touch;
}
:fullscreen.live-term{ min-height:100vh; overflow:hidden; }
@media (min-width:981px){
  .live-term--fullscreen > .live-term__main{ grid-column:1; grid-row:1; }
  .live-term--fullscreen > .live-term__gutter{ grid-column:2; grid-row:1; }
  .live-term--fullscreen > .live-term__side{ grid-column:3; grid-row:1; }
}
@media (max-width:980px){
  /* below the breakpoint the tape/sidebar stack in a single column (same
     rule the base .live-term already applies) — let that stack scroll as
     one unit instead of fighting it for a fixed height, same tradeoff
     Immersive Mode makes at this breakpoint. */
  .live-term--fullscreen{ grid-template-columns:minmax(0,1fr); grid-template-rows:none; overflow-y:auto; }
  .live-term--fullscreen .live-term__main{ height:auto; overflow-y:visible; }
  .live-term--fullscreen .live-term__side{ height:auto; overflow-y:visible; }
  /* :fullscreen.live-term (higher specificity, above) sets overflow:hidden
     unconditionally — override it here for the native Fullscreen API case
     specifically, or the phone can enter fullscreen but never scroll. */
  .live-term--fullscreen{
    scrollbar-gutter:auto;
    scrollbar-width:thin;
    scrollbar-color:var(--line) transparent;
  }
  .live-term--fullscreen::-webkit-scrollbar{ width:6px; }
  .live-term--fullscreen::-webkit-scrollbar-thumb{ background:var(--line); }
  :fullscreen.live-term.live-term--fullscreen{ overflow-y:auto; overflow-x:hidden; }
}

/* ---------- Sound controls ---------- */
.sound-control{ position:relative; }
.sound-panel{
  position:absolute; top:calc(100% + 8px); right:0; z-index:20;
  width:240px;
  background:var(--panel); border:1px solid var(--line); border-radius:10px;

  padding:12px;
  font-family:var(--font-mono);
}
.sound-panel__head{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  margin-bottom:10px; padding-bottom:8px;
  border-bottom:1px solid var(--line-soft);
}
.sound-panel__head strong{ font-size:13.5px; color:var(--ink); }
.sound-panel__master{ display:flex; align-items:center; gap:5px; font-size:12px; color:var(--mute); cursor:pointer; }
.sound-panel__profile-row{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:2px 0 10px; margin-bottom:6px;
  border-bottom:1px solid var(--line-soft);
}
.sound-panel__profile-row label{ font-size:12.5px; color:var(--mute); flex:none; }
.sound-panel__profile-row select{
  flex:1; font-family:var(--font-mono); font-size:12.5px;
  background:var(--void); color:var(--ink);
  border:1px solid var(--line); border-radius:5px;
  padding:3px 6px; cursor:pointer;
}
.sound-panel__volume-row{
  display:flex; align-items:center; gap:8px;
  padding:2px 0 10px;
  margin-bottom:6px;
  border-bottom:1px solid var(--line-soft);
}
.sound-panel__volume-row label{ font-size:12.5px; color:var(--mute); flex:none; }
.sound-panel__volume-row input[type="range"]{
  flex:1; accent-color:var(--signal); cursor:pointer;
}
.sound-panel__volume-value{
  font-size:12px; color:var(--mute-dim); flex:none; min-width:32px; text-align:right;
}
.sound-panel__row{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:5px 0;
}
.sound-panel__profile{ display:flex; align-items:center; gap:6px; font-size:13px; color:var(--ink); cursor:pointer; }
.sound-panel__profile input{ accent-color:var(--signal); }
.sound-panel__row select{
  font-family:var(--font-mono); font-size:12px;
  background:var(--void); color:var(--ink);
  border:1px solid var(--line); border-radius:5px;
  padding:2px 5px; cursor:pointer;
}
.sound-panel__test{
  width:100%; margin-top:8px;
  font-family:var(--font-mono); font-size:12.5px; font-weight:600;
  color:var(--ink); background:var(--panel, #12151C);
  border:1px solid var(--line); border-radius:6px;
  padding:6px; cursor:pointer;
}
.sound-panel__test:hover{ border-color:var(--mute-dim); }
.sound-panel__hint{
  margin:8px 0 0; font-size:11.5px; line-height:1.4; color:var(--mute-dim);
}

/* ---------- Settings popover (Display + Filters + Sound, consolidated) ---------- */
.filter-control{ position:relative; }
.filter-panel{
  position:absolute; top:calc(100% + 8px); left:0; z-index:20;
  width:200px;
  background:var(--panel); border:1px solid var(--line); border-radius:10px;

  padding:12px;
  font-family:var(--font-mono);
}
/* Settings is always a fixed, centered modal dialog — on desktop AND
   mobile — rather than a popover anchored under the toolbar button.
   Being `position:fixed` means its position is purely viewport-relative:
   it can't drift, and it doesn't care where the button that opened it
   lives, whether that's a cramped mobile toolbar or a wide desktop one.
   Previously this centered treatment only kicked in above a min-width
   breakpoint, with a separate anchored-popover styling below it — that
   in-between anchored state (position:absolute, relative to the toolbar
   button) is what let the panel appear to drift/slide as the page
   reflowed from incoming trades. Making it unconditional removes that
   anchored state entirely.
   Centered with `inset:0` + `margin:auto` rather than the more common
   `top/left:50%` + `translate(-50%,-50%)` trick: auto-margins let the
   browser's own fixed-positioning layout center the box in the actual
   viewport directly, with no percentage-of-viewport / transform math for
   anything to go subtly wrong in. */
.filter-panel--settings{
  position:fixed;
  inset:0; margin:auto;
  display:flex; flex-direction:column;
  width:min(760px, calc(100vw - 32px));
  height:fit-content;
  max-width:none;
  max-height:calc(100vh - 64px);
  overflow-y:auto; overscroll-behavior:contain;
  padding:16px 18px 18px;
  box-sizing:border-box;
  box-shadow:0 24px 64px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.3);
  z-index:200;
}
/* position:fixed above has the same specificity as the browser's default
   [hidden]{display:none} rule, but author CSS always wins that tie — so
   without this, the panel would render open (dead center, backdrop and
   all) on page load, before the Settings button is ever clicked. */
.filter-panel--settings[hidden]{ display:none; }
/* Smooth open/close: the panel already toggles the [hidden] attribute in
   JS (trade-tape.js), which is instant with no transition surface — add
   a fade+scale driven by an "is-open" class that JS applies a frame after
   removing [hidden] (and removes a frame before restoring [hidden]), so
   the transition below actually has something to animate between.
   Centering here comes from inset:0+margin:auto above, so the animation
   only needs to scale — no translate offset to keep in sync with it. */
.filter-panel--settings{
  opacity:0;
  transform:scale(.97);
  transition:opacity .16s ease, transform .16s ease;
}
.filter-panel--settings.filter-panel--open{
  opacity:1;
  transform:scale(1);
}
.filter-panel__head{
  display:flex; align-items:center; justify-content:space-between;
  margin:-16px -18px 10px;
  padding:14px 18px 10px;
  background:var(--surface-header);
  border-bottom:1px solid var(--line);
  /* Settings can grow tall enough to scroll (many categories expanded at
     once, especially Notifications) — keep the head (and its close
     button) pinned to the top of that scroll instead of it disappearing
     upward, which on a phone meant scrolling all the way back up just to
     find the way to close the dialog. */
  position:sticky; top:-16px; z-index:2;
}
.filter-panel__head strong{ font-size:13.5px; color:var(--ink); }
.filter-panel__close{
  display:inline-flex; /* Settings is always the modal treatment now */
  align-items:center; justify-content:center;
  width:24px; height:24px; padding:0;
  background:none; border:none; border-radius:6px;
  color:var(--mute-dim); font-size:13.5px; cursor:pointer;
  transition:color .15s ease, background .15s ease;
}
.filter-panel__close:hover{ color:var(--ink); background:rgba(255,255,255,0.06); }
.filter-panel__group{ padding:6px 0; border-bottom:1px solid var(--line-soft); }
.filter-panel__group:last-child{ border-bottom:none; padding-bottom:0; }
.filter-panel__group-label{
  display:block; font-size:11.5px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--mute-dim); margin-bottom:5px;
}
.filter-panel__radio, .filter-panel__checkbox{
  display:flex; align-items:center; gap:6px;
  font-size:13px; color:var(--ink); cursor:pointer;
  padding:2px 0;
}
.filter-panel__radio input, .filter-panel__checkbox input{ accent-color:var(--signal); }
.settings-checkbox{ margin-top:2px; }
.settings-row{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:4px 0;
}
.settings-row__label{ font-size:13px; color:var(--ink); }
.settings-row__control--buttons{ display:flex; gap:6px; }
.settings-row__select{
  font-family:var(--font-mono); font-size:12.5px;
  background:var(--void); color:var(--ink);
  border:1px solid var(--line); border-radius:5px;
  padding:3px 6px; cursor:pointer;
}
/* ---------- Settings categories: collapsible accordion ---------- */
.settings-categories{ display:flex; flex-direction:column; }
.settings-category{ border-bottom:1px solid var(--line-soft); }
.settings-category:last-child{ border-bottom:none; }
.settings-category__header{
  width:100%; display:flex; align-items:center; gap:8px;
  background:none; border:none; margin:0;
  font-family:var(--font-mono); text-align:left; cursor:pointer;
  padding:9px 2px;
  -webkit-tap-highlight-color:transparent;
}
.settings-category__title{
  flex:1; font-size:12px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--mute-dim);
}
.settings-category__header--open .settings-category__title{ color:var(--ink); }
.settings-category__chevron{
  font-size:11.5px; line-height:1; color:var(--mute-dim);
  transition:transform .15s ease;
}
.settings-category__header--open .settings-category__chevron{ transform:rotate(180deg); color:var(--mute); }
.settings-category__body{ padding:0 2px 10px; }
.settings-category__body[hidden]{ display:none; }
.settings-category__hint{
  font-size:12px; line-height:1.4; color:var(--mute-dim);
  margin:0 0 6px;
}
.settings-subgroup{ padding:4px 0; }
.settings-subgroup .filter-panel__group-label{ margin-bottom:5px; }
.settings-reset-btn{
  width:100%; margin-top:2px;
  font-family:var(--font-mono); font-size:12.5px; font-weight:600;
  color:var(--danger); background:var(--panel, #12151C);
  border:1px solid var(--danger); border-radius:6px;
  padding:7px; cursor:pointer;
  transition:background .12s ease, color .12s ease;
}
.settings-reset-btn:hover{ background:var(--danger); color:var(--void, #0a0b0d); }
.settings-reset-btn:disabled{ opacity:.6; cursor:default; background:var(--panel, #12151C); color:var(--danger); }
.settings-category__header:hover .settings-category__title{ color:var(--ink); }

/* Settings dialog chrome: applies at every width now that the panel is
   always the fixed centered modal (previously gated to min-width:981px,
   with mobile relying on a different, anchored-popover layout). Categories
   lay out in an auto-fit grid — the number of columns grows with the
   panel's own width, not a fixed 2-per-row — so the more room a screen
   has, the shorter (not scrollier) the panel gets; on narrow phones the
   grid naturally collapses to one column. A generous max-height +
   overflow-y:auto is kept purely as a last-resort safety net for very
   short/zoomed-in viewports; in normal use it should never be needed. */
.filter-panel--settings .settings-categories{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(220px, 1fr));
  gap:2px 20px;
  align-items:start;
}
.filter-panel--settings .settings-category{
  box-sizing:border-box;
  min-width:0;
}
/* Notifications (sound) has the most controls (profile, volume,
   per-type thresholds, test button) — give it the full width instead
   of squeezing it into one grid cell. */
.filter-panel--settings .settings-category--wide{
  grid-column:1 / -1;
}
/* A translucent backdrop behind the centered dialog: dims the terminal
   so the modal reads clearly as modal, and doubles as a big, obvious
   click target to dismiss it (clicks bubble to the existing document
   click-to-close listener in trade-tape.js — no extra JS needed). */
.filter-panel__backdrop{
  position:fixed; inset:0; z-index:199;
  background:rgba(4,6,10,.6);
  opacity:0; pointer-events:none;
  transition:opacity .16s ease;
}
.filter-panel__backdrop--open{ opacity:1; pointer-events:auto; }
/* Bigger tap targets on the category headers themselves at narrower
   widths, since these are the primary touch controls for showing/hiding
   a whole group. */
@media (max-width:980px){
  .settings-category__header{ padding:11px 2px; }
}
/* Phone-width touch targets: rows/checkboxes/radios/selects get more
   height and breathing room than the desktop density above, since a
   fingertip needs more room than a mouse cursor. Scoped to the settings
   dialog specifically so the compact trade-tape filter popovers
   elsewhere keep their tighter desktop sizing. */
@media (max-width:600px){
  .filter-panel--settings .filter-panel__radio,
  .filter-panel--settings .filter-panel__checkbox{
    padding:7px 0; font-size:14px; gap:9px;
  }
  .filter-panel--settings .filter-panel__radio input,
  .filter-panel--settings .filter-panel__checkbox input{
    width:18px; height:18px;
  }
  .filter-panel--settings .settings-row{ padding:7px 0; }
  .filter-panel--settings .settings-row__select,
  .filter-panel--settings select{
    padding:6px 8px; font-size:13.5px;
  }
  .filter-panel--settings .settings-row__control--buttons .toolbar-btn{
    padding:6px 12px;
  }
}
/* Sound now lives inline inside Settings instead of its own popover —
   same markup/ids as before, just without the floating position and
   its own trigger button (see sound.js: btn is optional there now). */
.sound-panel--inline{
  position:static; width:auto; border:none; border-radius:0; padding:0;
}
.sound-panel--inline .sound-panel__head{ border-bottom:none; padding-bottom:2px; margin-bottom:6px; justify-content:flex-start; }
.sound-panel--divider{ margin-top:12px; padding-top:12px; border-top:1px solid var(--line-soft); }


/* ---------- Recent-trades heatmap ---------- */
.tape-heatmap{
  display:flex; align-items:stretch; gap:1px;
  height:20px;
  padding:0 12px;
  background:var(--void);
  border-bottom:1px solid var(--line-soft);
}
.tape-heatmap__cell{ flex:1 1 0; min-width:2px; border-radius:1px; margin:3px 0; }
.tape-heatmap__cell--buy{ background:var(--pulse); }
.tape-heatmap__cell--sell{ background:var(--danger); }
.tape-heatmap__cell--tier1{ opacity:.35; }
.tape-heatmap__cell--tier2{ opacity:.6; }
.tape-heatmap__cell--tier3{ opacity:.85; }
.tape-heatmap__cell--tier4{ opacity:1; }

/* ---------- Largest recent trade ---------- */
.tape-row--biggest{
  outline:1px solid var(--signal);
  outline-offset:-1px;
  box-shadow:inset 0 0 0 1px rgba(245,166,35,.25);
  /* the row element is newly created in the DOM whenever a trade becomes
     the biggest-in-5m (see tapeRowSignature/buildTapeRowEl in trade-tape.js),
     so a plain CSS entrance animation fires automatically the moment it's
     inserted — no JS timing hooks needed. Kept short and understated: a
     quick opacity/lift, not a flashy pop. */
  animation:tapeRowBiggestIn .35s ease-out;
}
@keyframes tapeRowBiggestIn{
  from{ opacity:0; transform:translateY(-3px); }
  to{ opacity:1; transform:translateY(0); }
}
@media (prefers-reduced-motion: reduce){
  .tape-row--biggest{ animation:none; }
}
.tape-row__crown{ flex:none; font-size:12.5px; line-height:1; margin-right:-4px; }

/* ---------- Chart and terminal synchronization ----------
   A brief neutral flash (not tinted per side — buy/sell color already comes
   from the row's own background/text) applied only to a row's very first
   paint, both here on the trade tape and on the liquidations sidebar rows
   further down. Matches the terminal request literally: ~300ms. */
.tape-row--flash-in,
.liq-sidebar__row--flash-in{ animation:rowFlashIn .3s ease-out; }
@keyframes rowFlashIn{
  from{ box-shadow:inset 0 0 0 999px rgba(255,255,255,.18); }
  to{ box-shadow:inset 0 0 0 999px rgba(255,255,255,0); }
}
@media (prefers-reduced-motion: reduce){
  .tape-row--flash-in,
  .liq-sidebar__row--flash-in{ animation:none; }
}

/* ---------- Order flow ----------
   Same overlay-bar pattern as .liq-multi-row__bar / .whale-stats__bar: the
   Buy/Sell % legend sits on top of the bar itself (pinned to its two ends)
   instead of on its own line underneath, so all three widgets share one
   visual language for red/green ratio bars. */
.orderflow-ratio-bar-wrap{ position:relative; }
/* Low-sample state: the buy/sell % legend can look 100%-confident off a
   single trade, same as it would off hundreds. Dim it and dash the bar
   outline so a thin sample reads as "noisy", not "settled". The title
   attribute (set in JS) carries the actual trade count on hover/focus. */
.orderflow-ratio-bar-wrap--low-sample .orderflow-ratio-bar{ opacity:.55; }
.orderflow-ratio-bar-wrap--low-sample .orderflow-ratio-bar{
  outline:1px dashed var(--line); outline-offset:2px;
}
.orderflow-ratio-bar-wrap--low-sample .orderflow-ratio-legend__buy,
.orderflow-ratio-bar-wrap--low-sample .orderflow-ratio-legend__sell{ opacity:.75; }
.orderflow-ratio-bar{
  display:flex; height:16px; border-radius:5px; overflow:hidden;
  background:var(--line-soft);
}
.orderflow-ratio-bar__buy{ background:var(--pulse); transition:width .3s ease; }
.orderflow-ratio-bar__sell{ background:var(--danger); transition:width .3s ease; }
.orderflow-ratio-legend{
  position:absolute; inset:0;
  display:flex; justify-content:space-between; align-items:center;
  padding:0 7px;
  font-family:var(--font-mono); font-size:12px;
  pointer-events:none;
}
.orderflow-ratio-legend__buy,
.orderflow-ratio-legend__sell{
  color:#fff; font-weight:700; text-shadow:0 1px 2px rgba(0,0,0,.55);
  white-space:nowrap;
}
.orderflow-ratio-legend b{ font-weight:700; }
/* Compact "last 60 seconds" readout: one line instead of a 2x2 grid under
   its own "Last 60 seconds" heading — cuts the card's height by close to
   half versus the old layout. Sell vol is dropped here since it's already
   implied by the ratio bar/legend directly above. */
.orderflow-60s{
  margin-top:8px; padding-top:8px;
  border-top:1px solid var(--line-soft);
}
.orderflow-60s--compact{
  display:flex; align-items:baseline; justify-content:center; flex-wrap:wrap; gap:5px;
  font-family:var(--font-mono); font-size:13px; color:var(--mute-dim);
}
.orderflow-60s-stat b{ font-size:14.5px; font-weight:700; color:var(--ink); }
.orderflow-60s-sep{ color:var(--line); }
/* Explicit window marker so this row is never mistaken for part of the
   "last 5m" tag in the card head — it's a different, shorter window. */
.orderflow-60s-window{
  display:inline-block; padding:1px 5px; margin-right:2px;
  border:1px solid var(--line); border-radius:3px;
  font-size:10px; font-weight:700; letter-spacing:.02em;
  color:var(--mute-dim); cursor:help;
}

/* ---------- Market statistics ---------- */
.mstat-row{
  display:flex; justify-content:space-between; align-items:center;
  padding:6px 0;
  font-family:var(--font-mono); font-size:13.5px;
  border-bottom:1px solid var(--line-soft);
}
.mstat-row:last-child{ border-bottom:none; }
.mstat-label{ color:var(--mute-dim); display:inline-flex; align-items:center; }
.mstat-value{ color:var(--ink); font-weight:600; }

/* Market Pulse column: keep the labels (1m/5m/15m Buy/Sell, Dominant side)
   visible next to the values so the numbers are self-explanatory. */
.marketpulse-card .mstat-value{ text-align:right; }








.marketpulse-card .mstat-row--pulse{
  display:block;
  padding:5px 0 7px;
}
.marketpulse-card .mstat-row--pulse:last-child{ padding-bottom:2px; }
.marketpulse-stat__head{
  display:flex; align-items:baseline; justify-content:space-between;
  min-width:0; gap:10px; margin-bottom:5px;
}
.marketpulse-stat__head .mstat-label,
.marketpulse-stat__head .mstat-value{ min-width:0; }
.marketpulse-stat__head .mstat-value{ flex:none; font-variant-numeric:tabular-nums; white-space:nowrap; }
.marketpulse-status{
  position:relative; height:13px; min-width:0; overflow:hidden;
  border:1px solid var(--line);
  background:linear-gradient(90deg,rgba(15,143,99,.055) 0 50%,rgba(204,72,72,.055) 50% 100%);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.22);
}
.marketpulse-status__buy,
.marketpulse-status__sell{
  position:absolute; z-index:1; top:2px; bottom:2px; left:2px; right:2px;
  transform:scaleX(0); transition:transform .45s cubic-bezier(.2,.75,.25,1), opacity .2s ease;
}
.marketpulse-status__buy{
  transform-origin:left center;
  background:linear-gradient(90deg,rgba(15,143,99,.58),var(--pulse));
}
.marketpulse-status__sell{
  transform-origin:right center;
  background:linear-gradient(270deg,rgba(204,72,72,.58),var(--danger));
}
.marketpulse-status__segments{ display:none; }
.marketpulse-status__mid{
  position:absolute; z-index:4; top:0; bottom:0; left:50%; width:2px;
  transform:translateX(-1px); pointer-events:none;
  background:repeating-linear-gradient(180deg,var(--signal) 0 3px,transparent 3px 6px);
  filter:drop-shadow(0 0 2px rgba(214,173,75,.46));
}
.marketpulse-status[data-state="collecting"] .marketpulse-status__buy,
.marketpulse-status[data-state="collecting"] .marketpulse-status__sell{ opacity:0; }
.marketpulse-status[data-state="collecting"]::before{
  content:""; position:absolute; z-index:1; top:2px; bottom:2px; left:-30%; width:30%;
  background:linear-gradient(90deg,transparent,var(--signal),transparent);
  animation:marketpulse-status-loading 1.25s linear infinite;
}
.marketpulse-status--dominant[data-dominant="buy"]{ border-color:rgba(15,143,99,.5); }
.marketpulse-status--dominant[data-dominant="sell"]{ border-color:rgba(204,72,72,.5); }
.marketpulse-status--dominant[data-dominant="neutral"]{ border-color:var(--line); }
@keyframes marketpulse-status-loading{ to{ left:100%; } }
@media (prefers-reduced-motion:reduce){
  .marketpulse-status__buy,.marketpulse-status__sell{ transition:none; }
  .marketpulse-status[data-state="collecting"]::before{ left:35%; animation:none; }
}
@media (max-width:560px){
  .marketpulse-card .mstat-row--pulse{ padding:6px 0 8px; }
  .marketpulse-status{ height:12px; }
  .marketpulse-stat__head{ margin-bottom:4px; }
}

/* ---------- compact metric tooltips ----------
   Small ⓘ trigger next to a label or value that isn't self-explanatory
   (Order Flow scoring, the various "Volume" figures, funding/OI/long-short,
   cluster counts on the tape, etc). The actual bubble is one shared
   floating element (see metric-tooltips.js) so it's never clipped by a
   card's own layout — this just styles the small trigger itself and, on
   real hover-capable desktop pointers, reveals the bubble without needing
   a click; touch devices always use tap (handled in JS) so there's no
   double-tap-to-click quirk. */
.metric-tip{
  display:inline-flex; align-items:center; justify-content:center;
  width:13px; height:13px; margin-left:5px;
  border-radius:50%; border:1px solid var(--line); background:none;
  color:var(--mute-dim); font-family:var(--font-mono); font-size:10.5px; line-height:1;
  cursor:help; flex-shrink:0; padding:0; vertical-align:middle;
  transition:color .15s ease, border-color .15s ease;
}
.metric-tip:hover, .metric-tip:focus-visible, .metric-tip--open{
  color:var(--signal); border-color:var(--signal); outline:none;
}
/* Mobile: keep the glyph's small inline size (it sits mid-sentence next to
   labels like "Open interest") but give it a real ~32px tap target via an
   invisible expanded hit-area, instead of enlarging the visible dot. */
@media (max-width:760px){
  .metric-tip{ position:relative; }
  .metric-tip::after{
    content:''; position:absolute; top:50%; left:50%;
    transform:translate(-50%,-50%); width:32px; height:32px;
  }
}
.metric-tip-bubble{
  position:absolute; z-index:130; display:none;
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:8px 10px; box-shadow:0 10px 30px rgba(0,0,0,.45);
  font-family:var(--font-mono); font-size:12.5px; line-height:1.5; color:var(--mute);
}
.metric-tip-bubble.open{ display:block; }

/* ---------- Market Pulse ---------- */
.tag--pos{ color:var(--pulse); border-color:rgba(0,255,136,.35); background:rgba(0,255,136,.08); }
.tag--neg{ color:var(--danger); border-color:rgba(255,77,77,.35); background:rgba(255,77,77,.08); }
/* Smoother "feel" when a tag flips direction (e.g. the live chart's price
   tag going from pos to neg on a tick) instead of an instant hard swap. */
.tag--pos, .tag--neg{ transition:background .2s ease, border-color .2s ease, color .2s ease; }

/* ---------- Order Flow Score ----------
   Headline ("Buy Pressure" / "Sell Pressure") + the buy/sell split as two
   big numbers, then a semicircle gauge whose needle sweeps between the red
   (bearish) and green (bullish) zones for the same -100..+100 composite
   score — a needle position reads faster than a bare number, with the
   exact score and its Bullish/Bearish/Neutral label kept underneath the
   arc for anyone who wants the precise figure too. */
.ofscore-pressure{ text-align:center; margin-bottom:2px; }
.ofscore-pressure__label{
  font-size:12.5px; font-weight:700; color:var(--mute-dim);
  text-transform:uppercase; letter-spacing:.05em;
  margin-bottom:4px;
}
.ofscore-pressure__label.pos{ color:var(--pulse); }
.ofscore-pressure__label.neg{ color:var(--danger); }
.ofscore-pressure__ratio{
  font-family:var(--font-mono); font-size:25px; font-weight:700;
  line-height:1.1; margin-bottom:2px;
}
.ofscore-pressure__buy{ color:var(--pulse); }
.ofscore-pressure__sell{ color:var(--danger); }
.ofscore-pressure__sep{ color:var(--mute-dim); font-weight:400; margin:0 2px; }

.ofscore-gauge-wrap{ position:relative; margin:0 auto; max-width:190px; }
.ofscore-gauge{ display:block; width:100%; height:auto; overflow:visible; }
.ofscore-gauge__zone{
  fill:none; stroke-width:14; stroke-linecap:butt;
}
.ofscore-gauge__zone--sell{ stroke:var(--danger); opacity:.85; }
.ofscore-gauge__zone--neutral{ stroke:var(--signal); opacity:.55; }
.ofscore-gauge__zone--buy{ stroke:var(--pulse); opacity:.85; }
.ofscore-gauge__needle line{
  stroke:var(--ink); stroke-width:3; stroke-linecap:round;
}
.ofscore-gauge__hub{ fill:var(--ink); }
/* Readout sits under the arc's flat baseline rather than inside it, so the
   needle always has clear room to sweep across the full zone without ever
   passing behind the numbers. */
.ofscore-gauge__readout{
  margin-top:-6px; text-align:center;
}
.ofscore-value{
  font-family:var(--font-mono); font-size:26px; font-weight:700;
  text-align:center; color:var(--ink); line-height:1.1;
}
.ofscore-value.pos{ color:var(--pulse); }
.ofscore-value.neg{ color:var(--danger); }
.ofscore-label{
  text-align:center; font-size:12.5px; color:var(--mute-dim);
  text-transform:uppercase; letter-spacing:.04em;
  margin-top:2px; margin-bottom:10px;
}

/* ---------- Loading dots: subtle "still listening" indicator ----------
   Used in place of static "Collecting…" text wherever a card is waiting on
   its first data — three small dots, currentColor so they always match
   whatever label they sit inside, pulsing in a gentle staggered wave
   rather than a hard blink. Purely decorative; the real label text is
   still present for screen readers via the accompanying .sr-only span. */
.loading-dots{ display:inline-flex; align-items:center; gap:3px; vertical-align:middle; }
.loading-dots__dot{
  width:4px; height:4px; border-radius:50%;
  background:currentColor; opacity:.3;
  animation:loading-dots-pulse 1.3s ease-in-out infinite;
}
@keyframes loading-dots-pulse{
  0%, 80%, 100%{ opacity:.3; transform:scale(.85); }
  40%{ opacity:1; transform:scale(1); }
}
@media (prefers-reduced-motion:reduce){
  .loading-dots__dot{ animation:none; opacity:.6; }
}

/* Exchange marks: small rounded-square icon tiles (each SVG paints its own
   brand-accurate background + mark) instead of the old flat 3-letter text
   badges — so an exchange is tellable apart by its tile at a glance. */
.tape-row__exch, .liq-sidebar__exch, .whale-exch{
  flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:6px; overflow:hidden;
  box-shadow:0 0 0 1px rgba(255,255,255,0.06);
}
.tape-row__exch{ width:18px; height:18px; }
.liq-sidebar__exch{ width:17px; height:17px; }
.whale-exch{ width:17px; height:17px; }
.tape-row__exch svg, .liq-sidebar__exch svg, .whale-exch svg{ display:block; }

/* ---------- trade tape rows ---------- */
.live-tape{
  flex:1; min-height:0;
  overflow-y:auto;
  scrollbar-gutter:stable;
  overscroll-behavior:contain;
  overflow-anchor:none;
  padding:4px 0;
  /* very low-contrast scanline texture so the space below the last trade
     (or under the "Waiting for new trades…" indicator on a quiet market)
     reads as intentional terminal surface rather than dead black space.
     Deliberately faint — it should not compete with trade row data. */
  background-image:repeating-linear-gradient(
    0deg,
    rgba(255,255,255,0.018) 0px,
    rgba(255,255,255,0.018) 1px,
    transparent 1px,
    transparent 3px
  );
}
.live-tape__empty{
  padding:40px 16px; text-align:center;
  color:var(--mute-dim); font-size:14.5px;
  display:flex; flex-direction:column; align-items:center; gap:10px;
}
.live-tape__empty-icon{
  font-size:26px; line-height:1; opacity:.35;
}
.live-tape__empty-title{
  font-family:var(--font-mono); font-size:14px; font-weight:700;
  color:var(--mute); letter-spacing:.02em;
}
.live-tape__empty-sub{
  font-size:12.5px; color:var(--mute-dim); max-width:280px;
}
/* Loading variant: a slow pulse on the icon signals "still working on it"
   without implying anything is broken. */
.live-tape__empty--loading .live-tape__empty-icon{
  animation:th-empty-pulse 1.6s ease-in-out infinite;
}
@keyframes th-empty-pulse{
  0%, 100%{ opacity:.25; }
  50%{ opacity:.55; }
}
/* Unavailable variant: static (no pulse) plus an amber accent on the title
   so it visibly reads as a different state from "still loading". */
.live-tape__empty--unavailable .live-tape__empty-title{ color:var(--signal); }
.live-tape__empty--unavailable .live-tape__empty-icon{ opacity:.3; }
/* ---------- idle-state indicator ----------
   Sits at the bottom of the tape panel (not inside the virtualized row
   list — it's a sibling of #live-tape-list, so it's never touched by that
   list's own render/spacer logic). Anchored to the panel rather than the
   scrolling list, so it always reads as "part of the empty space below
   the last trade" whether that gap is small or (during a quiet market)
   fills most of the ~70vh panel. Hidden by default; trade-tape.js adds
   .live-tape-idle--visible once a while has passed with no new prints,
   and removes it the moment the next trade arrives. */
.live-tape-idle{
  position:absolute; left:50%; bottom:16px; transform:translateX(-50%);
  display:flex; align-items:center; gap:7px;
  padding:6px 14px;
  font-family:var(--font-mono); font-size:12.5px; color:var(--mute-dim);
  background:rgba(11,11,11,0.7); border:1px solid var(--line);
  opacity:0; pointer-events:none;
  transition:opacity .4s ease;
  z-index:2;
}
.live-tape-idle--visible{ opacity:1; }
.live-tape-idle__dot{
  width:6px; height:6px; flex:none;
  background:var(--signal);
  animation:liveTapeIdlePulse 1.6s ease-in-out infinite;
}
@keyframes liveTapeIdlePulse{
  0%, 100%{ opacity:.35; transform:scale(.85); }
  50%{ opacity:1; transform:scale(1.15); }
}
@media (prefers-reduced-motion: reduce){
  .live-tape-idle__dot{ animation:none; }
}
.tape-row{
  display:flex; align-items:center; gap:8px;
  padding:1.5px 10px;
  font-family:var(--font-mono); font-size:var(--tape-fs, 11px);
  line-height:1.3;
  border-bottom:1px solid rgba(255,255,255,0.03);
  border-left:2px solid transparent;
}
.tape-row--buy{ background:rgba(0,255,136,.06); }
.tape-row--sell{ background:rgba(255,77,77,.06); }
.tape-row.tape-tier-2{ background-color:rgba(0,255,136,.12); }
.tape-row.tape-tier-2.tape-row--sell{ background-color:rgba(255,77,77,.12); }
.tape-row.tape-tier-3{ font-weight:700; padding-top:5px; padding-bottom:5px; background-color:rgba(0,255,136,.2); }
.tape-row.tape-tier-3.tape-row--sell{ background-color:rgba(255,77,77,.2); }
.tape-row.tape-tier-4{ font-weight:800; padding-top:6px; padding-bottom:6px; background-color:rgba(0,255,136,.32); }
.tape-row.tape-tier-4.tape-row--sell{ background-color:rgba(255,77,77,.32); }

/* ---------- outsized-print highlight hierarchy ($100K / $500K / $1M) ----------
   Layered on top of the buy/sell tint above via a left accent bar + faint
   wash, so direction stays legible while size still stands out. Escalates
   via border thickness + glow within the amber family, not by switching
   to --danger red on the top tier — a big *buy* print (green wash) getting
   a red border/value would read as a sell it isn't. Direction stays the
   tape's own job (background tint, ▲/▼ side glyph, price colour); this
   hierarchy is purely "how big", so it never touches red/green. */
.tape-row.tape-hl-1{ border-left-color:rgba(255,200,87,.55); box-shadow:inset 4px 0 10px -8px rgba(255,200,87,.6); }
.tape-row.tape-hl-2{ border-left-color:var(--signal); background-image:linear-gradient(90deg, rgba(255,200,87,.14), rgba(255,200,87,.05) 60%); }
.tape-row.tape-hl-3{
  border-left-width:4px;
  border-left-color:var(--signal);
  background-image:linear-gradient(90deg, rgba(255,200,87,.26), rgba(255,200,87,.07) 65%);
  box-shadow:inset 0 0 0 1px rgba(255,200,87,.3);
  font-weight:800;
}
.tape-row.tape-hl-3 .tape-row__value{ color:var(--signal); }

/* ---------- Settings: Terminal — Highlight whale trades toggles ----------
   trade-tape.js always computes tape-hl-1/2/3 for every row; these shell
   modifiers (flipped by settings-extras.js) neutralize a tier's accent
   without touching the size-based tape-tier-N bolding above, which is a
   separate always-on density cue. th-hl-off is the master "Highlight whale
   trades" switch; th-hl-N-off are the individual >100k/>500k/>1M toggles. */
.th-hl-off .tape-row.tape-hl-1,
.th-hl-off .tape-row.tape-hl-2,
.th-hl-off .tape-row.tape-hl-3,
.th-hl-1-off .tape-row.tape-hl-1,
.th-hl-2-off .tape-row.tape-hl-2,
.th-hl-3-off .tape-row.tape-hl-3{
  border-left-color:transparent; box-shadow:none; background-image:none;
}
.th-hl-off .tape-row.tape-hl-3 .tape-row__value,
.th-hl-3-off .tape-row.tape-hl-3 .tape-row__value{ color:inherit; }

/* ---------- Settings: Terminal — Show volumes toggle ---------- */
.th-hide-volumes .tape-row__value{ display:none; }

.tape-row__side{ flex:none; width:12px; text-align:center; font-size:11.5px; }
.tape-row--buy .tape-row__side{ color:var(--pulse); }
.tape-row--sell .tape-row__side{ color:var(--danger); }
.tape-row__price{ flex:none; width:90px; color:var(--ink); font-variant-numeric:tabular-nums; }
.tape-row--buy .tape-row__price{ color:var(--pulse); }
.tape-row--sell .tape-row__price{ color:var(--danger); }
.tape-row__qty{ flex:1; min-width:0; color:var(--mute); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tape-row__value{ flex:none; width:72px; text-align:right; color:var(--ink); font-weight:600; }
.tape-row__time{ flex:none; width:66px; text-align:right; color:var(--mute-dim); font-size:12.5px; white-space:nowrap; }
.tape-row__cluster{
  flex:none; font-size:11.5px; font-weight:700;
  color:#000000; background:var(--pulse);
  border-radius:999px; padding:1px 6px; line-height:1.4;
  cursor:help;
}
.tape-row--sell .tape-row__cluster{ background:var(--danger); color:#fff; }

/* ---------- Tape modes: Compact / Normal / Large / Whales only ----------
   Normal = the base .tape-row rule above, no class needed. Compact/Large
   only change row density (padding/gap/font); the tier-based padding bumps
   above (tape-tier-3/4) still apply on top of whichever density is active.
   Whales-only doesn't change row layout — the filtering that keeps only
   $100k+ prints happens in trade-tape.js's render() — this just adds a
   small accent so it's visually obvious the mode is active even before any
   trade has arrived. */
.tape-mode--compact .tape-row{ padding-top:1px; padding-bottom:1px; gap:8px; font-size:var(--tape-fs, 10px); }
.tape-mode--compact .tape-row.tape-tier-3{ padding-top:3px; padding-bottom:3px; }
.tape-mode--compact .tape-row.tape-tier-4{ padding-top:4px; padding-bottom:4px; }

.tape-mode--large .tape-row{ padding-top:8px; padding-bottom:8px; gap:12px; font-size:var(--tape-fs, 14px); }
.tape-mode--large .tape-row.tape-tier-3{ padding-top:11px; padding-bottom:11px; }
.tape-mode--large .tape-row.tape-tier-4{ padding-top:14px; padding-bottom:14px; }
.tape-mode--large .tape-row__value{ width:88px; }

.tape-mode--whales .live-tape{ border-top:2px solid var(--signal); }
.tape-mode--whales .tape-row{ border-left:2px solid rgba(255,200,87,.4); }

/* ---------- terminal typography + density pass ----------
   IBM Plex Mono everywhere inside the sidebar (headers were inheriting the
   site's display font), and tighter card padding so the 2-column grid
   above reads as dense/information-rich rather than airy. */
.live-term__side .widget-card{
  background:transparent;
  border:none;
  border-bottom:1px solid var(--line);
  padding:8px 10px;
}
.live-term__side .widget-card:last-child{ border-bottom:none; }
.live-term__side .widget-card__head{ margin-bottom:6px; }
.live-term__side .widget-card__head h4{
  font-family:var(--font-mono); font-size:12.5px; font-weight:700;
  text-transform:uppercase; letter-spacing:.07em; color:var(--mute);
}
.live-term__side .mstat-row{ padding:2px 0; font-size:12.5px; }

/* ---------- sidebar: single-column stack ----------
   Was a 2-column dense grid pairing narrow stat cards side by side
   (Large Trades | Market Overview, etc.); now that
   Large Trades and Market Overview have moved out into the
   Volume panel (.live-term__main), Squeeze Detector is the only card here that
   was ever narrow enough to pair — with nothing left to pair it with, a
   2-column grid just leaves an empty half-width gap next to it, so this
   drops to a plain single-column stack instead. */
.live-term__side{
  min-width:0;
  display:grid;
  grid-template-columns:1fr;
  gap:0; align-content:start;
  border-left:1px solid var(--line);
  /* A hair lighter than --void (pure black), rather than relying only on
     the 1px border above, so the two columns read as separate surfaces
     even at a glance/low brightness — not a visible "different color",
     just enough of a lift to give the eye a natural seam. */
  background:#070707;
  position:relative;
  /* ---------- scroll-boundary fades ----------
     A soft inset shadow at the top/bottom edges hints that the card list
     continues beyond view. Lives on the container's own box (not a scrolled
     child), so it stays anchored at the edges whether the sidebar scrolls
     independently (fullscreen, via overflow-y:auto) or the whole page
     scrolls past it below the 980px breakpoint — and it never covers or
     intercepts clicks on the cards underneath. */
  box-shadow:
    inset 0 24px 16px -16px rgba(0,0,0,.55),
    inset 0 -24px 16px -16px rgba(0,0,0,.55);
}
.live-term__side .widget-card{ min-width:0; }
/* ---------- customizable dashboard: hidden widgets ----------
   display:none (not visibility/opacity) so the stack immediately closes the
   gap left behind — no manual reflow needed. The card stays in the DOM and
   keeps receiving live updates underneath; only its box is pulled from the
   layout. */
.live-term__side .widget-card.widget-card--hidden,
.live-term__side .wc-split-col.widget-card--hidden{ display:none !important; }
/* Liquidation heatmap: same toggle mechanism as the sidebar widgets above,
   but this card sits outside #live-term-side (it is a full-width card further
   down the Crypto panel), so it needs its own unscoped display:none rule. */
.liq-heatmap-card.widget-card--hidden{ display:none !important; }
/* Large Trades + Market Overview: same toggle mechanism too, but these
   live inside .live-term__main (see the "Volume panel" block below), not
   #live-term-side or the liquidation heatmap group above — so they also need their
   own (unscoped) display:none rule. */
.whale-card.widget-card--hidden,
.mktoverview-card.widget-card--hidden,
.retention-card.widget-card--hidden{ display:none !important; }
/* ---------- Volume panel: Large Trades + Market Overview ----------
   Live directly inside .live-term__main, below the trade tape — under the
   TRADINGHUB TERMINAL header, in the same bordered panel, not a separate
   column. No drag handle (not part of the right sidebar's reorder set). */
.live-term__main .whale-card,
.live-term__main .mktoverview-card{
  background:transparent;
  border:none;
  border-top:1px solid var(--line);
  padding:8px 10px;
  min-width:0;
  flex:none;
}
.live-term__main .widget-card__head{ margin-bottom:6px; }
.live-term__main .whale-card .widget-card__head h4,
.live-term__main .mktoverview-card .widget-card__head h4{
  font-family:var(--font-mono); font-size:12.5px; font-weight:700;
  text-transform:uppercase; letter-spacing:.07em; color:var(--mute);
}
.live-term__main .mktoverview-card .mstat-row{ padding:2px 0; font-size:12.5px; }

.liq-sidebar{ display:flex; flex-direction:column; min-width:0; max-width:100%; overflow:hidden; }
.liq-sidebar .widget-card__body{ display:flex; flex-direction:column; min-height:0; min-width:0; max-width:100%; flex:1; }
.liq-sidebar__src{
  font-family:var(--font-mono); font-size:11.5px; font-weight:500;
  color:var(--mute-dim); text-transform:uppercase; letter-spacing:.05em;
  margin-left:8px;
}

/* ---------- Liquidations: stats summary ---------- */
.liq-stats{ padding-bottom:10px; margin-bottom:8px; border-bottom:1px solid var(--line-soft); }

/* ---------- Liquidations: compact multi-window summary ----------
   Four timeframes stay visible at once, but each is a dense data row:
   timeframe | Long value + label | Short value + label. This keeps the
   information scannable without wasting vertical space in the sidebar. */
.liq-multi{
  display:flex;
  flex-direction:column;
  gap:0;
}
.liq-multi-block{
  display:grid;
  grid-template-columns:38px minmax(0,1fr);
  align-items:center;
  min-height:34px;
  padding:4px 0;
  border-bottom:1px solid var(--line-soft);
}
.liq-multi-block:first-child{ padding-top:2px; }
.liq-multi-block:last-child{ padding-bottom:2px; border-bottom:none; }
.liq-multi-block__win{
  display:block;
  margin:0;
  text-align:center;
  font-family:var(--font-mono);
  font-size:10.5px;
  font-weight:700;
  line-height:1;
  letter-spacing:.035em;
  color:var(--mute-dim);
  text-transform:uppercase;
}
.liq-multi-block__sides{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  align-items:center;
  gap:6px;
  min-width:0;
}
.liq-multi-block__side{
  min-width:0;
  display:flex;
  flex-direction:row;
  align-items:baseline;
  justify-content:center;
  text-align:center;
  gap:4px;
  padding:0 2px;
}
.liq-multi-block__value{
  font-family:var(--font-mono);
  font-variant-numeric:tabular-nums;
  font-size:14px;
  font-weight:800;
  line-height:1.05;
  color:var(--ink);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  max-width:100%;
}
.liq-multi-block__label{
  flex:none;
  font-family:var(--font-mono);
  font-size:9px;
  font-weight:600;
  line-height:1;
  letter-spacing:.04em;
  color:var(--mute-dim);
}
.liq-multi-block__side--long .liq-multi-block__value{ color:var(--danger); }
.liq-multi-block__side--short .liq-multi-block__value{ color:var(--pulse); }
@media (max-width:640px){
  .liq-multi-block{ grid-template-columns:34px minmax(0,1fr); min-height:32px; padding:3px 0; }
  .liq-multi-block__value{ font-size:13px; }
  .liq-multi-block__label{ font-size:8.5px; }
  .liq-multi-block__sides{ gap:4px; }
}

/* ---------- Squeeze Detector card ----------
   Longs/Shorts destroyed reuses the same two-column stat pattern as
   .liq-multi-block above (long = --danger, short = --pulse — same colors,
   since a short liquidation is what feeds a bullish squeeze). The verdict
   line below escalates LOW/MEDIUM/HIGH via weight/glow within the same
   directional color rather than switching hue, same convention as the
   tape's outsized-print highlight tiers. */
.squeeze-destroyed{
  display:flex; align-items:stretch; gap:8px;
  padding-bottom:9px; margin-bottom:9px;
  border-bottom:1px dashed var(--line-soft);
}
.squeeze-destroyed__col{
  flex:1 1 0; min-width:0;
  display:flex; flex-direction:column; align-items:center; gap:1px;
}
.squeeze-destroyed__value{
  font-family:var(--font-mono); font-size:19px; font-weight:800;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%;
  line-height:1.15;
}
.squeeze-destroyed__col--long .squeeze-destroyed__value{ color:var(--danger); }
.squeeze-destroyed__col--short .squeeze-destroyed__value{ color:var(--pulse); }
.squeeze-destroyed__label{
  font-family:var(--font-mono); font-size:10px; font-weight:600; letter-spacing:.06em;
  color:var(--mute-dim); text-transform:uppercase;
}
.squeeze-verdict{
  display:flex; flex-direction:column; align-items:center; gap:3px;
  padding:4px 0 9px;
}
.squeeze-verdict__label{
  font-family:var(--font-mono); font-size:16px; font-weight:800; letter-spacing:.03em;
  color:var(--ink);
}
.squeeze-verdict__label.pos{ color:var(--pulse); }
.squeeze-verdict__label.neg{ color:var(--danger); }
.squeeze-verdict__level{
  font-family:var(--font-mono); font-size:11px; font-weight:700; letter-spacing:.08em;
  padding:1px 8px; border-radius:3px; border:1px solid var(--line);
  color:var(--mute-dim);
}
.squeeze-verdict__level:empty{ display:none; }
.squeeze-verdict__level--low.pos{ color:var(--pulse); border-color:rgba(0,255,136,.3); background:rgba(0,255,136,.06); }
.squeeze-verdict__level--low.neg{ color:var(--danger); border-color:rgba(255,77,77,.3); background:rgba(255,77,77,.06); }
.squeeze-verdict__level--medium.pos{ color:var(--pulse); border-color:rgba(0,255,136,.45); background:rgba(0,255,136,.12); font-weight:800; }
.squeeze-verdict__level--medium.neg{ color:var(--danger); border-color:rgba(255,77,77,.45); background:rgba(255,77,77,.12); font-weight:800; }
.squeeze-verdict__level--high.pos{
  color:var(--pulse); border-color:var(--pulse); background:rgba(0,255,136,.18); font-weight:800;
  box-shadow:0 0 10px rgba(0,255,136,.25);
}
.squeeze-verdict__level--high.neg{
  color:var(--danger); border-color:var(--danger); background:rgba(255,77,77,.18); font-weight:800;
  box-shadow:0 0 10px rgba(255,77,77,.25);
}
.squeeze-factors{
  display:flex; align-items:center; justify-content:center; flex-wrap:wrap;
  gap:5px 10px;
  font-family:var(--font-mono); font-size:11px; color:var(--mute-dim);
}

.liq-sidebar__head-row{
  display:flex; align-items:center; gap:6px;
  padding:4px 6px 8px;
  font-family:var(--font-mono); font-size:11.5px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--mute-dim);
  border-bottom:1px solid var(--line-soft);
}
.liq-sidebar__head-row span:nth-child(1){ flex:none; width:22px; }
.liq-sidebar__head-row span:nth-child(2){ flex:none; width:44px; }
.liq-sidebar__head-row span:nth-child(3){ flex:none; width:50px; }
.liq-sidebar__head-row span:nth-child(4){ flex:1; }
.liq-sidebar__head-row span:nth-child(5){ flex:none; width:64px; }
.liq-sidebar__head-row .ta-r{ text-align:right; }

.liq-sidebar__list{
  list-style:none; margin:0; padding:0;
  flex:1; min-height:0; min-width:0; width:100%; max-width:100%;
  overflow-y:auto; overflow-x:hidden;
  max-height:400px;
}
.liq-sidebar__empty{
  padding:20px 8px; text-align:center;
  color:var(--mute-dim); font-size:13.5px; list-style:none;
}
.liq-sidebar__row{
  display:flex; align-items:center; gap:6px;
  width:100%; min-width:0; max-width:100%;
  padding:6px; box-sizing:border-box; overflow:hidden;
  font-family:var(--font-mono); font-size:13px;
  border-bottom:1px solid rgba(255,255,255,0.03);
}
.liq-sidebar__row--long{ background:rgba(255,77,77,.10); }
.liq-sidebar__row--short{ background:rgba(0,255,136,.10); }
.liq-sidebar__sym{ flex:none; width:44px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:700; color:var(--ink); }
.liq-sidebar__side{ flex:none; width:50px; font-size:12px; white-space:nowrap; }
.liq-sidebar__row--long .liq-sidebar__side{ color:var(--danger); }
.liq-sidebar__row--short .liq-sidebar__side{ color:var(--pulse); }
.liq-sidebar__usd{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:right; font-weight:700; color:var(--ink); }
.liq-sidebar__time{ flex:none; width:64px; text-align:right; color:var(--mute-dim); font-size:12px; white-space:nowrap; }

/* ---------- unusually-large liquidation highlighting ----------
   Same three tiers as the trade tape's highlightTier() ($100k/$500k/$1M),
   layered as an inset ring on top of the long/short background tint so
   both signals stay visible at once. Escalates via ring thickness/
   brightness within the amber family, not by switching to red/green — a
   big *short* liquidation (green row) ringed in --danger would read as a
   sell signal it isn't, so size stays on its own amber channel. */
.liq-sidebar__row--tier1{ box-shadow:inset 0 0 0 1px rgba(255,200,87,.35); }
.liq-sidebar__row--tier2{ box-shadow:inset 0 0 0 1px rgba(255,159,10,.55); }
.liq-sidebar__row--tier3{ box-shadow:inset 0 0 0 2px rgba(255,159,10,.9); }
.liq-sidebar__row--tier2 .liq-sidebar__usd,
.liq-sidebar__row--tier3 .liq-sidebar__usd{ color:var(--signal); }

/* thin scrollbars to match the rest of the terminal */
.live-tape, .liq-sidebar__list, .live-term__side{ scrollbar-width:thin; scrollbar-color:var(--line) transparent; }
.live-tape::-webkit-scrollbar, .liq-sidebar__list::-webkit-scrollbar, .live-term__side::-webkit-scrollbar{ width:6px; }
.live-tape::-webkit-scrollbar-thumb, .liq-sidebar__list::-webkit-scrollbar-thumb, .live-term__side::-webkit-scrollbar-thumb{ background:var(--line); border-radius:3px; }

/* ---------- Whale Tracker ---------- */

/* ---------- Whale Tracker: stats summary ---------- */
.whale-stats{ padding-bottom:8px; margin-bottom:8px; border-bottom:1px solid var(--line-soft); }
.whale-stats__row{ display:flex; gap:10px; }
.whale-stats__item{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; font-family:var(--font-mono); }
.whale-stats__label{ font-size:11.5px; color:var(--mute-dim); text-transform:uppercase; letter-spacing:.04em; }
.whale-stats__value{ font-size:14.5px; font-weight:700; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* Empty state: no whale trades recorded yet for this asset — collapse the
   whole card to one short line instead of showing an empty stats row,
   empty filter tabs and an empty list stacked on top of each other. */
.whale-card--empty .widget-card__head{ margin-bottom:2px; }
.whale-card--empty .widget-card__body{
  height:auto; padding-top:0; padding-bottom:0;
}
.whale-empty-msg{
  font-family:var(--font-mono); font-size:13.5px; color:var(--mute-dim);
  line-height:1.3;
}
.whale-empty-msg[hidden]{ display:none; }

.whale-tabs{ display:flex; flex-wrap:wrap; gap:5px; margin-bottom:8px; }
.whale-tab{
  flex:1 1 auto; padding:5px 6px;
  font-family:var(--font-mono); font-size:12px; font-weight:600;
  color:var(--mute-dim); background:var(--void);
  border:1px solid var(--line); border-radius:6px;
  cursor:pointer; transition:color .15s ease, border-color .15s ease, background .15s ease;
  white-space:nowrap;
}
.whale-tab:hover{ color:var(--ink); }
.whale-tab--active{ color:var(--ink); border-color:var(--signal); background:rgba(255,255,255,0.04); }
.whale-head-row{
  display:flex; align-items:center; gap:6px;
  padding:4px 6px 8px;
  font-family:var(--font-mono); font-size:11.5px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--mute-dim);
  border-bottom:1px solid var(--line-soft);
}
.whale-head-row span:nth-child(1){ flex:none; width:26px; }
.whale-head-row span:nth-child(2){ flex:none; width:36px; }
.whale-head-row span:nth-child(3){ flex:none; width:54px; }
.whale-head-row span:nth-child(4){ flex:1; }
.whale-head-row span:nth-child(5){ flex:none; width:64px; }
.whale-head-row .ta-r{ text-align:right; }
.whale-list{
  list-style:none; margin:0; padding:0;
  max-height:340px; overflow-y:auto;
  overscroll-behavior:contain;
  overflow-anchor:none;
  scrollbar-width:thin; scrollbar-color:var(--line) transparent;
}
.whale-list::-webkit-scrollbar{ width:6px; }
.whale-list::-webkit-scrollbar-thumb{ background:var(--line); border-radius:3px; }
.whale-empty{
  padding:20px 8px; text-align:center;
  color:var(--mute-dim); font-size:13.5px; list-style:none;
}
.whale-row{
  display:flex; align-items:center; gap:6px;
  padding:6px;
  font-family:var(--font-mono); font-size:13px;
  border-bottom:1px solid rgba(255,255,255,0.03);
}
.whale-row--buy{ background:rgba(0,255,136,.10); }
.whale-row--sell{ background:rgba(255,77,77,.10); }
.whale-pair{ flex:none; width:36px; font-weight:700; color:var(--ink); }
.whale-side{ flex:none; width:54px; font-size:12px; white-space:nowrap; }
.whale-row--buy .whale-side{ color:var(--pulse); }
.whale-row--sell .whale-side{ color:var(--danger); }
.whale-value{ flex:1; text-align:right; font-weight:700; color:var(--ink); }
.whale-time{ flex:none; width:64px; text-align:right; color:var(--mute-dim); font-size:12px; white-space:nowrap; }

/* ---------- unusually-large whale trade highlighting ----------
   Same three tiers as the trade tape's highlightTier() ($100k/$500k/$1M).
   Escalates via ring thickness/brightness within the amber family, not by
   switching to red/green — direction is already shown by the row's own
   buy/sell tint (.whale-row--buy/--sell above), so a size-based ring in
   --danger would silently repaint a *buy* row red once it got big enough. */
.whale-row--tier1{ box-shadow:inset 0 0 0 1px rgba(255,200,87,.35); }
.whale-row--tier2{ box-shadow:inset 0 0 0 1px rgba(255,159,10,.55); }
.whale-row--tier3{ box-shadow:inset 0 0 0 2px rgba(255,159,10,.9); }
.whale-row--tier2 .whale-value,
.whale-row--tier3 .whale-value{ color:var(--signal); }

/* ---------- big-trade flash (flash-effects.js) ----------
   A brief pulse across the whole live-tape panel on $100k+/$500k+/$1M+
   prints, so a whale trade registers even if you're not staring at the
   tape row itself. Buy = green tint, sell = red tint; intensity and
   duration scale with size. Border-box only (box-shadow), so it never
   shifts layout. */
.live-term--flash-buy{ --flash-rgb: 0,255,136; }
.live-term--flash-sell{ --flash-rgb: 255,77,77; }
.live-term--flash-t1{ animation: liveTermFlash .5s ease-out; }
.live-term--flash-t2{ animation: liveTermFlash .7s ease-out; }
.live-term--flash-t3{ animation: liveTermFlashBig 1s ease-out; }
@keyframes liveTermFlash{
  0%{ box-shadow: inset 0 0 0 1px rgba(var(--flash-rgb,0,255,136),.5), 0 0 26px -4px rgba(var(--flash-rgb,0,255,136),.4); }
  100%{ box-shadow: inset 0 0 0 1px rgba(var(--flash-rgb,0,255,136),0), 0 0 26px -4px rgba(var(--flash-rgb,0,255,136),0); }
}
@keyframes liveTermFlashBig{
  0%{ box-shadow: inset 0 0 0 2px rgba(var(--flash-rgb,0,255,136),.85), 0 0 46px -2px rgba(var(--flash-rgb,0,255,136),.55); }
  55%{ box-shadow: inset 0 0 0 1px rgba(var(--flash-rgb,0,255,136),.4), 0 0 32px -4px rgba(var(--flash-rgb,0,255,136),.32); }
  100%{ box-shadow: inset 0 0 0 1px rgba(var(--flash-rgb,0,255,136),0), 0 0 26px -4px rgba(var(--flash-rgb,0,255,136),0); }
}
@media (prefers-reduced-motion: reduce){
  .live-term--flash-t1, .live-term--flash-t2, .live-term--flash-t3{ animation:none; }
  .livechart-price--flash-up, .livechart-price--flash-down{ animation:none; }
}

/* ---------- Live Chart widget ---------- */
.livechart-card .widget-card__body{ padding-top:2px; }
/* Right-edge padding for this card is set further down, in the panel
   visual-hierarchy block (search "HIGH: Live Chart") — that rule has the
   same specificity and comes later in the cascade, so it's the one that
   actually wins; edit there, not here. */
/* Brief wash of color on the header price tag for a live tick — the
   underlying .tag--pos/.tag--neg background shows again once the
   animation ends (animations don't persist past their keyframes unless
   given fill-mode:forwards, which this deliberately omits). */
@keyframes livechartPriceFlashUp{ 0%{ background:rgba(0,255,136,.38); } 100%{ background:transparent; } }
@keyframes livechartPriceFlashDown{ 0%{ background:rgba(255,77,77,.38); } 100%{ background:transparent; } }
.livechart-price--flash-up{ animation:livechartPriceFlashUp .5s ease-out; }
.livechart-price--flash-down{ animation:livechartPriceFlashDown .5s ease-out; }
.livechart-toolbar{
  display:flex; align-items:center; flex-wrap:wrap; gap:6px 8px;
  /* Separates the toolbar from the chart without reducing canvas space. */
  margin-bottom:3px;
}
.livechart-toolbar .tape-toolbar__group{ display:flex; align-items:center; gap:4px; }
.livechart-toolbar .tape-toolbar__select{ padding:3px 5px; }
#livechart-type-group{ gap:2px; }
#livechart-type-group .toolbar-btn{ padding:3px 8px; }
/* Desktop chart tools belong in the chart toolbar, not behind a phone-style
   More menu. The existing DOM is kept so all established listeners/state stay
   authoritative; above 640px the wrapper becomes a normal wrapping toolbar
   group, while the More trigger is reserved for the mobile bottom sheet. */
.livechart-toolbar .livechart-controls-group{ min-width:0; }
.livechart-overflow-btn{
  align-items:center; justify-content:center; gap:6px;
  min-height:28px; padding:3px 9px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:700;
  letter-spacing:.04em; text-transform:uppercase; white-space:nowrap;
  color:var(--mute); background:var(--panel); border:1px solid var(--line);
  border-radius:5px; cursor:pointer;
}
.livechart-overflow-btn:hover,.livechart-overflow-btn:focus-visible{ color:var(--ink); border-color:var(--mute-dim); outline:none; }
.livechart-overflow-btn__chevron{ font-size:9px; line-height:1; transition:transform .15s ease; }
.livechart-overflow-btn[aria-expanded="true"]{ color:var(--signal); border-color:rgba(255,200,87,.55); }
.livechart-overflow-btn[aria-expanded="true"] .livechart-overflow-btn__chevron{ transform:rotate(180deg); }
.livechart-overflow-panel[hidden]{ display:none !important; }
@media (min-width:641px){
  /* Desktop toolbar is a single-row control strip. More remains phone-only.
     Width pressure is handled by density classes from the chart-card
     ResizeObserver, never by wrapping or moving controls into More. */
  .livechart-toolbar{
    align-items:center; flex-wrap:nowrap; gap:4px;
    min-width:0; overflow:visible;
  }
  .livechart-toolbar > .tape-toolbar__group{ flex:0 0 auto; min-width:0; }
  .livechart-toolbar .livechart-controls-group{
    display:flex; flex:1 1 auto; align-items:center; min-width:0;
    margin-left:2px; padding-left:6px; border-left:1px solid var(--line);
  }
  .livechart-overflow{ display:contents; }
  .livechart-overflow-btn{ display:none !important; }
  .livechart-overflow-panel:not([hidden]){
    display:flex; position:static; flex:1 1 auto; flex-direction:row;
    flex-wrap:nowrap; align-items:center; gap:3px; min-width:0;
    width:auto; max-height:none; box-sizing:border-box; padding:0; overflow:visible;
    background:transparent; border:0; border-radius:0; box-shadow:none;
  }
  .livechart-overflow-panel > .toolbar-btn,
  .livechart-overflow-panel > .filter-control > .toolbar-btn{
    width:auto; min-height:28px; justify-content:center; text-align:center;
    padding:3px 6px; white-space:nowrap;
  }
  .livechart-overflow-panel .toolbar-btn__label{ display:inline; white-space:nowrap; }
  .livechart-overflow-panel > .filter-control{ width:auto; flex:0 0 auto; }
  .livechart-overflow-panel .livechart-indicator-panel{
    position:absolute; width:min(330px,calc(100vw - 24px)); margin-top:0;
  }
  .livechart-overflow-panel .livechart-layout-panel{
    position:absolute; width:260px; margin-top:0;
  }
  .livechart-toolbar > .tape-toolbar__group--right{ align-self:center; margin-left:0; }

  /* Requested icon-only desktop actions. Their text remains in the DOM for
     the mobile sheet and aria-label/title preserve accessible meaning. */
  #livechart-share-btn,
  #livechart-fullscreen-btn{ width:30px; min-width:30px; padding:3px; }
  #livechart-share-btn .toolbar-btn__label,
  #livechart-fullscreen-btn .toolbar-btn__label{ display:none !important; }

  /* Mild active state for utility toggles: visibly on, without the bright
     amber treatment used by primary actions. */
  #livechart-autoscroll-btn.toolbar-btn--active,
  #livechart-draw-visibility-btn.toolbar-btn--active{
    color:var(--mute); background:rgba(255,200,87,.055);
    border-color:rgba(255,200,87,.25); box-shadow:none;
  }
  #livechart-autoscroll-btn.toolbar-btn--active:hover,
  #livechart-draw-visibility-btn.toolbar-btn--active:hover{
    color:var(--ink); background:rgba(255,200,87,.085);
    border-color:rgba(255,200,87,.34);
  }
  #livechart-autoscroll-btn.toolbar-btn--active .livechart-autoscroll-btn__dot{
    background:var(--pulse); opacity:.7; box-shadow:none;
  }

  /* First compression step keeps the descriptive controls but removes the
     two longest labels. Every action remains directly clickable. */
  .livechart-card--desktop-condensed #livechart-teleport-btn,
  .livechart-card--desktop-condensed #livechart-draw-visibility-btn{
    width:30px; min-width:30px; padding:3px;
  }
  .livechart-card--desktop-condensed #livechart-teleport-btn .toolbar-btn__label,
  .livechart-card--desktop-condensed #livechart-draw-visibility-btn .toolbar-btn__label{
    display:none !important;
  }
  .livechart-card--desktop-condensed .livechart-toolbar .tape-toolbar__select{ padding-left:3px; padding-right:3px; }

  /* Tight resizable desktop cards become icon-forward rather than wrapping.
     Mobile starts at 640px and continues to use the labelled More sheet. */
  .livechart-card--desktop-tight .livechart-overflow-panel > .toolbar-btn,
  .livechart-card--desktop-tight .livechart-overflow-panel > .filter-control > .toolbar-btn{
    width:30px; min-width:30px; padding:3px;
  }
  .livechart-card--desktop-tight .livechart-overflow-panel .toolbar-btn__label{ display:none !important; }
  .livechart-card--desktop-tight #livechart-symbol-select{ max-width:88px; }
  .livechart-card--desktop-tight #livechart-tf-select{ max-width:64px; }
}
@media (max-width:640px){
  /* .livechart-overflow's immediate parent (.livechart-controls-group)
     is otherwise sized to its content — .livechart-overflow's own
     width:100% below was only ever 100% of that narrow parent, not of
     the toolbar row, so the button stayed hugging the right edge
     instead of becoming its own row. */
  .livechart-toolbar .livechart-controls-group{
    flex:1 0 calc(100% - 40px);
    width:auto;
    min-width:0;
    margin-left:0;
  }
  .livechart-overflow{
    display:flex; position:relative;
    width:100%;
    margin-left:0;
    margin-top:4px;
    /* Full-width bar of its own, same as .exch-toolbar-row__toggle above —
       a border-top here reads as the same "separate control" cue the
       terminal's toggle gets from its container's border-bottom, without
       relying on being squeezed against the chart-type icon group. */
    border-left:none;
    border-top:1px solid var(--line);
    padding-left:0;
    padding-top:4px;
  }
  .livechart-overflow-btn{
    display:flex; align-items:center; justify-content:center; gap:6px;
    width:100%;
    padding:4px 8px;
    font-family:var(--font-mono); font-size:11px; font-weight:600;
    letter-spacing:.04em; text-transform:uppercase;
    color:var(--mute);
    background:transparent;
    border:none;
    cursor:pointer;
  }
  .livechart-overflow-btn:hover{ color:var(--ink); }
  .livechart-overflow-btn__chevron{ font-size:10px; line-height:1; transition:transform .15s ease; }
  .livechart-overflow-btn[aria-expanded="true"]{ color:var(--signal); }
  .livechart-overflow-btn[aria-expanded="true"] .livechart-overflow-btn__chevron{ transform:rotate(180deg); }
  .livechart-toolbar > .tape-toolbar__group--right{
    flex:0 0 32px;
    align-self:stretch;
    margin:4px 0 0;
    padding-top:4px;
    border-top:1px solid var(--line);
  }
  #livechart-add-second-btn{
    width:32px;
    min-width:32px;
    height:100%;
    min-height:27px;
    padding:3px;
  }
  .livechart-overflow-panel{ display:none; }
  .livechart-overflow-panel[hidden]{ display:none !important; }
  .livechart-overflow-panel:not([hidden]){ display:flex; }
  .livechart-overflow-panel .toolbar-btn{
    width:100%; justify-content:flex-start;
  }
  .livechart-overflow-panel .toolbar-btn__label{ display:inline; }
  .livechart-overflow-panel .filter-control.livechart-indicator-control{ width:100%; }
  .livechart-overflow-panel .filter-control.livechart-indicator-control > .toolbar-btn{ width:100%; }
  .livechart-overflow-panel .livechart-indicator-panel{
    position:static; width:100%; margin-top:4px;
  }
  .livechart-overflow-panel .filter-control.livechart-layout-control{ width:100%; }
  .livechart-overflow-panel .filter-control.livechart-layout-control > .toolbar-btn{ width:100%; }
  .livechart-overflow-panel .livechart-layout-panel{
    position:static; width:100%; margin-top:4px;
  }
}
.livechart-indicator-control{ position:relative; }
.livechart-indicator-panel{
  width:min(330px, calc(100vw - 24px));
  max-height:min(72vh, 620px); overflow:auto;
  top:calc(100% + 6px); right:0; left:auto;
}
/* Full Trading Hub fullscreen creates independently scrollable terminal
   columns. Keep the Indicators menu out of the sidebar's overflow/stacking
   context while that larger terminal is fullscreen. A fixed, centered panel
   stays entirely inside the fullscreen viewport and above every terminal
   card. Normal chart and per-chart fullscreen behavior are unchanged. */
.live-term--fullscreen .livechart-indicator-panel:not([hidden]){
  position:fixed !important;
  top:50% !important;
  left:50% !important;
  right:auto !important;
  transform:translate(-50%,-50%) !important;
  width:min(360px, calc(100vw - 24px)) !important;
  max-height:min(80dvh, 620px) !important;
  margin:0 !important;
  box-sizing:border-box;
  z-index:320 !important;
  overscroll-behavior:contain;
  box-shadow:0 20px 60px rgba(0,0,0,.62);
}
.livechart-indicator-panel .filter-panel__checkbox{ cursor:pointer; }
/* Oscillator/volume rows get a second control — a small pill that flips
   between "Pane" (own strip below the chart, the long-standing behavior)
   and "Chart" (drawn as a translucent band directly inside the price
   chart). Kept compact since it sits inline with an already-narrow
   checkbox label. */
.livechart-indicator-panel .filter-panel__row{
  display:flex; align-items:center; justify-content:space-between; gap:6px;
}
.livechart-indicator-panel .filter-panel__row .filter-panel__checkbox{ flex:1; min-width:0; }
.livechart-indicator-close{ display:none; }
.livechart-indicator-backdrop[hidden]{ display:none !important; }
@media (max-width:640px){
  body.th-indicator-sheet-open{ overflow:hidden; }
  .livechart-indicator-backdrop{
    position:fixed; inset:0; z-index:1090;
    background:rgba(0,0,0,.72); backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px);
  }
  .livechart-indicator-panel.livechart-indicator-panel--mobile-sheet{
    position:fixed !important;
    top:auto !important; right:10px !important; bottom:max(10px,env(safe-area-inset-bottom)) !important; left:10px !important;
    z-index:1100 !important;
    display:block !important;
    width:auto !important; max-width:none !important;
    max-height:calc(100dvh - 20px) !important;
    margin:0 !important; padding:0 12px 14px !important;
    overflow:auto !important; overscroll-behavior:contain;
    border:1px solid var(--line) !important;
    background:var(--panel) !important;
    box-shadow:0 24px 70px rgba(0,0,0,.7) !important;
  }
  .livechart-indicator-panel--mobile-sheet .filter-panel__head{
    position:sticky; top:0; z-index:2;
    display:flex; align-items:center; justify-content:space-between;
    min-height:48px; margin:0 -12px 8px; padding:0 12px;
    border-bottom:1px solid var(--line); background:var(--surface-header);
  }
  .livechart-indicator-panel--mobile-sheet .filter-panel__head strong{
    color:var(--ink); font:700 13px/1.2 var(--font-mono); letter-spacing:.04em; text-transform:uppercase;
  }
  .livechart-indicator-panel--mobile-sheet .livechart-indicator-close{
    display:inline-grid; place-items:center; width:40px; height:40px; padding:0;
    border:0; background:transparent; color:var(--mute); font-size:25px; line-height:1; cursor:pointer;
  }
  .livechart-indicator-panel--mobile-sheet .livechart-indicator-close:focus-visible{
    outline:2px solid var(--signal); outline-offset:-3px; color:var(--ink);
  }
  .livechart-indicator-panel--mobile-sheet .filter-panel__group{ padding:7px 0 3px; }
  .livechart-indicator-panel--mobile-sheet .filter-panel__group + .filter-panel__group{ border-top:1px solid var(--line-soft); }
  .livechart-indicator-panel--mobile-sheet .filter-panel__group-label{
    display:block; padding:4px 2px 7px; color:var(--mute-dim);
    font:700 10px/1.2 var(--font-mono); letter-spacing:.08em; text-transform:uppercase;
  }
  .livechart-indicator-panel--mobile-sheet .filter-panel__row,
  .livechart-indicator-panel--mobile-sheet > .filter-panel__checkbox{
    min-height:44px; margin:0; padding:5px 2px; border-bottom:1px solid var(--line-soft);
  }
  .livechart-indicator-panel--mobile-sheet > .filter-panel__checkbox{ display:flex; align-items:center; }
  .livechart-indicator-panel--mobile-sheet .filter-panel__checkbox{
    color:var(--ink); font-size:13px; line-height:1.3; cursor:pointer;
  }
  .livechart-indicator-panel--mobile-sheet .filter-panel__checkbox input{
    width:18px; height:18px; margin:0 9px 0 0; accent-color:var(--signal);
  }
  .livechart-indicator-panel--mobile-sheet .livechart-ind-settings-tools{ gap:8px; }
  .livechart-indicator-panel--mobile-sheet .livechart-ind-summary{ max-width:120px; font-size:10.5px; }
  .livechart-indicator-panel--mobile-sheet .livechart-ind-settings-btn,
  .livechart-indicator-panel--mobile-sheet .livechart-ind-place{ min-width:38px; min-height:38px; }
  .livechart-indicator-panel--mobile-sheet .livechart-ind-field{ grid-template-columns:minmax(0,1fr) 104px; min-height:45px; }
  .livechart-indicator-panel--mobile-sheet .livechart-ind-field input{ height:38px; font-size:16px; }
  .livechart-indicator-panel--mobile-sheet .livechart-ind-editor__actions{ position:sticky; bottom:0; padding-top:8px; background:var(--panel); }
  .livechart-indicator-panel--mobile-sheet .livechart-ind-action{ min-height:42px; }
}
.livechart-ind-settings-tools{
  display:flex; align-items:center; justify-content:flex-end; gap:5px; flex:none;
}
.livechart-ind-summary{
  max-width:94px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  color:var(--mute-dim); font:10px/1.2 var(--font-mono);
}
.livechart-ind-settings-btn{
  display:inline-grid; place-items:center; width:25px; height:25px; padding:0;
  border:1px solid var(--line-soft); border-radius:5px; background:transparent;
  color:var(--mute); font-size:13px; line-height:1; cursor:pointer;
  transition:border-color .15s ease, color .15s ease, background .15s ease;
}
.livechart-ind-settings-btn:hover,
.livechart-ind-settings-btn:focus-visible{
  color:var(--signal); border-color:rgba(255,200,87,.65); background:var(--signal-soft); outline:none;
}
.livechart-indicator-panel--editing > :not(.livechart-ind-editor){ display:none !important; }
.livechart-ind-editor{ min-width:0; padding:2px; }
.livechart-ind-editor[hidden]{ display:none; }
.livechart-ind-editor__head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:4px; }
.livechart-ind-editor__head strong{ color:var(--ink); font-size:13px; letter-spacing:.01em; }
.livechart-ind-editor__close{
  width:28px; height:28px; border:0; border-radius:5px; background:transparent;
  color:var(--mute); font-size:20px; cursor:pointer;
}
.livechart-ind-editor__close:hover{ color:var(--ink); background:var(--panel-hover); }
.livechart-ind-editor__hint{ margin:0 0 10px; color:var(--mute-dim); font-size:10.5px; line-height:1.4; }
.livechart-ind-editor__form{ display:grid; gap:8px; }
.livechart-ind-field{ display:grid; grid-template-columns:minmax(0, 1fr) 92px; align-items:center; gap:12px; }
.livechart-ind-field__label{ color:var(--mute); font-size:11.5px; line-height:1.25; }
.livechart-ind-field input{
  width:100%; min-width:0; height:31px; box-sizing:border-box; padding:4px 7px;
  border:1px solid var(--line-soft); border-radius:5px; background:var(--void);
  color:var(--ink); font:11.5px var(--font-mono); text-align:right;
}
.livechart-ind-field input:focus{ outline:none; border-color:var(--signal); box-shadow:0 0 0 2px var(--signal-soft); }
.livechart-ind-field input[aria-invalid="true"]{ border-color:var(--danger); }
.livechart-ind-editor__error{ margin:0; color:var(--danger); font-size:10.5px; line-height:1.35; }
.livechart-ind-editor__error[hidden]{ display:none; }
.livechart-ind-editor__actions{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:6px; margin-top:3px; }
.livechart-ind-action{
  min-height:32px; border:1px solid var(--line-soft); border-radius:5px;
  font-size:11px; font-weight:700; cursor:pointer;
}
.livechart-ind-action--secondary{ background:transparent; color:var(--mute); }
.livechart-ind-action--secondary:hover{ color:var(--ink); background:var(--panel-hover); }
.livechart-ind-action--primary{ background:var(--signal); border-color:var(--signal); color:var(--void); }
.livechart-ind-action:disabled{ opacity:.45; cursor:not-allowed; }
.livechart-ind-place{
  flex:none; border:1px solid var(--line-soft); background:transparent;
  color:var(--mute-dim); font-size:10.5px; line-height:1;
  padding:3px 7px; border-radius:20px; cursor:pointer;
  transition:color .15s ease, border-color .15s ease, background .15s ease;
}
.livechart-ind-place:hover{ color:var(--ink); border-color:var(--mute-dim); }
.livechart-layout-control{ position:relative; }
.livechart-layout-panel{
  width:260px;
  top:calc(100% + 6px); right:0; left:auto;
}
.livechart-layout-panel .settings-category__hint{ margin:2px 0 8px; }
.livechart-layout-panel .settings-row{ padding:0 0 8px; }
.livechart-layout-panel__actions{
  display:flex; gap:6px;
}
.livechart-layout-panel__actions .toolbar-btn{ flex:1; justify-content:center; }
.livechart-export-panel__actions{
  display:flex; gap:6px;
}
.livechart-export-panel__actions .toolbar-btn{ flex:1; justify-content:center; }
.livechart-ind-place[data-placement="overlay"]{
  color:var(--void); background:var(--signal); border-color:var(--signal);
}
/* Replay mode is a UI state, not a market signal, so it uses the shared
   .toolbar-btn--active amber styling (see line ~293) instead of red —
   red is reserved for price/trade direction elsewhere in the terminal. */

/* ---------- Replay Mode: compact scrub/play bar ---------- */
.livechart-replay-bar{
  display:flex; align-items:center; gap:6px;
  margin-bottom:8px;
  padding:4px 8px;
  background:var(--signal-soft);
  border:1px solid rgba(255,200,87,.35);
  border-radius:6px;
}
.livechart-replay-bar[hidden]{ display:none; }
.livechart-replay-bar .toolbar-btn--sq{ padding:2px 7px; font-size:12.5px; flex:0 0 auto; }
.livechart-replay-slider{
  flex:1; min-width:0;
  accent-color:var(--signal);
  height:4px;
  cursor:pointer;
}
.livechart-replay-time{
  font-family:var(--font-mono); font-size:11.5px; color:var(--mute);
  white-space:nowrap;
}
.livechart-replay-speed{ padding:2px 4px; font-size:12.5px; flex:0 0 auto; }

.chart-share-modal{
  position:fixed; inset:0; z-index:970;
  display:none; align-items:center; justify-content:center;
  padding:20px;
}
.chart-share-modal.open{ display:flex; }
.chart-share-modal__backdrop{
  position:absolute; inset:0;
  background:rgba(3,3,3,0.78); backdrop-filter:blur(4px);
}
html.chart-share-lock{ overflow:hidden; }
.chart-share-modal__panel{
  position:relative; width:100%; max-width:480px; max-height:88vh;
  background:var(--panel); border:1px solid var(--line);
  box-shadow:0 24px 70px rgba(0,0,0,.55);
  display:flex; flex-direction:column; gap:10px;
  padding:16px; overflow-y:auto;
}
.chart-share-modal__close{
  position:absolute; top:8px; right:8px; width:28px; height:28px;
  display:flex; align-items:center; justify-content:center;
  background:transparent; border:1px solid var(--line); color:var(--mute);
  font-size:18px; line-height:1; cursor:pointer;
}
.chart-share-modal__close:hover{ color:var(--ink); border-color:var(--mute-dim); }
.chart-share-modal__preview{
  border:1px solid var(--line); background:var(--void);
  display:flex; align-items:center; justify-content:center; overflow:hidden;
}
.chart-share-modal__img{ display:block; width:100%; height:auto; }
.chart-share-modal__label{
  font:600 11px var(--font-mono); color:var(--mute); text-transform:uppercase; letter-spacing:.04em;
}
.chart-share-modal__input{
  width:100%; padding:9px 10px; font:14px var(--font-body); color:var(--ink);
  background:var(--panel-hover); border:1px solid var(--line); border-radius:var(--radius-sm);
}
.chart-share-modal__input:focus{ outline:none; border-color:var(--signal); }
.chart-share-modal__actions{ display:flex; gap:8px; margin-top:2px; }
.chart-share-modal__btn{
  flex:1; padding:10px 12px; font:600 13px var(--font-mono); cursor:pointer;
  background:var(--panel-hover); border:1px solid var(--line); color:var(--ink);
  transition:border-color .15s ease, color .15s ease;
}
.chart-share-modal__btn:hover{ border-color:var(--mute-dim); }
.chart-share-modal__btn--primary{
  background:var(--signal-soft); border-color:var(--signal); color:var(--signal);
}
.chart-share-modal__btn--primary:hover{ background:var(--signal); color:var(--void); }
.chart-share-modal__status{
  font:600 12px var(--font-mono); color:var(--pulse); margin:0; text-align:center;
}
.chart-share-modal__status--error{ color:var(--danger); }
.chart-share-modal__hint{
  font:12px var(--font-body); color:var(--mute-dim); margin:0; line-height:1.4;
}
.chart-import-choice__options{ display:flex; flex-direction:column; gap:8px; }
.chart-import-choice__option{
  display:flex; flex-direction:column; gap:3px; text-align:left;
  padding:12px 14px; cursor:pointer;
  background:var(--panel-hover); border:1px solid var(--line); color:var(--ink);
  transition:border-color .15s ease, background .15s ease;
}
.chart-import-choice__option:hover{ border-color:var(--signal); background:var(--signal-soft); }
.chart-import-choice__option-title{ display:block; font:700 14px var(--font-mono); color:var(--ink); }
.chart-import-choice__option-desc{ display:block; font:12px var(--font-body); color:var(--mute); line-height:1.4; margin-top:2px; }
@media (max-width:520px){
  .chart-share-modal{ padding:0; align-items:flex-end; }
  .chart-share-modal__panel{ max-width:none; max-height:92vh; border-left:0; border-right:0; border-bottom:0; }
}

/* Stats strip under the chart header — 24h high, low, current price + %
   change, volume, and open interest, readable at a glance without needing
   to check the separate Market Overview card. */
.livechart-ticker{
  margin-bottom:6px;
  padding:5px 8px 4px;
  background:var(--void);
  border:1px solid var(--line-soft);
  border-radius:6px;
}
.livechart-ticker__stats{
  display:flex; align-items:stretch;
  gap:1px;
  background:var(--line-soft);
  border:1px solid var(--line-soft);
  border-radius:5px;
  overflow:hidden;
}
/* Wraps the 24H+Low cells and the Vol+OI cells so they can be relocated
   as a unit onto the chart overlay on mobile (see wireLiveChartMobileStats
   in core.js) without disturbing desktop layout — display:contents makes
   the wrapper invisible to layout, so its .livechart-ticker__stat children
   act as direct flex items of .livechart-ticker__stats, same as if there
   were no wrapper at all. */
.livechart-ticker__extra{ display:contents; }
.livechart-ticker__stat{
  flex:1; min-width:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:1px;
  padding:3px 3px;
  background:var(--panel, #12151C);
}
.livechart-ticker__stat-label{
  font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--mute-dim);
  white-space:nowrap;
  display:inline-flex; align-items:center;
}
.livechart-ticker__stat-value{
  font-family:var(--font-mono); font-size:14px; font-weight:600;
  color:var(--ink);
  white-space:nowrap;
}
/* The 24H/Low cells double as a compact range read, same red/green
   convention the rest of the terminal uses for high/low reference points. */
.livechart-ticker__stat:nth-child(1) .livechart-ticker__stat-value{ color:var(--pulse); }
.livechart-ticker__stat:nth-child(2) .livechart-ticker__stat-value{ color:var(--danger); }
/* The PRICE cell reads as too cramped at the base 1px stat gap — give it
   a bit more room between the label and the value than the other
   (deliberately tight) ticker cells, in both the stacked (default) and
   inline (mobile, see below) layouts. */
.livechart-ticker__stat--price{ gap:6px; }
/* Price + % change cell — same font-mono treatment as the other stat
   values, just two spans side by side instead of one. */
.livechart-ticker__pricechg{
  display:flex; align-items:baseline; gap:7px; min-width:0;
}
.livechart-ticker__stat--price .livechart-ticker__price{
  font-family:var(--font-mono); font-size:14px; font-weight:600;
  line-height:1.1; color:var(--ink); white-space:nowrap;
}
.livechart-ticker__price.pos{ color:var(--pulse); }
.livechart-ticker__price.neg{ color:var(--danger); }
.livechart-ticker__stat--price .livechart-ticker__change{
  font-family:var(--font-mono); font-size:11px; font-weight:600;
  color:var(--mute-dim); white-space:nowrap;
}
.livechart-ticker__change.pos{ color:var(--pulse); }
.livechart-ticker__change.neg{ color:var(--danger); }

/* On phones, 24H/Low/Vol/OI move onto the chart itself (see
   #livechart-chart-stats below and wireLiveChartMobileStats in core.js) —
   the ticker row is left holding just Price+change, so it can breathe
   instead of squeezing 5 cells into one line. */
@media (max-width:640px){
  .livechart-ticker{ margin-bottom:4px; padding:4px 8px; }
  .livechart-ticker__stats{ display:flex; }
  /* Safety net: if JS hasn't relocated them yet (or is unavailable),
     hide 24H/Low/Vol/OI here rather than let them crowd the row —
     they belong on the chart overlay at this width, not in the ticker. */
  .livechart-ticker__extra{ display:none; }
  .livechart-ticker__stat--price{
    flex:1; width:100%;
    flex-direction:row; align-items:baseline; justify-content:center;
    gap:8px;
  }
  .livechart-ticker__stat--price .livechart-ticker__stat-label{ font-size:10px; }
  .livechart-ticker__pricechg{ gap:6px; }
  .livechart-ticker__stat--price .livechart-ticker__price{ font-size:15px; }
  .livechart-ticker__stat--price .livechart-ticker__change{ font-size:11px; }
}

/* ---------- thin stats strip: 24H / Low / Vol / OI (mobile only) ----------
   Relocated here from the ticker row by wireLiveChartMobileStats() in
   core.js. No longer an on-chart overlay — it now sits in normal flow
   right under the toolbar (below the "More" button on phones), as its
   own thin full-width strip above the canvas. Kept at the same small
   type size the values already rendered at on the chart overlay, just
   moved off the canvas so it doesn't cover price action; hairline
   top/bottom rules mark it as its own compact row without spending
   more than a couple of pixels of padding on it. */
.livechart-chart-stats{
  display:none;
}
@media (max-width:640px){
  .livechart-chart-stats{
    display:flex;
    flex-direction:row;
    align-items:baseline;
    justify-content:center;
    flex-wrap:wrap;
    gap:2px 14px;
    padding:3px 0;
    margin:-2px 0 6px;
    border-top:1px solid var(--line);
    border-bottom:1px solid var(--line);
  }
}
/* display:contents so all four stats become direct children of the strip
   above (24H, Low, Vol, OI each their own item) instead of two grouped
   pairs — keeps them flowing as one single-line row. */
.livechart-chart-stats .livechart-ticker__extra{
  display:contents;
}
.livechart-chart-stats .livechart-ticker__stat{
  display:flex; flex-direction:row; align-items:baseline; gap:3px;
  padding:0; background:transparent;
}
.livechart-chart-stats .livechart-ticker__stat-label{
  font-size:6.5px; color:var(--mute-dim);
}
.livechart-chart-stats .livechart-ticker__stat-value{
  font-size:7.5px; color:var(--ink); font-family:var(--font-mono);
}
.livechart-chart-stats .livechart-ticker__stat:nth-child(1) .livechart-ticker__stat-value,
.livechart-chart-stats #livechart-ticker-high{ color:var(--pulse); }
.livechart-chart-stats #livechart-ticker-low{ color:var(--danger); }
.livechart-chart-stats .metric-tip{ display:none; }

/* Chart/Volume is a phone-only view switch. Keep it out of desktop layout
   even before JavaScript initialises, and render it as one compact segmented
   control on phones instead of two unstyled adjacent words. */
.livechart-view-tabs{ display:none; }
@media (max-width:760px){
  .livechart-view-tabs:not([hidden]){
    display:grid; grid-template-columns:1fr 1fr; gap:2px;
    width:100%; margin:3px 0 4px; padding:2px;
    border:1px solid var(--line-soft); border-radius:5px;
    background:var(--void);
  }
  .livechart-view-tab{
    min-height:28px; padding:4px 10px;
    border:0; border-radius:3px; background:transparent;
    color:var(--mute); cursor:pointer;
    font:700 10px/1 var(--font-mono); letter-spacing:.055em; text-transform:uppercase;
  }
  .livechart-view-tab:hover,.livechart-view-tab:focus-visible{ color:var(--ink); outline:none; }
  .livechart-view-tab--active{ color:var(--signal); background:var(--signal-soft); }
}

@media (max-width:360px){
  .livechart-ticker__stat-label{ font-size:8.5px; }
  .livechart-ticker__stat-value,
  .livechart-ticker__stat--price .livechart-ticker__price{ font-size:10.5px; }
}

/* ---------- drawing tools: side panel (desktop) ----------
   On desktop the trend-line / horizontal-line / vertical-line tools sit in
   a vertical toolbar beside the chart (TradingView-style) instead of in the
   top toolbar's "More" popover. #livechart-chart-row is the flex row that
   holds this sidebar plus .livechart-canvas-wrap; its --side-left/--side-right
   modifier (toggled by the ⇄ button, remembered per-browser) decides which
   edge the sidebar renders on via `order`. Below 640px there's no room for a
   side column, so wireDrawToolbarPlacement() in live-chart.js re-parents the
   same three <button> elements into #livechart-draw-mobile-slot inside the
   existing top-toolbar "More" popover instead of duplicating them. */
.livechart-chart-row{ position:relative; display:flex; align-items:stretch; }
.livechart-chart-row .livechart-canvas-wrap{ flex:1; min-width:0; }
.livechart-draw-toolbar{
  display:flex; flex-direction:column; align-items:center;
  flex:0 0 var(--draw-rail-width,72px); width:var(--draw-rail-width,72px); gap:4px; padding:6px 0;
  background:var(--panel); border:1px solid var(--line-soft);
}
.livechart-draw-toolbar[hidden]{ display:none !important; }
.livechart-draw-visibility-btn:not(.toolbar-btn--active) .toolbar-btn__icon{ opacity:.58; }
.livechart-draw-reveal-btn{
  position:absolute; top:8px; left:4px; z-index:9;
  box-sizing:border-box; max-width:calc(100% - 8px);
  height:30px; display:flex; align-items:center; gap:5px;
  padding:0 8px 0 6px;
  border:1px solid rgba(255,200,87,.55); border-radius:4px;
  background:rgba(12,14,18,.96); color:var(--signal);
  box-shadow:0 5px 16px rgba(0,0,0,.42);
  cursor:pointer; font:700 9px/1 var(--font-mono); white-space:nowrap;
}
.livechart-draw-reveal-btn[hidden]{ display:none !important; }
.livechart-draw-reveal-btn:hover,
.livechart-draw-reveal-btn:focus-visible{ background:var(--signal-soft); outline:none; }
.livechart-draw-reveal-btn .th-draw-icon{ width:16px !important; min-width:16px; height:16px !important; }
.livechart-chart-row--side-right .livechart-draw-reveal-btn{
  left:auto; right:4px; padding:0 6px 0 8px;
}
.livechart-chart-row--side-left .livechart-draw-toolbar{ order:0; border-right:none; }
.livechart-chart-row--side-right .livechart-draw-toolbar{ order:1; border-left:none; }
.livechart-draw-toolbar .toolbar-btn{ width:22px; height:22px; padding:0; justify-content:center; }
.livechart-draw-toolbar__spacer{ flex:1; }
.livechart-draw-toolbar__side-btn{
  flex:0 0 auto;
  width:22px; height:22px;
  display:flex; align-items:center; justify-content:center;
  background:transparent; border:1px solid var(--line-soft); border-radius:4px;
  color:var(--mute); cursor:pointer;
}
.livechart-draw-toolbar__side-btn:hover{ color:var(--ink); border-color:var(--line); }
.livechart-chart-row--side-right .livechart-draw-toolbar__side-btn svg{ transform:scaleX(-1); }
/* display:contents so, on mobile, the trend-line/h-line/v-line buttons
   re-parented into this slot (see wireDrawToolbarPlacement() in
   live-chart.js) lay out exactly like any other direct child of
   .livechart-overflow-panel — same full-width row treatment share/
   fullscreen already get there — rather than as a nested flex row. */
.livechart-draw-mobile-slot{ display:contents; }
@media (max-width:640px){
  .livechart-draw-toolbar{ display:none; }
}
.livechart-card--compact-tools .livechart-draw-toolbar:not(.is-mobile){ display:none; }

/* ---------- professional shared drawing suite ---------- */
.th-drawing-overlay{
  position:absolute; inset:0; z-index:2;
  display:block; pointer-events:none;
}
.th-draw-object-menu{
  position:absolute; z-index:7;
  display:flex; align-items:stretch; gap:2px;
  max-width:calc(100% - 8px); box-sizing:border-box;
  padding:4px; border:1px solid var(--line); border-radius:6px;
  background:rgba(13,15,19,.98); box-shadow:0 10px 28px rgba(0,0,0,.52);
  pointer-events:auto; user-select:none;
}
.th-draw-object-menu[hidden],.th-draw-object-menu [hidden]{ display:none !important; }
.th-draw-object-menu button{
  min-width:52px; height:38px; box-sizing:border-box;
  display:flex; align-items:center; justify-content:center; gap:5px;
  padding:0 8px; border:1px solid transparent; border-radius:4px;
  background:transparent; color:var(--ink); cursor:pointer;
  font:700 9px/1 var(--font-mono); white-space:nowrap;
}
.th-draw-object-menu button:hover,.th-draw-object-menu button:focus-visible{
  color:var(--signal); border-color:rgba(255,200,87,.42); background:rgba(255,200,87,.09); outline:none;
}
.th-draw-object-menu button.is-active{ color:var(--signal); background:rgba(255,200,87,.09); }
.th-draw-object-menu button:disabled{ opacity:.35; cursor:default; }
.th-draw-object-menu .th-draw-icon{ width:18px !important; min-width:18px; height:18px !important; }
.th-draw-object-menu__delete{ color:var(--danger) !important; }
.th-draw-object-menu__delete:hover,.th-draw-object-menu__delete:focus-visible{
  border-color:rgba(255,91,110,.5) !important; background:rgba(255,91,110,.1) !important;
}
.livechart-draw-toolbar.th-draw-toolbar{
  position:relative; display:flex; flex:0 0 var(--draw-rail-width,72px); width:var(--draw-rail-width,72px);
  box-sizing:border-box; padding:3px 2px; overflow:visible;
  z-index:8;
}
.th-draw-mobile-toggle{ display:none; }
.th-draw-mobile-head{ display:none; }
.th-draw-toolbar__body{
  width:100%; display:flex; flex-direction:column; align-items:center; gap:2px;
}
.th-draw-toolbar__body--shell{
  min-height:100%; justify-content:center; gap:8px;
  opacity:.72; pointer-events:none;
}
.th-draw-toolbar__body--shell small{
  max-width:62px; color:var(--mute); text-align:center;
  font:700 8px/1.25 var(--font-mono); letter-spacing:.02em;
}
.th-draw-shell-spinner{
  width:17px; height:17px; box-sizing:border-box;
  border:2px solid var(--line); border-top-color:var(--signal);
  border-radius:50% !important;
  animation:th-draw-shell-spin .8s linear infinite;
}
@keyframes th-draw-shell-spin{ to{ transform:rotate(360deg); } }
.th-draw-group{ position:relative; width:100%; display:flex; justify-content:center; }
.th-draw-category,.th-draw-action,.th-draw-mobile-toggle{
  position:relative; box-sizing:border-box; border:1px solid transparent; border-radius:3px;
  background:transparent; color:var(--ink); font:700 11px/1 var(--font-mono);
  cursor:pointer; -webkit-tap-highlight-color:transparent;
}
.th-draw-category,.th-draw-action{ width:var(--draw-button-width,64px); height:var(--draw-button-height,42px); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; padding:2px 1px; }
.th-draw-category > span,.th-draw-action > span{ display:block; line-height:0; pointer-events:none; }
.th-draw-category small,.th-draw-action small{ display:block; max-width:calc(var(--draw-button-width,64px) - 4px); overflow:hidden; color:var(--mute); font:700 var(--draw-label-size,8px)/1 var(--font-mono); letter-spacing:.015em; text-overflow:ellipsis; white-space:nowrap; pointer-events:none; }
.th-draw-icon{ display:block !important; width:var(--draw-icon-size,24px) !important; min-width:var(--draw-icon-size,24px); height:var(--draw-icon-size,24px) !important; color:inherit; overflow:visible; pointer-events:none; }
.th-draw-icon path,.th-draw-icon circle,.th-draw-icon rect,.th-draw-icon ellipse{ fill:none !important; stroke:currentColor !important; vector-effect:non-scaling-stroke; }
.th-draw-category:hover,.th-draw-action:hover,.th-draw-category.is-active,.th-draw-action.is-active,
.th-draw-category[aria-expanded="true"],.th-draw-toolbar [data-tool].is-active{
  color:var(--signal); border-color:rgba(255,200,87,.42); background:rgba(255,200,87,.09);
}
.th-draw-category:hover small,.th-draw-action:hover small,.th-draw-category[aria-expanded="true"] small,.th-draw-action.is-active small{ color:var(--signal); }
.th-draw-action:disabled{ opacity:.25; cursor:default; }
.th-draw-category i{
  position:absolute; right:1px; bottom:1px; width:0; height:0;
  border-left:3px solid transparent; border-top:3px solid currentColor; opacity:.6;
}
.th-draw-divider{ width:18px; height:1px; margin:1px 0; background:var(--line); flex:none; }
.th-draw-flyout{
  display:none; position:absolute; left:var(--draw-flyout-offset,70px); top:-3px; z-index:30;
  width:300px; max-height:480px; overflow:auto; box-sizing:border-box;
  padding:6px; border:1px solid var(--line); border-radius:5px;
  background:rgba(13,15,19,.98); box-shadow:0 12px 32px rgba(0,0,0,.48);
}
.livechart-chart-row--side-right .th-draw-flyout{ left:auto; right:var(--draw-flyout-offset,70px); }
.th-draw-group.is-open .th-draw-flyout{ display:grid; grid-template-columns:1fr; gap:2px; }
.th-draw-flyout strong{
  padding:4px 7px 6px; color:var(--mute-dim); font-size:10px;
  letter-spacing:.08em; text-transform:uppercase;
}
.th-draw-flyout button{
  min-height:36px; display:grid; grid-template-columns:40px 1fr; align-items:center;
  padding:3px 7px; border:0; border-radius:4px; background:transparent;
  color:var(--ink); text-align:left; cursor:pointer; font-size:12.5px;
}
.th-draw-flyout button:hover,.th-draw-flyout button.is-active{ background:rgba(255,255,255,.055); color:var(--signal); }
.th-draw-flyout button:disabled{ opacity:.3; cursor:default; }
.th-draw-flyout button b{ display:grid; place-items:center; color:var(--signal); }
.th-draw-flyout button b .th-draw-icon{ width:21px; height:21px; }
.th-draw-style-panel{
  position:absolute; z-index:31; left:var(--draw-rail-width,72px); bottom:0; width:280px; box-sizing:border-box;
  padding:9px; border:1px solid var(--line); border-radius:5px;
  background:rgba(13,15,19,.98); box-shadow:0 12px 32px rgba(0,0,0,.48);
}
.livechart-chart-row--side-right .th-draw-style-panel{ left:auto; right:var(--draw-rail-width,72px); }
.th-draw-style-panel__head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:7px; color:var(--ink); font-size:11px; }
.th-draw-style-panel__head button{ width:22px; height:22px; padding:0; border:0; background:transparent; color:var(--mute); cursor:pointer; font-size:17px; }
.th-draw-style-panel label{ display:grid; grid-template-columns:62px 1fr; align-items:center; gap:7px; min-height:30px; color:var(--mute); font-size:10px; }
.th-draw-style-panel input[type="color"]{ width:100%; height:24px; padding:1px; border:1px solid var(--line); background:var(--void); }
.th-draw-style-panel input[type="range"]{ width:100%; accent-color:var(--signal); }
.th-draw-width-control{ display:grid; grid-template-columns:minmax(0,1fr) 58px; align-items:center; gap:7px; min-width:0; }
.th-draw-width-control input[type="number"]{ width:58px; height:25px; box-sizing:border-box; padding:2px 5px; border:1px solid var(--line); border-radius:3px; background:var(--void); color:var(--ink); font:10px var(--font-mono); text-align:right; }
.th-draw-width-control input[type="number"]:focus{ outline:none; border-color:var(--signal); box-shadow:0 0 0 1px var(--signal-soft); }
.th-draw-style-panel select{ height:25px; border:1px solid var(--line); border-radius:3px; background:var(--void); color:var(--ink); font-size:10px; }
.th-draw-style-lock{ width:100%; min-height:34px; margin-top:6px; display:flex; align-items:center; justify-content:center; gap:7px; border:1px solid var(--line); border-radius:4px; background:var(--panel); color:var(--ink); cursor:pointer; font-size:11px; }
.th-draw-style-lock .th-draw-icon{ width:17px; height:17px; }
.th-draw-style-lock.is-active{ color:var(--signal); border-color:rgba(255,200,87,.45); }

.livechart-draw-toolbar.th-draw-toolbar.is-mobile{
    position:fixed; left:0; top:0; display:block !important; flex:0 0 0; width:0; height:0;
    padding:0; border:0; background:transparent; overflow:visible; z-index:1090;
}
/* The More sheet is the single mobile launcher. Do not render a second
   "Drawing tools" button before the actual drawing panel. */
.th-draw-toolbar.is-mobile .th-draw-mobile-toggle{ display:none !important; }
.th-draw-mobile-backdrop[hidden]{ display:none !important; }
body.th-draw-sheet-open{ overflow:hidden; }
.th-draw-mobile-backdrop{
    position:fixed; inset:0; z-index:1085; background:rgba(0,0,0,.72);
    backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px);
}
.th-draw-toolbar.is-mobile .th-draw-toolbar__body{
    display:none; position:fixed; left:10px; right:10px; bottom:max(10px,env(safe-area-inset-bottom)); z-index:1090;
    width:auto; max-height:min(70dvh,560px); overflow-y:auto; overscroll-behavior:contain; box-sizing:border-box;
    grid-template-columns:repeat(5,minmax(42px,1fr)); align-items:start; gap:5px;
    padding:0 10px 10px; border:1px solid var(--line); border-radius:12px;
    background:rgba(12,14,18,.99); box-shadow:0 24px 70px rgba(0,0,0,.7);
}
.th-draw-toolbar.is-mobile.is-open .th-draw-toolbar__body{ display:grid; }
.th-draw-toolbar.is-mobile .th-draw-mobile-head{
    position:sticky; top:0; z-index:4; grid-column:1/-1; display:flex; align-items:center; justify-content:space-between;
    min-height:50px; margin:0 -10px 5px; padding:0 10px; border-bottom:1px solid var(--line); background:var(--surface-header);
}
.th-draw-mobile-head strong{ color:var(--ink); font:700 13px/1.2 var(--font-mono); letter-spacing:.04em; text-transform:uppercase; }
.th-draw-mobile-close{
    display:inline-grid; place-items:center; width:40px; height:40px; padding:0; border:0; background:transparent;
    color:var(--mute); font-size:25px; cursor:pointer;
}
.th-draw-mobile-close:focus-visible{ outline:2px solid var(--signal); outline-offset:-3px; color:var(--ink); }
.th-draw-toolbar.is-mobile .th-draw-recent,.th-draw-toolbar.is-mobile .th-draw-group{ width:100%; }
.th-draw-toolbar.is-mobile .th-draw-category,.th-draw-toolbar.is-mobile .th-draw-action{ width:100%; height:48px; border-color:var(--line-soft); font-size:11px; }
.th-draw-toolbar.is-mobile .th-draw-divider{ grid-column:1/-1; width:100%; margin:2px 0; }
.th-draw-toolbar.is-mobile .th-draw-flyout{
    position:fixed; left:10px !important; right:10px !important; top:auto; bottom:64px;
    width:auto; max-height:52vh; grid-template-columns:repeat(2,minmax(0,1fr));
}
.th-draw-toolbar.is-mobile .th-draw-flyout strong{ grid-column:1/-1; }
.th-draw-toolbar.is-mobile .th-draw-style-panel{
    position:fixed; left:10px !important; right:10px !important; top:auto; bottom:10px;
    width:auto; max-height:70vh; overflow:auto;
}
.livechart-draw-toolbar.th-draw-toolbar.is-mobile[hidden]{ display:none !important; }

.livechart-canvas-wrap{
  position:relative;
  height:520px;
  background:var(--void);
  border:1px solid var(--line-soft);
  overflow:hidden;
}
.livechart-extreme-price{
  position:absolute; z-index:6; pointer-events:none; white-space:nowrap;
  color:var(--ink); font:700 12px/1 var(--font-mono,monospace);
  text-shadow:-1px -1px 0 var(--void),1px -1px 0 var(--void),-1px 1px 0 var(--void),1px 1px 0 var(--void),0 0 4px var(--void);
}
.livechart-extreme-price--high{ transform:translate(-50%,-100%); }
.livechart-extreme-price--low{ transform:translate(-50%,0); }
@media(max-width:640px){ .livechart-extreme-price{font-size:12.5px;} }

.livechart-canvas-wrap canvas{
  display:block; width:100%; height:100%;
  cursor:crosshair;
  /* The chart handles its own drag-to-pan and pinch-to-zoom (live-chart.js);
     without this the browser also tries to scroll/zoom the page for the
     same touch gestures, fighting the chart for them. */
  touch-action:none;
}
/* ---------- resizable chart height (drag to resize, remembered) ---------- */
.livechart-resize-handle{
  position:absolute; left:0; right:0; bottom:0; height:7px;
  cursor:row-resize;
  z-index:3;
  touch-action:none;
}
.livechart-resize-handle::after{
  content:''; position:absolute; left:0; right:0; bottom:2px; height:1px;
  background:var(--line-soft);
}
.livechart-resize-handle:hover::after,
.livechart-resize-handle--active::after{ bottom:1px; height:3px; background:var(--signal); }
.livechart-card:fullscreen .livechart-resize-handle,
.livechart-card--fullscreen .livechart-resize-handle{ display:none; }
/* ---------- top-left OHLC legend ---------- */
.livechart-topleft-overlay{
  position:absolute; top:6px; left:8px; z-index:3;
  display:flex; flex-direction:column; gap:3px;
  pointer-events:none;
}
.livechart-legend{
  display:flex; flex-wrap:wrap; gap:2px 10px;
  font-family:var(--font-mono); font-size:11.5px; color:var(--mute-dim);
  text-shadow:0 1px 2px rgba(0,0,0,.8);
}
/* Mobile: the O/H/L/C strip is otherwise a single unwrapped-looking row
   that runs straight into the shaded price-axis panel on the right (it
   already wraps via flex-wrap, but with no right boundary it wraps far
   too late, right at the axis). Stopping it short of the axis makes it
   wrap onto a second line while there's still room, instead of visually
   colliding with the price labels. 24H/Low/Vol/OI no longer render on
   the chart itself below 640px (moved into the thin .livechart-chart-stats
   strip under the toolbar instead), so this only needs to clear the
   price-axis gutter (56px on narrow phones — see chartPadR in
   live-chart.js) plus a small gap. */
@media (max-width:640px){
  .livechart-topleft-overlay{ right:62px; }
}
.livechart-legend b{ font-weight:700; color:var(--ink); }
.livechart-legend .pos{ color:var(--pulse); }
.livechart-legend .neg{ color:var(--danger); }
.livechart-marker-legend{
  position:absolute; bottom:14px; left:8px; z-index:3;
  display:flex; flex-wrap:wrap; gap:2px 9px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:700; letter-spacing:.02em;
  pointer-events:none;
  text-shadow:0 1px 2px rgba(0,0,0,.85);
}
.livechart-marker-legend .lcml-item--buy{ color:var(--pulse); }
.livechart-marker-legend .lcml-item--sell{ color:var(--danger); }
.livechart-marker-legend .lcml-item--whale{ color:var(--signal); }
.livechart-marker-legend .lcml-item--liq{ color:var(--ink); }
.livechart-loading{
  position:absolute; inset:0; z-index:3;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-size:12.5px; color:var(--mute-dim);
  background:rgba(5,5,5,.5);
  transition:opacity .2s ease;
}
.livechart-loading[hidden]{ display:none; }
.livechart-subpane{
  position:relative;
  height:64px; /* fallback for before JS applies the persisted/dragged height */
  margin-top:4px;
  background:var(--void);
  border:1px solid var(--line-soft);
  overflow:hidden;
}
.livechart-subpane canvas{ display:block; width:100%; height:100%; }
.livechart-subpane__label{
  position:absolute; top:3px; left:6px; z-index:2;
  font-family:var(--font-mono); font-size:10.5px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--mute-dim);
  pointer-events:none;
}
/* ---------- resizable subpane height (volume/RSI/MACD/Stoch/ATR — drag to
   resize, remembered, all panes share one height) ---------- */
.livechart-subpane-resize-handle{
  position:absolute; left:0; right:0; bottom:0; height:7px;
  cursor:row-resize;
  z-index:3;
  touch-action:none;
}
.livechart-subpane-resize-handle::after{
  content:''; position:absolute; left:0; right:0; bottom:2px; height:1px;
  background:var(--line-soft);
}
.livechart-subpane-resize-handle:hover::after,
.livechart-subpane-resize-handle--active::after{ bottom:1px; height:3px; background:var(--signal); }

/* Safety net: whatever goes fullscreen on this site should never fall back
   to the browser's own white default — same principle as the ticker bar
   above (hidden/clipped unless a specific rule below opens it up). */
:fullscreen{ background:var(--void); }
::backdrop{ background:var(--void); }

/* fullscreen: the card itself becomes the fullscreen element and grows to
   fill the viewport, same convention as .live-term--fullscreen for the tape */
.livechart-card:fullscreen,
.livechart-card.livechart-card--fullscreen{
  background:var(--panel); padding:12px;
  width:100%; height:100vh; height:100dvh;
  max-width:none; max-height:none; box-sizing:border-box;
  display:flex; flex-direction:column;
  overflow:hidden;
}
/* The normal chart height is persisted as an inline pixel height so users can
   resize the card. Inline styles outrank ordinary stylesheet declarations;
   without !important that saved ~267/297px height survives fullscreen and
   leaves most of the viewport black. Fullscreen owns the available height,
   while the stored inline value remains intact and automatically becomes
   active again after exit. */
.livechart-card:fullscreen .livechart-canvas-wrap,
.livechart-card--fullscreen .livechart-canvas-wrap{
  flex:1 1 0;
  width:auto;
  height:auto !important;
  min-width:0;
  min-height:0;
}
/* .livechart-canvas-wrap is now nested inside #livechart-chart-row (the
   drawing-tools sidebar + chart flex row) rather than being a direct child
   of .widget-card__body, so the row itself also needs flex:1 to claim the
   extra vertical space — .livechart-canvas-wrap's own flex:1 above then
   fills the row's height via align-items:stretch (the row's default). */
.livechart-card:fullscreen .livechart-chart-row,
.livechart-card--fullscreen .livechart-chart-row{ flex:1; min-height:0; }

/* ---------- price alerts ---------- */
/* Lives as a sibling of .livechart-canvas-wrap now (see core.js), not
   inside it — that wrap clips with `overflow:hidden`, which used to slice
   the popover in half whenever its real rendered height exceeded the
   wrap's remaining space. It's `position:absolute` against `.livechart-card`
   (see the `position:relative` rule added below) rather than
   `position:fixed` against the viewport — fixed let it drift away from the
   chart entirely. Anchoring to the card keeps it fully visible AND visually
   attached to the widget it belongs to; see positionAlarmPopover in
   live-chart.js for the clamping math. */
.livechart-card{ position:relative; }
/* ---------- secondary (2nd) chart — lightweight, independent panel opened
   from the primary chart's "+" toolbar button (live-chart-secondary.js).
   Reuses every .livechart-* class above for identical styling; only needs
   its own top margin (it sits right after the primary chart in the DOM,
   not wrapped in the primary's own head/toolbar markup) and a close btn. */
.livechart2-slot:not([hidden]){ margin-top:10px; }
.livechart2-close-btn{
  position:absolute; top:6px; right:6px; z-index:4;
}
.alarm-popover{
  position:absolute; z-index:50;
  min-width:252px; max-width:280px;
  max-height:calc(100vh - 16px); overflow-y:auto;
  background:var(--panel, #101010); border:1px solid var(--line-soft);
  border-radius:8px;
  padding:12px 14px 14px;
  box-shadow:0 10px 28px rgba(0,0,0,.55);
  font-family:var(--font-mono); font-size:11.5px; color:var(--ink);
}
.alarm-popover[hidden]{ display:none; }

.alarm-popover__header{
  display:flex; align-items:center; justify-content:space-between;
  margin-bottom:10px; padding-bottom:9px;
  border-bottom:1px solid var(--line-soft);
}
.alarm-popover__title{ font-size:12px; font-weight:700; letter-spacing:.02em; color:var(--ink); }
.alarm-popover__close{
  width:20px; height:20px; padding:0; margin:-2px -2px 0 0;
  display:flex; align-items:center; justify-content:center;
  background:transparent; border:none; border-radius:4px;
  color:var(--mute-dim); font-size:16px; line-height:1; cursor:pointer;
}
.alarm-popover__close:hover{ background:var(--void); color:var(--ink); }

.alarm-popover__field{ margin-bottom:12px; }
.alarm-popover__field:last-of-type{ margin-bottom:0; }
.alarm-popover__field > label,
.alarm-popover__field-label{
  display:block; margin-bottom:6px;
  font-size:10px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--mute-dim);
}
.alarm-popover__price-wrap{
  display:flex; align-items:stretch;
  border:1px solid var(--line-soft); border-radius:5px;
  background:var(--void); overflow:hidden;
}
.alarm-popover__price-wrap:focus-within{ border-color:var(--signal); }
.alarm-popover__price-input{
  flex:1 1 auto; min-width:0;
  background:transparent; border:none;
  color:var(--ink); font-family:var(--font-mono); font-size:12.5px; font-weight:600;
  padding:7px 8px;
}
.alarm-popover__price-input:focus{ outline:none; }
.alarm-popover__price-suffix{
  flex:0 0 auto; align-self:center;
  padding:0 9px; color:var(--mute-dim); font-size:10.5px; font-weight:700; letter-spacing:.03em;
  border-left:1px solid var(--line-soft);
}

.alarm-popover__options{ display:flex; flex-direction:column; gap:6px; }
.alarm-popover__option{
  display:flex; align-items:flex-start; gap:8px;
  padding:7px 8px; border:1px solid var(--line-soft); border-radius:5px;
  cursor:pointer; transition:border-color .12s ease, background .12s ease;
}
.alarm-popover__option:hover{ border-color:var(--mute-dim); }
.alarm-popover__option:has(input:checked){
  border-color:var(--signal); background:var(--signal-soft);
}
.alarm-popover__option input{ margin-top:2px; accent-color:var(--signal); flex:0 0 auto; }
.alarm-popover__option-text{ display:flex; flex-direction:column; gap:1px; line-height:1.3; }
.alarm-popover__option-text strong{ font-size:11.5px; font-weight:600; color:var(--ink); }
.alarm-popover__option-text small{ font-size:10px; color:var(--mute-dim); }

.alarm-popover__actions{ display:flex; gap:8px; margin-top:12px; }
.alarm-popover__btn{
  flex:1 1 0; padding:7px 8px;
  background:var(--void); border:1px solid var(--line-soft); border-radius:5px;
  color:var(--ink); font-family:var(--font-mono); font-size:11px; font-weight:600; cursor:pointer;
  transition:border-color .12s ease, opacity .12s ease;
}
.alarm-popover__btn:hover{ border-color:var(--mute-dim); }
.alarm-popover__btn--primary{ background:var(--signal); color:var(--void); border-color:var(--signal); }
.alarm-popover__btn--primary:hover{ opacity:.9; }

.alarm-toast-stack{
  position:absolute; top:8px; right:8px; z-index:6;
  display:flex; flex-direction:column; gap:6px;
  pointer-events:none;
  max-width:min(260px, 70%);
}
.alarm-toast{
  background:rgba(10,10,10,.92); border:1px solid var(--signal);
  border-radius:5px; padding:7px 10px;
  font-family:var(--font-mono); font-size:11px; color:var(--ink);
  box-shadow:0 4px 14px rgba(0,0,0,.5);
  animation:alarm-toast-in .18s ease-out;
}
.alarm-toast b{ color:var(--signal); }
@keyframes alarm-toast-in{ from{ opacity:0; transform:translateY(-6px); } to{ opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion: reduce){ .alarm-toast{ animation:none; } }

/* Brief whole-chart wash when an alarm fires, same technique as the price-tag flash */
.livechart-canvas-wrap.livechart-canvas-wrap--alarm-flash{ animation:alarm-flash-wash .9s ease-out; }
@keyframes alarm-flash-wash{
  0%{ box-shadow: inset 0 0 0 2px var(--signal); }
  100%{ box-shadow: inset 0 0 0 2px transparent; }
}
@media (prefers-reduced-motion: reduce){ .livechart-canvas-wrap.livechart-canvas-wrap--alarm-flash{ animation:none; } }
.livechart-card:fullscreen .widget-card__body,
.livechart-card--fullscreen .widget-card__body{ flex:1; min-height:0; display:flex; flex-direction:column; }

@media (max-width:640px){
  .livechart-toolbar .tape-toolbar__label{ display:none; }
  /* ~10% shorter than the 267px desktop/default height — phones don't
     have the vertical room to spare, and the chart stays perfectly
     readable smaller. Only the *default* changes; the resize handle
     still drags freely from here exactly as before. */
  .livechart-canvas-wrap{ height:240px; }
}

/* ============================================================
   Mobile default layout
   Placed at the end of the stylesheet on purpose: several of these
   rules share a selector with an earlier, unconditional rule (e.g.
   .live-term__side's display:grid, .live-tape's flex:1), and at equal
   specificity the later declaration in the file wins whenever both
   apply — so this block needs to come last to reliably override them
   below the breakpoint, without touching the desktop rules themselves.
   ============================================================ */
@media (max-width:980px){
  .live-term{ overflow-x:hidden; }

  /* ---------- reorder: Live Chart first, trade tape second,
     Liquidations third, everything else after ----------
     .live-term__side is only ever a wrapper for the sidebar cards —
     giving it display:contents unwraps it so those cards become direct
     items of the .live-term grid alongside .live-term__main, which lets
     `order` interleave them instead of the whole sidebar always trailing
     the tape as one block. Every descendant selector still matches
     (e.g. ".live-term__side .widget-card"): display:contents only drops
     the wrapper's own box — its border-left/background/scroll-fade
     shadow no longer render — it stays in the DOM. Drag-to-reorder
     (layout-persistence.js) still works exactly as before; it reorders
     the underlying DOM/localStorage, it just no longer changes what's
     drawn here, since this fixed order is the point of a "default"
     mobile layout. */
  .live-term__side{ display:contents; }
  .livechart-card{ order:1; }
  .live-term__main{ order:2; }
  .liq-sidebar{ order:3; }
  .squeeze-card{ order:4; }
  .orderflow-card{ order:5; }
  .pulseflow-card{ order:6; }

  /* ---------- 30 trade rows by default ----------
     The tape used to stretch (flex:1) to fit however many rows were
     currently rendered — easily 1000px+ tall — forcing a long scroll
     before reaching Live Chart/Liquidations below it. A default .tape-row
     (12px text, 1.3 line-height, 1.5px top/bottom padding, 1px border)
     is ~20px tall, so 30 rows is ~600px: fixing .live-tape's height there
     shows 30 rows by default, with the rest reachable by scrolling inside
     the tape itself — same as it already works on desktop, just bounded
     by row count instead of viewport height. The 80vh ceiling only kicks
     in on short/landscape phones — tall enough on ordinary portrait
     phones that it doesn't clip the 30-row target. Live updates,
     clustering, filters, pause/clear, etc. are untouched — this only
     changes how tall the scroll area is. */
  .live-term__main{ height:auto; }
  .live-term__tape-frame{ height:auto; }
  .live-tape{ flex:none; height:600px; max-height:80vh; }

  /* ---------- readability on small screens ---------- */
  .live-term__side .widget-card{ padding:10px 12px; }
  .live-term__side .widget-card__head{ margin-bottom:8px; }
  .live-term__side .widget-card__head h4{ font-size:13px; }
  .live-term__side .mstat-row{ padding:4px 0; font-size:13px; }
  .liq-sidebar__row, .whale-row{ padding:6px 6px; }

  /* ---------- mobile-only: compress Liquidations + Whales, less visual
     noise (fewer dividers, tighter spacing) — desktop stays untouched. ---------- */
  .liq-stats{ padding-bottom:8px; margin-bottom:6px; }
  .liq-multi{ display:flex; flex-direction:column; gap:0; }
  .liq-multi-block{ padding:3px 0; border-bottom:1px solid var(--line-soft); }
  .liq-multi-block:last-child{ border-bottom:none; }
  .liq-sidebar__head-row{ padding:4px 6px 6px; }
  .whale-head-row{ padding:4px 6px 6px; }
  .whale-stats{ margin-bottom:6px; }
  .whale-tabs{ margin-bottom:6px; }

  /* ---------- chart: stay inside the card on mobile ----------
     This used to break the canvas out of the card's own left/right
     padding with a negative margin so candles ran edge-to-edge. That
     made the panel read as oversized/"wide" on phones instead of a
     compact, contained widget like its neighbors — reverted. The wrap
     now keeps its normal border on all four sides, same as desktop,
     just at the smaller mobile chart height set above. */
}

/* ============================================================
   VISUAL PRIORITY — 3-tier hierarchy
   ------------------------------------------------------------
   Everything under .live-term used to read at the same visual
   weight (same background, same border, same header treatment)
   regardless of how important the panel actually is. That forces
   the eye to scan the whole terminal instead of landing on the
   thing that matters most.

   Three tiers, same content/layout — only background depth,
   border weight and header opacity move:

     HIGH   — Terminal (trade tape) + Live Chart
              the two panels the terminal is actually "for"
     MEDIUM — Buy/Sell, Liquidations
              secondary, glanceable order-flow signals
     LOW    — Market Pulse, Large Trades, Market Overview
              supporting context, read on demand not at a glance
   ============================================================ */

/* ---- HIGH: Terminal (trade tape) ---- */
.live-term__main{
  background:var(--panel-hover);
  border-top:2px solid var(--signal);
}
.term-identity-bar{ opacity:1; }

/* ---- HIGH: Live Chart ---- */
#terminal-shell .live-term__side .livechart-card{
  background:var(--panel-hover);
  border:1px solid var(--line);
  border-top:2px solid var(--signal);
  /* Authoritative chart-card geometry. The #terminal-shell scope is
     intentional: it beats the generic sidebar-card rule in
     styles-terminal.css, which otherwise restores 14px on both sides.
     The canvas and toolbar keep their own boundary, so 4px is sufficient
     and gives the reclaimed width directly to market data. */
  --card-pad-y:8px;
  --card-pad-x:4px;
  --card-head-gap:5px;
  padding:8px 4px 6px;
}
#terminal-shell .live-term__side .livechart-card:fullscreen,
#terminal-shell .live-term__side .livechart-card.livechart-card--fullscreen{
  border-top:2px solid var(--signal);
  padding:6px;
}
/* ---- MEDIUM: Buy/Sell + Liquidations ---- */
.live-term__side .orderflow-card,
.live-term__side .liq-sidebar{
  background:var(--panel);
  border-bottom:1px solid var(--line);
}
.live-term__side .orderflow-card .widget-card__head,
.live-term__side .liq-sidebar .widget-card__head{ opacity:.85; }

/* ---- LOW: Market Pulse, Large Trades, Market Overview ---- */
.live-term__side .pulseflow-card,
.live-term__main .whale-card,
.live-term__main .mktoverview-card{
  background:transparent;
  border-bottom:1px solid var(--line-soft);
}
.live-term__side .pulseflow-card .widget-card__head,
.live-term__main .whale-card .widget-card__head,
.live-term__main .mktoverview-card .widget-card__head{ opacity:.65; }

/* Drag-reordering swaps a card's position in the DOM, not which panel
   it represents — keep the tier rules keyed to the panel classes above
   (unaffected by order) rather than nth-child, so re-ordering a widget
   never silently changes its priority tier. */

/* LATENCY becomes the compact recovery control only when health logic is active. */
#term-identity-latency[role="button"]{
  cursor:pointer;
  outline:none;
  border-radius:4px;
  padding:1px 3px;
  margin:-1px -3px;
}
#term-identity-latency[role="button"]:hover,
#term-identity-latency[role="button"]:focus-visible{ background:rgba(255,255,255,.055); }
#term-identity-latency.term-identity--bad{
  text-decoration:underline;
  text-decoration-style:dotted;
  text-underline-offset:3px;
}







.asset-command-row{
  display:flex;
  align-items:stretch;
  min-width:0;
  border-bottom:1px solid var(--line);
  background:var(--panel);
}
.asset-command-row .asset-select{
  flex:1 1 auto;
  min-width:0;
  padding:5px 10px;
  border-bottom:0;
  background:transparent;
  flex-wrap:nowrap;
  overflow:hidden;
}
.asset-quick-controls{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:4px;
  flex:0 0 auto;
  padding:4px 9px 4px 7px;
  border-left:1px solid var(--line);
}
.asset-quick-controls .filter-control{
  display:flex;
  align-items:center;
}
.asset-quick-controls .toolbar-btn--icon-only{
  width:28px;
  min-width:28px;
  height:26px;
  min-height:26px;
  padding:0;
  justify-content:center;
  gap:0;
  border-color:transparent;
  border-radius:2px;
}
.asset-quick-controls .toolbar-btn--icon-only:hover,
.asset-quick-controls .toolbar-btn--icon-only.toolbar-btn--active{
  border-color:var(--line);
}
.asset-quick-controls .toolbar-btn--icon-only.toolbar-btn--active{
  border-color:var(--signal);
}
.asset-quick-controls .toolbar-btn__label{
  display:none !important;
}
.asset-quick-controls .toolbar-btn__icon{
  font-size:14px;
}

/* Exchange connections are a settings-level preference, not a permanent
   top-level toolbar. The native checkbox remains in the DOM for keyboard and
   screen-reader interaction while the label behaves like a compact source tile. */
.settings-exchange-source-group{
  margin-top:9px;
  padding-top:9px;
  border-top:1px solid var(--line);
}
.settings-exchange-grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:6px;
  margin-top:5px;
}
.settings-exchange-toggle{
  position:relative;
  display:flex;
  align-items:center;
  gap:7px;
  min-width:0;
  padding:7px 8px;
  font-family:var(--font-mono);
  font-size:11px;
  font-weight:600;
  color:var(--mute);
  background:var(--void);
  border:1px solid var(--line);
  cursor:pointer;
  transition:border-color .15s ease,background .15s ease,color .15s ease;
}
.settings-exchange-toggle:hover{
  color:var(--ink);
  border-color:var(--mute-dim);
}
.settings-exchange-toggle:has(input:checked){
  color:var(--ink);
  border-color:rgba(255,200,87,.48);
  background:var(--signal-soft);
}
.settings-exchange-toggle input{
  position:absolute;
  inline-size:1px;
  block-size:1px;
  opacity:0;
  pointer-events:none;
}
.settings-exchange-toggle:has(input:focus-visible){
  outline:2px solid var(--signal);
  outline-offset:2px;
}
.settings-exchange-toggle__icon{
  width:16px;
  height:16px;
  flex:none;
}
.settings-exchange-toggle__label{
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

@media (max-width:640px){
  .asset-command-row{
    align-items:center;
  }
  .asset-command-row .asset-select{
    padding:3px 3px;
  }
  .asset-command-row .asset-pill{
    padding:4px 3px;
    font-size:9.5px;
    gap:3px;
  }
  .asset-command-row .asset-pill__chg{
    font-size:9px;
  }
  .asset-quick-controls{
    gap:1px;
    padding:3px 3px 3px 2px;
  }
  .asset-quick-controls .toolbar-btn--icon-only{
    width:27px;
    min-width:27px;
    height:28px;
    min-height:28px;
    padding:0;
  }
  .asset-quick-controls .toolbar-btn__icon{
    font-size:13px;
  }
  .settings-exchange-grid{
    grid-template-columns:1fr;
  }
}







#crypto-tape-root,
#crypto-tape-root .live-term,
#crypto-tape-root .live-term__main,
#crypto-tape-root .live-term__side,
#crypto-tape-root .widget-card,
#crypto-tape-root .live-tape,
#crypto-tape-root .whale-list{ overflow-anchor:none; }

.whale-card .widget-card__body{
  min-height:356px;
}
.whale-list{
  height:260px;
  max-height:260px;
  overflow-y:auto;
  overscroll-behavior:contain;
  scrollbar-gutter:stable;
}
.whale-card--empty .whale-card__live{ display:none !important; }
.whale-card--empty .widget-card__body{
  min-height:356px;
  display:flex;
  align-items:center;
  justify-content:center;
  padding-top:0;
  padding-bottom:0;
}
.whale-card--empty .whale-empty-msg{
  display:flex;
  align-items:center;
  justify-content:center;
  min-height:260px;
  width:100%;
  text-align:center;
}
@media (max-width:980px){
  .whale-card .widget-card__body{ min-height:300px; }
  .whale-list{ height:210px; max-height:210px; }
  .whale-card--empty .widget-card__body{ min-height:300px; }
  .whale-card--empty .whale-empty-msg{ min-height:210px; }
}





#terminal-shell,
.term-bleed,
#crypto-tape-root,
#crypto-tape-root .live-term__tape-frame,
#crypto-tape-root .live-tape{
  overflow-anchor:none;
}
/* Normal tape rows: one immutable height regardless of trade size, crown,
   clustering or highlight tier. 26px intentionally matches the virtualizer's
   initial row estimate, eliminating the first-render spacer correction too. */
#crypto-tape-root .tape-row,
#crypto-tape-root .tape-row.tape-tier-2,
#crypto-tape-root .tape-row.tape-tier-3,
#crypto-tape-root .tape-row.tape-tier-4{
  box-sizing:border-box;
  height:26px;
  min-height:26px;
  max-height:26px;
  padding-top:0;
  padding-bottom:0;
  overflow:hidden;
}
/* Large prints remain visually stronger without altering layout metrics. */
#crypto-tape-root .tape-row.tape-tier-3,
#crypto-tape-root .tape-row.tape-tier-4{
  font-weight:800;
}

/* Density modes also keep a single fixed row height per mode. */
#crypto-tape-root.tape-mode--compact .tape-row,
#crypto-tape-root.tape-mode--compact .tape-row.tape-tier-3,
#crypto-tape-root.tape-mode--compact .tape-row.tape-tier-4{
  height:22px;
  min-height:22px;
  max-height:22px;
  padding-top:0;
  padding-bottom:0;
}
#crypto-tape-root.tape-mode--large .tape-row,
#crypto-tape-root.tape-mode--large .tape-row.tape-tier-3,
#crypto-tape-root.tape-mode--large .tape-row.tape-tier-4{
  height:34px;
  min-height:34px;
  max-height:34px;
  padding-top:0;
  padding-bottom:0;
}
#crypto-tape-root .tape-row__cluster{
  box-sizing:border-box;
  height:18px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding-top:0;
  padding-bottom:0;
}
/* The old "biggest trade" entrance translated the row vertically by 3px.
   Keep a subtle opacity cue but never move the row itself. */
#crypto-tape-root .tape-row--biggest{
  animation:tapeRowBiggestStable .28s ease-out;
}
@keyframes tapeRowBiggestStable{
  from{ opacity:.55; }
  to{ opacity:1; }
}
@media (prefers-reduced-motion: reduce){
  #crypto-tape-root .tape-row--biggest{ animation:none; }
}

/* Liquidations: exact centered geometry.
   Header uses equal side columns, so the title is mathematically centered
   rather than visually pulled by the LIVE badge. */
#terminal-shell .liq-sidebar .widget-card__head{
  display:grid;
  grid-template-columns:76px minmax(0,1fr) 76px;
  align-items:center;
  column-gap:8px;
}
#terminal-shell .liq-sidebar .widget-card__head .panel-drag-handle{
  justify-self:start;
}
#terminal-shell .liq-sidebar .widget-card__head h4{
  justify-self:center;
  width:100%;
  margin:0;
  text-align:center;
  white-space:normal;
}
#terminal-shell .liq-sidebar .widget-card__head .tag{
  justify-self:end;
  margin:0;
}
#terminal-shell .liq-sidebar .liq-sidebar__src{
  margin-left:6px;
}

/* Summary itself is centered as a three-column instrument:
   timeframe | long | short. No nested 38px + remainder imbalance. */
#terminal-shell .liq-stats{
  display:flex;
  justify-content:center;
  width:100%;
}
#terminal-shell .liq-multi{
  width:min(100%,430px);
  margin-left:auto;
  margin-right:auto;
}
#terminal-shell .liq-multi-block{
  grid-template-columns:52px minmax(0,1fr) minmax(0,1fr);
  width:100%;
}
#terminal-shell .liq-multi-block__sides{
  display:contents;
}
#terminal-shell .liq-multi-block__win,
#terminal-shell .liq-multi-block__side{
  justify-self:stretch;
  text-align:center;
}
#terminal-shell .liq-multi-block__side{
  display:flex;
  justify-content:center;
  align-items:baseline;
  min-width:0;
}

@media (max-width:640px){
  #terminal-shell .liq-sidebar .widget-card__head{
    grid-template-columns:42px minmax(0,1fr) 68px;
    column-gap:5px;
  }
  #terminal-shell .liq-sidebar .widget-card__head h4{
    font-size:12px;
  }
  #terminal-shell .liq-sidebar .liq-sidebar__src{
    display:block;
    margin:2px 0 0;
    font-size:9px;
    line-height:1.1;
  }
  #terminal-shell .liq-multi-block{
    grid-template-columns:42px minmax(0,1fr) minmax(0,1fr);
  }
}

/* Dynamic liquidation event list also owns a fixed viewport. New events may
   scroll inside this box, but can never grow the card and push Squeeze/Pulse
   panels below it. */
#terminal-shell .liq-sidebar__list{
  box-sizing:border-box;
  height:168px;
  min-height:168px;
  max-height:168px;
  overflow-y:auto;
  overscroll-behavior:contain;
  scrollbar-gutter:stable;
  overflow-anchor:none;
}
#terminal-shell .liq-sidebar__empty{
  box-sizing:border-box;
  min-height:167px;
  padding:0 8px;
  display:flex;
  align-items:center;
  justify-content:center;
}
#terminal-shell .liq-sidebar__row{
  box-sizing:border-box;
  height:28px;
  min-height:28px;
  max-height:28px;
  padding-top:0;
  padding-bottom:0;
  overflow:hidden;
}
@media (max-width:640px){
  #terminal-shell .liq-sidebar__list{
    height:140px;
    min-height:140px;
    max-height:140px;
  }
  #terminal-shell .liq-sidebar__empty{ min-height:139px; }
  #terminal-shell .liq-sidebar__row{
    height:28px;
    min-height:28px;
    max-height:28px;
  }
}


/* ---------- Chart Teleport ---------- */
.livechart-teleport-btn{min-width:30px;width:30px;padding:3px;justify-content:center}
.livechart-teleport-btn svg{display:block}
.livechart-teleport-popover{position:absolute;z-index:90;top:82px;right:14px;width:min(340px,calc(100% - 28px));box-sizing:border-box;padding:0 14px 14px;background:var(--panel);border:1px solid var(--line);border-radius:8px;box-shadow:0 18px 46px rgba(0,0,0,.48);font-family:var(--font-mono)}
.livechart-teleport-popover[hidden]{display:none}
.livechart-teleport-popover__head{display:flex;align-items:center;justify-content:space-between;margin:0 -14px 12px;padding:10px 12px 9px 14px;border-bottom:1px solid var(--line);background:var(--surface-header)}
.livechart-teleport-popover__head strong{color:var(--ink);font-size:12px;letter-spacing:.03em;text-transform:uppercase}
.livechart-teleport-popover__close{width:25px;height:25px;display:grid;place-items:center;padding:0;border:0;background:transparent;color:var(--mute);cursor:pointer;font-size:18px;line-height:1}
.livechart-teleport-popover__close:hover{color:var(--ink)}
.livechart-teleport-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.livechart-teleport-grid label{display:flex;flex-direction:column;gap:4px;min-width:0}
.livechart-teleport-grid label>span{color:var(--mute);font-size:10px;text-transform:uppercase;letter-spacing:.06em}
.livechart-teleport-grid__wide{grid-column:1/-1}
.livechart-teleport-grid input,.livechart-teleport-grid select{width:100%;min-width:0;height:31px;box-sizing:border-box;border:1px solid var(--line);border-radius:4px;background:var(--void);color:var(--ink);padding:5px 7px;font:11.5px var(--font-mono);outline:none}
.livechart-teleport-grid input:focus,.livechart-teleport-grid select:focus{border-color:rgba(255,200,87,.62)}
.livechart-teleport-preview{margin-top:10px;padding:8px 9px;border:1px solid var(--line-soft);background:rgba(255,255,255,.015);color:var(--mute);font-size:10.5px;line-height:1.45}
.livechart-teleport-status{min-height:16px;padding-top:6px;color:var(--danger);font-size:10.5px;line-height:1.35}
.livechart-teleport-actions{display:flex;justify-content:flex-end;gap:7px;margin-top:3px}
.livechart-teleport-actions .toolbar-btn{min-height:29px}
@media(max-width:640px){.livechart-overflow-panel .livechart-teleport-btn{width:34px;min-width:34px;align-self:flex-start;justify-content:center;padding:3px}.livechart-teleport-popover{position:fixed;top:50%;right:auto;left:50%;transform:translate(-50%,-50%);width:min(340px,calc(100vw - 24px));z-index:220}}



html.th-perf-busy .live-term .tape-row,
html.th-perf-busy .live-term .whale-row,
html.th-perf-busy .live-term .liq-sidebar__row,
html.th-perf-busy .live-term .toolbar-btn {
  transition-duration: 0ms !important;
}
html.th-perf-extreme .live-term .tape-row,
html.th-perf-extreme .live-term .whale-row,
html.th-perf-extreme .live-term .liq-sidebar__row,
html.th-perf-extreme .live-term .toolbar-btn,
html.th-perf-extreme .live-term .term-identity-bar__dot,
html.th-perf-extreme .live-term .live-tape__heat-cell {
  animation: none !important;
  transition: none !important;
  box-shadow: none !important;
}




#crypto-tape-root .tape-row.tape-tier-2{ background-color:rgba(0,255,136,.055); }
#crypto-tape-root .tape-row.tape-tier-2.tape-row--sell{ background-color:rgba(255,77,77,.055); }
#crypto-tape-root .tape-row.tape-tier-3{ background-color:rgba(0,255,136,.085); font-weight:650; }
#crypto-tape-root .tape-row.tape-tier-3.tape-row--sell{ background-color:rgba(255,77,77,.085); }
#crypto-tape-root .tape-row.tape-tier-4{ background-color:rgba(0,255,136,.11); font-weight:700; }
#crypto-tape-root .tape-row.tape-tier-4.tape-row--sell{ background-color:rgba(255,77,77,.11); }



#terminal-shell.theme-light .live-term{
  --void:#F4F5F6;
  --panel:#FFFFFF;
  --panel-hover:#F0F1F3;
  --surface-header:#E8EAED;
  --line:#D8DCE0;
  --line-soft:#E7E9EC;
  --ink:#14161A;
  --mute:#5B6067;
  --mute-dim:#737982;
  --signal:#B5790F;
  --signal-soft:rgba(181,121,15,.12);
  --pulse:#0F8F63;
  --pulse-soft:rgba(15,143,99,.11);
  --danger:#C93338;
  --danger-soft:rgba(201,51,56,.11);
  background:var(--void);
  color:var(--ink);
}
#terminal-shell.theme-light .live-term__main,
#terminal-shell.theme-light .live-term__side,
#terminal-shell.theme-light .live-term__tape-frame,
#terminal-shell.theme-light .livechart-canvas-wrap,
#terminal-shell.theme-light .livechart-subpane{ background:var(--void); }
#terminal-shell.theme-light .live-term__side{
  background:#F8F9FA;
  box-shadow:inset 0 18px 14px -18px rgba(20,22,26,.16), inset 0 -18px 14px -18px rgba(20,22,26,.16);
}
#terminal-shell.theme-light .term-identity-bar,
#terminal-shell.theme-light .filter-panel__head,
#terminal-shell.theme-light .livechart-teleport-popover__head{ background:var(--surface-header); }
#terminal-shell.theme-light .filter-panel--settings,
#terminal-shell.theme-light .sound-panel,
#terminal-shell.theme-light .alarm-popover,
#terminal-shell.theme-light .livechart-teleport-popover,
#terminal-shell.theme-light .chart-share-modal__panel,
#terminal-shell.theme-light .metric-tip-bubble{
  background:var(--panel);
  color:var(--ink);
  box-shadow:0 20px 50px rgba(20,22,26,.16);
}
#terminal-shell.theme-light .filter-panel__backdrop,
#terminal-shell.theme-light .chart-share-modal__backdrop{ background:rgba(20,22,26,.34); }
#terminal-shell.theme-light .livechart-loading{ background:rgba(244,245,246,.76); }
#terminal-shell.theme-light .alarm-toast{
  background:rgba(255,255,255,.96);
  box-shadow:0 4px 14px rgba(20,22,26,.18);
}
#terminal-shell.theme-light .livechart-teleport-preview{ background:rgba(20,22,26,.025); }
#terminal-shell.theme-light .settings-exchange-toggle,
#terminal-shell.theme-light .settings-row__select,
#terminal-shell.theme-light .sound-panel select,
#terminal-shell.theme-light .sound-panel input[type=range],
#terminal-shell.theme-light .livechart-teleport-grid input,
#terminal-shell.theme-light .livechart-teleport-grid select{
  background:var(--panel);
  color:var(--ink);
  border-color:var(--line);
}
#terminal-shell.theme-light .asset-pill--active{ color:#14161A; }
#terminal-shell.theme-light .orderflow-ratio-legend__buy,
#terminal-shell.theme-light .orderflow-ratio-legend__sell{ text-shadow:none; }
#terminal-shell.theme-light .livechart-marker-legend{ text-shadow:none; }







#crypto-tape-root .tape-row--flash-in,
#crypto-tape-root .tape-row--biggest{
  animation:none !important;
  transform:none !important;
}

/* One shared flash layer for the bounded Volume viewport. It is never part of
   layout, never captures input, and only animates opacity through WAAPI. */
#crypto-tape-root .live-term__tape-frame{
  position:relative;
  isolation:isolate;
}
#crypto-tape-root .tape-volume-flash-overlay{
  position:absolute;
  inset:20px 0 0 0; /* leave the heatmap strip visually untouched */
  z-index:5;
  pointer-events:none;
  opacity:0;
  background:transparent;
  contain:strict;
  will-change:opacity;
}
#crypto-tape-root .live-tape,
#crypto-tape-root .live-tape-idle{
  position:relative;
  z-index:3;
}
#crypto-tape-root .tape-heatmap{
  position:relative;
  z-index:3;
}




#crypto-tape-root .live-term--flash-t1,
#crypto-tape-root .live-term--flash-t2,
#crypto-tape-root .live-term--flash-t3{
  animation:none !important;
  box-shadow:none !important;
}

/* Busy/extreme modes preserve the background cue; only its JS frequency and
   opacity are reduced. Do not apply the older blanket box-shadow:none rule to
   the overlay because it has no shadow in the first place. */
html.th-perf-busy #crypto-tape-root .tape-volume-flash-overlay,
html.th-perf-extreme #crypto-tape-root .tape-volume-flash-overlay{
  transition:none !important;
  box-shadow:none !important;
}

@media (prefers-reduced-motion: reduce){
  #crypto-tape-root .tape-volume-flash-overlay{ display:none; }
}




#crypto-tape-root .tape-row--biggest,
#crypto-tape-root .tape-row.tape-hl-1,
#crypto-tape-root .tape-row.tape-hl-3{
  box-shadow:none !important;
}






#crypto-tape-root .tape-volume-flash-overlay{
  display:none !important;
  animation:none !important;
  opacity:0 !important;
}
#crypto-tape-root .live-tape{
  contain:layout paint style;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}
#crypto-tape-root .tape-row,
#crypto-tape-root .tape-row--biggest,
#crypto-tape-root .tape-row--flash-in{
  animation:none !important;
  transition:none !important;
  transform:none !important;
}
/* Compact source line. Full instrument/window/coverage/method details live
   behind the info button instead of repeating a technical sentence in every panel. */
.data-contract{display:flex;align-items:center;min-height:24px;gap:7px;padding:3px 9px;border-bottom:1px solid var(--line-soft);font:650 9px/1.2 var(--font-mono);letter-spacing:.025em;color:var(--mute-dim);background:rgba(255,255,255,.012)}
.data-contract--internal,.data-contract[hidden]{display:none!important}
.data-contract__state{display:inline-flex;align-items:center;min-width:12ch;font-weight:800;color:#aaa}.data-contract__state:before{content:'';width:5px;height:5px;margin-right:5px;border-radius:50%;background:#777}
.data-contract__venue{color:var(--mute);white-space:nowrap}.data-contract__market{padding:1px 4px;border:1px solid var(--line);border-radius:2px;color:#aeb8c1}.data-contract__age{min-width:4.5ch;text-align:right;white-space:nowrap;color:var(--mute-dim);font-weight:600;font-variant-numeric:tabular-nums}
.data-contract__coverage{white-space:nowrap;color:#f4c95d}.data-contract__info{margin-left:auto;width:20px;height:20px;padding:0;border:0;background:transparent;color:var(--mute-dim);font:600 12px/20px var(--font-mono);cursor:help}.data-contract__info:hover,.data-contract__info:focus-visible{color:var(--ink);outline:1px solid var(--line)}
.data-contract[data-state="LIVE"] .data-contract__state{color:var(--pulse)}.data-contract[data-state="LIVE"] .data-contract__state:before{background:var(--pulse)}
.data-contract[data-state="DELAYED"] .data-contract__state,.data-contract[data-state="PARTIAL"] .data-contract__state{color:#f4c95d}.data-contract[data-state="DELAYED"] .data-contract__state:before,.data-contract[data-state="PARTIAL"] .data-contract__state:before{background:#f4c95d}
.data-contract[data-state="STALE"] .data-contract__state{color:var(--danger)}.data-contract[data-state="STALE"] .data-contract__state:before{background:var(--danger)}
.data-contract[data-state="RECONNECTING"] .data-contract__state{color:#f0a34a}.data-contract[data-state="RECONNECTING"] .data-contract__state:before{background:#f0a34a}
.data-contract[data-data-contract-id="live-chart"] .data-contract__info,.data-contract[data-data-contract-id="live-chart-secondary"] .data-contract__info{display:none}
@media(max-width:700px){.data-contract{gap:5px;padding:3px 7px;font-size:8.5px}.data-contract__venue{max-width:92px;overflow:hidden;text-overflow:ellipsis}.data-contract__info{margin-left:auto}}

/* Compact local price alerts. Keep the empty/default card close to the height
   of the Market Pulse card in the opposite column so the next full-width
   widget does not appear to jump down after a large empty block. */
.retention-card{margin-top:8px}.retention-card .widget-card__body{display:grid;gap:5px;padding:6px 8px}.retention-form{display:grid;grid-template-columns:minmax(54px,.55fr) minmax(112px,1.15fr) minmax(86px,.8fr) minmax(88px,.7fr);gap:5px}.retention-form label{display:grid;gap:2px;color:var(--mute);font:600 8px/1.15 var(--font-mono);text-transform:uppercase;letter-spacing:.035em}.retention-form input,.retention-form select,.retention-form button{width:100%;min-width:0;height:27px;box-sizing:border-box;background:var(--panel);border:1px solid var(--line);color:var(--ink);padding:4px 6px;font:500 9px var(--font-mono)}.retention-form button{align-self:end;cursor:pointer;color:var(--signal);font-weight:700}.retention-permission{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:6px;padding:3px 5px;border:1px solid var(--line);background:var(--panel-soft)}.retention-permission button{height:24px;padding:0 7px;border:1px solid var(--line);background:var(--panel);color:var(--signal);font:700 8.5px var(--font-mono);cursor:pointer}.retention-permission button:disabled{color:var(--mute);cursor:default}.retention-permission span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--mute);font:500 8px/1.2 var(--font-mono)}.retention-alert-columns{display:grid;grid-template-columns:1fr 1fr;gap:7px}.retention-alert-columns section{min-width:0}.retention-alert-columns h5{margin:0 0 3px;color:var(--mute);font:700 8.5px/1.15 var(--font-display);text-transform:uppercase;letter-spacing:.05em}.retention-list{list-style:none;margin:0;padding:0;display:grid;gap:3px;font:500 8.5px/1.2 var(--font-mono)}.retention-list li{display:flex;justify-content:space-between;gap:6px;border-bottom:1px solid var(--line);padding:0 0 3px}.retention-list button{border:0;background:transparent;color:var(--mute);cursor:pointer;font-size:13px}.retention-empty{color:var(--mute-dim)}.retention-note{margin:0;color:var(--mute-dim);font:500 7.5px/1.25 var(--font-mono)}.retention-note--warning{color:#c7a85c}
@media(max-width:760px){.retention-form{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.retention-permission,.retention-alert-columns{grid-template-columns:1fr}.retention-form{grid-template-columns:1fr 1fr}}
@media(max-width:900px){.retention-grid{grid-template-columns:1fr}}@media(max-width:520px){.retention-form{grid-template-columns:1fr}}




@media(max-width:640px){
  #crypto-tape-root .livechart-card:not(:fullscreen):not(.livechart-card--fullscreen) .livechart-canvas-wrap{
    height:250px !important;
    height:clamp(220px,36svh,260px) !important;
    min-height:220px !important;
  }
  #crypto-tape-root .livechart-toolbar>.tape-toolbar__group--right{
    display:none;
  }
  #crypto-tape-root #livechart-add-second-btn{
    display:none!important;
  }
  #crypto-tape-root .live-tape{
    height:390px;
    max-height:55vh;
  }
  #crypto-tape-root .whale-card--empty .widget-card__body{
    min-height:112px;
  }
  #crypto-tape-root .whale-card--empty .whale-empty-msg{
    min-height:88px;
    padding:0 12px;
    line-height:1.45;
  }
  #terminal-shell .liq-sidebar__list{
    height:112px;
    min-height:112px;
    max-height:112px;
  }
  #terminal-shell .liq-sidebar__empty{
    min-height:111px;
  }
  #crypto-tape-root .asset-pill,
  #crypto-tape-root .asset-quick-controls .toolbar-btn,
  #crypto-tape-root .livechart-overflow-btn{
    touch-action:manipulation;
  }
  #crypto-tape-root .asset-pill__chg{
    display:none !important;
  }
  #crypto-tape-root .asset-select--stacked .asset-pill{
    flex-direction:row;
    align-items:center;
    justify-content:center;
  }
  #crypto-tape-root .asset-pill__label{
    overflow:visible;
    text-overflow:clip;
  }




  #crypto-tape-root .livechart-canvas-wrap{
    height:240px !important;
    min-height:220px !important;
    max-height:240px !important;
  }
  #crypto-tape-root .livechart-card:fullscreen .livechart-canvas-wrap,
  #crypto-tape-root .livechart-card.livechart-card--fullscreen .livechart-canvas-wrap{
    height:auto !important;
    min-height:0 !important;
    max-height:none !important;
  }
}



.livechart-tools-sheet__head{ display:none; }
.livechart-tools-backdrop[hidden]{ display:none !important; }
@media(max-width:640px){
  body.th-chart-tools-sheet-open{ overflow:hidden; }
  .livechart-tools-backdrop{
    position:fixed; inset:0; z-index:1070;
    background:rgba(0,0,0,.72); backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px);
  }
  .livechart-overflow-panel.livechart-overflow-panel--mobile-sheet{
    position:fixed !important; inset:auto 10px max(10px,env(safe-area-inset-bottom)) 10px !important;
    z-index:1080 !important; display:grid !important; grid-template-columns:repeat(4,minmax(0,1fr));
    align-items:stretch; gap:7px; width:auto !important; max-width:none !important; max-height:calc(100dvh - 20px);
    box-sizing:border-box; margin:0 !important; padding:0 10px 12px !important;
    overflow:auto; overscroll-behavior:contain; border:1px solid var(--line);
    border-radius:12px; background:var(--panel); box-shadow:0 24px 70px rgba(0,0,0,.7);
  }
  .livechart-overflow-panel--mobile-sheet .livechart-tools-sheet__head{
    position:sticky; top:0; z-index:3; grid-column:1/-1; display:flex; align-items:center; justify-content:space-between;
    min-height:48px; margin:0 -10px 1px; padding:0 10px;
    border-bottom:1px solid var(--line); background:var(--surface-header);
  }
  .livechart-tools-sheet__head strong{ color:var(--ink); font:700 13px/1.2 var(--font-mono); letter-spacing:.04em; text-transform:uppercase; }
  .livechart-tools-sheet__close{
    display:inline-grid; place-items:center; width:40px; height:40px; padding:0;
    border:0; background:transparent; color:var(--mute); font-size:25px; cursor:pointer;
  }
  .livechart-tools-sheet__close:focus-visible{ outline:2px solid var(--signal); outline-offset:-3px; color:var(--ink); }
  /* Mobile More is an icon-forward command palette rather than a stack of
     desktop-sized text rows. Captions remain short and visible for touch
     clarity, while the icons are the primary visual affordance. */
  .livechart-overflow-panel--mobile-sheet > .filter-control{ display:contents; }
  .livechart-overflow-panel--mobile-sheet > .toolbar-btn,
  .livechart-overflow-panel--mobile-sheet > .filter-control > .toolbar-btn{
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
    width:100% !important; min-width:0; min-height:66px; padding:7px 3px;
    border:1px solid var(--line-soft); border-radius:8px; background:rgba(255,255,255,.018);
    color:var(--ink); text-align:center; box-shadow:none;
  }
  .livechart-overflow-panel--mobile-sheet > .toolbar-btn:active,
  .livechart-overflow-panel--mobile-sheet > .filter-control > .toolbar-btn:active{
    transform:translateY(1px); background:rgba(255,255,255,.035);
  }
  .livechart-overflow-panel--mobile-sheet > .toolbar-btn.toolbar-btn--active,
  .livechart-overflow-panel--mobile-sheet > .filter-control > .toolbar-btn.toolbar-btn--active{
    color:var(--ink); border-color:rgba(255,200,87,.28); background:rgba(255,200,87,.055);
  }
  .livechart-overflow-panel--mobile-sheet .toolbar-btn__icon{
    display:grid; place-items:center; width:26px; min-width:26px; height:26px; font-size:19px; line-height:1;
  }
  .livechart-overflow-panel--mobile-sheet .toolbar-btn__icon svg{ width:20px; height:20px; }
  .livechart-overflow-panel--mobile-sheet .toolbar-btn__label{
    display:block !important; position:static !important; width:100% !important; height:auto !important;
    margin:0 !important; overflow:hidden !important; clip:auto !important; white-space:normal !important;
    color:var(--mute); font:700 9px/1.15 var(--font-mono); letter-spacing:.01em;
    text-overflow:ellipsis; max-height:2.3em;
  }
  .livechart-overflow-panel--mobile-sheet .toolbar-btn--active .toolbar-btn__label{ color:var(--ink); }
  .livechart-overflow-panel--mobile-sheet .livechart-indicator-panel,
  .livechart-overflow-panel--mobile-sheet .livechart-layout-panel{
    grid-column:1/-1; width:100% !important; margin-top:1px; box-sizing:border-box;
  }
  .livechart-overflow-panel--mobile-sheet .livechart-layout-panel:not([hidden]){ display:block; }
  .livechart-overflow-panel--mobile-sheet .livechart-teleport-btn{ align-self:stretch; }
}

@media(max-width:350px){
  .livechart-overflow-panel.livechart-overflow-panel--mobile-sheet{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}

@media(max-width:380px){
  #crypto-tape-root .tape-row__qty{display:none}
  #crypto-tape-root .tape-row__price{width:78px}
  #crypto-tape-root .tape-row__value{width:62px}
  #crypto-tape-root .tape-row__time{width:54px;font-size:10.5px}
}





@media(max-width:640px){
  #terminal-shell #crypto-tape-root .livechart-card:not(:fullscreen):not(.livechart-card--fullscreen){
    --card-pad-y:3px;
    --card-pad-x:3px;
    --card-head-gap:0px;
    padding:3px 3px 5px !important;
  }
  #terminal-shell #crypto-tape-root .livechart-card > .widget-card__body{
    padding-top:0 !important;
  }
  #terminal-shell #crypto-tape-root .livechart-ticker{
    margin:0 0 2px;
    padding:2px 4px;
  }
  #terminal-shell #crypto-tape-root .livechart-ticker__stat{
    min-height:18px;
    padding:1px 2px;
  }
  #terminal-shell #crypto-tape-root .livechart-toolbar{
    gap:2px 4px;
    margin:0 0 1px;
  }
  #terminal-shell #crypto-tape-root .livechart-toolbar .tape-toolbar__group{
    gap:2px;
  }
  #terminal-shell #crypto-tape-root .livechart-toolbar .tape-toolbar__select,
  #terminal-shell #crypto-tape-root #livechart-type-group .toolbar-btn{
    box-sizing:border-box;
    min-height:24px;
    height:24px;
    padding:2px 5px;
  }
  #terminal-shell #crypto-tape-root .livechart-toolbar .livechart-controls-group{
    margin:0;
  }
  #terminal-shell #crypto-tape-root .livechart-overflow{
    margin-top:1px;
    padding-top:1px;
  }
  #terminal-shell #crypto-tape-root .livechart-overflow-btn{
    min-height:20px;
    padding:2px 6px;
    line-height:1.1;
  }
  #terminal-shell #crypto-tape-root .livechart-chart-stats{
    flex-wrap:nowrap;
    gap:2px 10px;
    margin:0 0 3px;
    padding:1px 0;
    overflow:hidden;
  }
}





#terminal-shell .widget-card__head{
  display:flex !important;
  grid-template-columns:none !important;
  flex-wrap:nowrap !important;
  align-items:center;
  min-width:0;
  overflow:hidden;
}
#terminal-shell .widget-card__head > h4{
  display:block !important;
  flex:1 1 auto;
  min-width:0;
  width:auto !important;
  margin:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap !important;
  line-height:1.2;
}
#terminal-shell .widget-card__head > :not(h4){
  flex:0 0 auto;
  min-width:0;
  white-space:nowrap;
}
#terminal-shell .liq-sidebar .widget-card__head{ column-gap:8px; }
#terminal-shell .liq-sidebar .widget-card__head h4{
  justify-self:auto;
  text-align:left;
}
#terminal-shell .liq-sidebar .liq-sidebar__src{
  display:inline !important;
  margin:0 0 0 5px !important;
  white-space:nowrap;
}
#terminal-shell .liq-sidebar .widget-card__head > .tag{
  box-sizing:border-box;
  width:110px;
  min-width:110px !important;
  max-width:110px;
  justify-content:center;
  gap:5px;
  padding:3px 8px;
  font-size:10px;
  overflow:hidden;
}
#terminal-shell #liqside-status-text{
  display:block;
  flex:1 1 auto;
  min-width:0;
  overflow:hidden;
  text-align:center;
  text-overflow:ellipsis;
  white-space:nowrap;
}
#terminal-shell .heatmap-head__status{
  box-sizing:border-box;
  width:116px;
  min-width:116px !important;
  justify-content:flex-end;
  overflow:hidden;
  white-space:nowrap;
}
#terminal-shell .heatmap-head__status > .tag{
  box-sizing:border-box;
  display:flex;
  width:100%;
  min-width:0;
  max-width:100%;
  justify-content:center;
  overflow:hidden;
}
#terminal-shell .heatmap-head__status > .tag > span:last-child{
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
#terminal-shell #term-identity-connected{
  display:inline-block;
  min-width:3ch;
  text-align:center;
}
#terminal-shell #term-identity-ws-text{
  display:inline-block;
  min-width:11ch;
  white-space:nowrap;
}
#terminal-shell .radar-head{
  display:flex;
  flex-direction:row !important;
  flex-wrap:nowrap;
  align-items:center;
  min-width:0;
  overflow:hidden;
}
#terminal-shell .radar-head__copy{
  flex:1 1 auto;
  min-width:0;
}
#terminal-shell .radar-eyebrow,
#terminal-shell .radar-head__copy > p:last-child{ display:none; }
#terminal-shell .radar-head h2{
  margin:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
#terminal-shell .radar-head__actions{
  flex:0 0 auto;
  width:auto !important;
  flex-direction:row !important;
  flex-wrap:nowrap;
  white-space:nowrap;
}
@media(max-width:640px){
  #terminal-shell .widget-card__head{ gap:4px; }
  #terminal-shell .liq-sidebar .widget-card__head > .tag{
    width:80px;
    min-width:80px !important;
    max-width:80px;
    gap:3px;
    padding:2px 4px;
    font-size:8px;
    letter-spacing:0;
  }
  #terminal-shell .heatmap-head__status{
    width:78px;
    min-width:78px !important;
  }
}


.th-draw-flyout__head{display:flex;align-items:center;gap:6px;min-width:0}
.th-draw-flyout__head strong{flex:1;min-width:0}
.th-draw-mobile-back,.th-draw-style-back{display:none}
@media (max-width:640px){
  .th-draw-toolbar.is-mobile .th-draw-toolbar__body{
    grid-template-columns:repeat(4,minmax(0,1fr));
    max-height:min(58dvh,460px);
    overflow-x:hidden;
  }
  .th-draw-toolbar.is-mobile .th-draw-flyout{
    position:static!important;left:auto!important;right:auto!important;top:auto!important;bottom:auto!important;
    grid-column:1/-1;width:100%;max-width:none;max-height:none;box-shadow:none;border:0;padding:0;
    background:transparent;overflow:visible;grid-template-columns:repeat(2,minmax(0,1fr));
  }
  .th-draw-toolbar.is-mobile .th-draw-flyout__head{
    position:sticky;top:50px;z-index:3;grid-column:1/-1;min-height:42px;margin:0 0 5px;
    padding:0 2px;border-bottom:1px solid var(--line);background:rgba(12,14,18,.99);
  }
  .th-draw-toolbar.is-mobile .th-draw-flyout__head strong{padding:0 4px;color:var(--ink)}
  .th-draw-toolbar.is-mobile .th-draw-mobile-back,
  .th-draw-toolbar.is-mobile .th-draw-style-back{
    display:inline-grid;place-items:center;width:38px;height:38px;flex:0 0 38px;padding:0;
    border:1px solid var(--line);border-radius:6px;background:var(--panel);color:var(--ink);font:700 18px/1 var(--font-mono);cursor:pointer;
  }
  .th-draw-toolbar.is-mobile.is-detail-open .th-draw-toolbar__body>.th-draw-recent,
  .th-draw-toolbar.is-mobile.is-detail-open .th-draw-toolbar__body>.th-draw-divider,
  .th-draw-toolbar.is-mobile.is-detail-open .th-draw-toolbar__body>.th-draw-action,
  .th-draw-toolbar.is-mobile.is-detail-open .th-draw-toolbar__body>.th-draw-group:not(.is-open){display:none!important}
  .th-draw-toolbar.is-mobile.is-detail-open .th-draw-toolbar__body>.th-draw-group.is-open{grid-column:1/-1;display:block;width:100%}
  .th-draw-toolbar.is-mobile.is-detail-open .th-draw-toolbar__body>.th-draw-group.is-open>.th-draw-category{display:none!important}
  .th-draw-toolbar.is-mobile .th-draw-style-panel{
    position:static!important;left:auto!important;right:auto!important;top:auto!important;bottom:auto!important;
    grid-column:1/-1;width:100%;max-width:none;max-height:none;box-shadow:none;border:0;padding:0 2px 4px;background:transparent;overflow:visible;
  }
  .th-draw-toolbar.is-mobile .th-draw-style-panel[hidden]{display:none!important}
  .th-draw-toolbar.is-mobile .th-draw-style-panel__head{
    position:sticky;top:50px;z-index:3;min-height:42px;margin:0 0 6px;padding:0 2px;
    border-bottom:1px solid var(--line);background:rgba(12,14,18,.99);gap:6px;
  }
  .th-draw-toolbar.is-mobile .th-draw-style-panel__head strong{flex:1}
  .th-draw-toolbar.is-mobile.is-style-open .th-draw-toolbar__body>.th-draw-recent,
  .th-draw-toolbar.is-mobile.is-style-open .th-draw-toolbar__body>.th-draw-divider,
  .th-draw-toolbar.is-mobile.is-style-open .th-draw-toolbar__body>.th-draw-action,
  .th-draw-toolbar.is-mobile.is-style-open .th-draw-toolbar__body>.th-draw-group{display:none!important}
}
@media (max-width:360px){.th-draw-toolbar.is-mobile .th-draw-toolbar__body{grid-template-columns:repeat(3,minmax(0,1fr))}}
