/* public/styles/leaderboard.css */
.leaderboard-page{display:flex;flex-direction:column;color:var(--text-primary)}

/* Universal — strip the chat-app card chrome from .leaderboard-page on
   every leaderboard mount (anon and authed). The double-card pattern
   (page card wrapping artifact card) was decorative; the leaderboard
   is the primary view when you're on /lo-leaderboard/*, not one card
   among many, so the chrome adds noise without separating anything
   useful. */
body.has-mmi-one-shell .leaderboard-page {
  background: transparent !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin-bottom: 0 !important;
}
/* Universal — strip the inner .lb-artifact card chrome too. Source
   rule at mmi-one-shell.css:4017 wrapped the leaderboard contents in
   bg + border + rounded; with the outer page chrome gone it just
   floats orphaned. */
body.has-mmi-one-shell .lb-artifact {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  overflow: visible !important;
}
/* Authed-side carryover: the artifact-header (trophy + title chip +
   share / view-as actions) keeps its layout but loses the card-bg +
   border-bottom that was painted at mmi-one-shell.css:4025 to match
   the now-stripped wrapper. The row sits on the page bg directly,
   actions still clickable. Anon hides the whole header (hero owns
   that role) — see body.has-public-shell rule below. */
body.has-mmi-one-shell .lb-artifact-header {
  background: transparent !important;
  border-bottom: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
}
/* Universal — drop the .lb-chat-turn wrapper padding. The bubble has
   its own internal padding via .lb-chat-explanation / .message-bubble;
   the wrapper padding was redundant chrome that pushed the visible
   bubble inward by 16px. */
body.has-mmi-one-shell .lb-artifact .lb-chat-turn {
  padding: 0 !important;
}
/* Anon-only: the trophy + "Overall Leaderboard" chip is redundant
   once the hero is in place — same product framing twice. Authed
   keeps the header since they don't get a hero; the share + view-as
   actions live there. */
body.has-public-shell .lb-artifact-header { display: none; }
/* Phone-width content takeover — the outer .max-w-6xl already drops to
   8px padding at ≤768px (see styles.css:6544), but the leaderboard page
   card adds its own p-4 (16px) on top, so cards sit 24px in from each
   edge of a 390pt phone. Tighten both layers so the leaderboard reads
   nearly edge-to-edge and the LO cards have room to breathe (no more
   "Dominic H…" truncation). Outer wrapper handles its own padding
   override below; this rule shrinks the inner page card.

   Selector specificity has to beat Tailwind's p-4 utility, which is a
   single class. `.leaderboard-page.leaderboard-page` doubles the class
   for specificity without a !important arms race. */
@media (max-width: 640px) {
  .leaderboard-page.leaderboard-page { padding: 0.5rem; }
  body > .max-w-6xl { padding: 0.25rem !important; }
  /* Force a real symmetric gutter on the anon leaderboard. Earlier
     attempts relied on body padding alone but couldn't beat the
     asymmetric mmi-one-shell.css rules in every case. Layer the
     padding at body, wrapper, and the leaderboard page itself so
     content cannot end up flush to the viewport edge regardless of
     which rule wins the specificity fight at runtime. */
  /* Phone gutter — symmetric 16px on each side via body padding alone.
     Specificity chained against has-mmi-one-shell (always set
     alongside has-public-shell by mountPublicShell) so this beats
     `body.has-mmi-one-shell { padding-right: 16px }` at the same
     media query — same (0,2,1) specificity, plus mine has !important.
     The leaderboard-page itself stays unpadded on mobile so we don't
     double up the gutter. */
  body.has-tmo-brand.has-mmi-one-shell,
  body.has-public-shell.has-mmi-one-shell {
    padding-left: 16px !important;
    padding-right: 16px !important;
  }
  body.has-tmo-brand.has-mmi-one-shell > .max-w-6xl,
  body.has-public-shell.has-mmi-one-shell > .max-w-6xl {
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
}
/* Desktop: with max-width: none stripped at mmi-one-shell.css:171,
   the leaderboard column extends edge-to-edge on wide viewports which
   reads as cramped. Put the gutter on the leaderboard column itself
   (#leaderboardPage), not on .max-w-6xl, so the artifact sidebar — a
   sibling of #lbColWrapper inside the same wrapper — stays close to
   the viewport right edge like it did before this branch. */
@media (min-width: 640px) {
  body.has-tmo-brand #leaderboardPage.leaderboard-page {
    padding-left: 24px !important;
    padding-right: 24px !important;
  }
}
@media (min-width: 1024px) {
  body.has-tmo-brand #leaderboardPage.leaderboard-page {
    padding-left: 48px !important;
    padding-right: 48px !important;
  }
}
/* Outer gutter on the column wrapper so the leaderboard card's left
   edge isn't glued to the gnav rail. Applied to #lbColWrapper (not
   .max-w-6xl) so the artifact sidebar — a row sibling of the wrapper
   — keeps hugging the viewport right edge, preserving the design
   intent documented at lines 89-94. Scoped to leaderboard-view-active
   so it covers both the anon bundle (which also sets has-tmo-brand)
   and the authenticated app's leaderboard view (which doesn't). */
@media (min-width: 640px) {
  body.leaderboard-view-active #lbColWrapper {
    margin-left: 16px;
  }
}
/* Dossier-continuation mode (View Full Profile from a leaderboard row):
   let the column wrapper scroll as one unit instead of each card having its
   own scroll — otherwise flex-1 splits height 50/50 with a double scrollbar. */
body.leaderboard-dossier-mode #leaderboardPage{flex:none!important;overflow:visible!important}
body.leaderboard-dossier-mode #messagesContainer{flex:none!important;overflow:visible!important}
body.leaderboard-dossier-mode #lbColWrapper{overflow-y:auto}
/* Same layout treatment for synthetic roster lists (Top LOs at <lender> /
   Top Agents at <office>) when the user asks a question via the message
   box and the response renders in the chat stream below the roster. */
body.roster-question-mode #pinnedPage{flex:none!important;overflow:visible!important}
body.roster-question-mode #messagesContainer{flex:none!important;overflow:visible!important}
body.roster-question-mode #rosterColWrapper{overflow-y:auto}
.lb-controls{display:flex;flex-wrap:wrap;gap:1rem;align-items:center;margin-bottom:1rem;padding-bottom:1rem;border-bottom:1px solid var(--border-secondary)}
/* Universal — strip the filter row's card-bg now that the surrounding
   chrome is gone (was set at mmi-one-shell.css:4118 with bg +
   border-bottom + 12/16 padding to match the artifact card; without
   that card it reads as an unanchored gray bar mid-page). Keep a
   hairline bottom rule on desktop so the tabs-left-controls-right
   layout reads as a contained toolbar instead of two floating
   element groups. Mobile stays borderless. */
body.has-mmi-one-shell .lb-artifact .lb-controls,
body.has-mmi-one-shell .lb-controls {
  background: transparent !important;
  border-bottom: 1px solid hsl(var(--border) / 0.5) !important;
  padding: 4px 0 12px !important;
  margin-bottom: 0.75rem;
}
/* Control-collapse breakpoint (860px). The entity toggle + 4 category tabs
   stop fitting one row around ~830px, so the desktop bar wraps to 3 rows below
   that — collapse to the mobile category-select + Filters-button treatment
   before it gets there. Keep this in sync with the two control queries below
   (the layout flip + spacing); the page-gutter queries stay at 640px. */
