/* ============================================================================
   Vibe Dashboard v2 — Leaderboard screen, Sep 20 design (VIB-503).
   Title + LAST SNAPSHOT block, 3 stat cells, date stepper + 14-bar strip +
   1D/7D/30D, top-3 cards, venue tabs + hide-zero toggle + search, ranked
   table with share bars, footer count, formula footnote.
   Builds on styles/v2-shell.css's shared kit (.v2-card, .v2-empty). Tokens
   only from styles/vibe-tokens.css — no hardcoded colours. Flat surfaces
   only: no gradients, no glassmorphism. Numbers tabular-nums.
   ============================================================================ */

/* FIX1.5: medal colors with no --v- token live as --v2l-* props (never hex
   in rules, never inline in JSX). Values pinned by the no-hex test below. */
:root {
  --v2l-silver: #C6CBD6;
  --v2l-bronze: #C08457;
}

.v2l-head {
  display: flex;
  /* F2 (reviewer round 6): flex-wrap: wrap let the row itself break onto two
     lines whenever the subtitle's UNWRAPPED hypothetical width (flex-wrap's
     line-break test uses the item's content size, not its post-shrink size)
     overflowed the container — min-width: 0 on .v2l-head-main only helps it
     shrink once on the line, it can't stop that hypothetical overflow from
     wrapping LAST SNAPSHOT below. Desktop never wraps the row; the subtitle
     text wraps inside its own shrunk column instead (mock 23's longest
     subtitle, Referral). Mobile restores the stack at 760px below. */
  flex-wrap: nowrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px 16px;
  margin-bottom: 6px;
}
/* Round 3 item 1: the title+subtitle column flexes/shrinks so LAST SNAPSHOT
   (flex-shrink: 0 below) stays pinned top-right on every tab, even with a
   long subtitle (mock 23) — without min-width: 0 a flex item's default
   min-width is its content's un-wrapped size, which can push the row wide
   enough that the snapshot column wraps below instead of the subtitle
   text wrapping inside its own column. */
.v2l-head-main { flex: 1 1 auto; min-width: 0; }
.v2l-title {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -.6px;
  color: var(--v-heading);
}
.v2l-subtitle { font-size: 14.5px; color: var(--v-text-2); margin-top: 5px; }

/* ---------- underline TABS row (mocks 20-24, round 2 C1): its own row
   under the header, a bottom rule, replacing the old segmented pill
   switch. ---------- */
