/* ============================================================================
 * TRADEIZ — Aggregation full-data pages
 * Routes: /movers, /sentiment, /liquidations
 *
 * Design rule (locked by product):
 *   ALL text is strictly black/white — var(--tt-fg-0..3).
 *   Color is NEVER used in this stylesheet. No red/green for any field.
 *   The only non-neutral visuals allowed:
 *     - Side pill (LONG / SHORT): bold text only, background neutral grey
 *     - Active tab underline: var(--tt-fg-0) — the brightest neutral
 *     - Focus ring on inputs: var(--tt-fg-0)
 *   Hover on interactive elements: var(--tt-fg-0) — brighter neutral only.
 * ============================================================================ */

/* [FIX] 2026-04-24 — .header-wrapper is position:fixed (height ~70px desktop,
 * 54px mobile). Without compensating padding-top the content is hidden under
 * the nav bar. flex:1 needed because #page.page is display:flex/column
 * (custom.css L400) — without it footer floats up against the last table row. */
.tt-agg {
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  font-family: 'Inter', 'Plus Jakarta Sans', sans-serif;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  min-height: calc(100vh - 70px);
  flex: 1;
  padding: 120px 0 80px;
}

.tt-agg .container { max-width: 1300px; padding-left: 24px; padding-right: 24px; }

.tt-agg__head {
  margin-bottom: 24px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}

.tt-agg__back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 400;
  color: var(--tt-fg-0);
  text-decoration: none;
  margin-bottom: 12px;
  transition: color .12s ease;
}
.tt-agg__back::before {
  content: '\2039';
  font-size: 16px;
  line-height: 1;
}
.tt-agg__back:hover { color: var(--tt-fg-0); text-decoration: none; }

.tt-agg__title,
.tt-liqpage__title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--tt-fg-0);
  margin: 0;
}
.tt-agg__title-icon {
  display: inline-flex;
  flex-shrink: 0;
  width: var(--web-icon-size);
  height: var(--web-icon-size);
  color: var(--tt-fg-0);
}
.tt-agg__title-icon svg {
  width: var(--web-icon-size);
  height: var(--web-icon-size);
  display: block;
  stroke: var(--tt-fg-0);
  fill: none;
  stroke-width: var(--web-icon-stroke);
}

.tt-agg__subtitle {
  font-size: 14px;
  color: var(--tt-fg-0);
  font-weight: 400;
  margin-top: 6px;
}

.tt-agg__meta {
  font-size: 12px;
  color: var(--tt-fg-0);
  display: flex;
  align-items: center;
  gap: 12px;
}

.tt-agg__export-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 12px;
  border-radius: 8px;
  border: 1px solid var(--tt-line);
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color .12s ease, opacity .12s ease;
}
.tt-agg__export-btn:hover { border-color: var(--tt-fg-0); }
.tt-agg__export-btn.is-disabled,
.tt-agg__export-btn[disabled] {
  opacity: .55;
  cursor: not-allowed;
}

/* ── Page actions menu (⋯ replaces Export CSV button) ───────────────────── */
.tt-agg__page-menu {
  position: relative;
  flex-shrink: 0;
}
.tt-agg__page-menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 8px;
  border: 1px solid var(--tt-line);
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  cursor: pointer;
  transition: border-color .12s ease;
}
.tt-agg__page-menu-btn svg { width: var(--web-icon-size); height: var(--web-icon-size); stroke: var(--tt-fg-0); fill: none; stroke-width: var(--web-icon-stroke); }
.tt-agg__page-menu-btn:hover { border-color: var(--tt-fg-0); }
.tt-agg__page-menu-pop {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 168px;
  padding: 4px;
  border-radius: 8px;
  border: 1px solid var(--tt-line);
  background: var(--tt-bg-2);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .22);
  z-index: 30;
}
.tt-agg__page-menu-pop[hidden] { display: none !important; }
.tt-agg__page-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--tt-fg-0);
  font-size: 14px;
  font-weight: 400;
  cursor: pointer;
  text-align: left;
}
.tt-agg__page-menu-item svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  stroke: var(--tt-fg-0);
  fill: none;
}
.tt-agg__page-menu-item:hover { background: var(--tt-bg-3); }
.tt-agg__page-menu-item.is-disabled {
  opacity: .55;
  cursor: not-allowed;
}

/* ── Toolbar (search + filters) ──────────────────────────────────────────── */
.tt-agg__toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 20px;
  padding: 12px 0;
  background: transparent;
}

.tt-agg__toolbar-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tt-agg__toolbar-label {
  font-size: 12px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--tt-fg-0);
}

.tt-agg__input,
.tt-agg__select {
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  border: 1px solid var(--tt-line);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 14px;
  font-family: inherit;
  min-width: 120px;
  outline: none;
  transition: border-color .12s ease;
}
.tt-agg__input:focus,
.tt-agg__select:focus { border-color: var(--tt-fg-0); }

.tt-agg__input::placeholder { color: var(--tt-fg-3); }

.tt-agg__select {
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--tt-fg-2) 50%),
                    linear-gradient(135deg, var(--tt-fg-2) 50%, transparent 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 26px;
}

/* [FIX] 2026-06-11 — trades threshold dropdown option contrast in dark theme.
 * Reason: some UAs rendered native option popup with a light background while
 * inheriting white text from .tt-agg__select, making options unreadable.
 * Change: force option foreground/background to current theme vars.
 * Warning: keep using --tt-fg-0/--tt-bg-0 for theme parity. */
.tt-agg__select option {
  color: var(--tt-fg-0);
  background: var(--tt-bg-0);
}

.tt-agg__select option:checked,
.tt-agg__select option:hover,
.tt-agg__select option:focus {
  color: var(--tt-bg-0);
  background: var(--tt-fg-0);
}

.tt-liqlive__select option {
  color: var(--tt-fg-0);
  background: var(--tt-bg-0);
}

.tt-liqlive__select option:checked,
.tt-liqlive__select option:hover,
.tt-liqlive__select option:focus {
  color: var(--tt-bg-0);
  background: var(--tt-fg-0);
}

/* ── Tab bar ─────────────────────────────────────────────────────────────── */
.tt-agg__tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--tt-line);
  margin-bottom: 16px;
}

.tt-agg__tab {
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color .12s ease, border-color .12s ease;
  font-family: inherit;
}
.tt-agg__tab:hover { color: var(--tt-fg-0); }
.tt-agg__tab.is-active {
  color: var(--tt-fg-0);
  border-bottom-color: var(--tt-fg-0);
}

/* [FIX] 2026-06-12 — dex movers tabs active state and icons
 * Reason: flatten rules zeroed .tt-agg__tab borders so is-active underline
 *   was invisible; tabs were plain label text with no icon affordance.
 * Change: sc-tab-ico layout + pill inverted-fill active on movfund rail only.
 * Warning: do NOT add .tt-agg__tab to the global inverted-fill block — other
 *   agg pages (movers rank, funding detail) keep underline semantics. */
.tt-agg .sc-tab-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: inherit;
}
.tt-agg .sc-tab-ico svg {
  display: block;
  width: 14px;
  height: 14px;
  stroke: currentColor;
  fill: none;
}
.tt-agg .sc-tab-label {
  min-width: 0;
  line-height: 1.2;
}
#tt-dex-whales .tt-agg__tabs,
#tt-dex-funding-arb .tt-agg__tabs {
  gap: 6px;
  border-bottom: none;
  margin-bottom: 12px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
#tt-dex-whales .tt-agg__tabs::-webkit-scrollbar,
#tt-dex-funding-arb .tt-agg__tabs::-webkit-scrollbar {
  display: none;
}
#tt-dex-whales .tt-agg__tab,
#tt-dex-funding-arb .tt-agg__tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  border-radius: 6px;
  border: 0;
  border-bottom: none;
  padding: 8px 14px;
  opacity: 0.55;
  transition: opacity .12s ease, background .12s ease, color .12s ease;
}
#tt-dex-whales .tt-agg__tab:hover,
#tt-dex-funding-arb .tt-agg__tab:hover {
  opacity: 0.85;
}
#tt-dex-whales .tt-agg__tab.is-active,
#tt-dex-funding-arb .tt-agg__tab.is-active {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
  opacity: 1;
  border-bottom: none;
}
#tt-dex-movfund-sec .tt-dex-movfund__tabs {
  gap: 6px;
  border-bottom: none;
  margin-bottom: 12px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
#tt-dex-movfund-sec .tt-dex-movfund__tabs::-webkit-scrollbar {
  display: none;
}
#tt-dex-movfund-sec .tt-agg__tab {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  border-radius: 6px;
  border: 0;
  border-bottom: none;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  opacity: 0.55;
  transition: opacity .12s ease, background .12s ease, color .12s ease;
}
#tt-dex-movfund-sec .tt-agg__tab:hover {
  opacity: 0.85;
}
#tt-dex-movfund-sec .tt-agg__tab.is-active {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
  opacity: 1;
  border-bottom: none;
}

/* ── Data table ──────────────────────────────────────────────────────────── */
.tt-agg__table-wrap {
  background: transparent;
  overflow-x: auto;
}

.tt-agg__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.tt-agg__table thead th {
  position: sticky;
  top: 0;
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  font-weight: 400;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  /* [CHANGE] 2026-05-11 — see tbody td note above. */
  text-align: left;
  padding: 10px 14px;
  border: 0;
  border-bottom: 1px solid var(--tt-line);
  white-space: nowrap;
  user-select: none;
}
.tt-agg__table thead th:first-child {
  /* [CHANGE] 2026-05-11 — first-column header now uses the same padding as
   * the matching tbody td:first-child so the "#" header sits exactly above
   * the rank digits. Previously thead had padding-left:0 while tbody had
   * padding:0 8px 0 6px, which shifted the column header ~6px left of the
   * rank numbers and looked misaligned. */
  text-align: left;
  padding: 10px 6px 10px 8px;
}
.tt-agg__table thead th.is-sortable { cursor: pointer; }
.tt-agg__table thead th.is-sortable:hover { color: var(--tt-fg-0); }
.tt-agg__table thead th.is-sortable .sort-arrow {
  display: inline-block;
  margin-left: 4px;
  color: var(--tt-fg-0);
  font-size: 12px;
}
.tt-agg__table thead th.is-sorted .sort-arrow { color: var(--tt-fg-0); }

/* [FIX] 2026-05-09 P2-2 — generic agg-table row click → /chart removed,
   so default cursor. Pages that still have a real destination (e.g.
   /trades → /trades/:base) override cursor:pointer below. */
.tt-agg__table tbody tr {
  border: 0;
  cursor: default;
  transition: background .08s ease;
}
.tt-agg__table tbody tr:hover { background: var(--tt-bg-2); }

.tt-agg__table tbody td {
  padding: 10px 14px;
  /* [CHANGE] 2026-05-11 — default td alignment flipped from right → left.
   * Reason: product asked for "all columns left-aligned" across every
   * aggregation table for visual consistency with /new-listings + /unlocks.
   * Pages that still need right-aligned numeric helpers (rank `:first-child`,
   * legacy `.num`) keep their explicit right-alignment overrides below.
   * The opt-in `.tt-agg__td--left` class is preserved so existing JS that
   * emits it stays harmless (and keeps the unified padding). */
  text-align: left;
  white-space: nowrap;
  color: var(--tt-fg-0);
  vertical-align: middle;
  border: 0;
}
.tt-agg__table tbody td:first-child {
  /* [CHANGE] 2026-05-11 — flip rank column from right → left so the "#"
   * header (now left-aligned in the global flatten) and the rank digits
   * (1/2/3…) line up vertically. Width kept at 32px so the column stays
   * narrow regardless of digit count up to 3 chars. */
  text-align: left;
  padding: 10px 6px 10px 8px;
  width: 32px;
  white-space: nowrap;
}

/* [FIX] 2026-04-25 — explicit left-align utility for Symbol column.
 * Reason: default `.tt-agg__table tbody td { text-align: right }` only
 *         leaves the 1st column left-aligned via :first-child. But every
 *         data table on /funding has `#` as col 1 and `Symbol` as col 2,
 *         so the symbol/coin pair was rendered RIGHT-aligned and broke
 *         the visual rhythm vs the row icon (which sits at the left edge).
 * Change: add `.tt-agg__th--left` / `.tt-agg__td--left` to opt-in to
 *         left-alignment from the JS render layer (renderers were already
 *         emitting these classes — they just had no CSS rule).
 *         Use a high-specificity selector so it wins over the default
 *         right-align on tbody td. */
.tt-agg__table thead th.tt-agg__th--left,
.tt-agg__table tbody td.tt-agg__td--left {
  text-align: left;
}
/* [FIX] 2026-05-04 — unify column spacing on pages that mark content
 * columns with `tt-agg__td--left` (DEX Perps Overview / Whale Tracker /
 * Funding Arbitrage / Whale Address Detail all have NO rank column,
 * so the first content column fell through to the `:first-child`
 * rank-column rule which uses `padding: 0 6px` + `width: 32px`. That
 * made the gap between col-1 and col-2 ≈10px while every other pair
 * was ~28px, looking visibly lopsided).
 * Change: whenever a cell (or header) carries `tt-agg__td--left`
 * (`tt-agg__th--left`) keep the standard 10px 14px table padding
 * regardless of column position, and clear the rank-column width
 * constraint. Pages that DO want a narrow rank column (movers /
 * sentiment / liquidations / funding) just omit the `--left` class
 * on column 1 — they are unaffected.
 * Warning: do not lower either padding value back to 4/6/8 — it is
 *   what restores the even 28px gutter across every content column. */
.tt-agg__table thead th.tt-agg__th--left,
.tt-agg__table tbody td.tt-agg__td--left {
  padding: 10px 14px;
  width: auto;
}

/* [FIX] 2026-07-05 — restore right-align for `.num` columns (regression since
 * 2026-05-11 default-left flip). JS renderers across DEX / funding / trades
 * still emit `class="num"` for numeric cols; without this rule PnL $ cols
 * looked left-aligned while integer cols only appeared right by accident. */
.tt-agg__table thead th.num,
.tt-agg__table tbody td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.tt-agg__rank {
  display: inline-block;
  min-width: 20px;
  font-size: 12px;
  font-weight: 400;
  color: var(--tt-fg-0);
  /* [CHANGE] 2026-05-11 — match the parent td:first-child left-align so
   * single-digit (1) and double-digit (10) ranks share a stable left edge
   * directly under the "#" header. */
  text-align: left;
  flex-shrink: 0;
}

.tt-agg__sym-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}
.tt-agg__sym-name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 400;
  color: var(--tt-fg-0);
  font-size: 14px;
  min-width: 0;
  max-width: 100%;
}
.tt-agg__sym-name > span:not(.tt-coin-icon) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tt-agg__sym-meta {
  font-size: 12px;
  color: var(--tt-fg-0);
  margin-top: 2px;
}
.tt-agg__sym-text { display: flex; flex-direction: column; }

/* Coin icon (reuse same circular wrapper as home page)
 * [UPDATE] 2026-04-28 — unified to 32px across home + all aggregation pages
 * (movers / sentiment / liquidations / trades). Chart page uses .coin-icon
 * (different class, app.css), so this change does NOT affect chart.
 * Reason: industry convention (Coinglass / TradingView / Bybit) uses 32px
 * coin logos on listing/detail pages for instant brand recognition. */
.tt-coin-icon {
  display: inline-flex;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--tt-bg-3);
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}
.tt-coin-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.tt-coin-icon__fb {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  background: var(--tt-bg-3);
}

/* ── Value styles — strictly black/white only ────────────────────────────── */
.tt-agg__val--mono { color: var(--tt-fg-0); font-weight: 400; }
.tt-agg__val--dim  { color: var(--tt-fg-0); }

/* Side pill: no border, neutral background */
.tt-agg__pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  background: var(--tt-bg-3);
  color: var(--tt-fg-0);
}

/* ── Empty / loading states ──────────────────────────────────────────────── */
.tt-agg__empty {
  padding: 60px 20px;
  text-align: center;
  color: var(--tt-fg-0);
  font-size: 14px;
}

.tt-agg__skel-row td {
  text-align: left !important;
}
.tt-agg__skel {
  display: inline-block;
  height: 12px;
  width: 80%;
  background: linear-gradient(90deg, var(--tt-bg-2) 0%, var(--tt-bg-3) 50%, var(--tt-bg-2) 100%);
  background-size: 200% 100%;
  border-radius: 4px;
  animation: tt-agg-shimmer 1.4s ease-in-out infinite;
}
@keyframes tt-agg-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Pagination ──────────────────────────────────────────────────────────── */
.tt-agg__pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 16px;
  flex-wrap: wrap;
}

.tt-agg__pager-info {
  font-size: 12px;
  color: var(--tt-fg-0);
}

.tt-agg__pager-controls {
  display: flex;
  align-items: center;
  gap: 6px;
}

.tt-agg__pager-btn {
  background: var(--tt-bg-1);
  color: var(--tt-fg-0);
  border: 1px solid var(--tt-line);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
  min-width: 36px;
}
.tt-agg__pager-btn:hover:not(:disabled) {
  color: var(--tt-fg-0);
  border-color: var(--tt-fg-0);
}
.tt-agg__pager-btn:disabled {
  color: var(--tt-fg-0);
  cursor: not-allowed;
  opacity: 0.4;
}
.tt-agg__pager-btn.is-active {
  color: var(--tt-bg-0);
  background: var(--tt-fg-0);
  border-color: var(--tt-fg-0);
}

.tt-agg__pager-size {
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  border: 1px solid var(--tt-line);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 12px;
  font-family: inherit;
}

/* Fixed signup CTA on aggregation pages (SEO / conversion) */
.tt-agg {
  padding-bottom: 72px;
}
.tt-agg__signup-cta {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 0;
  padding: 14px 18px;
  background: var(--tt-bg-2);
  border: 1px solid var(--tt-line);
  border-radius: 0;
  max-width: 100%;
}
.tt-agg__signup-cta-text {
  margin: 0;
  flex: 1 1 200px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--tt-fg-0);
}
.tt-agg__signup-cta-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 600;
  color: var(--tt-bg-0);
  background: var(--tt-fg-0);
  border-radius: 6px;
  text-decoration: none;
}
.tt-agg__signup-cta-btn:hover {
  color: var(--tt-bg-0);
  text-decoration: none;
  opacity: 0.92;
}

/* ── Responsive (table/toolbar only — page padding lives in safety-net §2–5) */
@media (max-width: 768px) {
  .tt-agg__title { font-size: 22px; }
  .tt-agg__table thead th,
  .tt-agg__table tbody td { padding: 10px 8px; font-size: 12px; }
  /* [FIX] 2026-05-04 — mobile override for the new td--left uniform padding.
   * Without this the desktop 10px 14px wins on specificity and left-aligned
   * cells end up visibly wider than right-aligned ones on narrow screens. */
  .tt-agg__table thead th.tt-agg__th--left,
  .tt-agg__table tbody td.tt-agg__td--left { padding: 10px 8px; }
  .tt-agg__toolbar { padding: 10px; }
  .tt-agg__toolbar-group { flex-basis: 100%; }
  .tt-agg__input,
  .tt-agg__select { min-width: 0; flex: 1; }
}

/* ============================================================================
 * /liquidations — Real-time liquidations page (Zone A/B/C/D)
 *
 * Styling rules (locked by .cursor/rules/web_app_styling.mdc):
 *   - color: only var(--tt-fg-0) for text, except listed exceptions
 *     (LONG/SHORT pills use --tt-up/--tt-down — financial UA convention).
 *   - font-size: only {12, 14, 16, 18, 20, 22} px.
 *   - placeholder: var(--tt-fg-3) is allowed by exception list.
 * ============================================================================ */

/* ── Page head ────────────────────────────────────────────────────────────── */
.tt-liqpage__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.tt-liqpage__head-left { display: flex; flex-direction: column; gap: 4px; }
.tt-liqpage__head-right { display: flex; align-items: center; justify-content: flex-end; }
.tt-liqpage__title {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--tt-fg-0);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.tt-liqpage__sub {
  font-size: 12px;
  color: var(--tt-fg-0);
}

/* ── Liquidations page tabs (Live · Breakdown · Analysis) ─────────────── */
.tt-liq-tabs {
  display: flex;
  gap: 6px;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 4px;
  margin-bottom: 20px;
  border: 1px solid var(--tt-line);
  border-radius: 10px;
  background: var(--tt-bg-1);
  position: sticky;
  top: 0;
  z-index: 20;
}
.tt-liq-tabs::-webkit-scrollbar { display: none; }

.tt-liq-tabs__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 400;
  font-family: inherit;
  color: var(--tt-fg-0);
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
  white-space: nowrap;
}
.tt-liq-tabs__btn:hover { background: var(--tt-bg-2); }
.tt-liq-tabs__btn.is-active {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
}

.tt-liq-tabs__icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: inherit;
}
.tt-liq-tabs__icon svg {
  stroke: var(--tt-fg-0);
  fill: none;
}

.tt-liq-pane { margin-bottom: 0; }
.tt-liq-pane.is-hidden { display: none; }