@media (max-width: 860px) {
  body.has-mmi-one-shell .lb-artifact .lb-controls,
  body.has-mmi-one-shell .lb-controls {
    border-bottom: 0 !important;
    padding: 0 0 0.75rem !important;
  }
}
/* Phone-only: 1rem padding-bottom + 1rem margin-bottom = 32px of dead air
   below the filter row before the first card. Halve it; the divider
   line still reads as a separator at the tighter spacing. */
@media (max-width: 860px) {
  .lb-controls { gap: .5rem; margin-bottom: .5rem; padding-bottom: .5rem; }
  body.has-public-shell .lb-controls { margin-bottom: .5rem; }
}
.lb-categories{display:flex;flex-wrap:wrap;gap:.5rem}
.lb-category-btn{padding:.55rem 1rem;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border-secondary);border-radius:8px;cursor:pointer;font-size:.9rem;font-weight:500;transition:all .15s}
.lb-category-btn:hover{background:var(--bg-quaternary);color:var(--text-primary)}
.lb-category-btn--active{background:hsl(var(--primary));color:#fff;border-color:hsl(var(--primary))}
/* Bonzo/Datacenter/Elevate/Hiddenthings themes apply a blanket
   "button:not(.opp-card-why-toggle)" override at specificity (0,2,1) with
   !important, which wipes out the accent. Match that specificity (button +
   two classes) and !important so the accent wins at runtime. */
.leaderboard-page button.lb-category-btn.lb-category-btn--active{background:hsl(var(--primary)) !important;color:#fff !important;border-color:hsl(var(--primary)) !important}
.lb-mobile-only { display: none; }
.lb-filters{display:flex;gap:.5rem;align-items:center;margin-left:auto;flex-wrap:wrap}
@media (max-width: 860px) {
  /* Mobile: category <select> fills width, Filters icon button auto-width
     to its right, sort segmented moves inside the panel below. */
  .lb-categories { display: none; }
  .lb-controls > .lb-mobile-only { display: block; flex: 1 1 auto; min-width: 0; }
  .lb-controls > .lb-filters-toggle { flex: 0 0 auto; }
  /* Native <select>s render taller than a button group with matching padding,
     so stretch the entity toggle to the row's height (driven by the category
     <select> beside it) and vertically center the labels. Guarantees the
     heights line up without hard-coding a pixel value. */
  .lb-controls > .lb-entity-toggle { align-self: stretch; }
  .lb-entity-toggle .lb-segment { display: flex; align-items: center; }
  .lb-filters { display: none; }
  .lb-filters.lb-filters--open {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: .65rem;
    flex-basis: 100%;
    padding-top: .5rem;
  }
}
.lb-state-select{padding:.5rem .75rem;background:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-secondary);border-radius:6px;font-size:.9rem;cursor:pointer}
.lb-segmented{display:inline-flex;border:1px solid var(--border-secondary);border-radius:6px;overflow:hidden;background:var(--bg-tertiary)}
.lb-segment{padding:.5rem .85rem;background:transparent;color:var(--text-secondary);border:none;cursor:pointer;font-size:.85rem;font-weight:500;font-family:inherit;transition:background .12s,color .12s}
.lb-segment:hover:not(.lb-segment--active){background:var(--bg-quaternary);color:var(--text-primary)}
.lb-segment--active{background:hsl(var(--primary));color:#fff}
.lb-segment + .lb-segment{border-left:1px solid var(--border-secondary)}
.lb-segmented--disabled{opacity:.55;pointer-events:none}
/* Entity toggle (Loan Officers | Lenders) is a peer of the category buttons on
   desktop and sits beside the filter <select>s on mobile. The base .lb-segment
   (.85rem / .5rem padding) renders shorter than those neighbors, so match the
   category-button box here — scoped to the entity toggle so the in-panel sort
   toggle keeps its compact size. */
.lb-entity-toggle{border-radius:8px}
.lb-entity-toggle .lb-segment{padding:.55rem .9rem;font-size:.9rem}
.lb-share-btn{display:inline-flex;align-items:center;gap:.45rem;padding:.5rem .85rem;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border-secondary);border-radius:6px;font-size:.85rem;font-weight:500;cursor:pointer;transition:background .12s,color .12s,border-color .12s}
.lb-share-btn:hover{background:var(--bg-quaternary);color:var(--text-primary);border-color:hsl(var(--primary))}
.lb-share-btn--copied{background:hsl(var(--primary));color:#fff;border-color:hsl(var(--primary))}
.lb-share-btn--copied svg{color:#fff}
/* Themes with a blanket button:not(...) override need extra specificity to
   keep the active segment's accent color. Matches the category-btn pattern. */
.lb-segmented button.lb-segment.lb-segment--active{background:hsl(var(--primary))!important;color:#fff!important}
.lb-results{flex:1}
.lb-chat-turn{display:flex;flex-direction:column;gap:1rem;max-width:100%}
.lb-chat-assistant{align-self:stretch}
.lb-chat-answer{animation:lbFadeIn .22s ease-out}
.lb-debug-sql-row{display:flex;justify-content:flex-end;padding:.75rem 0 0}
.lb-view-sql-btn{display:inline-flex;align-items:center;gap:.4rem;padding:.35rem .7rem;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border-secondary);border-radius:6px;cursor:pointer;font-size:.8rem}
.lb-view-sql-btn:hover{background:var(--bg-quaternary);color:var(--text-primary)}
.lb-view-sql-btn svg{width:14px;height:14px}
@keyframes lbFadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}
.lb-table tbody tr.lb-row{animation:lbRowIn .28s ease-out both;animation-delay:calc(var(--lb-row-idx,0) * 18ms)}
@keyframes lbRowIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}
.lb-table{width:100%;border-collapse:collapse;font-size:.9rem}
.lb-table thead th{text-align:left;padding:.75rem .9rem;border-bottom:1px solid var(--border-secondary);color:var(--text-muted);font-weight:600;font-size:.78rem;letter-spacing:.04em;text-transform:uppercase}
.lb-table tbody tr{cursor:pointer;transition:background .12s}
/* Scope hover to pointer devices. Without this, iOS Safari treats the
   first tap as a hover-reveal and only fires the click on the second
   tap — making every leaderboard card require two taps to open. */
@media (hover:hover){.lb-table tbody tr:hover{background:var(--bg-tertiary)}}
.lb-table tbody td{padding:.75rem .9rem;border-bottom:1px solid var(--border-secondary)}
.lb-col-rank{width:3rem;color:var(--text-muted);font-variant-numeric:tabular-nums;font-weight:600;text-align:center}
.lb-table thead th.lb-col-rank{text-align:center}
.lb-rank-medal{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border-radius:50%;color:#0b1220;font-weight:700;font-size:.82rem;line-height:1}
.lb-rank-medal--1{background:linear-gradient(135deg,#facc15 0%,#d4a017 100%)}
.lb-rank-medal--2{background:linear-gradient(135deg,#e5e7eb 0%,#9ca3af 100%)}
.lb-rank-medal--3{background:linear-gradient(135deg,#f2a468 0%,#b45309 100%);color:#fff}
.lb-col-metric{text-align:right;font-variant-numeric:tabular-nums;color:var(--text-secondary)}
.lb-col-metric--active{color:var(--text-primary);font-weight:600}
.lb-col-climb{white-space:nowrap;line-height:1.25}
.lb-climb{color:#22c55e;font-weight:600;font-variant-numeric:tabular-nums;font-size:.9rem}
.lb-climb-range{color:var(--text-muted);font-size:.72rem;font-variant-numeric:tabular-nums;margin-top:2px}
.lb-retention-rate{color:#22c55e;font-weight:600}
.lb-col-trend{width:120px;padding-left:.9rem}
.lb-sparkline{display:flex;align-items:flex-end;gap:2px;height:28px;width:100%}
.lb-sparkline-empty{color:var(--text-muted);font-size:.8rem}
.lb-col-name{font-weight:500}
.lb-my-rank-callout{display:inline;padding:0;margin:0;color:hsl(var(--primary));font-weight:700;font-size:inherit;font-family:inherit;line-height:inherit;cursor:pointer;text-decoration:underline;text-decoration-color:rgba(59,130,246,.35);text-underline-offset:3px;transition:color .12s,text-decoration-color .12s}
.lb-my-rank-callout:hover{color:#60a5fa;text-decoration-color:#60a5fa}
/* Theme files ship a blanket `.<theme> button:not(...){border:1px solid !important}`
   at specificity (0,2,1). The `body.leaderboard-view-active button.<class>`
   selector below is (0,2,2), so it wins regardless of source order. */
body.leaderboard-view-active button.lb-my-rank-callout{background:none !important;border:none !important;outline:none !important;box-shadow:none !important}
body.leaderboard-view-active button.lb-my-rank-callout:focus,
body.leaderboard-view-active button.lb-my-rank-callout:focus-visible{outline:none !important;box-shadow:none !important;border:none !important}
.lb-row--flash{animation:lbRowHighlightPulse 1.6s ease-out 1}
.lb-row--active{background:var(--bg-quaternary)!important}
.lb-row--highlight{background:var(--bg-quaternary)!important;box-shadow:inset 3px 0 0 0 hsl(var(--primary));animation:lbRowHighlightPulse 1.6s ease-out 1}
@keyframes lbRowHighlightPulse{0%{background:rgba(59,130,246,.18)}100%{background:var(--bg-quaternary)}}
.lb-row--you{background:rgba(59,130,246,.08)!important;box-shadow:inset 3px 0 0 0 hsl(var(--primary))}
.lb-row--pinned td{border-top:1px solid var(--border-secondary)}
.lb-row--pinned{position:sticky;bottom:0;background:rgba(30,41,59,.96)!important;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:2}
.lb-row--pinned.lb-row--you{box-shadow:inset 3px 0 0 0 hsl(var(--primary)),0 -4px 12px rgba(0,0,0,.18)}
.lb-you-badge{display:inline-flex;align-items:center;padding:.1rem .45rem;margin-left:.4rem;background:hsl(var(--primary));color:#fff;border-radius:999px;font-size:.65rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
/* Shared-with-you row — injected at the top when an anon viewer arrives on
   a board via a spotlight share for an LO beyond top 50. Mirrors the you-row
   visual language but in green (distinct from the user's own row) and sticks
   to the top of the table since the visitor came specifically to see this LO. */
.lb-row--shared{background:rgba(16,185,129,.08)!important;box-shadow:inset 3px 0 0 0 #10b981}
.lb-row--pinned.lb-row--shared{top:0;bottom:auto;box-shadow:inset 3px 0 0 0 #10b981,0 4px 12px rgba(0,0,0,.18)}
.lb-shared-badge{display:inline-flex;align-items:center;padding:.1rem .45rem;margin-left:.4rem;background:#10b981;color:#fff;border-radius:999px;font-size:.65rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.lb-col-share{width:36px;text-align:center;padding:0 .25rem!important}
/* Inline company under the name is mobile-card-only; on desktop the
   standalone .lb-col-company column carries the value. */
.lb-name-company-inline { display: none; }

/* Anon-only welcome-style hero — bold display title with a Bonzo-pink
   accent on the "ranked nightly" phrase (mirrors the chat surface's
   "Ask the mortgage market anything" pattern where pink hooks the
   defining word). Tiny inline "Updated …" timestamp below the hint
   reads as text, not chrome — no pill, no border. Mirrors the
   .mmi-shell__welcome-* visual without reusing those selectors so
   styling stays leaderboard-local. */
.lb-hero {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 24px 0 20px;
  text-align: left;
}
/* Row holding the H1 + share button — H1 fills the row, share sits
   top-right. Visitors who want to share the current filtered view
   (e.g. "Top rookies in Michigan by units, 2026") get a single
   obvious affordance; click delegates to `data-lb-action="share"`
   which routes to the existing #lbShareHeaderBtn via _bindEvents. */
.lb-hero__row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.lb-hero__share {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  padding: 7px 12px;
  background: hsl(var(--secondary) / 0.4);
  border: 1px solid hsl(var(--foreground) / 0.18);
  border-radius: 999px;
  color: hsl(var(--foreground));
  font: 600 12.5px/1 'Inter', sans-serif;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.lb-hero__share:hover {
  background: hsl(var(--secondary));
  border-color: hsl(var(--foreground) / 0.4);
}
.lb-hero__share svg { flex-shrink: 0; }
/* On phones the H1 wraps to 2 lines and the share button label is
   the first thing pushed off — collapse to icon-only at ≤640. */
@media (max-width: 640px) {
  .lb-hero__share { padding: 8px; }
  .lb-hero__share-label { display: none; }
}

.lb-hero__title {
  font: 700 28px/1.18 'Inter', sans-serif;
  letter-spacing: -0.02em;
  margin: 0;
  color: hsl(var(--foreground));
}
/* Bonzo brand pink — same HSL the auth landing uses for its "anything"
   accent (mmi-one-shell.css:2828). Hardcoded so the marketing color
   stays consistent across light / dark / hidden-things themes. */
.lb-hero__title-accent {
  color: hsl(330 78% 56%);
  font-weight: 700;
}
/* Single supporting line — freshness + dataset attribution combined
   with middot separators. Replaces the prior 3-row hint+refresh stack
   that read as jumbled on desktop. */
.lb-hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font: 400 13px/1.4 'Inter', sans-serif;
  color: hsl(var(--muted-foreground));
  margin: 0;
}
.lb-hero__meta-icon {
  display: inline-flex;
  color: hsl(330 78% 56%);
  flex-shrink: 0;
}
.lb-hero__meta-sep { color: hsl(var(--muted-foreground) / 0.5); }
/* "MMI mortgage origination data" → mmi.io. Foreground color (white on
   dark theme) for base and :visited so the link doesn't flip between
   muted-gray (unvisited) and white (visited). Subtle underline keeps
   the link affordance without competing with the H1. */
.lb-hero__meta-link,
.lb-hero__meta-link:visited {
  color: hsl(var(--foreground));
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: hsl(var(--foreground) / 0.5);
  transition: text-decoration-color 120ms ease;
}
.lb-hero__meta-link:hover {
  text-decoration-color: hsl(var(--foreground));
}
@media (max-width: 640px) {
  .lb-hero { padding: 16px 0 14px; gap: 8px; }
  .lb-hero__title { font-size: 22px; line-height: 1.22; }
  .lb-hero__meta { font-size: 12px; gap: 4px; }
}

/* Anon-only header treatment: bigger title + filter-aware subtitle + a
   trust-chip row of brand stats. Authed users keep the compact existing
   header (no overrides applied). */
.lb-artifact--anon .lb-artifact-title {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  row-gap: .15rem;
  column-gap: .65rem;
}
.lb-artifact--anon .lb-artifact-name {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -.01em;
}
.lb-artifact--anon .lb-anon-subtitle {
  flex-basis: 100%;
  margin: .15rem 0 0;
  padding: 0;
  color: var(--text-secondary);
  font-size: .9rem;
  line-height: 1.45;
}

.lb-trust-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  padding: 6px 4px 10px;
  /* No border-top — `.lb-artifact-header` already supplies a `border-bottom`
     in mmi-one-shell.css. Stacking both showed as a slightly-thicker double
     line, more visible in anon mode where this row sits between header and
     controls. */
}
.lb-trust-chip {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .7rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-secondary);
  border-radius: 999px;
  color: var(--text-secondary);
  font-size: .8rem;
  white-space: nowrap;
}
.lb-trust-chip__icon { flex-shrink: 0; color: hsl(var(--primary)); opacity: .85; }
.lb-trust-chip--brand {
  background: transparent;
  border: 0;
  padding-left: 0;
}
.lb-trust-chip__link {
  color: hsl(var(--primary)) !important;
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 600;
}
.lb-trust-chip__link:hover { text-decoration-thickness: 2px; }

/* Trust chips fully hidden on the anon surface — they restate the
   hero hint ("From MMI's mortgage origination dataset — 25 years of
   records across 3,000+ counties.") almost verbatim, so stacking the
   two created a redundancy that read as visual noise on desktop and
   pushed the filter row down. The hint carries the credibility
   signal; chips don't add new info. Authed users still get the chips
   (they don't get a hero). */
body.has-public-shell .lb-trust-chips { display: none; }
@media (max-width: 640px) { .lb-trust-chips { display: none; } }

/* Inactive category tabs ("Leading Rookies", "Biggest Climbers",
   "Retention Champions") were `background: transparent + border: 0`
   under the authed shell (mmi-one-shell.css:4516), which read as static
   text labels next to the filled-primary "Overall" pill on the anon
   landing — visitors had no signal these are clickable tabs. Give them
   an outlined-chip treatment so they read as a segmented control: same
   border/radius across all four tabs, active fills primary, inactive
   stays subtle. Applies to both anon and authed users — both share
   the same "is this clickable?" problem with the bare-text look.
   Selector includes `button` so specificity (0,2,2) matches the
   source rule and source order (this file loads later) wins. */
body.has-mmi-one-shell button.lb-category-btn {
  background: hsl(var(--secondary) / 0.4) !important;
  border: 1px solid hsl(var(--foreground) / 0.18) !important;
  color: hsl(var(--foreground)) !important;
}
body.has-mmi-one-shell button.lb-category-btn:hover {
  background: hsl(var(--secondary)) !important;
  border-color: hsl(var(--foreground) / 0.4) !important;
}
body.has-mmi-one-shell button.lb-category-btn.lb-category-btn--active {
  border-color: hsl(var(--primary)) !important;
}

/* (Composer pill width-cap rule deleted — #inputBar is now hidden for
   the anon leaderboard via `body.has-tmo-brand #inputBar { display: none }`
   so the inner pill geometry doesn't matter.) */

/* Mobile: hide the meta breadcrumb under the anon title (the subtitle and
   trust chip cover what it conveys, and on small screens the extra line
   makes the header feel cluttered). */
@media (max-width: 640px) {
  .lb-artifact--anon .lb-artifact-meta { display: none; }
}

/* Filters toggle — collapses the 3 selects on mobile into a single button
   with a count of non-default filters. Sort segmented stays visible. */
.lb-filters-toggle {
  display: none;
  align-items: center;
  gap: .35rem;
  padding: .45rem .75rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-secondary);
  border-radius: 8px;
  color: var(--text-primary);
  font-size: .9rem;
  font-weight: 500;
  cursor: pointer;
}
.lb-filters-toggle:hover { background: var(--bg-quaternary); }
.lb-filters-toggle__count { color: var(--text-tertiary); font-weight: 400; }
/* 860px — control-collapse breakpoint (see note above). Must match the layout
   flip; otherwise the tabs hide but the Filters button never appears. */
@media (max-width: 860px) {
  .lb-filters-toggle { display: inline-flex; }
}

.lb-row-share-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;background:transparent;color:var(--text-muted);border:1px solid transparent;border-radius:6px;cursor:pointer;transition:background .12s,color .12s,border-color .12s,opacity .12s;opacity:0}
.lb-row:hover .lb-row-share-btn,.lb-row--highlight .lb-row-share-btn,.lb-row--you .lb-row-share-btn,.lb-row--shared .lb-row-share-btn{opacity:1}
.lb-row-share-btn:hover{background:var(--bg-tertiary);color:var(--text-primary);border-color:hsl(var(--primary))}
@media (max-width:540px){.lb-col-share{display:none}}
/* Share-preview modal — backdrop + card + preview image + actions row */
.lb-share-preview-backdrop{position:fixed;inset:0;background:rgba(8,12,22,.7);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:1000;animation:lbModalFade .12s ease-out}
@keyframes lbModalFade{from{opacity:0}to{opacity:1}}
.lb-share-preview{position:relative;background:var(--bg-secondary);border:1px solid var(--border-secondary);border-radius:14px;padding:1.25rem;width:min(640px,calc(100vw - 2rem));max-height:calc(100vh - 2rem);overflow:auto;color:var(--text-primary);box-shadow:0 20px 60px -10px rgba(0,0,0,.6);animation:lbModalRise .14s ease-out}
@keyframes lbModalRise{from{transform:translateY(8px);opacity:0}to{transform:translateY(0);opacity:1}}
.lb-share-preview-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.85rem}
.lb-share-preview-title{font-size:1rem;font-weight:600;margin:0}
.lb-share-preview-close{background:transparent;border:none;color:var(--text-muted);width:1.75rem;height:1.75rem;border-radius:6px;cursor:pointer;font-size:1.3rem;line-height:1;display:flex;align-items:center;justify-content:center}
.lb-share-preview-close:hover{background:var(--bg-tertiary);color:var(--text-primary)}
.lb-share-preview-card{position:relative;border:1px solid var(--border-secondary);border-radius:10px;overflow:hidden;background:var(--bg-tertiary);aspect-ratio:1200/630;margin-bottom:.85rem}
.lb-share-preview-card img{width:100%;height:100%;display:block;object-fit:cover;opacity:0;transition:opacity .5s ease-out}
/* Match the "Key Insights" dashboard-summary-shimmer loading pulse byte-
   for-byte: solid `hsl(var(--secondary))` base + transparent-highlight
   gradient using `hsl(var(--foreground) / 0.18)`, 1.6s linear sweep. The
   previous --bg-tertiary / --bg-quaternary palette was too close in shade
   for the highlight to read, so the pulse looked flat. Falls back to the
   legacy --bg-* tokens for any non-shell host (mmi-one-tokens.css
   maps --bg-tertiary onto hsl(var(--secondary)) on the shell anyway, so
   the visible result matches Key Insights on every theme). */
.lb-share-preview-skeleton{position:absolute;inset:0;background-color:hsl(var(--secondary, 217 33% 20%));background-image:linear-gradient(90deg,transparent 0%,hsl(var(--foreground, 210 40% 98%) / 0.18) 50%,transparent 100%);background-size:200% 100%;background-repeat:no-repeat;animation:skeleton-shimmer 1.6s linear infinite;opacity:1;transition:opacity .35s ease-out}
.lb-share-preview-card--ready img{opacity:1}
.lb-share-preview-card--ready .lb-share-preview-skeleton{opacity:0;pointer-events:none}
.lb-share-preview-url{display:flex;gap:.5rem;margin-bottom:.85rem}
.lb-share-preview-url input{flex:1;padding:.5rem .75rem;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border-secondary);border-radius:6px;font-size:.85rem;font-family:inherit}
.lb-share-preview-copy{padding:.5rem 1rem;background:hsl(var(--primary));color:#fff;border:none;border-radius:6px;cursor:pointer;font-weight:500;font-size:.85rem;font-family:inherit;transition:background .12s}
.lb-share-preview-copy:hover{background:var(--accent-primary-hover,#2563eb)}
.lb-share-preview-copy--ok{background:#16a34a}
.lb-share-preview-networks{display:flex;gap:.5rem;flex-wrap:wrap}
.lb-share-network-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:.55rem .85rem;color:#fff;border:1px solid transparent;border-radius:8px;cursor:pointer;font-size:.85rem;font-weight:500;font-family:inherit;transition:filter .12s,box-shadow .12s}
/* Specificity (0,2,2) beats every theme's `.<theme> button:not(...){...!important}`
   blanket rule (0,2,1). Without this, themes overwrite the network color with
   their generic button background. */
body.leaderboard-view-active button.lb-share-network-btn{color:#fff !important;border:1px solid transparent !important}
body.leaderboard-view-active button.lb-share-network-btn:hover{filter:brightness(1.08);box-shadow:0 2px 6px rgba(0,0,0,.18)}
body.leaderboard-view-active button.lb-share-network-btn--linkedin{background:#0a66c2 !important}
body.leaderboard-view-active button.lb-share-network-btn--twitter{background:#000 !important}
body.leaderboard-view-active button.lb-share-network-btn--facebook{background:#1877f2 !important}
.lb-view-as-btn{display:inline-flex;align-items:center;gap:.4rem}
.lb-view-as-btn--active{background:hsl(var(--primary));color:#fff;border-color:hsl(var(--primary))}
.lb-view-as-btn--active:hover{background:var(--accent-primary-hover,#2563eb)}
/* Idle state: eye icon only — label is hidden until staff actually start
   impersonating. When active, label flips on so the staff member can see
   which NMLS they're viewing as ("Viewing as #1234"). */
.lb-view-as-btn .lb-view-as-label{display:none}
.lb-view-as-btn--active .lb-view-as-label{display:inline}
.lb-view-as-dialog{width:min(420px,calc(100vw - 2rem))}
.lb-view-as-hint{margin:0 0 .75rem;color:var(--text-muted);font-size:.85rem;line-height:1.4}
.lb-view-as-form{display:flex;gap:.5rem;margin-bottom:.75rem}
.lb-view-as-input{flex:1;padding:.5rem .75rem;background:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-secondary);border-radius:6px;font-size:.9rem;font-family:inherit}
.lb-view-as-input:focus{outline:none;border-color:hsl(var(--primary))}
.lb-view-as-clear{display:block;width:100%;padding:.5rem;background:transparent;color:var(--text-muted);border:1px solid var(--border-secondary);border-radius:6px;cursor:pointer;font-size:.85rem;font-family:inherit;transition:background .12s,color .12s}
.lb-view-as-clear:hover{background:var(--bg-tertiary);color:var(--text-primary)}
.lb-empty{padding:2.5rem;text-align:center;color:var(--text-muted);font-size:.95rem}
/* Clickable company name in any row — visually a link, behaves as a filter
   trigger. Hover lifts the underline + accent color so users discover the
   affordance. Inherits font/size from the cell so the table layout doesn't
   shift when a row swaps from plain text to a button. */
.lb-col-company-link{padding:0;margin:0;color:inherit;font:inherit;cursor:pointer;text-align:left;text-decoration:none;transition:color .12s}
/* Same specificity-bump pattern as .lb-my-rank-callout — beats the
   `.<theme> button:not(...){border:!important}` rules that ship in every
   theme. Hover state forces a dashed under-rule via border-bottom (set in
   the bumped rule below so the !important + specificity both win). */
body.leaderboard-view-active button.lb-col-company-link{background:none !important;border:none !important;outline:none !important;box-shadow:none !important}
body.leaderboard-view-active button.lb-col-company-link:hover{color:hsl(var(--primary)) !important;border-bottom:1px dashed hsl(var(--primary)) !important}
body.leaderboard-view-active button.lb-col-company-link:focus,
body.leaderboard-view-active button.lb-col-company-link:focus-visible{outline:none !important;box-shadow:none !important;border:none !important}
/* "Filtered: <Company> ×" notice rendered above the table whenever the
   company filter is active. Muted background + accent border so it reads
   as scope context, not a primary action. Bigger than the inline .lb-you-
   badge — it's a top-of-table notice. */
.lb-filter-banner{display:inline-flex;align-items:center;gap:.5rem;margin:0 0 .85rem;padding:.45rem .75rem;background:rgba(59,130,246,.08);color:var(--text-primary);border:1px solid rgba(59,130,246,.4);border-radius:999px;font-size:.85rem}
.lb-filter-banner-label{color:var(--text-muted);font-weight:500}
.lb-filter-banner-value{color:var(--text-primary);font-weight:600}
.lb-filter-banner-clear{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;background:transparent;color:var(--text-muted);border:none;border-radius:50%;cursor:pointer;font-size:1rem;line-height:1;font-family:inherit;transition:background .12s,color .12s}
.lb-filter-banner-clear:hover{background:var(--bg-tertiary);color:var(--text-primary)}
/* Pin glyph beside the city is only shown in the mobile card layout
   below — hide it in the desktop table. */
.lb-loc-pin { display:none }
/* Progressive column drop on narrow viewports — hide in this order so the
   #/Name/Volume/Units columns (the rank story) survive longest. Retention
   rate has its own class and stays visible even on narrow widths since it's
   the headline metric for that category. */
@media (max-width:1100px){.lb-table .lb-col-loc{display:none}}
@media (max-width:900px){.lb-table .lb-col-avg{display:none}}
@media (max-width:700px){.lb-table .lb-col-company{display:none}}
@media (max-width:540px){.lb-table .lb-col-trend{display:none}}
/* Phone-width: ditch the table layout entirely and render each row as a
   self-contained card. Avoids horizontal scroll, preserves sticky on
   pinned rows (the rows are now block-flow, not table-row), and gives
   the columns we restored more breathing room. Source of truth for the
   markup is still <table>, so screen readers see proper row semantics
   above the visual reshape. */
@media (max-width:540px) {
  .lb-table { display:block; width:100% }
  .lb-table thead { display:none }
  .lb-table tbody { display:block }
  /* Flex + order + wrap lays each tr out as a multi-line card. Each
     direct-child <td> is one flex item; lines are formed by setting
     flex-basis:100% on the items that should start a new line and
     leaving the rest as auto-width so they flow inline. */
  .lb-table tbody tr.lb-row {
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    column-gap:.6rem;
    row-gap:.55rem;
    background:var(--bg-secondary);
    border:1px solid var(--border-secondary);
    border-radius:10px;
    /* 4px left stripe + 8px (.5rem) padding-left = 12px content offset,
       matching the hero's 12px padding-left and the .lb-state-select
       dropdown's 12px text inset. Vertical padding stays .85rem so the
       card still breathes. */
    padding:.85rem .85rem .85rem .5rem;
    margin-bottom:.6rem;
  }
  .lb-table tbody td { border:none; padding:0; text-align:left; }
  /* Strip cell borders + text decoration in card mode. Has to match the
     theme override at mmi-one-shell.css:4193 which sets
     `body.has-mmi-one-shell .lb-table tbody td { border-bottom: 1px solid ... !important }`
     at specificity (0,2,2) — without the body.has-mmi-one-shell prefix
     here our rule loses despite being later in source order. */
  body.has-mmi-one-shell .lb-table tbody td,
  .lb-table tbody td,
  .lb-table tbody td *,
  .lb-table tbody td *::before,
  .lb-table tbody td *::after {
    text-decoration:none !important;
    border-bottom:none !important;
  }
  /* Larger profile avatar to anchor the card as a person, not a row. */
  .lb-table .lb-name-cell .lb-avatar {
    width:2.75rem;
    height:2.75rem;
  }
  /* Smaller rounded-rect rank badge (vs the previous larger circle) so
     it sits flush with the avatar rather than competing with it. */
  .lb-table .lb-rank-medal {
    width:1.75rem;
    height:1.75rem;
    border-radius:6px;
    font-size:.85rem;
  }

  /* Line 1: rank · name (grows) · share, all vertically centered. */
  .lb-table .lb-col-rank {
    flex:0 0 auto;
    width:auto;
    min-width:1.75rem;
    font-size:1rem;
    font-weight:600;
    order:1;
    text-align:center;
    align-self:center;
  }
  /* Constrain name so a long string truncates with an ellipsis instead
     of wrapping and pushing the share button to a new line. */
  .lb-table .lb-col-name {
    flex:1 1 0;
    min-width:0;
    overflow:hidden;
    font-weight:600;
    font-size:.95rem;
    order:2;
  }
  .lb-table .lb-name-cell { min-width:0 }
  /* Truncate only the name span itself, not the pinned "You" / "Shared
     with you" badges that also live inside .lb-name-cell. */
  .lb-table .lb-name-cell > span:not(.lb-you-badge):not(.lb-shared-badge) {
    flex:1 1 auto;
    min-width:0;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
  }
  .lb-table .lb-col-share {
    display:inline-block !important;
    flex:0 0 auto;
    width:auto;
    order:3;
    align-self:flex-start;
  }
  /* Share button on mobile: visible bordered box (no hover-only opacity),
     anchored to the top-right corner of the card via the flex-shrink:0
     above + align-self:flex-start. */
  .lb-table .lb-row .lb-row-share-btn {
    opacity:1 !important;
    width:36px !important;
    height:36px !important;
    background:rgba(255,255,255,.04) !important;
    border:1px solid var(--border-secondary) !important;
    border-radius:8px;
    color:var(--text-secondary) !important;
  }
  /* Line 2 (was): company used to live on its own row. Now stacked
     under the LO name in the name cell (.lb-name-company-inline) to
     reclaim a row of vertical space per card. Standalone column
     stays in the DOM for desktop tables; hide it here. */
  .lb-table .lb-col-company { display: none !important; }
  /* Name cell becomes a flex row of [avatar | name + company stacked].
     Both name and company truncate with ellipsis so a long lender
     name doesn't break the share button position. */
  .lb-table .lb-col-name .lb-name-stack {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    gap: 1px;
  }
  .lb-table .lb-col-name .lb-name-text {
    font-weight: 600;
    line-height: 1.15;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .lb-table .lb-col-name .lb-name-company-inline {
    display: block;
    font-size: .72rem;
    color: var(--text-muted);
    line-height: 1.15;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Line 3: location on its own line with a small pin glyph (override the
     <1100px hide). Pin is visible only here, not in the desktop table. */
  .lb-table .lb-col-loc {
    display:flex !important;
    align-items:center;
    flex:0 0 100%;
    font-size:.75rem;
    color:var(--text-muted);
    opacity:.85;
    order:5;
  }
  /* Restore the pin glyph in card mode (global rule above hides it for
     the desktop table). */
  .lb-table .lb-col-loc .lb-loc-pin {
    display:inline-flex !important;
    flex:0 0 auto;
    margin-right:.3rem;
    color:var(--text-muted);
  }
  /* Metrics row — hero (active sort) sits inline with the supporting
     metrics on a single row instead of taking its own line. Hero stays
     visually dominant via bolder/bigger font; supporting numbers read
     as quieter siblings. Climber category's rank-change cell joins the
     row so all four templates (overall, rookie, climbers, retention)
     show three side-by-side metric blocks: hero + 2 supports. */
  .lb-table .lb-col-metric.lb-col-metric--active {
    display:flex !important;
    flex-direction:column !important;
    align-items:flex-start;
    flex:0 0 auto;
    order:7;
    gap:.15rem;
    margin:.6rem 1.25rem 0 0;
    font-size:1.35rem;
    font-weight:800;
    font-variant-numeric:tabular-nums;
    line-height:1.1;
    color:var(--text-primary);
  }
  .lb-table .lb-col-metric.lb-col-metric--active::before {
    content:attr(data-label);
    order:-1;
    font-size:.6rem;
    font-weight:700;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
  }
  .lb-table .lb-col-metric.lb-col-metric--active::after { content:none }

  /* Supporting metrics — same row as the hero, smaller font + lighter
     weight. order:7 (matching the hero) so the source order Volume →
     Loans → (Avg|Retention) maps directly onto the visual order. */
  .lb-table .lb-col-metric:not(.lb-col-metric--active),
  .lb-table .lb-col-avg:not(.lb-col-metric--active) {
    display:flex !important;
    flex-direction:column;
    flex:0 0 auto;
    order:7;
    margin:.6rem 1.25rem 0 0;
    padding:0;
    font-size:1rem;
    font-weight:600;
    font-variant-numeric:tabular-nums;
    color:var(--text-primary);
    line-height:1.15;
  }
  .lb-table .lb-col-metric:not(.lb-col-metric--active)::before,
  .lb-table .lb-col-avg:not(.lb-col-metric--active)::before {
    content:attr(data-label) !important;
    order:-1;
    margin-bottom:.15rem;
    font-size:.6rem;
    font-weight:700;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
  }
  .lb-table .lb-col-metric:not(.lb-col-metric--active)::after,
  .lb-table .lb-col-avg:not(.lb-col-metric--active)::after { content:none !important }

  /* Climber's rank-change cell joins the metric row as a third block
     (the JS now drops Avg Loan for climbers so this is exactly the
     third slot). The cell's existing two-line structure (.lb-climb
     value + .lb-climb-range "#prior → #current") fits the label-above-
     value pattern of the supporting metrics — add a "Rank Change"
     pseudo-label and tighten the inner type to match. */
  .lb-table .lb-col-climb {
    display:flex !important;
    flex-direction:column;
    flex:0 0 auto;
    order:7;
    margin:.6rem 1.25rem 0 0;
    padding:0;
    line-height:1.15;
  }
  .lb-table .lb-col-climb::before {
    content:"Rank Change";
    order:-1;
    margin-bottom:.15rem;
    font-size:.6rem;
    font-weight:700;
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--text-muted);
  }
  .lb-table .lb-col-climb .lb-climb { font-size:1rem; font-weight:600; }
  .lb-table .lb-col-climb .lb-climb-range { font-size:.7rem; color:var(--text-muted); }

  /* Sparkline full-width. */
  .lb-table .lb-col-trend {
    display:block !important;
    flex:0 0 100%;
    order:9;
    padding-left:0 !important;
    margin-top:.5rem;
    position:relative;
  }
  /* Caption above the bars so the chart reads as data, not decoration.
     Card-only — the desktop table has its own column header. The
     caption text comes from `data-trend-caption` on the parent .lb-row,
     set by JS per active sort / category so climbers, retention, and
     loan-count-sorted boards all get the right label without a CSS
     :has() fallback that misses on older browsers. */
  .lb-table .lb-row .lb-col-trend::before {
    content:attr(data-trend-caption);
    display:block;
    font-size:.6rem;
    font-weight:600;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--text-muted);
    margin-bottom:.3rem;
  }

  /* Left accent stripe colored by rank tier — gold/silver/bronze for top
     3 (matching the medal), subtle gray for the rest. :has() is supported
     in modern Safari + Chrome; on browsers without it the rule no-ops
     and the card just has its normal border. */
  .lb-table tbody tr.lb-row { border-left:4px solid var(--border-secondary) }
  .lb-table tbody tr.lb-row:has(.lb-rank-medal--1) { border-left-color:#facc15 }
  .lb-table tbody tr.lb-row:has(.lb-rank-medal--2) { border-left-color:#9ca3af }
  .lb-table tbody tr.lb-row:has(.lb-rank-medal--3) { border-left-color:#b45309 }

  /* Pinned rows keep their accent; sticky now derives from block-flow
     (display:flex) instead of table-row, which is reliable. */
  .lb-table tbody tr.lb-row--pinned { box-shadow:inset 3px 0 0 0 hsl(var(--primary)) }
  .lb-table tbody tr.lb-row--shared { box-shadow:inset 3px 0 0 0 #10b981 }
}
/* Mobile: collapse the share group to the generic copy-link button only, and
   shrink the View As button to its eye icon. */
@media (max-width:540px){
  .lb-social-btn{display:none}
  .lb-view-as-btn .lb-view-as-label{display:none}
}

/* ============================================================
   Anonymous clamp-warning modal — interstitial shown when an
   unauth viewer lands on a share URL with locked filters.
   ============================================================ */
.leaderboard-clamp-modal {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-modal) + 1);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--transition-slow);
  pointer-events: none;
}
.leaderboard-clamp-modal.entering { opacity: 1; pointer-events: auto; }
.leaderboard-clamp-modal.exiting { opacity: 0; pointer-events: none; }

.lcm-backdrop {
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.lcm-content {
  position: relative;
  background: var(--bg-secondary);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-xl);
  max-width: 38rem;
  width: 92vw;
  max-height: 90vh;
  overflow-y: auto;
  /* Extra right padding gives the last-month sparkline tooltip room to render
     inside the modal instead of triggering a viewport horizontal scroll. */
  padding: 1.75rem 2.25rem 1.25rem 1.5rem;
  box-shadow: var(--shadow-dark-xl);
  transform: scale(0.96);
  transition: transform var(--transition-slow);
}
.leaderboard-clamp-modal.entering .lcm-content { transform: scale(1); }
.leaderboard-clamp-modal.exiting .lcm-content { transform: scale(0.96); }

.lcm-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 50%;
  color: var(--text-secondary);
  cursor: pointer;
}
.lcm-close:hover { background: var(--bg-tertiary); color: var(--text-primary); }

.lcm-title {
  margin: 0 2rem 1rem 0;
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.35;
}

.lcm-preview { margin: 0 0 1rem; min-height: 4rem; }
.lcm-preview--loading {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-tertiary);
  font-size: 0.875rem;
  padding: 1.5rem 0;
}

.lcm-card {
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-lg);
  background: var(--bg-tertiary);
  padding: 0.75rem;
}
.lcm-card-subhead {
  font-size: 0.78rem;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0 0.25rem 0.5rem;
}
.lcm-row {
  display: grid;
  grid-template-columns: 1.5rem 2.25rem 1fr auto;
  align-items: center;
  gap: 0.65rem;
  padding: 0.5rem 0.25rem;
  border-top: 1px solid var(--border-secondary);
}
.lcm-row:first-of-type { border-top: 0; }
.lcm-row-rank {
  font-weight: 700;
  color: var(--text-tertiary);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}
.lcm-row--rank-1 .lcm-row-rank { color: #facc15; }
.lcm-row--rank-2 .lcm-row-rank { color: #9ca3af; }
.lcm-row--rank-3 .lcm-row-rank { color: #b45309; }
.lcm-row-name { font-weight: 600; color: var(--text-primary); font-size: 0.92rem; }
.lcm-row-co { color: var(--text-secondary); font-size: 0.8rem; }
.lcm-row-stat { text-align: right; }
.lcm-row-vol { font-weight: 600; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.lcm-row-units { color: var(--text-tertiary); font-size: 0.78rem; }

/* Spotlight card — mirrors the mobile leaderboard row layout (rank badge +
   avatar + name/company/location, stat block, sparkline) so the modal feels
   like a single row pulled out of the table the viewer is about to land in. */
.lcm-snap {
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-lg);
  padding: 0.85rem;
  background: var(--bg-secondary);
}
.lcm-snap--primary { border-color: var(--border-primary); }

.lcm-card-head {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: 0.65rem;
  margin-bottom: 0.75rem;
}
.lcm-rank-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.75rem;
  height: 1.75rem;
  padding: 0 0.4rem;
  border-radius: 6px;
  font-weight: 700;
  font-size: 0.95rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-secondary);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.lcm-rank-badge--1 { background: #facc15; color: #1a1a1a; border-color: #facc15; }
.lcm-rank-badge--2 { background: #9ca3af; color: #1a1a1a; border-color: #9ca3af; }
.lcm-rank-badge--3 { background: #b45309; color: #ffffff; border-color: #b45309; }

.lcm-card-id { min-width: 0; }
.lcm-card-id .lcm-snap-name { font-size: 1rem; }
.lcm-card-loc {
  color: var(--text-tertiary);
  font-size: 0.78rem;
  margin-top: 0.15rem;
}

.lcm-snap-name { font-weight: 600; color: var(--text-primary); font-size: 0.95rem; }
.lcm-snap-co { color: var(--text-secondary); font-size: 0.82rem; }

.lcm-card-rank {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0.25rem 0 0.85rem;
}
.lcm-snap-pill {
  display: inline-block;
  font-weight: 700;
  font-size: 0.92rem;
  color: #ffffff;
  background: hsl(var(--primary));
  padding: 0.18rem 0.55rem;
  border-radius: 999px;
}
.lcm-snap-suffix { font-size: 0.82rem; color: var(--text-secondary); line-height: 1.4; }

.lcm-card-stats {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border-secondary);
}
.lcm-stat-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.65rem; }
.lcm-stat-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
  margin-bottom: 0.1rem;
}
.lcm-stat-value {
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  font-size: 0.95rem;
}
.lcm-stat-value--big { font-size: 1.6rem; line-height: 1.1; }

/* Shared sparkline lives at .lb-sparkline; the modal card just adds spacing. */
.lcm-snap--card .lb-sparkline {
  margin-top: 0.7rem;
}

.lcm-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1rem;
}
.lcm-chips-label {
  font-size: 0.78rem;
  color: var(--text-tertiary);
  margin-right: 0.25rem;
}
.lcm-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  font-size: 0.82rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-primary);
  color: var(--text-secondary);
}
.lcm-chip--locked { color: var(--text-primary); }
.lcm-chip-lock { font-size: 0.75rem; opacity: 0.8; }

.lcm-cta {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 0.65rem;
}
.lcm-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.65rem 1rem;
  border-radius: var(--radius-md);
  font-size: 0.92rem;
  font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
}
/* Primary CTA is an <a href> for middle-click/open-in-new-tab. The `a.X`
   selector + literal `#fff !important` guarantees contrast regardless of
   theme — `hsl(var(--primary-foreground))` resolves to a near-primary tone
   in some themes, which produced blue-on-blue on the previous attempt. */
.leaderboard-clamp-modal a.lcm-btn-primary,
.leaderboard-clamp-modal a.lcm-btn-primary:visited,
.leaderboard-clamp-modal a.lcm-btn-primary:hover {
  background: hsl(var(--primary));
  color: #ffffff !important;
  text-decoration: none !important;
}
.leaderboard-clamp-modal a.lcm-btn-primary:hover { filter: brightness(1.05); }
.leaderboard-clamp-modal .lcm-btn-secondary {
  background: transparent;
  color: var(--text-secondary) !important;
  border-color: var(--border-primary);
}
.leaderboard-clamp-modal .lcm-btn-secondary:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary) !important;
}

.lcm-footnote {
  margin: 0;
  font-size: 0.78rem;
  color: var(--text-tertiary);
  text-align: center;
  line-height: 1.4;
}

/* ---------------------------------------------------------------------
   Anonymous footer CTA — appears below #lbResults on the public bundle.
   Sized to feel like a leaderboard card so it sits naturally at the
   bottom of the scrolled list, but visually distinct via the gradient
   background so it doesn't read as another ranked row.
   --------------------------------------------------------------------- */
.lb-anon-footer-cta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  padding: 14px 16px;
  background: linear-gradient(135deg, hsl(var(--primary) / 0.08), hsl(var(--primary) / 0.18));
  border: 1px solid hsl(var(--primary) / 0.25);
  border-radius: 12px;
}
.lb-anon-footer-cta__text { flex: 1; min-width: 0; }
.lb-anon-footer-cta__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.25;
}
.lb-anon-footer-cta__sub {
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-muted);
}
.lb-anon-footer-cta__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  padding: 9px 14px;
  background: hsl(var(--primary));
  color: #fff !important;
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  text-decoration: none !important;
  border: none;
  transition: filter 120ms ease;
}
.lb-anon-footer-cta__btn:hover { filter: brightness(1.08); }
.lb-anon-footer-cta__btn svg { flex-shrink: 0; }

@media (max-width: 540px) {
  .lb-anon-footer-cta { margin-top: 12px; padding: 12px 14px; }
  .lb-anon-footer-cta__title { font-size: 13px; }
  .lb-anon-footer-cta__sub { font-size: 11.5px; }
  .lb-anon-footer-cta__btn { padding: 8px 12px; font-size: 12px; }
}

/* Hide the chat composer entirely on the anon leaderboard. The input
   is non-functional for anon (chat requires auth); the page-level
   Sign-up affordances live in the header pill and the footer CTA
   below the leaderboard. Scoped to `has-tmo-brand` (added only by
   client/leaderboard.js) so the chat-app anon landing keeps its real
   composer where typing is part of the product tour. */
body.has-tmo-brand #inputBar { display: none !important; }

/* Hide the shell title chip ("MMI Loan Officer Leaderboard") on the
   anon leaderboard — the "Top Mortgage Originators / Powered by MMI"
   wordmark to its left already identifies the surface. Authed users
   keep the chip since their wordmark stays "ChatMMI" and the chip
   carries the per-view label. */
body.has-tmo-brand .mmi-shell__title-chip { display: none !important; }

/* The mobile toolbar exposes its own #lbStateFilterMobile select, so
   hide the original #lbStateFilter inside the .lb-filters panel on
   phones — otherwise opening the funnel shows two state selects.
   Two-way sync keeps both in lockstep regardless. */
/* 860px — control-collapse breakpoint (see note above): the mobile toolbar's
   own state select takes over at the same width the funnel collapses. */
@media (max-width: 860px) {
  .lb-filters #lbStateFilter { display: none; }
}

/* ---------------------------------------------------------------------
   600ms fake progress bar inside the chat thinking bubble. Sits under
   the dots + "Looking up the leaderboard…" line and fills 0→90% over
   500ms then holds at 90% (the last 10% is reserved for the real-data
   arrival; the bubble is replaced wholesale when results land so the
   bar never visibly "stops"). Bonzo pink for the fill so it ties to
   the hero accent.
   --------------------------------------------------------------------- */
.lb-chat-progress {
  margin-top: 8px;
  height: 3px;
  width: 100%;
  background: hsl(var(--muted-foreground) / 0.15);
  border-radius: 2px;
  overflow: hidden;
}
.lb-chat-progress__bar {
  height: 100%;
  width: 0;
  background: hsl(330 78% 56%);
  border-radius: 2px;
  animation: lb-chat-progress-fill 400ms cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}
@keyframes lb-chat-progress-fill {
  0%   { width: 0; }
  60%  { width: 70%; }
  100% { width: 92%; }
}