.v2l-tabs {
  display: flex;
  gap: 26px;
  border-bottom: 1px solid var(--v-border-soft);
  margin: 4px 0 20px;
  /* Round 3 item 2: on narrow viewports 5 tabs don't fit — scroll the row
     horizontally instead of wrapping labels to two lines or clipping the
     last tab; the page itself never gains horizontal overflow. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.v2l-tabs::-webkit-scrollbar { display: none; }
.v2l-tab {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 0 0 12px;
  margin-bottom: -1px;
  font-family: var(--v-font);
  font-size: 14px;
  font-weight: 600;
  color: var(--v-text-2);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.v2l-tab:hover { color: var(--v-text); }
.v2l-tab.is-active { color: var(--v-text); border-bottom-color: var(--v-link); }
.v2l-tab:focus-visible { outline: 2px solid var(--v-link); outline-offset: 2px; }

/* ---------- LAST SNAPSHOT block: right-aligned, mono overline ---------- */

.v2l-snap { text-align: right; flex-shrink: 0; }
.v2l-snap-label {
  font-family: var(--v-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--v-text-2);
}
.v2l-snap-value {
  font-size: 16px;
  font-weight: 600;
  color: var(--v-text-table);
  margin-top: 3px;
  white-space: nowrap;
}

/* ---------- 3 stat cells ---------- */

.v2l-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--v-border-soft);
  border: 1px solid var(--v-border);
  border-radius: var(--v-r-card);
  overflow: hidden;
}
.v2l-stat {
  background: var(--v-surface);
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}
.v2l-stat-label {
  font-family: var(--v-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--v-text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2l-stat-value, .v2l-stat-value-dim {
  min-height: 28px;
  display: flex;
  align-items: center;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -.6px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.v2l-stat-value { color: var(--v-text-bright); }
.v2l-stat-value-dim { color: var(--v-text-2); }
.v2l-stat-sub {
  font-size: 12px;
  color: var(--v-text-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}

/* ---------- date bar: stepper + bars + 1D/7D/30D ---------- */

.v2l-datebar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 20px;
  border: 1px solid var(--v-border);
  background: var(--v-surface);
  border-radius: var(--v-r-card);
  padding: 14px 18px;
}
.v2l-stepper { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.v2l-step {
  appearance: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--v-r-icon);
  border: 1px solid var(--v-border-well);
  background: transparent;
  color: var(--v-text-2);
  cursor: pointer;
}
.v2l-step:hover:not(:disabled) { background: var(--v-inset); }
.v2l-step:disabled { color: var(--v-text-3); opacity: .45; cursor: default; }
.v2l-step:focus-visible { outline: 2px solid var(--v-link); outline-offset: 1px; }
.v2l-day-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.v2l-day-label-row { display: flex; align-items: center; gap: 8px; }
.v2l-day-label { font-size: 17px; font-weight: 700; letter-spacing: -.3px; color: var(--v-text-bright); }
.v2l-day-chip, .v2l-day-chip-today {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 7px;
  border-radius: 5px;
  font-family: var(--v-font-mono);
  font-size: 9.5px;
  letter-spacing: 1.2px;
  border: 1px solid var(--v-border-well);
  color: var(--v-text-2);
}
.v2l-day-chip-today { color: var(--v-green); border-color: color-mix(in srgb, var(--v-green) 35%, transparent); }
.v2l-day-meta {
  font-family: var(--v-font-mono);
  font-size: 11.5px;
  color: var(--v-text-3);
  font-variant-numeric: tabular-nums;
}

/* 14-bar strip: flex bars, hover link-blue, selected bar highlighted. */
.v2l-bars {
  flex: 1 1 240px;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 40px;
}
.v2l-bar, .v2l-bar-active {
  flex: 1 1 0;
  min-width: 0;
  border-radius: 3px;
  cursor: pointer;
}
.v2l-bar { background: color-mix(in srgb, var(--v-link) 24%, transparent); }
.v2l-bar-active { background: var(--v-link); }
.v2l-bar:hover, .v2l-bar-active:hover { background: var(--v-link); }
.v2l-bar:focus-visible, .v2l-bar-active:focus-visible { outline: 2px solid var(--v-link); outline-offset: 1px; }

/* 1D/7D/30D segmented control. */
.v2l-period {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border-radius: 9px;
  background: var(--v-inset);
  border: 1px solid var(--v-border);
  flex-shrink: 0;
}
.v2l-period-btn, .v2l-period-active {
  appearance: none;
  border: 0;
  border-radius: var(--v-r-icon);
  padding: 6px 12px;
  background: transparent;
  color: var(--v-text-2);
  font-family: var(--v-font-mono);
  font-size: 11.5px;
  font-weight: 500;
  cursor: pointer;
}
.v2l-period-btn:hover { color: var(--v-text); }
.v2l-period-active { background: var(--v-blue); color: var(--v-white); }
.v2l-period-btn:focus-visible, .v2l-period-active:focus-visible { outline: 2px solid var(--v-link); outline-offset: 1px; }

/* ---------- top-3 cards; #1 takes the gold tint ---------- */

.v2l-top3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.v2l-top, .v2l-top-first {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 14px 16px;
  border-radius: var(--v-r-card);
  min-width: 0;
  border: 1px solid var(--v-border-well);
  background: var(--v-surface);
}
.v2l-top-first {
  background: color-mix(in srgb, var(--v-amber) 6%, var(--v-surface));
}
.v2l-top-rank {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 10px;
  display: grid;
  place-items: center;
  font-family: var(--v-font-mono);
  font-size: 13.5px;
  font-weight: 700;
  border: 1px solid var(--v-border-well);
  background: var(--v-inset);
}
.v2l-top-body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.v2l-top-handle {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--v-text-table);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2l-top-meta {
  display: flex;
  flex-wrap: wrap;
  column-gap: 8px;
  row-gap: 2px;
  font-family: var(--v-font-mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--v-text-3);
}
/* FIX1.5: rank color by place (mock r.rankFg). The amount span takes its
   card's rank class; the share span keeps the muted meta color. */
.v2l-rank, .v2l-rank-1, .v2l-rank-2, .v2l-rank-3 { font-weight: 500; }
.v2l-rank { color: var(--v-text-3); }
.v2l-rank-1 { color: var(--v-amber); }
.v2l-rank-2 { color: var(--v2l-silver); }
.v2l-rank-3 { color: var(--v2l-bronze); }

/* ---------- table card: toolbar, table, footer ---------- */

.v2l-board {
  border: 1px solid var(--v-border);
  background: var(--v-surface);
  border-radius: var(--v-r-card);
}
.v2l-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px 18px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--v-border-soft);
  flex-wrap: wrap;
}
.v2l-venue-toggle {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--v-border);
  border-radius: 9px;
  background: var(--v-inset);
}
.v2l-venue {
  appearance: none;
  border: 0;
  border-radius: var(--v-r-icon);
  padding: 7px 14px;
  background: transparent;
  color: var(--v-text-2);
  font-family: var(--v-font);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.v2l-venue:hover { color: var(--v-text); }
.v2l-venue.is-active { background: var(--v-blue); color: var(--v-white); }
.v2l-venue:focus-visible { outline: 2px solid var(--v-link); outline-offset: 1px; }
.v2l-tools { display: flex; align-items: center; gap: 12px 16px; flex-wrap: wrap; }
.v2l-toggle {
  appearance: none;
  border: 0;
  background: transparent;
  display: flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  padding: 0;
  font: inherit;
}
.v2l-toggle:focus-visible { outline: 2px solid var(--v-link); outline-offset: 2px; }
.v2l-switch, .v2l-switch-on {
  width: 34px;
  height: 20px;
  flex-shrink: 0;
  border-radius: 999px;
  padding: 2px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  background: var(--v-inset);
  border: 1px solid var(--v-border-well);
}
.v2l-switch { justify-content: flex-start; }
.v2l-switch-on { justify-content: flex-end; background: var(--v-blue); }
.v2l-knob { width: 14px; height: 14px; border-radius: 999px; background: var(--v-white); }
.v2l-switch .v2l-knob { background: var(--v-text-3); }
.v2l-toggle-label { font-size: 13px; color: var(--v-text-2); white-space: nowrap; }
.v2l-search-wrap { position: relative; display: flex; align-items: center; }
.v2l-search-icon {
  position: absolute;
  left: 11px;
  display: grid;
  place-items: center;
  color: var(--v-text-3);
  pointer-events: none;
}
.v2l-search {
  width: 168px;
  box-sizing: border-box;
  padding: 9px 12px 9px 32px;
  border-radius: var(--v-r-icon);
  border: 1px solid var(--v-border-well);
  background: var(--v-inset);
  font-family: var(--v-font);
  font-size: 13px;
  color: var(--v-text-table);
  outline: none;
}
.v2l-search::placeholder { color: var(--v-text-3); }
.v2l-search:focus { border-color: var(--v-border-blue); }

/* ---------- ranked table ---------- */

.v2l-table-wrap {
  overflow-x: auto;
}
.v2l-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  color: var(--v-text-table);
}
.v2l-table thead th {
  font-family: var(--v-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--v-text-2);
  text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--v-border-soft);
  white-space: nowrap;
}
.v2l-table tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--v-border-row);
  vertical-align: middle;
}
/* S1b C17: column gutters track the mock grid gap — 14px at desktop, 10px
   under 1180px. The app keeps its table markup, so the mock's column-gap
   maps onto cell padding. */