/* [FIX] 2026-06-11 — Live tab Row 3: 2×2 CSS grid so bottom pair (top symbols +
   live feed) share one horizontal row and equal height. Top row: exchange + KPI. */
.tt-liqsplit--merged {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: auto minmax(280px, 1fr);
  align-items: stretch;
}
.tt-liqsplit--merged > .tt-liqbyex {
  grid-column: 1;
  grid-row: 1;
  margin-bottom: 0;
  min-height: 0;
}
.tt-liqsplit--merged > .tt-liqkpi-rail {
  grid-column: 2;
  grid-row: 1;
  align-self: start;
}
.tt-liqsplit--merged > .tt-liqtop-section {
  grid-column: 1;
  grid-row: 2;
  margin-bottom: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.tt-liqsplit--merged > .tt-liqlive {
  grid-column: 2;
  grid-row: 2;
  margin-bottom: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.tt-liqsplit--merged .tt-liqtop {
  flex: 1;
  min-height: 0;
  max-height: none;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tt-liqsplit--merged .tt-liqlive__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tt-liqsplit--merged .tt-liqlive__list {
  flex: none;
  min-height: 0;
  max-height: none;
  overflow: visible;
}

.tt-liqpage__windowbar {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--tt-line);
  border-radius: 8px;
  background: var(--tt-bg-1);
}
.tt-liqpage__winbtn {
  background: transparent;
  color: var(--tt-fg-0);
  border: 0;
  border-radius: 6px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 400;
  font-family: inherit;
  cursor: pointer;
  transition: background .12s ease;
}
.tt-liqpage__winbtn:hover { background: var(--tt-bg-2); }
.tt-liqpage__winbtn.is-active {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
}

/* ── Zone E (right): vertical KPI rail next to Exchange leaderboard ──────── */
/* [ADD] 2026-04-24 — replaces the old 6-cell horizontal .tt-liqkpi strip.
   Reason: layout request — KPI cards moved below the heatmap into a 1-column
   stack on the right (3/10 width); left 7/10 holds the exchange leaderboard.
   The rail is sized by the parent split column (flex: 1) so the table on the
   left and the rail on the right are visually balanced even with 6 KPI cells. */
.tt-liqkpi-rail {
  background: var(--tt-bg-1);
  border: 1px solid var(--tt-line);
  border-radius: 10px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.tt-liqkpi-rail__cell {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: var(--tt-bg-2);
  border-radius: 8px;
  min-width: 0;
}
.tt-liqkpi-rail__label {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tt-liqkpi-rail__value {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  text-align: right;
}
/* [EXCEPTION] LONG/SHORT direction colors are financial UA convention */
.tt-liqkpi__value--up   { color: var(--tt-up); }
.tt-liqkpi__value--down { color: var(--tt-down); }

/* ── Common section container ─────────────────────────────────────────────── */
.tt-liqsection {
  background: var(--tt-bg-1);
  border: 1px solid var(--tt-line);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
.tt-liqsection__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.tt-liqsection__title {
  font-size: 16px;
  font-weight: 700;
  color: var(--tt-fg-0);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.tt-liq-window-badge {
  flex-shrink: 0;
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
  border-color: var(--tt-fg-0);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: lowercase;
}
.tt-liqkpi-rail__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0 4px 4px;
  flex-shrink: 0;
}
.tt-liqkpi-rail__head-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--tt-fg-0);
}
.tt-liqsection__sub {
  font-size: 12px;
  color: var(--tt-fg-0);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* ── Zone B: Heatmap ──────────────────────────────────────────────────────── */
.tt-liqheat {
  position: relative;
  width: 100%;
  height: 360px;
  background: var(--tt-bg-0);
  border-radius: 8px;
  overflow: hidden;
}
/* [FIX] 2026-05-09 P2-2 — heatmap cell click → /chart removed; cursor default. */
.tt-liqheat__cell {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: default;
  transition: filter .12s ease;
  overflow: hidden;
  text-align: center;
  padding: 2px;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-liqheat__cell:hover,
.tt-liqheat__cell.is-heat-active { filter: brightness(1.15); }
.tt-liqheat__sym {
  font-weight: 700;
  line-height: 1.1;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}
.tt-liqheat__val {
  font-weight: 600;
  line-height: 1.1;
  opacity: 0.85;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}
.tt-liqheat__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--tt-fg-0);
  font-size: 14px;
}

/* ── Split layout for Zone C / D ──────────────────────────────────────────── */
/* align-items:stretch — columns share equal height; inner lists flex-fill remaining space. */
.tt-liqsplit {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 20px;
  align-items: stretch;
  margin-bottom: 20px;
}
.tt-liqsplit__col {
  margin-bottom: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* Section cards inside split columns must fill column height */
.tt-liqsplit__col .tt-liqsection {
  flex: 1;
  min-height: 0;
  margin-bottom: 0;
}

/* ── Zone C: Top symbols leaderboard ──────────────────────────────────────── */
.tt-liqsplit__col .tt-liqtop {
  flex: 1;
  min-height: 0;
  max-height: 80vh;
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tt-liqtop {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.tt-liqtop__head,
.tt-liqtop__row {
  display: grid;
  --tt-liqtop-ls-w: 120px;
  grid-template-columns:
    24px
    minmax(0, 1fr)
    minmax(24px, var(--tt-liqtop-ls-w))
    minmax(68px, 80px)
    40px;
  column-gap: 12px;
  row-gap: 8px;
  align-items: center;
  padding: 6px 8px;
  box-sizing: border-box;
}
.tt-liqtop__head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--tt-bg-1);
  border-bottom: 1px solid var(--tt-line);
  margin-bottom: 4px;
  align-items: center;
}
.tt-liqtop__col {
  font-size: 12px;
  color: var(--tt-fg-0);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tt-liqtop__col--total,
.tt-liqtop__col--share {
  text-align: right;
}
.tt-liqtop__col--ls {
  text-align: right;
  justify-self: stretch;
}
.tt-liqtop__pair {
  min-width: 0;
  overflow: hidden;
}
.tt-liqtop__pair .tt-agg__sym-cell {
  min-width: 0;
}
.tt-liqtop__pair .tt-agg__sym-text {
  min-width: 0;
  overflow: hidden;
}
.tt-liqtop__pair .tt-agg__sym-meta {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tt-liqtop__pair .tt-coin-icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}
/* [FIX] 2026-05-09 P2-2 — top-row click → /chart removed; cursor default. */
.tt-liqtop__row {
  border-radius: 6px;
  cursor: default;
  transition: background .08s ease;
  align-items: center;
}
.tt-liqtop__row:hover { background: var(--tt-bg-2); }
.tt-liqtop__rank {
  font-size: 12px;
  color: var(--tt-fg-0);
  font-weight: 400;
  text-align: right;
  flex-shrink: 0;
}
.tt-liqtop__sym {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tt-liqtop__bar {
  display: flex;
  align-items: stretch;
  justify-self: end;
  width: 100%;
  min-width: 24px;
  max-width: var(--tt-liqtop-ls-w, 96px);
  height: 8px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--tt-bg-0);
}
/* [EXCEPTION] long/short bar tint follows direction convention */
.tt-liqtop__bar-long  { background: var(--tt-up); }
.tt-liqtop__bar-short { background: var(--tt-down); }
.tt-liqtop__val {
  font-size: 14px;
  color: var(--tt-fg-0);
  font-weight: 400;
  text-align: right;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  white-space: nowrap;
  flex-shrink: 0;
}
.tt-liqtop__share {
  font-size: 12px;
  color: var(--tt-fg-0);
  text-align: right;
  white-space: nowrap;
  flex-shrink: 0;
}
.tt-liqtop__empty {
  padding: 24px;
  text-align: center;
  color: var(--tt-fg-0);
  font-size: 14px;
}

/* ── Zone D: Real-time tape ───────────────────────────────────────────────── */
/* Top bar: title + status left, filters right — all on one line */
.tt-liqlive__topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--tt-line);
  flex-shrink: 0;
}
.tt-liqlive__topbar-left {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.tt-liqlive__topbar-left .tt-liqsection__title {
  margin: 0;
  white-space: nowrap;
}
.tt-liqlive__filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  flex: 1;
  min-width: 0;
}
.tt-liqlive__field {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.tt-liqlive__field-label {
  font-size: 12px;
  font-weight: 400;
  color: var(--tt-fg-0);
  white-space: nowrap;
}
/* [FIX] 2026-05-02 — unify all exchange + coin icons to 32px per user
   product request ("所有的交易所和币 都要有32px的图标"). The smaller
   filter-dropdown variant keeps its own size via .tt-exchange-icon--filter.
   Chart page uses /images/logos/*.png via EXCHANGE_GROUPS; same assets here. */
.tt-exchange-icon-wrap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  overflow: hidden;
  border-radius: 6px;
}
.tt-exchange-icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
  display: block;
  border-radius: 6px;
  /* white tray so dark-theme logos (white PNGs) are always visible */
  background: rgba(255, 255, 255, 0.15);
  padding: 3px;
}
.tt-exchange-icon__fb {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  background: rgba(255, 255, 255, 0.15);
}
.tt-liqlive__exchange-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  width: 100%;
}
.tt-liqlive__exchange-icon-slot {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
}
.tt-liqlive__exchange-icon-slot .tt-exchange-icon--filter {
  width: 22px;
  height: 22px;
  background: rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  padding: 2px;
}
.tt-liqlive__select,
.tt-liqlive__input {
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  border: 1px solid var(--tt-line);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 14px;
  font-family: inherit;
  outline: none;
  min-width: 140px;
  transition: border-color .12s ease;
}
/* Must follow .tt-liqlive__select — two-class rule beats single-class min-width:140px so icon is not squeezed off */
.tt-liqlive__select.tt-liqlive__select--inrow {
  flex: 1;
  min-width: 0;
  width: auto;
}
.tt-liqlive__select:focus,
.tt-liqlive__input:focus { border-color: var(--tt-fg-0); }
/* [EXCEPTION] placeholder uses tt-fg-3 per UA exception list */
.tt-liqlive__input::placeholder { color: var(--tt-fg-3); }
.tt-liqlive__chips {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
.tt-liqlive__chip {
  background: var(--tt-bg-0);
  color: var(--tt-fg-0);
  border: 1px solid var(--tt-line);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 400;
  font-family: inherit;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.tt-liqlive__chip:hover { border-color: var(--tt-fg-0); }
.tt-liqlive__chip.is-active {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
  border-color: var(--tt-fg-0);
}

/* Real-time tape: at most 5000 rows kept in JS buffer (LIVE_TAPE_BUFFER_MAX),
   at most 500 rendered to DOM (LIVE_TAPE_RENDER_MAX) — see tt.liquidations.js.
   [FIX] 2026-04-24 — list is the scrolling container; head sits inside as
   a position:sticky child so head + rows share scrollbar gutter exactly
   (industry-standard sticky-header-in-scroller pattern).
   [FIX] 2026-06-11 — .tt-liqlive__body is the scroller on merged layout;
   legacy path keeps .tt-liqlive__list as scroller when body wrapper absent. */
.tt-liqlive__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tt-liqlive__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-height: 0;
  max-height: 74vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ── Tape grid (8 tracks, no Pair column) ───────────────────────────────────
   Symbol · Time · Side · Exchange · Price · Qty · Value · ↗ */
.tt-liqlive__head,
.tt-liqlive__row {
  display: grid;
  grid-template-columns:
    minmax(100px, 1.4fr)    /* symbol (icon + full pair) */
    58px                    /* time     */
    48px                    /* side tag */
    minmax(90px, 1.2fr)     /* exchange (icon + name) */
    minmax(70px, 0.9fr)     /* price */
    minmax(60px, 0.7fr)     /* quantity */
    minmax(62px, 0.8fr)     /* value */
    14px;                   /* go arrow */
  align-items: center;
  column-gap: 6px;
  padding: 3px 8px;
  box-sizing: border-box;
}

.tt-liqlive__head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--tt-bg-1);
  border-bottom: 1px solid var(--tt-line);
  margin-bottom: 4px;
  font-size: 12px;
  color: var(--tt-fg-0);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 400;
  line-height: 1;
  padding-top: 4px;
  padding-bottom: 4px;
}
/* head cells: respect each column's natural alignment (numeric right, text left) */
.tt-liqlive__head .tt-liqlive__price,
.tt-liqlive__head .tt-liqlive__qty,
.tt-liqlive__head .tt-liqlive__val { text-align: right; }
.tt-liqlive__head .tt-liqlive__sidecell { text-align: center; }

/* [EXCEPTION] LONG/SHORT row tint — dark theme uses color-mix, light theme uses fixed low-opacity */
.tt-liqlive__row--long  { background: color-mix(in srgb, var(--tt-up)   15%, transparent); }
.tt-liqlive__row--short { background: color-mix(in srgb, var(--tt-down) 15%, transparent); }
body.theme--light .tt-liqlive__row--long  { background: rgba(8, 153, 129, 0.10); }
body.theme--light .tt-liqlive__row--short { background: rgba(242, 54, 69, 0.10); }
/* [FIX] 2026-05-09 P2-2 — live row click → /chart removed; cursor default.
   The "↗ go" arrow column (.tt-liqlive__go) is now visually decorative;
   it stays in the markup but has no destination. Hover background still
   tints to keep the tape feeling responsive. */
.tt-liqlive__row {
  border-radius: 4px;
  cursor: default;
  transition: background-color .1s ease;
  font-size: 14px;
  color: var(--tt-fg-0);
}
.tt-liqlive__row--long:hover  { background: color-mix(in srgb, var(--tt-up)   25%, transparent); }
.tt-liqlive__row--short:hover { background: color-mix(in srgb, var(--tt-down) 25%, transparent); }
body.theme--light .tt-liqlive__row--long:hover  { background: rgba(8, 153, 129, 0.18); }
body.theme--light .tt-liqlive__row--short:hover { background: rgba(242, 54, 69, 0.18); }

/* All cells share these defaults */
.tt-liqlive__col {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}

.tt-liqlive__time {
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-liqlive__sidecell {
  display: flex;
  align-items: center;
  justify-content: center;
}
.tt-liqlive__sidetag {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.03em;
  padding: 1px 5px;
  border-radius: 4px;
  color: var(--tt-fg-0);
}
/* [EXCEPTION] LONG/SHORT semantic colors */
.tt-liqlive__sidetag--long  { background: color-mix(in srgb, var(--tt-up)   38%, transparent); }
.tt-liqlive__sidetag--short { background: color-mix(in srgb, var(--tt-down) 38%, transparent); }

.tt-liqlive__symcell {
  display: flex;
  align-items: center;
  gap: 6px;
}
.tt-liqlive__sym {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.tt-liqlive__pair {
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-liqlive__vencell {
  display: flex;
  align-items: center;
  gap: 6px;
}
.tt-liqlive__ven {
  font-size: 12px;
  color: var(--tt-fg-0);
  text-transform: capitalize;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.tt-liqlive__mkt {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: 0.7;
  text-transform: uppercase;
}
.tt-liqlive__price {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  text-align: right;
}
.tt-liqlive__qty {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  text-align: right;
}
.tt-liqlive__val {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  text-align: right;
}
.tt-liqlive__go {
  font-size: 14px;
  color: var(--tt-fg-0);
  text-align: right;
  opacity: 0;
  transition: opacity .12s ease;
}
.tt-liqlive__row:hover .tt-liqlive__go { opacity: 1; }
.tt-liqlive__empty {
  padding: 24px;
  text-align: center;
  color: var(--tt-fg-0);
  font-size: 14px;
}

/* Live status dot */
.tt-liqlive__dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tt-fg-3);
}
/* [EXCEPTION] live/paused/failed status indicator follows financial UA */
.tt-liqlive__dot--live    { background: var(--tt-up);  box-shadow: 0 0 6px var(--tt-up); }
.tt-liqlive__dot--paused  { background: var(--tt-fg-3); }
.tt-liqlive__dot--failed  { background: var(--tt-down); }
.tt-liqlive__dot--connecting { background: var(--tt-fg-3); }

/* ── Zone E (left): Exchange leaderboard table ────────────────────────────── */
/* [ADD] 2026-04-24 — replaces the inferred Top exchange KPI cell with a full,
   per-exchange ranked table driven by /agg/liq/byexchange?window=…
   Layout uses a CSS grid header + body so columns align without a real <table>;
   keeps the same look-and-feel as Top liquidated symbols. */
.tt-liqbyex {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* [FIX] 2026-04-24 — column alignment between head and body (v2).
   Reason: previous attempts tried to compensate for the scrollbar gutter
           with a hardcoded padding-right on the head (14px guess). This
           was wrong on every OS / browser combo (Windows Chrome 17px,
           Firefox 16px, macOS overlay 0px). The header sat outside the
           scrolling container so it could never share the same width as
           the rows that DID get clipped by the scrollbar.
   Change: head now lives INSIDE the scrolling container (.tt-liqbyex__body)
           as a position:sticky child, so head + rows are siblings under
           the same overflow ancestor and the browser handles gutter
           reservation automatically. The shared grid-template-columns
           ruleset still applies to both head and row, guaranteeing
           identical column widths.
   Warning: do NOT move .tt-liqbyex__head back outside the body wrapper —
            this regresses the alignment bug. */
.tt-liqbyex__head,
.tt-liqbyex__row {
  display: grid;
  grid-template-columns:
    minmax(110px, 1.6fr)   /* exchange */
    minmax(80px,  1fr)     /* total */
    minmax(80px,  1fr)     /* long */
    minmax(96px,  1.1fr)   /* short — wider min so gap to L/S is clear */
    minmax(148px, 1.5fr)   /* L/S in venue */
    minmax(56px,  0.6fr);  /* market share */
  align-items: center;
  column-gap: 20px;
  padding: 8px 10px;
  box-sizing: border-box;
}
.tt-liqbyex__head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--tt-bg-1);
  border-bottom: 1px solid var(--tt-line);
  margin-bottom: 4px;
}
.tt-liqbyex__col {
  font-size: 12px;
  color: var(--tt-fg-0);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tt-liqbyex__row {
  border-radius: 6px;
  font-size: 14px;
  color: var(--tt-fg-0);
  font-weight: 400;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}
.tt-liqbyex__row + .tt-liqbyex__row { margin-top: 2px; }
.tt-liqbyex__row:hover { background: var(--tt-bg-2); }
.tt-liqbyex__col--ex {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.tt-liqbyex__exname {
  font-size: 14px;
  font-weight: 400;
  color: var(--tt-fg-0);
  text-transform: capitalize;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tt-liqbyex__col--total,
.tt-liqbyex__col--long,
.tt-liqbyex__col--short,
.tt-liqbyex__col--share {
  text-align: right;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.tt-liqbyex__row .tt-liqbyex__col--total { font-size: 14px; font-weight: 400; }
.tt-liqbyex__row .tt-liqbyex__col--long  { color: var(--tt-up); }   /* [EXCEPTION] LONG green */
.tt-liqbyex__row .tt-liqbyex__col--short { color: var(--tt-down); } /* [EXCEPTION] SHORT red */
.tt-liqbyex__col--ratio {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  padding-left: 16px;
  border-left: 1px solid var(--tt-line);
}
.tt-liqbyex__bar {
  position: relative;
  height: 6px;
  background: var(--tt-bg-2);
  border-radius: 3px;
  overflow: hidden;
  display: flex;
}
/* [EXCEPTION] L/S split bar uses up/down semantic colors */
.tt-liqbyex__bar-long  { background: var(--tt-up); }
.tt-liqbyex__bar-short { background: var(--tt-down); }
.tt-liqbyex__ratiotxt {
  font-size: 12px;
  color: var(--tt-fg-0);
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  white-space: nowrap;
}
.tt-liqbyex__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* head is position:sticky inside this scroller; rows wrap natural flow */
}
.tt-liqbyex__rows {
  /* plain block container for the row list; rows handle their own spacing */
}
.tt-liqbyex__empty {
  padding: 24px 12px;
  text-align: center;
  color: var(--tt-fg-0);
  font-size: 14px;
}

/* ── Liquidations responsive ──────────────────────────────────────────────── */

/* ≤992px: tablet — single-column stacked layout */
@media (max-width: 992px) {
  .tt-liqsplit,
  .tt-liqsplit--merged {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    align-items: start;
    gap: 16px;
  }
  .tt-liqsplit--merged > .tt-liqbyex,
  .tt-liqsplit--merged > .tt-liqkpi-rail,
  .tt-liqsplit--merged > .tt-liqtop-section,
  .tt-liqsplit--merged > .tt-liqlive {
    grid-column: 1;
    grid-row: auto;
    min-height: 0;
  }
  .tt-liqsplit__col { display: block; }
  .tt-liqsplit__col .tt-liqsection { flex: none; margin-bottom: 0; }
  .tt-liqheat { height: 280px; }
  .tt-liqsplit--merged .tt-liqtop,
  .tt-liqsplit--merged .tt-liqlive__body,
  .tt-liqsplit__col .tt-liqtop,
  .tt-liqlive__list {
    flex: none;
    max-height: 55vh;
  }
  .tt-liqkpi-rail {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 0;
  }
  .tt-liqkpi-rail__cell {
    flex: 1 1 calc(33% - 8px);
    min-width: 130px;
  }
}

/* ≤768px: mobile — compact everything */
@media (max-width: 768px) {
  .tt-liqpage__title { font-size: 20px; }
  .tt-liqpage__head {
    gap: 10px;
    margin-bottom: 12px;
  }
  .tt-liqsection { padding: 12px; }
  .tt-liqheat { height: 200px; }
  .tt-liqsplit,
  .tt-liqsplit--merged { gap: 12px; margin-bottom: 12px; }

  /* topbar: title+dot one row, filters stacked below */
  .tt-liqlive__topbar {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding-bottom: 8px;
    margin-bottom: 8px;
  }
  .tt-liqlive__topbar-left {
    width: 100%;
  }
  .tt-liqlive__filters {
    width: 100%;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
  .tt-liqlive__field {
    width: 100%;
    flex-direction: row;
    align-items: center;
    gap: 8px;
  }
  .tt-liqlive__field-label {
    flex-shrink: 0;
    min-width: 88px;
  }
  .tt-liqlive__select,
  .tt-liqlive__input {
    flex: 1;
    min-width: 0;
    font-size: 14px;
    padding: 5px 8px;
  }
  .tt-liqlive__exchange-row { flex: 1; min-width: 0; }
  .tt-liqlive__chips { flex-wrap: nowrap; gap: 4px; }
  .tt-liqlive__chip { font-size: 12px; padding: 2px 7px; }

  /* live tape: drop qty / go, keep Symbol · Time · Side · Exchange · Price · Value */
  .tt-liqlive__head,
  .tt-liqlive__row {
    grid-template-columns:
      minmax(72px, 1fr) /* symbol */
      46px              /* time */
      40px              /* side */
      minmax(64px, 1fr) /* exchange */
      minmax(56px, auto)/* price */
      minmax(52px, auto);/* value */
    column-gap: 4px;
    padding: 3px 6px;
  }
  .tt-liqlive__qty,
  .tt-liqlive__mkt,
  .tt-liqlive__go { display: none; }
  .tt-liqlive__list { max-height: 50vh; }
  .tt-liqlive__time { font-size: 12px; }
  .tt-liqlive__sym  { font-size: 12px; }
  .tt-liqlive__ven  { font-size: 12px; }
  .tt-liqlive__price,
  .tt-liqlive__val  { font-size: 12px; }

  /* KPI rail: 2-column grid on mobile */
  .tt-liqkpi-rail {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    padding: 10px;
  }
  .tt-liqkpi-rail__cell {
    flex: none;
    min-width: 0;
    padding: 8px 10px;
    gap: 6px;
  }
  .tt-liqkpi-rail__label,
  .tt-liqkpi-rail__value { font-size: 14px; }

  /* top symbols table */
  .tt-liqtop__head,
  .tt-liqtop__row {
    --tt-liqtop-ls-w: 96px;
    grid-template-columns:
      20px
      minmax(0, 1fr)
      minmax(20px, var(--tt-liqtop-ls-w))
      minmax(56px, 72px)
      36px;
    column-gap: 8px;
    row-gap: 6px;
    padding: 5px 6px;
  }
  .tt-liqtop__sym { font-size: 14px; }
  .tt-liqtop__val { font-size: 14px; }

  /* byex table: drop ratio column */
  .tt-liqbyex__head,
  .tt-liqbyex__row {
    grid-template-columns:
      minmax(88px, 1.3fr)
      minmax(68px, 1fr)
      minmax(68px, 1fr)
      minmax(76px, 1.1fr)
      minmax(52px, 0.55fr);
    gap: 10px;
    padding: 5px 8px;
    font-size: 14px;
  }
  .tt-liqbyex__col--ratio { display: none; }
  .tt-liqbyex__exname { font-size: 14px; }
}

/* ≤480px: small phone — further simplify live tape */
@media (max-width: 480px) {
  .tt-agg .container { padding-left: 12px; padding-right: 12px; }
  .tt-liqheat { height: 160px; }

  /* tiny tape: Symbol · Time · Side · Value only */
  .tt-liqlive__head,
  .tt-liqlive__row {
    grid-template-columns:
      minmax(60px, 1fr) /* symbol */
      42px              /* time */
      36px              /* side */
      minmax(52px, auto);/* value */
    column-gap: 4px;
    padding: 3px 4px;
  }
  .tt-liqlive__vencell,
  .tt-liqlive__price { display: none; }

  /* topbar field label narrower */
  .tt-liqlive__field-label { min-width: 68px; }

  /* KPI rail: stack 2 per row but smaller */
  .tt-liqkpi-rail__label,
  .tt-liqkpi-rail__value { font-size: 12px; }
  .tt-liqkpi-rail__cell { padding: 6px 8px; }

  /* byex: drop short + ratio, keep exchange/total/long/share */
  .tt-liqbyex__head,
  .tt-liqbyex__row {
    grid-template-columns:
      minmax(80px, 1.4fr)
      minmax(62px, 1fr)
      minmax(62px, 1fr)
      minmax(48px, 0.6fr);
    gap: 4px;
    font-size: 12px;
  }
  .tt-liqbyex__col--short,
  .tt-liqbyex__col--ratio { display: none; }
  .tt-liqbyex__exname { font-size: 12px; }

  .tt-liqtop__head,
  .tt-liqtop__row {
    --tt-liqtop-ls-w: 72px;
    grid-template-columns:
      18px
      minmax(0, 1fr)
      minmax(20px, var(--tt-liqtop-ls-w))
      minmax(52px, 64px)
      32px;
    column-gap: 6px;
    row-gap: 4px;
  }
}

/* ============================================================================
 * [ADD] 2026-04-24 — /funding + /sentiment composite-page styles
 * Reason: new 7-section composite layouts for /funding (KPI/flow/arb/treemap/
 *         cross/settlements/history) and /sentiment (greed gauge/factor radar/
 *         L/S heatmap/liq pressure/divergence/crowd/history). All variables
 *         re-use existing --tt-* tokens; only black/white text and the
 *         pre-approved up/down semantic colours per the styling rule.
 * ============================================================================ */

/* [REMOVED] 2026-05-11 — `.tt-sent-tabs` / `.tt-sent-tab` / `.tt-sent-pane`
 * deleted with the /sentiment monolith split into three independent URLs
 * (overview / positioning / funding-oi). Tabs are no longer needed; each
 * sub-topic is its own page. Liquidation tab dropped entirely (use
 * /liquidations instead). */

/* Top Trader empty-state overlay sits inside the chart slot */
.tt-sent-tt { position: relative; }
.tt-sent-tt__empty {
  position: absolute;
  left: 0; right: 0; top: 50%;
  transform: translateY(-50%);
  text-align: center;
  font-size: 14px;
  color: var(--tt-fg-0);
  opacity: 0.55;
  padding: 12px 20px;
  pointer-events: none;
}

.tt-fund-section { margin: 24px 0 32px; }
.tt-fund-section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 14px;
}
.tt-fund-section__title {
  font-size: 18px;
  font-weight: 700;
  color: var(--tt-fg-0);
  margin: 0;
}
.tt-fund-section__subtitle {
  font-size: 12px;
  color: var(--tt-fg-0);
  flex: 1 1 auto;
}
.tt-fund-tabs {
  display: inline-flex;
  gap: 4px;
  margin-left: auto;
  background: rgba(120, 123, 134, .08);
  border-radius: 8px;
  padding: 3px;
}
.tt-fund-tab {
  background: transparent;
  border: 0;
  color: var(--tt-fg-0);
  opacity: .7;
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background .12s, opacity .12s;
}
.tt-fund-tab:hover { opacity: 1; }
.tt-fund-tab.is-active {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
  opacity: 1;
}

/* ── Section 1: Weighted KPI strip ─────────────────────────────────────── */
.tt-fund-kpi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
}
.tt-fund-kpi__card {
  background: rgba(120, 123, 134, .04);
  border: 1px solid rgba(120, 123, 134, .12);
  border-radius: 12px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tt-fund-kpi__head { display: flex; align-items: center; gap: 10px; }
.tt-fund-kpi__head-base { font-size: 16px; font-weight: 700; color: var(--tt-fg-0); }
.tt-fund-kpi__head-sub { font-size: 12px; color: var(--tt-fg-0); opacity: .55; }
.tt-fund-kpi__rates { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.tt-fund-kpi__rate { display: flex; flex-direction: column; gap: 2px; }
.tt-fund-kpi__rate-label { font-size: 12px; color: var(--tt-fg-0); opacity: .55; }
.tt-fund-kpi__rate-value { font-size: 22px; font-weight: 700; color: var(--tt-fg-0); }
.tt-fund-kpi__rate.is-up    .tt-fund-kpi__rate-value { color: var(--tt-up); }
.tt-fund-kpi__rate.is-down  .tt-fund-kpi__rate-value { color: var(--tt-down); }
.tt-fund-kpi__rate-apr { font-size: 12px; color: var(--tt-fg-0); opacity: .65; font-weight: 500; }
.tt-fund-kpi__meta { display: flex; gap: 14px; font-size: 12px; color: var(--tt-fg-0); opacity: .55; flex-wrap: wrap; }
.tt-fund-kpi__spark { height: 60px; min-width: 0; }
.tt-fund-spark__empty { font-size: 12px; color: var(--tt-fg-0); opacity: .4; padding: 22px 0; text-align: center; }

/* [ADD] 2026-07-06 — BACKLOG-008 large-orders wall-history chart empty overlay.
   Colour var(--tt-fg-0) + 12px font per web_app_styling.mdc whitelist. */
.tt-lo-hist { margin-top: 24px; }
.tt-lo-hist__chart { position: relative; }
.tt-lo-hist__empty {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .55;
  text-align: center;
  padding: 0 16px;
  pointer-events: none;
}
.tt-lo-hist__empty-title { font-size: 14px; }
.tt-lo-hist__empty-sub { font-size: 12px; opacity: .8; }

/* ── Section 2: Settlement Flow band ───────────────────────────────────── */
.tt-fund-flow {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.tt-fund-flow__cell {
  background: rgba(120, 123, 134, .04);
  border: 1px solid rgba(120, 123, 134, .12);
  border-radius: 12px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tt-fund-flow__label { font-size: 12px; color: var(--tt-fg-0); opacity: .65; }
.tt-fund-flow__net { font-size: 22px; font-weight: 700; }
.tt-fund-flow__net.is-up   { color: var(--tt-up); }
.tt-fund-flow__net.is-down { color: var(--tt-down); }
.tt-fund-flow__bar { height: 8px; background: rgba(120, 123, 134, .15); border-radius: 4px; overflow: hidden; display: flex; }
.tt-fund-flow__bar-long  { background: var(--tt-up);   height: 100%; }
.tt-fund-flow__bar-short { background: var(--tt-down); height: 100%; }
.tt-fund-flow__legend { display: flex; flex-direction: column; gap: 2px; font-size: 12px; }
.tt-fund-flow__leg-long  { color: var(--tt-up); }
.tt-fund-flow__leg-short { color: var(--tt-down); }

/* ── Section 3: Cross-Exchange Arbitrage ─────────────────────────────── */
.tt-fund-arb { background: rgba(120,123,134,.04); border: 1px solid rgba(120,123,134,.12); border-radius: 12px; overflow: auto; }
.tt-fund-arb__table th { white-space: nowrap; font-size: 12px; }
.tt-fund-arb__table td { font-size: 14px; }

/* ── Shared heat cell border (SSoT: settlement treemap .tt-fund-treemap__cell) ─ */
.tt-fund-treemap__cell,
.tt-mov-treemap__cell,
.tt-liqheat__cell,
.tt-sent-fheat__cell {
  border: 1px solid rgba(0, 0, 0, .15);
  box-sizing: border-box;
}

/* ── Section 4: Settlement Treemap ───────────────────────────────────── */
.tt-fund-treemap {
  position: relative;
  width: 100%;
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 12px;
  overflow: hidden;
}
/* [FIX] 2026-05-09 P2-2 round 2 — funding treemap cell is display-only (WEB-260:
   no chart-nav handler binds; navigateToChart removed). cursor:pointer was
   misleading the user into thinking the cell was actionable. Hover scale kept
   as a scan affordance only. */
.tt-fund-treemap__cell {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 6px;
  color: var(--tt-fg-0);
  cursor: default;
  transition: transform .12s;
  overflow: hidden;
}
.tt-fund-treemap__cell:hover,
.tt-fund-treemap__cell.is-heat-active { transform: scale(1.02); z-index: 2; }
.tt-fund-treemap__base { font-weight: 700; line-height: 1.1; min-width: 0; max-width: 100%; overflow: hidden; }
.tt-fund-treemap__val  { line-height: 1.1; opacity: .9; }
.tt-fund-treemap__skew { line-height: 1.1; opacity: .8; }

/* ── Section 5: Cross full table — fixed-style table override ────────── */
.tt-fund-cross-table th, .tt-fund-cross-table td { white-space: nowrap; padding: 10px 8px; font-size: 12px; }
.tt-fund-cross-table .is-up   { color: var(--tt-up); }
.tt-fund-cross-table .is-down { color: var(--tt-down); }

/* ── Section 7: Funding+Price history ────────────────────────────────── */
.tt-fund-hist__chart { width: 100%; min-height: 360px; background: rgba(120,123,134,.04); border-radius: 12px; position: relative; }
.tt-fund-hist__base { width: 80px; }
.tt-fund-hist__window { min-width: 80px; }
/* [ADD] 2026-05-11 — P2#24a settlement markers checkbox label.
   Sits inline with the base/window selectors; the checkbox itself
   is the native control (theme-neutral), the wrapping <label> only
   provides spacing + font-size from the whitelist (12px). */
.tt-fund-hist__markers-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--tt-fg-0);
  font-size: 12px;
  cursor: pointer;
  user-select: none;
}
.tt-fund-hist__markers-toggle input[type="checkbox"] {
  cursor: pointer;
}
/* [ADD] 2026-04-25 — graceful empty/warming/error overlay for the history chart */
.tt-fund-hist__empty {
    position: absolute; inset: 0; display: flex; flex-direction: column; gap: 6px;
    align-items: center; justify-content: center; padding: 16px; text-align: center;
    color: var(--tt-fg-0); font-size: 14px; pointer-events: none;
    background: rgba(120,123,134,.06); border-radius: 12px;
}
.tt-fund-hist__empty-title { font-size: 14px; font-weight: 600; }
.tt-fund-hist__empty-sub   { font-size: 12px; opacity: .7; max-width: 420px; line-height: 1.5; }

/* ── Detail tabs — wrap Arbitrage / Cross / Settlement / History ─────── */
/* [ADD] 2026-04-25 — collapse 4 heavy modules into a single tabbed panel
 *   so the page no longer scrolls past 4 stacked tables. */
.tt-fund-detail { padding: 0; }
.tt-fund-detail__tabs {
    display: flex; gap: 0; flex-wrap: wrap;
    border-bottom: 1px solid rgba(120,123,134,.18);
    margin-bottom: 12px;
}
.tt-fund-detail__tab {
    appearance: none; background: transparent; border: 0;
    padding: 12px 18px; font-size: 14px; font-weight: 500;
    color: var(--tt-fg-0); opacity: .55; cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: opacity .15s ease, border-color .15s ease;
}
.tt-fund-detail__tab:hover { opacity: .85; }
.tt-fund-detail__tab.is-active {
    opacity: 1; border-bottom-color: #2962ff;
}
.tt-fund-detail__pane[hidden] { display: none; }
.tt-fund-detail__pane-head { margin-bottom: 12px; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* ============================================================================
 * /sentiment composite styles
 * ============================================================================ */

/* ── Hero gauge ───────────────────────────────────────────────────────── */
.tt-sent-hero {
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 16px;
  padding: 24px;
}
.tt-sent-hero__inner {
  display: grid;
  grid-template-columns: 320px 1fr 280px;
  gap: 24px;
  align-items: center;
}
.tt-sent-hero__gauge {
  position: relative;
  width: 320px;
  height: 180px;
  overflow: hidden;
}
.tt-sent-hero__gauge-arc {
  position: absolute;
  inset: 0;
  border-radius: 320px 320px 0 0;
  -webkit-mask: radial-gradient(circle at 50% 100%, transparent 90px, black 91px);
          mask: radial-gradient(circle at 50% 100%, transparent 90px, black 91px);
}
.tt-sent-hero__gauge-needle {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 4px;
  height: 130px;
  border-radius: 2px;
  transform-origin: bottom center;
  background: var(--tt-fg-0);
  transition: transform .4s ease;
}
.tt-sent-hero__gauge-value {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
}
.tt-sent-hero__gauge-num   { font-size: 22px; font-weight: 800; line-height: 1; }
.tt-sent-hero__gauge-label { font-size: 14px; font-weight: 600; margin-top: 4px; }
.tt-sent-hero__legend {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-sent-hero__legend span { font-weight: 500; }
.tt-sent-hero__spark { width: 100%; height: 80px; }

/* ── Factor breakdown bars ────────────────────────────────────────────── */
.tt-sent-factors {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tt-sent-factor {
  display: grid;
  grid-template-columns: 180px 1fr 70px;
  gap: 12px;
  align-items: center;
}
.tt-sent-factor__label { font-size: 14px; font-weight: 600; color: var(--tt-fg-0); }
.tt-sent-factor__bar {
  position: relative;
  height: 18px;
  background: rgba(120,123,134,.10);
  border-radius: 4px;
  overflow: hidden;
}
.tt-sent-factor__bar-axis {
  position: absolute;
  top: 0;
  left: 50%;
  width: 2px;
  height: 100%;
  background: rgba(120,123,134,.5);
}
.tt-sent-factor__bar-fill {
  position: absolute;
  top: 0;
  height: 100%;
}
.tt-sent-factor__bar-fill.is-up   { background: var(--tt-up); }
.tt-sent-factor__bar-fill.is-down { background: var(--tt-down); }
.tt-sent-factor__score { font-size: 16px; font-weight: 700; text-align: right; }
.tt-sent-factor__score.is-up   { color: var(--tt-up); }
.tt-sent-factor__score.is-down { color: var(--tt-down); }
.tt-sent-factor__desc {
  grid-column: 2 / 4;
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .55;
}
.tt-sent-factor__desc em { font-style: normal; font-weight: 600; opacity: 1; }

/* [REMOVED] 2026-05-11 — `.tt-sent-liq*` (Liquidation Pressure card) deleted
 *   with the /sentiment monolith split. Liquidation data lives at
 *   /liquidations now and uses its own dedicated styling. */

/* ── Divergence two-column layout ─────────────────────────────────────── */
.tt-sent-div { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.tt-sent-div__col {
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 12px;
  padding: 14px;
  overflow: auto;
}
.tt-sent-div__title { font-size: 14px; font-weight: 700; margin: 0 0 10px; }
.tt-sent-div__title.is-up   { color: var(--tt-up); }
.tt-sent-div__title.is-down { color: var(--tt-down); }
.tt-sent-div table .is-up   { color: var(--tt-up); }
.tt-sent-div table .is-down { color: var(--tt-down); }

/* ── L/S Ratio Extremes (positioning page, REST-ext landing 2026-07-06) ── */
.tt-sent-lsx { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.tt-sent-lsx__col {
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 12px;
  padding: 14px;
}
.tt-sent-lsx__col-head { font-size: 14px; font-weight: 700; margin: 0 0 10px; color: var(--tt-fg-0); }
/* [EXCEPTION] long/short accent = directional up/down green/red pair. */
.tt-sent-lsx__col-head.is-up   { color: var(--tt-up); }
.tt-sent-lsx__col-head.is-down { color: var(--tt-down); }
.tt-sent-lsx__list { list-style: none; margin: 0; padding: 0; }
.tt-sent-lsx__row {
  display: grid;
  grid-template-columns: 20px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid rgba(120,123,134,.08);
}
.tt-sent-lsx__row:last-child { border-bottom: 0; }
.tt-sent-lsx__rank { font-size: 12px; color: var(--tt-fg-0); opacity: .6; text-align: center; }
.tt-sent-lsx__sym { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tt-sent-lsx__sym-text { display: flex; flex-direction: column; min-width: 0; }
.tt-sent-lsx__base { font-size: 14px; font-weight: 600; color: var(--tt-fg-0); }
.tt-sent-lsx__meta { font-size: 12px; color: var(--tt-fg-0); opacity: .55; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tt-sent-lsx__ratio { font-size: 14px; font-weight: 700; color: var(--tt-fg-0); font-variant-numeric: tabular-nums; }
.tt-sent-lsx__empty { list-style: none; font-size: 14px; color: var(--tt-fg-0); opacity: .55; padding: 12px 0; }
@media (max-width: 720px) {
  .tt-sent-lsx { grid-template-columns: 1fr; }
}

/* ── Liquidation Sentiment (funding-oi page, REST-ext landing 2026-07-06) ── */
.tt-sent-liq { display: block; }
.tt-sent-liq__split { margin-bottom: 18px; }
.tt-sent-liq__split-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 6px;
}
.tt-sent-liq__total { color: var(--tt-fg-0); opacity: .7; font-weight: 500; }
.tt-sent-liq__bar {
  display: flex;
  height: 14px;
  border-radius: 7px;
  overflow: hidden;
  background: rgba(120,123,134,.12);
}
/* [EXCEPTION] long/short liquidation split uses directional up/down colours. */
.tt-sent-liq__bar-long  { background: var(--tt-up); }
.tt-sent-liq__bar-short { background: var(--tt-down); }
.tt-sent-liq__ex-head {
  font-size: 12px;
  font-weight: 700;
  color: var(--tt-fg-0);
  opacity: .7;
  margin: 0 0 8px;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.tt-sent-liq__ex { list-style: none; margin: 0; padding: 0; }
.tt-sent-liq__ex-row {
  display: grid;
  grid-template-columns: 130px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
}
.tt-sent-liq__ex-name { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--tt-fg-0); min-width: 0; }
.tt-sent-liq__ex-name span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tt-sent-liq__ex-bar {
  display: flex;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: rgba(120,123,134,.12);
}
.tt-sent-liq__ex-long  { background: var(--tt-up); }
.tt-sent-liq__ex-short { background: var(--tt-down); }
.tt-sent-liq__ex-usd { font-size: 14px; color: var(--tt-fg-0); font-variant-numeric: tabular-nums; text-align: right; }
@media (max-width: 640px) {
  .tt-sent-liq__ex-row { grid-template-columns: 96px 1fr auto; gap: 8px; }
}

/* ── BTC Cycle Indicators (overview page, REST-ext landing 2026-07-06) ── */
.tt-sent-cycle__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}
.tt-sent-cycle__card {
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 12px;
  padding: 14px;
}
.tt-sent-cycle__label { font-size: 12px; color: var(--tt-fg-0); opacity: .6; margin-bottom: 6px; }
.tt-sent-cycle__val {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 20px;
  font-weight: 700;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-sent-cycle__tag { font-size: 12px; font-weight: 600; color: var(--tt-fg-0); opacity: .7; }
/* [EXCEPTION] valuation zone tag uses directional up/down colours. */
.tt-sent-cycle__tag.is-up   { color: var(--tt-up); opacity: 1; }
.tt-sent-cycle__tag.is-down { color: var(--tt-down); opacity: 1; }
.tt-sent-cycle__locked {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 28px 14px;
  background: rgba(120,123,134,.04);
  border: 1px dashed rgba(120,123,134,.2);
  border-radius: 12px;
  cursor: pointer;
}
.tt-sent-cycle__locked-text { font-size: 14px; color: var(--tt-fg-0); opacity: .7; text-align: center; }
.tt-sent-cycle__locked-btn {
  font-size: 14px;
  font-weight: 600;
  color: var(--tt-fg-0);
  background: rgba(41,98,255,.14);
  border: 1px solid rgba(41,98,255,.4);
  border-radius: 8px;
  padding: 8px 18px;
  cursor: pointer;
}

/* ── Up/Down universal helpers (used inline) ──────────────────────────── */
.tt-up   { color: var(--tt-up); }
.tt-down { color: var(--tt-down); }

/* ── Home page additions: greed card + liq pressure card ──────────────── */
.tt-greed-card, .tt-liqpress-card { padding: 8px 0; }
.tt-greed { display: flex; flex-direction: column; gap: 8px; align-items: center; padding: 4px 6px; }
.tt-greed__value { font-size: 22px; font-weight: 800; line-height: 1; }
.tt-greed__label { font-size: 14px; font-weight: 600; }
.tt-greed__bar { width: 100%; height: 8px; background: rgba(120,123,134,.15); border-radius: 4px; overflow: hidden; }
.tt-greed__bar-fill { height: 100%; transition: width .4s ease; }
.tt-greed__legend { width: 100%; display: flex; justify-content: space-between; font-size: 12px; color: var(--tt-fg-0); opacity: .6; }
.tt-greed__cta { font-size: 12px; color: var(--tt-fg-0); opacity: .8; text-decoration: none; }
.tt-greed__cta:hover { opacity: 1; text-decoration: underline; }

.tt-liqpress { display: flex; flex-direction: column; gap: 8px; padding: 4px 6px; }
.tt-liqpress__total { font-size: 22px; font-weight: 800; color: var(--tt-fg-0); text-align: center; }
.tt-liqpress__sub { font-size: 12px; color: var(--tt-fg-0); opacity: .6; text-align: center; }
.tt-liqpress__bar { display: flex; height: 12px; background: rgba(120,123,134,.15); border-radius: 6px; overflow: hidden; }
.tt-liqpress__bar-long  { background: var(--tt-up);   height: 100%; }
.tt-liqpress__bar-short { background: var(--tt-down); height: 100%; }
.tt-liqpress__legend { display: flex; justify-content: space-between; font-size: 12px; }
.tt-liqpress__leg-long  { color: var(--tt-up); }
.tt-liqpress__leg-short { color: var(--tt-down); }
.tt-liqpress__cta { font-size: 12px; color: var(--tt-fg-0); opacity: .8; text-decoration: none; text-align: center; }
.tt-liqpress__cta:hover { opacity: 1; text-decoration: underline; }

/* ── tt-tape additions for new "Top Liquidated 1h" rendering ─────────── */
.tt-tape__meta-long  { color: var(--tt-up); font-weight: 600; }
.tt-tape__meta-short { color: var(--tt-down); font-weight: 600; }

/* ────────────────────────────────────────────────────────────────────── */
/* [ADD] 2026-04-25 — /movers chart panels                                */
/*   4 stacked sections above the existing OI Surging/Dropping table:    */
/*     1. KPI strip   (Total OI / Avg Δ / Surging count / Dropping count)*/
/*     2. Treemap     (USD-area, Δ%-tinted, hand-rolled in tt.movers.js) */
/*     3. Scatter     (X=log10 OI USD, Y=Δ%, hand-rolled SVG)            */
/*     4. Exchange Bar (per-venue added/removed USD, horizontal bars)    */
/*   All four share one tt-mov-windowbar (1h / 24h) at the top so the    */
/*   user can pivot the entire upper half with a single click.           */
/*                                                                        */
/*   Style discipline: every color: rule below uses var(--tt-fg-0) or    */
/*   the canonical var(--tt-up) / var(--tt-down) per the styling rule.   */
/*   Every font-size sits on the {12,14,16,18,22,28} whitelist.          */
/* ────────────────────────────────────────────────────────────────────── */

.tt-mov-windowbar {
  display: inline-flex;
  gap: 4px;
  background: rgba(120,123,134,.10);
  border-radius: 8px;
  padding: 4px;
  margin: 12px 0 4px;
}
.tt-mov-windowbtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  color: var(--tt-fg-0);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: background .12s;
}
.tt-mov-windowbtn__icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: inherit;
}
.tt-mov-windowbtn__icon svg {
  stroke: var(--tt-fg-0);
  fill: none;
}
.tt-mov-windowbtn:hover    { background: rgba(120,123,134,.16); }
.tt-mov-windowbtn.is-active{ background: var(--tt-bg-0); box-shadow: 0 0 0 1px var(--tt-line) inset; }

.tt-mov-section { margin: 16px 0 24px; }
.tt-mov-section__head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 10px;
}
.tt-mov-section__title {
  font-size: 18px;
  font-weight: 700;
  color: var(--tt-fg-0);
  margin: 0;
}
.tt-mov-section__subtitle {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .65;
}

/* KPI strip */
.tt-mov-kpi {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.tt-mov-kpi__cell {
  background: rgba(120,123,134,.06);
  border: 1px solid rgba(120,123,134,.14);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.tt-mov-kpi__label {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .6;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.tt-mov-kpi__value {
  font-size: 22px;
  font-weight: 700;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-mov-kpi__value.is-up   { color: var(--tt-up); }
.tt-mov-kpi__value.is-down { color: var(--tt-down); }
.tt-mov-kpi__hint {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .5;
}

/* Treemap (mirrors tt-fund-treemap structure) */
.tt-mov-treemap {
  position: relative;
  width: 100%;
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 12px;
  overflow: hidden;
}
/* [FIX] 2026-05-09 P2-2 — treemap cell click → /chart removed; cursor default. */
.tt-mov-treemap__cell {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 6px;
  color: var(--tt-fg-0);
  cursor: default;
  transition: transform .12s;
  overflow: hidden;
}
.tt-mov-treemap__cell:hover,
.tt-mov-treemap__cell.is-heat-active { transform: scale(1.02); z-index: 2; }
.tt-mov-treemap__base { font-weight: 700; line-height: 1.1; min-width: 0; max-width: 100%; overflow: hidden; }
.tt-mov-treemap__pct  { font-weight: 700; line-height: 1.1; }
.tt-mov-treemap__val  { line-height: 1.1; opacity: .85; }

/* Scatter plot */
.tt-mov-scatter {
  width: 100%;
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 12px;
  overflow: hidden;
  padding: 4px;
}
/* [FIX] 2026-05-09 P2-2 — scatter dot click → /chart removed; cursor default. */
.tt-mov-scatter__dot {
  cursor: default;
  transition: filter .1s;
}
.tt-mov-scatter__dot:hover { filter: brightness(1.3); }

/* Per-Exchange OI flow bar */
.tt-mov-exchbar {
  --tt-mov-exchbar-name-w: 168px;
  --tt-mov-exchbar-net-w: 88px;
  --tt-mov-exchbar-side-num-w: 72px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: rgba(120,123,134,.04);
  border: 1px solid rgba(120,123,134,.12);
  border-radius: 12px;
  padding: 12px 16px;
}
.tt-mov-exchbar__row {
  display: grid;
  grid-template-columns: var(--tt-mov-exchbar-name-w) minmax(0, 1fr) var(--tt-mov-exchbar-net-w);
  align-items: center;
  gap: 12px;
}
.tt-mov-exchbar__name {
  min-width: 0;
  width: var(--tt-mov-exchbar-name-w);
}
.tt-mov-exchbar__name.tt-dex-venue-cell > span:not(.tt-exchange-icon-wrap) {
  text-transform: capitalize;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tt-mov-exchbar__track {
  display: grid;
  grid-template-columns: var(--tt-mov-exchbar-side-num-w) minmax(0, 1fr) minmax(0, 1fr) var(--tt-mov-exchbar-side-num-w);
  align-items: center;
  column-gap: 6px;
  min-width: 0;
}
.tt-mov-exchbar__bar {
  display: flex;
  align-items: center;
  height: 14px;
  min-width: 0;
}
.tt-mov-exchbar__bar--neg {
  justify-content: flex-end;
  border-right: 1px solid rgba(120,123,134,.3);
  padding-right: 4px;
}
.tt-mov-exchbar__bar--pos {
  justify-content: flex-start;
  padding-left: 4px;
}
.tt-mov-exchbar__fill {
  height: 10px;
  border-radius: 2px;
  max-width: 100%;
}
.tt-mov-exchbar__fill--neg { background: var(--tt-down); }
.tt-mov-exchbar__fill--pos { background: var(--tt-up); }
.tt-mov-exchbar__num {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--tt-fg-0);
}
.tt-mov-exchbar__num--neg { text-align: right; }
.tt-mov-exchbar__num--pos { text-align: left; }
.tt-mov-exchbar__num.is-up   { color: var(--tt-up); }
.tt-mov-exchbar__num.is-down { color: var(--tt-down); }
.tt-mov-exchbar__net {
  font-size: 14px;
  font-weight: 400;
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  width: var(--tt-mov-exchbar-net-w);
  color: var(--tt-fg-0);
}
.tt-mov-exchbar__net.is-up   { color: var(--tt-up); }
.tt-mov-exchbar__net.is-down { color: var(--tt-down); }

@media (max-width: 1024px) {
  .tt-mov-kpi { grid-template-columns: repeat(2, 1fr); }
  .tt-mov-exchbar {
    --tt-mov-exchbar-name-w: 140px;
    --tt-mov-exchbar-net-w: 72px;
    --tt-mov-exchbar-side-num-w: 60px;
  }
  .tt-mov-exchbar__row { gap: 8px; }
}
@media (max-width: 640px) {
  .tt-mov-kpi { grid-template-columns: 1fr; }
  .tt-mov-section__title { font-size: 16px; }
}

/* ── Responsive layout collapses ─────────────────────────────────────── */
@media (max-width: 1024px) {
  .tt-sent-hero__inner { grid-template-columns: 1fr; gap: 16px; justify-items: center; }
  .tt-sent-hero__legend { flex-direction: row; flex-wrap: wrap; justify-content: center; }
  .tt-sent-div { grid-template-columns: 1fr; }
  .tt-sent-factor { grid-template-columns: 140px 1fr 60px; }
}
@media (max-width: 640px) {
  .tt-fund-kpi__rates { grid-template-columns: 1fr; }
  .tt-fund-flow { grid-template-columns: 1fr; }
  .tt-sent-factor { grid-template-columns: 1fr; }
  .tt-sent-factor__score { text-align: left; }
  .tt-sent-factor__desc { grid-column: 1; }
  .tt-fund-section__title { font-size: 16px; }
  .tt-sent-hero__gauge { width: 240px; height: 140px; }
  .tt-sent-hero__gauge-needle { height: 100px; }
  .tt-sent-hero__gauge-num { font-size: 22px; }
}

/* ============================================================================
   [ADD] 2026-04-25 — /sentiment dashboard styles
   [UPDATE] 2026-05-11 — page split into 3 URLs (overview / positioning /
     funding-oi). `.tt-sent-liq*` (Liquidation Pressure) and `.tt-sent-liqex*`
     (per-exchange split) are removed; .tt-sent-tabs / .tt-sent-pane
     (top-level tabs) are removed. Surviving primitives are reused across the
     3 child pages.
   Sections covered (post-split):
     1 hero v2          → .tt-sent-heroV2*  (overview)
     2 BTC vs Alt       → .tt-sent-btcalt*  (positioning)
     3 5-factor radar   → .tt-sent-radar*   (overview)
     4 funding heatmap  → .tt-sent-fheat*   (funding-oi)
     6 top trader L/S   → .tt-sent-tt*      (positioning)
     7 OI waterfall     → .tt-sent-wf*      (funding-oi)
     9 divergence       → .tt-sent-div*     (funding-oi)
   Strict adherence to web_app_styling.mdc:
     - colors only var(--tt-fg-0) / var(--tt-up) / var(--tt-down) / opacity
     - font-size only {12,14,16,18,22,28}
============================================================================ */

/* Section 1 — Hero v2 */
.tt-sent-heroV2 {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.tt-sent-heroV2__top {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 24px;
  align-items: center;
}
.tt-sent-heroV2__gauge {
  position: relative;
  text-align: center;
}
.tt-sent-heroV2__gauge svg { display: block; max-width: 280px; margin: 0 auto; }
.tt-sent-heroV2__gauge-num {
  position: absolute;
  left: 0; right: 0;
  bottom: 28%;
  font-size: 22px;
  font-weight: 700;
  color: var(--tt-fg-0);
  line-height: 1;
}
.tt-sent-heroV2__gauge-label {
  position: absolute;
  left: 0; right: 0;
  bottom: 14%;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--tt-fg-0);
}
.tt-sent-heroV2__right {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.tt-sent-heroV2__verdict {
  font-size: 16px;
  line-height: 1.5;
  color: var(--tt-fg-0);
}
.tt-sent-heroV2__deltas {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.tt-sent-heroV2__delta-cell {
  background: rgba(120,123,134,0.08);
  border-radius: 10px;
  padding: 12px 14px;
  text-align: center;
}
.tt-sent-heroV2__delta-label {
  display: block;
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: 0.6;
  margin-bottom: 6px;
}
.tt-sent-heroV2__delta-val {
  display: block;
  font-size: 18px;
  font-weight: 700;
  color: var(--tt-fg-0);
}
.tt-sent-heroV2__delta-val.is-up   { color: var(--tt-up); }
.tt-sent-heroV2__delta-val.is-down { color: var(--tt-down); }
.tt-sent-heroV2__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-sent-heroV2__legend span { opacity: 0.85; }
.tt-sent-heroV2__legend .is-fear        { color: var(--tt-down); }
/* [EXCEPTION] sentiment mild legend — financial semantic colors */
.tt-sent-heroV2__legend .is-fear-mild   { color: #f4845f; }
.tt-sent-heroV2__legend .is-neutral     { opacity: 0.6; }
.tt-sent-heroV2__legend .is-greed-mild  { color: #86c068; }
.tt-sent-heroV2__legend .is-greed       { color: var(--tt-up); }
.tt-sent-heroV2__spark { height: 90px; }

/* Section 2 — BTC vs Alt */
.tt-sent-btcalt {
  display: grid;
  grid-template-columns: 1fr 1.4fr 1fr;
  gap: 18px;
  align-items: center;
}
.tt-sent-btcalt__col { text-align: center; }
.tt-sent-btcalt__label {
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--tt-fg-0);
  opacity: 0.7;
  margin-bottom: 6px;
}
.tt-sent-btcalt__gauge { position: relative; max-width: 220px; margin: 0 auto; }
.tt-sent-btcalt__gauge svg { display: block; }
.tt-sent-btcalt__num {
  position: absolute;
  left: 0; right: 0;
  bottom: 22%;
  font-size: 22px;
  font-weight: 700;
  color: var(--tt-fg-0);
}
.tt-sent-btcalt__center {
  text-align: center;
  background: rgba(120,123,134,0.06);
  border-radius: 12px;
  padding: 14px 16px;
}
.tt-sent-btcalt__diverge-label {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: 0.6;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.tt-sent-btcalt__diverge-val {
  font-size: 22px;
  font-weight: 700;
  color: var(--tt-fg-0);
  margin: 4px 0;
}
.tt-sent-btcalt__diverge-val.is-up   { color: var(--tt-up); }
.tt-sent-btcalt__diverge-val.is-down { color: var(--tt-down); }
.tt-sent-btcalt__hint {
  font-size: 14px;
  color: var(--tt-fg-0);
  opacity: 0.8;
  margin-bottom: 12px;
}
.tt-sent-btcalt__factors {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 12px;
  font-size: 12px;
  text-align: left;
}
.tt-sent-btcalt__factors > div {
  display: flex;
  justify-content: space-between;
  background: rgba(120,123,134,0.04);
  padding: 4px 8px;
  border-radius: 6px;
  color: var(--tt-fg-0);
}
.tt-sent-btcalt__factors em { font-style: normal; opacity: 0.7; }
.tt-sent-btcalt__factors span { font-variant-numeric: tabular-nums; }

/* Section 3 — Radar */
.tt-sent-radar {
  display: block;
}
.tt-sent-radar__wrap {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 24px;
  align-items: center;
  background: rgba(120,123,134,0.04);
  border: 1px solid rgba(120,123,134,0.12);
  border-radius: 12px;
  padding: 18px;
}
.tt-sent-radar__chart {
  width: min(100%, 460px);
  max-height: 340px;
  aspect-ratio: 480 / 360;
  justify-self: center;
}
.tt-sent-radar__chart svg {
  display: block;
  width: 100%;
  height: 100%;
}
.tt-sent-radar__legend {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tt-sent-radar__leg-row {
  display: grid;
  grid-template-columns: 1fr 60px;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--tt-fg-0);
  border-bottom: 1px dashed rgba(120,123,134,0.18);
  padding-bottom: 6px;
}
.tt-sent-radar__leg-row:last-child { border-bottom: none; }
.tt-sent-radar__leg-name em { font-style: normal; opacity: 0.6; font-size: 12px; }
.tt-sent-radar__leg-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.tt-sent-radar__leg-num.is-up   { color: var(--tt-up); }
.tt-sent-radar__leg-num.is-down { color: var(--tt-down); }

/* Section 4 — Funding Heatmap */
.tt-sent-fheat {
  background: rgba(120,123,134,0.04);
  border: 1px solid rgba(120,123,134,0.12);
  border-radius: 12px;
  padding: 12px;
  overflow-x: auto;
}
.tt-sent-fheat__grid {
  display: grid;
  gap: 1px;
  min-width: 640px;
}
.tt-sent-fheat__head,
.tt-sent-fheat__row {
  display: grid;
  grid-template-columns: minmax(140px, 1.4fr) repeat(var(--tt-fheat-cols, 5), minmax(70px, 1fr));
  align-items: stretch;
  gap: 1px;
}
.tt-sent-fheat__head {
  background: transparent;
  margin-bottom: 6px;
}
.tt-sent-fheat__head-base,
.tt-sent-fheat__head-ex {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: 0.7;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 6px 10px;
  text-align: center;
}
.tt-sent-fheat__head-base { text-align: left; }
.tt-sent-fheat__head-ex { text-align: left; }
.tt-sent-fheat__head-ex-cell {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
.tt-sent-fheat__head-ex-cell > span:not(.tt-exchange-icon-wrap) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tt-sent-fheat__head-ex .tt-exchange-icon--fheat {
  width: 18px;
  height: 18px;
  padding: 1px;
  border-radius: 4px;
}
.tt-sent-fheat__base {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 8px 10px;
  background: rgba(120,123,134,0.06);
  border-radius: 4px;
}
.tt-sent-fheat__base-name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--tt-fg-0);
}
.tt-sent-fheat__base-name .tt-coin-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}
.tt-sent-fheat__base-name .tt-coin-icon__fb { font-size: 12px; }
.tt-sent-fheat__base-oi {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: 0.6;
}
.tt-sent-fheat__cell {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--tt-fg-0);
  padding: 8px 6px;
  border-radius: 4px;
  min-height: 36px;
}

/* Section 6 — Top Trader vs Retail L/S */
.tt-sent-tt {
  background: rgba(120,123,134,0.04);
  border: 1px solid rgba(120,123,134,0.12);
  border-radius: 12px;
  padding: 14px 16px;
}
.tt-sent-tt__legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  font-size: 12px;
  color: var(--tt-fg-0);
  margin-bottom: 10px;
}
.tt-sent-tt__leg { display: inline-flex; align-items: center; gap: 6px; }
.tt-sent-tt__leg i {
  display: inline-block;
  width: 14px;
  height: 2px;
  border-radius: 1px;
}
.tt-sent-tt__leg--acc i { background: var(--tt-fg-2); }
.tt-sent-tt__leg--oi  i { background: #2962ff; }
.tt-sent-tt__leg--last { margin-left: auto; font-variant-numeric: tabular-nums; }
.tt-sent-tt__leg--last em { font-style: normal; opacity: 0.6; }
.tt-sent-tt__chart { width: 100%; height: 320px; }

/* Section 7 — OI Growth Waterfall */
.tt-sent-waterfall {
  background: rgba(120,123,134,0.04);
  border: 1px solid rgba(120,123,134,0.12);
  border-radius: 12px;
  padding: 14px 16px;
}
.tt-sent-wf {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tt-sent-wf__row {
  display: grid;
  grid-template-columns: 80px 1fr 110px 80px;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--tt-fg-0);
}
.tt-sent-wf__base {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
}
.tt-sent-wf__base .tt-coin-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}
.tt-sent-wf__base .tt-coin-icon__fb { font-size: 12px; }
.tt-sent-wf__track {
  position: relative;
  height: 14px;
  background: rgba(120,123,134,0.08);
  border-radius: 4px;
  overflow: hidden;
}
.tt-sent-wf__zero {
  position: absolute;
  left: 50%;
  top: 0; bottom: 0;
  width: 1px;
  background: rgba(120,123,134,0.4);
}
.tt-sent-wf__bar {
  position: absolute;
  top: 2px;
  height: 10px;
  border-radius: 2px;
}
.tt-sent-wf__bar.is-up   { background: var(--tt-up); }
.tt-sent-wf__bar.is-down { background: var(--tt-down); }
.tt-sent-wf__usd,
.tt-sent-wf__pct {
  font-variant-numeric: tabular-nums;
  text-align: right;
  font-size: 14px;
}

/* [REMOVED] 2026-05-11 — `.tt-sent-liqex*` (per-exchange liq split) deleted
 *   together with `.tt-sent-liq*` after the Liquidation tab on /sentiment
 *   was retired in favour of /liquidations. */

/* Responsive collapses for new sentiment sections */
@media (max-width: 1024px) {
  .tt-sent-heroV2__top   { grid-template-columns: 1fr; justify-items: center; }
  .tt-sent-btcalt        { grid-template-columns: 1fr; }
  .tt-sent-radar__wrap   { grid-template-columns: 1fr; }
  .tt-sent-radar__chart  { width: min(100%, 420px); max-height: 315px; }
  .tt-sent-tt__chart     { height: 280px; }
}
@media (max-width: 640px) {
  .tt-sent-heroV2__deltas    { grid-template-columns: 1fr; }
  .tt-sent-wf__row           { grid-template-columns: 60px 1fr 90px 60px; gap: 6px; }
  .tt-sent-fheat__head,
  .tt-sent-fheat__row        { grid-template-columns: minmax(110px, 1.2fr) repeat(var(--tt-fheat-cols, 5), minmax(54px, 1fr)); }
  .tt-sent-radar__chart      { width: min(100%, 320px); max-height: 240px; }
}

/* ============================================================================
 * [ADD] 2026-04-26 — /trades list & /trades/:base detail page
 *
 * [EXCEPTION] colours: Buy = var(--tt-up), Sell = var(--tt-down). This
 *   stylesheet's general rule is neutral-only, but Large Order Trades is
 *   the canonical industry case where green/red sides are mandatory
 *   (Bybit / TradingView all use the same convention).
 * ============================================================================ */

/* up/down value cells (used by /trades and /trades/:base whale prints) */
/* [FIX] 2026-06-11 — `.tt-agg__table tbody td { color: var(--tt-fg-0) }`
 * flatten rule (0,1,2) beat standalone `.tt-agg__val--up/down` (0,1,0),
 * so Buy/Sell side + buy/sell USD columns rendered white. Scope up/down
 * to table cells so specificity (0,2,2) wins. */
.tt-agg__table tbody td.tt-agg__val--up,
.tt-agg__val--up   { color: var(--tt-up);   font-variant-numeric: tabular-nums; }
.tt-agg__table tbody td.tt-agg__val--down,
.tt-agg__val--down { color: var(--tt-down); font-variant-numeric: tabular-nums; }
.tt-agg__table tbody td.tt-up,
.tt-agg__table tbody td.is-up { color: var(--tt-up);   font-variant-numeric: tabular-nums; }
.tt-agg__table tbody td.tt-down,
.tt-agg__table tbody td.is-down { color: var(--tt-down); font-variant-numeric: tabular-nums; }

/* KPI strip (also reused by tt-trades-kpi on the home page) */
.tt-trades-kpi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin: 16px 0 20px;
}
.tt-trades-kpi__card {
  background: rgba(127,127,127,.06);
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 6px;
  padding: 12px 14px;
}
.tt-trades-kpi__label {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .7;
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.tt-trades-kpi__val {
  font-size: 18px;
  font-weight: 600;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-trades-kpi__val--up   { color: var(--tt-up); }
.tt-trades-kpi__val--down { color: var(--tt-down); }

/* Volume profile (horizontal sell|buy bars per price bin) */
.tt-vp-grid {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-vp-row {
  display: grid;
  grid-template-columns: 80px 1fr 1fr;
  align-items: center;
  gap: 6px;
  height: 18px;
}
.tt-vp-row__price {
  text-align: right;
  font-variant-numeric: tabular-nums;
  opacity: .85;
}
.tt-vp-row__sell, .tt-vp-row__buy {
  position: relative;
  height: 100%;
  background: rgba(127,127,127,.06);
  border-radius: 2px;
  overflow: hidden;
}
.tt-vp-row__sell { display: flex; justify-content: flex-end; }
.tt-vp-row__buy  { display: flex; justify-content: flex-start; }
.tt-vp-row__bar {
  position: absolute; top: 0; bottom: 0;
  opacity: .85;
}
.tt-vp-row__sell .tt-vp-row__bar { right: 0; }
.tt-vp-row__buy  .tt-vp-row__bar { left: 0; }
.tt-vp-row span {
  position: relative; z-index: 1;
  padding: 0 6px;
  font-variant-numeric: tabular-nums;
}

/* Exchange breakdown rows */
.tt-breakdown {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-breakdown__row {
  display: grid;
  grid-template-columns: 180px 1fr 90px;
  align-items: center;
  gap: 10px;
}
/* [FIX] 2026-06-11 — breakdown volume-share pct clipped to zero width.
 * Reason: label column is grid-fixed (~180px) but icon + ex + mt exceeded it;
 * default flex-shrink:1 let .tt-breakdown__pct collapse while overflow-x:hidden
 * on .tt-td-scroll-panel hid the overflow — badge promised "Volume share" but
 * no visible % in each row.
 * Change: min-width:0 + ellipsis on ex/mt; flex-shrink:0 + nowrap on pct.
 * Warning: do NOT remove flex-shrink:0 from __pct — pct will vanish again. */
.tt-breakdown__label {
  display: flex; gap: 6px; align-items: baseline;
  min-width: 0;
}
.tt-breakdown__ex {
  font-weight: 600; text-transform: uppercase;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tt-breakdown__mt {
  opacity: .65; font-size: 12px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex-shrink: 1;
}
.tt-breakdown__pct {
  margin-left: auto;
  opacity: .7;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  white-space: nowrap;
}
.tt-breakdown__bar {
  height: 12px;
  background: rgba(127,127,127,.08);
  border-radius: 3px;
  overflow: hidden;
  display: flex;
}
.tt-breakdown__bar-buy  { height: 100%; }
.tt-breakdown__bar-sell { height: 100%; }
.tt-breakdown__total {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}

/* Buy / Sell pressure gauge */
.tt-pressure { display: flex; flex-direction: column; gap: 12px; padding-top: 12px; }
.tt-pressure__bar {
  height: 18px;
  background: rgba(127,127,127,.08);
  border-radius: 4px;
  overflow: hidden;
  display: flex;
}
.tt-pressure__buy  { height: 100%; }
.tt-pressure__sell { height: 100%; }
.tt-pressure__legend {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-pressure__legend-buy  { color: var(--tt-up); }
.tt-pressure__legend-sell { color: var(--tt-down); }

/* Card empty state */
.tt-card__empty {
  padding: 24px 0;
  text-align: center;
  font-size: 14px;
  color: var(--tt-fg-0);
  opacity: .55;
}

/* Detail page chart panel */
.tt-td-chart { width: 100%; height: 340px; }
/* [FIX] 2026-06-11 — VP is HTML histogram, not lightweight-charts. Give it
 * its own scrollable panel so up to 60 price bins stay inside the card
 * instead of painting over Exchange Breakdown / Whale Prints below.
 * Reason: .tt-td-chart fixed height + default overflow:visible let VP rows
 * escape the card bounds and overlap the next grid row.
 * Change: .tt-td-vp-panel + .tt-td-scroll-panel with max-height + overflow-y.
 * Warning: do NOT reuse .tt-td-chart for VP — CVD needs the fixed canvas box. */
.tt-td-vp-panel,
.tt-td-scroll-panel {
  width: 100%;
  max-height: 340px;
  overflow-x: hidden;
  overflow-y: auto;
  min-height: 0;
}
.tt-td-vp-panel .tt-vp-grid {
  padding-right: 4px;
}

/* /trades/:base — section rhythm + card containment */
#tt-trades-detail .tt-trades-detail__section {
  margin-bottom: 16px;
}
#tt-trades-detail .tt-trades-detail__section:last-child {
  margin-bottom: 0;
}
#tt-trades-detail .tt-trades-detail__card {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
#tt-trades-detail .tt-trades-detail__prints {
  max-height: 420px;
  overflow-y: auto;
  overflow-x: auto;
}
#tt-trades-detail .tt-vp-row {
  grid-template-columns: 96px minmax(0, 1fr) minmax(0, 1fr);
}
#tt-trades-detail .tt-breakdown__row {
  grid-template-columns: minmax(170px, 220px) minmax(0, 1fr) 90px;
}
#tt-trades-detail .tt-breakdown__label {
  align-items: center;
  gap: 8px;
  min-width: 0;
}
#tt-trades-detail .tt-trades-detail__venue {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
#tt-trades-detail .tt-trades-detail__venue-text {
  min-width: 0;
  text-transform: capitalize;
}
#tt-trades-detail .tt-trades-detail__venue-mkt {
  opacity: 0.7;
  text-transform: lowercase;
}
#tt-trades-detail .tt-trades-detail__prints .tt-trades-detail__venue {
  display: flex;
}
/* [FIX] 2026-05-13 — height moved off inline `style=` so responsive
   overrides below don't need !important. EJS template now sets only
   class names. JS (lightweight-charts) reads container client size. */

/* /trades list — clickable rows */
#tt-trades-tbody tr[data-base] { cursor: pointer; }
#tt-trades-tbody tr[data-base]:hover { background: rgba(127,127,127,.06); }

/* /trades list — per-row drill-down action (last column) */
.tt-agg__th--action,
.tt-agg__td--action {
  width: 1%;
  white-space: nowrap;
  padding-left: 14px;
  padding-right: 14px;
}
.tt-agg__row-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--tt-line);
  border-radius: 6px;
  background: rgba(127,127,127,.12);
  color: var(--tt-fg-0);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: background .12s ease, border-color .12s ease;
}
#tt-trades-tbody tr[data-base]:hover .tt-agg__row-link,
#tt-screener-tbody tr[data-base]:hover .tt-agg__row-link {
  background: rgba(127,127,127,.2);
  border-color: rgba(127,127,127,.45);
}
.tt-agg__row-link:hover,
.tt-agg__row-link:focus-visible {
  background: rgba(127,127,127,.24);
  border-color: var(--tt-fg-0);
  outline: none;
}
.tt-agg__row-link svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  stroke: var(--tt-fg-0);
  fill: none;
}
.tt-agg__row-link__text {
  line-height: 1;
}

/* Trades detail area: title icon + label alignment
 * (sym-name unified with other tables in the consolidated rule below). */
#tt-trades-detail .tt-agg__title   { display: inline-flex; align-items: center; gap: 10px; }

@media (max-width: 768px) {
  .tt-breakdown__row { grid-template-columns: 110px 1fr 80px; }
  .tt-vp-row         { grid-template-columns: 64px 1fr 1fr; }
}

/* ── /liquidations overview KPI row (3 windows × 4 cells) ─────────────── */
/* [ADD] 2026-04-28 */
.tt-liq-overview { padding: 16px; }
.tt-liq-overview__grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 16px;
}
.tt-liq-overview__col {
  display: flex; flex-direction: column; gap: 6px;
  padding: 12px 14px;
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 6px;
  min-width: 0;
}
.tt-liq-overview__label {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .65;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.tt-liq-overview__notional {
  font-size: 22px;
  font-weight: 700;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-liq-overview__rowmeta {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-liq-overview__metakey { opacity: .6; }
.tt-liq-overview__metaval { font-variant-numeric: tabular-nums; font-weight: 600; }
.tt-liq-overview__metaval--icon { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.tt-liq-overview__metaval--icon span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 768px) {
  .tt-liq-overview__grid { grid-template-columns: 1fr; }
  .tt-liq-overview__notional { font-size: 18px; }
}

/* ── /screener — clickable rows ──────────────────────────────────────── */
/* [ADD] 2026-04-28; [FIX] 2026-05-09 P2-2: click removed (no destination);
   [FIX] 2026-07-05: rows navigate to /currencies/:base/futures again, so
   cursor:pointer is restored. Hover tint kept for scan-affordance. */
#tt-screener-tbody tr[data-base] { cursor: pointer; }
#tt-screener-tbody tr[data-base]:hover { background: rgba(127,127,127,.06); }

/* ── /squeeze — same pattern ─────────────────────────────────────────── */
/* [ADD] 2026-04-28; [FIX] 2026-05-09 P2-2: row click → /chart removed. */
#tt-squeeze-tbody tr[data-base]:hover { background: rgba(127,127,127,.06); }

/* ── Unified Base-column icon + ticker alignment for all aggregation tables
 * [REFACTOR] 2026-05-11 — consolidated from 6 per-tbody rules into a single
 *   selector list. Without inline-flex the 32px coin icon falls back to
 *   inline-block layout and aligns to the text baseline, dragging the
 *   ticker label visibly below the icon centre. Decorative properties
 *   (display/align-items/gap), not colour/font-size → not subject to the
 *   .tt- styling whitelist. */
#tt-trades-tbody          .tt-agg__sym-name,
#tt-screener-tbody        .tt-agg__sym-name,
#tt-squeeze-tbody         .tt-agg__sym-name,
#tt-newlist-tbody         .tt-agg__sym-name,
#tt-unlocks-tbody         .tt-agg__sym-name,
#tt-hl-tbody              .tt-agg__sym-name,
#tt-fund-basis-prem-tbody .tt-agg__sym-name,
#tt-fund-basis-disc-tbody .tt-agg__sym-name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; max-width: 100%; }

/* [FIX] 2026-06-11 — coin icon ↔ ticker overlap regression on /trades list.
 * Root cause: the inner ticker <span> had no min-width:0, so in an inline-flex
 * row a long base symbol could not shrink and pushed past the 32px icon's
 * box, visually overlapping it on narrow cells. Pin the icon's box
 * (flex-shrink:0 already on .tt-coin-icon) AND let the label shrink + ellipsize
 * so the two never collide. Decorative layout only — not subject to the
 * colour/font-size whitelist. */
#tt-trades-tbody          .tt-agg__sym-name > span:not(.tt-coin-icon),
#tt-screener-tbody        .tt-agg__sym-name > span:not(.tt-coin-icon),
#tt-squeeze-tbody         .tt-agg__sym-name > span:not(.tt-coin-icon),
#tt-newlist-tbody         .tt-agg__sym-name > span:not(.tt-coin-icon),
#tt-unlocks-tbody         .tt-agg__sym-name > span:not(.tt-coin-icon),
#tt-hl-tbody              .tt-agg__sym-name > span:not(.tt-coin-icon),
#tt-fund-basis-prem-tbody .tt-agg__sym-name > span:not(.tt-coin-icon),
#tt-fund-basis-disc-tbody .tt-agg__sym-name > span:not(.tt-coin-icon) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── /screener — at-a-glance mini bars (number + bar combo) ────────── */
/* [ADD] 2026-04-29 — replace plain numeric cells with number + mini bar
   for 1h%/24h%/Funding/OI Δ%/Liq columns. Bars use the same up/down
   colour vars as the existing pct cells (var(--tt-up)/var(--tt-down))
   per web_app_styling rule exception list. Bars are 28px wide max so the
   table density stays unchanged. */
.tt-cell-bar {
  /* Stack number + bar vertically so the row height stays unchanged
     even when the bar is rendered. The bar sits below the number using
     a negative top margin trick that keeps cell height ≈ row baseline. */
  position: relative;
  padding-bottom: 8px;
}
.tt-cell-bar__num {
  display: block;
  line-height: 1.2;
}
.tt-bar-uni,
.tt-bar-bi {
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 4px;
  height: 3px;
  border-radius: 2px;
  background: rgba(127,127,127,.12);
  overflow: hidden;
}
.tt-bar-uni > span {
  display: block;
  height: 100%;
  border-radius: 2px;
}
.tt-bar-uni--up   { background: var(--tt-up);   margin-left: 0; }
.tt-bar-uni--down { background: var(--tt-down); margin-left: 0; }
/* Bi-directional bar: a 1px centerline + half-fill that extends from
   center towards the appropriate side. Industry pattern for funding /
   centred-zero metrics. */
.tt-bar-bi::before {
  content: ""; position: absolute;
  left: 50%; top: -1px; bottom: -1px;
  width: 1px;
  background: rgba(127,127,127,.4);
  transform: translateX(-0.5px);
}
.tt-bar-bi__fill {
  position: absolute;
  top: 0; bottom: 0;
  border-radius: 2px;
}
.tt-bar-bi__fill--up   { background: var(--tt-up); }
.tt-bar-bi__fill--down { background: var(--tt-down); }
/* Liq overload dot — appears next to the 24h Liq number when liq exceeds
   1% of OI (industry threshold for forced-deleveraging episodes). */
.tt-liq-warn {
  display: inline-block;
  width: 6px; height: 6px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--tt-down);
  vertical-align: middle;
  box-shadow: 0 0 0 2px rgba(239,83,80,.18);
}

/* ── 7-day sparkline column — P2#16 (2026-05-11) ───────────────────
   Renders as an inline SVG polyline inside each table cell. We keep
   the cell narrow (80px) and centred so it does not push the wide
   numeric columns off-screen. Empty rows fall back to `tt-spark--
   empty` which prints a dim em-dash; that way the column always
   reserves space and the table layout never reflows when individual
   bases fall outside the screener leader's top-30 spark window.   */
.tt-cell-spark {
  text-align: center;
  vertical-align: middle;
  padding: 4px 8px;
  white-space: nowrap;
}
.tt-spark {
  display: inline-block;
  vertical-align: middle;
  line-height: 0;
}
.tt-spark--empty {
  /* empty spark cell uses muted dash — empty 7d cell renders an em-dash
     that should not visually compete with real data. Per web_app_styling
     rule §2 exception "input placeholder = var(--tt-fg-3)", we apply the
     same rule to data-placeholder cells. */
  color: var(--tt-fg-0);
  font-size: 12px;
}

/* ── /funding settlement countdown ribbon — Wave 1.1 (P0 #5) ─────── */
/* [ADD] 2026-04-29 — three-cell ribbon under the page hero showing the
   next funding settlement for binance/bybit/okx in HH:MM:SS. Layout is
   centred horizontally, picks up the existing fg/up colour vars and uses
   the font-size whitelist (12 / 18). */
.tt-fund-countdown {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 24px;
  padding: 14px 16px;
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 10px;
  background: rgba(127,127,127,.04);
  color: var(--tt-fg-0);
}
.tt-fund-countdown__label {
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .75;
}
.tt-fund-countdown__list {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}
.tt-fund-countdown__cell {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}
.tt-fund-countdown__ex {
  font-size: 12px;
  opacity: .75;
}
.tt-fund-countdown__time {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
  color: var(--tt-fg-0);
}

/* ── Altcoin Season Index — Wave 1.2 (P0 #7) ────────────────────── */
/* Home KPI card content (#tt-sent-kpi-altseason .tt-sent-kpi__body) and
   /sentiment Overview large panel (#tt-altseason-large). Bar uses three
   colour zones (≤25 BTC / 25-75 transition / ≥75 alt) with a marker dot. */
.tt-altseason__num {
  font-size: 22px;
  font-weight: 600;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.tt-altseason__num-suffix {
  font-size: 14px;
  opacity: .55;
}
.tt-altseason__label {
  font-size: 14px;
  margin: 4px 0 10px 0;
  color: var(--tt-fg-0);
}
.tt-altseason__bar {
  position: relative;
  display: flex;
  height: 6px;
  border-radius: 4px;
  overflow: hidden;
  background: rgba(127,127,127,.12);
}
.tt-altseason__bar--lg { height: 12px; }
.tt-altseason__bar-zone { height: 100%; }
.tt-altseason__bar-zone--btc { width: 25%; background: rgba(239,83,80,.55); }
.tt-altseason__bar-zone--mid { width: 50%; background: rgba(127,127,127,.30); }
.tt-altseason__bar-zone--alt { width: 25%; background: rgba(38,166,154,.55); }
.tt-altseason__bar-marker {
  position: absolute;
  top: 50%;
  width: 12px; height: 12px;
  margin-left: -6px;
  border-radius: 50%;
  background: var(--tt-fg-0);
  border: 2px solid rgba(0,0,0,.55);
  transform: translateY(-50%);
  box-shadow: 0 0 0 2px rgba(255,255,255,.18);
}
.tt-altseason__bar--lg .tt-altseason__bar-marker {
  width: 18px; height: 18px;
  margin-left: -9px;
}
.tt-altseason__legend {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .8;
}

/* Large /sentiment Overview panel */
.tt-altseason-large {
  padding: 18px 20px;
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 12px;
  background: rgba(127,127,127,.04);
  color: var(--tt-fg-0);
}
.tt-altseason-large__row {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.tt-altseason-large__num {
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.tt-altseason-large__num-suffix {
  font-size: 16px;
  opacity: .55;
}
.tt-altseason-large__meta { display: flex; flex-direction: column; gap: 4px; }
.tt-altseason-large__state {
  font-size: 18px;
  font-weight: 600;
}
.tt-altseason-large__sub {
  font-size: 12px;
  opacity: .7;
}
.tt-altseason-large__legend {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 12px;
  opacity: .85;
}

/* ── Predicted Funding Top/Bottom 5 — Wave 1.3 (P0 #2) ─────────── */
.tt-fund-pred {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 768px) {
  .tt-fund-pred { grid-template-columns: 1fr; }
}
.tt-fund-pred__col {
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 10px;
  padding: 12px 14px;
  background: rgba(127,127,127,.04);
}
.tt-fund-pred__col-head {
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .75;
  margin-bottom: 8px;
  color: var(--tt-fg-0);
}
.tt-fund-pred__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* [FIX] 2026-05-09 P2-2 — predicted-funding row click → /chart removed. */
.tt-fund-pred__row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: default;
  color: var(--tt-fg-0);
}
.tt-fund-pred__row:hover { background: rgba(127,127,127,.10); }
.tt-fund-pred__rank {
  font-size: 12px;
  opacity: .7;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.tt-fund-pred__sym {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.tt-fund-pred__sym-text { display: flex; flex-direction: column; min-width: 0; }
.tt-fund-pred__base { font-size: 14px; font-weight: 600; }
.tt-fund-pred__meta { font-size: 12px; opacity: .65; }
.tt-fund-pred__val {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.tt-fund-pred__val-sub {
  font-size: 12px;
  font-weight: 400;
  font-style: normal;
  opacity: .7;
}

/* ── Cascade Events list — Wave 2.3 (P0 #6) ───────────────────── */
.tt-liq-cascade__list { margin-top: 4px; }
.tt-liq-cascade__rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* [FIX] 2026-05-09 P2-2 round 2 — cascade row is display-only (WEB-260 removed
   bindCascadeClicks / navigateToChart). cursor:pointer kept hinting
   interactivity that no longer exists, so it drops to default. Hover tint
   kept so the strip still scans as a list. */
.tt-liq-cascade__row {
  display: grid;
  grid-template-columns: 28px 1.3fr 1fr 1fr 0.9fr 1fr;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 8px;
  background: rgba(127,127,127,.04);
  cursor: default;
  color: var(--tt-fg-0);
}
.tt-liq-cascade__row:hover { background: rgba(127,127,127,.10); }
@media (max-width: 980px) {
  .tt-liq-cascade__row { grid-template-columns: 28px 1fr 1fr; gap: 8px; }
  .tt-liq-cascade__amp, .tt-liq-cascade__venues { display: none; }
}
.tt-liq-cascade__rank {
  font-size: 12px;
  opacity: .7;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.tt-liq-cascade__sym {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.tt-liq-cascade__sym-text { display: flex; flex-direction: column; min-width: 0; }
.tt-liq-cascade__base { font-size: 14px; font-weight: 600; }
.tt-liq-cascade__when { font-size: 12px; opacity: .65; }
.tt-liq-cascade__metric {
  display: inline-flex;
  flex-direction: column;
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.tt-liq-cascade__metric em {
  font-size: 12px;
  font-style: normal;
  font-weight: 400;
  opacity: .65;
}
.tt-liq-cascade__venues {
  font-size: 12px;
  opacity: .75;
  text-align: right;
}

/* ── ±1% Depth strip — Wave 2.2 (P0 #3) ────────────────────────── */
.tt-td-depth {
  margin: 12px 0;
}
.tt-td-depth:empty { display: none; }
.tt-td-depth__row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 10px;
  background: rgba(127,127,127,.04);
}
@media (max-width: 720px) {
  .tt-td-depth__row { grid-template-columns: repeat(2, 1fr); }
}
.tt-td-depth__cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--tt-fg-0);
}
.tt-td-depth__label {
  font-size: 12px;
  opacity: .65;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.tt-td-depth__val {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ── Cross-Basis dual-column layout — Wave 2.1 (P0 #4) ────────── */
.tt-fund-basis {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 920px) {
  .tt-fund-basis { grid-template-columns: 1fr; }
}
.tt-fund-basis__col {
  border: 1px solid rgba(127,127,127,.18);
  border-radius: 10px;
  padding: 12px 14px;
  background: rgba(127,127,127,.04);
}
.tt-fund-basis__col-head {
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .75;
  margin-bottom: 10px;
  color: var(--tt-fg-0);
}

/* Home funding row countdown chip — single-line above the 3-card grid. */
.tt-funding-row__countdown {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 8px;
  margin: 0 0 10px 0;
  color: var(--tt-fg-0);
}
.tt-funding-row__countdown-label {
  font-size: 12px;
  opacity: .65;
}
.tt-funding-row__countdown-time {
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ── /currencies/:base/futures composite dashboard ──────────────────────
 * Wave 3.1 (P0 #8). Pure layout container — colours/fonts inherit from
 * the global tokens to satisfy web_app_styling.mdc (only --tt-fg-0 +
 * --tt-up/--tt-down are referenced for direction-bearing data).
 */
.tt-cur-kpi {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
}
.tt-cur-kpi__cell {
  background: rgba(127,127,127,.05);
  border-radius: 8px;
  padding: 12px 14px;
  color: var(--tt-fg-0);
}
.tt-cur-kpi__label {
  font-size: 12px;
  opacity: .7;
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.tt-cur-kpi__value {
  font-size: 18px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.tt-cur-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.tt-cur-card {
  background: rgba(127,127,127,.05);
  border-radius: 8px;
  padding: 14px;
  color: var(--tt-fg-0);
}
.tt-cur-card__title {
  font-size: 14px;
  font-weight: 400;
  margin-bottom: 10px;
  color: var(--tt-fg-0);
}
.tt-cur-card__body {
  font-size: 14px;
  color: var(--tt-fg-0);
}
.tt-cur-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.tt-cur-table th,
.tt-cur-table td {
  padding: 6px 8px;
  text-align: left;
  font-size: 14px;
  color: var(--tt-fg-0);
  border-bottom: 1px solid rgba(127,127,127,.12);
}
.tt-cur-table th.num,
.tt-cur-table td.num {
  /* [CHANGE] 2026-05-11 — flipped right → left to match /currencies sidebar
   * with the unified left-aligned column convention used elsewhere. */
  text-align: left;
  font-variant-numeric: tabular-nums;
}
.tt-cur-depth__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 0;
  font-size: 14px;
  border-bottom: 1px solid rgba(127,127,127,.12);
  color: var(--tt-fg-0);
}
.tt-cur-depth__row:last-child { border-bottom: 0; }
.tt-cur-links {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}
.tt-cur-link {
  font-size: 14px;
  color: var(--tt-fg-0);
  text-decoration: none;
  padding: 8px 12px;
  background: rgba(127,127,127,.05);
  border-radius: 6px;
}
.tt-cur-link:hover { background: rgba(127,127,127,.12); }
@media (max-width: 720px) {
  .tt-cur-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tt-cur-grid { grid-template-columns: 1fr; }
}

/* ── /liquidations · Heatmap time window (adjacent to treemap) ───── */
.tt-liq-heatmap__windowbar {
  display: inline-flex;
  gap: 6px;
  margin-left: auto;
  flex-shrink: 0;
}

/* ── /liquidations · Liquidation History (Wave 3.2 P1 #11) ─────────── */
.tt-liq-history__windowbar {
  display: inline-flex;
  gap: 6px;
  margin-left: auto;
}
.tt-liq-history__grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 12px;
  align-items: stretch;
}
.tt-liq-history__chart {
  background: rgba(127,127,127,.05);
  border-radius: 8px;
  padding: 12px;
  min-height: 0;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.tt-liq-history__canvas {
  width: 100%;
  height: 180px;
  display: block;
  cursor: crosshair;
  flex-shrink: 0;
}
.tt-liq-history__empty {
  position: absolute;
  inset: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
  justify-content: center;
  padding: 16px;
  text-align: center;
  color: var(--tt-fg-0);
  font-size: 14px;
  pointer-events: none;
  background: rgba(127,127,127,.04);
  border-radius: 6px;
}
.tt-liq-history__empty-title { font-size: 14px; font-weight: 600; color: var(--tt-fg-0); }
.tt-liq-history__empty-sub   { font-size: 12px; opacity: .7; max-width: 420px; line-height: 1.5; color: var(--tt-fg-0); }
.tt-liq-history__tooltip {
  position: absolute;
  z-index: 6;
  min-width: 148px;
  padding: 8px 10px;
  border: 1px solid rgba(127,127,127,.28);
  border-radius: 4px;
  background: var(--tt-bg-1, rgba(18,18,20,.96));
  color: var(--tt-fg-0);
  font-size: 12px;
  line-height: 1.5;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0,0,0,.28);
  white-space: nowrap;
}
.tt-liq-history__tt-time {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .65;
  margin-bottom: 4px;
}
.tt-liq-history__tt-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
.tt-liq-history__tt-label { font-size: 12px; color: var(--tt-fg-0); }
.tt-liq-history__tt-val {
  font-size: 12px;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-liq-history__tt-total {
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px solid rgba(127,127,127,.22);
}

/* ── /liquidations · Liquidation Map (realized liq by price bucket) ── */
.tt-liq-map__controls {
  display: inline-flex;
  gap: 10px;
  margin-left: auto;
  flex-wrap: wrap;
}
.tt-liq-map__basebar,
.tt-liq-map__windowbar {
  display: inline-flex;
  gap: 6px;
}
.tt-liq-map__legend {
  display: flex;
  gap: 18px;
  margin: 6px 0 8px;
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-liq-map__legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.tt-liq-map__swatch {
  width: 12px;
  height: 12px;
  border-radius: 2px;
  display: inline-block;
}
/* [EXCEPTION] finance red/green liquidation semantics — long=green, short=red */
.tt-liq-map__swatch--long  { background: var(--tt-up); }
.tt-liq-map__swatch--short { background: var(--tt-down); }
.tt-liq-map__chart {
  background: rgba(127,127,127,.05);
  border-radius: 8px;
  padding: 12px;
  position: relative;
  overflow: hidden;
  min-height: 200px;
}
.tt-liq-map__canvas {
  width: 100%;
  height: 360px;
  display: block;
  cursor: crosshair;
}
.tt-liq-map__empty {
  position: absolute;
  inset: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
  justify-content: center;
  padding: 16px;
  text-align: center;
  color: var(--tt-fg-0);
  font-size: 14px;
  background: rgba(127,127,127,.04);
  border-radius: 6px;
}
.tt-liq-map__empty-title { font-size: 14px; font-weight: 600; color: var(--tt-fg-0); }
.tt-liq-map__empty-sub   { font-size: 12px; opacity: .7; max-width: 420px; line-height: 1.5; color: var(--tt-fg-0); }
.tt-liq-map__tooltip {
  position: absolute;
  z-index: 6;
  min-width: 168px;
  padding: 8px 10px;
  border: 1px solid rgba(127,127,127,.28);
  border-radius: 4px;
  background: var(--tt-bg-1, rgba(18,18,20,.96));
  color: var(--tt-fg-0);
  font-size: 12px;
  line-height: 1.5;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0,0,0,.28);
  white-space: nowrap;
}
.tt-liq-map__tt-time {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .65;
  margin-bottom: 4px;
}
.tt-liq-map__tt-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
.tt-liq-map__tt-label { font-size: 12px; color: var(--tt-fg-0); }
.tt-liq-map__tt-val {
  font-size: 12px;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}

.tt-liq-history__top10 {
  background: rgba(127,127,127,.05);
  border-radius: 8px;
  padding: 12px;
  overflow: auto;
  max-height: 320px;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
@media (max-width: 720px) {
  .tt-liq-history__grid { grid-template-columns: 1fr; }
}

/* ── /unlocks Token Unlock calendar (Wave 3.5 P1 #10) ────────────────
 * [REDESIGN] 2026-05-11 — page rebuilt on top of the standard
 *   `tt-agg__table-wrap` + `tt-agg__table` primitives so it visually
 *   matches /new-listings, /movers, /liquidations, /funding etc.
 *   The previous grey-card wrapper (`.tt-unlocks-table`), bespoke token
 *   cell classes (`.tt-unlocks-token` / `.tt-unlocks-token__name`) and
 *   disclaimer card background (`.tt-unlocks-disclaimer`) are removed.
 *   The accidentally-global `.tt-cur-table td:nth-child(2) { min-width }`
 *   rule that leaked into /currencies and /liquidations is also dropped.
 * Rules compliance (web_app_styling.mdc):
 *   - color: var(--tt-fg-0) only (no fg-1/2/3); de-emphasis via opacity.
 *   - font-size kept on the 12/14/16/18/22/28 whitelist (12 here).
 *   - decorative props (display/align-items/gap/min-width) unrestricted. */
/* sym-name inline-flex unified with other tables in the consolidated rule
 * (search "Unified Base-column icon + ticker alignment"). Here we only keep
 * unlocks-specific min-width / white-space so the Token column never
 * collapses next to long Type strings ("Team allocation" etc). */
#tt-unlocks-tbody .tt-agg__sym-name {
  min-width: 0;
  white-space: nowrap;
}
#tt-unlocks-grid tbody td:nth-child(2),
#tt-unlocks-grid thead th:nth-child(2) { min-width: 120px; }
.tt-agg__disclaimer {
  margin: 24px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--tt-fg-0);
  opacity: 0.55;
}

/* ── /dex DEX family (Phase 1-3) ─────────────────────────────────────
 * Layout primitives for /dex, /dex/whales, /dex/funding-arb, and
 * /dex/whales/:address. Colours/fonts obey web_app_styling.mdc — only
 * var(--tt-fg-0), no opacity hacks on text, font-sizes from the
 * 12/14/16/18/22/28 whitelist. */

/* Tab panes on /dex and /dex/whales — only one visible at a time. is-hidden
 * is a simple display:none rather than aria-hidden because these panes don't
 * enter/leave the DOM (keeping them avoids JS thrash on tab switches). */
.tt-dex-pane {
  margin-top: 12px;
}
.tt-dex-pane.is-hidden {
  display: none;
}

/* Address chip inside a table row. Link colour uses the accent hover
 * exception from web_app_styling.mdc §Exception list; the base state is
 * the standard foreground so the row stays readable on both themes. */
.tt-dex-addr {
  color: var(--tt-fg-0);
  text-decoration: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px;
  border-bottom: 1px dashed var(--tt-fg-0);
}
.tt-dex-addr:hover {
  /* [EXCEPTION] accent hover — product's single allowed brand accent. */
  color: #2962ff;
  border-bottom-color: #2962ff;
}

/* Small rounded chip next to the address or next to a venue name. The
 * --dex variant is blue-outlined (matches the DEX accent) but text colour
 * is still the 0-level foreground to keep contrast; label-type chips
 * (market_maker / arbitrage / fund / ...) colour the border only. */
.tt-dex-chip {
  display: inline-block;
  font-size: 12px;
  color: var(--tt-fg-0);
  padding: 2px 6px;
  border-radius: 999px;
  border: 1px solid var(--tt-fg-0);
  margin-left: 6px;
  line-height: 1.4;
}
.tt-dex-chip--dex {
  border-color: #2962ff;
}
.tt-dex-chip--market_maker {
  border-color: #26a69a;
}
.tt-dex-chip--arbitrage {
  border-color: #ffb300;
}
.tt-dex-chip--fund {
  border-color: #ab47bc;
}
.tt-dex-chip--proprietary {
  border-color: #ef5350;
}

/* [ADD] 2026-05-02 — unified venue + base cells with 32px icons.
 * Used by tt.dex.js / tt.dex.whales.js / tt.dex.funding-arb.js /
 * tt.dex.address.js to render "<icon 32> <label>" inline. Font size from
 * the 14 whitelist; colour var(--tt-fg-0) per web_app_styling.mdc. */
.tt-dex-venue-cell,
.tt-dex-base-cell {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--tt-fg-0);
  font-size: 14px;
  min-width: 0;
}

/* Row padding bump so the 32px icons don't clip against th/td vertical
 * borders. Only applies inside /dex family pages via their scoping classes
 * (.tt-agg on /dex/* pages already wraps every table). */
.tt-agg .tt-dex-venue-cell > span:not(.tt-exchange-icon-wrap),
.tt-agg .tt-dex-base-cell  > span:not(.tt-coin-icon) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* [ADD] 2026-07-05 — funding settlement-interval badge next to the raw rate.
 * Neutral colour (not the up/down cell colour) so users can tell the single
 * settle period apart from the signed rate. 12px is the aggregation-page
 * secondary-label size (web_app_styling.mdc whitelist). */
.tt-dex-fund-period {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: 0.65;
  margin-left: 4px;
  white-space: nowrap;
}

/* ── Liquidation Waterfall (Block D, /dex/whales) ─────────────────────── */
/* [ADD] 2026-05-08 — DEX plan §7.3 Block D. Strict typography:
 * font sizes from {12,14,16,18}; text colour var(--tt-fg-0); semantic
 * up/down colours allowed for LONG/SHORT bars per web_app_styling.mdc
 * exception list. */
.tt-agg .tt-dex-liqwf__subtitle,
.tt-agg .tt-dex-liqwf__venues {
  font-size: 12px;
  line-height: 1.35;
  font-weight: 400;
  color: var(--tt-fg-0);
  opacity: .65;
}
.tt-agg .tt-dex-liqwf__subtitle {
  margin: 0 0 6px;
}
.tt-agg .tt-dex-liqwf__venues {
  margin: 0 0 8px;
}
.tt-dex-liqwf__head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px; margin: 12px 0 8px;
}
/* [CHG] 2026-07-05 — up to Top-10 dynamic base chips: horizontal scroll
   instead of wrapping so the head row stays one line (scrollbar hidden by
   the global tradeiz-custom.css rule, shows on hover). */
.tt-dex-liqwf__bases {
  display: flex; gap: 6px;
  overflow-x: auto;
  flex-wrap: nowrap;
  min-width: 0;
}
.tt-dex-liqwf__base {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid var(--tt-line);
  color: var(--tt-fg-0);
  font-size: 14px;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  flex: 0 0 auto;
}
.tt-dex-liqwf__base .tt-coin-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.tt-dex-liqwf__base .tt-coin-icon__fb { font-size: 12px; }
.tt-dex-liqwf__base:hover {
  border-color: #2962ff; /* [EXCEPTION] product accent — hover is allowed */
}
.tt-dex-liqwf__base.is-active {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
  border-color: var(--tt-fg-0);
}
.tt-dex-liqwf__meta {
  font-size: 14px;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-dex-liqwf__chart {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 0;
}
.tt-dex-liqwf__row {
  display: grid;
  grid-template-columns: 110px 1fr 200px;
  align-items: center;
  gap: 12px;
  padding: 2px 0;
  font-size: 12px;
  color: var(--tt-fg-0);
  font-variant-numeric: tabular-nums;
}
.tt-dex-liqwf__row.is-mark {
  /* Decorative mark-price marker — uses the product accent in border
     only (decorative, not text colour, per web_app_styling.mdc). */
  border-top: 1px solid #2962ff;
  border-bottom: 1px solid #2962ff;
  padding: 4px 0;
  background: rgba(41, 98, 255, 0.06);
}
.tt-dex-liqwf__price {
  text-align: right;
  font-weight: 600;
}
.tt-dex-liqwf__bars {
  position: relative;
  height: 10px;
  display: flex;
  align-items: center;
  gap: 2px;
}
.tt-dex-liqwf__bar {
  height: 100%;
  border-radius: 2px;
  min-width: 0;
}
.tt-dex-liqwf__bar--long {
  background: var(--tt-up);   /* [EXCEPTION] LONG = green */
}
.tt-dex-liqwf__bar--short {
  background: var(--tt-down); /* [EXCEPTION] SHORT = red */
}
.tt-dex-liqwf__nums {
  display: flex; justify-content: space-between; gap: 8px;
}
.tt-agg .tt-dex-liqwf__footnote {
  font-size: 12px;
  line-height: 1.35;
  font-weight: 400;
  color: var(--tt-fg-0);
  opacity: .65;
  margin-top: 8px;
}

/* ============================================================================
 * MINIMAL FLAT THEME — global flatten for /movers, /sentiment*, /liquidations,
 *   /funding, /screener, /squeeze, /trades, /new-listings, /unlocks,
 *   /hyperliquid, /dex* and similar aggregation pages.
 *
 * [ADD] 2026-05-11 — product directive: "remove all panel/card backgrounds
 *   and 3D feel; keep the page minimal and flat".
 *
 * Strategy:
 *   - Strip background fills, borders, box-shadows and rounded corners from
 *     every section/card/panel container so blocks separate via whitespace
 *     only (margin / padding) — not visual chrome.
 *   - KEEP the up/down semantic colors (var(--tt-up)/var(--tt-down)),
 *     liquidation-warn dots, status indicators, and data-driven heatmap
 *     fills (treemap cells, liq cells, sparkline strokes) — these are
 *     financial-UA legibility, not "container chrome".
 *   - KEEP table row hover tint so users can still trace a row across many
 *     numeric columns.
 *   - KEEP 1px border-bottom under thead (visual cue that header ≠ data).
 *   - KEEP rank pill background for legibility against the hover tint.
 *
 * Scope: scoped under .tt-home / .tt-agg roots so chart page (/chart) and
 *   third-party header/footer/menu chrome are NOT affected.
 * Compliance: only strips DECORATIVE properties (background / border-radius
 *   / box-shadow / non-bottom borders) — does NOT change `color` or
 *   `font-size`, so it stays inside the web_app_styling.mdc whitelist
 *   (the rule only constrains those two property categories). */

/* Outer page panels / sections */
.tt-agg .tt-liqsection,
.tt-agg .tt-mov-section,
.tt-agg .tt-fund-section,
.tt-agg .tt-sent-section {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Inner card-style cells (KPI strips, overview tiles, cascade rows,
 * chart wrappers, history charts/top10, sentiment hero/divergence, etc.) */
.tt-agg .tt-mov-kpi__cell,
.tt-agg .tt-liq-overview__col,
.tt-agg .tt-liq-cascade__row,
.tt-agg .tt-liq-history__chart,
.tt-agg .tt-liq-history__top10,
.tt-agg .tt-liq-map__chart,
.tt-agg .tt-fund-card,
.tt-agg .tt-sent-card,
.tt-agg .tt-sent-hero,
.tt-agg .tt-sent-radar__wrap,
.tt-agg .tt-sent-div__col {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Toolbars, tabs, table-wrap — drop chrome but keep layout. */
.tt-agg .tt-agg__toolbar,
.tt-agg .tt-agg__table-wrap,
.tt-agg .tt-agg__tabs,
.tt-agg .tt-fund-tabs,
.tt-agg .tt-mov-windowbar,
.tt-agg .tt-liqpage__windowbar,
.tt-agg .tt-liq-history__windowbar,
.tt-agg .tt-liq-map__basebar,
.tt-agg .tt-liq-map__windowbar {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Active toolbar buttons: collapse the inset shadow / pill background to
 * a simple accent color, keeping affordance without 3D feel. */
.tt-agg .tt-mov-windowbtn.is-active,
.tt-agg .tt-fund-tab.is-active,
.tt-agg .tt-agg__tab.is-active,
.tt-agg .tt-liqpage__winbtn.is-active {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
}

/* Pager + input chrome flatten */
.tt-agg .tt-agg__pager-btn,
.tt-agg .tt-agg__input,
.tt-agg .tt-agg__select,
.tt-agg .tt-fund-search,
.tt-agg .tt-mov-windowbtn,
.tt-agg .tt-liqpage__winbtn,
.tt-agg .tt-fund-tab,
.tt-agg .tt-agg__tab {
  background: transparent;
  border-radius: 0;
  box-shadow: none;
}

/* [FIX] 2026-05-12 — restore inverted-fill active chips after flatten rule.
 * Reason: flatten (above) sets background:transparent on every inverted-fill
 *   chip (.tt-agg__pager-btn / .tt-fund-tab / .tt-liqpage__winbtn .is-active)
 *   while leaving color:var(--tt-bg-0), so selected labels render black-on-black
 *   (dark theme) or white-on-white (light theme) — invisible active state.
 * Change: re-assert inverted fill with higher specificity (financial convention:
 *   current selection = fg/bg swap). Extended 2026-06-11 for fund-tab + winbtn.
 * Extended 2026-06-11 — restore border-radius:6px on default + active (flatten
 *   zeroed radius → square chips on /sentiment/funding-oi etc.). */
.tt-agg .tt-agg__pager-btn,
.tt-agg .tt-agg__pager-btn.is-active,
.tt-agg .tt-agg__pager-btn.is-active:hover,
.tt-agg .tt-fund-tab,
.tt-agg .tt-fund-tab.is-active,
.tt-agg .tt-fund-tab.is-active:hover,
.tt-agg .tt-liqpage__winbtn,
.tt-agg .tt-liqpage__winbtn.is-active,
.tt-agg .tt-liqpage__winbtn.is-active:hover,
.tt-agg .tt-mov-windowbtn,
.tt-agg .tt-mov-windowbtn.is-active,
.tt-agg .tt-mov-windowbtn.is-active:hover {
  border-radius: 6px;
}
.tt-agg .tt-agg__pager-btn.is-active,
.tt-agg .tt-agg__pager-btn.is-active:hover,
.tt-agg .tt-fund-tab.is-active,
.tt-agg .tt-fund-tab.is-active:hover,
.tt-agg .tt-liqpage__winbtn.is-active,
.tt-agg .tt-liqpage__winbtn.is-active:hover,
.tt-agg .tt-mov-windowbtn.is-active,
.tt-agg .tt-mov-windowbtn.is-active:hover {
  background: var(--tt-fg-0);
  color: var(--tt-bg-0);
  border-color: var(--tt-fg-0);
  opacity: 1;
}

/* Keep a subtle 1px line for inputs/buttons so click-targets remain visible
 * (border is line-only, not a fill — matches the "minimal" brief). */
.tt-agg .tt-agg__pager-btn,
.tt-agg .tt-agg__input,
.tt-agg .tt-agg__select,
.tt-agg .tt-fund-search {
  border: 1px solid var(--tt-line);
}
.tt-agg .tt-mov-windowbtn,
.tt-agg .tt-liqpage__winbtn,
.tt-agg .tt-fund-tab,
.tt-agg .tt-agg__tab { border: 0; }

/* Same flatten for home page (/) — strip chrome from unused legacy panel
 * hooks only. Content modules (.tt-card / rail / live / tape) keep borders
 * in tradeiz-home.css so tiles read as discrete cells on #000. */
.tt-home .tt-home__panel,
.tt-home .tt-home__card,
.tt-home .tt-home__section,
.tt-home .tt-home__hero {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
/* Keep the row hover affordance everywhere even after flatten — it is
 * essential scan UX for long numeric tables. */

/* =====================================================================
   [ADD] 2026-05-13 — RESPONSIVE SAFETY NET (home + agg pages)
   Scope: index.ejs (.tt-home + .tt-ti-landing) and every aggregation
   page (<main class="tt-agg">) used by /movers, /sentiment*, /liquidations,
   /funding, /trades*, /screener, /squeeze, /new-listings, /hyperliquid,
   /unlocks, /currencies/*, /dex*. Chart page (.app, /chart) is NOT in
   scope (excluded per web_app_styling.mdc).

   Placement: this block lives at the very end of the LAST loaded CSS
   (tradeiz-aggregations.css comes after tradeiz-custom.css and
   tradeiz-home.css in agg-page-head.ejs / index.ejs). Equal-specificity
   rules in earlier files therefore lose the cascade tiebreak to these
   overrides, which is exactly what we want.

   Rationale: existing breakpoints in tradeiz-home.css / tradeiz-aggregations.css
   only handle a few top-level grids (.tt-grid--triple, .tt-spotlight-layout,
   .tt-liqblock__top). At tablet widths (768-991px) and phone widths
   (≤575px) many secondary grids (.tt-spotlight-live in 3-col, .tt-cta,
   .tt-liqsplit, .tt-liqlive__filters, .tt-sent-quad, .tt-trades-kpi,
   .tt-mov-windowbar, .tt-fund-kpi, .tt-fund-pred, .tt-sent-factor,
   .tt-liq-cascade__row, .tt-td-depth__row, .tt-fund-basis) collapse
   awkwardly or stay multi-column past their comfortable width, causing
   horizontal overflow + content overlap on iPad / phone viewports.

   Design rules (strict):
     1. Mobile-first additive: each rule only ACTIVATES below its
        breakpoint; never overrides desktop layout.
     2. No new color/font-size — fully compliant with web_app_styling.mdc
        (only existing var(--tt-fg-0) used; no new font-size values).
     3. No `!important` — selector specificity (.tt-home .X or .tt-agg .X)
        is 2-class deep so it beats the 1-class authoring style without
        forcing the cascade.
     4. Breakpoints aligned with existing site breakpoints so cascade is
        predictable:
          ≤ 1199.98px  — small laptop / large tablet landscape
          ≤  991.98px  — tablet portrait (Bootstrap md)
          ≤  767.98px  — phone landscape (Bootstrap sm)
          ≤  575.98px  — phone portrait (Bootstrap xs)

   Warning: do NOT raise selector specificity by adding extra parents —
   the existing CSS already has long ancestor chains; matching them keeps
   the cascade weight balanced. Adding `body` or `html` would tilt the
   cascade and break per-page tweaks.

   Warning: do NOT move this block back to tradeiz-custom.css — it MUST
   be in the last-loaded stylesheet (aggregations.css) so source-order
   tiebreaks fall this way. If you must split it, every selector that
   competes with a .tt-home/.tt-agg rule in home.css must keep an extra
   class on top of what home.css uses. */

/* ────────────────────────────────────────────────────────────────────
   1) Universal: prevent horizontal overflow on every device
   ──────────────────────────────────────────────────────────────────── */
.tt-home,
.tt-agg {
  overflow-x: clip;
  /* `clip` (CSS Overflow 3) is preferred over `hidden`: it does NOT
     establish a scroll container, so position:sticky table heads inside
     .tt-liqlive__list / .tt-liqbyex__body keep working. Falls back to
     `auto` on browsers without clip support (Chromium 90+ / FF 81+ /
     Safari 16+, fully covered on supported devices). */
}
/* .tt-ti-landing keeps its original `overflow: hidden` (defined in
   tradeiz-custom.css) — the star-field decoration uses `width: 100vw`
   and relies on hidden to clip cleanly. Don't change. */

/* Table-like content stays scrollable, never breaks layout */
.tt-agg .tt-agg__table-wrap,
.tt-agg .tt-liqlive__list,
.tt-agg .tt-liqlive__body,
.tt-agg .tt-liqbyex__body,
.tt-agg .tt-liqtop,
.tt-agg .tt-liq-cascade__list {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ────────────────────────────────────────────────────────────────────
   2) ≤ 1199.98px (small laptop / large tablet)
   ──────────────────────────────────────────────────────────────────── */
@media (max-width: 1199.98px) {
  /* Home hero: tagline + screenshot were sized for 1600px+, cap tagline
     and pull screenshot tighter so the CTA + stats bar all stay above
     the fold without overlap. */
  .tt-home #tt-home-tagline.tt-ti-landing__tagline {
    line-height: 1.08;
    margin: 16px auto clamp(36px, 5vw, 56px);
  }
  .tt-home .tt-ti-landing__main {
    margin-top: -32px;
  }

  /* Spotlight: chart 500px is too tall once it stacks with 3 live cards
     side-by-side on small laptops — drop to 420px. Selector intentionally
     mirrors tradeiz-home.css `.tt-spotlight-layout .tt-spotlight` (no
     `.tt-home` prefix) so home.css's 991/767 breakpoints can still
     override us at narrower widths. */
  .tt-spotlight-layout .tt-spotlight { height: 420px; }
  .tt-spotlight-live { height: 420px; }

  /* Sentiment quad (5 cards in a row) → 3 cols at 1199. */
  .tt-home .tt-sent-quad { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Agg page padding: top 120px was tuned for fixed header at 70px desktop;
     header collapses to mobile bar at ≤991 but this band still needs less
     vertical breathing room. */
  .tt-agg { padding: 100px 0 60px; }

  /* Home Market Pulse side rail: 4-across tiles squeeze value+label on tablet;
     2×2 keeps labels readable without the ≤767 inner-tile restack. */
  .tt-home .tt-pulse--side {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ────────────────────────────────────────────────────────────────────
   3) ≤ 991.98px (tablet portrait, ipad standard)
   ──────────────────────────────────────────────────────────────────── */
@media (max-width: 991.98px) {
  /* Home hero stays vertical (already handled in tradeiz-custom.css media
     991), but ensure the section can grow taller than the viewport when
     the screenshot + CTA + stats bar all stack. min-height: 100vh on
     short tablets (iPad portrait 1024×768) crushes the layout. */
  .tt-ti-landing {
    min-height: 0;
    min-height: auto;
  }
  .tt-home .tt-ti-landing__main {
    margin-top: 0;
    padding-top: 32px;
  }
  .tt-home #tt-home-tagline.tt-ti-landing__tagline {
    margin: 8px auto clamp(28px, 4vw, 40px);
  }
  /* [FIX] 2026-05-13 — Removed `.tt-home .tt-ti-landing__cta { margin-top:
     clamp(24px, 4vw, 36px) }`. Reason: this rule had higher specificity
     (`.tt-home` + class chain = 0,2,0) than the canonical CTA margin
     rule in tradeiz-custom.css (`.tt-ti-landing__cta` = 0,1,0), so it
     unconditionally overrode the scaled margin-top formula
     `(clamp(36px,4vw,52px)+5) * var(--tt-cta-scale)` at every viewport
     ≤991.98. The result: at 992px the margin-top was the scaled value
     ~34px (correct), but at 991px it suddenly became a flat 36px that
     did NOT scale with --tt-cta-scale — visually the CTA jumped
     downward 1.7px AND lost its proportional relationship with the
     transform-scaled button silhouette, manifesting as the "button
     detaches from screenshot at 991→990" report. The original comment
     "long bi-slant CTA wraps badly on tablet" is obsolete: since
     2026-05-13 the CTA is scaled via `transform: scale()` (see
     tradeiz-custom.css) so its label can never wrap regardless of
     viewport — the silhouette shrinks together with the label. */

  /* Agg page padding under mobile header (~54px). */
  .tt-agg { padding: 90px 0 60px; }

  /* Sentiment quad → 2 cols. */
  .tt-home .tt-sent-quad { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Trades / movers / sentiment KPI strips → 2 cols when wider than card
     content allows, fall back to single column on tablets. */
  .tt-home .tt-trades-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

  /* Spotlight layout already collapses at 991 in tradeiz-home.css. Only
     fix the absolute-positioned liqbar that overlaps the chart on shorter
     spotlight heights — pin it relative instead. */
  .tt-home .tt-spotlight__liqbar {
    position: static;
    margin: 8px 16px 12px;
  }
  .tt-home .tt-spotlight__chart {
    height: calc(100% - 56px);
  }

  /* CTA banner: text + buttons should stack on tablet to avoid the
     buttons being squeezed past the right edge. */
  .tt-home .tt-cta {
    flex-direction: column;
    align-items: flex-start;
    padding: 22px 24px;
    gap: 16px;
  }
  .tt-home .tt-cta__actions { width: 100%; }
  .tt-home .tt-cta__actions .tz-btn { flex: 1; justify-content: center; }

  /* Liquidations page splits (left 7 / right 3, plus 1+1 bottom row) →
     stack at tablet width. The aggregations CSS only does this at ≤720,
     causing overlap and squished tables in the 720-991 window. */
  .tt-agg .tt-liqsplit,
  .tt-agg .tt-liqsplit--merged {
    grid-template-columns: 1fr;
    gap: 16px;
  }

  /* History grid (chart + top10) and other multi-col agg grids. Listed
     selectors are all confirmed `display: grid` containers in
     tradeiz-aggregations.css; non-grid elements are not included. */
  .tt-agg .tt-liq-history__grid,
  .tt-agg .tt-fund-pred,
  .tt-agg .tt-fund-basis,
  .tt-agg .tt-fund-kpi__rates,
  .tt-agg .tt-cur-grid,
  .tt-agg .tt-sent-div,
  .tt-agg .tt-fund-flow,
  .tt-agg .tt-sent-heroV2__top,
  .tt-agg .tt-sent-btcalt,
  .tt-agg .tt-sent-radar__wrap {
    grid-template-columns: 1fr;
    gap: 16px;
  }

  /* Live-tape filter row (exchange / symbol / min-value chips) — make each
     field full width so the chip strip stays readable. */
  .tt-agg .tt-liqlive__filters {
    flex-wrap: wrap;
    gap: 12px;
  }
  .tt-agg .tt-liqlive__field {
    flex: 1 1 100%;
    min-width: 0;
  }

  /* Live tape top bar (title + status + filters) — stack title above
     filters on tablet so filters don't squeeze the title. */
  .tt-agg .tt-liqlive__topbar {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  /* /liquidations Cascade row was a 6-col grid; aggregations.css collapses
     to 3 cols at 720, but 991-720 stays too tight. Pre-collapse to 3 cols
     a breakpoint earlier. */
  .tt-agg .tt-liq-cascade__row {
    grid-template-columns: 28px 1fr 1fr;
    row-gap: 4px;
  }

  /* Movers / Sentiment full-table toolbars already wrap; ensure each input
     group breaks onto its own row on tablet. */
  .tt-agg .tt-agg__toolbar { gap: 10px; }
  .tt-agg .tt-agg__toolbar-group { flex: 1 1 100%; }

  /* Window pill bars: 5+ buttons can overflow at narrow widths — allow
     horizontal scroll instead of wrapping (1 row = visually tight). */
  .tt-agg .tt-mov-windowbar,
  .tt-agg .tt-liqpage__windowbar,
  .tt-agg .tt-liq-history__windowbar {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
    white-space: nowrap;
  }

  /* Agg page head: title + meta on separate rows on tablet so the meta
     pill doesn't push the title to a second line. */
  .tt-agg .tt-agg__head,
  .tt-agg .tt-liqpage__head {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .tt-agg .tt-liqsection__head .tt-liq-heatmap__windowbar {
    align-self: flex-start;
    margin-left: 0;
  }
}

/* ────────────────────────────────────────────────────────────────────
   4) ≤ 767.98px (phone landscape, large phone portrait)
   ──────────────────────────────────────────────────────────────────── */
@media (max-width: 767.98px) {
  /* Tighten vertical spacing on home sections to fit phone screens. */
  .tt-home .tt-section { padding: 36px 0; }
  .tt-home .tt-ti-landing__main { padding-top: 24px; padding-bottom: 8px; }
  .tt-home #tt-home-tagline.tt-ti-landing__tagline {
    line-height: 1.14;
    margin: 4px auto 24px;
  }

  /* Sentiment quad → 1 col on phone (5 cards stacked is acceptable; trying
     2 cols leaves an orphan tile). */
  .tt-home .tt-sent-quad { grid-template-columns: 1fr; }

  /* Spotlight live cards row → vertical stack (renderer puts 3 cards in a
     3-col grid at 991). */
  .tt-home .tt-spotlight-live { grid-template-columns: 1fr; }
  .tt-home .tt-spotlight-layout .tt-spotlight { height: 280px; }

  /* [FIX] 2026-05-13 — keep Home Trades KPI as 2×2 on phones, not 4×1.
     Reason: user feedback "再手机上...4 行打字很难看" — short labels
     (24h Volume / Whale Trades 24h) and compact values ($106.59B / 44,672)
     fit comfortably in a 2-col grid down to 320px. 4×1 stack wasted
     vertical space and broke the visual rhythm of the section.
     Warning: do NOT change back to 1fr — 4 stacked rows is the bug. */
  .tt-home .tt-trades-kpi {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  /* Smaller value font on phones so 2-col cells don't crowd at 320px.
     16px is in the whitelist (12/14/16/18/22/28). */
  .tt-home .tt-trades-kpi .tt-trades-kpi__val { font-size: 16px; }
  .tt-home .tt-trades-kpi .tt-trades-kpi__card { padding: 10px 12px; }

  /* Agg container padding shrinks (top must not exceed the 768px band). */
  .tt-agg { padding: 80px 0 48px; }
  .tt-agg .container { padding-left: 16px; padding-right: 16px; }

  /* Liq heat / movers treemap: aspect ratio kept square-ish so the smallest
     phones still see at least a 240px tall heatmap. */
  .tt-agg .tt-liqheat,
  .tt-home .tt-liqheat {
    aspect-ratio: 1.5 / 1;
    min-height: 220px;
  }

  /* All multi-col card grids in agg pages → 1 col. Selectors are 2-class
     deep (.tt-agg .X) so they beat the 1-class authoring style used in
     tradeiz-aggregations.css without needing !important. */
  .tt-agg .tt-mov-kpi,
  .tt-agg .tt-liq-overview__grid,
  .tt-agg .tt-cur-kpi,
  .tt-agg .tt-fund-pred,
  .tt-agg .tt-fund-basis,
  .tt-agg .tt-td-depth__row {
    grid-template-columns: 1fr;
  }

  /* Home · Market Pulse tiles (.tt-pulse--side .tt-pulse__tile)
     ----------------------------------------------------------------
     Bug: at ≤767 home.css already collapses the OUTER pulse grid to
     2 cols (line 1335 of tradeiz-home.css), but each INNER tile still
     uses `grid-template-columns: minmax(0,1fr) auto` (defined at line
     1035 of tradeiz-home.css), placing the 22px notional value LEFT
     and the uppercase letter-spaced label ("24H LIQUIDATIONS",
     ~150px wide) RIGHT in the same row. Each outer column on a 375px
     phone is only ~165px wide minus padding ≈ 137px content area —
     not enough for value + label horizontally → text overlaps.

     Fix: restack the tile content vertically on phone (value on top,
     label below, long/short bar still spans the full tile width). The
     uppercase / letter-spacing on the label is preserved because the
     web_app_styling rule only restricts color & font-size, not the
     text-transform / tracking. */
  .tt-home .tt-pulse--side .tt-pulse__tile {
    grid-template-columns: 1fr;
    row-gap: 4px;
    padding: 12px 14px;
  }
  .tt-home .tt-pulse--side .tt-pulse__value {
    grid-column: 1;
    grid-row: auto;
    justify-self: start;
  }
  .tt-home .tt-pulse--side .tt-pulse__label {
    grid-column: 1;
    grid-row: auto;
    justify-self: start;
    text-align: left;
  }
  .tt-home .tt-pulse--side .tt-pulse__bar-wrap {
    grid-column: 1;
    grid-row: auto;
    margin-top: 6px;
  }

  /* Note: .tt-vp-row (volume profile bars: label / sell / buy) and
     .tt-breakdown__row (label / value / share) intentionally keep their
     3-col structure on mobile — they are already tightened to compact
     widths at ≤768 in tradeiz-aggregations.css (lines 2592-2595). Do
     NOT collapse them to 2 cols here; the third column would be lost. */
}

/* ────────────────────────────────────────────────────────────────────
   5) ≤ 575.98px (phone portrait — strictest)
   ──────────────────────────────────────────────────────────────────── */
@media (max-width: 575.98px) {
  /* Page-level container padding — match Bootstrap default (12px). */
  .tt-home .container,
  .tt-agg .container {
    padding-left: 12px;
    padding-right: 12px;
  }

  /* Section spacing: title 18px already enforced by tradeiz-home.css media
     767. Re-tighten bottom margin so headers don't eat half the viewport. */
  .tt-home .tt-section__head { margin-bottom: 16px; }
  .tt-home .tt-section__foot { margin-top: 16px; }
  .tt-home .tt-section { padding: 28px 0; }
  .tt-agg { padding: 72px 0 40px; }

  /* CTA buttons: stack vertically on the narrowest phones. */
  .tt-home .tt-cta__actions {
    flex-direction: column;
  }
  .tt-home .tt-cta__actions .tz-btn { width: 100%; }

  /* Agg page title shrinks on phones. */
  .tt-agg .tt-agg__title,
  .tt-agg .tt-liqpage__title { font-size: 22px; }
  .tt-agg .tt-agg__subtitle,
  .tt-agg .tt-liqpage__sub { font-size: 12px; line-height: 1.4; }

  /* Coverage scrollable lists: cap height so they don't push the footer
     way down on phones with one long table. */
  .tt-agg .tt-liqlive__list { max-height: 60vh; }

  /* Chip / pill rows wrap on narrowest phones. */
  .tt-agg .tt-liqlive__chips { flex-wrap: wrap; }

  /* All remaining 2-col grids inside agg pages → 1 col. The selectors are
     intentionally narrow (.tt-agg ancestor required) so home page mini
     grids are not affected. All entries listed are confirmed `display:
     grid` containers in tradeiz-aggregations.css. */
  .tt-agg .tt-cur-grid,
  .tt-agg .tt-fund-flow,
  .tt-agg .tt-sent-div {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 399.98px) {
  .tt-home .container,
  .tt-agg .container {
    padding-inline: 14px;
    box-sizing: border-box;
  }
  .tt-home .tt-rail__grid {
    gap: 10px;
  }
  .tt-home .tt-liqheat {
    min-height: 140px;
  }
}

/* ────────────────────────────────────────────────────────────────────
   6) Touch-pointer specific (any width): kill hover-only reveals so
      tap on iOS / Android isn't sticky.
   ──────────────────────────────────────────────────────────────────── */
@media (hover: none) and (pointer: coarse) {
  .tt-home .tt-ti-landing__visual:hover .tt-ti-landing__shot-frame,
  .tt-home .tt-ti-landing__visual:hover .tt-ti-landing__shot-plate--rear {
    transform: none;
  }
}

/* =====================================================================
   [ADD v2] 2026-05-13 — RESPONSIVE SAFETY NET · DEEP PASS
   Whole-site sweep across every page (excl. /chart) on tablet (≤991) and
   phone (≤767, ≤575) to fix tab strips, pager, section heads, in-card
   chart heights and remaining horizontal-scroll surfaces that the first
   pass did not cover. Same authoring rules:
     - selector specificity ≥ 2 classes (.tt-agg .X or .tt-home .X)
     - no !important
     - no new color / new font-size (all values from whitelist)
   ===================================================================== */

/* ── ≤ 991.98px — tablet portrait ───────────────────────────────────── */
@media (max-width: 991.98px) {
  /* Tab strips: scroll horizontally on touch instead of wrapping. Wrapping
     tabs to 2 rows looks broken (the active underline visually disconnects
     from neighbouring rows). All three tab-strip variants on the site
     share the same fix. */
  .tt-agg .tt-agg__tabs,
  .tt-agg .tt-fund-tabs,
  .tt-agg .tt-fund-detail__tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* Hide scrollbar on tabs themselves for a cleaner look (global
       rule lower in the page already hides bars and reveals them on
       hover; tabs override to permanently hide for visual polish). */
    scrollbar-width: none;
  }
  .tt-agg .tt-agg__tabs::-webkit-scrollbar,
  .tt-agg .tt-fund-tabs::-webkit-scrollbar,
  .tt-agg .tt-fund-detail__tabs::-webkit-scrollbar { display: none; }

  /* Each tab keeps full vertical hit-target but slightly tighter side
     padding so 4-6 tabs are still close to fitting in one screen width
     before horizontal scroll kicks in. font-size stays 14px (whitelist). */
  .tt-agg .tt-agg__tab,
  .tt-agg .tt-fund-tab,
  .tt-agg .tt-fund-detail__tab,
  .tt-agg .tt-mov-windowbtn,
  .tt-agg .tt-liqpage__winbtn {
    flex-shrink: 0;
    white-space: nowrap;
    padding-left: 14px;
    padding-right: 14px;
  }

  /* Funding settlement countdown row: 4 cells × (ex 12px + time 18px tabular)
     ≈ 4 × ~120px + 28px gap × 3 = 564px → overflow on phones.
     Reduce gap to 12px (keeps semantic legibility) and let cells wrap. */
  .tt-agg .tt-fund-countdown__list {
    gap: 12px 16px;
    flex-wrap: wrap;
  }
  .tt-agg .tt-fund-countdown {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  /* fund-detail pane-head was `display: flex; space-between` putting the
     subtitle on the left and the in-pane controls (tabs/inputs) on the
     right; on tablets the subtitle wraps to 2 lines and the right block
     ends up overlapping. Stack vertically instead. */
  .tt-agg .tt-fund-detail__pane-head,
  .tt-agg .tt-fund-section__head {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  /* `.tt-fund-tabs { margin-left: auto }` becomes meaningless once parent
     is column; ensure it sits on its own row, allowing horizontal scroll. */
  .tt-agg .tt-fund-section__head .tt-fund-tabs,
  .tt-agg .tt-fund-detail__pane-head .tt-fund-tabs {
    margin-left: 0;
    align-self: flex-start;
    width: 100%;
  }

  /* DEX whales liquidation-waterfall head (bases tabs + meta) — stack. */
  .tt-agg .tt-dex-liqwf__head {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .tt-agg .tt-dex-liqwf__bases {
    flex-wrap: nowrap;
    overflow-x: auto;
  }

  /* Pager: pager-info (left, "1-50 of 1234") + pager-controls (right) →
     stack on tablet so the controls aren't pinned to a viewport edge with
     no breathing room. */
  .tt-agg .tt-agg__pager {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .tt-agg .tt-agg__pager-controls {
    flex-wrap: wrap;
    justify-content: flex-start;
  }

  /* In-card chart heights on /trades/:base (Volume Profile / CVD).
     Two cards stacking on tablet would otherwise push the page past
     1000px before any data is visible. */
  .tt-agg .tt-td-chart,
  .tt-agg .tt-td-vp-panel,
  .tt-agg .tt-td-scroll-panel {
    max-height: 280px;
  }
  .tt-agg .tt-td-chart {
    height: 280px;
  }
  .tt-agg .tt-trades-detail__prints {
    max-height: 360px;
  }

  /* Funding history / OI history chart — same idea, but no inline style
     so plain specificity is enough. */
  .tt-agg .tt-fund-hist__chart {
    min-height: 260px;
  }
}

/* ── ≤ 767.98px — phone landscape / large phone portrait ─────────────── */
@media (max-width: 767.98px) {
  /* Title icon (.tt-coin-icon inside h1) gets a touch smaller on phones so
     the heading stays one line at typical base symbols (BTC/ETH/SOL). */
  .tt-agg .tt-agg__title .tt-coin-icon,
  .tt-agg .tt-agg__title .tt-coin-icon img,
  .tt-agg .tt-agg__title .tt-coin-icon__fb {
    width: 22px;
    height: 22px;
  }

  /* Tighten tab padding further to fit more visible tabs on a phone
     viewport before the horizontal scroll cue appears. */
  .tt-agg .tt-agg__tab,
  .tt-agg .tt-fund-tab,
  .tt-agg .tt-fund-detail__tab {
    padding-left: 12px;
    padding-right: 12px;
  }

  /* Volume Profile / CVD card title row: "Volume Profile" + "Buy/Sell by
     price" badge — let the badge sit below the title on narrow phones so
     neither truncates. */
  .tt-home .tt-card__title,
  .tt-agg .tt-card__title {
    flex-wrap: wrap;
    row-gap: 4px;
  }

  /* The /trades/:base chart cards keep a usable height even at 360px. */
  .tt-agg .tt-td-chart,
  .tt-agg .tt-td-vp-panel,
  .tt-agg .tt-td-scroll-panel {
    max-height: 240px;
  }
  .tt-agg .tt-td-chart {
    height: 240px;
  }
  .tt-agg .tt-trades-detail__prints {
    max-height: 320px;
  }
  #tt-trades-detail .tt-vp-row {
    grid-template-columns: 72px minmax(0, 1fr) minmax(0, 1fr);
  }
  #tt-trades-detail .tt-breakdown__row {
    grid-template-columns: minmax(110px, 140px) minmax(0, 1fr) 80px;
  }

  /* Funding settlement countdown — already wrapping; tighten time fontsize
     stays 18px (whitelist) but cell gap halves. */
  .tt-agg .tt-fund-countdown__cell { gap: 6px; }
}

/* ── ≤ 575.98px — phone portrait ─────────────────────────────────────── */
@media (max-width: 575.98px) {
  /* Pager controls: shrink button padding so 5-7 page buttons + Prev/Next
     fit in one row before wrapping. */
  .tt-agg .tt-agg__pager-btn {
    padding: 4px 8px;
    font-size: 12px;
  }

  /* Tighten table cell padding further on the smallest phones — the
     aggregations.css ≤768 rule already drops to 10px 8px; this slimmer
     value (8px 6px) keeps a 4-column table readable at 360px. */
  .tt-agg .tt-agg__table thead th,
  .tt-agg .tt-agg__table tbody td {
    padding: 8px 6px;
    font-size: 12px;
  }
  .tt-agg .tt-agg__table thead th.tt-agg__th--left,
  .tt-agg .tt-agg__table tbody td.tt-agg__td--left {
    padding: 8px 6px;
  }

  /* Funding countdown stacked on phones: each ex/time pair on its own
     line for readability. */
  .tt-agg .tt-fund-countdown__list { gap: 8px 12px; }

  /* DEX whales liqwf bases tabs (BTC/ETH/SOL) keep one row even at 320px.
     Compact padding. */
  .tt-agg .tt-dex-liqwf__base {
    padding: 6px 10px;
    font-size: 12px;
  }
}

/* ============================================================================
 * [ADD] 2026-06-24 — Incremental 6-item front-end styles
 *   #3 RSI heatmap grid · #7 large-orders (reuses table primitives) ·
 *   #6 DEX venue share bars · #5 Net Position legend · #2 funding cumulative.
 * Text colour stays var(--tt-fg-0); RSI cell fills + up/down are the only
 * colour exceptions (data-visualisation + financial direction semantics).
 * Font sizes stay on the {12,14,16,18,20,22}px scale.
 * ========================================================================== */

/* ── #3 RSI multi-timeframe heatmap ─────────────────────────────────────── */
.tt-rsi-table tbody td.tt-rsi-cell {
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--tt-fg-0);
}
/* RSI cells receive an hsla() fill inline (data-visualisation scale). The
   --na cell carries no fill and reads as a muted neutral dash. */
.tt-rsi-table tbody td.tt-rsi-cell--na { opacity: .45; }

.tt-rsi-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .75;
}
.tt-rsi-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.tt-rsi-legend__sw {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  display: inline-block;
}
.tt-rsi-legend__sw--os      { background: hsla(170,70%,45%,.55); }
.tt-rsi-legend__sw--neutral { background: hsla(85,70%,45%,.18); }
.tt-rsi-legend__sw--ob      { background: hsla(0,70%,45%,.55); }

/* ── #6 DEX venue share bars ─────────────────────────────────────────────── */
.tt-dex-share { display: flex; flex-direction: column; gap: 10px; }
.tt-dex-share__row {
  display: grid;
  grid-template-columns: 160px 120px 1fr;
  align-items: center;
  gap: 12px;
}
.tt-dex-share__venue {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--tt-fg-0);
  font-weight: 600;
  min-width: 0;
}
.tt-dex-share__venue span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tt-dex-share__track {
  position: relative;
  width: 120px;
  height: 10px;
  border-radius: 4px;
  background: rgba(120,123,134,.12);
  overflow: hidden;
}
.tt-dex-share__fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 4px;
  background: rgba(41,98,255,.55); /* [EXCEPTION] product accent for share fill */
}
.tt-dex-share__stats {
  display: inline-flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 10px;
  margin-left: auto;
  min-width: 0;
}
.tt-dex-share__pct {
  font-size: 14px;
  color: var(--tt-fg-0);
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}
.tt-dex-share__sub {
  font-size: 12px;
  color: var(--tt-fg-0);
  opacity: .55;
  white-space: nowrap;
}
.tt-dex-share__caption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--tt-fg-0);
  margin-bottom: 4px;
}
/* [ADD] 2026-06-25 — #6 per-venue OI-share trend sparkline.
   The trend line is a full-width second row inside the existing share row
   grid, so the 3-col venue/track/pct layout is untouched when no trend. */
.tt-dex-share__trend-note { font-size: 12px; font-weight: 400; color: var(--tt-fg-0); opacity: .55; }
.tt-dex-share__trend {
  grid-column: 1 / -1;
  height: 28px;
  margin-top: 2px;
  color: rgba(41,98,255,.85); /* [EXCEPTION] product accent for data-viz trend line */
}
.tt-dex-share__spark-svg { width: 100%; height: 100%; display: block; }

/* ── #5 Net Position legend (sentiment positioning extra dimension) ──────── */
.tt-sent-net__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--tt-fg-0);
}
.tt-sent-net__leg { display: inline-flex; align-items: center; gap: 6px; }
.tt-sent-net__leg i { width: 18px; height: 3px; border-radius: 2px; display: inline-block; }
.tt-sent-net__leg--acc i { background: #999999; } /* [EXCEPTION] retail series stroke */
.tt-sent-net__leg--oi  i { background: #2962ff; } /* [EXCEPTION] top-trader series stroke */
.tt-sent-net__chart { width: 100%; }
.tt-sent-net__last {
  margin-left: auto;
  opacity: .9;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 12px;
  font-variant-numeric: tabular-nums;
}
.tt-sent-net__sum em { font-style: normal; opacity: .6; margin-right: 4px; }
.tt-sent-net__empty {
  font-size: 14px;
  color: var(--tt-fg-0);
  opacity: .6;
  padding: 24px 0;
  text-align: center;
}

/* ── #2 Funding cumulative / APR ranking lists ──────────────────────────── */
.tt-fund-cum__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.tt-fund-cum__cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.tt-fund-cum__col-head {
  font-size: 14px;
  font-weight: 700;
  color: var(--tt-fg-0);
  margin-bottom: 8px;
}
@media (max-width: 768px) {
  .tt-dex-share__row { grid-template-columns: 110px 96px 1fr; gap: 8px; }
  .tt-fund-cum__cols { grid-template-columns: 1fr; gap: 16px; }
}

/* ── Shared aggregation heatmap tooltip + scaled cell labels ─────────── */
.tt-heat-tip {
  position: fixed;
  z-index: 10050;
  pointer-events: none;
  min-width: 180px;
  max-width: 300px;
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--popover-bg, #1e222d);
  border: 1px solid var(--popover-border, rgba(120, 123, 134, .35));
  box-shadow: var(--popover-shadow, 0 8px 24px rgba(0, 0, 0, .35));
  opacity: 0;
  visibility: hidden;
  transition: opacity .12s ease;
  font-size: 14px;
  line-height: 1.4;
  color: var(--tt-fg-0);
}
.tt-heat-tip.is-visible {
  opacity: 1;
  visibility: visible;
}
.tt-heat-tip__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 16px;
  font-weight: 700;
  color: var(--tt-fg-0);
}
.tt-heat-tip__head .tt-coin-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}
.tt-heat-tip__head .tt-coin-icon img,
.tt-heat-tip__head .tt-coin-icon__fb {
  width: 100%;
  height: 100%;
}
.tt-heat-tip__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 14px;
  margin-top: 4px;
}
.tt-heat-tip__label {
  color: var(--tt-fg-0);
  opacity: .75;
}
.tt-heat-tip__val {
  font-weight: 600;
  color: var(--tt-fg-0);
  text-align: right;
}
.tt-heat-tip__val--up { color: var(--tt-up); }
.tt-heat-tip__val--down { color: var(--tt-down); }
.tt-heat-cell__symline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  max-width: 100%;
  line-height: 1.1;
}
.tt-heat-cell__symline .tt-coin-icon {
  width: 1.05em;
  height: 1.05em;
  flex-shrink: 0;
}
.tt-heat-cell__symline .tt-coin-icon img,
.tt-heat-cell__symline .tt-coin-icon__fb {
  width: 100%;
  height: 100%;
  font-size: 12px;
}
.tt-liqheat__sym .tt-heat-cell__symline,
.tt-mov-treemap__base .tt-heat-cell__symline,
.tt-fund-treemap__base .tt-heat-cell__symline {
  max-width: 100%;
}
.tt-mov-treemap__cell,
.tt-fund-treemap__cell,
.tt-liqheat__cell,
.tt-liqheat__sym,
.tt-liqheat__val,
.tt-mov-treemap__base,
.tt-mov-treemap__pct,
.tt-mov-treemap__val,
.tt-fund-treemap__base,
.tt-fund-treemap__val,
.tt-fund-treemap__skew,
.tt-sent-fheat__cell {
  font-family: inherit;
  color: var(--tt-fg-0);
}
.tt-heat-cell__symline--compact,
.tt-heat-cell__symline > span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  max-width: 100%;
}

