  /* Reserve the scrollbar gutter so the centered shell never shifts sideways. */
  html { scrollbar-gutter: stable; }
  body { background: var(--grad-page); background-attachment: fixed; min-height: 100vh; margin: 0; color: var(--text-hi); display: flex; flex-direction: column; }
  /* width:100% is required: body is a flex column, so margin:0 auto otherwise
     shrink-wraps .shell to its content and max-width never engages. box-sizing
     so width:100% + padding doesn't overflow the viewport (was clipping content
     on mobile). */
  .shell { box-sizing: border-box; width: 100%; max-width: 1513px; margin: 0 auto; padding: 16px; }

  /* Period selector */
  .period-bar {
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
    padding: 6px; display: flex; gap: 4px; margin-bottom: 12px; align-items: center;
  }
  .period-bar .label {
    font-size: 9px; font-weight: 700; color: var(--text-md);
    letter-spacing: 0.6px; padding: 0 12px;
  }
  .period-bar button {
    background: transparent; border: 1px solid transparent; border-radius: 4px;
    color: var(--text-md); font-size: 11px; padding: 5px 12px; cursor: pointer;
    font-family: var(--mono);
  }
  .period-bar button.active {
    background: rgba(26, 127, 255, 0.15); border-color: #1a7fff; color: var(--accent-2);
    font-weight: 700;
  }
  /* .toggle-btn styles moved to stables-filter.js (.stables-toggle). */
  .period-bar .info { margin-left: auto; color: var(--text-md); font-size: 10px; font-family: var(--mono); display: flex; gap: 12px; align-items: center; }
  .period-bar .info .stat { display: inline-flex; gap: 5px; align-items: baseline; }
  .period-bar .info .stat .k { color: var(--text-lo); font-size: 9px; text-transform: uppercase; letter-spacing: 0.5px; }
  .period-bar .info .stat .v { color: var(--text-hi); font-weight: 700; }
  .period-bar .info .sep { color: var(--border); }

  /* The top filter section is GONE (owner 2026-07-06). The global period lives
     as a compact dropdown INSIDE the tabs row; CEX scope is drill-only. */
  #an-tabs .an-period { flex: 0 0 auto; margin-left: 4px; align-self: center; }
  /* Back from a drilled per-CEX view to the dashboards. */
  .cex-back {
    display: inline-flex; align-items: center; gap: 6px; margin: 2px 0 10px;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
    color: var(--text-md); font: 600 12px var(--font); padding: 7px 12px; cursor: pointer;
  }
  .cex-back:hover { color: var(--text-hi); border-color: var(--border2); }
  .cex-back .mat-ic { font-size: 15px; }

  /* Per-CEX accumulation / distribution table */
  .accum-tbl { width: 100%; border-collapse: collapse; font-size: 11px; }
  .accum-tbl th { text-align: left; color: var(--text-lo); font-weight: 700; font-size: 9px; text-transform: uppercase; letter-spacing: .5px; padding: 6px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; }
  .accum-tbl th.sortable { cursor: pointer; user-select: none; }
  .accum-tbl th.sortable:hover { color: var(--text-hi); }
  /* Rank-velocity markers */
  .accum-fire { font-size: 11px; line-height: 1; animation: accum-fire-blink 1s ease-in-out infinite; }
  @keyframes accum-fire-blink { 0%,100% { opacity: 1; } 50% { opacity: .2; } }
  .accum-move { font-size: 9px; font-weight: 700; padding: 0 4px; border-radius: 3px; font-family: var(--mono); line-height: 1.5; }
  .accum-move.up   { color: var(--flow-in);  background: var(--flow-in-bg); }
  .accum-move.down { color: var(--flow-out); background: var(--flow-out-bg); }
  /* Period dropdown - violet accent to match the segmented filters. */
  .accum-period {
    -webkit-appearance: none; appearance: none;
    background-color: var(--accent-dim);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none' stroke='%23a78bff' stroke-width='1.5'><path d='M1 1l4 4 4-4'/></svg>");
    background-repeat: no-repeat; background-position: right 9px center;
    border: 1px solid var(--accent-border);
    color: var(--accent-2);
    border-radius: 5px;
    padding: 5px 26px 5px 10px;
    font-family: var(--mono); font-size: 11px; font-weight: 700;
    cursor: pointer; outline: none;
  }
  .accum-period:hover, .accum-period:focus { border-color: var(--accent); }
  .accum-period option { background: var(--bg-card); color: var(--text-hi); font-weight: 400; }
  .accum-tbl td { padding: 7px 10px; border-bottom: 1px solid var(--border); font-family: var(--mono); color: var(--text-hi); white-space: nowrap; }
  .accum-tbl tr:hover td { background: var(--bg-hover); }
  .accum-tbl .num { text-align: right; }
  .accum-tbl .dir { font-size: 8px; font-weight: 700; padding: 1px 7px; border-radius: 100px; letter-spacing: .4px; }
  /* Flow direction: inflow (into CEX) = green, outflow (out of CEX) = red. */
  .accum-tbl .dir.acc { background: var(--flow-in-bg);  color: var(--flow-in);  border: 1px solid var(--flow-in-border); }
  .accum-tbl .dir.dis { background: var(--flow-out-bg); color: var(--flow-out); border: 1px solid var(--flow-out-border); }
  .accum-pager { display:flex; justify-content:space-between; align-items:center; padding:10px 4px 2px; font-size:11px; color:var(--text-md); font-family:var(--mono); }
  .accum-pager button { background:transparent; border:1px solid var(--border); border-radius:5px; color:var(--text-md); font-size:11px; padding:4px 10px; cursor:pointer; font-family:inherit; }
  .accum-pager button:hover:not(:disabled) { border-color:var(--accent-border); color:var(--text-hi); }
  .accum-pager button:disabled { opacity:.4; cursor:default; }

  /* Grid */
  .grid {
    display: grid; gap: 12px;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
  }
  @media (min-width: 1200px) {
    .grid { grid-template-columns: 1fr 1fr 1fr; }
    .span-2 { grid-column: span 2; }
  }

  /* Two-column dashboard: compact main stack (Net Flow / CEX Activity /
     Heatmap) on the left, Big Movers on the right matching the main
     column's intrinsic height (no fixed max-height, no empty gap below
     Heatmap). Below 1100px collapses to single column.
     Flex (not grid) so the side column stretches to sibling height - that
     was the source of the "huge gap before Assets" the user spotted. */
  .dash-2col {
    display: flex; flex-direction: column; gap: 12px;
    align-items: stretch;
  }
  .dash-main {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; gap: 12px;
  }
  /* Base (stacked, mobile): full-width column. */
  .dash-side {
    display: flex; flex-direction: column;
  }
  @media (min-width: 1100px) {
    .dash-2col { flex-direction: row; align-items: flex-start; }
    /* Wider, fixed right rail - like the scanner Events panel - so the
       Big-Movers cards (asset/amount/USD + from->to + chip) fit without
       cramping. Sticky so it stays in view while the main column scrolls. */
    .dash-side {
      flex: 0 0 400px; width: 400px; min-width: 380px;
      position: sticky; top: 12px; align-self: flex-start;
      max-height: calc(100vh - 24px);
    }
  }
  .dash-side .movers-card {
    flex: 1;
    display: flex; flex-direction: column;
    min-height: 0;     /* required for the inner scroll to actually clip */
  }
  .dash-side .movers-scroll {
    flex: 1; overflow-y: auto; min-height: 0;
  }
  .dash-side .movers-scroll::-webkit-scrollbar { width: 6px; }
  .dash-side .movers-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
  /* Match the canonical .ark-card used on scanner/chart: gradient surface,
     soft shadow + top hairline, token radius. */
  .card {
    background: var(--bg-card); background-image: var(--grad-card);
    border: 1px solid var(--border); border-radius: var(--r-lg);
    padding: 14px; overflow: hidden;
    box-shadow: var(--shadow-1), inset 0 1px 0 var(--hairline);
  }
  /* Match .ark-card-title: small uppercase mono-ish label, low-contrast. */
  .card-title {
    font-size: 10px; font-weight: 700; color: var(--text-lo);
    margin-bottom: 12px; display: flex; align-items: center; justify-content: space-between;
    letter-spacing: 0.8px; text-transform: uppercase;
  }
  .card-title .hint { color: var(--text-md); font-size: 10px; font-weight: 400; font-family: var(--mono); }

  /* Net flow bars */
  .nf-row {
    display: flex; align-items: center; gap: 10px; padding: 8px 0;
    border-bottom: 1px solid var(--bg-input); font-family: var(--mono); font-size: 11px;
  }
  .nf-row:last-child { border-bottom: 0; }
  .nf-name { min-width: 90px; color: var(--text-hi); font-weight: 700; }
  .nf-bars { flex: 1; display: flex; height: 20px; position: relative; }
  .nf-bar  {
    height: 100%; transition: width .3s; min-width: 1px;
    /* Render USD value inline so user doesn't need to hover for the number. */
    display: flex; align-items: center; justify-content: center;
    font-size: 9px; font-weight: 700; color: #ffffff;
    text-shadow: 0 0 3px rgba(0,0,0,.55);
    overflow: hidden; white-space: nowrap;
  }
  .nf-bar.in  { background: var(--flow-in);   border-radius: 2px 0 0 2px; }
  .nf-bar.out { background: var(--flow-out);  border-radius: 0 2px 2px 0; }
  .nf-net    { min-width: 80px; text-align: right; font-weight: 700; }
  .nf-net.pos { color: var(--flow-in); }
  .nf-net.neg { color: var(--flow-out); }

  /* CEX summary */
  .cex-summary {
    display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  }
  .cex-side {
    background: var(--bg-card2); border: 1px solid var(--border); border-radius: 6px;
    padding: 12px; text-align: center;
  }
  .cex-side.deposit  { border-color: color-mix(in srgb, var(--flow-in) 30%, transparent); }
  .cex-side.withdraw { border-color: color-mix(in srgb, var(--flow-out) 30%, transparent); }
  .cex-side .label { font-size: 10px; color: var(--text-md); text-transform: uppercase; letter-spacing: 0.6px; font-family: var(--mono); }
  .cex-side .value { font-size: 18px; font-weight: 700; margin: 4px 0 2px; font-family: var(--mono); }
  .cex-side.deposit  .value { color: var(--flow-in); }
  .cex-side.withdraw .value { color: var(--flow-out); }
  .cex-side .count { font-size: 10px; color: var(--text-md); font-family: var(--mono); }
  .cex-bias {
    text-align: center; margin-top: 12px;
    padding: 8px; background: var(--bg-card2); border-radius: 6px;
    font-family: var(--mono); font-size: 11px;
  }
  .cex-bias.accumulating { color: var(--flow-out); background: var(--flow-out-bg); }
  .cex-bias.distributing { color: var(--flow-in);  background: var(--flow-in-bg); }
  .cex-bias.neutral      { color: var(--text-md); }

  /* Top assets */
  .asset-table {
    width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 11px;
  }
  .asset-table th {
    text-align: left; color: var(--text-md); padding: 6px 8px; font-size: 9px;
    font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase;
    border-bottom: 1px solid var(--border);
  }
  .asset-table th.right { text-align: right; }
  .asset-table td {
    padding: 7px 8px; border-bottom: 1px solid var(--bg-input); color: var(--text-hi);
  }
  .asset-table td.right { text-align: right; }
  .asset-table tr:last-child td { border-bottom: 0; }
  .asset-table .net.pos { color: var(--flow-out); }
  .asset-table .net.neg { color: var(--flow-in); }

  /* Entity selector for top assets */
  .entity-tabs { display: flex; gap: 4px; margin-bottom: 10px; overflow-x: auto; }
  #assets { max-height: 340px; overflow-y: auto; }
  #assets::-webkit-scrollbar { width: 6px; }
  #assets::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
  .entity-tabs button {
    background: transparent; border: 1px solid var(--border); border-radius: 3px;
    color: var(--text-md); font-size: 10px; padding: 3px 8px; cursor: pointer;
    font-family: var(--mono); white-space: nowrap;
  }
  .entity-tabs button.active { border-color: var(--accent-2); color: var(--accent-2); }
  /* Top-N seg toggle next to entity tabs */
  .asset-topn-toggle button {
    background: transparent; border: 0; border-radius: 0;
    color: var(--text-md); font-size: 10px; padding: 3px 10px; cursor: pointer;
    font-family: var(--mono); white-space: nowrap;
  }
  .asset-topn-toggle button + button { border-left: 1px solid var(--border); }
  .asset-topn-toggle button:hover { color: var(--text-hi); }
  .asset-topn-toggle button.active { background: var(--accent-dim); color: var(--accent-2); }

  /* Big movers now render as scanner-style .ark-anomaly flow-cards (styles live
     in assets/style.css). The old .mover-* table-row styles were removed. */

  /* Heatmap */
  .heatmap-wrap { overflow-x: auto; }
  .heatmap {
    display: grid; gap: 2px; font-family: var(--mono); font-size: 9px;
    margin-top: 8px;
  }
  .heatmap .hour-labels {
    display: grid; grid-template-columns: 80px repeat(var(--cols, 24), 1fr); gap: 2px; color: var(--text-md);
  }
  .heatmap .hour-labels span { text-align: center; font-size: 8px; padding: 2px 0; line-height: 1.25; }
  .heatmap .entity-row {
    display: grid; grid-template-columns: 80px repeat(var(--cols, 24), 1fr); gap: 2px;
    align-items: center;
  }
  /* 6h/24h bucket toggle */
  .heat-bkt { background:var(--bg-card2);border:1px solid var(--border);color:var(--text-md);border-radius:4px;padding:3px 11px;font-size:10px;cursor:pointer;font-family:var(--mono) }
  .heat-bkt.active { background:var(--accent-dim);border-color:var(--accent-2);color:var(--accent-2) }
  .heatmap .entity-row .name { font-size: 10px; color: var(--text-hi); font-weight: 700; }
  .heatmap .cell {
    aspect-ratio: 1; border-radius: 3px;
    background: rgba(120, 140, 170, .04);
    display: flex; align-items: center; justify-content: center;
    font-size: 8px; font-weight: 700; color: rgba(255,255,255,.78);
    position: relative; cursor: help;
    /* Hold a readable minimum even when the grid gets cramped on short
       periods (15m / 1h) - without this the aspect-ratio:1 cells
       collapse to a few pixels each and the row visually breaks. */
    min-width: 18px; min-height: 18px;
    transition: box-shadow .12s, filter .12s;
  }
  .heatmap .cell.empty { font-weight: 400; }
  /* Row hover: dim the rest, brighten the active row so the eye locks
     onto one CEX's full 24h profile at a time. */
  .heatmap .entity-row:hover .cell { opacity: .55; }
  .heatmap .entity-row:hover .cell:hover,
  .heatmap .entity-row:hover { opacity: 1; }
  .heatmap .entity-row:hover .name { color: #fff; }
  /* Hover effect: only box-shadow + brighten - no transform/scale, since
     scale made the cell escape `overflow-x:auto` of .heatmap-wrap and
     forced a scrollbar to appear on every mouseover. */
  .heatmap .cell:hover {
    box-shadow: 0 0 0 1px rgba(77,168,255,.8), inset 0 0 0 1px rgba(255,255,255,.15);
    filter: brightness(1.4);
    z-index: 2;
  }
  /* Top-5 hottest (entity, hour) cells get a flame badge with a soft
     amber glow - instantly distinguishes the most active slots from
     plain dark-blue gradient. */
  .heatmap .cell.top {
    box-shadow: inset 0 0 0 1px rgba(255,140,0,.55), 0 0 6px rgba(255,140,0,.25);
  }
  .heatmap .cell .hot-flame {
    position: absolute;
    top: -3px; right: -3px;
    font-size: 12px;
    color: #ff9000;
    text-shadow: 0 0 4px rgba(255,140,0,.7);
    pointer-events: none;
    /* Pulse via text-shadow only - no transform/scale so the flame can't
       enlarge into the wrap's scrollbar trigger zone. */
    animation: hot-pulse 2.2s ease-in-out infinite;
  }
  @keyframes hot-pulse {
    0%, 100% { opacity: .85; text-shadow: 0 0 3px rgba(255,140,0,.55); }
    50%      { opacity: 1;   text-shadow: 0 0 8px rgba(255,140,0,.95); }
  }

  /* Loading */
  .loading {
    text-align: center; color: var(--text-md); font-family: var(--mono);
    font-size: 11px; padding: 30px;
  }
  .empty { color: var(--text-lo); text-align: center; padding: 20px; font-size: 11px; font-family: var(--mono); }

  /* Section heading separates CEX / MM / Interactions blocks. */
  .section-title {
    font-size: 13px; font-weight: 700; color: var(--text-hi);
    letter-spacing: .4px; text-transform: uppercase;
    margin: 20px 0 10px; padding-bottom: 6px;
    display: flex; align-items: center; gap: 8px;
    border-bottom: 1px solid var(--border);
  }
  .section-title .mat-ic { font-size: 16px; }
  .section-title .hint {
    margin-left: auto; font-size: 10px; font-weight: 400; color: var(--text-lo);
    text-transform: none; letter-spacing: 0; font-family: var(--mono);
  }

  /* Activity-spike alert banner. Pulses when MM↔CEX tx in the last
     `windowMin` exceed the prior `baselineMin` average by ratio threshold. */
  .spike-banner {
    background: linear-gradient(90deg, color-mix(in srgb, var(--red) 18%, transparent), color-mix(in srgb, var(--red) 5%, transparent));
    border: 1px solid color-mix(in srgb, var(--red) 45%, transparent); border-radius: 8px;
    padding: 10px 14px; margin-bottom: 12px;
    display: none; align-items: center; gap: 12px;
  }
  .spike-banner.visible { display: flex; animation: spike-pulse 1.6s ease-in-out infinite; }
  .spike-banner .mat-ic { color: var(--red); font-size: 22px; flex-shrink: 0; }
  .spike-banner .text { flex: 1; min-width: 0; }
  .spike-banner .title-text { font-weight: 700; color: var(--red); font-size: 13px; }
  .spike-banner .detail-text { font-size: 10px; color: var(--text-hi); font-family: var(--mono); margin-top: 2px; }
  .spike-banner .ratio-pill {
    font-family: var(--mono); font-weight: 700; font-size: 16px;
    color: var(--red); padding: 4px 10px; border-radius: 4px;
    background: color-mix(in srgb, var(--red) 15%, transparent); border: 1px solid color-mix(in srgb, var(--red) 40%, transparent);
  }
  @keyframes spike-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--red) 35%, transparent); }
    50%      { box-shadow: 0 0 0 10px color-mix(in srgb, var(--red) 0%, transparent); }
  }

  /* MM net-flow row - same skeleton as .nf-row but with CEX-family
     breakdown chips on the right side instead of a totals number. */
  .mm-row {
    display: flex; align-items: center; gap: 10px; padding: 10px 0;
    border-bottom: 1px solid var(--bg-input);
    font-family: var(--mono); font-size: 11px;
  }
  .mm-row:last-child { border-bottom: 0; }
  .mm-row .mm-name { min-width: 100px; font-weight: 700; }
  .mm-row .mm-bars { flex: 1; display: flex; height: 18px; }
  .mm-row .mm-bar.dep { background: var(--flow-out); border-radius: 2px 0 0 2px; min-width: 1px; }
  .mm-row .mm-bar.wd  { background: var(--flow-in);  border-radius: 0 2px 2px 0; min-width: 1px; }
  .mm-row .mm-net { min-width: 90px; text-align: right; font-weight: 700; }
  .mm-row .mm-net.pos { color: var(--flow-out); }
  .mm-row .mm-net.neg { color: var(--flow-in); }
  .mm-row .mm-bias {
    font-size: 9px; font-weight: 700; padding: 2px 6px; border-radius: 8px;
    text-transform: uppercase; letter-spacing: .5px;
  }
  .mm-row .mm-bias.loading   { color: var(--flow-in); background: color-mix(in srgb, var(--flow-in) 12%, transparent); border: 1px solid color-mix(in srgb, var(--flow-in) 35%, transparent); }
  .mm-row .mm-bias.unloading { color: var(--flow-out); background: color-mix(in srgb, var(--flow-out) 12%, transparent); border: 1px solid color-mix(in srgb, var(--flow-out) 35%, transparent); }
  .mm-row .mm-bias.neutral   { color: var(--text-md); background: rgba(143,168,200,.08); border: 1px solid var(--border); }

  /* CEX × MM interaction matrix - heat-mapped grid cells. */
  .matrix-wrap { overflow-x: auto; }
  .matrix {
    display: grid; gap: 1px; background: var(--border); border-radius: 4px;
    overflow: hidden; min-width: max-content;
  }
  .matrix .cell {
    background: var(--bg-card2); padding: 8px 10px;
    font-family: var(--mono); font-size: 11px;
    color: var(--text-hi); text-align: center;
    min-width: 90px;
  }
  .matrix .cell.header {
    font-weight: 700; color: var(--text-md); background: var(--bg-card);
    text-transform: uppercase; font-size: 9px; letter-spacing: .5px;
  }
  .matrix .cell.row-header { text-align: left; }
  .matrix .cell.empty { color: var(--text-lo); }
  .matrix .cell .vol { font-weight: 700; }
  .matrix .cell .sub { font-size: 9px; color: var(--text-md); margin-top: 2px; }

  /* Mobile: dense tables scroll horizontally instead of crushing/overflowing. */
  @media (max-width: 860px) {
    #accum-table { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .accum-tbl { min-width: 560px; }
    .asset-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }
  }