@media (max-width: 1180px) {
  .v2l-table thead th, .v2l-table tbody td { padding-left: 10px; padding-right: 10px; }
}
/* FIX1 verify pass 1: the mock's retuned 7-column tracks (Vibe.dc.html
   3038-3040) mapped onto the fixed table — rank fixed, wallet roomy
   (200px base: the mock's 170px minimum grown by its 1.7fr, which a fixed
   table cannot express), numerics at mock minimums. Fixed tables size from `width`, not
   `min-width`, so the tracks use width. The wallet cell (handle + address
   + copy) stays on ONE line; the address hides under 1180px like the mock.
   Rank-head padding trims so RANK never runs into WALLET. */
.v2l-table { table-layout: fixed; }
.v2l-table thead th:nth-child(1), .v2l-table tbody td:nth-child(1) { width: 36px; padding-left: 6px; padding-right: 4px; }
/* D8 round 2 item 7: widened so a normal-length handle + short address
   never truncates at 1280px (mock 20-24 show both in full). */
.v2l-table thead th:nth-child(2), .v2l-table tbody td:nth-child(2) { width: 220px; }
.v2l-table thead th:nth-child(3), .v2l-table tbody td:nth-child(3),
.v2l-table thead th:nth-child(4), .v2l-table tbody td:nth-child(4) { width: 88px; }
.v2l-table thead th:nth-child(5), .v2l-table tbody td:nth-child(5) { width: 100px; }
.v2l-table thead th:nth-child(6), .v2l-table tbody td:nth-child(6) { width: 124px; }
.v2l-table thead th:nth-child(7), .v2l-table tbody td:nth-child(7) { width: 130px; }
/* F1 (reviewer round 6, mock 21): the shared col3/4 width (88px, tuned for
   Volume/All's "Majors USD"/"Trading pts") is too narrow for LP's much
   longer "Your revenue USDC" / "Ref revenue USDC" (and TVL's "(avg)"
   suffix) — the sort arrow ran the label into the next head's text. Scope
   wider tracks to the LP table by its own testid rather than growing every
   table's shared columns. */
/* L70: the one LP tab — Revenue (col3) and TVL (col4) heads are shorter
   now ("Revenue USDC", "TVL USD (avg)"), and POINTS (col5) gets the room
   (L70-ADD1: "not credited" must never run under the SHARE bar). */
.v2l-table[data-testid="lp-board-table"] thead th:nth-child(3),
.v2l-table[data-testid="lp-board-table"] tbody td:nth-child(3),
.v2l-table[data-testid="lp-board-table"] thead th:nth-child(4),
.v2l-table[data-testid="lp-board-table"] tbody td:nth-child(4) { width: 150px; }
.v2l-table[data-testid="lp-board-table"] thead th:nth-child(5),
.v2l-table[data-testid="lp-board-table"] tbody td:nth-child(5) { width: 132px; }
/* F1: Referral's "Active referees" (col5) is longer than the shared 100px
   track (tuned for "Weighted USD"/"Referral pts"); "Trade ref pts" (col3)
   is tighter too. Ref pts (col6) keeps the shared width — it's short. */
.v2l-table[data-testid="referral-board-table"] thead th:nth-child(3),
.v2l-table[data-testid="referral-board-table"] tbody td:nth-child(3) { width: 120px; }
.v2l-table[data-testid="referral-board-table"] thead th:nth-child(5),
.v2l-table[data-testid="referral-board-table"] tbody td:nth-child(5) { width: 155px; }
/* G12 audit 2026-09-21 (POINTS overflow): the fixed table's 12px placeholder
   ("not credited yet" / "awaiting backfill") is wider than the old 76px
   POINTS track, and tbody cells inherit white-space: nowrap — so it ran on
   under the SHARE cell painted later. The track is widened (funded by the
   wallet track, which ellipsizes), the cell clips instead of bleeding, and
   the placeholder wraps to two lines below 1180px instead of overflowing. */
.v2l-table tbody td[data-label="Points"] { overflow: hidden; }
.v2l-walletline {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  max-width: 100%;
  white-space: nowrap;
}
.v2l-walletline .v2l-wallet {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2l-walletline .v2l-addr { flex-shrink: 0; }
.v2l-walletline .v2l-copy { flex-shrink: 0; }
@media (max-width: 1180px) {
  .v2l-table thead th:nth-child(1), .v2l-table tbody td:nth-child(1) { width: 30px; }
  .v2l-table thead th:nth-child(2), .v2l-table tbody td:nth-child(2) { width: 84px; }
  .v2l-addr { display: none; }
}
/* S1b F5: the mobile row card cell stays hidden on desktop. */
.v2l-table tbody td.v2l-mcard { display: none; }
.v2l-mcard-l1 { display: flex; align-items: center; gap: 10px; min-width: 0; }
.v2l-mcard-handle {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--v-text-table);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2l-mcard-main {
  margin-left: auto;
  flex-shrink: 0;
  font-family: var(--v-font-mono);
  font-size: 13.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--v-text-table);
}
.v2l-mcard-l3 { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.v2l-mcard-tag {
  font-family: var(--v-font-mono);
  font-size: 11px;
  color: var(--v-text-3);
}
.v2l-mcard-tag > span { color: var(--v-text-table); }
.v2l-row:last-child td { border-bottom: 0; }
.v2l-row.is-top3 { background: color-mix(in srgb, var(--v-blue) 6%, transparent); }
/* FIX1.4: the viewer's own row — tint + 2 px left edge (mock r.bg / r.edge).
   Inset shadow keeps the edge from shifting the row layout. */
.v2l-row.is-you {
  background: color-mix(in srgb, var(--v-blue) 7%, transparent);
  box-shadow: inset 2px 0 0 var(--v-blue);
}
/* Round 3 item 3: the viewer's own row reads blue on every tab (handle +
   share bar) — including Referral's green bars and the mobile card, which
   share these same classes, so one rule covers desktop + mobile. */
.v2l-row.is-you .v2l-wallet,
.v2l-row.is-you .v2l-mcard-handle {
  color: var(--v-link);
}
.v2l-row.is-you .v2l-share-fill,
.v2l-row.is-you .v2l-share-fill-ref,
.v2l-row.is-you .v2l-share-fill-lp {
  background: var(--v-link);
}
.v2l-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.v2l-table thead th.v2l-num { text-align: right; }
/* S1b C13: click-to-sort heads — text buttons in the th; the active head
   reads bright with a blue arrow (mock c.fg / c.arrowFg). Keyboard comes
   free with the button; the th carries aria-sort. */
.v2l-sort {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
}
.v2l-sort:hover { color: var(--v-text); }
.v2l-sort:focus-visible { outline: 2px solid var(--v-link); outline-offset: 2px; }
.v2l-sort.is-active { color: var(--v2l-silver); }
.v2l-sort-arrow { font-size: 9px; color: transparent; }
.v2l-sort.is-active .v2l-sort-arrow { color: var(--v-link); }
/* S1b C13: the sorted column sets semibold (mock weight 600). */
.v2l-table tbody td.v2l-col-sorted { font-weight: 600; }
/* S1b C12: no credited rows → muted `not credited yet`, never a dressed 0. */
.v2l-pts-null {
  display: inline-block;
  color: var(--v-text-3);
  font-size: 12px;
  line-height: 1.25;
  white-space: normal;
  overflow-wrap: anywhere;
  vertical-align: middle;
}
.v2l-wallet {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--v-text-table);
}
/* FIX1.1/1.2: shortened address after the handle, mono muted. */
.v2l-addr {
  font-family: var(--v-font-mono);
  font-size: 11.5px;
  color: var(--v-text-3);
  margin-left: 9px;
  white-space: nowrap;
}
/* FIX1.1: 22 px copy icon button — invisible until the row is hovered or
   the button takes keyboard focus; green while the copy feedback shows. */
.v2l-copy {
  appearance: none;
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  cursor: pointer;
  vertical-align: middle;
  opacity: 0;
}
.v2l-row:hover .v2l-copy, .v2l-row:focus-within .v2l-copy, .v2l-copy:focus-visible { opacity: 1; }
.v2l-copy:hover { background: var(--v-inset); }
.v2l-copy.is-copied { color: var(--v-green); opacity: 1; }
.v2l-copy:focus-visible { outline: 2px solid var(--v-link); outline-offset: 1px; }
/* FIX2.2: touch has no hover — the icon stays visible where hover is absent. */
@media (hover: none) {
  .v2l-copy { opacity: 1; }
}
/* FIX1.3: rank + money cells read JetBrains Mono 13 px, tabular-nums. */
.v2l-table tbody td[data-label="Rank"], .v2l-table tbody td.v2l-num {
  font-family: var(--v-font-mono);
  font-size: 13px;
}
.v2l-share-cell { display: flex; align-items: center; justify-content: flex-end; gap: 9px; min-width: 0; max-width: 100%; overflow: hidden; }
.v2l-share {
  display: block;
  flex: 1 1 0;
  min-width: 0;
  height: 5px;
  border-radius: 999px;
  background: var(--v-inset);
  overflow: hidden;
}
/* POLISH v1.1.99: the POINTS placeholder wraps inside its own cell, never
   under the SHARE bar (the bar above is clipped to the SHARE cell). */