/* ══════════════════════════════════════════════════════════════
   FLOW PULSE - the "All exchanges" dashboard (#dash-view).
   Hero net-flow + sentiment, exchange leaderboard, asset net-flow,
   whale tape, activity heatmap. Wired in js/pages/analytics.js.
   ══════════════════════════════════════════════════════════════ */
.fp-hero { position:relative; overflow:hidden; border:1px solid var(--border2); border-radius:18px;
  background: radial-gradient(120% 140% at 12% 0%, rgba(231,76,92,.14), transparent 42%),
              radial-gradient(120% 140% at 88% 100%, rgba(16,185,129,.13), transparent 45%),
              var(--bg-card);
  padding:26px 28px; margin-bottom:20px; }
.fp-hero-grid { display:grid; grid-template-columns:1.05fr 1fr; gap:30px; align-items:center; min-height:200px; }
.fp-hero-k { font:600 11px var(--mono); letter-spacing:1.4px; text-transform:uppercase; color:var(--text-lo); }
.fp-hero-num { font-size:58px; font-weight:800; letter-spacing:-2px; line-height:1.02; margin:8px 0 8px; color:var(--text-hi); }
.fp-hero-sub { font-size:14px; color:var(--text-md); line-height:1.5; max-width:440px; }
.fp-hero-sub b { color:var(--text-hi); }
.fp-sentiment { display:inline-flex; align-items:center; gap:9px; margin-top:16px; padding:9px 15px; border-radius:100px; font:700 13px var(--font); }
/* Verdict pills are ACCENT-neutral (2026-07-05 design audit): a green
   ACCUMULATION pill under a red outflow number contradicted the page's
   green=inflow / red=outflow colour model. Direction owns green/red. */