.v2l-table tbody td[data-label="Points"] .v2l-pts-null {
  display: inline-block;
  max-width: 100%;
  overflow-wrap: break-word;
}
/* POLISH v1.1.99: EST badge beside a figure reads "$2.06  EST" — weekday
   chips in label rows are untouched. */
.v2l-table tbody td.v2l-num .v2l-day-chip { margin-left: 7px; }
/* LP FIX1: same 7px EST gap inside the mobile card's main value (volume card
   carries no EST chip, so this is a no-op there). */
.v2l-table tbody td.v2l-mcard .v2l-mcard-main .v2l-day-chip { margin-left: 7px; }
.v2l-share-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--v-blue);
}
/* L70-ADD1: the short POINTS placeholder stays on one line inside its own
   cell (full text in its tooltip), and a not-credited row's SHARE is a
   dash with no bar. */
.v2l-pts-nc {
  display: inline-block;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
  font-family: var(--v-font);
  font-size: 12px;
  color: var(--v-text-3);
  cursor: help;
}
.v2l-share-none { color: var(--v-text-3); }
.v2l-pts-pop-row.is-total { font-weight: 600; color: var(--v-text); }
.v2l-share-pct {
  flex-shrink: 0;
  width: 48px;
  text-align: right;
  font-family: var(--v-font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--v-text-2);
}
.v2l-footer {
  padding: 14px 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--v-text-3);
  font-variant-numeric: tabular-nums;
}
/* D8 round 2 C6: pagination — ‹ 1 2 3 › (mocks 20-24). */
.v2l-pager { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.v2l-pager-btn {
  appearance: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: var(--v-r-icon);
  border: 1px solid var(--v-border-well);
  background: transparent;
  color: var(--v-text-2);
  cursor: pointer;
}
.v2l-pager-btn:hover:not(:disabled) { background: var(--v-inset); }
.v2l-pager-btn:disabled { color: var(--v-text-3); opacity: .45; cursor: default; }
.v2l-pager-btn:focus-visible { outline: 2px solid var(--v-link); outline-offset: 1px; }
.v2l-pager-page {
  appearance: none;
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  border-radius: var(--v-r-icon);
  border: 1px solid transparent;
  background: transparent;
  color: var(--v-text-2);
  font-family: var(--v-font-mono);
  font-size: 12px;
  cursor: pointer;
}
.v2l-pager-page:hover { color: var(--v-text); }
.v2l-pager-page.is-active { background: var(--v-blue); color: var(--v-white); }
.v2l-pager-page:focus-visible { outline: 2px solid var(--v-link); outline-offset: 1px; }
/* F6: the collapsed-run marker between windowed page buttons. */
.v2l-pager-ellipsis {
  min-width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  color: var(--v-text-3);
  font-family: var(--v-font-mono);
  font-size: 12px;
}
/* FIX2.4: partial-window honesty — muted meta line under the period control
   whenever the window reaches before the first ledger award day. */
.v2l-credited-from {
  padding: 0 22px 10px;
  font-size: 12px;
  color: var(--v-text-3);
}
/* LB-UI-TRUTH: the board answered pointsDegraded:true (points-ledger read
   failed) — amber notice, points blank for now, other figures current. */
.v2l-degraded {
  margin: 0 0 12px;
  padding: 10px 14px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--v-amber);
  background: var(--v-amber-tint);
  border: 1px solid var(--v-border-amber);
  border-radius: 10px;
}
/* POINTS-TOOLTIP (2026-09-21): hover/tap breakdown on credited POINTS
   cells. Desktop only — the ≤760px card below keeps its plain PTS tag plus
   a title hook, so no rule here may touch .v2l-mcard or the mobile block. */
.v2l-pts {
  position: relative;
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
.v2l-pts:focus-visible { outline: 2px solid var(--v-link); outline-offset: 2px; }
.v2l-pts-pop {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 5;
  min-width: 200px;
  padding: 9px 12px 10px;
  border: 1px solid var(--v-border);
  border-radius: var(--v-r-card);
  background: var(--v-surface);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  font-family: var(--v-font-mono);
  font-size: 12px;
  line-height: 1.5;
  text-align: left;
  white-space: nowrap;
}
.v2l-pts:hover .v2l-pts-pop,
.v2l-pts:focus-within .v2l-pts-pop,
.v2l-pts.is-open .v2l-pts-pop { display: block; }
.v2l-pts-pop-head {
  display: block;
  font-size: 10px;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--v-text-3);
  margin-bottom: 5px;
}
.v2l-pts-pop-row { display: flex; justify-content: space-between; gap: 18px; color: var(--v-text-table); }
.v2l-pts-pop-note { display: block; margin-top: 6px; color: var(--v-text-3); white-space: normal; max-width: 230px; }
/* PTS-PORTAL (2026-09-23, stacking fix): the in-cell absolute popover painted
   under the later rows — the Points td clips with overflow:hidden and the
   table wrap scrolls, so the OPEN popover portals to document.body as
   position:fixed. .is-portal reuses the base popover look verbatim (no new
   visual design); left/right/top reset so the inline style set from the
   anchor rect (flip + clamp keep it in the viewport) is the only position.
   z-index sits above sticky chrome, below modal traps. */
.v2l-pts-pop.is-portal,
.v2l-how-pop.is-portal {
  position: fixed;
  left: auto;
  right: auto;
  top: auto;
  display: block;
  z-index: 2000;
  max-width: min(270px, calc(100vw - 16px));
  max-height: min(320px, calc(100vh - 16px));
  overflow: auto;
}
/* D8 C8 (round 2 — full rebuild, mocks 30-33): the ONE points-tooltip box.
   312px wide, the --v-tile surface (design-system near-match for the mock),
   12px radius, AUTO height (no
   fixed clip — popover.jsx measures the real node so a tall body never cuts
   off its footer), 8px viewport margin via the shared clamp math. Built by
   popover.jsx's PtsTipBody; every board passes popClass="v2l-ptip-pop". */
.v2l-ptip-pop.is-portal {
  position: fixed;
  left: auto;
  right: auto;
  top: auto;
  display: block;
  z-index: 2000;
  width: min(312px, calc(100vw - 16px));
  max-height: calc(100vh - 16px);
  overflow: auto;
  padding: 16px;
  border-radius: var(--v-r-card);
  background: var(--v-tile);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
  font-family: var(--v-font);
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
  white-space: normal;
}
/* Round 3 item 4: a long date range (7D/30D) next to the DAY tag must wrap
   to a second line, never truncate the range — align-items: flex-start (not
   center) so the tag stays pinned top-right once the kicker wraps. */
.v2l-ptip-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.v2l-ptip-kicker {
  font-family: var(--v-font-mono);
  font-size: 10px;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--v-text-2);
  white-space: normal;
  overflow-wrap: break-word;
}
.v2l-ptip-tag {
  flex-shrink: 0;
  padding: 2px 7px;
  border: 1px solid var(--v-border-well);
  border-radius: 5px;
  font-family: var(--v-font-mono);
  font-size: 9.5px;
  letter-spacing: 1px;
  color: var(--v-text-2);
}
.v2l-ptip-handle-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.v2l-ptip-handle {
  font-size: 14px;
  font-weight: 600;
  color: var(--v-text-bright);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2l-ptip-total {
  flex-shrink: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--v-heading);
  font-variant-numeric: tabular-nums;
}
.v2l-ptip-pts-unit { font-size: 12px; font-weight: 500; color: var(--v-text-2); margin-left: 3px; }
.v2l-ptip-bar {
  display: flex;
  gap: 2px;
  height: 6px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--v-inset);
  margin-bottom: 12px;
}
.v2l-ptip-seg { display: block; min-width: 2px; border-radius: 2px; }
.v2l-ptip-divider { height: 1px; background: var(--v-border-soft); margin: 10px 0; }
.v2l-ptip-row { margin-bottom: 10px; }
.v2l-ptip-row:last-of-type { margin-bottom: 0; }
.v2l-ptip-row-top { display: flex; align-items: center; gap: 8px; }
.v2l-ptip-swatch { flex-shrink: 0; width: 8px; height: 8px; border-radius: 2px; }
.v2l-ptip-label { flex: 1 1 auto; min-width: 0; color: var(--v-text-table); }
.v2l-ptip-value { flex-shrink: 0; font-weight: 600; color: var(--v-text-bright); font-variant-numeric: tabular-nums; }
.v2l-ptip-sub {
  margin: 3px 0 0 16px;
  font-family: var(--v-font-mono);
  font-size: 11px;
  line-height: 1.4;
  color: var(--v-text-3);
  white-space: normal;
}
.v2l-ptip-daylist-head {
  font-family: var(--v-font-mono);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--v-text-3);
  margin-bottom: 6px;
}
.v2l-ptip-day-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 2px 0;
  font-family: var(--v-font-mono);
  font-size: 12px;
  color: var(--v-text-table);
  font-variant-numeric: tabular-nums;
}
.v2l-ptip-day-row > span:nth-child(2) { color: var(--v-text-3); }
.v2l-ptip-more { margin-top: 4px; font-family: var(--v-font-mono); font-size: 11px; color: var(--v-text-3); }
.v2l-ptip-footer {
  margin: 12px -16px -16px;
  padding: 12px 16px;
  border-radius: 0 0 var(--v-r-card) var(--v-r-card);
  background: var(--v-inset);
  font-size: 12px;
  line-height: 1.5;
  color: var(--v-text-2);
  white-space: normal;
}
/* Source colours (mocks 30-33): trading blue, LP amber, trade-referral
   green, LP-referral a lighter green; referral levels lighten per level. */