.fp-sentiment.acc { background:var(--accent-dim, rgba(155,114,255,.13)); color:var(--accent-2,#c3aeff); border:1px solid var(--accent-border, rgba(155,114,255,.32)); }
.fp-sentiment.dis { background:var(--accent-dim, rgba(155,114,255,.13)); color:var(--accent-2,#c3aeff); border:1px solid var(--accent-border, rgba(155,114,255,.32)); }
.fp-sentiment.neu { background:var(--bg-card2); color:var(--text-md); border:1px solid var(--border2); }
.fp-ex-locked-more { padding: 12px 14px; }
.fp-ex-locked-more .fp-ex-head { margin: 0; align-items: center; gap: 9px; }
.fp-ex-locked-more .fp-ex-name { font-size: 13px; color: var(--text-md); }
.fp-pulse { width:8px; height:8px; border-radius:50%; background:currentColor; box-shadow:0 0 0 4px color-mix(in srgb, currentColor 22%, transparent); animation:fp-sp 1.6s infinite; }
@keyframes fp-sp { 50%{ opacity:.4 } }
.fp-tug-k { display:flex; justify-content:space-between; font:600 11px var(--mono); letter-spacing:.6px; text-transform:uppercase; color:var(--text-lo); margin-bottom:9px; }
.fp-tug { height:48px; border-radius:12px; overflow:hidden; display:flex; box-shadow:inset 0 0 0 1px var(--border); }
.fp-tug-in { background:linear-gradient(180deg, var(--flow-in,#16d398), color-mix(in srgb, var(--flow-in,#10b981) 85%, #000)); display:flex; align-items:center; padding:0 14px; color:#fff; text-shadow:0 1px 2px rgba(0,0,0,.28); font-weight:700; font-size:14px; white-space:nowrap; }
.fp-tug-out { background:linear-gradient(180deg, var(--flow-out,#ef5d6b), color-mix(in srgb, var(--flow-out,#e74c5c) 85%, #000)); display:flex; align-items:center; justify-content:flex-end; padding:0 14px; color:#fff; text-shadow:0 1px 2px rgba(0,0,0,.28); font-weight:700; font-size:14px; white-space:nowrap; }
.fp-tug-legend { display:flex; justify-content:space-between; margin-top:10px; font-size:12px; color:var(--text-md); }
.fp-tug-legend b { color:var(--text-hi); }
.fp-spark { margin-top:18px; }

/* Flow colour key (under the hero). Swatches read --flow-in/--flow-out so they
   track the admin colour + invert toggle - never raw green/red. */
.fp-flowkey { display:flex; align-items:center; gap:8px 18px; flex-wrap:wrap; margin:-8px 2px 18px; font:500 11.5px var(--mono); color:var(--text-md); }
.fp-flowkey .k { display:inline-flex; align-items:center; gap:7px; }
.fp-flowkey .k i { width:11px; height:11px; border-radius:3px; flex:none; }
.fp-flowkey .k.in i  { background:var(--flow-in); }
.fp-flowkey .k.out i { background:var(--flow-out); }
.fp-flowkey-note { color:var(--text-lo); display:inline-flex; align-items:center; gap:10px; }
.fp-flowkey-note::before { content:""; width:4px; height:4px; border-radius:50%; background:var(--border3); }
@media (max-width:600px){ .fp-flowkey-note::before { display:none; } .fp-flowkey { gap:6px 14px; } }

/* Stablecoin flow card (market-wide dry-powder read). Split bar + net + per-stable
   chips. Colours via --flow-in/--flow-out so they follow the admin colour set. */
.fp-stable { padding:16px 18px; }
.fp-st-bar { height:13px; border-radius:999px; overflow:hidden; display:flex; background:var(--bg-card2); box-shadow:inset 0 0 0 1px var(--border); }
.fp-st-bar i { height:100%; display:block; min-width:2px; }
.fp-st-bar .in  { background:linear-gradient(90deg,#0e9e6e,var(--flow-in)); }
.fp-st-bar .out { background:linear-gradient(90deg,var(--flow-out),#c23b4d); }
.fp-st-row { display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-top:13px; }
.fp-st-net { font:800 18px var(--mono); letter-spacing:-.3px; }
.fp-st-leg { display:flex; gap:16px; font:600 12px var(--mono); color:var(--text-md); }
.fp-st-leg i { width:10px; height:10px; border-radius:3px; display:inline-block; margin-right:6px; vertical-align:-1px; }
.fp-st-leg b { color:var(--text-hi); }
.fp-st-read { font-size:13px; color:var(--text-md); line-height:1.5; margin-top:8px; }
.fp-st-read b { color:var(--text-hi); }
.fp-stchips { display:flex; flex-wrap:wrap; gap:8px; margin-top:14px; }
.fp-stchip { display:inline-flex; align-items:center; gap:7px; font:600 12.5px var(--font); color:var(--text-hi); background:var(--bg-card2); border:1px solid var(--border2); border-radius:999px; padding:5px 12px 5px 7px; }
.fp-stchip img { width:18px; height:18px; border-radius:50%; }
.fp-stchip b { font-family:var(--mono); font-size:11.5px; font-weight:700; }

.fp-sec { display:flex; align-items:center; justify-content:space-between; margin:26px 2px 13px; }
.fp-sec h2 { font-size:13px; font-weight:800; letter-spacing:.5px; text-transform:uppercase; color:var(--text-hi); margin:0; }
.fp-hint { font:500 12px var(--mono); color:var(--text-lo); }
/* Mobile: title + hint + meta/controls crammed onto one row and wrapped into an
   ugly 2-line knot. Stack the controls under the title; drop the verbose
   "tap to open a CEX" cue (cells are obviously tappable on touch). */
@media (max-width: 640px) {
  .fp-sec { flex-wrap:wrap; gap:4px 8px; margin:16px 2px 9px; }
  .fp-sec h2 { width:100%; }
  /* .fp-sec scope = higher specificity than the base .fp-explore rule below,
     so the hide wins regardless of source order. */
  .fp-sec .fp-explore { display:none; }
}
/* "tap to open a CEX" explore cue - accent-coloured with a touch icon so it
   reads as an invitation to interact, not a passive label. */
.fp-explore { display:inline-flex; align-items:center; gap:4px; color:var(--accent-2); }
.fp-explore .mat-ic { font-size:15px; }

.fp-lb { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(218px,1fr); gap:13px; overflow-x:auto; padding-bottom:2px; }
.fp-ex { position:relative; border:1px solid var(--border); border-radius:14px; background:var(--bg-card); padding:16px 16px 14px; overflow:hidden; cursor:pointer; transition:border-color .15s, transform .15s, box-shadow .15s; }
.fp-ex:hover { border-color:var(--accent-border); transform:translateY(-2px); box-shadow:0 8px 22px rgba(0,0,0,.28); }
.fp-ex:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
/* Persistent "View flows →" call-to-action. Visible at rest (not hover-only) so
   touch users see the card is tappable; brightens + nudges the arrow on
   hover/focus. This is the explicit "click here to explore" cue. */
.fp-ex-cta { display:flex; align-items:center; gap:5px; margin-top:12px; padding-top:11px; border-top:1px solid var(--border); font:700 11px var(--mono); letter-spacing:.4px; text-transform:uppercase; color:var(--accent-2); }
.fp-ex-arrow { transition:transform .15s; }
.fp-ex:hover .fp-ex-cta, .fp-ex:focus-visible .fp-ex-cta { color:var(--accent); }
.fp-ex:hover .fp-ex-arrow, .fp-ex:focus-visible .fp-ex-arrow { transform:translateX(3px); }
.fp-ex-stripe { position:absolute; left:0; top:0; bottom:0; width:3px; }
.fp-ex-head { display:flex; align-items:center; gap:9px; margin-bottom:13px; }
.fp-ex-head img { width:26px; height:26px; border-radius:50%; }
.fp-ex-name { font-weight:700; font-size:14.5px; color:var(--text-hi); }
.fp-ex-rank { margin-left:auto; font:700 11px var(--mono); color:var(--text-lo); background:var(--bg-card2); padding:3px 8px; border-radius:7px; }
.fp-ex-net { font-size:24px; font-weight:800; letter-spacing:-.6px; }
.fp-ex-net.pos { color:var(--flow-in); } .fp-ex-net.neg { color:var(--flow-out); }
.fp-ex-net small { font-size:12px; font-weight:600; color:var(--text-lo); letter-spacing:0; margin-left:6px; }
.fp-ex-split { height:7px; border-radius:5px; overflow:hidden; display:flex; margin:11px 0 8px; background:var(--bg-card2); }
.fp-ex-split .i { background:var(--flow-in); } .fp-ex-split .o { background:var(--flow-out); }
.fp-ex-meta { display:flex; justify-content:space-between; align-items:center; font-size:11.5px; color:var(--text-md); }
.fp-ex-meta b { color:var(--text-hi); }
.fp-ex-vol { color:var(--text-lo); font-family:var(--mono); }
/* Locked-exchange teaser card: reveal-not-hide. Real name + tx count + lock + CTA,
   no flow numbers (server sends none). Visually muted vs an unlocked card. */
.fp-ex-locked { border-style:dashed; background:var(--bg-card2, var(--bg-card)); }
.fp-ex-locked .fp-ex-name { color:var(--text-md); }
.fp-ex-lock { margin-left:auto; font-size:18px; color:var(--text-lo); }
.fp-ex-locked-body { margin:8px 0 2px; min-height:50px; }
.fp-ex-locked-tx { font-size:13px; color:var(--text-md); }
.fp-ex-locked-tx b { color:var(--text-hi); font-family:var(--mono); }
.fp-ex-locked-hint { font-size:11.5px; color:var(--text-lo); margin-top:6px; }
.fp-ex-locked .fp-ex-cta { color:var(--accent-2); border-top-color:var(--accent-border); }
.fp-ex-locked:hover { border-color:var(--accent-border); }
.fp-ex-locked:hover .fp-ex-lock { color:var(--accent-2); }

.fp-duo { display:grid; grid-template-columns:1.15fr .85fr; gap:18px; align-items:start; min-width:0; }
/* Grid/flex children default to min-width:auto and refuse to shrink below their
   content - that overflows the page on mobile (the cut-off asset/tape cards).
   Let them shrink to their column; the inner flexible bits have min-width:0 too. */
.fp-duo > .fp-card, .fp-lb > .fp-ex, .fp-asset, .fp-wm, .fp-ex-meta { min-width:0; }
.fp-card { border:1px solid var(--border); border-radius:14px; background:var(--bg-card); min-width:0; }
/* 30d DAILY activity chart (main tab): daily bars = total volume summed across the SELECTED
   exchanges; filter chips toggle each exchange in/out. Mobile-first - 30 thin bars flex to fit. */
.fp-act { padding:16px 18px; }
.fp-act-empty { color:var(--text-lo); font-size:12px; padding:14px; text-align:center; }

/* Net Flow per day chart - one baseline, height=|net|, colour=direction (--flow-in/--flow-out). */
.nf-head { margin-bottom:18px; }
.nf-kicker { font:600 11px var(--mono); letter-spacing:1px; color:var(--text-lo); margin-bottom:7px; }
.nf-netrow { display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; }
.nf-arrow { font:700 20px var(--mono); line-height:1; }
.nf-net { font:700 28px var(--mono); letter-spacing:-.8px; }
.nf-netcap { font:500 12px var(--mono); color:var(--text-lo); }
.nf-sub { font:500 11.5px var(--mono); color:var(--text-md); margin-top:6px; }

.nf-plot { display:flex; gap:12px; }
.nf-yaxis { display:flex; flex-direction:column; justify-content:space-between; height:220px; padding-bottom:22px; text-align:right; flex:none; }
.nf-yl { font:500 10px var(--mono); color:var(--text-lo); }
.nf-area { flex:1; position:relative; min-width:0; }
.nf-grid { position:absolute; left:0; right:0; top:0; height:198px; display:flex; flex-direction:column; justify-content:space-between; pointer-events:none; }
.nf-grid > span { height:1px; background:var(--border); }
.nf-grid > span.nf-base { background:var(--border2, var(--border)); }
.nf-bars { position:relative; z-index:2; display:flex; align-items:flex-end; gap:4px; height:198px; }
.nf-col { position:relative; flex:1 1 0; min-width:0; display:flex; align-items:flex-end; height:100%; cursor:pointer; transition:opacity .12s; }
.nf-bar { width:100%; border-radius:3px 3px 0 0; transition:height .2s ease; }
.nf-bars:hover .nf-col { opacity:.4; }
.nf-bars:hover .nf-col:hover { opacity:1; }
.nf-tip { position:absolute; left:50%; transform:translateX(-50%); white-space:nowrap; padding:5px 9px; border-radius:7px; background:var(--bg-card2,#1a1b26); border:1px solid var(--border2,var(--border)); font:700 11px var(--mono); box-shadow:0 6px 18px rgba(0,0,0,.5); z-index:5; opacity:0; transition:opacity .12s; pointer-events:none; }
.nf-tip > span { display:block; font:400 9px var(--mono); color:var(--text-lo); margin-top:1px; }
.nf-col:hover .nf-tip { opacity:1; }
.nf-xaxis { display:flex; justify-content:space-between; margin-top:8px; font:500 10px var(--mono); color:var(--text-lo); }

.nf-legend { display:flex; gap:18px; flex-wrap:wrap; align-items:center; margin-top:18px; padding-top:16px; border-top:1px solid var(--border); }
.nf-leg { display:inline-flex; align-items:center; gap:7px; font:500 12px var(--mono); color:var(--text-md); }
.nf-leg i { width:11px; height:11px; border-radius:3px; flex:none; }

@media (max-width:560px){
  .fp-act { padding:14px; }
  .nf-net { font-size:24px; }
  .nf-arrow { font-size:18px; }
  .nf-netcap { display:none; }
  .nf-plot { gap:8px; }
  .nf-yaxis { height:182px; padding-bottom:20px; }
  .nf-yl { font-size:9px; }
  .nf-grid, .nf-bars { height:160px; }
  .nf-bars { gap:2px; }
  .nf-bar { border-radius:2px 2px 0 0; }
  .nf-tip { display:none; }                 /* mobile = no hover; colour + legend carry it (matches the mobile design) */
  .nf-legend { flex-direction:column; gap:9px; align-items:flex-start; }
}
.fp-ch { padding:14px 16px 12px; font-size:12px; font-weight:800; letter-spacing:.5px; text-transform:uppercase; color:var(--text-hi); display:flex; justify-content:space-between; align-items:center; border-bottom:1px solid var(--border); }
.fp-ch .fp-hint { font-size:11px; text-transform:none; letter-spacing:0; }
.fp-card-body { padding:6px 0; }

.fp-asset { display:flex; align-items:center; gap:10px; padding:9px 16px; }
.fp-asset:hover { background:var(--bg-hover); }
/* Asset rows filter the whale tape to that coin. Persistent funnel glyph (faint
   at rest so touch users see it's interactive), brighter on hover, solid +
   accent-tinted row when active. */
.fp-asset.clickable { cursor:pointer; }
.fp-asset-go { font-size:16px; color:var(--text-lo); opacity:.32; transition:opacity .15s, color .15s; flex-shrink:0; }
.fp-asset.clickable:hover .fp-asset-go { opacity:.85; }
.fp-asset.sel { background:var(--accent-dim); }
.fp-asset.sel .fp-asset-go { opacity:1; color:var(--accent-2); }
.fp-tape-clear { color:var(--accent-2); cursor:pointer; }
.fp-tape-clear:hover { color:var(--accent); text-decoration:underline; }
.fp-asset img { width:24px; height:24px; border-radius:50%; flex-shrink:0; }
.fp-as { width:52px; font-weight:700; font-size:13px; color:var(--text-hi); }
.fp-bar { flex:1; height:22px; position:relative; }
.fp-bar .mid { position:absolute; left:50%; top:0; bottom:0; width:1px; background:var(--border2); }
.fp-bar .fill { position:absolute; top:4px; height:14px; border-radius:4px; }
.fp-bar .fill.pos { left:50%; background:linear-gradient(90deg, color-mix(in srgb, var(--flow-in,#10b981) 85%, #000), var(--flow-in,#16d398)); }
.fp-bar .fill.neg { right:50%; background:linear-gradient(90deg, var(--flow-out,#ef5d6b), color-mix(in srgb, var(--flow-out,#e74c5c) 85%, #000)); }
.fp-av { width:78px; text-align:right; font:700 13px var(--mono); }
.fp-av.pos { color:var(--flow-in); } .fp-av.neg { color:var(--flow-out); }

/* Guest / free-plan "unlock more" badge above the asset section. */
.fp-ta-badge { display:flex; align-items:center; gap:10px; margin:0 0 12px; padding:11px 14px; cursor:pointer;
  border:1px solid color-mix(in srgb, var(--accent,#7b5cff) 38%, var(--border)); border-radius:10px;
  background:color-mix(in srgb, var(--accent,#7b5cff) 10%, var(--bg-card)); color:var(--text-hi); font-size:13px; }
.fp-ta-badge:hover { background:color-mix(in srgb, var(--accent,#7b5cff) 16%, var(--bg-card)); }
.fp-ta-badge .mat-ic { color:var(--accent-2,#a98bff); font-size:19px; flex:0 0 auto; }
.fp-ta-badge-msg { flex:1 1 auto; min-width:0; }
.fp-ta-badge-cta { flex:0 0 auto; font-weight:800; color:var(--accent-2,#a98bff); white-space:nowrap; }

.fp-tape { max-height:540px; overflow:auto; }
.fp-wm { display:flex; align-items:center; gap:10px; padding:11px 16px; border-bottom:1px solid var(--border); }
.fp-wm:last-child { border-bottom:0; }
.fp-wm:hover { background:var(--bg-hover); }
/* Tape rows open the whale's wallet (or the tx). Persistent chevron is the
   "click to explore" cue - visible at rest so it works on touch, brighter +
   nudged on hover. */
.fp-wm.clickable { cursor:pointer; }
.fp-wm-go { color:var(--text-lo); font:700 19px var(--mono); line-height:1; flex-shrink:0; margin-left:2px; transition:color .15s, transform .15s, opacity .15s; }
.fp-wm.clickable:hover .fp-wm-go { color:var(--accent-2); transform:translateX(2px); }
/* discover badge (.disc-row) replaces the chevron on hover */
.fp-wm.disc-row:hover .fp-wm-go, .fp-asset.disc-row:hover .fp-asset-go { opacity:0; }
.fp-wm img { width:28px; height:28px; border-radius:50%; flex-shrink:0; }
.fp-wm-mid { flex:1; min-width:0; }
.fp-wm-top { display:flex; align-items:baseline; gap:7px; }
.fp-wm-amt { font-weight:800; font-size:14px; color:var(--text-hi); }
.fp-wm-sym { font:700 11px var(--mono); color:var(--text-md); }
.fp-wm-route { font-size:11.5px; color:var(--text-lo); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.fp-wm-right { text-align:right; }
.fp-wm-usd { font:800 13px var(--mono); }
.fp-wm-usd.in { color:var(--flow-in); } .fp-wm-usd.out { color:var(--flow-out); } .fp-wm-usd.int { color:var(--accent-2); }
.fp-wm-chip { display:inline-block; font:700 9px var(--mono); letter-spacing:.5px; padding:2px 7px; border-radius:5px; margin-top:4px; }
.fp-wm-chip.c-in { background:color-mix(in srgb, var(--flow-in,#16d398) 15%, transparent); color:var(--flow-in,#16d398); }
.fp-wm-chip.c-out { background:color-mix(in srgb, var(--flow-out,#ef5d6b) 15%, transparent); color:var(--flow-out,#ff8a96); }
.fp-wm-chip.c-int { background:rgba(123,92,255,.16); color:var(--accent-2); }

.fp-heat { padding:14px 16px 18px; overflow-x:auto; }
.fp-heat-grid { display:flex; flex-direction:column; gap:6px; min-width:560px; }
.fp-heat-row { display:grid; grid-template-columns:130px repeat(var(--hn,7),1fr); gap:6px; align-items:center; }
.fp-heat-row.head .fp-heat-h { text-align:center; font:600 10px var(--mono); color:var(--text-lo); }
.fp-heat-ex { display:flex; align-items:center; gap:8px; font-weight:700; font-size:12.5px; color:var(--text-hi); }
.fp-heat-ex img { width:18px; height:18px; border-radius:50%; }
/* Each CEX row is a drill-down into that exchange. Whole row is the tap target;
   the label carries a chevron so it reads as interactive even on touch (no
   hover). Row brightens on hover/focus. */
.fp-heat-row[data-cex] { cursor:pointer; border-radius:9px; transition:background .12s; }
.fp-heat-row[data-cex]:hover { background:var(--bg-hover); }
.fp-heat-row[data-cex]:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.fp-heat-go { margin-left:auto; color:var(--accent-2); font-weight:800; opacity:.55; transition:opacity .15s, transform .15s; }
.fp-heat-row[data-cex]:hover .fp-heat-go, .fp-heat-row[data-cex]:focus-visible .fp-heat-go { opacity:1; transform:translateX(2px); }
.fp-heat-cell { height:38px; border-radius:8px; display:grid; place-items:center; font:700 11px var(--mono); color:#fff; border:1px solid var(--border); transition:transform .1s; }
.fp-heat-cell:hover { transform:scale(1.07); border-color:var(--accent-border); }
.fp-heat-legend { display:flex; align-items:center; gap:7px; margin-top:13px; font:500 10px var(--mono); color:var(--text-lo); }
.fp-heat-legend .sw { width:16px; height:12px; border-radius:3px; }
.fp-heat-peakkey { display:inline-flex; align-items:center; gap:5px; }
.fp-heat-peakkey .dot { width:7px; height:7px; border-radius:50%; background:var(--accent-2); }
/* per-CEX busiest cell of the week - ring + corner dot */
.fp-heat-cell { position:relative; }
.fp-heat-cell.peak { outline:2px solid var(--accent-2); outline-offset:-2px; font-weight:800; color:#fff; }
.fp-heat-cell.peak::after { content:''; position:absolute; top:3px; right:3px; width:5px; height:5px; border-radius:50%; background:var(--accent-2); box-shadow:0 0 0 2px rgba(123,92,255,.3); }
/* Locked-exchange heatmap row: reveal-not-hide. Name + lock + tx count + CTA, no cells. */
.fp-heat-row[data-locked-cex] { cursor:pointer; border-radius:9px; }
.fp-heat-row.locked .fp-heat-name { color:var(--text-md); }
.fp-heat-row.locked .fp-ex-lock { font-size:15px; color:var(--text-lo); }
.fp-heat-locked { grid-column:2 / -1; display:flex; align-items:center; gap:12px; height:38px; padding:0 13px; border:1px dashed var(--border); border-radius:8px; background:var(--bg-card2,var(--bg-card)); }
.fp-heat-locked-tx { font:600 11px var(--mono); color:var(--text-md); }
.fp-heat-locked-cta { margin-left:auto; font:700 10.5px var(--mono); letter-spacing:.4px; text-transform:uppercase; color:var(--accent-2); }
.fp-heat-row[data-locked-cex]:hover .fp-heat-locked { border-color:var(--accent-border); }
.fp-heat-row[data-locked-cex]:hover .fp-ex-lock { color:var(--accent-2); }
.fp-heat-row[data-locked-cex]:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
/* heatmap granularity toggle (its own filter: Daily / 6h) */
.fp-heat-toggle { display:flex; align-items:center; }
.fp-heat-toggle button { background:var(--bg-card); border:1px solid var(--border); color:var(--text-md); font:600 11px var(--mono); padding:4px 11px; cursor:pointer; }
.fp-heat-toggle button:first-of-type { border-radius:7px 0 0 7px; }
.fp-heat-toggle button:last-of-type { border-radius:0 7px 7px 0; border-left:0; }
.fp-heat-toggle button.on { background:var(--accent); border-color:var(--accent); color:#fff; }

/* Styled heatmap tooltip (replaces the dated native title=). */
.fp-tip { position:fixed; z-index:9999; pointer-events:none; opacity:0; transform:translateY(3px); transition:opacity .1s ease;
  background:var(--bg-card2); border:1px solid var(--border2); border-radius:10px; padding:9px 12px;
  box-shadow:0 10px 28px rgba(0,0,0,.45); max-width:280px; }
.fp-tip.on { opacity:1; transform:none; }
.fp-tip .t1 { font-weight:700; font-size:12.5px; color:var(--text-hi); }
.fp-tip .t2 { font-size:11.5px; color:var(--text-md); margin-top:3px; font-family:var(--mono); }
.fp-tip .t2 b { color:var(--text-hi); }
.fp-tip .t3 { display:flex; align-items:center; gap:6px; font:600 11px var(--font); color:var(--accent-2); margin-top:5px; }
.fp-tip .t3 .dot { width:6px; height:6px; border-radius:50%; background:var(--accent-2); box-shadow:0 0 0 3px rgba(123,92,255,.25); }

/* Keep the vertical scrollbar ALWAYS present (not just when content overflows),
   so the page width is identical for the short skeleton and the taller loaded
   content - no sideways shift on filter switch. overflow-y:scroll is the
   reliable cross-browser version of scrollbar-gutter:stable. */
html { overflow-y: scroll; scrollbar-gutter: stable; }

/* The page must NEVER scroll horizontally. Data grids (heatmap, wide leaderboard)
   scroll inside their own card instead; clip stops any stray overflow reaching
   the page. Doesn't affect nested overflow-x:auto scrollers. */
.shell { overflow-x: clip; }

@media (max-width:980px){ .fp-lb{ grid-auto-flow:row; grid-template-columns:repeat(2,1fr); grid-auto-columns:auto; overflow:visible; } }
@media (max-width:860px){
  .shell{ padding:6px; }   /* system-wide minimum mobile gutter */
  .fp-hero{ padding:18px 16px; }
  .fp-hero-grid{ grid-template-columns:1fr; gap:20px; min-height:0; }
  .fp-hero-num{ font-size:36px; letter-spacing:-1px; }
  .fp-hero-sub{ font-size:13px; }
  .fp-sentiment{ font-size:12px; padding:8px 13px; }
  .fp-duo{ grid-template-columns:1fr; }
}
@media (max-width:600px){
  .fp-lb{ grid-template-columns:1fr; }
  .fp-heat{ padding:12px 8px 16px; }
  /* phones: show only the CEX icon in the heatmap row label (no name); the
     drill chevron is dropped here (no room in the 26px label column) - the row
     is still tappable and the leaderboard CTA above already teaches the pattern. */
  .fp-heat-name{ display:none; }
  .fp-heat-go{ display:none; }
  .fp-heat-row{ grid-template-columns:26px repeat(var(--hn,7),1fr); gap:4px; }
  .fp-heat-cell{ height:34px; font-size:9.5px; }
  .fp-heat-ex{ justify-content:center; }
  .fp-heat-ex img{ width:18px; height:18px; margin:0; }
  .fp-heat-h{ font-size:8.5px; }
  /* duo cards: let flexible bits shrink so values aren't clipped */
  .fp-bar{ min-width:0; }
  .fp-as{ width:46px; }
  .fp-av{ width:70px; font-size:12px; }
  .fp-asset{ gap:8px; padding:9px 12px; }
  .fp-wm{ padding:10px 12px; }
}

/* Dashboard tab panels (Exchanges / Assets / Stablecoins / Heatmap). The tab
   bar uses the shared .seg-tabs (style.css); analytics.js toggles [hidden]. */
.an-panel[hidden] { display: none; }