.v2l-ptip-seg[data-kind="trade"], .v2l-ptip-swatch[data-kind="trade"] { background: var(--v-link); }
.v2l-ptip-seg[data-kind="lp"], .v2l-ptip-swatch[data-kind="lp"] { background: var(--v-amber); }
.v2l-ptip-seg[data-kind="traderef"], .v2l-ptip-swatch[data-kind="traderef"] { background: var(--v-green); }
.v2l-ptip-seg[data-kind="lpref"], .v2l-ptip-swatch[data-kind="lpref"] { background: color-mix(in srgb, var(--v-green) 55%, white); }
.v2l-ptip-seg[data-kind="l1"], .v2l-ptip-swatch[data-kind="l1"] { background: var(--v-green); }
.v2l-ptip-seg[data-kind="l2"], .v2l-ptip-swatch[data-kind="l2"] { background: color-mix(in srgb, var(--v-green) 80%, white); }
.v2l-ptip-seg[data-kind="l3"], .v2l-ptip-swatch[data-kind="l3"] { background: color-mix(in srgb, var(--v-green) 60%, white); }
.v2l-ptip-seg[data-kind="l4"], .v2l-ptip-swatch[data-kind="l4"] { background: color-mix(in srgb, var(--v-green) 45%, white); }
.v2l-ptip-seg[data-kind="l5"], .v2l-ptip-swatch[data-kind="l5"] { background: color-mix(in srgb, var(--v-green) 30%, white); }

/* ---------- states ---------- */

.v2l-empty {
  border: 1px solid var(--v-border);
  border-radius: var(--v-r-card);
  background: var(--v-surface);
  padding: 28px 20px;
  text-align: center;
  font-size: 14px;
  color: var(--v-text-2);
}
.v2l-board .v2l-empty { border: 0; border-radius: 0; }
/* S6 P-LB-5 (desktop-neutral): inboard empty title/sub spans — sub shows on mobile only. */
.v2l-empty-title { display: block; }
.v2l-empty-sub { display: none; }
.v2l-locked {
  border: 1px solid var(--v-border);
  border-radius: var(--v-r-card);
  background: var(--v-surface);
  padding: 28px 20px;
  text-align: center;
  font-size: 14px;
  color: var(--v-text-2);
}
.v2l-loading {
  border: 1px solid var(--v-border);
  border-radius: var(--v-r-card);
  background: var(--v-surface);
  padding: 28px 20px;
  text-align: center;
  font-size: 14px;
  color: var(--v-text-3);
}
.v2l-note {
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--v-text-3);
}
/* Round 4 item 4: LP TVL's one-row notice — amber icon + "Experimental"
   label (600), the rest of the row stays the default grey .v2l-note color. */
.v2l-experimental-icon { color: var(--v-amber); vertical-align: -2px; }
.v2l-experimental-label { color: var(--v-amber); font-weight: 600; }
.v2l-formula {
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--v-text-3);
}

/* ---------- mobile (max-width 760px) — matches v2-volume.css (B12) ----------
   The table collapses to cards: one bordered row per wallet, cells stacked
   with their column label sourced from data-label. Stat grid and top-3
   cards stack; the date bar wraps. */

@media (max-width: 760px) {
  /* S6 P-LB-2: no title/subtitle overrides — desktop 30px/700 + 14.5px inherit. */
  /* F2: mobile keeps the stacked header (title/subtitle row, then snapshot). */
  .v2l-head { flex-wrap: wrap; }
  .v2l-snap { text-align: left; }
  .v2l-stats { grid-template-columns: 1fr; }
  .v2l-top3 { grid-template-columns: 1fr; }
  .v2l-datebar { align-items: stretch; flex-direction: column; }
  .v2l-bars { flex-basis: auto; }
  /* S6 P-LB-3: period pill inlines left; datebar stays column, bars auto. */
  .v2l-period { align-self: flex-start; }
  /* S6 P-LB-1/4: toolbar stacks left-aligned; venue inline, toggle + search each on their own line. */
  .v2l-toolbar { align-items: flex-start; flex-direction: column; }
  .v2l-venue-toggle { max-width: 100%; }
  .v2l-tools { align-items: flex-start; flex-direction: column; }
  .v2l-search { width: 168px; }
  /* FIX2.2: touch cards never hover — keep the copy icon visible here too. */
  .v2l-copy { opacity: 1; }
  /* S6 P-LB-6: flat list rows — hairline, 2px medal/you edge, no cards. */
  .v2l-table-wrap { overflow: visible; }
  .v2l-table thead { display: none; }
  .v2l-table, .v2l-table tbody, .v2l-row { display: block; }
  .v2l-row {
    border: 0;
    border-bottom: 1px solid var(--v-border-row);
    border-radius: 0;
    background: transparent;
    margin-bottom: 0;
    padding: 0;
  }
  .v2l-row.is-rank1 { box-shadow: inset 2px 0 0 var(--v-amber); }
  .v2l-row.is-rank2 { box-shadow: inset 2px 0 0 var(--v2l-silver); }
  .v2l-row.is-rank3 { box-shadow: inset 2px 0 0 var(--v2l-bronze); }
  .v2l-row.is-you { box-shadow: inset 2px 0 0 var(--v-blue); }
  .v2l-board { overflow: hidden; }
  .v2l-table tbody td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-bottom: 0;
    padding: 7px 14px;
    text-align: right;
  }
  .v2l-table tbody td::before {
    content: attr(data-label);
    font-family: var(--v-font-mono);
    font-size: 10px;
    letter-spacing: 1.3px;
    text-transform: uppercase;
    color: var(--v-text-3);
  }
  .v2l-share-cell { flex: 1; max-width: 200px; }
  .v2l-share { min-width: 0; }
  /* S1b F5: desktop cells hide; the row card shows L1 rank + handle +
     sorted metric, L2 share bar + pct, L3 inline MAJ / VIBE / PTS. */
  .v2l-table tbody td:not(.v2l-mcard) { display: none; }
  .v2l-table tbody td.v2l-mcard {
    display: flex;
    flex-direction: column;
    /* FIX1 verify pass 1: rows stretch full width (the generic mobile td
       centers) — L1 metric pins right, the share bar fills, L3 starts left. */
    align-items: stretch;
    gap: 10px;
    border-bottom: 0;
    padding: 13px 16px 14px;
    text-align: left;
  }
  .v2l-table tbody td.v2l-mcard::before { content: none; }
  /* LP FIX: the desktop 124px 6th-column track (volume Points) also matches
     the LP row's 6th child, which is the mobile card — release it to full
     width here. No-op for the volume board (its card is 8th child, already
     auto) and for desktop (the card stays display:none there). */
  .v2l-table tbody td.v2l-mcard { width: auto; }
  .v2l-mcard .v2l-share-cell { max-width: none; }
  /* S6 P-LB-5: inboard empty state (pad 52px 22px, 14px/600 title + 12.5px sub). */
  .v2l-board .v2l-empty {
    padding: 52px 22px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 9px;
    text-align: center;
  }
  .v2l-empty-title { font-size: 14px; font-weight: 600; color: var(--v-text-table); }
  .v2l-empty-sub { display: block; font-size: 12.5px; color: var(--v-text-3); }
  /* S6 P-LB-7: row line-1 rank reads 12.5px mono (was inheriting 13.5px body). */
  .v2l-mcard-l1 > span:first-child {
    font-family: var(--v-font-mono);
    font-size: 12.5px;
    font-weight: 500;
  }
  /* S6 P-LB-11: LP experimental note sits 8px below the switcher. */
  .v2l-note[data-testid="lp-points-experimental-note"] { margin: 8px 0 0; }
}

/* CELL-STATES (2026-09-22): every empty or odd points cell explains itself.
   Desktop additions only — the ≤760px mobile block above is untouched. */
.v2l-state-chip {
  display: inline-block;
  padding: 2px 9px;
  border: 1px solid var(--v-border);
  border-radius: 999px;
  font-family: var(--v-font-mono);
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  line-height: 1.6;
  white-space: nowrap;
}
.v2l-state-chip.is-pending { color: var(--v-text-3); }
.v2l-state-chip.is-excluded {
  color: var(--v-amber);
  border-color: color-mix(in srgb, var(--v-amber) 45%, transparent);
  background: color-mix(in srgb, var(--v-amber) 8%, transparent);
}
.v2l-how { position: relative; display: inline-block; }
.v2l-how-link {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  color: var(--v-link);
  font: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  cursor: pointer;
}
.v2l-how-link:focus-visible { outline: 2px solid var(--v-link); outline-offset: 2px; }
.v2l-how-pop {
  position: absolute;
  left: 0;
  top: calc(100% + 6px);
  z-index: 5;
  width: 312px;
  max-width: min(312px, calc(100vw - 16px));
  padding: 14px 16px;
  border: 1px solid var(--v-border);
  border-radius: var(--v-r-card);
  background: var(--v-surface);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  font-family: var(--v-font);
  font-size: 13px;
  line-height: 1.5;
  text-align: left;
}
/* D8 round 4 item 7: mock 34 — proportional sans (not mono), grey body
   (var(--v-text-2), the mock's muted grey). */
.v2l-how-row { display: block; margin-top: 8px; color: var(--v-text-2); white-space: normal; }
/* D8 round 2 C7 + round 4 item 7: mock 34 — 600-weight white title + one
   paragraph, replacing the old five-bullet quick list. */
.v2l-how-title { display: block; font-family: var(--v-font); font-size: 15px; font-weight: 600; color: var(--v-text); }

/* ---------- D8 (points leaderboard order): tab BETA chip, info tips,
   referral toolbar/share, points-tip visual additions ---------- */

.v2l-beta-chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border: 1px solid color-mix(in srgb, var(--v-amber) 45%, transparent);
  border-radius: 5px;
  font-family: var(--v-font-mono);
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--v-amber);
  vertical-align: middle;
}
.v2l-info-ico {
  display: inline-flex;
  margin-left: 5px;
  color: var(--v-text-3);
  cursor: help;
  vertical-align: -1px;
}
.v2l-info-ico:hover { color: var(--v-text-2); }
.v2l-toolbar-count {
  font-family: var(--v-font-mono);
  font-size: 12.5px;
  color: var(--v-text-2);
}
/* Referral tab: green share bars (mock 23), same shape as the default blue
   share cell — only the fill colour differs. */
.v2l-share-ref { }
.v2l-share-fill-ref { background: var(--v-green); }
/* Round 4 item 5: LP tabs (revenue + TVL) get amber share bars — desktop
   and the mobile card share this class already. */
.v2l-share-fill-lp { background: var(--v-amber); }
