﻿/* ──────────────────────────────────────────────────────────────────
   Theme palettes — 8 named variants derived from the booster-pack
   logo (deep purple + gold + cream-yellow + dark navy + sepia accents).
   Each theme defines a complete CSS variable block so picking one in
   Settings swaps the entire site palette atomically.
   ──────────────────────────────────────────────────────────────────
   LIGHT family: Parchment (default), Cream, Lavender, Mist
   DARK  family: Velvet (default), Midnight, Black, Bronze
   ──────────────────────────────────────────────────────────────────
   :root carries Parchment values as a fallback for the case where
   data-theme isn't set yet (first paint before JS runs). Explicit
   [data-theme="parchment"] repeats them for cleanliness — both selectors
   match equally on first-load, so the order doesn't matter. */

:root, html[data-theme="parchment"] {
  /* Warm cream-tan parchment. Original light theme the user preferred
     before we went lavender — restored as the default. */
  --bg: #f4f1eb;
  --bg-solid: #f4f1eb;
  --bg-surface: rgba(0,0,0,0.03);
  --bg-surface-hover: rgba(0,0,0,0.05);
  --bg-card: #fdfbf6;
  --bg-modal: #f5f1e7;
  --border: rgba(0,0,0,0.1);
  --border-accent: rgba(160,130,60,0.22);
  --text: #1a1a1a;
  --text-muted: rgba(0,0,0,0.4);
  --text-dim: rgba(0,0,0,0.58);
  --accent: #8a6d1b;
  --accent-glow: rgba(138,109,27,0.08);
  --green: #166534;
  --red: #991b1b;
  --stat-bg: rgba(0,0,0,0.03);
  --table-header: rgba(0,0,0,0.02);
  --table-row-hover: rgba(0,0,0,0.02);
  --btn-bg: transparent;
  --btn-border: rgba(0,0,0,0.12);
  --btn-text: rgba(0,0,0,0.55);
  --btn-active-bg: rgba(138,109,27,0.1);
  --btn-active-text: #8a6d1b;
  --btn-active-border: rgba(138,109,27,0.3);
  --mode: light;
  --tooltip-bg: #fff;
  --tooltip-border: rgba(0,0,0,0.12);
  --tooltip-shadow: 0 4px 16px rgba(0,0,0,0.12);
  --heatmap-text-hi: #412402;
  --heatmap-text-lo: rgba(0,0,0,0.3);
  --heatmap-color: rgba(138,109,27,VAL);
}

/* ──────────────────────────────────────────────────────────────────
   Multi-color gradient themes — each canvas blends multiple brand
   colors so the bg itself looks layered, not flat. Implementation
   trick: --bg holds a CSS gradient instead of a hex color. Every
   site element that uses `background: var(--bg)` (body, body::before,
   modal backdrops, sticky headers, etc.) renders the gradient.
   Fallback color is the dominant tone — for any browser/print path
   that ignores the gradient, the page still reads correct.
   ────────────────────────────────────────────────────────────────── */

html[data-theme="aurora"] {
  /* Aurora — diagonal northern-lights wash from deep purple through
     violet to warm gold. Feels like the booster pack's burst rays
     spread across a stage backdrop. */
  --bg: linear-gradient(135deg, #150826 0%, #2a1450 40%, #3a2810 100%);
  --bg-solid: #1a0e30; /* flat deep-purple base; chrome must NOT paint the gradient (it'd show the warm-gold end as a misaligned slice) */
  --bg-surface: rgba(255,255,255,0.05);
  --bg-surface-hover: rgba(255,255,255,0.08);
  --bg-card: rgba(255,255,255,0.07);
  --bg-modal: #2a1f3f;
  --border: rgba(255,255,255,0.13);
  --border-accent: rgba(232,200,80,0.32);
  --text: #f3e8ff;
  --text-muted: rgba(255,255,255,0.5);
  --text-dim: rgba(255,255,255,0.65);
  --accent: #e8c850;
  --accent-glow: rgba(232,200,80,0.2);
  --green: #7ed897;
  --red: #ff8a8a;
  --stat-bg: rgba(255,255,255,0.06);
  --table-header: rgba(255,255,255,0.04);
  --table-row-hover: rgba(255,255,255,0.05);
  --btn-bg: transparent;
  --btn-border: rgba(255,255,255,0.17);
  --btn-text: rgba(255,255,255,0.7);
  --btn-active-bg: rgba(232,200,80,0.16);
  --btn-active-text: #f4d770;
  --btn-active-border: rgba(232,200,80,0.4);
  --mode: dark;
  --tooltip-bg: #1a0e30;
  --tooltip-border: rgba(255,255,255,0.14);
  --tooltip-shadow: 0 4px 20px rgba(0,0,0,0.55);
  --heatmap-text-hi: #fff0b0;
  --heatmap-text-lo: rgba(255,255,255,0.3);
  --heatmap-color: rgba(232,200,80,VAL);
}

html[data-theme="sunrise"] {
  /* Sunrise — diagonal watercolor wash from warm peach through soft
     pink to pale lavender. Like a sunrise sky on aged paper. Light
     family: deep plum text, gold accent. The gradient is subtle so
     the page still reads "white/cream paper", just tinted. */
  --bg: linear-gradient(135deg, #fbe9d4 0%, #f4e8e8 45%, #ece2f1 100%);
  --bg-solid: #f5e9e4;
  --bg-surface: rgba(60,30,100,0.04);
  --bg-surface-hover: rgba(60,30,100,0.07);
  --bg-card: #fffaf0;
  --bg-modal: #faf0e0;
  --border: rgba(80,40,90,0.13);
  --border-accent: rgba(160,130,60,0.3);
  --text: #2a1f3a;
  --text-muted: rgba(42,31,58,0.55);
  --text-dim: rgba(42,31,58,0.7);
  --accent: #8a6d1b;
  --accent-glow: rgba(138,109,27,0.1);
  --green: #166534;
  --red: #991b1b;
  --stat-bg: rgba(80,40,90,0.04);
  --table-header: rgba(80,40,90,0.03);
  --table-row-hover: rgba(80,40,90,0.04);
  --btn-bg: transparent;
  --btn-border: rgba(80,40,90,0.15);
  --btn-text: rgba(42,31,58,0.6);
  --btn-active-bg: rgba(138,109,27,0.12);
  --btn-active-text: #8a6d1b;
  --btn-active-border: rgba(138,109,27,0.32);
  --mode: light;
  --tooltip-bg: #fff;
  --tooltip-border: rgba(80,40,90,0.15);
  --tooltip-shadow: 0 4px 16px rgba(80,40,90,0.15);
  --heatmap-text-hi: #2a1f3a;
  --heatmap-text-lo: rgba(42,31,58,0.32);
  --heatmap-color: rgba(138,109,27,VAL);
}

html[data-theme="watercolor"] {
  /* Watercolor — mesh-style soft blobs on warm cream paper. Faint
     purple blob top-left, faint gold blob bottom-right, on a base of
     pale parchment. Subtle enough that the page reads "tinted paper",
     painterly enough to feel intentional. Closest light analogue to
     the dark Tarot theme. */
  --bg:
    radial-gradient(ellipse 900px 700px at 15% 22%, rgba(180,130,210,0.22) 0%, transparent 55%),
    radial-gradient(ellipse 800px 600px at 85% 78%, rgba(220,170,70,0.2) 0%, transparent 55%),
    #f7f1e3;
  --bg-solid: #f7f1e3;
  --bg-surface: rgba(60,30,100,0.04);
  --bg-surface-hover: rgba(60,30,100,0.07);
  --bg-card: #fdfaf0;
  --bg-modal: #f9f3e5;
  --border: rgba(80,40,90,0.13);
  --border-accent: rgba(160,130,60,0.3);
  --text: #2a1f3a;
  --text-muted: rgba(42,31,58,0.55);
  --text-dim: rgba(42,31,58,0.7);
  --accent: #8a6d1b;
  --accent-glow: rgba(138,109,27,0.1);
  --green: #166534;
  --red: #991b1b;
  --stat-bg: rgba(80,40,90,0.04);
  --table-header: rgba(80,40,90,0.03);
  --table-row-hover: rgba(80,40,90,0.04);
  --btn-bg: transparent;
  --btn-border: rgba(80,40,90,0.15);
  --btn-text: rgba(42,31,58,0.6);
  --btn-active-bg: rgba(138,109,27,0.12);
  --btn-active-text: #8a6d1b;
  --btn-active-border: rgba(138,109,27,0.32);
  --mode: light;
  --tooltip-bg: #fff;
  --tooltip-border: rgba(80,40,90,0.15);
  --tooltip-shadow: 0 4px 16px rgba(80,40,90,0.15);
  --heatmap-text-hi: #2a1f3a;
  --heatmap-text-lo: rgba(42,31,58,0.32);
  --heatmap-color: rgba(138,109,27,VAL);
}

html[data-theme="daydream"] {
  /* Daydream — golden-hour glow blooming from top-right over a soft
     pale-lavender-to-cream linear base. Like reading a Disney
     fairytale book in late afternoon sun. The radial spotlight is
     gold, the base linear is pale-purple→cream — gentlest of the
     light gradients. */
  --bg:
    radial-gradient(ellipse 1200px 800px at 85% 8%, rgba(232,200,80,0.28) 0%, transparent 55%),
    linear-gradient(165deg, #efe6f3 0%, #f6ecda 100%);
  --bg-solid: #f3ecdf;
  --bg-surface: rgba(60,30,100,0.04);
  --bg-surface-hover: rgba(60,30,100,0.07);
  --bg-card: #fcf7ec;
  --bg-modal: #f6eedd;
  --border: rgba(80,40,90,0.13);
  --border-accent: rgba(160,130,60,0.3);
  --text: #2a1f3a;
  --text-muted: rgba(42,31,58,0.55);
  --text-dim: rgba(42,31,58,0.7);
  --accent: #8a6d1b;
  --accent-glow: rgba(138,109,27,0.1);
  --green: #166534;
  --red: #991b1b;
  --stat-bg: rgba(80,40,90,0.04);
  --table-header: rgba(80,40,90,0.03);
  --table-row-hover: rgba(80,40,90,0.04);
  --btn-bg: transparent;
  --btn-border: rgba(80,40,90,0.15);
  --btn-text: rgba(42,31,58,0.6);
  --btn-active-bg: rgba(138,109,27,0.12);
  --btn-active-text: #8a6d1b;
  --btn-active-border: rgba(138,109,27,0.32);
  --mode: light;
  --tooltip-bg: #fff;
  --tooltip-border: rgba(80,40,90,0.15);
  --tooltip-shadow: 0 4px 16px rgba(80,40,90,0.15);
  --heatmap-text-hi: #2a1f3a;
  --heatmap-text-lo: rgba(42,31,58,0.32);
  --heatmap-color: rgba(138,109,27,VAL);
}

html[data-theme="velvet"], html[data-theme="dark"] {
  /* Deep velvet purple — the booster-pack interior shade. Default dark
     theme. data-theme="dark" alias kept for backwards compat with any
     code, saved view, or localStorage that pre-dates the rename. */
  --bg: #180a22;
  --bg-solid: #180a22;
  --bg-surface: rgba(255,255,255,0.04);
  --bg-surface-hover: rgba(255,255,255,0.07);
  --bg-card: rgba(255,255,255,0.06);
  --bg-modal: #241340;
  --border: rgba(255,255,255,0.08);
  --border-accent: rgba(200,170,100,0.25);
  --text: #e8e2f4;
  --text-muted: rgba(255,255,255,0.4);
  --text-dim: rgba(255,255,255,0.55);
  --accent: #c8a846;
  --accent-glow: rgba(200,168,70,0.15);
  --green: #5cb87a;
  --red: #d45c5c;
  --stat-bg: rgba(255,255,255,0.05);
  --table-header: rgba(255,255,255,0.03);
  --table-row-hover: rgba(255,255,255,0.03);
  --btn-bg: transparent;
  --btn-border: rgba(255,255,255,0.12);
  --btn-text: rgba(255,255,255,0.6);
  --btn-active-bg: rgba(200,168,70,0.12);
  --btn-active-text: #c8a846;
  --btn-active-border: rgba(200,168,70,0.3);
  --mode: dark;
  --tooltip-bg: #1a1c22;
  --tooltip-border: rgba(255,255,255,0.1);
  --tooltip-shadow: 0 4px 16px rgba(0,0,0,0.4);
  --heatmap-text-hi: #f0e0a0;
  --heatmap-text-lo: rgba(255,255,255,0.25);
  --heatmap-color: rgba(200,168,70,VAL);
  /* Note: color-scheme:dark was previously set here to fix unreadable
     <select> dropdowns. Pulled off the root because Samsung Internet
     applied a tan/cream UA tint to <button> backgrounds (incl. the
     profile-btn / avatar tile) when color-scheme was at the root level.
     Form-control fix moved to a dedicated rule below. */
}

html[data-theme="black"] {
  /* OLED / Pure Black. True #000 canvas, surfaces lift minimally. Saves
     battery on AMOLED, max contrast against gold accent. */
  --bg: #000000;
  --bg-solid: #000000;
  --bg-surface: rgba(255,255,255,0.05);
  --bg-surface-hover: rgba(255,255,255,0.08);
  --bg-card: rgba(255,255,255,0.06);
  --bg-modal: #0a0a0a;
  --border: rgba(255,255,255,0.13);
  --border-accent: rgba(200,170,100,0.3);
  --text: #ffffff;
  --text-muted: rgba(255,255,255,0.45);
  --text-dim: rgba(255,255,255,0.6);
  --accent: #c8a846;
  --accent-glow: rgba(200,168,70,0.18);
  --green: #5cb87a;
  --red: #d45c5c;
  --stat-bg: rgba(255,255,255,0.05);
  --table-header: rgba(255,255,255,0.04);
  --table-row-hover: rgba(255,255,255,0.04);
  --btn-bg: transparent;
  --btn-border: rgba(255,255,255,0.14);
  --btn-text: rgba(255,255,255,0.65);
  --btn-active-bg: rgba(200,168,70,0.14);
  --btn-active-text: #c8a846;
  --btn-active-border: rgba(200,168,70,0.32);
  --mode: dark;
  --tooltip-bg: #050505;
  --tooltip-border: rgba(255,255,255,0.12);
  --tooltip-shadow: 0 4px 16px rgba(0,0,0,0.6);
  --heatmap-text-hi: #f0e0a0;
  --heatmap-text-lo: rgba(255,255,255,0.3);
  --heatmap-color: rgba(200,168,70,VAL);
}

html[data-theme="light"] {
  /* Alias for backward-compat with any persisted theme="light" pref.
     Resolves to Parchment values. */
  --bg: #f4f1eb;
  --bg-solid: #f4f1eb;
  --bg-surface: rgba(0,0,0,0.03);
  --bg-surface-hover: rgba(0,0,0,0.05);
  --bg-card: #fdfbf6;
  --bg-modal: #f5f1e7;
  --border: rgba(0,0,0,0.1);
  --border-accent: rgba(160,130,60,0.22);
  --text: #1a1a1a;
  --text-muted: rgba(0,0,0,0.4);
  --text-dim: rgba(0,0,0,0.58);
  --accent: #8a6d1b;
  --accent-glow: rgba(138,109,27,0.08);
  --green: #166534;
  --red: #991b1b;
  --stat-bg: rgba(0,0,0,0.03);
  --table-header: rgba(0,0,0,0.02);
  --table-row-hover: rgba(0,0,0,0.02);
  --btn-bg: transparent;
  --btn-border: rgba(0,0,0,0.12);
  --btn-text: rgba(0,0,0,0.55);
  --btn-active-bg: rgba(138,109,27,0.1);
  --btn-active-text: #8a6d1b;
  --btn-active-border: rgba(138,109,27,0.3);
  --mode: light;
  --tooltip-bg: #fff;
  --tooltip-border: rgba(0,0,0,0.12);
  --tooltip-shadow: 0 4px 16px rgba(0,0,0,0.12);
  --heatmap-text-hi: #412402;
  --heatmap-text-lo: rgba(0,0,0,0.3);
  --heatmap-color: rgba(138,109,27,VAL);
}
*,*::before,*::after{box-sizing:border-box;}

/* Native form controls (select option panels, scrollbars, focus rings) in
   dark themes. Was previously applied as `color-scheme: dark` on root, but
   Samsung Internet (and possibly other Chromium forks) used that signal to
   apply a UA-default tan tint to <button> backgrounds — visible on the
   profile-btn / avatar tile on mobile. Scoping to the form controls only
   keeps dropdown options readable in dark mode without touching buttons. */
html[data-mode="dark"] :where(select, input, textarea, option, datalist){
  color-scheme: dark;
}

/* Body padding uses max(designed, safe-area-inset) so iOS notched devices
   (iPhone 14 Pro+, Dynamic Island) pad content away from the Island,
   home indicator, and landscape rounded corners. env() resolves to 0 on
   devices without insets, so desktop and non-cutout Android are
   unaffected. Pairs with <meta viewport-fit=cover> + apple-mobile-web-app-
   status-bar-style=black-translucent in Index.html. */
/* body uses background-color (not the background shortcut) so a gradient
   value in --bg is silently ignored at the body level — the body is only
   1300px wide and a gradient anchored to it wouldn't align with the
   fullscreen ::before layer, creating a visible seam at the column edges.
   For solid colors, background-color accepts the value normally. For
   gradient themes (aurora/spotlight/tarot), body stays transparent and the
   gradient paints exclusively via body::before, which spans the entire
   viewport via position:fixed. */
body{margin:0;font-family:'Nunito Sans',sans-serif;font-size:14px;color:var(--text);background-color:var(--bg);
  padding:max(1.5rem,env(safe-area-inset-top)) max(1.5rem,env(safe-area-inset-right)) max(1.5rem,env(safe-area-inset-bottom)) max(1.5rem,env(safe-area-inset-left));
  max-width:1300px;margin:0 auto;min-height:100vh;position:relative;}
body::before{content:'';position:fixed;inset:0;z-index:-2;background:var(--bg);}
body::after{content:'';position:fixed;inset:0;z-index:-1;opacity:0.5;background:
  radial-gradient(ellipse 600px 600px at 10% 20%, rgba(200,168,70,0.04) 0%, transparent 70%),
  radial-gradient(ellipse 500px 500px at 85% 70%, rgba(100,140,220,0.04) 0%, transparent 70%),
  radial-gradient(ellipse 400px 400px at 50% 50%, rgba(160,80,180,0.03) 0%, transparent 70%);pointer-events:none;}
h1,h2,h3,.title-font{font-family:'Cinzel',serif;}
table{border-collapse:collapse;width:100%;}
th,td{padding:8px 12px;border-bottom:1px solid var(--border);font-size:13px;}
th{font-weight:500;color:var(--text-muted);font-size:11px;text-transform:uppercase;letter-spacing:0.5px;background:var(--table-header);text-align:right;}
th:first-child,td:first-child{text-align:left;}
td{text-align:right;}
tr:hover{background:var(--table-row-hover);}
button{cursor:pointer;border:1px solid var(--btn-border);background:var(--btn-bg);border-radius:6px;padding:6px 14px;font-size:12px;color:var(--btn-text);font-family:'Nunito Sans',sans-serif;transition:all 0.15s ease;}
button:hover{background:var(--bg-surface-hover);}
button.active{background:var(--btn-active-bg);color:var(--btn-active-text);border-color:var(--btn-active-border);}
button:disabled{opacity:0.3;cursor:not-allowed;}
select{border:1px solid var(--btn-border);border-radius:6px;padding:6px 10px;font-size:13px;background:var(--bg-solid);color:var(--text);font-family:'Nunito Sans',sans-serif;}
select option{background:var(--bg-solid);color:var(--text);}
input[type="checkbox"]{accent-color:var(--accent);}
/* Top nav layout — three peers: [logo | tabs (scrollable middle) | right cluster]. */
.top-nav{display:flex;gap:6px;align-items:center;margin-bottom:1.5rem;}
.tabs{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:1 1 auto;min-width:0;}
/* Two-row tab grid: row 1 = "my stuff" (Collection / Cards / Decks), row 2 =
   "market intel" (Screener / Price Graphing / Analytics) + Help. Each tab is
   an icon-over-label chip. The grid container stacks the rows vertically. */
.tabs-grid{flex-direction:column;align-items:flex-start;gap:6px;}
.tabs-row{display:flex;gap:4px;align-items:stretch;flex-wrap:nowrap;}
.nav-tab{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:3px;min-width:74px;padding:6px 10px 5px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;
  color:var(--text-muted);cursor:pointer;transition:all 0.12s;
  font-family:'Cinzel',serif;font-weight:600;letter-spacing:0.2px;
  /* <a> tab: kill default link styling so it renders identically to the
     previous <button> while preserving Ctrl/middle/right-click affordances. */
  text-decoration:none;}
.nav-tab:hover{color:var(--accent);border-color:var(--accent);}
.nav-tab.active{background:var(--accent-glow);color:var(--accent);
  border-color:var(--accent);}
.nav-tab-icon{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;line-height:0;}
.nav-tab-icon svg{display:block;}
.nav-tab-label{font-size:10px;line-height:1.1;white-space:nowrap;text-transform:uppercase;
  /* text-align:center: when the label wraps to two lines on mobile (e.g. Price /
     Graphing), the wrapped words should stack centered under the icon rather
     than left-aligned, which looked off-axis next to the centered icon. */
  text-align:center;}
/* Help: rendered as a bubble in the right cluster's bubble row alongside
   install + theme-toggle (moved out of the tabs grid 2026-05-26 so it
   doesn't crowd the Screener/Price Graphing/Analytics row on phones and
   overlap the sign-in pill / profile chip). The bubble inherits `.theme-toggle`
   shape; `.active` paints the gold accent so the user can tell when they're
   on the How It Works page. SVG centers inside the 32×32 / 36×36 circle
   naturally (icon is 18px). */
.theme-toggle--help svg{display:block;}
.theme-toggle--help.active{background:var(--accent-glow);color:var(--accent);
  border-color:var(--accent);}
.top-nav-right{flex-shrink:0;display:flex;flex-direction:column;
  align-items:flex-end;gap:4px;}
/* Bubbles row needs an explicit horizontal flex on desktop too — without
   it, the row falls back to block layout and the three bubble buttons can
   line up with subtle vertical offsets (the user saw `?` painting above
   `🌙` because of baseline alignment, not a deliberate stack). Mobile re-
   declares this inside the @media block with !important for safety. */
.top-nav-right-row--bubbles{display:flex;gap:4px;align-items:center;}
/* Logo button — wraps the wordmark and routes to Home on click. */
.tabs-logo-btn{background:transparent;border:none;padding:0;margin:0;cursor:pointer;
  display:inline-flex;align-items:center;flex-shrink:0;
  /* <a> wrapper: drop default link styling so the wordmark stays clean. */
  text-decoration:none;color:inherit;}
.tabs-logo-btn:hover{opacity:0.85;}
.tabs-logo-btn img{height:60px;width:auto;display:block;pointer-events:none;}
@media (max-width:640px){
  /* Reclaim horizontal real estate: body padding was 24px on each side, 13% of a 375 viewport.
     Still pad top/bottom by env(safe-area-inset) so iOS Dynamic Island /
     home indicator can't overlap the top nav (Photo 1) or eat the bottom
     action bar. max(14px, env) keeps the designed 14px floor for
     non-notched mobile devices. */
  body{
    padding:
      max(14px, env(safe-area-inset-top))
      max(14px, env(safe-area-inset-right))
      max(14px, env(safe-area-inset-bottom))
      max(14px, env(safe-area-inset-left));
    overflow-x:clip;
  }
  /* Defense against any descendant that mis-sizes wider than the viewport
     (causing pinch-zoom-out to reveal dead space on the right). `clip` is
     used instead of `hidden` because hidden makes the element a scroll
     container, which breaks position:sticky for descendants like the
     mobile Cards/Deck tab toggle in the deck editor. clip caps overflow
     without converting to a scroll container. */
  html{overflow-x:clip;}
  /* iOS Safari zooms in when an input has font-size < 16px. Force ≥16 everywhere on phone. */
  input,textarea,select{font-size:16px !important;}
  /* On mobile the top bar is [logo | tabs | right-cluster] flex row WITHOUT
     a global scroll. Only the middle .tabs is a horizontal scroller — that
     way the logo and right cluster (profile / sign-in / theme) are always
     anchored on-screen and never overlap each other. (Previous approach made
     the whole top-nav scroll, and a sticky-right cluster overlapped the last
     tabs visually.) */
  .top-nav{position:sticky;top:0;z-index:50;background:var(--bg-solid);
    padding-top:8px;padding-bottom:6px;
    margin-left:-14px;margin-right:-14px;padding-left:10px;padding-right:10px;
    margin-bottom:1rem;gap:6px;
    flex-wrap:nowrap;overflow:visible;align-items:center;}
  /* Logo is the pressure valve: when the nav overflows (narrow phone or, more
     commonly, Samsung "Display size" zoom that inflates every element), let the
     logo shrink proportionally instead of the right-anchored SIGN IN / install
     cluster spilling past the screen edge and clipping. object-fit keeps aspect
     so it scales down cleanly rather than squishing. In the normal case there's
     positive free space (the tabs scroller eats it), so the logo stays 46px. */
  .tabs-logo-btn{flex-shrink:1;min-width:0;}
  .tabs-logo-btn img{height:46px !important;width:auto;max-width:100%;
    object-fit:contain;object-position:left center;}
  /* Middle: the actual horizontal scroller. tabs-grid stacks two rows of
     chips inside; the wider row drives the scroll width. */
  .tabs{flex:1 1 0;min-width:0;overflow-x:auto;overflow-y:visible;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;}
  .tabs::-webkit-scrollbar{display:none;}
  .tabs-grid{align-items:stretch;}
  .tabs-row{flex-wrap:nowrap;}
  .tabs-row > .nav-tab{flex-shrink:0;}
  /* Compact icon tabs on mobile. Tight padding + narrow gaps + WRAPPABLE
     labels with an explicit max-width so the two-word "Price Graphing"
     actually breaks to two lines instead of pushing Analytics off the right
     edge. white-space:normal alone wouldn't wrap because the parent .nav-tab
     has no width constraint — the label would stay one line and the button
     would just grow wider. max-width:54px forces the break. Single-word
     labels (COLLECTION ~55px, ANALYTICS ~50px, SCREENER ~45px) fit one
     line at this width and stay on one line. Tab heights even out via
     align-items:stretch on .tabs-grid. */
  .nav-tab{min-width:46px;padding:3px 4px 2px;gap:1px;}
  .nav-tab-icon{width:16px;height:16px;}
  .nav-tab-icon svg{width:14px;height:14px;}
  /* max-width:66px is wide enough that single-word 10-char labels like
     "COLLECTION" stay on one line in Cinzel 8.5px (was clipping the final
     "N" to a 2nd line at 58px), while 14-char "PRICE GRAPHING" still
     wraps to two lines (it needs ~76px on one line). Centered (inherited
     from base rule above) so the wrapped text aligns under the icon. */
  .nav-tab-label{font-size:8.5px;white-space:normal;line-height:1.05;
    max-width:66px;word-break:normal;overflow-wrap:break-word;hyphens:none;}
  .tabs-row{gap:3px;}
  /* Mobile help bubble — slightly tighter SVG inside the 36×36 bubble so
     it visually balances the install + theme glyphs (which read smaller). */
  .top-nav-right .theme-toggle--help svg{width:18px;height:18px;}
  /* Right cluster on mobile: two stacked sub-rows. Row 1 = sign-in/profile
     pill. Row 2 = small bubble controls (install + theme). Keeps the cluster
     narrow horizontally so it doesn't crowd the tabs, while every control
     stays visible inline (no hiding in overflow). Explicit bg so as the page
     scrolls under the sticky header, content doesn't show through the gaps
     between bubble buttons. */
  .top-nav-right{display:flex !important;flex-direction:column;
    align-items:flex-end;gap:4px;flex:0 0 auto;flex-shrink:0;
    background:var(--bg-solid);padding-left:4px;}
  .top-nav-right-row--bubbles{display:flex;gap:4px;align-items:center;
    background:var(--bg-solid);}
  /* Mobile tap targets — Apple HIG recommends 44pt minimum; we cap at 36px
     to keep the two-row nav from getting too tall. Was 28px which made the
     profile pill (Photo 4 regression) almost impossible to hit on iPhone. */
  .signin-btn{padding:6px 11px;font-size:11px;min-height:36px;}
  /* On mobile the profile button collapses to just the avatar circle. The
     name eats ~80px which was the difference between row 2 (Screener / Price
     Graphing / Analytics / ?) fitting vs. the help button scrolling off the
     right. Tap the avatar to open the popover; the full name is in there. */
  .profile-btn{padding:2px;min-height:36px;min-width:36px;
    border-radius:50%;gap:0;}
  .profile-btn-name{display:none;}
  .top-nav-right .theme-toggle{min-height:36px;width:36px;padding:0;font-size:14px;
    display:inline-flex;align-items:center;justify-content:center;}
  /* Pin the settings popover to the viewport on mobile so it isn't clipped
     by ancestor overflow rules. Coordinates anchored to top-right of screen,
     not the avatar button. `top` and `right` honor safe-area-inset so the
     popover doesn't open under the iPhone Dynamic Island (Photo 4 regression
     was partly this — the user could tap the avatar but couldn't reach the
     menu that appeared underneath the Island). */
  .settings-popover{position:fixed !important;
    top:calc(56px + env(safe-area-inset-top)) !important;
    right:max(8px, env(safe-area-inset-right)) !important;
    left:auto !important;
    max-height:calc(100vh - 64px - env(safe-area-inset-top) - env(safe-area-inset-bottom)) !important;
    overflow-y:auto !important;
    max-width:calc(100vw - 16px - env(safe-area-inset-left) - env(safe-area-inset-right));}
  /* Bump tiny mover-tile text + tile width so cards are readable on phones. */
  .mover-tile{flex-basis:158px;}
  .mover-tile .mt-name{font-size:11px;}
  .mover-tile .mt-meta{font-size:10px;}
  .mover-tile .mt-prices{font-size:11px;}
  .mover-tile .mt-prices .mt-lbl{font-size:9px;}
  .mover-tile .mt-deltas{font-size:10px;}
  .mover-tile .mt-deltas .mt-dh,
  .mover-tile .mt-deltas .mt-dlbl{font-size:9px;}
  .mover-tile .mt-deltas .mt-dval{font-size:10px;}
  /* Tap targets: Use Low / Use Market price-mode toggles, small chip-style buttons. */
  .market-subtabs > button,
  .card-detail-tabs > button{min-height:36px;}
  /* Deck readonly banner toolbar buttons (Mulligan / Export / Edit) — bump from 29px. */
  .deck-readonly-banner button{min-height:36px;}
}
/* Cards tab — multi-select bulk bar + per-tile checkbox + ephemeral toast. */
.cards-bulk-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;
  padding:8px 12px;margin-bottom:10px;
  background:var(--accent-glow);border:1px solid var(--border-accent);border-radius:8px;
  position:sticky;top:8px;z-index:10;}
/* On phones the two-row top-nav is ~94px and sticky at top:0; pin the bulk bar
   just below it so its 'Add to…' controls aren't occluded behind the header
   when scrolling with cards selected. (Same coordinate system as the nav, so
   no extra safe-area term — the body padding already offsets both.) */
@media (max-width:640px){ .cards-bulk-bar{top:96px;} }
.cards-bulk-count{font-size:13px;font-weight:700;color:var(--accent);
  padding:2px 8px;background:var(--bg-card);border-radius:5px;}
.cards-bulk-link{background:none;border:none;color:var(--text-dim);font-size:12px;
  cursor:pointer;padding:2px 6px;border-radius:4px;}
.cards-bulk-link:hover{color:var(--accent);background:var(--bg-card);}
.cards-bulk-spacer{flex:1;}
.cards-bulk-action{position:relative;display:inline-block;}
.cards-bulk-primary{padding:6px 14px;font-size:13px;font-weight:700;
  background:var(--accent);color:#fff;border:none;border-radius:6px;cursor:pointer;}
.cards-bulk-primary:hover{filter:brightness(1.08);}
.cards-bulk-menu{position:absolute;top:calc(100% + 4px);right:0;min-width:280px;
  background:var(--bg-modal);border:1px solid var(--border);border-radius:8px;
  box-shadow:0 8px 24px rgba(0,0,0,0.35);z-index:20;padding:4px;}
.cards-bulk-menu-picker{max-height:360px;overflow-y:auto;}
.cards-bulk-menu-head{display:flex;align-items:center;gap:8px;
  padding:6px 8px;font-size:11px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);border-bottom:1px solid var(--border);
  margin-bottom:4px;}
.cards-bulk-back{background:transparent;border:none;color:var(--text-muted);
  cursor:pointer;font-size:14px;padding:0 4px;}
.cards-bulk-back:hover{color:var(--accent);}
.cards-bulk-menu-item{display:flex;align-items:center;gap:10px;width:100%;
  padding:7px 10px;background:transparent;border:none;border-radius:6px;
  cursor:pointer;text-align:left;color:var(--text);}
.cards-bulk-menu-item:hover{background:var(--bg-surface);}
.cards-bulk-menu-icon{flex-shrink:0;width:22px;height:22px;display:inline-flex;
  align-items:center;justify-content:center;font-size:14px;font-weight:700;
  color:var(--accent);background:var(--accent-glow);border-radius:5px;}
.cards-bulk-menu-title{font-size:13px;font-weight:600;line-height:1.25;}
.cards-bulk-menu-sub{font-size:11px;color:var(--text-muted);line-height:1.3;}
.cards-bulk-picker-list{display:flex;flex-direction:column;gap:1px;}

/* The little checkbox button overlaid on each card tile. Hidden by default
   in grid mode and revealed on hover; once selected, stays visible. */
.card-tile-check{position:absolute;top:6px;left:6px;width:22px;height:22px;
  padding:0;display:inline-flex;align-items:center;justify-content:center;
  border:1.5px solid rgba(255,255,255,0.85);background:rgba(0,0,0,0.45);
  color:#fff;border-radius:4px;font-size:13px;font-weight:700;cursor:pointer;
  z-index:3;opacity:0;transition:opacity 0.1s,background 0.1s,border-color 0.1s;
  line-height:1;}
.card-tile:hover .card-tile-check,
.card-tile-check.on{opacity:1;}
.card-tile-check.on{background:var(--accent);border-color:var(--accent);}
.card-tile.is-selected{box-shadow:0 0 0 2px var(--accent);}
/* In list rows the checkbox sits inline at the left edge. */
.card-row .card-tile-check{position:static;flex-shrink:0;margin-right:4px;
  opacity:1;background:transparent;color:var(--text-muted);
  border:1.5px solid var(--border);}
.card-row .card-tile-check.on{background:var(--accent);border-color:var(--accent);color:#fff;}
.card-row.is-selected{background:var(--accent-glow);}

.cards-toast{position:fixed;bottom:calc(24px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);
  background:var(--bg-card);color:var(--text);
  border:1px solid var(--border-accent);border-radius:8px;
  padding:10px 16px;font-size:13px;font-weight:600;
  box-shadow:0 6px 18px rgba(0,0,0,0.18);z-index:100;}
.loading-status{font-size:11px;color:var(--text-muted);letter-spacing:0.3px;
  margin:-1.25rem 0 1rem 36px;font-weight:500;}

/* Sub-tab strip used inside the Market view. Sits at the top of the page,
   below the main nav, with a softer treatment so it reads as secondary. */
.market-subtabs{display:flex;flex-wrap:wrap;gap:4px;align-items:center;
  margin:-4px 0 16px 0;padding-bottom:10px;border-bottom:1px solid var(--border);}

/* ── Price Database ─────────────────────────────────────────────────── */
.price-db{display:flex;flex-direction:column;gap:10px;}
/* Mode bar — prominent Raw / Graded segmented toggle. Sits above the preset
   chips because flipping it changes the entire dataset (raw card prices vs.
   eBay graded sales) and therefore which presets and columns are even
   visible. Treating it as a peer of presets buried it; making it a separate
   bar makes the consequence obvious. */
.price-db-modebar{display:inline-flex;border:1px solid var(--border);
  border-radius:8px;overflow:hidden;background:var(--bg-surface);
  width:fit-content;}
.price-db-modebtn{padding:7px 16px;font-size:12px;font-weight:700;
  font-family:'Cinzel',serif;letter-spacing:0.5px;text-transform:uppercase;
  background:transparent;color:var(--text-muted);border:0;
  border-right:1px solid var(--border);cursor:pointer;transition:all 0.12s;}
.price-db-modebtn:last-child{border-right:0;}
.price-db-modebtn:hover{color:var(--accent);}
.price-db-modebtn.active{background:var(--accent);color:#fff;}
.price-db-presets{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.price-db-preset{padding:5px 12px;font-size:12px;font-weight:600;cursor:pointer;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:14px;}
.price-db-preset:hover{border-color:var(--accent);}
.price-db-preset.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.price-db-filters{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
/* Primary filter row — visually distinct so set/ink/rarity are obviously
   the most-used filters. Slight surface tint + subtle border, no busy
   borders. Secondary row sits below with the rest of the controls. */
.price-db-filters-primary{padding:8px 10px;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:8px;margin-bottom:6px;}
.price-db-filters-primary .price-db-search{flex:1 1 200px;min-width:160px;}
.price-db-filters select,
.price-db-filters input{padding:5px 8px;font-size:12px;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:5px;outline:none;}
.price-db-search{min-width:180px;flex:1;}
.price-db-count{font-size:11px;}
/* Table scrolls in both directions inside its own wrapper so the sticky
   thead + sticky name column actually work — sticky requires a scrolling
   ancestor closer than the viewport. */
.price-db-tablewrap{overflow:auto;max-height:calc(100vh - 280px);
  border:1px solid var(--border);border-radius:8px;}
/* Landscape phones / short windows: the desktop 280px header reservation eats
   so much of the viewport that the table itself rendered at 1.5 rows on a
   411px landscape Android. Drop the cap entirely so the table flows into
   the page and natural page scroll reveals more rows — instead of forcing
   the user to scroll inside a 311px "sub-menu" while the page below sits
   empty. Horizontal scroll on the wrap is preserved (the table is wider
   than the viewport). Tradeoff: the sticky thead stays anchored to the
   top of the wrap (its scroll container) and scrolls with the page rather
   than pinning to the viewport top; pinning the thead to viewport while
   keeping horizontal scroll needs a structural split of header/body and
   is deferred. */
@media (max-height:600px){
  .price-db-tablewrap{max-height:none;}
}
.price-db-table{width:100%;border-collapse:collapse;font-size:12px;}
.price-db-table thead{position:sticky;top:0;z-index:3;background:var(--bg-solid);}
.price-db-table thead th{background:var(--bg-solid);border-bottom:1px solid var(--border);
  box-shadow:0 1px 0 var(--border);}
.price-db-table th{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.3px;
  color:var(--text-muted);text-align:left;padding:8px 8px;border-bottom:1px solid var(--border);
  white-space:nowrap;background:var(--bg-surface);}
.price-db-table th.sortable{cursor:pointer;user-select:none;}
.price-db-table th.sortable:hover{color:var(--accent);}
.price-db-table th.th-num{text-align:right;}
.price-db-table tbody tr{border-bottom:1px solid var(--border);}
.price-db-table tbody tr:hover{background:var(--bg-surface);}
.price-db-table td{padding:5px 8px;vertical-align:middle;}
.price-db-table .td-img{width:32px;}
.price-db-table .td-img img{width:28px;height:39px;object-fit:cover;border-radius:3px;display:block;}
/* Name column: narrow, with the full name WRAPPING to 2 lines (no blank gap,
   no ellipsis truncation) so long names like "Buzz Lightyear - Jungle Rampager"
   read in full while the column stays compact. Meta (grade #cn) stays 1 line. */
.price-db-table .th-name, .price-db-table .td-name{min-width:128px;max-width:186px;width:186px;text-align:left;}
.price-db-table .td-name-link{flex:1;min-width:0;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden;white-space:normal;}
.price-db-table .td-name-meta{display:block;font-size:10px;color:var(--text-muted);
  margin-top:1px;padding-left:0;text-align:left;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* Set column: compact; the set name WRAPS to up to 3 lines so even the longest
   names read in full ("Lorcana Challenge Promo (C1)", "EPCOT Festival of the Arts"
   each need 3 lines at this width) instead of truncating with an ellipsis. Vertical
   wrap (not a wider column) because the table already scrolls horizontally. The td's
   title attr still surfaces the full name on hover. */
.price-db-table .td-set, .price-db-table .th-set{max-width:84px;width:84px;color:var(--text-muted);font-size:11px;}
.price-db-table .td-set{overflow:hidden;display:-webkit-box;-webkit-line-clamp:3;
  -webkit-box-orient:vertical;white-space:normal;line-height:1.18;}
/* Rarity is just a dot icon — minimal column width, but the icon itself can be
   larger than its 18px default for legibility (the column stays narrow). */
.price-db-table .td-rarity, .price-db-table .th-rarity{width:30px;text-align:center;padding-left:2px;padding-right:2px;}
.price-db-table .th-rarity{font-size:9px;letter-spacing:0;}
.price-db-table .td-rarity .rarity-tag-icon{width:24px;height:24px;}
.price-db-table .td-num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;}
.price-db-table .pct-up{color:var(--green);font-weight:600;}
.price-db-table .pct-down{color:var(--red);font-weight:600;}
/* Compact uppercase signal tags. Fixed dimensions so a row with 1 sig
   lines up vertically with a row with 4 sigs — no emoji-soup. */
.price-db-sig{display:inline-block;font-size:10px;font-weight:700;letter-spacing:0.4px;
  padding:2px 6px;border-radius:3px;margin:1px 2px;cursor:help;
  min-width:38px;text-align:center;line-height:1.2;
  border:1px solid transparent;}
.price-db-sig.sig-buy{   background:rgba(220,38,38,0.15); color:#dc2626; border-color:rgba(220,38,38,0.35);}
.price-db-sig.sig-crash{ background:rgba(220,38,38,0.08); color:#dc2626; border-color:rgba(220,38,38,0.20);}
.price-db-sig.sig-disc{  background:rgba(22,163,74,0.15); color:#15803d; border-color:rgba(22,163,74,0.35);}
.price-db-sig.sig-prem{  background:rgba(217,119,6,0.15); color:#b45309; border-color:rgba(217,119,6,0.35);}
.price-db-sig.sig-trend{ background:rgba(37,99,235,0.12); color:#1d4ed8; border-color:rgba(37,99,235,0.30);}
html[data-mode="dark"] .price-db-sig.sig-buy{   color:#fca5a5;}
html[data-mode="dark"] .price-db-sig.sig-crash{ color:#fca5a5;}
html[data-mode="dark"] .price-db-sig.sig-disc{  color:#86efac;}
html[data-mode="dark"] .price-db-sig.sig-prem{  color:#fdba74;}
html[data-mode="dark"] .price-db-sig.sig-trend{ color:#93c5fd;}

/* Inline preset description sentence that swaps based on the active chip. */
.price-db-desc{font-size:11px;line-height:1.4;padding:2px 2px 4px;}

/* Advanced filter drawer — collapses by default; shows a stacked set of
   numeric range inputs that build a Morningstar-style query on top of
   the basic dropdowns. */
.price-db-advbtn{padding:5px 10px;font-size:11px;font-weight:600;cursor:pointer;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:5px;}
.price-db-advbtn:hover{border-color:var(--accent);}
.price-db-adv{display:flex;flex-direction:column;gap:6px;padding:10px 12px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;
  margin-top:-2px;}
.price-db-adv-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.price-db-adv-row label{font-size:11px;font-weight:600;color:var(--text-muted);
  min-width:120px;text-transform:uppercase;letter-spacing:0.3px;}
.price-db-adv-row input,
.price-db-adv-row select{padding:4px 8px;font-size:12px;
  background:var(--bg-card);color:var(--text);border:1px solid var(--border);
  border-radius:5px;outline:none;}
.price-db-adv-row input[type="number"]{width:90px;}
.price-db-adv-row input:focus,
.price-db-adv-row select:focus{border-color:var(--accent);}

/* Batch action bar — surfaces when 1+ rows are selected. Sits above the
   table count line so the user always sees how many are picked + the
   action menu without scrolling. */
.price-db-batchbar{display:flex;align-items:center;gap:8px;padding:8px 12px;
  background:var(--accent-glow);border:1px solid var(--border-accent);
  border-radius:8px;}
.price-db-batchcount{font-size:13px;color:var(--text);}
.price-db-batchbtn{padding:6px 14px;font-size:12px;font-weight:700;cursor:pointer;
  background:var(--accent);color:#fff;border:none;border-radius:6px;}
.price-db-batchbtn:hover{filter:brightness(1.1);}
.price-db-batchmenu{position:absolute;top:calc(100% + 6px);right:0;z-index:200;
  width:280px;background:var(--bg-modal);border:1px solid var(--border);
  border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,0.35);
  padding:4px;display:flex;flex-direction:column;}
.price-db-batchitem{display:block;padding:9px 12px;font-size:13px;font-weight:500;
  cursor:pointer;background:transparent;border:none;text-align:left;
  color:var(--text);text-decoration:none;border-radius:5px;}
.price-db-batchitem:hover:not(:disabled){background:var(--bg-surface-hover,var(--bg-surface));}
.price-db-batchitem:disabled{opacity:0.5;cursor:not-allowed;}
.price-db-toast{position:fixed;bottom:calc(24px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);
  z-index:500;padding:10px 18px;background:var(--accent);color:#fff;
  border-radius:8px;font-size:13px;font-weight:600;
  box-shadow:0 6px 18px rgba(0,0,0,0.3);}

/* Checkbox column + selected-row highlight. */
.price-db-table th.th-check,
.price-db-table td.td-check{width:28px;text-align:center;padding-left:6px;padding-right:0;}
.price-db-table td.td-check input{cursor:pointer;}
.price-db-table tr.price-db-row-sel{background:var(--accent-glow);}
.price-db-table tr.price-db-row-sel:hover{background:var(--accent-glow);}

/* Name cell: clickable name + small ↗ TCGPlayer link beside it. align-items
   flex-start so the ↗ rides the first line when the name wraps to two. */
.price-db-table .td-name-main{display:flex;align-items:flex-start;gap:5px;min-width:0;
  font-weight:600;color:var(--text);line-height:1.2;}
.price-db-table .td-name-link:hover{color:var(--accent);text-decoration:underline;}
.price-db-table .td-tcg-link{display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;font-size:11px;border-radius:4px;
  background:var(--bg-surface);color:var(--text-muted);text-decoration:none;
  border:1px solid var(--border);font-weight:700;flex-shrink:0;}
.price-db-table .td-tcg-link:hover{background:var(--accent);color:#fff;border-color:var(--accent);}

/* Multi-select dropdown for rarities / inks. */
.price-db-multibtn{padding:5px 12px;font-size:12px;font-weight:600;cursor:pointer;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:5px;white-space:nowrap;}
.price-db-multibtn:hover{border-color:var(--accent);}
/* Rarity filter buttons — same selectable-chip pattern the Cards tab uses. */
.price-db-raritybtns{display:inline-flex;flex-wrap:wrap;gap:3px;align-items:center;}
.price-db-raritybtn{padding:4px 10px;font-size:11px;font-weight:600;cursor:pointer;
  background:var(--bg-surface);color:var(--text-muted);border:1px solid var(--border);
  border-radius:14px;letter-spacing:0.2px;}
.price-db-raritybtn:hover{border-color:var(--accent);color:var(--text);}
.price-db-raritybtn.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.price-db-raritybtn.clear{color:var(--accent);border-style:dashed;}
.price-db-colsmenu{position:absolute;top:calc(100% + 4px);right:0;z-index:200;min-width:230px;max-height:360px;overflow-y:auto;
  background:var(--bg-modal);border:1px solid var(--border);border-radius:8px;box-shadow:0 10px 26px rgba(0,0,0,0.4);padding:6px;}
/* Mobile: the absolute right:0 menu grows leftward off the screen edge when the
   ⚙ Columns button sits mid-row (labels got clipped). Pin it as a viewport-anchored
   bottom sheet so the whole list stays on-screen regardless of the button position. */
@media (max-width:720px){
  .price-db-colsmenu{position:fixed;top:auto;left:10px;right:10px;bottom:10px;
    min-width:0;width:auto;max-width:none;max-height:60vh;z-index:300;}
}
.price-db-colsmenu-head{display:flex;align-items:center;justify-content:space-between;padding:4px 6px 7px;
  font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-muted);border-bottom:1px solid var(--border);margin-bottom:4px;}
.price-db-colsmenu-reset{appearance:none;background:transparent;border:1px solid var(--border);border-radius:5px;
  font-size:10px;font-weight:700;padding:2px 7px;cursor:pointer;color:var(--text-dim);text-transform:none;letter-spacing:0;}
.price-db-colsmenu-reset:hover{border-color:var(--accent);color:var(--accent);}
.price-db-colsmenu-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:3px 6px;border-radius:5px;}
.price-db-colsmenu-row:hover{background:var(--bg-surface);}
.price-db-colsmenu-lbl{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text);cursor:pointer;flex:1;min-width:0;}
.price-db-colsmenu-lbl input{cursor:pointer;}
.price-db-colsmenu-move{display:inline-flex;gap:2px;flex-shrink:0;}
.price-db-colsmenu-move button{appearance:none;background:var(--bg-card);border:1px solid var(--border);border-radius:4px;
  width:20px;height:20px;font-size:9px;cursor:pointer;color:var(--text-dim);display:flex;align-items:center;justify-content:center;padding:0;}
.price-db-colsmenu-move button:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.price-db-colsmenu-move button:disabled{opacity:0.3;cursor:default;}
.price-db-multimenu{position:absolute;top:calc(100% + 4px);left:0;z-index:200;
  min-width:170px;max-height:320px;overflow-y:auto;
  background:var(--bg-modal);border:1px solid var(--border);border-radius:7px;
  box-shadow:0 8px 20px rgba(0,0,0,0.35);padding:4px;
  display:flex;flex-direction:column;gap:1px;}
.price-db-multiitem{display:flex;align-items:center;gap:8px;padding:6px 10px;
  font-size:13px;cursor:pointer;border-radius:4px;color:var(--text);user-select:none;}
.price-db-multiitem:hover{background:var(--bg-surface);}
.price-db-multiitem input{cursor:pointer;}
.price-db-multiclear{margin-top:4px;padding:5px 10px;font-size:11px;font-weight:600;
  cursor:pointer;background:transparent;border:none;color:var(--accent);text-align:left;}
.price-db-multiclear:hover{background:var(--accent-glow);border-radius:4px;}

/* Window-picker chips shown only for Gainers / Losers presets. */
.price-db-winrow{display:flex;flex-wrap:wrap;align-items:center;gap:5px;}
.price-db-winchip{padding:4px 11px;font-size:11px;font-weight:700;cursor:pointer;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:12px;letter-spacing:0.3px;}
.price-db-winchip:hover{border-color:var(--accent);}
.price-db-winchip.active{background:var(--accent);color:#fff;border-color:var(--accent);}

/* Secondary toolbar (collection chips + signal filter chips) sits below the
   preset description so the main toolbar stays uncluttered. */
.price-db-secondary{display:flex;flex-wrap:wrap;gap:12px;align-items:center;
  padding:4px 2px;}
.price-db-collchips{display:inline-flex;gap:0;}
.price-db-collchip{padding:4px 12px;font-size:11px;font-weight:700;cursor:pointer;
  background:var(--bg-surface);color:var(--text-muted);
  border:1px solid var(--border);letter-spacing:0.3px;}
.price-db-collchip:first-child{border-radius:14px 0 0 14px;}
.price-db-collchip:last-child{border-radius:0 14px 14px 0;border-left:none;}
.price-db-collchip:nth-child(2){border-left:none;border-right:none;}
.price-db-collchip:hover:not(.active){background:var(--bg-card);color:var(--text);}
.price-db-collchip.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.price-db-sigfilter{display:inline-flex;flex-wrap:wrap;gap:4px;align-items:center;}
.price-db-sigchip{font-size:10px;font-weight:700;letter-spacing:0.4px;
  padding:3px 8px;border-radius:4px;cursor:pointer;
  background:transparent;border:1px solid var(--border);color:var(--text-muted);
  min-width:42px;text-align:center;}
.price-db-sigchip:hover{border-color:var(--accent);color:var(--text);}
.price-db-sigchip.active.sig-buy{   background:rgba(220,38,38,0.18); color:#dc2626; border-color:#dc2626;}
.price-db-sigchip.active.sig-crash{ background:rgba(220,38,38,0.10); color:#dc2626; border-color:#dc2626;}
.price-db-sigchip.active.sig-disc{  background:rgba(22,163,74,0.18); color:#15803d; border-color:#15803d;}
.price-db-sigchip.active.sig-prem{  background:rgba(217,119,6,0.18); color:#b45309; border-color:#b45309;}
.price-db-sigchip.active.sig-trend{ background:rgba(37,99,235,0.15); color:#1d4ed8; border-color:#1d4ed8;}

/* Compact screener density. The class is built dynamically as "density-"+density
   (Index.html) and the value persists in localStorage `packsink:screener:density`
   and in saved screener-view payloads, so these rules must stay even though the
   current UI no longer exposes a toggle to enter compact — existing users can
   still be in it. Do NOT remove (a literal grep for "density-compact" finds
   nothing because the token is string-concatenated). */
.price-db.density-compact .price-db-table{font-size:11px;}
.price-db.density-compact .price-db-table th,
.price-db.density-compact .price-db-table td{padding:3px 6px;}
.price-db.density-compact .price-db-table .td-img img{width:22px;height:31px;}
.price-db.density-compact .price-db-table .td-name-meta{font-size:9px;}

/* Highlight the active sort column so users see why a row is at the top. */
.price-db-table th.sort-active{color:var(--accent);}
.price-db-table td.sort-active{background:var(--accent-glow);}

/* Saved-view chips at the top of the page. Each chip = a stored snapshot
   of the user's filter + preset state. */
.price-db-savedviews{display:flex;flex-wrap:wrap;gap:6px;align-items:center;
  padding:6px 10px;background:var(--bg-surface);border:1px dashed var(--border);
  border-radius:8px;}
.price-db-savedchip{display:inline-flex;align-items:stretch;
  background:var(--bg-card);border:1px solid var(--border);border-radius:14px;
  overflow:hidden;}
.price-db-savedchip button{padding:4px 10px;font-size:11px;font-weight:600;
  cursor:pointer;background:transparent;border:none;color:var(--text);}
.price-db-savedchip button:hover{background:var(--accent-glow);color:var(--accent);}
.price-db-savedclose{padding:4px 8px !important;color:var(--text-muted) !important;
  border-left:1px solid var(--border) !important;font-weight:700;font-size:12px !important;}
.price-db-savedclose:hover{color:var(--red) !important;background:transparent !important;}

/* Pin the name column horizontally — handy when scrolling right to see
   far-out Δ% columns. Uses position:sticky on the third <td>/<th>. The
   nth-child here matches the post-ink column order. */
.price-db-table th:nth-child(3),
.price-db-table td:nth-child(3){position:sticky;left:0;z-index:2;
  background:var(--bg-modal);
  /* Right-edge separator + shadow so other columns visually pass UNDER this
     sticky column instead of overlapping when horizontally scrolling. */
  box-shadow:1px 0 0 var(--border), 6px 0 8px -6px rgba(0,0,0,0.35);}
.price-db-table tbody tr:hover td:nth-child(3){background:var(--bg-modal);}
.price-db-table thead th:nth-child(3){z-index:4;background:var(--bg-modal);}
.price-db-table tr.price-db-row-sel td:nth-child(3){background:var(--accent-glow);}

/* Mobile: trim padding, hide image / set / rarity columns AND the checkbox
   (the checkbox is functionally invisible on mobile anyway — the sticky
   NAME column overlays it permanently — but it still occupied 28px of
   table width). Columns rendered are:
   [1] checkbox · [2] image · [3] name+meta · [4] set · [5] rarity ·
   [6] Low · [7] NM Market · [8+] Δ% windows · [last] signals
   With checkbox/image/set/rarity hidden and NAME tightened to 110-135px,
   the default no-scroll view fits NAME + Low + NM Market + 1W on a
   standard 360-414px phone, which is what the user asked for. Batch-select
   via checkbox stays available on tablet/desktop. */
@media (max-width: 720px){
  .price-db-table{font-size:11px;}
  .price-db-table th, .price-db-table td{padding:3px 4px;}
  .price-db-table th:nth-child(1), .price-db-table td:nth-child(1){display:none;} /* checkbox */
  .price-db-table th:nth-child(2), .price-db-table td:nth-child(2){display:none;} /* image */
  .price-db-table th:nth-child(4), .price-db-table td:nth-child(4){display:none;} /* set */
  .price-db-table th:nth-child(5), .price-db-table td:nth-child(5){display:none;} /* rarity */
  .price-db-table th:nth-child(3), .price-db-table td:nth-child(3){min-width:110px;max-width:135px;}
  /* Tighten the icon-only rarity chips so all 9 canonical rarities fit on a
     single row on phones. At the desktop 4px 10px padding + 3px gap, the
     9-chip strip (~380px) wrapped the last chip (Promo) onto a second line
     on a ~375px viewport. Trimmed padding + gap keep them on one line. */
  .price-db-raritybtns{gap:2px;}
  .price-db-raritybtn-icon{padding:4px 5px;gap:0;}
}
.market-subtab{padding:5px 12px;font-size:12px;font-weight:600;
  background:transparent;color:var(--text-dim);
  border:1px solid transparent;border-radius:6px;cursor:pointer;
  transition:background 0.1s,color 0.1s,border-color 0.1s;}
.market-subtab:hover{color:var(--text);background:var(--bg-surface);}
.market-subtab.active{color:var(--accent);background:var(--accent-glow);
  border-color:var(--border-accent);}
.market-sim-kind{display:inline-flex;margin-left:6px;
  border:1px solid var(--border);border-radius:6px;overflow:hidden;}
.market-sim-kind button{background:transparent;color:var(--text-muted);
  border:none;padding:4px 12px;font-size:11px;font-weight:600;cursor:pointer;}
.market-sim-kind button:hover{color:var(--text);background:var(--bg-surface-hover);}
.market-sim-kind button.active{background:var(--accent);color:#fff;}
.market-flag{display:flex;align-items:center;gap:5px;font-size:12px;
  cursor:pointer;color:var(--text-dim);margin-left:8px;}

/* ── Card Averages set-chip selector + EV row ─────────────────────────── */
.card-avg-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-bottom:14px;}
.card-avg-chips-lbl{font-size:11px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);margin-right:4px;}
.card-avg-chip{font-size:11px;font-weight:600;padding:4px 10px;
  background:transparent;color:var(--text-dim);
  border:1px solid var(--border);border-radius:14px;cursor:pointer;
  transition:background 0.1s,color 0.1s,border-color 0.1s;}
.card-avg-chip:hover{color:var(--text);border-color:var(--border-accent);}
.card-avg-chip.active{background:var(--accent-glow);color:var(--accent);
  border-color:var(--border-accent);}
.card-avg-chip-reset{font-size:11px;font-weight:600;padding:4px 10px;
  background:transparent;color:var(--text-muted);
  border:1px solid var(--border);border-radius:14px;cursor:pointer;margin-left:4px;}
.card-avg-chip-reset:hover{color:var(--text);border-color:var(--border-accent);}
.card-avg-mode-hint{font-size:11px;color:var(--text-muted);font-style:italic;margin-left:8px;}
.card-avg-set-head{background:transparent;border:none;padding:0;cursor:pointer;
  color:inherit;font:inherit;display:inline-flex;align-items:center;gap:3px;}
.card-avg-set-head:hover{color:var(--accent);}
.card-avg-set-head-hint{font-size:10px;opacity:0;transition:opacity 0.1s;}
.card-avg-set-head:hover .card-avg-set-head-hint{opacity:1;}
.card-avg-ev-row td{border-top:2px solid var(--border);padding-top:10px;}

/* ── Expected Value view ──────────────────────────────────────────────── */
.ev-view{display:flex;flex-direction:column;gap:14px;}

/* Header card: title + integrated toggle controls. The toggles use the
   same visual language as the rest of the site's stat cards. */
.ev-header{background:var(--bg-card);border:1px solid var(--border);border-radius:12px;
  padding:18px 20px;display:flex;flex-wrap:wrap;gap:14px;align-items:center;}
.ev-header-title{flex:0 1 auto;min-width:0;margin-right:6px;}
.ev-header-eyebrow{font-size:10px;font-weight:700;letter-spacing:1px;
  text-transform:uppercase;color:var(--text-muted);margin-bottom:4px;}
.ev-header-h2{font-family:'Cinzel',serif;font-size:22px;font-weight:600;
  color:var(--accent);margin:0 0 4px 0;line-height:1.1;}
.ev-header-sub{font-size:12px;color:var(--text-muted);line-height:1.45;}

.ev-toggles{display:flex;gap:10px;flex-wrap:wrap;}
.ev-toggle{display:flex;align-items:center;gap:10px;padding:9px 14px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;
  cursor:pointer;transition:border-color 0.12s,background 0.12s,box-shadow 0.12s;
  min-width:200px;}
.ev-toggle:hover{border-color:var(--border-accent);}
.ev-toggle.on{background:var(--accent-glow);border-color:var(--border-accent);
  box-shadow:inset 0 0 0 1px var(--border-accent);}
.ev-toggle input{margin:0;width:14px;height:14px;cursor:pointer;accent-color:var(--accent);}
.ev-toggle-text{display:flex;flex-direction:column;gap:1px;}
.ev-toggle-title{font-size:13px;font-weight:700;color:var(--text);line-height:1.1;}
.ev-toggle.on .ev-toggle-title{color:var(--accent);}
.ev-toggle-sub{font-size:10px;color:var(--text-muted);font-variant-numeric:tabular-nums;line-height:1.1;}

/* Grouped "exclude chase rarities" toggle — one master button plus two
   sub-checkboxes so users can drop just Enchanted or just Iconic. */
.ev-toggle-group{flex-direction:column;align-items:stretch;gap:6px;padding:6px 10px 8px;}
.ev-toggle-group-btn{background:transparent;border:none;color:inherit;font:inherit;
  text-align:left;cursor:pointer;padding:4px 4px 2px;}
.ev-toggle-group-rows{display:flex;gap:10px;font-size:11px;color:var(--text-muted);
  border-top:1px dashed var(--border);padding-top:6px;margin-top:2px;}
.ev-toggle-sub-row{display:flex;align-items:center;gap:4px;cursor:pointer;}
.ev-toggle-sub-row input{margin:0;width:13px;height:13px;accent-color:var(--accent);}
.ev-toggle-sub-row.on{color:var(--accent);font-weight:600;}

/* Compact Low / Market segmented control embedded in each analytics
   sub-view's filter row (replaces the old subtab-strip placement). */
.price-mode-toggle{display:inline-flex;align-items:center;gap:6px;
  padding:4px 6px 4px 10px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:8px;}
.price-mode-label{font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.price-mode-toggle button{padding:4px 10px;background:transparent;
  color:var(--text-muted);border:none;border-radius:6px;
  cursor:pointer;font-size:12px;font-weight:600;transition:all 0.12s;}
.price-mode-toggle button:hover{color:var(--text);background:var(--bg-surface-hover);}
.price-mode-toggle button.active{background:var(--accent);color:#fff;}

/* Explainer banner shown at the top of analytics sub-views to define
   what the table actually means. Kept lightweight — small caption +
   bulleted glossary, no heavy chrome. */
.market-explainer{font-size:12px;color:var(--text-dim);line-height:1.55;
  background:var(--bg-surface);border:1px solid var(--border);
  border-left:3px solid var(--accent);border-radius:6px;
  padding:10px 14px;margin-bottom:14px;}
.market-explainer strong{color:var(--text);}
.market-explainer-defs{margin:6px 0 0;padding-left:18px;color:var(--text-muted);}
.market-explainer-defs li{margin:2px 0;}

/* Filter row shared by Card Averages / Playset Cost / Heatmap — wraps
   the price toggle and any view-specific filters together. */
.market-filter-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  margin-bottom:12px;}
.market-filter-spacer{flex:1;}

/* Simulate sub-tab kind selector — dropdown replaces the old button pair. */
.sim-kind-bar{display:flex;gap:10px;align-items:center;
  padding:10px 12px;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:8px;margin-bottom:14px;}
.sim-kind-label{font-size:11px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.sim-kind-select{padding:6px 10px;font-size:13px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:6px;color:var(--text);
  min-width:300px;}

/* Playset Cost — expanded card list rows. Clickable rows open the card
   modal; the TCG button next to each name jumps straight to TCGPlayer. */
.playset-row{transition:background 0.1s;}
.playset-row.clickable{cursor:pointer;}
.playset-row.clickable:hover{background:var(--accent-glow);}
.playset-tcg-btn{display:inline-block;margin-left:8px;padding:1px 6px;font-size:10px;
  font-weight:700;letter-spacing:0.3px;color:var(--accent);background:var(--accent-glow);
  border:1px solid var(--border-accent);border-radius:4px;text-decoration:none;
  vertical-align:middle;transition:all 0.1s;}
.playset-tcg-btn:hover{background:var(--accent);color:#fff;border-color:var(--accent);}

/* Sealed header layout — title block on the left, price toggle on the right. */
.sealed-header{display:flex;align-items:flex-start;justify-content:space-between;
  gap:18px;margin-bottom:14px;flex-wrap:wrap;}
.sealed-header-text{flex:1;min-width:240px;}

/* Per-set rows */
.ev-rows{display:flex;flex-direction:column;gap:6px;}
.ev-row{display:grid;grid-template-columns:1fr 180px 1fr;column-gap:18px;
  align-items:center;padding:11px 16px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:10px;
  transition:border-color 0.1s,background 0.1s;}
/* When sealed prices are loaded we insert a Box-price column between EV and the windows. */
.ev-rows.with-box .ev-row{grid-template-columns:1fr 180px 180px 1fr;}
/* Inline per-cell label rendered in every data row. Hidden on desktop
   (head row carries the column labels there) and flipped to block by
   the @media (max-width:780px) override below. Must be declared BEFORE
   the @media block so the cascade source-order tiebreaker lets the
   media rule win when the viewport matches. */
.ev-row-val-lbl-inline{display:none;}
@media (max-width:780px){
  /* Mobile layout: set name → ev/box stacked label+value below. Deltas
     hidden (tap the row to see per-window detail in the price history
     modal). Each value cell carries its own inline label so the user
     can tell EV/Box from EV/Pack from Box Price without the head row.
     Designed to never overflow, even on narrow phones. */
  .ev-row, .ev-rows.with-box .ev-row{
    grid-template-columns:1fr 1fr !important;
    grid-template-rows:auto auto;
    row-gap:10px;column-gap:10px;padding:12px;}
  .ev-row-set{font-size:13px;grid-column:1 / -1;grid-row:1;}
  .ev-row-vals{grid-column:1;grid-row:2;justify-content:flex-start;gap:14px;flex-wrap:wrap;align-items:flex-end;}
  .ev-row-box{grid-column:2;grid-row:2;justify-content:flex-end;gap:10px;flex-wrap:wrap;align-items:flex-end;}
  /* Higher-specificity selector (.ev-rows .ev-row-deltas) beats the
     top-level `.ev-row-deltas{display:grid}` rule without relying on
     !important — defends against any caching layer that strips the
     important annotation during stylesheet parse. */
  .ev-rows .ev-row-deltas, .ev-row .ev-row-deltas{display:none !important;}
  .ev-row-head{display:none;}
  /* Stack inline label above value. tabular-nums on the values keeps
     adjacent columns visually aligned despite different digit counts. */
  .ev-row-val{font-size:14px;min-width:0;align-items:flex-start;}
  .ev-row-box .ev-row-val,
  .ev-row-box .ev-box-diff{align-items:flex-end;text-align:right;}
  .ev-row-val-dim{font-size:13px;}
  .ev-box-diff{font-size:13px;min-width:0;padding:4px 8px;display:inline-flex;flex-direction:column;
    align-items:flex-end;gap:1px;line-height:1.05;}
  .ev-box-link{font-size:14px;}
  .ev-row-val-lbl-inline{display:block;font-size:9px;font-weight:700;letter-spacing:0.5px;
    text-transform:uppercase;color:var(--text-muted);line-height:1;margin-bottom:2px;}
  /* Diff badge has a tinted bg, so its inline label needs to read against it. */
  .ev-box-diff .ev-row-val-lbl-inline{opacity:0.85;}
}
.ev-row-box{display:flex;gap:14px;justify-content:flex-end;align-items:baseline;}
.ev-row:not(.ev-row-head):hover{border-color:var(--border-accent);
  background:var(--bg-surface);}
.ev-row-head{background:transparent;border:none;padding:2px 16px 4px;
  font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.ev-row-set{font-size:14px;font-weight:600;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ev-row-set-hint{display:inline-block;margin-left:6px;font-size:11px;
  color:var(--text-muted);opacity:0;transition:opacity 0.12s;}
.ev-row-clickable{cursor:pointer;}
.ev-row-clickable:hover .ev-row-set{color:var(--accent);}
.ev-row-clickable:hover .ev-row-set-hint{opacity:1;}
.ev-row-clickable:focus-visible{outline:2px solid var(--accent);outline-offset:1px;}
.ev-row-vals{display:flex;gap:14px;justify-content:flex-end;align-items:baseline;}
.ev-row-val{display:flex;flex-direction:column;align-items:flex-end;gap:1px;
  font-size:18px;font-weight:700;color:var(--text);
  font-variant-numeric:tabular-nums;min-width:78px;line-height:1.1;}
.ev-row-val-dim{font-size:13px;color:var(--text-dim);font-weight:600;}
.ev-row-val-lbl{font-size:9px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.ev-row-deltas{display:grid;grid-template-columns:repeat(6,1fr);column-gap:4px;}
/* Head-row wrapper that stacks an "EV change" label above the 1D-1Y heads —
   makes it obvious those pills measure EV-over-time, not EV-vs-box. Only
   used in the head row; data rows still have the bare .ev-row-deltas. */
.ev-row-deltas-wrap{display:flex;flex-direction:column;gap:4px;align-items:stretch;}
.ev-row-deltas-title{font-size:9px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);text-align:center;
  padding-bottom:2px;border-bottom:1px dashed var(--border);}
.ev-delta-cell{display:flex;align-items:center;justify-content:center;gap:2px;
  font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;
  padding:4px 6px;border-radius:6px;text-align:center;line-height:1;}
.ev-delta-head{background:transparent;color:var(--text-muted);font-size:10px;
  letter-spacing:0.4px;text-transform:uppercase;font-weight:700;padding:0;}
.ev-delta-up{background:rgba(22,101,52,0.14);color:var(--green);}
.ev-delta-down{background:rgba(153,27,27,0.12);color:var(--red);}
.ev-delta-flat{background:var(--bg-surface);color:var(--text-dim);}
.ev-delta-none{background:transparent;color:var(--text-muted);opacity:0.45;}
/* Box price link + diff badge */
.ev-box-link{color:var(--accent);text-decoration:none;display:inline-flex;align-items:baseline;gap:2px;}
.ev-box-link:hover{text-decoration:underline;}
.ev-box-link-ext{font-size:10px;opacity:0.7;}
.ev-box-diff{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;
  padding:3px 8px;border-radius:6px;min-width:60px;text-align:right;line-height:1.1;}
.ev-box-diff-up{background:rgba(22,101,52,0.18);color:var(--green);}
.ev-box-diff-down{background:rgba(153,27,27,0.16);color:var(--red);}
.ev-box-diff-flat{background:var(--bg-surface);color:var(--text-dim);}
.ev-box-diff-none{background:transparent;color:var(--text-muted);opacity:0.45;font-weight:500;}
html[data-mode="dark"] .ev-box-diff-up{background:rgba(127,217,165,0.15);color:#7fd9a5;}
html[data-mode="dark"] .ev-box-diff-down{background:rgba(232,140,140,0.15);color:#e88c8c;}
.ev-delta-arrow{font-size:8px;opacity:0.85;}
html[data-mode="dark"] .ev-delta-up{background:rgba(127,217,165,0.12);color:#7fd9a5;}
html[data-mode="dark"] .ev-delta-down{background:rgba(232,140,140,0.12);color:#e88c8c;}

/* Was a redundant @media (max-width:820px) block that fought the 780px
   rule above (and that left the data rows missing their column labels on
   mobile because the head row gets display:none'd). The 780px rule is the
   canonical mobile layout; inline labels per-cell handle the head-row gap. */

/* ── Sealed view ──────────────────────────────────────────────────────── */
.sealed-view{display:flex;flex-direction:column;gap:22px;}
.sealed-header{background:var(--bg-card);border:1px solid var(--border);
  border-radius:12px;padding:18px 20px;}
.sealed-set{display:flex;flex-direction:column;gap:8px;}
.sealed-set-header{display:flex;align-items:baseline;gap:8px;
  padding:4px 4px 6px;border-bottom:1px solid var(--border);}
.sealed-set-title{font-family:'Cinzel',serif;font-size:16px;font-weight:600;
  color:var(--accent);background:transparent;border:none;padding:0;
  display:inline-flex;align-items:center;gap:4px;}
button.sealed-set-title{cursor:pointer;}
span.sealed-set-title{cursor:default;}
button.sealed-set-title:hover{text-decoration:underline;}
.sealed-set-count{font-size:11px;color:var(--text-muted);font-weight:600;
  padding:1px 8px;border-radius:10px;background:var(--bg-surface);
  border:1px solid var(--border);font-variant-numeric:tabular-nums;}
/* Per-row clickable set pill that routes to Price Graphing. Replaces the
   product-type pill now that the section header carries the type. */
.sealed-set-pill{display:inline-flex;align-items:center;gap:3px;
  padding:4px 10px;font-size:11px;font-weight:600;
  background:transparent;color:var(--text-dim);
  border:1px solid var(--border);border-radius:14px;
  text-align:left;font-family:inherit;
  transition:background 0.1s,color 0.1s,border-color 0.1s;}
button.sealed-set-pill{cursor:pointer;}
button.sealed-set-pill:hover{color:var(--accent);
  border-color:var(--border-accent);background:var(--accent-glow);}
.sealed-set-pill-muted{cursor:default;color:var(--text-muted);}
/* Analytics sub-tabs (Sim Pack, Box Sim, Monte Carlo) render stat rows
   inline with `repeat(4,1fr)` / `repeat(3,1fr)`. Force a wrap on phones
   so each $ figure has room without overlapping its neighbor. */
@media (max-width:560px){
  .sim-kind-select{min-width:0;width:100%;}
  .stat-grid.stat-grid-4{grid-template-columns:repeat(2,minmax(0,1fr)) !important;}
  .stat-grid.stat-grid-3{grid-template-columns:repeat(2,minmax(0,1fr)) !important;}
}
.sealed-rows{display:flex;flex-direction:column;gap:5px;}
.sealed-row{display:grid;grid-template-columns:140px 1fr 90px 1fr;column-gap:14px;
  align-items:center;padding:9px 14px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:8px;
  transition:border-color 0.1s,background 0.1s;}
@media (max-width:780px){
  /* Mobile layout: set pill + name on row 1, price on row 2.
     Six-window delta pills hidden — they were rendering without any time-
     window labels (head row is hidden), so users saw "▼1.4%, ▼4.4%, ▼93.2%"
     with no idea which span each meant. Tap the row to open the price-
     history modal for detail.
     The redundant @media (max-width:820px) block that used to follow this
     one — and silently fought it — has been removed; this is the canonical
     mobile sealed-row layout. */
  .sealed-row{grid-template-columns:auto 1fr !important;
    grid-template-rows:auto auto;row-gap:6px;column-gap:10px;padding:10px 12px;}
  .sealed-row-set{grid-column:1;grid-row:1;align-self:center;}
  .sealed-row-name{grid-column:2;grid-row:1;font-size:13px;}
  .sealed-row-price{grid-column:1 / -1;grid-row:2;justify-self:flex-start;
    text-align:left;font-size:15px;}
  .sealed-row-deltas{display:none !important;}
  .sealed-row-head{display:none;}
  /* Set pill stays visible on mobile — sections aren't always obvious when
     scrolling fast and the pill is cheap. Compact width via shorter padding. */
  .sealed-set-pill, .sealed-set-pill-muted{padding:3px 7px;font-size:10px;}
}
.sealed-row:not(.sealed-row-head):hover{border-color:var(--border-accent);
  background:var(--bg-surface);}
.sealed-row-head{background:transparent;border:none;padding:0 14px 2px;
  font-size:10px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;
  color:var(--text-muted);}
.sealed-row-set{display:flex;justify-content:flex-start;min-width:0;}
.sealed-row-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:13px;font-weight:500;color:var(--text);}
.sealed-row-name a{color:inherit;text-decoration:none;display:inline-flex;
  align-items:center;gap:3px;}
.sealed-row-name a:hover{color:var(--accent);}
.sealed-name-ext{font-size:10px;opacity:0.55;}
.sealed-row-name a:hover .sealed-name-ext{opacity:1;}
.sealed-row-price{font-size:15px;font-weight:700;color:var(--text);
  text-align:right;font-variant-numeric:tabular-nums;}
.sealed-row-deltas{display:grid;grid-template-columns:repeat(6,1fr);column-gap:4px;}

/* @media (max-width:820px) block removed — was a duplicate of the 780px
   rule above that fought with it (single-column + no explicit child grid
   positions made the delta pills land in unpredictable cells). The 780px
   block is canonical. */
.stat{background:var(--stat-bg);border:1px solid var(--border);border-radius:8px;padding:10px 14px;}
.stat .lbl{font-size:11px;color:var(--text-muted);margin-bottom:3px;text-transform:uppercase;letter-spacing:0.3px;}
.stat .val{font-size:16px;font-weight:600;}
.card{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:9px;display:flex;flex-direction:column;gap:4px;transition:border-color 0.15s,transform 0.08s;}
.card:hover{border-color:var(--border-accent);}
.card.clickable{cursor:pointer;}
.card.clickable:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(0,0,0,0.08);}
.sim-buy-btn{display:flex;align-items:center;justify-content:center;gap:4px;margin-top:auto;padding:6px 10px;font-size:13px;font-weight:700;color:#fff;background:rgba(22,101,52,0.95);border-radius:6px;text-decoration:none;font-variant-numeric:tabular-nums;transition:background 0.1s;}
.sim-buy-btn:hover{background:rgba(22,101,52,1);}
.sim-buy-btn.disabled{background:var(--bg-surface);color:var(--text-muted);cursor:default;}
.sim-buy-ext{font-size:10px;opacity:0.85;}
.badge{font-size:10px;font-weight:600;padding:2px 6px;border-radius:4px;display:inline-block;white-space:nowrap;letter-spacing:0.3px;}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:1rem;}
.scr{overflow-x:auto;}
/* Home page never needs horizontal scroll — inner banners have their own
   scroll containers, and the tournament/banner row is sized in % units.
   `clip` prevents any stray descendant from making the whole page nudge
   sideways on mobile. */
.scr-home{overflow-x:clip;}
.green{color:var(--green);} .red{color:var(--red);} .muted{color:var(--text-muted);}
.card-img{width:100%;border-radius:6px;aspect-ratio:5/7;object-fit:cover;background:var(--bg-surface);}
.card-img-placeholder{width:100%;border-radius:6px;aspect-ratio:5/7;background:var(--bg-surface);display:flex;align-items:center;justify-content:center;color:var(--text-muted);font-size:10px;}
.progress-bar{width:100%;height:4px;background:var(--bg-surface);border-radius:2px;overflow:hidden;margin-top:8px;}
.progress-fill{height:100%;background:linear-gradient(90deg,var(--accent),#d4b85a);transition:width 0.3s ease;border-radius:2px;}
.footer{margin-top:3rem;padding:1.5rem 0;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:flex-end;gap:16px;}
/* On mobile the desktop's generous 3rem margin-top + 1.5rem padding-top
   (~72px combined) reads as wasted blank space below in-page content like
   the deck editor's stats/charts panel — the bottom of the panel ends up
   floating mid-screen even when scrolled to the very bottom of the page.
   Tighten both on phones so the content panel sits close to the footer
   without crowding it. */
@media (max-width:640px){
  .footer{margin-top:1rem;padding:0.75rem 0;gap:10px;}
}
.footer-logo{height:36px;opacity:0.85;border-radius:4px;}
.footer-logos{display:flex;align-items:center;gap:12px;flex-shrink:0;}
.footer-logo-packsink{height:48px;opacity:1;border-radius:0;}
/* Deck poster export — grouped options panel. Each group is its own card
   so Background/Columns/Show/Costs/Share read as distinct controls. */
/* Export Deck Image modal: two-pane layout — compact controls column on the
   left (Copy/Save up top, then options stacked tightly) and the poster preview
   on the right so it's visible without scrolling on desktop. Stacks vertically
   on mobile. */
/* .modal.modal-poster (two classes) so it beats the later `.modal{max-width:900px}`
   rule on specificity rather than source order — see "CSS pitfalls" in CLAUDE.md. */
.modal.modal-poster{max-width:1080px;}
.deck-poster-layout{display:flex;gap:18px;align-items:flex-start;}
.deck-poster-controls{flex:0 0 296px;display:flex;flex-direction:column;gap:12px;min-width:0;}
.deck-poster-preview{flex:1 1 auto;min-width:0;overflow:hidden;}
.deck-poster-actions{display:flex;gap:8px;flex-wrap:wrap;}
.deck-poster-actions button{flex:1 1 110px;padding:9px 14px;font-size:13px;white-space:nowrap;}
.deck-poster-hint{font-size:11px;line-height:1.4;color:var(--text-muted);}
.poster-toast{padding:8px 12px;font-size:12px;font-weight:600;background:var(--accent-glow);
  border:1px solid var(--border-accent);color:var(--accent);border-radius:6px;}
@media (max-width:760px){
  /* align-items:stretch (vs the row layout's flex-start) so the stacked panes
     fill the modal width — otherwise the preview shrinks to the poster's 1000px
     natural width and overflows the modal horizontally. */
  .deck-poster-layout{flex-direction:column;align-items:stretch;}
  .deck-poster-controls{flex:none;width:100%;}
}
.poster-options{display:flex;flex-direction:column;gap:10px;}
.poster-options-group{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:10px 12px;}
.poster-options-head{font-size:11px;font-weight:700;letter-spacing:0.4px;text-transform:uppercase;color:var(--text-muted);margin-bottom:8px;display:flex;align-items:center;gap:8px;}
.poster-options-sublbl{font-size:10px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:var(--text-muted);margin-bottom:4px;}
.poster-options-row{display:flex;gap:14px;flex-wrap:wrap;}
.poster-share-lockhint{font-size:10px;font-weight:500;color:var(--text-dim);text-transform:none;letter-spacing:0;}
.chip.chip-locked{opacity:0.7;cursor:pointer;font-style:italic;}
.chip.chip-locked:disabled{cursor:not-allowed;opacity:0.4;}
.chip.chip-locked:not(:disabled):hover{opacity:1;border-color:var(--accent);}
.poster-share-quick{display:flex;align-items:center;gap:6px;flex-basis:100%;margin-top:6px;
  padding-top:8px;border-top:1px dashed var(--border);font-size:11px;color:var(--text-muted);}
.footer-text{text-align:right;line-height:1.6;}
.footer-social a{font-size:11px;color:var(--accent);text-decoration:none;opacity:0.8;}
.footer-social a:hover{opacity:1;text-decoration:underline;}
.footer-disclosure{font-size:10px;color:var(--text-muted);margin-top:6px;max-width:520px;line-height:1.4;}
.theme-toggle{cursor:pointer;background:none;border:1px solid var(--btn-border);border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:16px;color:var(--text-dim);padding:0;transition:all 0.15s;}
.theme-toggle:hover{border-color:var(--accent);color:var(--accent);}
/* Tooltip */
.tip-wrap{position:relative;display:inline-flex;align-items:center;cursor:help;}
.tip-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;border:1px solid var(--btn-border);font-size:10px;font-weight:600;color:var(--text-muted);margin-left:4px;flex-shrink:0;}
.tip-wrap:hover .tip-icon{border-color:var(--accent);color:var(--accent);}
.tip-box{display:none;position:absolute;top:calc(100% + 8px);left:50%;transform:translateX(-50%);width:240px;padding:10px 12px;background:var(--tooltip-bg);border:1px solid var(--tooltip-border);border-radius:8px;box-shadow:var(--tooltip-shadow);font-size:12px;line-height:1.5;color:var(--text);z-index:100;pointer-events:none;text-align:left;font-weight:400;}
.tip-wrap:hover .tip-box{display:block;}
@media(max-width:600px){.tip-box{left:auto;right:0;transform:none;width:200px;}}
/* Best card highlight */
.best-card-display{background:var(--bg-card);border:1px solid var(--border-accent);border-radius:10px;padding:12px;text-align:center;max-width:180px;}
.best-card-display img{width:100%;border-radius:6px;margin-bottom:6px;}
/* FAQ */
.faq-section{max-width:720px;}
.faq-section h2{font-size:16px;font-weight:600;color:var(--accent);margin:1.5rem 0 0.5rem;}
.faq-section p,.faq-section li{font-size:13px;line-height:1.7;color:var(--text-dim);}
.faq-section strong{color:var(--text);font-weight:600;}
/* Cards tab ------------------------------------------------------------- */
.cards-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:14px;padding:10px;background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;}
@media (max-width:640px){
  /* Tighter filter box on phones — was eating ~40% of the viewport vertically. */
  .cards-toolbar{padding:6px;gap:6px;margin-bottom:10px;border-radius:8px;}
  .cards-toolbar .chip{padding:2px 7px;font-size:10.5px;}
  .cards-toolbar .chip.ink, .cards-toolbar .chip.ink-icon-chip{width:26px;height:26px;}
  .cards-toolbar .chip.cost-hex-chip{width:26px;height:26px;}
  .cards-toolbar .chip.cost-hex-chip .cost-hex{width:24px;height:24px;}
  .cards-toolbar .chip.chip-rarity-only{min-width:24px;padding:2px 4px;}
  .cards-toolbar .chip-rarity-icon{width:14px;height:14px;}
  .smart-search-wrap{padding:2px 6px;}
  .smart-search-wrap input[type="search"]{padding:6px 6px;}
  .cards-quickfilter-sub{padding-right:0;border-right:none;}
}
.cards-toolbar .search{flex:1;min-width:200px;}
.cards-toolbar input[type="search"]{width:100%;padding:8px 12px;border:1px solid var(--btn-border);border-radius:6px;background:var(--bg-solid);color:var(--text);font-size:13px;font-family:'Nunito Sans',sans-serif;}
.cards-toolbar input[type="search"]:focus{outline:none;border-color:var(--accent);}
.smart-search-wrap{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  padding:4px 6px;background:var(--bg-solid);border:1px solid var(--btn-border);border-radius:6px;
  transition:border-color 0.12s;}
.smart-search-wrap:focus-within{border-color:var(--accent);}
.smart-search-wrap input[type="search"]{flex:1;min-width:140px;padding:5px 6px;border:none;
  background:transparent;font-size:13px;color:var(--text);font-family:'Nunito Sans',sans-serif;}
.smart-search-wrap input[type="search"]:focus{outline:none;border:none;}
.smart-chip-strip{display:flex;flex-wrap:wrap;gap:4px;align-items:center;}
.smart-chip{display:inline-flex;align-items:center;gap:5px;padding:3px 4px 3px 8px;
  background:var(--accent);color:#fff;border:none;border-radius:14px;font-size:11px;
  font-weight:600;cursor:pointer;font-family:'Nunito Sans',sans-serif;
  transition:filter 0.12s;}
.smart-chip:hover{filter:brightness(1.08);}
.smart-chip-check{display:inline-flex;align-items:center;justify-content:center;
  width:13px;height:13px;border:1.5px solid rgba(255,255,255,0.7);border-radius:50%;
  font-size:9px;line-height:1;}
.smart-chip-label{letter-spacing:0.2px;}
.smart-chip-x{display:inline-flex;align-items:center;justify-content:center;
  width:16px;height:16px;border-radius:50%;font-size:13px;line-height:1;
  background:rgba(0,0,0,0.18);}
.smart-suggest-pop{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;
  background:var(--bg-modal);border:1px solid var(--border);border-radius:8px;
  box-shadow:0 6px 18px rgba(0,0,0,0.35);overflow:hidden;max-height:280px;overflow-y:auto;}
.smart-suggest-item{display:block;width:100%;padding:8px 12px;text-align:left;
  background:transparent;border:none;font-size:13px;color:var(--text);cursor:pointer;
  font-family:'Nunito Sans',sans-serif;}
.smart-suggest-item.is-active{background:var(--accent);color:#fff;}
.cards-chipgroup{display:flex;flex-wrap:wrap;gap:4px;}
/* Forces the next .cards-toolbar element onto a new flex row, so the cost
   filter row sits below the ink row instead of wrapping unpredictably. */
.toolbar-row-break{flex-basis:100%;height:0;margin:0;}
.clear-filters-btn{padding:5px 10px;font-size:11px;font-weight:600;
  background:rgba(153,27,27,0.08);color:var(--red);
  border:1px solid rgba(153,27,27,0.25);border-radius:5px;cursor:pointer;}
.clear-filters-btn:hover{background:rgba(153,27,27,0.16);border-color:var(--red);}
.chip{cursor:pointer;border:1px solid var(--btn-border);background:var(--btn-bg);border-radius:14px;padding:3px 10px;font-size:11px;color:var(--btn-text);transition:all 0.12s;font-family:'Nunito Sans',sans-serif;font-weight:500;display:inline-flex;align-items:center;gap:4px;}
.chip:hover{background:var(--bg-surface-hover);}
.chip.active{background:var(--btn-active-bg);color:var(--btn-active-text);border-color:var(--btn-active-border);}
.chip.ink{width:30px;height:30px;padding:0;justify-content:center;border-radius:50%;font-size:11px;font-weight:700;overflow:hidden;}
.chip.ink.active{box-shadow:0 0 0 2px var(--accent-glow);}
/* Variant that uses the official ink-shield icon instead of a single
   letter. Renders the icon at chip size; the tinted background still
   provides the visual identity when the icon is small. */
/* Filter chips that USE the ink shield render the bare icon — no chip
   wrapper (circle / dark fill / colored border). Matches the deck-row
   ink shield styling so the filter and the deck view read as the same
   visual language. The inline JSX `style` props that set background +
   borderColor per ink (from a pre-redesign era) are overridden here
   with !important rather than ripped out of 4 call sites. */
.chip.ink-icon-chip{width:30px;height:30px;padding:0;
  background:transparent !important;border:none !important;
  border-radius:0 !important;overflow:visible !important;
  box-shadow:none !important;}
.chip.ink-icon-chip:hover{background:transparent !important;}
.chip.ink.ink-icon-chip.active{box-shadow:none !important;}
.chip.ink-icon-chip img{width:100%;height:100%;object-fit:contain;display:block;}
.chip.ink-icon-chip:not(.active) img{filter:grayscale(60%) opacity(0.55);transition:filter 0.12s;}
.chip.ink-icon-chip:hover img{filter:none;}
.chip.ink-icon-chip.active img{filter:none;}
.chip.cost{min-width:28px;justify-content:center;font-weight:600;}
/* Cost chips that render the inline SVG hex instead of plain text. The
   chip itself becomes a transparent shell so the hex shape carries the
   visual; active state brightens the hex stroke + fill via CSS vars. */
.chip.cost-hex-chip{padding:0;background:transparent;border:none;
  width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;}
.chip.cost-hex-chip:hover{background:transparent;}
/* Inkable shield is wider than tall (viewBox 150x128) — let it autosize so
   it doesn't squish into the square slot used by cost hexes. */
.chip.cost-hex-chip .cost-hex-inkable{width:auto;height:28px;color:var(--cost-hex-stroke, #c8a846);}
.cost-hex-inkable{color:var(--cost-hex-stroke, #c8a846);}
.chip.cost-hex-chip.active .cost-hex-inkable{color:var(--accent);}
.chip.cost-hex-chip .cost-hex{width:28px;height:28px;display:block;
  filter:grayscale(40%) opacity(0.7);transition:filter 0.12s;}
.chip.cost-hex-chip:hover .cost-hex{filter:none;}
.chip.cost-hex-chip.active{background:transparent;}
.chip.cost-hex-chip.active .cost-hex{filter:none;--cost-hex-stroke:var(--accent);--cost-hex-fill:var(--accent-glow);--cost-hex-text:var(--text);}
html[data-mode="dark"] .chip.cost-hex-chip .cost-hex{--cost-hex-fill:#0e0e0e;}
.cards-count{font-size:11px;color:var(--text-muted);font-weight:500;text-transform:uppercase;letter-spacing:0.4px;}
.parsed-hint{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:8px 0 12px;padding:6px 10px;background:var(--bg-surface);border:1px solid var(--border-accent);border-radius:8px;font-size:11px;}
.parsed-hint-lbl{font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.5px;}
.parsed-hint-pill{background:var(--btn-active-bg);color:var(--btn-active-text);border:1px solid var(--btn-active-border);border-radius:10px;padding:2px 8px;font-weight:500;}
.cards-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:10px;}
@media (max-width:560px){
  .cards-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;}
  .deck-list{grid-template-columns:1fr !important;}
  .tournament-grid{grid-template-columns:1fr !important;}
  .deck-section-list{grid-template-columns:1fr !important;}
}
/* content-visibility lets the browser skip layout+paint for off-screen tiles.
   Critical for going from a small filtered set (~250 tiles) back to the full
   ~1500 — without it the unfilter triggers a multi-second main-thread freeze
   while the browser lays out every newly-mounted tile. Intrinsic size is the
   reserved placeholder while the tile is offscreen. */
.card-tile{position:relative;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;overflow:hidden;cursor:pointer;transition:transform 0.12s,border-color 0.12s,box-shadow 0.12s;display:flex;flex-direction:column;content-visibility:auto;contain-intrinsic-size:160px 280px;}
/* Image wrapper inside .card-tile — owns the absolute-positioned overlays
   so they anchor to the image, not to the bottom of the tile (which now
   may extend to include a deck +/- counter). */
.card-tile-img-wrap{position:relative;}
.card-tile:hover{transform:translateY(-2px);border-color:var(--border-accent);box-shadow:0 4px 12px rgba(0,0,0,0.08);}
.card-tile img{width:100%;aspect-ratio:5/7;object-fit:cover;display:block;background:var(--bg-surface);}
.card-tile .owned-badge{position:absolute;top:6px;right:6px;display:flex;flex-direction:column;gap:2px;align-items:flex-end;font-size:10px;font-weight:700;font-variant-numeric:tabular-nums;line-height:1;pointer-events:none;}
.card-tile .owned-badge .owned-n{background:rgba(22,101,52,0.92);color:#fff;padding:3px 6px;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,0.25);}
.card-tile .owned-badge .owned-f{background:rgba(85,55,140,0.92);color:#fff;padding:3px 6px;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,0.25);}
.card-tile .price-row{position:absolute;bottom:4px;left:4px;right:4px;display:flex;justify-content:flex-end;gap:3px;pointer-events:none;}
.card-tile .price-badge{color:#fff;padding:2px 5px;border-radius:5px;text-decoration:none;display:flex;flex-direction:column;align-items:flex-end;line-height:1.05;box-shadow:0 1px 4px rgba(0,0,0,0.22);pointer-events:auto;}
.card-tile .price-badge.normal{background:rgba(22,101,52,0.95);}
.card-tile .price-badge.normal:hover{background:rgba(22,101,52,1);}
.card-tile .price-badge.foil{background:rgba(85,55,140,0.92);}
.card-tile .price-badge.foil:hover{background:rgba(85,55,140,1);}
.card-tile .price-badge .label{font-size:7px;font-weight:700;letter-spacing:0.4px;opacity:0.9;text-transform:uppercase;margin-bottom:0;}
.card-tile .price-badge .low{font-size:10px;font-weight:700;display:inline-flex;align-items:center;gap:2px;}
.card-tile .price-badge .ext{font-size:8px;opacity:0.85;}
.card-tile .price-badge .market{font-size:8px;font-weight:500;opacity:0.85;margin-top:0;}
.card-tile .printing-tag{position:absolute;top:6px;left:6px;background:rgba(0,0,0,0.65);color:#fff;font-size:9px;padding:2px 6px;border-radius:4px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;}
/* Filter drawer */
.drawer-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.4);z-index:90;animation:fadeIn 0.15s ease;}
@keyframes fadeIn{from{opacity:0;}to{opacity:1;}}
.drawer{position:fixed;top:0;right:0;bottom:0;width:360px;max-width:100vw;background:var(--bg-solid);border-left:1px solid var(--border);z-index:91;display:flex;flex-direction:column;animation:slideIn 0.2s ease;box-shadow:-4px 0 20px rgba(0,0,0,0.15);}
@keyframes slideIn{from{transform:translateX(100%);}to{transform:translateX(0);}}

/* Movers banner — auto-scrolling marquee. We duplicate the tile list inline,
   then animate translateX from 0 → -50% so the second copy slides into the
   first's place seamlessly. Hover pauses; reduced-motion users get a static
   strip with native overflow-scroll. */
/* Auto-scrolling marquee that ALSO supports manual scroll. The container is
   a native overflow-scroll region; a JS rAF loop nudges scrollLeft each
   frame. Manual scroll / wheel / swipe just nudges scrollLeft directly and
   the loop resumes from wherever the user left off. */
/* No mask-image — masks force the wrap into a compositing layer and soften
   every child <img> at the layer's resolution (visible blur on AVIF cards).
   Instead, two absolutely-positioned gradient overlays fade the left/right
   edges, leaving children's pixels untouched. */
.movers-wrap{overflow-x:auto;overflow-y:hidden;padding:4px 4px 10px;position:relative;
  scrollbar-width:thin;
  overscroll-behavior-x:contain;}
.movers-wrap::before,
.movers-wrap::after{content:"";position:sticky;top:0;width:30px;height:100%;
  pointer-events:none;z-index:3;flex-shrink:0;}
.movers-wrap::before{left:0;background:linear-gradient(to right, var(--bg-solid), transparent);}
.movers-wrap::after{right:0;margin-left:auto;background:linear-gradient(to left, var(--bg-solid), transparent);}
.movers-wrap.is-paused::before,
.movers-wrap.is-paused::after{display:none;}
.movers-track{display:flex;width:max-content;gap:6px;}
/* Mover tile — fixed grid so every section lines up across tiles regardless
   of name length or missing data. Rows: image / name / meta / prices / deltas. */
.mover-tile{flex:0 0 138px;display:grid;
  grid-template-rows:auto auto auto auto auto;
  gap:2px;padding:3px 3px 5px;border:1px solid var(--border);border-radius:6px;
  background:var(--stat-bg,transparent);text-decoration:none;color:inherit;
  cursor:pointer;transition:border-color 0.15s ease;}
.mover-tile:hover{border-color:var(--accent);}
.mover-tile .mt-img-wrap{position:relative;}
/* image-rendering:auto (browser default) is correct for photos. The
   previous crisp-edges value was for pixel-art sprites and was making the
   AVIF card art look blocky. */
.mover-tile .mt-img-wrap img{width:100%;aspect-ratio:5/7;object-fit:cover;border-radius:3px;display:block;}
.mover-tile .mt-img-fallback{width:100%;aspect-ratio:5/7;border-radius:3px;
  background:var(--accent-glow);display:flex;align-items:center;justify-content:center;
  text-align:center;font-size:8px;color:var(--text-muted);padding:3px;box-sizing:border-box;}
.mover-tile .mt-tcg-link{position:absolute;bottom:3px;right:3px;
  width:16px;height:16px;display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,0.72);color:#fff;border-radius:3px;
  font-size:10px;line-height:1;text-decoration:none;font-weight:600;
  box-shadow:0 1px 2px rgba(0,0,0,0.3);transition:background 0.15s ease;}
.mover-tile .mt-tcg-link:hover{background:rgba(0,0,0,0.92);}
.mover-tile .mt-tcg-link svg{display:block;width:9px;height:9px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
/* Copy-tile-as-image button (top-right of the card art). Always visible,
   mirroring the always-on TCGPlayer link at bottom-right. */
.mover-tile .mt-export-btn{position:absolute;top:3px;right:3px;
  width:16px;height:16px;display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,0.72);color:#fff;border:none;border-radius:3px;
  padding:0;cursor:pointer;line-height:1;
  box-shadow:0 1px 2px rgba(0,0,0,0.3);transition:background 0.15s ease;}
.mover-tile .mt-export-btn:hover{background:rgba(0,0,0,0.92);}
/* "Copy banner page" buttons in a MoversBanner title row (1–10 / 11–20). */
.movers-banner-cam{display:inline-flex;align-items:center;justify-content:center;gap:4px;
  height:22px;padding:0 7px;cursor:pointer;border-radius:5px;
  background:transparent;border:1px solid var(--border);color:var(--text-muted);
  transition:color 0.15s ease,border-color 0.15s ease,background 0.15s ease;}
.movers-banner-cam:hover{color:var(--accent);border-color:var(--border-accent);background:var(--accent-glow);}
.mover-tile .mt-export-btn svg{display:block;width:10px;height:10px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
/* Export-only footer row below the delta grid: "packs.ink · <date>" on the
   left + small logo on the right. display:none in the live tile; the
   html2canvas clone flips it to flex (see exportMoverTileImage). */
.mover-tile .mt-export-footer{display:none;align-items:center;justify-content:space-between;
  gap:6px;border-top:1px solid var(--border);margin-top:2px;padding-top:4px;}
.mover-tile .mt-export-footer-txt{font-size:7.5px;font-weight:700;letter-spacing:0.2px;
  color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.mover-tile .mt-export-footer-logo{height:13px;width:auto;flex-shrink:0;display:block;
  object-fit:contain;}
/* Transient toast fired by deep-tree actions (mover-tile image export). */
.packsink-flash-toast{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom));
  transform:translateX(-50%) translateY(8px);
  background:var(--accent);color:#fff;padding:9px 16px;border-radius:8px;
  font-size:13px;font-weight:600;z-index:9999;box-shadow:0 4px 14px rgba(0,0,0,0.3);
  opacity:0;pointer-events:none;transition:opacity 0.18s ease,transform 0.18s ease;}
.packsink-flash-toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
.mover-tile .mt-name{font-size:9px;font-weight:600;line-height:1.15;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.mover-tile .mt-meta{font-size:8px;color:var(--text-muted);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
.mover-tile .mt-prices{display:grid;grid-template-columns:18px 1fr;column-gap:3px;
  row-gap:1px;font-size:10px;align-items:baseline;align-self:start;}
.mover-tile .mt-prices .mt-lbl{color:var(--text-muted);font-size:7px;font-weight:600;letter-spacing:0.2px;}
.mover-tile .mt-prices .mt-now{font-weight:700;text-align:right;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
.mover-tile .mt-deltas{display:grid;grid-template-columns:16px repeat(3,1fr);gap:0 3px;
  font-size:9px;align-items:center;border-top:1px solid var(--border);padding-top:4px;}
.mover-tile .mt-deltas .mt-dh{color:var(--text-muted);font-size:7px;text-align:center;}
.mover-tile .mt-deltas .mt-dlbl{color:var(--text-muted);font-size:7px;font-weight:600;letter-spacing:0.2px;}
.mover-tile .mt-deltas .mt-dval{text-align:center;font-weight:600;font-size:9px;
  padding:1px;border-radius:2px;overflow:hidden;white-space:nowrap;min-width:0;}
.mover-tile .mt-deltas .mt-dh.active,
.mover-tile .mt-deltas .mt-dval.active{background:var(--accent-glow);color:var(--accent);}
/* User settings popover (gear button in top tabs) */
.settings-popover{position:absolute;top:calc(100% + 6px);right:0;
  background:var(--bg-solid);border:1px solid var(--border);border-radius:8px;
  padding:10px 12px;min-width:200px;z-index:100;
  max-height:min(560px, calc(100vh - 90px));overflow-y:auto;
  box-shadow:0 6px 18px rgba(0,0,0,0.18);}
.settings-popover .settings-section-title{font-size:10px;font-weight:600;
  color:var(--text-muted);letter-spacing:0.5px;text-transform:uppercase;
  margin-bottom:8px;}
.settings-popover .settings-row{display:flex;align-items:center;gap:8px;
  font-size:13px;cursor:pointer;padding:4px 0;color:var(--text);}
.settings-popover .settings-row input[type="checkbox"]{margin:0;}
/* Block-layout variant: label above the control, full width. Used by the
   theme segmented picker where a horizontal checkbox layout would crowd. */
.settings-popover .settings-row--block{flex-direction:column;align-items:stretch;
  gap:5px;padding:6px 0;}
.settings-popover .settings-row-label{font-size:12px;color:var(--text);
  font-weight:600;letter-spacing:0.2px;}
/* Segmented control for the Light / Dark / System picker. */
.settings-popover .settings-seg{display:flex;border:1px solid var(--border);
  border-radius:6px;overflow:hidden;background:var(--bg-surface);}
.settings-popover .settings-seg button{flex:1;padding:6px 8px;font-size:12px;
  background:transparent;color:var(--text-muted);border:0;border-right:1px solid var(--border);
  cursor:pointer;transition:all 0.12s;}
.settings-popover .settings-seg button:last-child{border-right:0;}
.settings-popover .settings-seg button:hover{color:var(--accent);}
.settings-popover .settings-seg button.active{background:var(--accent);color:#fff;}
.settings-popover{min-width:240px;}
/* Home-page section visibility toggles — a tight stack of checkboxes under
   the "Home page sections" block label. */
.settings-home-panels{display:flex;flex-direction:column;}
.settings-home-panels .settings-row{padding:3px 0;font-size:12.5px;}
/* Theme picker — grid of named swatch + label buttons. 2 columns to keep
   the popover narrow; visual swatch shows the canvas color outer + the
   card color inner so users see both at a glance. Section labels group
   the light/dark families. */
.theme-picker{display:flex;flex-direction:column;gap:6px;margin-top:4px;}
.theme-picker-section-lbl{font-size:9px;font-weight:800;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);margin-top:4px;}
.theme-picker-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px;}
.theme-picker-btn{display:flex;align-items:center;gap:7px;padding:5px 7px;
  border:1px solid var(--border);border-radius:5px;background:var(--bg-surface);
  cursor:pointer;color:var(--text);font:inherit;text-align:left;transition:border-color 0.12s;}
.theme-picker-btn:hover{border-color:var(--accent);}
.theme-picker-btn.active{border-color:var(--accent);background:var(--accent-glow);}
.theme-picker-swatch{display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;border-radius:4px;flex-shrink:0;
  border:1px solid rgba(0,0,0,0.18);position:relative;}
.theme-picker-swatch-inner{display:block;width:9px;height:9px;border-radius:2px;
  position:absolute;right:2px;bottom:2px;
  box-shadow:0 0 0 1px rgba(0,0,0,0.12);}
.theme-picker-lbl{font-size:11px;font-weight:600;}
.settings-popover .avatar-row{display:flex;align-items:center;gap:10px;
  padding:2px 0 10px;margin-bottom:8px;border-bottom:1px solid var(--border);}
.settings-popover .avatar-row-info{min-width:0;flex:1;}
.settings-popover .avatar-row-name{font-size:13px;font-weight:600;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.settings-popover .avatar-row-email{font-size:11px;color:var(--text-muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px;}
.settings-popover .settings-row-stack{display:flex;flex-direction:column;gap:4px;margin-bottom:4px;}
.settings-popover .settings-action{padding:6px 10px;font-size:12px;font-weight:500;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:5px;cursor:pointer;text-align:left;width:100%;}
.settings-popover .settings-action:hover{background:var(--bg-surface-hover);border-color:var(--accent);}
.settings-popover .settings-action.link{background:transparent;border:none;
  color:var(--text-muted);text-decoration:underline;padding:2px 4px;font-size:11px;}
.settings-popover .settings-action.link:hover{color:var(--text);background:transparent;border:none;}
.settings-popover .settings-action.danger{color:var(--red);border-color:var(--border);}
.settings-popover .settings-action.primary{background:var(--accent);color:#fff;border-color:var(--accent);}
.settings-popover .settings-action.primary:hover{background:var(--accent);filter:brightness(1.05);}

/* Inline display-name editor inside the settings popover. */
.display-name-edit{display:flex;flex-direction:column;gap:6px;
  padding:8px;background:var(--bg-surface);border:1px solid var(--border);border-radius:6px;}
.display-name-edit input{font-size:13px;padding:6px 8px;
  border:1px solid var(--border);background:var(--bg-card);color:var(--text);
  border-radius:4px;outline:none;}
.display-name-edit input:focus{border-color:var(--accent);}
.display-name-edit-row{display:flex;gap:6px;justify-content:flex-end;}
.display-name-edit-err{font-size:11px;color:var(--red);}

/* First-time display-name modal. Blocking — covers the entire viewport. */
/* Mulligan simulator hand layout. */
.modal.mulligan-modal{max-width:min(1600px,96vw);}

/* Deck poster — always horizontal desktop layout, even on mobile. The
   snapshot is what users share; vertical-stacking was producing junk
   exports because html2canvas captures the rendered DOM at the current
   viewport. The wrap below makes the preview horizontally scrollable so
   mobile users can swipe to see the full poster, but the exported image
   stays the same on every device.
   Min-width keeps the inline flex header from collapsing the middle column. */
.deck-poster{min-width:1000px;}
/* JS applies transform:scale(N) + computed height so the 1000px+ poster
   visually fits the viewport. Native size is preserved on the inner element
   so html2canvas exports at the authored dimensions (snapshot path unsets
   the transform during capture). No horizontal scroll on the wrap. */
.deck-poster-wrap{transform-origin:top left;}
.mulligan-hand{display:grid;grid-template-columns:repeat(7,1fr);gap:14px;}
@media (max-width:900px){.mulligan-hand{grid-template-columns:repeat(4,1fr);}}
@media (max-width:560px){.mulligan-hand{grid-template-columns:repeat(3,1fr);}}
.mulligan-card{position:relative;padding:0;border:2px solid var(--border);background:var(--bg-card);
  border-radius:10px;cursor:pointer;overflow:hidden;transition:border-color 0.12s,box-shadow 0.12s;}
.mulligan-card:hover:not(:disabled){border-color:var(--accent);box-shadow:0 6px 18px rgba(0,0,0,0.3);}
.mulligan-card img{display:block;width:100%;aspect-ratio:5/7;object-fit:cover;image-rendering:auto;}
.mulligan-card.is-mull{border-color:var(--red);}
.mulligan-card.is-mull img{filter:grayscale(0.6) brightness(0.55);}
.mulligan-card-overlay{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  background:var(--red);color:#fff;padding:4px 10px;border-radius:6px;font-size:11px;
  font-weight:700;letter-spacing:0.4px;box-shadow:0 2px 6px rgba(0,0,0,0.35);}
.mulligan-card-fallback{display:flex;align-items:center;justify-content:center;aspect-ratio:5/7;
  padding:8px;font-size:11px;text-align:center;color:var(--text-muted);}
.mulligan-card:disabled{cursor:default;opacity:1;}
.mulligan-card:disabled img{filter:none;}

/* Graded Collection — main grid + right-side Set Tracking sidebar. */
.graded-collection{display:flex;flex-direction:column;gap:14px;}
.graded-collection-header{display:flex;justify-content:space-between;align-items:center;
  gap:14px;flex-wrap:wrap;padding:12px 16px;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:10px;}
.graded-collection-totals{display:flex;gap:24px;flex-wrap:wrap;}
.gc-stat .gc-stat-val{font-size:22px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums;color:var(--text);}
.gc-stat .gc-stat-val.green{color:var(--green);}
.gc-stat .gc-stat-lbl{font-size:10px;text-transform:uppercase;letter-spacing:0.4px;
  color:var(--text-muted);font-weight:600;margin-top:3px;}
.graded-collection-body{display:grid;grid-template-columns:1fr 280px;gap:16px;align-items:start;}
@media (max-width:900px){.graded-collection-body{grid-template-columns:1fr;}}
.graded-collection-main{display:flex;flex-direction:column;gap:18px;}
.gc-set-block{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:10px;padding:12px 14px;}
.gc-set-title{font-family:'Cinzel',serif;font-size:13px;font-weight:700;
  letter-spacing:0.4px;color:var(--accent);margin-bottom:10px;text-transform:uppercase;}
.gc-set-title .muted{font-family:inherit;font-size:11px;font-weight:500;margin-left:6px;}
/* minmax(0, 1fr) — the default `1fr` is shorthand for minmax(auto, 1fr),
   meaning a column expands to fit its widest child. Owned graded tiles
   carry an "PSA 10 ×1 $XXX" pill that's wider than tracked tiles, so under
   the default behavior the column containing an owned tile grows beyond
   1/3 of the row. Explicit 0 minimum forces every column to stay at 1/3
   even when content overflows (children get clipped/ellipsized instead). */
/* Auto-fill grid — packs as many tiles per row as fit the chosen
   min-width. On a typical 1440px laptop content area this lands 5-6 tiles
   per row instead of the previous 3, eliminating most of the horizontal
   slack each tile used to have. Browser auto-collapses to a single column
   once the viewport falls below the min, so we only need an explicit
   override for very narrow mobile where 200px is still wider than the
   viewport minus body padding. */
.gc-set-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));gap:6px;}
@media (max-width:640px){.gc-set-grid{grid-template-columns:1fr;}}
/* Sub-section headers inside a graded set block — used by
   SECTION_SPLIT_SETS (C1, C2) to split tiles into Non-Foil and Foil. */
.gc-printing-header{font-family:'Cinzel',serif;font-size:12px;font-weight:600;
  color:var(--accent);text-transform:uppercase;letter-spacing:0.5px;
  margin:10px 0 6px;padding-left:2px;}
.gc-printing-header:first-child{margin-top:4px;}
/* Empty state for graded view — when the user has no items and no goals. */
.gc-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:48px 20px;text-align:center;background:var(--bg-surface);
  border:1px dashed var(--border);border-radius:10px;gap:8px;}
.gc-empty-title{font-family:'Cinzel',serif;font-size:18px;font-weight:600;color:var(--text);}
.gc-empty-sub{font-size:13px;color:var(--text-muted);line-height:1.5;max-width:480px;}
.gc-empty-actions{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap;justify-content:center;}

/* Sealed collection — 3-col tile grid (cards are wider here because the
   product images are landscape, not portrait). Reuses the .gc-* class
   structure for layout consistency with Graded; only the bits that differ
   live under .sealed-coll. */
/* Auto-fill so wide screens pack ~5 columns (was a wasteful fixed 3) and
   the grid steps down gracefully as the viewport narrows. Mobile is forced
   to 2 columns (was a single awkward column). */
.sealed-coll .gc-set-grid{grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));
  align-items:start;}
/* Compact (image-off) tiles are pure text, so pack them tighter horizontally
   too — narrower min means more columns and far less wasted width. */
.sealed-coll .gc-set-grid.gc-compact{grid-template-columns:repeat(auto-fill, minmax(190px, 1fr));}
@media (max-width:640px){
  .sealed-coll .gc-set-grid{grid-template-columns:repeat(2, minmax(0,1fr));}
  .sealed-coll .gc-set-grid.gc-compact{grid-template-columns:repeat(2, minmax(0,1fr));}
  .sealed-coll .gc-card{padding:6px;gap:7px;}
  .sealed-coll .gc-card-img.sealed-card-img{width:40px;height:40px;}
  /* Image-grid tiles are too narrow at 2-col to fit value + counter on one
     line (the value clipped). Stack them: value on its own line, counter
     right below. Reserve the value line height so owned/unowned stay equal.
     Compact (image-off) tiles have the width to stay inline. */
  .sealed-coll .gc-set-grid:not(.gc-compact) .gc-card-foot{flex-direction:column;
    align-items:stretch;gap:2px;}
  .sealed-coll .gc-set-grid:not(.gc-compact) .gc-card-foot-meta{min-height:14px;}
  .sealed-coll .gc-set-grid:not(.gc-compact) .gc-card-foot .sealed-coll-counter{align-self:flex-end;}
}
/* Sealed tile = thumbnail on the left, info on the right (same row layout
   as the Graded tile, which makes the column more scannable than a stack
   of large box-art images). Image kept compact so a Booster-Box thumbnail
   doesn't dominate the tile. */
.sealed-coll .gc-card{flex-direction:row;gap:10px;padding:8px;align-items:flex-start;}
.sealed-coll .gc-card-img.sealed-card-img{width:56px;height:56px;flex-shrink:0;
  object-fit:contain;background:rgba(255,255,255,0.06);padding:4px;border-radius:6px;
  align-self:flex-start;}
/* Content packs to the top and the tile sizes to its content (the grid no
   longer stretches rows — see align-items:start above). Previously a 1fr
   middle row + 64px min-height force-aligned price/counter across a row,
   which left big empty gaps on short tiles and ballooned the compact view. */
.sealed-coll .gc-card-body{display:flex;flex-direction:column;
  gap:3px;min-width:0;flex:1;}
.sealed-coll .gc-card-name{white-space:normal;font-size:12px;line-height:1.25;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.sealed-coll .gc-card-sub{font-size:10px;}
.sealed-coll .gc-card-raw{display:flex;justify-content:space-between;align-items:center;gap:6px;
  margin-top:2px;font-size:11px;}
/* Booster-pack 3-art completion checklist (each set's pack has 3 cover arts
   with no separate SKU). Lives inline in the footer-meta (left of the counter)
   so it doesn't add a row / grow the tile. Three numbered toggle dots; filled
   = owned. */
.gc-pack-arts{display:inline-flex;align-items:center;gap:2px;min-width:0;}
.gc-pack-art-dot{width:15px;height:15px;border-radius:50%;border:1px solid var(--border);
  background:var(--bg-card);color:var(--text-muted);font-size:8.5px;font-weight:700;line-height:1;
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;flex-shrink:0;
  transition:border-color 0.1s,background 0.1s,color 0.1s;}
.gc-pack-art-dot:hover{border-color:var(--accent);color:var(--accent);}
.gc-pack-art-dot.on{background:var(--accent);border-color:var(--accent);color:#fff;}
/* Owned value tucked after the art dots (packs have no foot-meta value slot). */
.gc-pack-val{font-size:9px;font-weight:700;color:var(--green);font-variant-numeric:tabular-nums;
  margin-left:3px;white-space:nowrap;flex-shrink:0;}
/* Footer row: owned value (+ return) left, qty counter right. Always present
   so owned and unowned tiles are the same height (was an extra stacked
   "Owned value" line that made owned tiles taller). */
.sealed-coll .gc-card-foot{display:flex;align-items:center;justify-content:space-between;
  gap:8px;margin-top:auto;padding-top:3px;}
.sealed-coll .gc-card-foot-meta{display:flex;flex-direction:column;gap:0;min-width:0;line-height:1.1;}
.sealed-coll .gc-card-foot-val{font-size:12px;font-weight:700;color:var(--green);font-variant-numeric:tabular-nums;}
.sealed-coll .gc-card-foot-ret{font-size:10px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap;}
/* Smaller counter (scoped to the sealed view — the detail modal's counter is
   outside .sealed-coll and keeps its size). */
.sealed-coll .sealed-coll-counter{flex-shrink:0;padding:2px;gap:2px;}
.sealed-coll .sealed-coll-counter button{width:22px;height:22px;font-size:13px;}
.sealed-coll .sealed-coll-counter-qty{min-width:17px;font-size:13px;}
/* (Duplicate .gc-card-owned rule on line ~1179 removed — canonical rule
   lives just below at .gc-card.gc-card-owned to win on specificity.) */
/* Optional "amount paid + acquired date" inputs on owned rows. Rendered
   below the qty counter when the section's Track cost & date toggle is on.
   Both fields are optional; clearing them writes null. */
.cost-date-row{display:flex;gap:6px;margin-top:6px;padding-top:6px;border-top:1px dashed var(--border);}
.cost-date-field{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0;}
.cost-date-lbl{font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:0.4px;color:var(--text-muted);}
.cost-date-input-wrap{position:relative;display:flex;align-items:center;}
.cost-date-prefix{position:absolute;left:6px;font-size:11px;color:var(--text-muted);pointer-events:none;}
.cost-date-row input{font-size:11px;padding:4px 6px 4px 16px;border:1px solid var(--border);border-radius:4px;background:var(--bg-modal);color:var(--text);width:100%;min-width:0;font-variant-numeric:tabular-nums;}
.cost-date-row input[type=date]{padding-left:6px;}
.cost-date-row input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 1px var(--accent-glow);}
/* Graded: per-slot cost/date rows stack vertically below the slot pills. */
.gc-slot-meta-list{display:flex;flex-direction:column;gap:6px;margin-top:6px;padding-top:6px;border-top:1px dashed var(--border);}
.gc-slot-meta-row{display:flex;flex-direction:column;gap:3px;}
.gc-slot-meta-row .cost-date-row{margin-top:0;padding-top:0;border-top:none;}
.gc-slot-meta-tag{font-size:9px;font-weight:700;letter-spacing:0.4px;color:var(--text-muted);text-transform:uppercase;}
/* Slot header line: grade tag (left) + personal return (right). */
.gc-slot-meta-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px;}
.gc-slot-return{font-size:10.5px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap;}
/* (Canonical owned style lives at .gc-card.gc-card-owned a few lines down.) */
/* Compact mode strips the image so more SKUs fit per page. */
.sealed-coll .gc-set-grid.gc-compact .gc-card .sealed-card-img{display:none;}
.gc-card{display:flex;gap:7px;padding:5px 6px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:7px;position:relative;
  /* Lock grid items to exactly 1/N of the row regardless of inner content
     (owned slots' price pills are wider than tracked placeholders, which
     would otherwise pull the column wider via auto-sizing). */
  width:100%;min-width:0;box-sizing:border-box;}
/* Owned graded card — solid border, accent glow, full opacity. */
.gc-card.gc-card-owned{border:1px solid var(--accent);box-shadow:inset 0 0 0 1px var(--accent-glow);}
/* Tracked-only ("wishlist") graded card — dashed border, faint opacity. */
.gc-card.gc-card-tracked-only{border:1px dashed var(--text-muted);opacity:0.72;background:var(--bg-surface);}
.gc-card.gc-card-tracked-only:hover{opacity:1;}
/* Small check badge top-left for owned cards. */
.gc-card-owned-check{position:absolute;top:4px;left:4px;width:13px;height:13px;
  border-radius:50%;background:var(--accent);color:#fff;font-size:9.5px;font-weight:800;
  display:flex;align-items:center;justify-content:center;line-height:1;z-index:2;
  box-shadow:0 1px 3px rgba(0,0,0,0.35);}
/* Compact mode: hide images, shrink padding, tighten internal layout so
   the user can see ~2x more cards on screen. The accent border on owned
   cards still distinguishes them; the ✓ badge is hidden because there's
   no image to anchor it to. */
.gc-set-grid.gc-compact .gc-card-owned-check{display:none;}
.gc-set-grid.gc-compact .gc-card{padding:4px 6px;gap:5px;}
.gc-set-grid.gc-compact .gc-card .gc-card-img{display:none;}
.gc-set-grid.gc-compact .gc-card-body{gap:1px;}
.gc-set-grid.gc-compact .gc-card-name{font-size:10.5px;line-height:1.2;}
.gc-set-grid.gc-compact .gc-card-sub{font-size:9px;line-height:1.2;}
.gc-set-grid.gc-compact .gc-card-raw{margin-top:1px;font-size:9.5px;}
.gc-set-grid.gc-compact .gc-card-slots{margin-top:1px;gap:2px;}
.gc-set-grid.gc-compact .gc-slot{padding:1.5px 5px;font-size:9px;min-height:18px;}
.gc-set-grid.gc-compact .gc-card-add-btn{width:18px;height:18px;font-size:12px;top:2px;right:2px;}
.gc-set-grid.gc-compact .gc-card-remove-btn{width:16px;height:16px;font-size:12px;bottom:2px;right:2px;}
/* "+" button top-right — opens the Add modal pre-filled with this card.
   Always visible (mobile users have no hover). The button itself is 24px
   but an invisible ::after extends the tap target to 40x40 so touches
   don't fall through to the parent tile's openDetail handler. */
.gc-card-add-btn{position:absolute;top:3px;right:3px;width:20px;height:20px;
  border-radius:50%;background:var(--accent);color:#fff;font-size:13px;font-weight:800;
  border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;
  line-height:1;z-index:3;opacity:0.92;transition:opacity 0.12s, transform 0.12s;padding:0;
  box-shadow:0 1px 4px rgba(0,0,0,0.25);}
.gc-card-add-btn::after{content:"";position:absolute;inset:-10px;}
.gc-card:hover .gc-card-add-btn, .gc-card-add-btn:focus{opacity:1;}
.gc-card-add-btn:hover{filter:brightness(1.1);transform:scale(1.06);}
.gc-card-add-btn:active{transform:scale(0.94);}
/* × button to hide a tracked card from goal counting. Bottom-right of the
   tile — out of the top-right tap zone (reserved for + Add) and away from
   the card name in the top-left. Tracked-only tiles have no slot pills
   or buy link at the bottom-right, so this corner is clear. */
/* "Remove from tracking" button on unowned placeholder tiles. Bottom-right
   corner so it doesn't conflict with the + add button (top-right) or the
   card name (top-left). Replaces the older × Hide button — the new
   semantics are "remove forever" (recoverable only via owning the card or
   re-adding the set goal), not a togglable hide. Compact tiles get a
   smaller variant via .gc-set-grid.gc-compact override below. */
.gc-card-remove-btn{position:absolute;bottom:3px;right:3px;width:18px;height:18px;
  border-radius:50%;background:rgba(0,0,0,0.55);color:#fff;font-size:15px;font-weight:700;
  border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;
  line-height:1;z-index:3;opacity:0.7;transition:opacity 0.12s, transform 0.12s;padding:0;}
.gc-card-remove-btn::after{content:"";position:absolute;inset:-10px;}
.gc-card-remove-btn:hover{opacity:1;background:var(--red);transform:scale(1.06);}
/* Fixed-thumbnail card art. align-self:flex-start pins it to the top so
   any height difference between the image and the body (when the body
   has 4+ rows from Show Δ%) shows as a small gap BELOW the image
   instead of cropping the card. object-fit:contain guarantees the full
   card is visible regardless of any minor aspect mismatch between
   Lorcast's source files and our 5:7-shaped box. The previous
   align-self:stretch + object-fit:cover combination chopped the sides
   off taller tiles — full art > marginal vertical density. */
.gc-card-img{width:38px;height:53px;object-fit:contain;border-radius:4px;
  flex-shrink:0;align-self:flex-start;background:var(--bg-surface);}
.gc-card-body{min-width:0;flex:1;display:flex;flex-direction:column;gap:1px;}
.gc-card-name{font-size:11.5px;font-weight:600;color:var(--text);line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.gc-card-sub{font-size:9.5px;color:var(--text-muted);line-height:1.2;}
/* Slots stack vertically and each pill stretches to fill the body's full
   width — kills the horizontal blank space the old auto-width pills left
   between the pill's right edge and the tile's right padding. With most
   users owning one slot per card the stack reads as a single tight row;
   multi-slot cards (e.g. PSA 9 + PSA 10) get clean vertical separation
   instead of relying on flex-wrap to break unpredictably. */
.gc-card-slots{display:flex;flex-direction:column;gap:3px;margin-top:3px;align-items:stretch;}
.gc-slot{display:flex;align-items:center;gap:3px;padding:2.5px 6px;
  font-size:10px;font-weight:600;border-radius:4px;cursor:pointer;
  min-height:20px;position:relative;width:100%;box-sizing:border-box;}
.gc-slot-owned{background:rgba(200,168,70,0.15);color:#c8a846;
  border:1px solid rgba(200,168,70,0.35);}
.gc-slot-owned:hover{background:rgba(200,168,70,0.25);}
.gc-slot.gc-slot-armed{background:rgba(220,38,38,0.18);border-color:var(--red);color:var(--red);
  animation:gcSlotPulse 0.6s ease-in-out infinite alternate;}
.gc-slot.gc-slot-armed::after{display:none;}
@keyframes gcSlotPulse{from{box-shadow:0 0 0 0 rgba(220,38,38,0);} to{box-shadow:0 0 0 3px rgba(220,38,38,0.18);}}
/* Surface a × on hover so it's obvious the pill is the remove target. */
.gc-slot-owned::after{content:"×";opacity:0;margin-left:2px;color:var(--red);
  font-weight:800;font-size:12px;line-height:1;transition:opacity 0.12s;}
.gc-slot-owned:hover::after{opacity:0.85;}
@media (max-width: 640px){
  /* Always show × on touch — no hover to reveal it. */
  .gc-slot-owned::after{opacity:0.75;}
  .gc-slot{padding:6px 10px;font-size:11px;min-height:30px;}
}
.gc-slot-tracked{background:transparent;color:var(--text-muted);
  border:1px dashed var(--border);cursor:default;font-style:italic;}
/* Quick-add placeholder pill — looks like the tracked pill but acts as a
   button. Hover surfaces the affordance: solid border, accent color,
   "+ PSA 10" reads as an action. */
button.gc-slot-quickadd{appearance:none;font:inherit;cursor:pointer;}
button.gc-slot-quickadd:hover{background:var(--accent-glow);border-style:solid;
  border-color:var(--accent);color:var(--accent);font-style:normal;}
button.gc-slot-quickadd:disabled{cursor:default;opacity:0.8;}
button.gc-slot-quickadd:disabled:hover{background:transparent;border-style:dashed;
  border-color:var(--border);color:var(--text-muted);font-style:italic;}
.gc-slot-tag{font-weight:700;letter-spacing:0.3px;}
.gc-slot-qty{color:var(--text-dim);}
.gc-slot-px{color:var(--green);font-weight:700;}
/* Multi-window Δ% row on owned slots (toolbar "Show Δ%" toggle). The slot
   flips to column layout so the price line stays on top and the three
   labeled delta cells render beneath it, matching the home page mover-tile
   bottom grid. Label is small-caps + muted; value picks color from pctColor()
   inline. */
.gc-slot.gc-slot-with-deltas{flex-direction:column;align-items:stretch;
  gap:2px;padding:3px 6px 4px;}
/* Pin price to the right edge so the pill uses its full width: GRADER
   GRADE + ×qty stay grouped left, $price slams right via margin-left:
   auto on the price span. Cleaner than justify-content:space-between
   for 3 items because we want qty hugging the tag, not centered.
   The generic `.gc-slot .gc-slot-px` rule covers BOTH owned (inside
   .gc-slot-main) AND tracked-quickadd ("+ PSA 10 $X" with the ref
   price chip) pills so the right-align is consistent everywhere. */
.gc-slot-main{display:flex;align-items:center;gap:4px;width:100%;}
.gc-slot .gc-slot-px{margin-left:auto;}
.gc-slot-deltas{display:grid;grid-template-columns:repeat(3,minmax(32px,1fr));
  column-gap:4px;width:100%;line-height:1.1;}
.gc-slot-delta-cell{display:flex;align-items:baseline;gap:2px;}
.gc-slot-delta-lbl{font-size:7.5px;font-weight:700;letter-spacing:0.3px;
  color:var(--text-muted);}
.gc-slot-delta-val{font-weight:700;font-size:9.5px;}
/* Legacy single-pill class (left in as a no-op so any cached HTML rendering
   the old class doesn't break — actual markup now uses .gc-slot-deltas). */
.gc-slot-delta{font-weight:700;font-size:0.92em;margin-left:4px;}
/* "Graded Movers" collapsible banner at the top of GradedCollectionView.
   Owned-only — sourced from the user's graded items + a 35-day history
   fetch, sorted by |Δ%| in the selected window (1D / 1W / 1M). Shares the
   fetch with the per-tile Δ% pills above so a user with both on pays one
   round-trip total. Collapsed by default; persisted to
   packsink:graded:moversCollapsed. */
.graded-movers-banner{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:10px;margin-bottom:14px;}
.graded-movers-banner-head{display:flex;align-items:center;gap:10px;width:100%;
  background:none;border:none;color:var(--text);font:inherit;cursor:pointer;
  padding:10px 14px;text-align:left;}
.graded-movers-banner-head:hover{background:var(--bg-card);}
.graded-movers-banner.is-collapsed .graded-movers-banner-head{border-radius:10px;}
.graded-movers-banner-caret{color:var(--accent);font-weight:700;font-size:13px;
  width:10px;display:inline-block;}
.graded-movers-banner-title{font-family:'Cinzel',serif;font-weight:700;font-size:14px;
  color:var(--accent);letter-spacing:0.3px;}
.graded-movers-banner-sub{font-size:11px;}
.graded-movers-banner-body{padding:0 14px 12px;}
.graded-movers-banner-controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-bottom:10px;}
.graded-movers-screener-jump{margin-left:auto;font-size:11px;}
/* Strip uses the proven wrap-track pattern (mirrors .movers-wrap /
   .movers-track on the home banners): the OUTER element owns overflow-x,
   the INNER track is width:max-content so its flex children push past the
   wrap's width and the overflow scroll fires reliably. Without this split
   the strip's flex container sizes to its content (no overflow → no
   scrollbar) when the parent has no explicit constraint. min-width:0 on
   the wrap lets it shrink inside its grid/flex ancestor instead of
   ballooning to max-content. */
.graded-movers-banner-body{padding:0 14px 12px;min-width:0;max-width:100%;}
.graded-movers-strip-wrap{overflow-x:auto;overflow-y:hidden;padding:2px 0 6px;
  scrollbar-width:thin;min-width:0;max-width:100%;
  overscroll-behavior-x:contain;}
.graded-movers-strip-wrap::-webkit-scrollbar{height:6px;}
.graded-movers-strip-wrap::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px;}
.graded-movers-strip{display:flex;gap:8px;width:max-content;}
.gmover-tile{flex:0 0 142px;min-width:0;max-width:142px;display:flex;flex-direction:column;align-items:center;
  background:var(--bg-card);border:1px solid var(--border);border-radius:8px;
  padding:6px 6px 8px;cursor:pointer;text-align:center;
  font-family:inherit;color:var(--text);}
.gmover-tile:hover{border-color:var(--accent);transform:translateY(-1px);
  transition:transform 0.12s ease, border-color 0.12s ease;}
.gmover-tile img,.gmover-img-fallback{width:120px;height:168px;object-fit:cover;
  border-radius:5px;background:var(--bg-solid);}
.gmover-name{font-size:11px;font-weight:600;margin-top:6px;width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.gmover-meta{display:flex;justify-content:space-between;width:100%;gap:6px;
  font-size:10px;margin-top:3px;align-items:baseline;}
.gmover-grade{color:var(--accent);font-weight:700;letter-spacing:0.3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.gmover-price{color:var(--text-muted);}
.gmover-foil{font-size:8px;font-weight:800;letter-spacing:0.4px;text-transform:uppercase;
  color:var(--accent);border:1px solid var(--accent);border-radius:4px;padding:0 3px;
  line-height:1.5;white-space:nowrap;flex:0 0 auto;}
/* 3-window Δ% grid at the tile's bottom — label row + value row, evenly
   distributed across 3 columns (1D / 1W / 1M). Mirrors the home MoverTile
   .mt-deltas layout but compacted for the smaller tile footprint. */
.gmover-deltas{display:grid;grid-template-columns:repeat(3,1fr);
  width:100%;margin-top:5px;gap:1px 4px;text-align:center;}
.gmover-dh{font-size:8.5px;font-weight:700;letter-spacing:0.4px;
  color:var(--text-muted);}
.gmover-dv{font-size:10.5px;font-weight:700;}
.gmover-saledate{font-size:9.5px;font-weight:600;color:var(--text-muted);margin-top:4px;text-align:center;}
/* Home-page graded banner header (title + tab/window seg-toggles). */
.graded-home-head{display:flex;align-items:center;gap:8px;margin-bottom:3px;flex-wrap:wrap;}
.graded-home-title{font-family:'Cinzel',serif;font-size:12px;font-weight:600;margin:0;color:var(--accent);letter-spacing:0.3px;background:none;border:0;padding:0;}
button.graded-home-title{cursor:pointer;}
.graded-home-seg{}
.graded-home-seg button{font-size:10px;padding:3px 9px;}
.graded-home-filters{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-bottom:5px;}
.graded-home-flbl{font-size:9.5px;font-weight:700;letter-spacing:0.4px;text-transform:uppercase;color:var(--text-muted);margin-left:4px;}
.graded-home-flbl:first-child{margin-left:0;}
.gh-chip{font-size:10px;font-weight:600;padding:2px 8px;border:1px solid var(--border);border-radius:999px;background:var(--bg-surface);color:var(--text-muted);cursor:pointer;}
.gh-chip.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.gh-clear{color:var(--accent);background:none;border-color:var(--border-accent);}
@media (max-width:640px){
  .graded-movers-banner-head{padding:8px 10px;}
  .graded-movers-banner-body{padding:0 10px 10px;}
  .gmover-tile{flex-basis:120px;max-width:120px;}
  .gmover-tile img,.gmover-img-fallback{width:104px;height:146px;}
}
.graded-collection-side{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:10px;padding:12px 14px;position:sticky;top:12px;}
.gc-side-head{display:flex;justify-content:space-between;align-items:center;
  font-size:13px;font-weight:700;color:var(--accent);text-transform:uppercase;
  letter-spacing:0.4px;font-family:'Cinzel',serif;margin-bottom:10px;}
.gc-side-body{display:flex;flex-direction:column;gap:8px;}
.gc-goal{position:relative;padding:9px 28px 9px 11px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:6px;}
/* Whole goal tile is clickable — jumps to its set section in the left
   column. Cursor + hover lift + accent border on focus telegraph the
   interaction. The × remove button stops propagation so it doesn't fire
   the jump. */
.gc-goal-clickable{cursor:pointer;transition:border-color 0.12s ease,
  background 0.12s ease, transform 0.12s ease;}
.gc-goal-clickable:hover{border-color:var(--accent);background:var(--bg-surface);}
.gc-goal-clickable:focus-visible{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 2px rgba(200,168,70,0.25);}
.gc-goal-clickable:active{transform:translateY(1px);}
.gc-goal-name{font-size:12px;font-weight:700;color:var(--text);}
.gc-goal-sub{font-size:10px;margin-top:2px;}
.gc-goal-remove{position:absolute;top:6px;right:6px;width:18px;height:18px;
  border:none;background:transparent;color:var(--text-muted);cursor:pointer;
  font-size:14px;line-height:1;border-radius:4px;}
.gc-goal-remove:hover{color:var(--red);background:rgba(220,38,38,0.08);}
.gc-add-hit{display:flex;gap:10px;align-items:center;padding:6px 8px;
  background:transparent;border:1px solid transparent;border-radius:6px;
  cursor:pointer;width:100%;text-align:left;font-family:inherit;
  color:var(--text);}
.gc-add-hit:hover{background:var(--bg-surface);border-color:var(--border);}
/* Scope the card-thumb sizing so it doesn't bleed onto nested icons
   (e.g. RarityTag's icon) which were being rendered at 32x45 too. */
.gc-add-hit > img, .gc-add-hit-thumb{width:32px;height:45px;object-fit:cover;border-radius:3px;flex-shrink:0;}

/* Generic modal container — used by Artist Alley etc. */
.modal-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.55);z-index:200;
  display:flex;align-items:center;justify-content:center;padding:20px;animation:fadeIn 0.15s ease;}
.modal{background:var(--bg-modal);border:1px solid var(--border);border-radius:12px;
  box-shadow:0 12px 40px rgba(0,0,0,0.4);max-width:900px;width:100%;max-height:90vh;
  display:flex;flex-direction:column;overflow:hidden;}
.modal-header{display:flex;align-items:center;justify-content:space-between;
  padding:14px 18px;border-bottom:1px solid var(--border);background:var(--bg-surface);}
.modal-body{flex:1;overflow-y:auto;}

.name-prompt-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.55);
  z-index:10000;display:flex;align-items:center;justify-content:center;padding:20px;}
.name-prompt{background:var(--bg-modal);border:1px solid var(--border);border-radius:12px;
  padding:24px;max-width:440px;width:100%;
  box-shadow:0 12px 32px rgba(0,0,0,0.4);}
.name-prompt input{width:100%;font-size:15px;padding:10px 12px;
  border:1px solid var(--border);background:var(--bg-surface);color:var(--text);
  border-radius:6px;outline:none;box-sizing:border-box;}
.name-prompt input:focus{border-color:var(--accent);}

/* Premium graded Terms-of-Use gate (uses --bg-modal so it's opaque in dark mode). */
.graded-tos-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.6);
  z-index:10001;display:flex;align-items:center;justify-content:center;padding:20px;}
.graded-tos-modal{background:var(--bg-modal);border:1px solid var(--border);border-radius:12px;
  padding:24px;max-width:480px;width:100%;box-shadow:0 12px 32px rgba(0,0,0,0.45);}
.graded-tos-intro{font-size:13px;color:var(--text);margin:0 0 10px;line-height:1.5;}
.graded-tos-list{margin:0 0 12px;padding-left:20px;font-size:13px;color:var(--text);line-height:1.5;}
.graded-tos-list li{margin:3px 0;}
.graded-tos-note{font-size:11.5px;color:var(--text-muted);margin:0 0 14px;line-height:1.45;}
.graded-tos-note a{color:var(--accent);}
.graded-tos-check{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text);
  cursor:pointer;margin-bottom:16px;}
.graded-tos-check input{width:16px;height:16px;cursor:pointer;}
.graded-tos-actions{display:flex;gap:8px;justify-content:flex-end;align-items:center;}
.graded-tos-actions button:disabled{opacity:0.5;cursor:not-allowed;}

/* Variant/printing badge — makes the graded sub-variant (Two Swords, Text Error,
   Top Prize, Prize Wall, …) read as part of the card's identity across views. */
.variant-badge{display:inline-block;font-size:10px;font-weight:700;letter-spacing:0.3px;
  text-transform:uppercase;padding:2px 6px;border-radius:5px;vertical-align:middle;
  background:var(--accent-glow);color:var(--accent);border:1px solid var(--accent);
  white-space:nowrap;line-height:1.3;}
.td-name-meta .variant-badge{font-size:9px;padding:1px 5px;margin-left:1px;}
.card-detail-body h2 .variant-badge{font-size:12px;margin-left:8px;}
.graded-printing-toggle{margin:10px 0 4px;}

/* Footer stale-data warning pill (shown only when ETL is > 36h behind). */
.footer-stale{font-size:11px;color:var(--red);margin-top:4px;
  padding:3px 8px;background:rgba(153,27,27,0.08);border-radius:4px;
  display:inline-block;}
.settings-popover .settings-action.danger:hover{background:rgba(153,27,27,0.08);border-color:var(--red);}
.settings-popover .settings-action.primary{background:var(--accent);color:#fff;border-color:var(--accent);text-align:center;font-weight:600;}
.settings-popover .settings-action.primary:hover{filter:brightness(1.08);}
.settings-popover .settings-divider{height:1px;background:var(--border);margin:8px 0;}
/* Combined profile/settings button — shows avatar + name, replaces the
   former gear-only button when signed in. */
.profile-btn{display:flex;align-items:center;gap:6px;padding:4px 10px;font-size:12px;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:6px;cursor:pointer;min-height:36px;}
.profile-btn:hover{background:var(--bg-surface-hover);border-color:var(--accent);}
/* iOS Safari occasionally swallows taps that land on a child <img> or <span>
   inside an onClick'd button — only the button's background pixels reliably
   bubble up. Disable pointer events on children so the click target is the
   button itself, end of story. */
.profile-btn > *{pointer-events:none;}
/* Signed-out CTA: replaces the old gear-only button. Reads as a clear action
   instead of a settings affordance, since the popover's primary purpose for
   signed-out users is auth. Theme controls inside the popover let them tweak
   appearance even before signing in. */
.signin-btn{display:flex;align-items:center;justify-content:center;padding:6px 14px;
  font-size:12px;font-weight:700;font-family:'Cinzel',serif;letter-spacing:0.3px;
  background:var(--accent);color:#fff;border:1px solid var(--accent);
  border-radius:6px;cursor:pointer;min-height:36px;text-transform:uppercase;}
.signin-btn:hover{filter:brightness(1.08);}

/* Avatar picker modal */
.avatar-picker-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.5);
  display:flex;align-items:center;justify-content:center;z-index:9100;padding:16px;}
.avatar-picker{background:var(--bg-solid);border:1px solid var(--border);border-radius:10px;
  width:min(720px,100%);max-height:85vh;display:flex;flex-direction:column;
  box-shadow:0 10px 32px rgba(0,0,0,0.35);color:var(--text);overflow:hidden;}
/* Typeahead variant: narrower modal (search-first UX, no grid to fill out),
   padded content, no internal scrolling — the dropdown handles its own list. */
.avatar-picker--typeahead{width:min(460px,100%);max-height:none;padding:0 14px 16px;
  overflow:visible;}
.avatar-picker--typeahead .avatar-picker-head{border-bottom:0;padding:12px 0 4px;}
.avatar-picker-search-row{position:relative;}
.avatar-picker-results{position:static !important;margin-top:6px;
  max-height:340px;overflow-y:auto;box-shadow:none;border-radius:6px;}
.avatar-picker-head{display:flex;align-items:center;gap:10px;padding:12px 14px;
  border-bottom:1px solid var(--border);}
.avatar-picker-close{background:transparent;border:none;color:var(--text-muted);
  font-size:22px;line-height:1;cursor:pointer;padding:0 4px;}
.avatar-picker-close:hover{color:var(--text);}

/* Custom hover tooltip. Rendered via portal to document.body so it escapes
   clip-on-overflow ancestors (.movers-wrap, modals, etc). Native title=
   attrs had a ~1s delay and were unreliable on small text — this shows
   immediately. */
.tip-trigger{cursor:help;text-decoration:underline dotted rgba(0,0,0,0.25);
  text-underline-offset:2px;}
/* Tiny labels inside mover tiles — the dotted underline is too noisy at 7px. */
.mt-lbl.tip-trigger,.mt-dlbl.tip-trigger{text-decoration:none;}
.tip-bubble{position:fixed;transform:translate(-50%,calc(-100% - 9px));
  background:#1a1a1a;color:#f4f1eb;font-size:11px;font-weight:500;
  line-height:1.4;padding:7px 10px;border-radius:5px;max-width:240px;
  z-index:9999;pointer-events:none;box-shadow:0 4px 14px rgba(0,0,0,0.28);
  letter-spacing:0;text-align:left;}
.tip-bubble::after{content:"";position:absolute;top:100%;left:50%;
  transform:translateX(-50%);border:5px solid transparent;
  border-top-color:#1a1a1a;}

/* Home page two-column grid: left = banners, right = collection panel.
   Collapses to single column under 980px so the panel stacks below. */
/* Slim page title above the home grid. */
.home-page-title{margin-bottom:8px;}
/* Home quick-search bar — typeahead under the page title. Enter or click
   a suggestion to jump into the Cards tab with the query pre-applied. */
.home-quick-search{position:relative;display:flex;gap:6px;margin-top:8px;max-width:560px;}
.home-quick-search input[type="search"]{flex:1 1 auto;padding:8px 12px;font-size:14px;
  border:1px solid var(--border);border-radius:8px;background:var(--bg-card);color:var(--text);}
.home-quick-search input[type="search"]:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 2px var(--accent-glow);}
.home-quick-search-go{padding:8px 14px;font-size:13px;font-weight:600;border-radius:8px;
  background:var(--accent);color:#fff;border:1px solid var(--accent);cursor:pointer;}
.home-quick-search-go:hover{filter:brightness(1.08);}
.home-quick-search-list{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;
  background:var(--bg-modal);border:1px solid var(--border);border-radius:8px;
  box-shadow:0 8px 24px rgba(0,0,0,0.18);max-height:380px;overflow-y:auto;padding:4px;}
.home-quick-search-item{display:flex;gap:10px;align-items:center;width:100%;
  padding:6px 8px;border-radius:6px;border:none;background:transparent;color:var(--text);
  text-align:left;cursor:pointer;font-family:inherit;}
.home-quick-search-item:hover,
.home-quick-search-item.active{background:var(--bg-surface);}
.home-quick-search-item img{width:34px;height:48px;object-fit:cover;border-radius:4px;flex-shrink:0;}
.home-quick-search-item-text{min-width:0;flex:1;}
.home-quick-search-item-name{font-size:13px;font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;}
.home-quick-search-item-meta{font-size:11px;color:var(--text-muted);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;}
/* "Variants & other versions" section inside the home search dropdown. */
.home-quick-search-divider{font-family:'Cinzel',serif;font-size:10px;font-weight:600;
  letter-spacing:0.4px;text-transform:uppercase;color:var(--accent);
  padding:8px 12px 4px;border-top:1px solid var(--border);margin-top:4px;}
.home-quick-search-item--variant img{opacity:0.95;}
.home-quick-search-item--variant .home-quick-search-item-name{font-weight:500;}
/* Right column = stacked EV strip + Collection panel. Both elements
   inherit the column's full width (360px) so the right side reads as a
   single symmetrical stack matching the left column's feed. */
.home-grid-right{display:flex;flex-direction:column;gap:14px;min-width:0;
  position:sticky;top:8px;align-self:start;}

/* "Upcoming Set Championships Near Me" box (home right column). */
.sc-box{width:100%;box-sizing:border-box;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:8px;padding:10px 12px;}
.sc-box-head{display:flex;align-items:center;justify-content:space-between;gap:8px;}
.sc-box-title{font-family:'Cinzel',serif;font-size:12px;font-weight:600;
  letter-spacing:0.3px;color:var(--accent);min-width:0;}
.sc-collapse-btn{flex-shrink:0;background:none;border:none;color:var(--text-muted);
  cursor:pointer;font-size:12px;line-height:1;padding:3px 7px;border-radius:5px;}
.sc-collapse-btn:hover{color:var(--accent);background:var(--accent-glow);}
.sc-box-body{margin-top:8px;}
.sc-mode-toggle{display:flex;gap:0;margin-bottom:8px;border:1px solid var(--btn-border);
  border-radius:8px;overflow:hidden;background:var(--bg-solid);}
.sc-mode-btn{flex:1;padding:6px 8px;font-size:11.5px;font-weight:700;cursor:pointer;
  border:none;background:transparent;color:var(--text-dim);font-family:inherit;
  letter-spacing:0.02em;white-space:nowrap;transition:background .12s,color .12s;}
.sc-mode-btn+.sc-mode-btn{border-left:1px solid var(--btn-border);}
.sc-mode-btn:hover{color:var(--text);}
.sc-mode-btn.active{background:var(--accent);color:#fff;}
.sc-tile-kind{display:inline-block;margin-right:5px;padding:1px 5px;border-radius:4px;
  font-size:9px;font-weight:800;letter-spacing:0.03em;text-transform:uppercase;vertical-align:middle;}
.sc-tile-kind--sc{background:var(--accent-glow);color:var(--accent);}
.sc-tile-kind--pre{background:rgba(90,170,90,0.18);color:#3f9d54;}
html[data-mode="dark"] .sc-tile-kind--pre{background:rgba(120,210,130,0.16);color:#7ed492;}
.sc-box-title-btn{display:flex;align-items:center;gap:6px;background:none;border:none;cursor:pointer;
  text-align:left;min-width:0;padding:2px 0;font-family:'Cinzel',serif;font-size:12px;font-weight:600;
  letter-spacing:0.3px;color:var(--accent);}
.sc-box-title-btn:hover{filter:brightness(1.12);}
.sc-title-expand-hint{font-size:11px;color:var(--text-muted);flex-shrink:0;}
.sc-box-head-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;}
.sc-copy-link{background:none;border:1px solid var(--btn-border);color:var(--text-dim);cursor:pointer;
  font-size:10.5px;font-weight:600;line-height:1;padding:5px 9px;border-radius:6px;white-space:nowrap;font-family:inherit;}
.sc-copy-link:hover:not(:disabled){border-color:var(--border-accent);color:var(--accent);}
.sc-copy-link:disabled{opacity:0.4;cursor:not-allowed;}
/* Full-screen expanded view (title click) — fixed overlay, body scroll locked in JS. */
.sc-expanded-backdrop{position:fixed;inset:0;z-index:9500;background:rgba(0,0,0,0.6);
  display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;
  padding:max(20px,env(safe-area-inset-top)) 16px max(20px,env(safe-area-inset-bottom));}
.sc-box--expanded{width:min(720px,100%);max-width:720px;
  border:1px solid var(--border);border-radius:14px;background:var(--bg-solid);
  box-shadow:0 18px 60px rgba(0,0,0,0.5);}
.sc-box--expanded .sc-list{max-height:none;}

/* Elo event roster / field scouting (I4) */
.elo-roster-modal{max-width:480px;max-height:88vh;overflow-y:auto;text-align:left;}
.elo-roster-field{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0 6px;}
.elo-roster-field .elo-store-stat{flex:1 1 72px;}
.elo-roster-scraped{font-size:11px;margin-bottom:10px;}
.elo-roster-acct{color:var(--text-muted);font-size:11px;font-weight:400;}
.elo-row--static{cursor:default;}
.sc-modal-cta--roster{background:var(--btn-bg);color:var(--text);border:1px solid var(--border-accent);margin-top:6px;}
.sc-modal-cta--roster:hover{background:var(--accent-glow);}
.elo-roster-refresh{margin-top:8px;background:var(--btn-bg);border:1px solid var(--btn-border);
  color:var(--text-dim);border-radius:8px;padding:6px 12px;font-size:11px;font-weight:600;cursor:pointer;font-family:inherit;align-self:flex-start;}
.elo-roster-refresh:hover:not(:disabled){border-color:var(--border-accent);color:var(--accent);}
.elo-roster-refresh:disabled{opacity:0.5;cursor:wait;}
.sc-search-row{display:flex;gap:6px;margin-bottom:7px;}
.sc-country-select{flex-shrink:0;padding:7px 6px;font-size:13px;font-family:inherit;font-weight:600;
  border:1px solid var(--btn-border);border-radius:6px;background:var(--bg-solid);color:var(--text);cursor:pointer;}
.sc-country-select:focus{outline:none;border-color:var(--accent);}
.sc-date-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:7px;}
.sc-date-toggle{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-dim);cursor:pointer;}
.sc-date-toggle input{margin:0;width:13px;height:13px;accent-color:var(--accent);cursor:pointer;}
.sc-date-inputs{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap;}
.sc-date-input{padding:3px 6px;font-size:11px;border:1px solid var(--btn-border);
  border-radius:5px;background:var(--bg-solid);color:var(--text);font-family:inherit;}
.sc-date-input:focus{outline:none;border-color:var(--accent);}
.sc-date-clear{background:none;border:none;color:var(--text-muted);cursor:pointer;
  font-size:15px;line-height:1;padding:0 4px;border-radius:4px;}
.sc-date-clear:hover{color:var(--red);}
.sc-zip-input{flex:1;min-width:0;padding:7px 10px;font-size:13px;font-family:inherit;
  border:1px solid var(--btn-border);border-radius:6px;background:var(--bg-solid);color:var(--text);}
.sc-zip-input:focus{outline:none;border-color:var(--accent);}
.sc-search-btn{padding:7px 14px;font-size:12px;font-weight:700;border:none;border-radius:6px;
  background:var(--accent);color:#fff;cursor:pointer;font-family:inherit;white-space:nowrap;}
.sc-search-btn:hover{filter:brightness(1.07);}
.sc-radius-row{display:flex;flex-wrap:wrap;gap:5px;align-items:center;}
.sc-radius-btn{padding:4px 9px;font-size:11px;font-weight:600;border-radius:999px;cursor:pointer;
  border:1px solid var(--btn-border);background:transparent;color:var(--text-dim);font-family:inherit;}
.sc-radius-btn:hover{border-color:var(--border-accent);color:var(--text);}
.sc-radius-btn.active{background:var(--accent-glow);border-color:var(--border-accent);color:var(--accent);}
.sc-custom-wrap{display:inline-flex;gap:4px;align-items:center;}
.sc-custom-input{width:46px;padding:4px 6px;font-size:11px;border:1px solid var(--btn-border);
  border-radius:6px;background:var(--bg-solid);color:var(--text);font-family:inherit;}
.sc-custom-input:focus{outline:none;border-color:var(--accent);}
.sc-custom-go{padding:4px 8px;font-size:11px;font-weight:700;border:none;border-radius:6px;
  background:var(--accent);color:#fff;cursor:pointer;font-family:inherit;}
.sc-msg{font-size:11px;margin-top:8px;}
.sc-msg-err{color:var(--red);}
.sc-results{margin-top:8px;}
.sc-results-head{font-size:10px;text-transform:uppercase;letter-spacing:0.4px;
  color:var(--text-muted);font-weight:700;margin-bottom:5px;}
.sc-list{display:flex;flex-direction:column;gap:4px;max-height:340px;overflow-y:auto;}
.sc-tile{display:flex;align-items:stretch;width:100%;flex-shrink:0;border:1px solid var(--border);border-radius:6px;
  background:var(--bg-card);overflow:hidden;transition:border-color 0.12s,background 0.12s;}
.sc-tile:hover{border-color:var(--border-accent);background:var(--bg-surface-hover);}
.sc-tile-pinned{border-color:var(--accent);background:var(--accent-glow);}
.sc-tile-main-btn{flex:1;min-width:0;display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:8px;
  align-items:center;text-align:left;padding:6px 8px;border:none;background:transparent;color:var(--text);
  cursor:pointer;font-family:inherit;}
.sc-tile-date{font-size:10px;font-weight:700;color:var(--accent);white-space:nowrap;
  text-transform:uppercase;letter-spacing:0.3px;display:flex;flex-direction:column;gap:1px;}
.sc-tile-time{font-size:9px;font-weight:600;color:var(--text-muted);letter-spacing:0.2px;text-transform:none;}
.sc-tile-main{min-width:0;display:flex;flex-direction:column;}
.sc-tile-store{font-size:12px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sc-tile-evname{font-size:10.5px;color:var(--text-dim);line-height:1.25;margin:1px 0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.sc-tile-loc{font-size:10px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sc-tile-mi{font-size:11px;font-weight:700;color:var(--text-dim);white-space:nowrap;font-variant-numeric:tabular-nums;}
.sc-tile-pin{flex-shrink:0;width:34px;border:none;border-left:1px solid var(--border);background:transparent;
  cursor:pointer;font-size:13px;line-height:1;color:var(--text-muted);filter:grayscale(1) opacity(0.5);
  transition:filter 0.12s,background 0.12s;}
.sc-tile-pin:hover{background:var(--accent-glow);filter:grayscale(0.3) opacity(0.9);}
.sc-tile-pin.pinned{filter:none;background:var(--accent-glow);}
/* SC detail modal */
.sc-modal-overlay{position:fixed;inset:0;z-index:9600;background:rgba(0,0,0,0.55);
  display:flex;align-items:center;justify-content:center;padding:16px;}
.sc-modal{position:relative;width:100%;max-width:380px;background:var(--bg-modal);
  border:1px solid var(--border);border-radius:12px;padding:18px 18px 16px;
  box-shadow:0 18px 50px rgba(0,0,0,0.4);max-height:88vh;overflow-y:auto;}
.sc-modal-close{position:absolute;top:8px;right:10px;background:none;border:none;
  font-size:22px;line-height:1;color:var(--text-muted);cursor:pointer;padding:2px 6px;}
.sc-modal-close:hover{color:var(--text);}
.sc-modal-set{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.5px;color:var(--accent);}
.sc-modal-store{margin:3px 0 2px;font-size:18px;font-weight:700;color:var(--text);padding-right:22px;}
.sc-modal-evname{font-size:12px;color:var(--text-muted);font-style:italic;margin-bottom:4px;}
.sc-modal-when{font-size:13px;font-weight:600;color:var(--text);margin:4px 0 12px;}
.sc-modal-rows{margin:0 0 14px;display:flex;flex-direction:column;gap:8px;}
.sc-modal-rows > div{display:grid;grid-template-columns:74px 1fr;gap:8px;}
.sc-modal-rows dt{font-size:10px;text-transform:uppercase;letter-spacing:0.4px;color:var(--text-muted);font-weight:700;padding-top:1px;}
.sc-modal-rows dd{margin:0;font-size:13px;color:var(--text);}
.sc-modal-actions{display:flex;flex-direction:column;gap:7px;}
.sc-modal-cta{display:block;text-align:center;padding:9px 12px;font-size:13px;font-weight:700;
  background:var(--accent);color:#fff;border-radius:7px;text-decoration:none;}
.sc-modal-cta:hover{filter:brightness(1.07);}
.sc-modal-link{font-size:12px;color:var(--accent);text-decoration:none;font-weight:600;}
.sc-modal-link:hover{text-decoration:underline;}
.home-ev-strip{width:100%;box-sizing:border-box;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;
  padding:8px 10px;font-size:11px;}
.home-ev-strip-head{display:flex;justify-content:space-between;align-items:center;
  gap:10px;margin-bottom:4px;}
.home-ev-strip-title{font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.home-ev-strip-toggles{display:flex;gap:10px;font-size:10px;color:var(--text-muted);}
.home-ev-strip-toggles label{display:flex;align-items:center;gap:3px;cursor:pointer;}
.home-ev-strip-toggles input{margin:0;width:11px;height:11px;accent-color:var(--accent);}
.home-ev-strip-table{display:flex;flex-direction:column;gap:1px;}
.home-ev-strip-row{display:grid;grid-template-columns:minmax(0,1.4fr) 1fr 1fr 1.2fr;
  gap:6px;align-items:center;padding:3px 4px;border-radius:4px;}
.home-ev-strip-head-row{font-size:9px;font-weight:700;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--text-muted);}
.home-ev-strip-row:not(.home-ev-strip-head-row):hover{background:var(--bg-card);}
.home-ev-strip-row .num{text-align:right;font-variant-numeric:tabular-nums;}
.home-ev-strip-set{font-weight:600;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.home-ev-strip-box-link{color:var(--text);text-decoration:none;font-weight:600;}
.home-ev-strip-box-link .ext{font-size:9px;opacity:0.6;margin-left:2px;}
.home-ev-strip-box-link:hover{color:var(--accent);}

/* Following feed — left column above the first banner. Single-line rows:
   green/yellow dot (new vs updated) · deck name · creator + time · ink icons.
   Previously `position: sticky; top: 8px` on desktop so the panel pinned as
   the main column scrolled. Removed 2026-05-26 because the left column
   contains TWO `.home-feed` instances (Following + Tournament Results) —
   both sticky at the same top offset stack on top of each other once both
   reach the constraint, with Following visually covering Tournament Results.
   Letting both scroll naturally with the page sidesteps the conflict, and
   also fixes the residual mobile overlap that survived the @media override
   when service-worker caches were stale. */
.home-feed{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:8px;padding:6px 8px 8px;margin-bottom:14px;
  align-self:start;}
/* Event-news tiles in .home-left-col under Tournament Results. One per
   active EVENT_TILES entry; each artist name opens ArtistAlleyModal
   pre-picked. */
.home-news-tile{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:8px;padding:8px 10px 10px;width:100%;box-sizing:border-box;
  margin-bottom:0;align-self:stretch;}
.home-news-title{font-family:'Cinzel',serif;font-size:12px;font-weight:600;
  letter-spacing:0.3px;color:var(--accent);margin:0 2px 4px;}
/* Date + event-page link under the tile title. Single anchor: the date text
   is what visually labels the link; the ↗ glyph signals the external page. */
.home-news-event-link{display:inline-flex;align-items:center;gap:5px;
  font-size:11px;font-weight:600;color:var(--text-dim);
  margin:0 2px 8px;text-decoration:none;
  border-bottom:1px dashed transparent;line-height:1.3;
  transition:color 0.12s,border-color 0.12s;}
.home-news-event-link[href="#"]{cursor:default;}
.home-news-event-link:hover{color:var(--accent);}
.home-news-event-link[href]:not([href="#"]):hover{border-bottom-color:var(--accent);}
.home-news-event-link-arrow{font-size:10px;line-height:1;}
.home-news-list{list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:1px;}
.home-news-link{display:flex;width:100%;gap:6px;align-items:center;
  padding:7px 8px;background:none;border:none;border-radius:5px;
  cursor:pointer;font-family:'Nunito Sans',sans-serif;text-align:left;
  color:var(--text);transition:background 0.12s;}
.home-news-link:hover{background:var(--bg-card);}
.home-news-link-name{flex:1;min-width:0;font-size:13px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.home-news-link:hover .home-news-link-name{color:var(--accent);}
.home-news-link-chev{flex-shrink:0;color:var(--text-muted);font-size:14px;
  transition:transform 0.12s,color 0.12s;}
.home-news-link:hover .home-news-link-chev{color:var(--accent);transform:translateX(2px);}

/* Reusable expand/collapse toggle for home banners (Tournament Results,
   Following). Sticky-look chip at the bottom of the banner. */
.home-feed-collapse-toggle{display:block;margin:8px auto 2px;padding:5px 12px;
  font-size:10.5px;font-weight:700;letter-spacing:0.4px;text-transform:uppercase;
  background:transparent;border:1px solid var(--btn-border);border-radius:14px;
  color:var(--text-dim);cursor:pointer;}
.home-feed-collapse-toggle:hover{border-color:var(--accent);color:var(--accent);}
/* Mobile-only variant — hidden on desktop where the full feed always shows. */
.home-feed-collapse-toggle--mobile-only{display:none;}
@media (max-width:700px){
  .home-feed-collapse-toggle--mobile-only{display:block;}
  /* Hide overflow items in Following feed until expanded. */
  .home-feed-list:not(.is-expanded) .home-feed-item.is-overflow{display:none;}
  /* Collapsed Tournament Results shows top 2 per event (1st + 2nd) so the
     column actually fills next to the chase-movers banner instead of leaving
     a tall white gap. "Show more" reveals 3rd + 4th. */
  .home-tourney-decks:not(.is-expanded) li:nth-child(n+3){display:none;}
  /* On mobile, omit the deck name from tournament tiles entirely — keep
     just the player name + ink shields. The full deck name is one tap
     away in the tournament/deck detail view. */
  .home-tourney-deck .ht-deck{display:none;}
  .home-tourney-deck .ht-player::after{content:"";}
}
.home-feed-title{font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);margin:2px 4px 4px;}
/* Chase-row variant: matches the MoversBanner title styling (Cinzel, accent
   color, no uppercase transform) so "Tournament Results" reads as a peer
   of "Chase Movers" when they sit side by side in the mobile grid. */
.home-feed-title--chase{font-family:'Cinzel',serif;font-size:12px;font-weight:600;
  letter-spacing:0.3px;text-transform:none;color:var(--accent);margin:0 0 3px;}
.home-feed-empty{font-size:12px;color:var(--text-dim);line-height:1.5;
  padding:2px 4px 6px;}
.home-feed-signin{display:block;margin-top:6px;padding:6px 12px;font-size:12px;}
.home-feed-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px;
  max-height:340px;overflow-y:auto;}
.home-feed-item{}
.home-feed-link{display:flex;gap:6px;align-items:center;
  padding:3px 6px;border-radius:5px;text-decoration:none;color:inherit;
  transition:background 0.1s;line-height:1.2;}
.home-feed-link:hover{background:var(--bg-card);}
.home-feed-verb-dot{flex-shrink:0;width:6px;height:6px;border-radius:50%;
  background:var(--text-muted);}
.home-feed-verb-dot.pub{background:var(--green);}
.home-feed-verb-dot.upd{background:#d4a93b;}
.home-feed-main{flex:1;min-width:0;display:flex;flex-direction:column;}
.home-feed-deckname-line{display:flex;gap:5px;align-items:center;min-width:0;}
.home-feed-deckname{font-size:12px;font-weight:600;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1;}
.home-feed-link:hover .home-feed-deckname{color:var(--accent);}
.home-feed-fmt-tag{flex-shrink:0;font-size:8px;font-weight:700;letter-spacing:0.4px;
  padding:1px 4px;border-radius:3px;text-transform:uppercase;line-height:1.4;}
.home-feed-fmt-tag.fmt-infinity{background:var(--bg-card);color:var(--text-muted);
  border:1px solid var(--border);}
.home-feed-fmt-tag.fmt-core{background:var(--accent);color:#fff;}
.home-feed-meta{font-size:10px;color:var(--text-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.home-feed-creator{font-weight:600;color:var(--text-dim);}
.home-feed-inks{display:flex;gap:2px;flex-shrink:0;align-items:center;}
.home-feed-ink-icon{width:13px;height:13px;object-fit:contain;display:block;}

/* Panel header — flex container with title on the left, minimize button
   on the right. Used by CollectionPanel and other right-column panels. */
.panel-header{display:flex;justify-content:space-between;align-items:center;
  gap:8px;margin-bottom:8px;}
.panel-header .panel-title{margin:0;}
.panel-min-btn{background:transparent;border:1px solid var(--border);color:var(--text-muted);
  width:24px;height:24px;border-radius:5px;padding:0;cursor:pointer;font-size:11px;
  display:flex;align-items:center;justify-content:center;transition:all 0.12s;}
.panel-min-btn:hover{color:var(--accent);border-color:var(--accent);}
.panel-header-actions{display:flex;align-items:center;gap:6px;flex-shrink:0;}
.panel-eye-btn svg{display:block;}
.collection-panel.is-min{padding-bottom:12px;}

.home-grid{display:grid;grid-template-columns:240px minmax(0,1fr) 360px;gap:18px;
  align-items:start;margin-bottom:14px;}
.home-grid-main{min-width:0;}
.home-feed{grid-column:auto;}
.home-left-col{grid-column:1;display:flex;flex-direction:column;gap:14px;min-width:0;}
.home-left-col > .home-feed{align-self:stretch;width:100%;box-sizing:border-box;margin-bottom:0;}
/* Tournament column: .home-tourney-col--desktop renders inside .home-left-col
   (stacked below Following) and is hidden at ≤1100px, where the side-by-side
   chase-row slot ([data-debug="rareleg-row-tourney"]) takes over instead. */
.home-tourney-col > .home-feed{align-self:stretch;width:100%;box-sizing:border-box;margin-bottom:0;}
@media (max-width:1100px){
  .home-tourney-col--desktop{display:none;}
}
@media (max-width:1100px){
  /* Inside the mobile chase-row grid the tournament column is height-locked
     to the chase movers banner (alignItems:stretch on the grid). The home-feed
     fills the cell, and the .home-tourney-list inside is the scroll container
     — every flex ancestor needs min-height:0 for the scroll to actually work
     instead of overflowing. Rows are tightened so as many fit as possible
     before the scrollbar kicks in. */
  [data-debug="rareleg-row-tourney"]{display:flex;min-height:0;position:relative;}
  /* Take the panel OUT of flow (absolute, inset:0) so the tournament column
     contributes ZERO intrinsic height to the grid row — the row height is set
     entirely by the chase-movers column, and this panel fills that height and
     scrolls internally. Without this, once the content (4 events × top 8)
     exceeds the movers column it STRETCHES the row (~626px) instead of
     scrolling. */
  /* display:flex + margin-bottom:0 need !important to beat the stacked-column
     `.home-feed{display:block!important;margin-bottom:14px!important}` rule
     (≤1100px) — our selector is more specific, so !important wins the tie. */
  [data-debug="rareleg-row-tourney"] > .home-feed{margin-bottom:0 !important;padding:5px 7px;
    max-height:none;position:absolute;inset:0;width:100%;min-height:0;
    display:flex !important;flex-direction:column;box-sizing:border-box;}
  [data-debug="rareleg-row-tourney"] .home-tourney-list{gap:6px;flex:1;min-height:0;
    overflow-y:auto;overflow-x:hidden;
    /* Slim, theme-neutral scrollbar so it doesn't fight the gold accents. */
    scrollbar-width:thin;}
  [data-debug="rareleg-row-tourney"] .home-tourney-list::-webkit-scrollbar{width:5px;}
  [data-debug="rareleg-row-tourney"] .home-tourney-list::-webkit-scrollbar-thumb{
    background:var(--border);border-radius:3px;}
  [data-debug="rareleg-row-tourney"] .home-tourney-block{gap:2px;}
  /* No per-event cap here: the panel is height-locked to the chase-movers
     banner (flex:1 + overflow-y:auto on .home-tourney-list above), so all top-8
     deck rows for the 4 recent events SCROLL inside the box instead of
     stretching the row. (Previously capped to top 2 to keep the box near the
     banner height — but that hid useful rows; scrolling a fixed box is better.) */
  [data-debug="rareleg-row-tourney"] .home-tourney-name{font-size:10px;line-height:1.2;}
  [data-debug="rareleg-row-tourney"] .home-tourney-deck{padding:2px 4px;gap:4px;
    grid-template-columns:16px 1fr auto;font-size:10px;}
  [data-debug="rareleg-row-tourney"] .home-tourney-deck .ht-place{font-size:9px;}
  [data-debug="rareleg-row-tourney"] .home-tourney-deck .ht-player{font-size:10px;}
  [data-debug="rareleg-row-tourney"] .home-tourney-deck .ht-inks img{width:11px;height:11px;}
  /* Hide the deck name (ink-color noise) on the narrow mobile column. */
  [data-debug="rareleg-row-tourney"] .home-tourney-deck .ht-deck{display:none;}
}
.home-tourney-list{display:flex;flex-direction:column;gap:10px;}
/* Desktop: cap the tournament panel and scroll inside it so 4 events × top 8
   (up to ~32 rows) doesn't balloon the left column. Mobile handles its own
   height/scroll in the chase-row block above. */
.home-tourney-col--desktop .home-tourney-list{max-height:560px;overflow-y:auto;
  overflow-x:hidden;scrollbar-width:thin;}
.home-tourney-col--desktop .home-tourney-list::-webkit-scrollbar{width:5px;}
.home-tourney-col--desktop .home-tourney-list::-webkit-scrollbar-thumb{
  background:var(--border);border-radius:3px;}
.home-tourney-block{display:flex;flex-direction:column;gap:4px;}
.home-tourney-name{font-family:'Cinzel',serif;font-weight:700;font-size:12px;
  color:var(--accent);background:none;border:none;padding:0;cursor:pointer;text-align:left;
  letter-spacing:0.2px;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.home-tourney-name:hover{text-decoration:underline;}
.home-tourney-decks{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:2px;}
.home-tourney-deck{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:6px;
  align-items:center;width:100%;text-align:left;padding:4px 6px;border-radius:4px;
  background:none;border:1px solid transparent;color:var(--text);cursor:pointer;
  font-size:11px;line-height:1.2;}
.home-tourney-deck:hover:not(:disabled){background:var(--bg-card);border-color:var(--border);}
.home-tourney-deck:disabled{opacity:0.5;cursor:not-allowed;}
/* nowrap + auto-width column: "Top 4" / "Top 8" used to wrap into "Top" + "4"
   on the narrow signed-in home grid because the place column was pinned at
   28px. minmax(0,1fr) on the player column means it can still shrink if the
   place text is unusually long. */
.home-tourney-deck .ht-place{font-weight:800;color:var(--accent);font-size:10px;white-space:nowrap;padding-right:4px;}
.home-tourney-deck .ht-player{overflow:hidden;color:var(--text);font-weight:600;min-width:0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.2;}
.home-tourney-deck .ht-deck{color:var(--text-dim);font-weight:400;}
.home-tourney-deck .ht-inks{display:inline-flex;gap:1px;flex-shrink:0;}
.home-tourney-deck .ht-inks img{width:14px;height:14px;}
@media (max-width:1100px){
  /* Tablet + mobile re-layout: vertical stack, with signal first (movers +
     tourney are paired side-by-side inside home-grid-main). Following +
     collection panels stack below. */
  .home-grid{display:flex;flex-direction:column;min-width:0;max-width:100%;}
  .home-grid-main{order:1;min-width:0;max-width:100%;overflow:hidden;}
  .home-grid-main > *{min-width:0;max-width:100%;}
  /* Drop the sticky from .home-grid-right here. On desktop the right column
     (EV strip + CollectionPanel) pins so you can keep tracking your portfolio
     while scrolling the movers feed. On mobile the grid is a single column,
     so sticky pins the CollectionPanel to the viewport and the Following
     panel below it scrolls UNDER — both have translucent --bg-surface
     backgrounds, so the visual is a ghost-overlap of Following's "FOLLOWING"
     header rendering over CollectionPanel's "Your Top Movers" rows. */
  .home-grid-right{order:2;position:static;top:auto;}
  .home-left-col{order:3;}
}
@media (max-width:1100px){
  /* Stretch the panel full-width inside the stacked column — desktop's
     `align-self:start` would otherwise let it collapse to natural content
     width. Sticky is already off across all viewports (see the base rule)
     so no `position` override is needed here anymore. */
  .home-feed{align-self:stretch !important;width:100% !important;
    display:block !important;margin-bottom:14px !important;}
}
@media (max-width:640px){
  /* Tighten the page header so it doesn't eat 25% of the viewport. */
  .home-page-title{margin-bottom:6px;}
  /* Mover toolbar wraps; pause button stays out of the way. */
  .home-toolbar{flex-wrap:wrap;gap:6px;}
  /* Mover banner subtitle: wrap to next line instead of clipping when the
     window subtitle (e.g. "Top 20 non-chase by Low price") doesn't fit. */
  .movers-wrap + *, section > div > span.muted{white-space:normal;}
  /* Force the entire banner header (title + subtitle) to wrap so the
     subtitle gets its own line if it's long. */
  section > div[style*="flex"]:first-child > .muted,
  section > div[style*="flex"]:first-child{flex-basis:auto;}
}
.collection-panel{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:8px;padding:14px 16px;}
.collection-panel .panel-title{font-family:var(--font-title,inherit);font-size:13px;
  font-weight:600;letter-spacing:0.3px;margin:0 0 8px;color:var(--accent);
  text-transform:uppercase;}
.collection-panel .panel-value{margin-bottom:10px;}
.collection-panel .panel-value-now{font-size:24px;font-weight:700;line-height:1.1;}
.collection-panel .panel-value-delta{font-size:12px;font-weight:600;margin-top:3px;}
.collection-panel .panel-range-buttons{display:flex;gap:4px;margin-bottom:6px;}
.panel-section-toggles{display:flex;flex-wrap:wrap;gap:4px 12px;margin:4px 0 8px;font-size:11px;}
.panel-section-toggles label{display:inline-flex;align-items:center;gap:5px;cursor:pointer;
  color:var(--text);user-select:none;}
.panel-section-toggles input[type="checkbox"]{margin:0;}
.panel-toggle-swatch{width:10px;height:10px;border-radius:2px;display:inline-block;flex-shrink:0;}
.panel-section-toggles em{color:var(--text-muted);font-style:normal;font-variant-numeric:tabular-nums;
  font-size:10px;font-weight:600;}
.collection-panel .panel-range-buttons button{padding:3px 9px;font-size:11px;font-weight:600;
  background:transparent;color:var(--text-muted);border:1px solid var(--border);
  border-radius:4px;cursor:pointer;}
.collection-panel .panel-range-buttons button.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.collection-panel .panel-range-buttons button:hover:not(.active){color:var(--text);border-color:var(--accent);}
.collection-panel .panel-chart{margin:4px -4px 12px;}
.collection-panel .panel-movers{border-top:1px solid var(--border);padding-top:10px;}
.collection-panel .panel-movers-title{font-size:10px;font-weight:600;
  color:var(--text-muted);letter-spacing:0.5px;text-transform:uppercase;margin-bottom:6px;}
.collection-panel .panel-movers-controls{display:flex;flex-direction:column;gap:5px;margin-bottom:6px;}
.collection-panel .panel-dir-toggle{display:flex;gap:8px;font-size:11px;}
.collection-panel .panel-dir-toggle label{display:flex;align-items:center;gap:3px;cursor:pointer;
  color:var(--text-muted);user-select:none;}
.collection-panel .panel-dir-toggle label.on-up{color:var(--green);}
.collection-panel .panel-dir-toggle label.on-down{color:var(--red);}
.collection-panel .panel-dir-toggle input{margin:0;}
/* table-layout:fixed pins the IMG / price / pct columns to their declared
   widths and gives the name column the remainder. Without this the browser's
   auto-layout was leaking slack into the IMG cell (it grew to ~170px while
   the name truncated to 34px). */
.collection-panel .panel-movers-table{width:100%;border-collapse:collapse;font-size:11px;table-layout:fixed;}
.collection-panel .panel-movers-table tr{cursor:pointer;}
.collection-panel .panel-movers-table tr:hover{background:var(--bg-surface-hover);}
.collection-panel .panel-movers-table td{padding:3px 4px;vertical-align:middle;border:none;}
/* Card thumbnail in "Your Top Movers". Fixed cell width pins the column so
   the name cell (max-width:0 + flex-grow) reclaims the remaining space —
   without an explicit width here the table's auto-layout was leaving a big
   empty gap between thumbnail and name. `object-fit:cover` with a box
   aspect matching the Lorcast small image (146×204 = ~5:7) means the
   visible crop is sub-pixel — the whole card art is effectively shown.
   Specificity bump (td.panel-movers-img) beats the general TD padding. */
.collection-panel .panel-movers-table td.panel-movers-img{padding:3px 4px;width:40px;}
.collection-panel .panel-movers-img img{width:32px;height:45px;object-fit:cover;border-radius:3px;display:block;}
/* Two-line layout: card name (line 1) + optional "FOIL" sub-label (line 2,
   Cold Foil only). The cell uses vertical-align:top and a fixed top
   padding so the name-text always sits at the same Y across rows
   regardless of whether the sub-label is rendered. Without this, the td's
   default vertical-align:middle centered the name+tag stack, which moved
   the name up ~5px on rows with the sub-label and broke horizontal
   alignment across the column. The 6px padding-top puts the name slightly
   above the geometric middle of the 31px image cell — a deliberate
   compromise so two-line rows (name + tag) stay within the row height
   without growing it. */
.collection-panel .panel-movers-name{line-height:1.15;vertical-align:top;
  padding-top:6px !important;text-align:left;}
.collection-panel .panel-movers-name-text{overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.collection-panel .panel-movers-foil-tag{display:block;font-size:8.5px;font-weight:700;
  letter-spacing:0.5px;text-transform:uppercase;color:var(--accent);
  line-height:1;margin-top:2px;}
.collection-panel .panel-movers-price{text-align:right;font-variant-numeric:tabular-nums;color:var(--text-dim);width:50px;}
.collection-panel .panel-movers-pct{text-align:right;font-weight:600;font-variant-numeric:tabular-nums;width:54px;}

/* Home toolbar (window picker + direction toggles) */
.home-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin:8px 0 14px;}
.home-toolbar .seg-grp{display:flex;gap:4px;background:var(--stat-bg);border:1px solid var(--border);
  border-radius:8px;padding:3px;}
.home-toolbar .seg-grp button{background:transparent;border:none;color:var(--text);
  padding:4px 10px;border-radius:5px;font-size:12px;cursor:pointer;font-family:inherit;}
.home-toolbar .seg-grp button.active{background:var(--accent);color:#fff;}
.home-toolbar .seg-grp button:hover:not(.active){background:var(--accent-glow);}
.home-toolbar .dir-toggle{display:flex;gap:6px;align-items:center;flex-wrap:wrap;}
.home-toolbar .dir-toggle label{display:inline-flex;align-items:center;gap:5px;
  font-size:12px;color:var(--text-dim);cursor:pointer;
  border:1px solid var(--border);border-radius:6px;padding:4px 9px;
  background:var(--stat-bg);white-space:nowrap;}
.home-toolbar .dir-toggle label.on-up{color:var(--green);border-color:var(--green);}
.home-toolbar .dir-toggle label.on-down{color:var(--red);border-color:var(--red);}
.home-toolbar .dir-toggle label input{accent-color:currentColor;}
.drawer-header{padding:14px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;}
.drawer-header h3{margin:0;font-family:'Cinzel',serif;font-size:16px;color:var(--accent);}
.drawer-body{flex:1;overflow-y:auto;padding:12px 16px;}
.drawer-footer{padding:12px 16px;border-top:1px solid var(--border);display:flex;gap:8px;justify-content:space-between;}
.drawer-section{margin-bottom:14px;}
.drawer-section-head{font-size:11px;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);font-weight:700;margin-bottom:6px;}
.drawer-section .chip{margin:2px 2px 0 0;font-size:11px;}
.filter-count-badge{display:inline-block;background:var(--accent);color:#fff;border-radius:10px;padding:1px 6px;font-size:10px;font-weight:700;margin-left:4px;}
.drawer-divider{height:1px;background:var(--border);margin:10px 0 8px;}
.chip.promo{opacity:0.85;font-style:italic;}
/* Card detail modal ---------------------------------------------------- */
.card-detail-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.65);z-index:100;display:flex;align-items:center;justify-content:center;padding:20px;animation:fadeIn 0.15s ease;}

/* Enlarged card overlay — fires from tile double-click and detail-modal
   image click. Sits ABOVE the detail modal (z-index:200 > 100) so when the
   detail-modal image is clicked, the enlarged view appears on top and the
   modal stays underneath until dismissed. Clicking the backdrop or pressing
   Escape closes the overlay (handled in JS, see EnlargedCardOverlay). */
.enlarged-card-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.85);
  z-index:200;display:flex;align-items:center;justify-content:center;
  padding:20px;animation:fadeIn 0.15s ease;cursor:zoom-out;}
.enlarged-card-img{
  /* Force the image to scale UP to the viewport-derived size — the source
     is ~488×681px (Lorcast "normal"); without an explicit width it would
     just render at natural size and the user wouldn't get an "enlarged"
     view at all. width caps at the lesser of 92vw / 92vh*(5/7) so we never
     spill beyond the viewport in either axis; height:auto preserves the
     5:7 card aspect ratio. */
  width:min(92vw, calc(92vh * 5 / 7), 720px);
  height:auto;max-height:92vh;
  border-radius:14px;
  box-shadow:0 12px 50px rgba(0,0,0,0.7);cursor:default;}
.enlarged-card-close{position:absolute;
  top:max(20px, env(safe-area-inset-top));right:20px;
  width:40px;height:40px;font-size:22px;line-height:1;
  background:rgba(0,0,0,0.55);color:#fff;border:1px solid rgba(255,255,255,0.18);
  border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;}
.enlarged-card-close:hover{background:rgba(0,0,0,0.75);border-color:rgba(255,255,255,0.35);}
@media (max-width:640px){
  .enlarged-card-overlay{padding:12px;}
  .enlarged-card-img{max-width:96vw;max-height:88vh;border-radius:10px;}
  .enlarged-card-close{top:max(12px, env(safe-area-inset-top));right:12px;
    width:36px;height:36px;font-size:20px;}
}
.card-detail{position:relative;background:var(--bg-solid);border:1px solid var(--border);border-radius:14px;max-width:980px;max-height:92vh;width:100%;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,0.4);}
.card-detail > div:not(.card-detail-close):not(.card-detail-history-section):not(.card-detail-top){flex-shrink:0;}
.card-detail{overflow-y:auto;-webkit-overflow-scrolling:touch;}
.card-detail-top{display:flex;gap:0;flex-shrink:0;}
/* Mobile card-detail tightening is consolidated into the single
   @media (max-width:700px) block below (the project's table/wide-surface
   breakpoint). It previously lived in two overlapping blocks (640px + 700px)
   that both matched ≤640px and fought on source order — the 700px block won
   padding/img-max-width but only the 640px block actually stacked the image
   over the body (via .card-detail-top{flex-direction:column}), so in the
   641–700px band the image and body stayed side-by-side. One block now makes
   the phone layout deterministic across the whole ≤700px range. */
/* X close button. `top` uses max(10px, safe-area-inset-top) so it stays
   tappable on iPhone with Dynamic Island (otherwise sits at y≈18px
   under the Island's ~y=60px reach — Photo 3 regression). On desktop and
   non-notched devices the env value is 0 and we keep the designed 10px. */
.card-detail-close{position:absolute;top:max(10px,env(safe-area-inset-top));right:max(10px,env(safe-area-inset-right));width:34px;height:34px;border-radius:50%;background:rgba(0,0,0,0.4);color:#fff;border:none;font-size:22px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1;z-index:2;}
.card-detail-close:hover{background:rgba(0,0,0,0.7);}
.card-detail-image{flex:0 0 340px;padding:24px;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;}
.card-detail-image img{width:100%;max-width:300px;height:auto;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.25);}
/* In-modal banner tile of the card (canvas-drawn; preview == copied image). */
.card-tile-preview{position:relative;width:100%;max-width:300px;}
.card-tile-canvas{display:block;width:100%;height:auto;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.25);}
.card-tile-cam{position:absolute;top:8px;right:8px;width:30px;height:30px;display:flex;
  align-items:center;justify-content:center;background:rgba(0,0,0,0.72);color:#fff;border:none;
  border-radius:6px;padding:0;cursor:pointer;transition:background 0.15s ease;}
.card-tile-cam:hover{background:rgba(0,0,0,0.92);}
.card-tile-cam svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;display:block;}
.card-detail-body{flex:1;padding:28px 28px 28px 0;}
.card-detail-body h2{margin:0 0 4px;font-size:22px;color:var(--text);font-weight:600;}
.card-detail-subtitle{font-size:13px;color:var(--text-dim);margin-bottom:10px;}
.card-detail-meta{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:16px;}
.card-detail-set{font-size:12px;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.4px;font-weight:500;}
.card-detail-variant-tag{font-size:11px;font-weight:700;letter-spacing:0.3px;color:var(--accent);
  background:var(--accent-glow);border:1px solid var(--border-accent);border-radius:6px;padding:2px 8px;white-space:nowrap;}
.card-detail-stats{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px;}
.stat-pill{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:6px 10px;display:flex;flex-direction:column;line-height:1.2;min-width:60px;}
.stat-pill .lbl{font-size:9px;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.5px;font-weight:600;}
.stat-pill .val{font-size:14px;font-weight:600;color:var(--text);}
.card-detail-rules{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;font-size:13px;line-height:1.6;color:var(--text);margin-bottom:10px;white-space:pre-wrap;}
.card-detail-flavor{font-size:12px;color:var(--text-dim);font-style:italic;line-height:1.5;margin-bottom:18px;padding:0 4px;}
.card-detail-prices{display:flex;flex-direction:column;gap:10px;margin-top:14px;}
.printing-block{display:block;background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;padding:12px 14px;text-decoration:none;color:var(--text);cursor:pointer;transition:background 0.12s,border-color 0.12s,transform 0.08s;}
.printing-block:hover{background:var(--bg-surface-hover);border-color:var(--border-accent);}
.printing-block:active{transform:translateY(1px);}
.printing-block-head{display:flex;justify-content:space-between;align-items:center;}
.printing-title{font-size:11px;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);font-weight:700;}
.printing-ext{font-size:14px;color:var(--text-muted);}
.printing-block:hover .printing-ext{color:var(--accent);}
.printing-subtitle{font-size:10px;color:var(--text-muted);font-style:italic;margin-top:2px;}
.printing-prices{margin-top:6px;display:flex;flex-direction:column;gap:2px;}
.price-line{display:flex;justify-content:space-between;font-size:12px;color:var(--text-dim);}
.price-line .lbl{text-transform:uppercase;letter-spacing:0.4px;font-weight:500;font-size:10px;}
.price-line .val{font-weight:600;color:var(--text);}
.price-line .val.main{font-size:18px;font-weight:700;color:var(--text);}
@media (max-width: 700px){
  /* Mobile: stack image above body so a 375px viewport doesn't push content
     off-screen, and cap image height so the modal doesn't open zoomed-in onto
     a giant card. .card-detail-top is the actual flex ROW (image + body) —
     stacking happens here, not on .card-detail (already column). */
  .card-detail-overlay{padding:8px;}
  .card-detail{flex-direction:column;max-height:95vh;border-radius:10px;}
  .card-detail-top{flex-direction:column;}
  .card-detail-image{flex:0 0 auto;padding:20px 20px 0;}
  .card-detail-image img{max-width:220px;max-height:280px;width:auto;}
  .card-detail-body{padding:20px;}
  .card-detail-body h2{font-size:18px;}
  .card-detail-screener{padding:14px 20px;}
  .cd-stat{padding:8px 10px;}
  .cd-stat-grid{grid-template-columns:30px repeat(6,1fr);gap:1px 2px;}
  .cd-stat-h{font-size:8px;}
  .cd-stat-v{font-size:10px;}
}
/* Line chart -------------------------------------------------------- */
.line-chart-wrap{position:relative;}
.line-chart{display:block;cursor:crosshair;}
.chart-empty{font-size:11px;color:var(--text-muted);text-align:center;padding:14px;border:1px dashed var(--border);border-radius:6px;}
.chart-empty.large{padding:60px;font-size:13px;}
.legend-swatch{display:inline-block;width:10px;height:3px;border-radius:1px;margin-right:4px;vertical-align:middle;}
.chart-tooltip{position:absolute;top:6px;background:var(--tooltip-bg);border:1px solid var(--tooltip-border);box-shadow:var(--tooltip-shadow);border-radius:6px;padding:6px 10px;font-size:11px;pointer-events:none;z-index:5;min-width:130px;}
.chart-tooltip-date{font-weight:700;color:var(--text);margin-bottom:4px;font-size:11px;}
.chart-tooltip-row{display:flex;align-items:center;gap:6px;line-height:1.4;}
.chart-tooltip-label{flex:1;color:var(--text-dim);}
.chart-tooltip-value{font-weight:700;color:var(--text);font-variant-numeric:tabular-nums;}
.chart-tooltip-pct{font-size:10px;font-weight:600;margin-left:2px;font-variant-numeric:tabular-nums;}
.chart-tooltip-pct.up{color:var(--green);}
.chart-tooltip-pct.down{color:var(--red);}
.custom-date-input{padding:4px 8px;font-size:12px;border:1px solid var(--btn-border);border-radius:5px;background:var(--bg-solid);color:var(--text);font-family:'Nunito Sans',sans-serif;}
.card-detail-history-section{padding:18px 28px 24px;border-top:1px solid var(--border);background:var(--bg-surface);}
/* Tabs for switching between Price History chart and Graded table. */
.card-detail-tabs{display:flex;gap:4px;margin-bottom:14px;padding-bottom:8px;
  border-bottom:1px solid var(--border);}
.card-detail-tab{padding:7px 16px;font-size:13px;font-weight:600;border:none;
  background:transparent;color:var(--text-dim);border-radius:6px 6px 0 0;
  cursor:pointer;display:inline-flex;align-items:center;gap:6px;
  border-bottom:2px solid transparent;margin-bottom:-9px;transition:color 0.12s, border-color 0.12s;}
.card-detail-tab:hover{color:var(--text);}
.card-detail-tab.active{color:var(--accent);border-bottom-color:var(--accent);}
.card-detail-tab-count{font-size:10px;font-weight:700;padding:1px 6px;border-radius:8px;
  background:var(--bg-surface);color:var(--text-muted);font-variant-numeric:tabular-nums;}
.card-detail-tab.active .card-detail-tab-count{background:var(--accent);color:#fff;}

/* Graded Prices tab — grid table with sparklines. */
.graded-tab{padding:4px 0 2px;}
.graded-tab-explain{font-size:11.5px;color:var(--text-muted);margin-bottom:12px;line-height:1.5;}
/* Secondary explainer for the Paid / Acquired / Value meta inputs that render
   under each owned slot. Less prominent than the main explainer; sits just
   above the grader table. */
.graded-tab-meta-explain{font-size:11px;line-height:1.5;margin-bottom:10px;
  padding:8px 10px;background:var(--bg-card);border:1px solid var(--border);
  border-radius:6px;}
.graded-tab-meta-explain strong{color:var(--text);font-weight:700;}
/* Per-owned-slot meta row: full-width strip below the table row, holds the
   three inputs side by side via the existing CostDateInputs component. */
.graded-row-meta{padding:8px 14px 10px;background:var(--bg-card);
  border-top:1px dashed var(--border);
  display:flex;flex-direction:column;gap:6px;}
.graded-row-meta-tag{font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.graded-tab-table{display:flex;flex-direction:column;gap:1px;background:var(--border);
  border:1px solid var(--border);border-radius:8px;overflow:hidden;}
/* Columns: Grader · Grade · Latest avg (avg_1d, primary) · 30d avg (avg_30d,
   secondary) · Range (30d) · Trend (sparkline) · Last sale [· Owned]. The
   7d avg column was dropped 2026-05-26 — see CLAUDE.md note on graded
   primary-metric switch. avg_7d is no longer surfaced as a price; avg_1d
   is the "Last" and avg_30d is the smoother secondary, mirroring Low/NM
   Market for raw cards. */
.graded-tab-thead, .graded-row{display:grid;
  grid-template-columns:62px 56px 1fr 1fr 1.3fr 130px 90px;
  align-items:center;gap:0;background:var(--bg-card);padding:7px 10px;font-size:12px;}
.graded-tab-table-editable .graded-tab-thead,
.graded-tab-table-editable .graded-row{
  grid-template-columns:62px 56px 1fr 1fr 1.3fr 130px 90px 102px;}
.graded-owned-cell{display:inline-flex;align-items:center;gap:4px;justify-content:flex-end;}
.graded-qty-btn{appearance:none;background:var(--bg-surface);border:1px solid var(--btn-border);
  width:24px;height:24px;border-radius:50%;cursor:pointer;font-weight:800;font-size:14px;
  color:var(--text);display:inline-flex;align-items:center;justify-content:center;line-height:1;padding:0;}
.graded-qty-btn:hover:not(:disabled){background:var(--accent);color:#fff;border-color:var(--accent);}
.graded-qty-btn:disabled{opacity:0.4;cursor:not-allowed;}
.graded-qty-num{min-width:22px;text-align:center;font-variant-numeric:tabular-nums;
  font-weight:700;font-size:13px;color:var(--text-muted);}
.graded-qty-num.has{color:var(--accent);}
/* Prominent owned-graded block in the modal body. Renders only when the
   modal is opened from the Graded collection view (isGradedFocus). */
.card-detail-graded-owned{margin:12px 0 4px;padding:10px 12px;
  background:rgba(200,168,70,0.10);border:1px solid rgba(200,168,70,0.32);
  border-radius:8px;}
.card-detail-graded-owned-head{font-weight:700;font-size:13px;color:#c8a846;
  letter-spacing:0.3px;text-transform:uppercase;display:flex;
  justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;}
.card-detail-graded-add-btn{padding:4px 10px;font-size:11px;letter-spacing:0.3px;}
.card-detail-graded-owned-list{display:flex;flex-direction:column;gap:8px;margin-top:8px;}
/* Was a single flex row; each owned slot now stacks (qty controls on top,
   Paid / Acquired / Value inputs below) so the meta inputs have full width. */
.card-detail-graded-owned-row{display:flex;flex-direction:column;
  gap:8px;padding:8px 10px;background:var(--bg-card);border-radius:6px;}
.card-detail-graded-owned-line{display:flex;align-items:center;
  justify-content:space-between;gap:10px;}
.card-detail-graded-owned-tag{font-weight:700;font-size:12px;color:var(--text);letter-spacing:0.3px;}
.card-detail-graded-owned-ctl{display:inline-flex;align-items:center;gap:6px;}
.card-detail-graded-owned-help{font-size:11px;line-height:1.5;
  margin-top:6px;padding:6px 8px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:5px;}
.card-detail-graded-owned-help strong{color:var(--text);font-weight:700;}
.card-detail-graded-rawref{font-size:11px;line-height:1.5;margin-top:6px;padding:6px 8px;
  background:var(--accent-glow);border:1px solid var(--border-accent);border-radius:5px;}
.card-detail-graded-rawref strong{color:var(--accent);font-weight:700;}
.card-detail-graded-owned-qty{min-width:24px;text-align:center;font-variant-numeric:tabular-nums;
  font-weight:800;font-size:14px;color:var(--accent);}
.graded-tab-thead{font-weight:700;color:var(--text-muted);font-size:10px;
  text-transform:uppercase;letter-spacing:0.4px;background:var(--bg-surface);}
.graded-row.is-top{background:linear-gradient(90deg, rgba(200,168,70,0.10), var(--bg-card));}
.graded-grader{font-weight:700;font-size:12px;letter-spacing:0.3px;}
.graded-grade{font-weight:800;font-size:14px;font-variant-numeric:tabular-nums;color:var(--text);}
.graded-cell{font-variant-numeric:tabular-nums;color:var(--text);}
.graded-cell-main{font-weight:700;color:var(--green);}
.graded-cell-range{font-size:11px;color:var(--text-dim);display:inline-flex;gap:4px;align-items:center;}
.graded-cell-range .dash{color:var(--text-muted);}
.graded-spark{display:flex;align-items:center;}
.graded-spark-btn{appearance:none;background:transparent;border:1px solid transparent;border-radius:4px;
  padding:2px 4px;cursor:pointer;color:inherit;transition:background 0.12s, border-color 0.12s;}
.graded-spark-btn:hover{background:var(--bg-surface);border-color:var(--border);}
.graded-spark-btn.is-active{background:var(--bg-surface);border-color:var(--accent);}
.graded-row.is-expanded{background:var(--bg-surface);}
.graded-row-expand{background:var(--bg-card);padding:12px 14px 10px;border-top:1px dashed var(--border);}
.graded-featured-chart{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;
  padding:12px 14px 10px;margin-bottom:14px;}
.graded-featured-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:6px;}
.graded-featured-label{font-weight:700;font-size:13px;letter-spacing:0.3px;}
.graded-featured-sub{font-size:11px;}
.graded-date{font-size:10.5px;color:var(--text-muted);}
@media (max-width:780px){
  /* Mobile drops the Range column (nth-child 5 in the new 7-col layout)
     and the Last-sale column (nth-child 7). Latest avg + 30d avg + Trend
     stay visible. */
  .graded-tab-thead, .graded-row{grid-template-columns:56px 44px 1fr 1fr 110px;}
  .graded-tab-thead > :nth-child(5), .graded-row > :nth-child(5){display:none;}
  .graded-tab-thead > :nth-child(7), .graded-row > :nth-child(7){display:none;}
  .graded-tab-table-editable .graded-tab-thead,
  .graded-tab-table-editable .graded-row{
    grid-template-columns:56px 44px 1fr 1fr 110px 96px;}
}
/* ── Premium graded view: per-sale eBay scatter + Last Sold / Avg-5 ──────── */
.graded-sales-tab{padding:4px 0 2px;}
.gs-headline{display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  background:linear-gradient(90deg, rgba(200,168,70,0.10), var(--bg-card));
  border:1px solid var(--border);border-radius:10px;padding:12px 16px;margin-bottom:12px;}
.gs-headline-combo{font-weight:800;font-size:15px;letter-spacing:0.3px;white-space:nowrap;}
.gs-headline-stats{display:flex;gap:26px;flex-wrap:wrap;flex:1;}
.gs-stat{display:flex;flex-direction:column;gap:1px;}
.gs-stat-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);}
.gs-stat-val{font-size:20px;font-weight:800;color:var(--text);font-variant-numeric:tabular-nums;line-height:1.1;}
.gs-stat-sub{font-size:10.5px;color:var(--text-muted);}
.gs-combo-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px;}
.gs-combo-chip{display:inline-flex;align-items:center;gap:5px;cursor:pointer;
  font-family:'Nunito Sans',sans-serif;font-size:11.5px;font-weight:700;
  padding:4px 9px;border-radius:14px;border:1px solid var(--border);
  background:var(--bg-surface);color:var(--text-dim);transition:border-color .12s,color .12s,background .12s;}
.gs-combo-chip:hover{color:var(--text);}
.gs-combo-chip.active{background:var(--bg-card);font-weight:800;}
.gs-combo-chip.focus{box-shadow:0 0 0 2px var(--bg-solid),0 0 0 3px currentColor;}
.gs-combo-all.active{border-color:var(--accent);color:var(--accent);}
.gs-trend-toggle.active{border-color:var(--accent);color:var(--accent);}
.gs-copy-img{margin-left:auto;border-color:var(--accent);color:var(--accent);font-weight:800;}
.gs-copy-img:hover{background:var(--accent);color:var(--bg-solid);}
.gs-chip-mark{display:inline-flex;align-items:center;flex-shrink:0;}
.gs-chip-mark svg{display:block;}
.gs-report-btn,.gs-admin-btn{appearance:none;background:transparent;border:1px solid var(--border);
  border-radius:6px;padding:3px 9px;font-size:11px;font-weight:700;cursor:pointer;
  font-family:'Nunito Sans',sans-serif;color:var(--text-dim);transition:border-color .12s,color .12s;}
.gs-report-btn:hover{border-color:var(--red,#c0392b);color:var(--red,#c0392b);}
.gs-admin-btn:hover{border-color:var(--accent);color:var(--accent);}
/* Card-detail Raw/Graded toggle + graded price tile + graded price-changes */
.card-detail-rgtoggle{display:flex;gap:6px;padding:0 28px;margin:2px 0 6px;align-items:center;}
.card-detail-rgtoggle .card-detail-tab{cursor:pointer;}
.cd-add-private{margin-left:auto;font-size:11px!important;border:1px dashed var(--accent)!important;color:var(--accent)!important;}
.cd-graded-tile{margin-top:10px;border:1px solid var(--border);border-radius:10px;
  background:linear-gradient(90deg, rgba(200,168,70,0.08), var(--bg-card));padding:11px 13px;}
.cd-graded-tile-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px;}
.cd-graded-tile-tag{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);}
.cd-graded-tile-select{font-size:11px;font-weight:700;padding:3px 6px;border-radius:6px;
  background:var(--bg-modal);color:var(--text);border:1px solid var(--border);max-width:62%;}
.cd-graded-tile-stats{display:flex;gap:22px;flex-wrap:wrap;}
.cd-gt-stat{display:flex;flex-direction:column;gap:1px;}
.cd-gt-lbl{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-muted);}
.cd-gt-val{font-size:20px;font-weight:800;color:var(--text);font-variant-numeric:tabular-nums;line-height:1.1;}
.cd-gt-sub{font-size:10px;color:var(--text-muted);}
.cd-graded-tile-empty{font-size:12px;padding:4px 0;}
/* Standalone grader/grade picker under the (now graded-data) card tile. */
.card-detail-gradedpick{margin-top:8px;display:flex;justify-content:center;width:100%;}
.card-detail-gradedpick .cd-graded-tile-select{width:auto;max-width:100%;}
.cd-gt-deltas{display:flex;gap:6px;margin-top:10px;padding-top:9px;border-top:1px dashed var(--border);}
.cd-gt-delta{display:flex;flex-direction:column;align-items:center;gap:1px;flex:1;
  border:1px solid var(--border);border-radius:7px;padding:4px 6px;background:var(--bg-card);}
.cd-gt-delta-win{font-size:9px;font-weight:800;text-transform:uppercase;letter-spacing:0.4px;color:var(--text-muted);}
.cd-gt-delta-pct{font-size:13px;font-weight:800;font-variant-numeric:tabular-nums;}
.card-detail-prices-tag{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);margin-bottom:4px;}
.cd-graded-changes{display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.cd-gc-id{display:flex;flex-direction:column;gap:1px;}
.cd-gc-name{font-size:13px;font-weight:800;letter-spacing:0.3px;}
.cd-gc-px{font-size:11px;color:var(--text-muted);font-variant-numeric:tabular-nums;}
.cd-gc-px b{color:var(--text);}
.cd-gc-grid{display:flex;gap:8px;flex-wrap:wrap;}
.cd-gc-cell{display:flex;flex-direction:column;align-items:center;gap:1px;min-width:52px;
  border:1px solid var(--border);border-radius:8px;padding:5px 9px;background:var(--bg-card);}
.cd-gc-win{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:0.4px;color:var(--text-muted);}
.cd-gc-pct{font-size:14px;font-weight:800;font-variant-numeric:tabular-nums;}
/* Graded report / admin-edit / review modals */
.gs-modal{position:relative;background:var(--bg-modal);border:1px solid var(--border);border-radius:14px;
  padding:20px 22px;max-width:480px;width:calc(100% - 32px);box-shadow:0 18px 60px rgba(0,0,0,0.5);}
.gs-modal-title{margin:0 0 10px;font-family:'Cinzel',serif;font-size:17px;color:var(--accent);font-weight:700;display:flex;align-items:center;gap:8px;}
.gs-modal-admin-tag{font-family:'Nunito Sans',sans-serif;font-size:9px;font-weight:800;text-transform:uppercase;
  letter-spacing:0.6px;color:var(--bg-solid);background:var(--accent);padding:2px 6px;border-radius:5px;}
.gs-modal-sale{font-size:12.5px;color:var(--text);font-weight:700;margin-bottom:8px;font-variant-numeric:tabular-nums;}
.gs-modal-help{font-size:12px;line-height:1.5;margin:0 0 8px;}
.gs-modal-link{font-size:12px;font-weight:700;color:var(--accent);text-decoration:none;display:inline-block;margin-bottom:10px;}
.gs-modal-textarea{width:100%;box-sizing:border-box;background:var(--bg-card);color:var(--text);
  border:1px solid var(--border);border-radius:8px;padding:8px 10px;font-size:13px;font-family:inherit;resize:vertical;}
.gs-modal-fields{display:flex;gap:12px;margin-bottom:10px;}
.gs-modal-fields label{display:flex;flex-direction:column;gap:3px;font-size:10px;font-weight:800;
  text-transform:uppercase;letter-spacing:0.5px;color:var(--text-muted);}
.gs-modal-fields select,.gs-modal-fields input{font-size:13px;font-weight:600;padding:6px 8px;border-radius:7px;width:100%;box-sizing:border-box;
  background:var(--bg-card);color:var(--text);border:1px solid var(--border);font-family:inherit;text-transform:none;letter-spacing:0;}
.gs-modal-fields label{flex:1;}
.gs-modal-cardpick{margin-bottom:14px;position:relative;}
.gs-modal-cardpick-lbl{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-muted);margin-bottom:3px;}
.gs-modal-cardcur{font-size:13px;font-weight:700;color:var(--text);margin-bottom:5px;}
.gs-modal-cardpick input{width:100%;box-sizing:border-box;font-size:13px;padding:6px 8px;border-radius:7px;
  background:var(--bg-card);color:var(--text);border:1px solid var(--border);font-family:inherit;}
.gs-modal-cardmatches{display:flex;flex-direction:column;gap:1px;margin-top:4px;max-height:190px;overflow-y:auto;
  border:1px solid var(--border);border-radius:8px;background:var(--bg-modal);}
.gs-modal-cardmatch{appearance:none;background:transparent;border:none;text-align:left;cursor:pointer;
  padding:6px 9px;font-size:12.5px;font-weight:600;color:var(--text);font-family:'Nunito Sans',sans-serif;border-bottom:1px solid var(--border);}
.gs-modal-cardmatch:last-child{border-bottom:none;}
.gs-modal-cardmatch:hover{background:var(--bg-surface);}
.gs-modal-actions{display:flex;gap:8px;justify-content:flex-end;align-items:center;margin-top:6px;}
.gs-modal-actions button{appearance:none;border:1px solid var(--border);background:var(--bg-card);color:var(--text);
  border-radius:8px;padding:7px 14px;font-size:13px;font-weight:700;cursor:pointer;font-family:'Nunito Sans',sans-serif;}
.gs-modal-actions button.active{background:var(--accent);color:var(--bg-solid);border-color:var(--accent);}
.gs-modal-actions button:disabled{opacity:0.55;cursor:default;}
.gs-modal-del{color:var(--red,#c0392b)!important;border-color:var(--red,#c0392b)!important;}
.gs-modal-del.armed{background:var(--red,#c0392b)!important;color:#fff!important;}
.gs-review-modal{max-width:640px;max-height:82vh;display:flex;flex-direction:column;}
.gs-review-filter{display:flex;gap:6px;margin-bottom:12px;text-transform:capitalize;}
.gs-review-list{overflow-y:auto;display:flex;flex-direction:column;gap:8px;}
.gs-review-row{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--border);border-radius:10px;padding:9px 11px;background:var(--bg-card);}
.gs-review-img{width:40px;height:54px;object-fit:cover;border-radius:4px;background:var(--bg-surface);flex-shrink:0;}
.gs-review-body{flex:1;min-width:0;}
.gs-review-line{display:flex;gap:8px;align-items:baseline;font-size:13px;font-variant-numeric:tabular-nums;flex-wrap:wrap;}
.gs-review-line a{color:var(--accent);text-decoration:none;font-weight:800;}
.gs-review-title{font-size:11px;line-height:1.35;margin-top:2px;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;}
.gs-review-comment{font-size:12px;color:var(--text-dim);margin-top:4px;font-style:italic;}
.gs-review-actions{display:flex;flex-direction:column;gap:4px;flex-shrink:0;}
.gs-review-actions button{appearance:none;border:1px solid var(--border);background:var(--bg-modal);color:var(--text-dim);
  border-radius:6px;padding:3px 9px;font-size:11px;font-weight:700;cursor:pointer;font-family:'Nunito Sans',sans-serif;white-space:nowrap;}
.gs-review-actions button:hover{color:var(--text);border-color:var(--accent);}
.price-db-admin-reports{border-color:var(--red,#c0392b)!important;color:var(--red,#c0392b)!important;}
.gs-chip-count{font-size:9.5px;font-weight:800;color:var(--text-muted);
  background:var(--bg-modal);border-radius:8px;padding:0 5px;font-variant-numeric:tabular-nums;}
.gs-chart{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;
  padding:8px 10px 4px;margin-bottom:12px;}
.scatter-chart-wrap{position:relative;}
.scatter-chart{display:block;}
.scatter-tooltip{position:absolute;display:flex;gap:8px;align-items:center;
  background:var(--tooltip-bg);border:1px solid var(--tooltip-border);box-shadow:var(--tooltip-shadow);
  border-radius:8px;padding:6px 8px;pointer-events:none;z-index:6;max-width:230px;}
.scatter-tip-img{width:42px;height:56px;object-fit:cover;border-radius:4px;
  background:var(--bg-surface);flex-shrink:0;}
.scatter-tip-body{display:flex;flex-direction:column;gap:1px;min-width:0;}
.scatter-tip-grade{font-size:11px;font-weight:800;letter-spacing:0.3px;}
.scatter-tip-price{font-size:14px;font-weight:800;color:var(--text);font-variant-numeric:tabular-nums;}
.scatter-tip-meta{font-size:10px;color:var(--text-muted);white-space:nowrap;}
.scatter-tip-hint{font-size:9px;color:var(--accent);text-transform:uppercase;letter-spacing:0.4px;font-weight:700;}
.gs-sale-detail{position:relative;display:flex;gap:12px;align-items:flex-start;
  background:var(--bg-modal);border:1px solid var(--accent);border-radius:10px;
  padding:12px 14px;margin-bottom:12px;}
.gs-sale-detail-imgwrap{flex-shrink:0;display:block;}
.gs-sale-detail-img{width:64px;height:86px;object-fit:cover;border-radius:5px;background:var(--bg-surface);display:block;}
/* Clicking a scatter dot or a sales-table row pops the detail as a floating,
   always-visible card (the inline box used to appear above the table, off-screen
   when you clicked a row near the bottom). The popup shows a larger slab photo. */
.gs-sale-pop-backdrop{position:fixed;inset:0;z-index:1200;background:rgba(0,0,0,0.45);
  display:flex;align-items:center;justify-content:center;padding:20px;}
.gs-sale-detail--pop{margin-bottom:0;max-width:460px;width:100%;max-height:86vh;overflow:auto;
  box-shadow:0 16px 56px rgba(0,0,0,0.55);}
.gs-sale-detail--pop .gs-sale-detail-img{width:150px;height:201px;}
.gs-sale-detail-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;}
.gs-sale-detail-title{font-size:12px;color:var(--text-dim);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.gs-sale-detail-line{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;font-size:12px;}
.gs-sale-detail-grade{font-weight:800;font-size:13px;letter-spacing:0.3px;}
.gs-sale-detail-price{font-weight:800;font-size:16px;color:var(--text);font-variant-numeric:tabular-nums;}
.gs-sale-detail-links{display:flex;gap:14px;flex-wrap:wrap;}
.gs-sale-detail-links a{font-size:12px;font-weight:700;color:var(--accent);text-decoration:none;}
.gs-sale-detail-links a:hover{text-decoration:underline;}
.gs-sale-detail-close{position:absolute;top:6px;right:8px;appearance:none;background:transparent;
  border:none;color:var(--text-muted);font-size:18px;line-height:1;cursor:pointer;padding:2px 6px;}
.gs-sale-detail-close:hover{color:var(--text);}
/* per-grade/grader summary table */
.gs-summary-wrap{border:1px solid var(--border);border-radius:8px;overflow:hidden;margin-bottom:12px;}
.gs-summary{width:100%;border-collapse:collapse;font-size:12.5px;}
.gs-summary thead th{text-align:left;font-size:9.5px;font-weight:800;text-transform:uppercase;letter-spacing:0.5px;
  color:var(--text-muted);background:var(--bg-surface);padding:7px 10px;border-bottom:1px solid var(--border);}
.gs-summary th.num, .gs-summary td.num{text-align:right;font-variant-numeric:tabular-nums;}
.gs-summary tbody td{padding:7px 10px;border-bottom:1px solid var(--border);color:var(--text);white-space:nowrap;}
.gs-summary tbody tr:last-child td{border-bottom:none;}
.gs-summary-row{cursor:pointer;transition:background .1s;}
.gs-summary-row:hover{background:var(--bg-surface);}
.gs-summary-row.active{background:linear-gradient(90deg, rgba(200,168,70,0.14), transparent);}
.gs-summary-grader{font-weight:800;letter-spacing:0.3px;}
.gs-summary-grade{font-weight:800;}
.gs-summary-last{font-weight:700;}
.gs-private-tag{color:var(--accent);font-weight:800;}
.gs-hover-img{position:fixed;z-index:9999;width:210px;height:auto;max-height:300px;border-radius:8px;
  box-shadow:0 12px 36px rgba(0,0,0,0.55);pointer-events:none;background:var(--bg-surface);border:1px solid var(--border);}
.gs-table-row.gs-private td{background:linear-gradient(90deg, rgba(200,168,70,0.07), transparent);}
.gs-table-wrap{border:1px solid var(--border);border-radius:8px;overflow:hidden;}
.gs-table{width:100%;border-collapse:collapse;font-size:12px;}
.gs-table thead th{text-align:left;font-size:9.5px;font-weight:800;text-transform:uppercase;
  letter-spacing:0.5px;color:var(--text-muted);background:var(--bg-surface);
  padding:7px 10px;border-bottom:1px solid var(--border);}
.gs-table th.num, .gs-table td.num{text-align:right;font-variant-numeric:tabular-nums;}
.gs-table tbody td{padding:6px 10px;border-bottom:1px solid var(--border);color:var(--text);white-space:nowrap;}
.gs-table tbody tr:last-child td{border-bottom:none;}
.gs-table-row{cursor:pointer;transition:background .1s;}
.gs-table-row:hover{background:var(--bg-surface);}
.gs-table-row.sel{background:linear-gradient(90deg, rgba(200,168,70,0.12), transparent);}
.gs-table-row a{color:var(--accent);text-decoration:none;font-weight:800;}
.gs-table-more{padding:6px 10px;font-size:11px;}
/* Listing-title cell: wraps to ~2 lines of small text, height-bounded so it
   never grows the row; full title on hover via the td's title attr. */
.gs-table td.gs-table-title{white-space:normal;max-width:200px;min-width:120px;font-size:10px;
  line-height:1.2;max-height:2.4em;overflow:hidden;color:var(--text-dim);}
@media (max-width:600px){
  /* Title (2) + Type (6) + ↗ link (7) collapse on phones to keep the core
     Date / Grader / Grade / Price columns; tap a row to see the full title. */
  .gs-table th:nth-child(2), .gs-table td:nth-child(2){display:none;}
  .gs-table th:nth-child(6), .gs-table td:nth-child(6){display:none;}
  .gs-table th:nth-child(7), .gs-table td:nth-child(7){display:none;}
  .gs-stat-val{font-size:18px;}
}
.card-detail-history-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;flex-wrap:wrap;gap:10px;}
.card-detail-history-legend{display:flex;flex-wrap:wrap;gap:12px;font-size:11px;color:var(--text-dim);}
/* "Copy image" button in the price-history header — exports the portrait poster. */
.card-detail-copy-btn{display:inline-flex;align-items:center;gap:6px;
  padding:5px 11px;font-size:11px;font-weight:700;letter-spacing:0.2px;cursor:pointer;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);border-radius:14px;
  font-family:'Nunito Sans',sans-serif;transition:border-color 0.12s,color 0.12s;}
.card-detail-copy-btn:hover{border-color:var(--accent);color:var(--accent);}
.card-detail-copy-btn svg{display:block;}
/* ── Card-detail "Price changes" panel + stat rows ─────────────────────
   Banner-tile-style delta grid (6 windows × LOW/MKT) per printing/variant.
   (The copy-image export is drawn on a <canvas> in JS — see
   buildCardPosterBlob — so it needs no CSS and can't be broken by a stale
   cached stylesheet.) */
.card-detail-screener{padding:14px 28px;border-top:1px solid var(--border);background:var(--bg-solid);}
/* Screener entry point: surface price changes + chart first, push the card
   image + description below. Flex order on the existing column avoids any
   JSX restructuring. Extra right padding on the first block dodges the
   absolutely-positioned × close button. */
.card-detail--price-first .card-detail-screener{order:1;border-top:none;padding-right:60px;}
.card-detail--price-first .card-detail-history-section{order:2;}
.card-detail--price-first .card-detail-top{order:3;border-top:1px solid var(--border);}
.card-detail-screener-head{display:flex;align-items:center;justify-content:space-between;
  gap:10px;margin-bottom:10px;flex-wrap:wrap;}
.cd-screener-title{font-family:'Cinzel',serif;font-size:14px;color:var(--accent);font-weight:600;}
.cd-variants-btn{font-size:11px;font-weight:600;letter-spacing:0.2px;padding:5px 11px;
  border-radius:6px;border:1px solid var(--btn-border);background:var(--bg-surface);
  color:var(--text-dim);cursor:pointer;font-family:'Nunito Sans',sans-serif;
  transition:border-color 0.12s,color 0.12s;}
.cd-variants-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.cd-variants-btn:disabled{opacity:0.6;cursor:default;}
.cd-stat-list{display:flex;flex-direction:column;gap:10px;}
.cd-stat{background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;padding:9px 12px;}
.cd-stat-id{display:flex;align-items:baseline;flex-wrap:wrap;gap:6px;margin-bottom:7px;}
.cd-stat-dot{font-size:11px;line-height:1;align-self:center;}
.cd-stat-name{font-weight:700;font-size:13px;color:var(--text);}
.cd-stat-sub{font-size:11px;color:var(--text-muted);}
/* "Buy on TCGplayer" affiliate link — right-aligned on the name line; the
   price (.cd-stat-px, flex-basis:100%) wraps below it. */
.cd-stat-buy{margin-left:auto;align-self:center;display:inline-flex;align-items:center;gap:5px;
  font-size:10px;font-weight:700;letter-spacing:0.2px;padding:4px 9px;border-radius:6px;
  border:1px solid var(--btn-border);background:var(--bg-solid);color:var(--text-dim);
  text-decoration:none;white-space:nowrap;transition:border-color 0.12s,color 0.12s,background 0.12s;}
.cd-stat-buy:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-glow);}
.cd-stat-buy svg{width:10px;height:10px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;display:block;}
/* flex-basis:100% wraps the price onto its own line deterministically. */
.cd-stat-px{flex-basis:100%;font-size:12px;color:var(--text-dim);font-variant-numeric:tabular-nums;margin-top:1px;}
.cd-stat-px b{color:var(--text);font-weight:700;}
.cd-stat-grid{display:grid;grid-template-columns:34px repeat(6,1fr);gap:2px 4px;align-items:center;}
.cd-stat-h{font-size:9px;color:var(--text-muted);text-align:center;font-weight:600;letter-spacing:0.3px;}
.cd-stat-metric{font-size:8px;color:var(--text-muted);font-weight:700;letter-spacing:0.4px;}
.cd-stat-v{font-size:11px;font-weight:700;text-align:center;font-variant-numeric:tabular-nums;
  overflow:hidden;white-space:nowrap;min-width:0;}
.card-detail-history-toolbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:10px;}
.card-detail-history-toolbar .seg-toggle button{padding:3px 9px;font-size:11px;}
@media(max-width:700px){
  .card-detail-history-section{padding:16px 20px 20px;}
}
/* History tab ------------------------------------------------------- */
.history-view{display:flex;flex-direction:column;gap:14px;}
.history-toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;}
.history-card-mode{display:grid;grid-template-columns:280px 1fr;gap:14px;}
@media (max-width:900px){
  /* Stack picker above chart so neither is squeezed below readable width. */
  .history-card-mode{grid-template-columns:1fr;gap:10px;}
  .history-picker{max-height:none;}
  .history-picker-list{max-height:300px;}
}
@media (max-width:640px){
  /* Toolbar buttons can wrap; "Filter since release" header etc. fit. */
  .history-toolbar{gap:6px;}
  .history-toolbar > *{flex:0 1 auto;min-width:0;}
  /* Range button group can wrap independently. */
  .panel-range-buttons{flex-wrap:wrap;}
  /* Compare picker bar (PNG/SVG/CSV/Clear) — let buttons wrap below summary
     so they don't overflow the right edge. */
  .compare-picker-bar{padding:6px 8px;}
  .compare-summary{flex-basis:100%;}
  .compare-export-group{flex-basis:100%;overflow-x:auto;
    -webkit-overflow-scrolling:touch;padding-bottom:2px;}
  .compare-export-group .settings-action{flex-shrink:0;}
  /* Compare stats table on mobile: stack each row as its own card with
     inline labels instead of a horizontal scroller. Users were seeing
     "EN..." (End column truncated) because iOS hides scrollbars by default
     and they had no idea the table was swipable. Card-stack layout shows
     every column with a clear label and never clips. */
  .compare-stats-table{display:block;width:100%;border-collapse:separate;}
  .compare-stats-table thead{display:none;}
  .compare-stats-table tbody, .compare-stats-table tr{display:block;}
  .compare-stats-table tr{
    background:var(--bg-card);border:1px solid var(--border);border-radius:8px;
    padding:8px 12px;margin-bottom:8px;display:grid;
    grid-template-columns:1fr auto;column-gap:10px;row-gap:4px;}
  .compare-stats-table td{display:block;padding:0;font-size:12px;border:none;
    line-height:1.35;white-space:normal;}
  /* Swatch swatch — hide its cell, the row already groups visually. */
  .compare-stats-table td:nth-child(1){display:none;}
  /* "#" index goes top-left small */
  .compare-stats-table td:nth-child(2){grid-column:1;grid-row:1;font-size:10px;
    color:var(--text-muted);font-weight:700;text-transform:uppercase;letter-spacing:0.4px;}
  /* Product name — top-right of the index, large */
  .compare-stats-table td:nth-child(3){grid-column:2;grid-row:1;font-size:13px;
    color:var(--text);text-align:right;overflow:hidden;text-overflow:ellipsis;
    white-space:nowrap;min-width:0;max-width:62vw;}
  /* Type/Set subtitle — span full width below the name */
  .compare-stats-table td:nth-child(4){grid-column:1 / -1;grid-row:2;font-size:11px;
    color:var(--text-muted);}
  /* Start / End / Change — full-width with inline label injected via ::before */
  .compare-stats-table td:nth-child(5),
  .compare-stats-table td:nth-child(6),
  .compare-stats-table td:nth-child(7){
    grid-column:1 / -1;display:flex;justify-content:space-between;align-items:baseline;
    font-variant-numeric:tabular-nums;font-weight:600;}
  .compare-stats-table td:nth-child(5){grid-row:3;}
  .compare-stats-table td:nth-child(6){grid-row:4;}
  .compare-stats-table td:nth-child(7){grid-row:5;}
  .compare-stats-table td:nth-child(5)::before{content:"Start";color:var(--text-muted);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:0.3px;}
  .compare-stats-table td:nth-child(6)::before{content:"End";color:var(--text-muted);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:0.3px;}
  .compare-stats-table td:nth-child(7)::before{content:"Change";color:var(--text-muted);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:0.3px;}
}
.history-picker{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:8px;display:flex;flex-direction:column;gap:6px;max-height:540px;}
.graded-picker-filters{display:flex;flex-direction:column;gap:4px;
  padding:6px 4px;border-bottom:1px solid var(--border);margin-bottom:2px;}
.graded-picker-filter-row{display:flex;flex-wrap:wrap;gap:3px;align-items:center;}
.graded-picker-filter-lbl{font-size:9px;font-weight:700;letter-spacing:0.4px;
  color:var(--text-muted);text-transform:uppercase;margin-right:4px;min-width:42px;}
.graded-picker-filters .chip{font-size:10px;padding:2px 7px;}
.graded-picker-filters .chip-clear{font-size:9px;background:rgba(220,38,38,0.08);
  color:var(--red);border-color:rgba(220,38,38,0.3);}
.history-picker input{padding:6px 10px;border:1px solid var(--btn-border);border-radius:5px;background:var(--bg-solid);color:var(--text);font-size:12px;font-family:'Nunito Sans',sans-serif;}
.history-picker input:focus{outline:none;border-color:var(--accent);}
.history-picker-searchrow{display:flex;gap:6px;align-items:stretch;}
.history-picker-searchrow input[type="search"]{flex:1;min-width:0;}
.history-picker-filters-btn{padding:6px 10px;border:1px solid var(--btn-border);
  background:var(--bg-solid);color:var(--text);border-radius:5px;cursor:pointer;
  font-size:11px;font-weight:600;font-family:'Nunito Sans',sans-serif;
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap;}
.history-picker-filters-btn:hover{border-color:var(--accent);color:var(--accent);}
.history-picker-filters-btn.active{background:var(--accent-glow);
  border-color:var(--border-accent);color:var(--accent);}
.history-picker-filters-btn .filter-count-badge{background:var(--accent);color:#fff;
  font-size:9px;font-weight:700;padding:1px 5px;border-radius:8px;
  font-variant-numeric:tabular-nums;}
.history-picker-list{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:2px;}
.history-picker-item{display:block;width:100%;text-align:left;padding:6px 10px;background:transparent;border:1px solid transparent;border-radius:5px;cursor:pointer;color:var(--text);font-family:'Nunito Sans',sans-serif;}
.history-picker-item:hover{background:var(--bg-surface-hover);}
.history-picker-item.active{background:var(--btn-active-bg);border-color:var(--btn-active-border);}
.history-picker-item .hpi-name{font-size:12px;font-weight:600;color:var(--text);line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.history-picker-item .hpi-sub{font-size:10px;color:var(--text-muted);line-height:1.4;margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.history-picker-item.active .hpi-name{color:var(--btn-active-text);}
.history-picker-group{margin-bottom:6px;}
.history-picker-group-head{position:sticky;top:0;background:var(--bg-solid);font-size:10px;text-transform:uppercase;letter-spacing:0.6px;color:var(--accent);font-weight:700;padding:5px 8px 3px;border-bottom:1px solid var(--border);z-index:2;box-shadow:0 1px 0 var(--border);}
/* Card preview block (right pane) */
.history-card-preview{display:flex;gap:14px;align-items:flex-start;padding-bottom:12px;margin-bottom:12px;border-bottom:1px solid var(--border);}
.history-preview-img{width:100px;height:auto;border-radius:6px;flex-shrink:0;box-shadow:0 2px 6px rgba(0,0,0,0.12);}
.history-preview-info{flex:1;min-width:0;}
.history-preview-name{font-family:'Cinzel',serif;font-size:16px;font-weight:600;color:var(--text);margin-bottom:4px;}
.history-preview-meta{font-size:12px;color:var(--text-dim);margin-bottom:2px;}
.history-preview-type{font-size:11px;color:var(--text-muted);}
.history-chart-controls{display:flex;align-items:center;gap:14px;margin-bottom:8px;flex-wrap:wrap;}
.checkbox-group{display:flex;align-items:center;gap:12px;font-size:12px;color:var(--text-dim);}
.checkbox-group label{display:inline-flex;align-items:center;gap:5px;cursor:pointer;}
.checkbox-group input[type=checkbox]{margin:0;}
.legend-line-style{display:inline-flex;align-items:center;gap:5px;font-size:11px;color:var(--text-muted);}
.line-solid{display:inline-block;width:14px;height:2px;background:currentColor;border-radius:1px;}
.line-dashed{display:inline-block;width:14px;height:0;border-top:2px dashed currentColor;}
.history-picker-empty{font-size:11px;color:var(--text-muted);padding:14px 6px;text-align:center;}
.history-chart-pane{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:14px;}

/* Multi-card compare mode — the chart + a legend strip of removable
   card chips above it. */
.compare-legend{display:flex;flex-wrap:wrap;gap:6px;align-items:center;
  padding:8px 10px;background:var(--bg-surface);border:1px solid var(--border);
  border-radius:8px;}
.compare-chip{display:inline-flex;align-items:center;gap:6px;
  padding:3px 4px 3px 8px;font-size:12px;font-weight:600;
  background:var(--bg-card);border:1px solid var(--border);border-radius:14px;
  color:var(--text);}
.compare-swatch{width:10px;height:10px;border-radius:50%;flex-shrink:0;}
.compare-name{max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.compare-remove{width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center;
  background:transparent;border:none;color:var(--text-muted);cursor:pointer;
  font-weight:700;font-size:14px;border-radius:50%;line-height:1;padding:0;}
.compare-remove:hover{background:var(--bg-surface);color:var(--red);}
/* "+ variants" pill on each compare chip — adds every other printing /
   rarity variant of that card to the graph. Sized smaller than the chip
   itself so it reads as a secondary action. Hidden once the graph hits
   COMPARE_MAX. */
.compare-add-variants{font-size:9px;font-weight:700;letter-spacing:0.3px;
  text-transform:uppercase;padding:2px 6px;border-radius:8px;line-height:1;
  background:var(--accent-glow);color:var(--accent);
  border:1px solid var(--border-accent);cursor:pointer;
  white-space:nowrap;margin-left:2px;}
.compare-add-variants:hover{background:var(--accent);color:#fff;
  border-color:var(--accent);}
.compare-kind-tag{display:inline-block;font-size:9px;font-weight:700;letter-spacing:0.4px;text-transform:uppercase;
  padding:1px 5px;border-radius:8px;background:var(--bg-surface);color:var(--text-muted);
  border:1px solid var(--border);margin-left:4px;vertical-align:middle;}
.compare-picker-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:8px 10px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;margin-bottom:10px;}
.compare-summary{flex:1;min-width:0;}
.history-picker-hint{font-size:11px;color:var(--text-muted);padding:6px 10px 0;line-height:1.4;}
.history-picker-item.picker-multi{display:flex;align-items:center;gap:8px;padding:6px 10px;}
.history-picker-item.picker-multi .picker-check{
  width:16px;height:16px;flex-shrink:0;border:1.5px solid var(--border);border-radius:3px;
  display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;
  color:transparent;background:var(--bg-card);transition:all 0.12s;line-height:1;}
.history-picker-item.picker-multi.active .picker-check,
.history-picker-item.picker-multi .picker-check.checked{
  background:var(--accent);border-color:var(--accent);color:#fff;}
.history-picker-item.picker-multi .picker-text{display:flex;flex-direction:column;gap:1px;min-width:0;text-align:left;flex:1;}
.history-picker-item.picker-multi:disabled{opacity:0.45;cursor:not-allowed;}
.compare-export-group{display:flex;gap:4px;flex-shrink:0;}
.compare-stats-table{width:100%;border-collapse:collapse;margin-top:14px;font-size:12px;}
.compare-stats-table th{font-size:10px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;
  color:var(--text-muted);text-align:left;padding:6px 10px;border-bottom:1px solid var(--border);}
.compare-stats-table td{padding:7px 10px;border-bottom:1px solid var(--border);color:var(--text);vertical-align:middle;}
.compare-stats-table td.muted{color:var(--text-muted);}
.compare-stats-table td.num,.compare-stats-table th.num{text-align:right;font-variant-numeric:tabular-nums;}
.compare-stats-table td.num.up{color:#1d8d4a;font-weight:700;}
.compare-stats-table td.num.down{color:#c64c5a;font-weight:700;}
@media(max-width:720px){
  .history-card-mode{grid-template-columns:1fr;}
  .history-picker{max-height:280px;}
}
/* Quantity counters (used in modal and elsewhere) ---------------------- */
.printing-wrap{display:flex;flex-direction:column;gap:6px;}
.qty-row{display:flex;align-items:center;gap:10px;padding:6px 12px;background:var(--bg-card);border:1px solid var(--border);border-radius:8px;}
.qty-label{font-size:11px;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-muted);font-weight:700;}
.qty-btn{width:26px;height:26px;border-radius:50%;border:1px solid var(--btn-border);background:var(--btn-bg);color:var(--text);font-size:16px;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0;cursor:pointer;line-height:1;}
.qty-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.qty-btn:disabled{opacity:0.3;cursor:not-allowed;}
.qty-display{min-width:24px;text-align:center;font-weight:700;font-size:15px;font-variant-numeric:tabular-nums;}
.signin-prompt{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 12px;background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;font-size:13px;color:var(--text-dim);margin-top:8px;}
/* Empty states -------------------------------------------------------- */
.empty-state{max-width:560px;margin:3rem auto;text-align:center;padding:2rem;}
.empty-state h2{margin:0 0 12px;color:var(--accent);font-size:20px;}
.empty-state p{font-size:14px;color:var(--text-dim);line-height:1.6;}
/* Collection view ----------------------------------------------------- */
.collection-controls{display:flex;align-items:center;gap:14px;margin-bottom:14px;flex-wrap:wrap;}

/* Cards / Sealed top-level toggle inside the Collection tab. */
.collection-section-tabs{display:flex;gap:4px;margin-bottom:18px;
  padding-bottom:10px;border-bottom:1px solid var(--border);}
.collection-section-tab{padding:6px 16px;font-size:13px;font-weight:600;
  background:transparent;color:var(--text-dim);
  border:1px solid transparent;border-radius:6px;cursor:pointer;
  transition:background 0.1s,color 0.1s,border-color 0.1s;}
.collection-section-tab:hover{color:var(--text);background:var(--bg-surface);}
.collection-section-tab.active{color:var(--accent);background:var(--accent-glow);
  border-color:var(--border-accent);}

/* Sealed collection: per-user inventory view. Reuses the .sealed-* row
   styles from SealedView, but extends the grid for the owned-value column
   and the +/- counter at the end. */
.sealed-coll{display:flex;flex-direction:column;gap:22px;}
.sealed-coll-empty{padding:40px 20px;text-align:center;color:var(--text-dim);
  display:flex;flex-direction:column;align-items:center;gap:14px;}
.sealed-coll-flag{display:flex;align-items:center;gap:6px;font-size:12px;
  color:var(--text-dim);cursor:pointer;}
.sealed-coll-counter{display:flex;align-items:center;gap:4px;
  background:var(--bg-surface);border-radius:6px;padding:3px;
  border:1px solid var(--border);justify-self:end;}
.sealed-coll-counter button{width:30px;height:26px;border:1px solid var(--border);
  background:var(--bg-card);color:var(--text-dim);font-size:14px;font-weight:700;
  cursor:pointer;border-radius:4px;padding:0;line-height:1;
  transition:border-color 0.1s,color 0.1s;}
.sealed-coll-counter button:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.sealed-coll-counter button:disabled{opacity:0.3;cursor:not-allowed;}
.sealed-coll-counter-qty{min-width:28px;text-align:center;font-weight:700;
  font-size:14px;font-variant-numeric:tabular-nums;color:var(--text-dim);}
.sealed-coll-counter-qty.has{color:var(--text);}

@media (max-width: 820px){
  .sealed-coll-counter{justify-self:start;}
}
.import-csv-btn{padding:6px 12px;font-size:12px;font-weight:600;cursor:pointer;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:5px;margin-left:auto;}
.import-csv-btn:hover{background:var(--bg-surface-hover);border-color:var(--accent);}
.import-modal-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.45);
  display:flex;align-items:center;justify-content:center;z-index:9000;padding:16px;}
.import-modal{background:var(--bg-solid);border:1px solid var(--border);border-radius:8px;
  padding:18px 20px;max-width:480px;width:100%;box-shadow:0 8px 28px rgba(0,0,0,0.3);
  color:var(--text);}
.import-modal .import-summary{font-size:13px;line-height:1.55;
  background:var(--bg-surface);border-radius:6px;padding:10px 12px;margin-bottom:14px;}
.import-modal .import-unmatched{margin-top:8px;color:var(--text-dim);font-size:12px;}
.import-modal .import-unmatched ul{margin:4px 0 0;padding-left:18px;}
.import-modal .import-unmatched li{margin:1px 0;}
.import-modal .import-mode{display:flex;flex-direction:column;gap:6px;margin-bottom:16px;font-size:13px;}
.import-modal .import-mode label{display:flex;gap:8px;align-items:flex-start;cursor:pointer;}
.import-modal .import-mode input{margin-top:3px;}
.import-modal .import-actions{display:flex;justify-content:flex-end;gap:8px;}
.import-modal .import-actions button{padding:7px 14px;font-size:13px;font-weight:600;
  cursor:pointer;background:var(--bg-surface);color:var(--text);
  border:1px solid var(--border);border-radius:5px;}
.import-modal .import-actions button.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.import-modal .import-actions button:disabled{opacity:0.55;cursor:default;}
.seg-toggle{display:flex;border:1px solid var(--btn-border);border-radius:18px;overflow:hidden;flex-shrink:0;}
.seg-toggle button{border:none;border-radius:0;padding:5px 14px;font-size:12px;background:var(--btn-bg);color:var(--btn-text);font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;}
.seg-toggle button.active{background:var(--accent);color:#fff;}
.seg-toggle button + button{border-left:1px solid var(--btn-border);}
/* Mobile: convert the segmented control into wrap-friendly chips so 7-button
   groups (Since Release / 1Y / 6M / 3M / 1M / 1W / Custom on Price Graphing,
   and the same set in the card-detail modal's history toolbar) don't get
   clipped by the overflow:hidden pill on narrow viewports.
   Each button becomes its own rounded chip; wrap flows to a second row when
   needed. 4-button rows (mode tabs) stay on one row visually.
   `flex-shrink:1; min-width:0; max-width:100%` overrides the base rule's
   `flex-shrink:0` — without these the seg-toggle keeps its natural width
   (sum of buttons) regardless of parent constraints, so when the buttons
   total wider than the modal/card-detail container they bleed past the
   right edge and get clipped by the modal's overflow:hidden. */
@media (max-width:640px){
  .seg-toggle{flex-wrap:wrap;border:none;border-radius:0;overflow:visible;
    gap:4px;flex-shrink:1;min-width:0;max-width:100%;}
  .seg-toggle button{border:1px solid var(--btn-border);border-radius:14px;
    padding:5px 11px;font-size:11px;}
  .seg-toggle button + button{border-left:1px solid var(--btn-border);}
}
.copies-select{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-dim);font-weight:500;}
.copies-select select{padding:3px 8px;font-size:12px;}
.collection-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin-bottom:18px;}
.stat-card{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:10px 14px;}
.stat-card-lbl{font-size:10px;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);font-weight:700;}
.stat-card-val{font-size:22px;font-weight:700;color:var(--text);margin-top:4px;font-variant-numeric:tabular-nums;line-height:1.1;}
.stat-card-val.green{color:var(--green);}
.stat-card-val.red{color:var(--red);}
.stat-card-sub{font-size:11px;color:var(--text-muted);margin-top:4px;}
.collection-sets{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px;}
@media (max-width:560px){.collection-sets{grid-template-columns:1fr;gap:8px;}}
.set-progress-card{background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;padding:12px 14px;}
.set-progress-name{font-family:'Cinzel',serif;font-size:14px;font-weight:600;color:var(--accent);margin-bottom:10px;}
.set-progress-row{display:grid;grid-template-columns:60px 1fr;column-gap:8px;row-gap:2px;align-items:center;margin-bottom:8px;}
.set-progress-row:last-child{margin-bottom:0;}
.set-progress-row-label{font-size:10px;text-transform:uppercase;letter-spacing:0.4px;color:var(--text-muted);font-weight:600;grid-row:1/3;}
.set-progress-row-counts{font-size:12px;color:var(--text);font-weight:600;text-align:right;font-variant-numeric:tabular-nums;}
.set-progress-pct{color:var(--text-muted);font-weight:500;margin-left:4px;}
.set-progress-row .progress-bar{grid-column:2;height:6px;}
.progress-fill.foil{background:linear-gradient(90deg,rgba(85,55,140,0.9),rgba(140,90,200,0.9));}
.set-progress-card{cursor:pointer;transition:border-color 0.12s,transform 0.08s;}
.set-progress-card:hover{border-color:var(--border-accent);}
.set-progress-card:active{transform:translateY(1px);}
.set-chase-row{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;padding-top:8px;border-top:1px dashed var(--border);}
.chase-pill{display:inline-flex;align-items:center;gap:5px;background:var(--bg-card);border:1px solid var(--border);border-radius:6px;padding:2px 7px;font-size:10px;}
.chase-pill-lbl{font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.4px;}
.chase-pill-val{color:var(--text);font-weight:600;font-variant-numeric:tabular-nums;}
/* Set detail (Collection drill-down) ---------------------------------- */
.setdet-header{display:flex;align-items:center;gap:14px;margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid var(--border);flex-wrap:wrap;}
.setdet-back{font-size:12px;}
.setdet-title{margin:0;font-size:18px;color:var(--accent);}
.setdet-count{font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.4px;margin-left:auto;}
.setdet-bulk-add{padding:6px 12px;font-size:12px;font-weight:600;
  background:var(--accent-glow);color:var(--accent);
  border:1px solid var(--border-accent);border-radius:6px;cursor:pointer;
  font-family:'Nunito Sans',sans-serif;}
.setdet-bulk-add:hover{background:var(--accent);color:#fff;}
/* Undo toast surfaced after a successful Bulk Add. Lives at the set-detail
   level so it persists after the modal closes; auto-dismisses after 30s. */
.setdet-undo-toast{position:fixed;bottom:calc(24px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);
  z-index:120;display:flex;align-items:center;gap:14px;padding:10px 14px;
  background:var(--bg-card);border:1px solid var(--border-accent);
  border-radius:8px;box-shadow:0 6px 18px rgba(0,0,0,0.25);
  font-size:13px;color:var(--text);max-width:90vw;}
.setdet-undo-toast strong{font-weight:700;color:var(--accent);font-variant-numeric:tabular-nums;}
.setdet-undo-btn{padding:6px 14px;font-size:12px;font-weight:700;
  background:var(--accent);color:#fff;border:none;border-radius:6px;cursor:pointer;
  font-family:'Nunito Sans',sans-serif;}
.setdet-undo-btn:hover:not(:disabled){filter:brightness(1.08);}
.setdet-undo-btn:disabled{opacity:0.6;cursor:not-allowed;}
.setdet-undo-close{width:22px;height:22px;background:transparent;border:none;
  color:var(--text-muted);cursor:pointer;font-size:16px;line-height:1;border-radius:4px;}
.setdet-undo-close:hover{color:var(--text);background:var(--bg-surface);}
.setdet-toolbar{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-bottom:10px;padding:6px 8px;background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;}
.setdet-search{flex:1;min-width:160px;padding:5px 9px;border:1px solid var(--btn-border);border-radius:5px;background:var(--bg-solid);color:var(--text);font-size:12px;font-family:'Nunito Sans',sans-serif;}
.setdet-search:focus{outline:none;border-color:var(--accent);}
.setdet-sort{padding:4px 8px;font-size:12px;border:1px solid var(--btn-border);border-radius:5px;background:var(--bg-solid);color:var(--text);margin-left:auto;}
.setdet-value-stats{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px;}
.setdet-stat{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;padding:10px 14px;}
.setdet-stat-lbl{font-size:10px;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);font-weight:700;}
.setdet-stat-val{font-size:22px;font-weight:700;color:var(--text);margin-top:4px;font-variant-numeric:tabular-nums;line-height:1.1;}
.setdet-stat-val.green{color:var(--green);}
.setdet-stat-val.red{color:var(--red);}
.setdet-stat-sub{font-size:11px;color:var(--text-muted);margin-top:4px;}
@media (max-width: 520px){
  .setdet-value-stats{grid-template-columns:1fr;}
}
.setdet-buy-missing{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px;padding:10px 14px;background:linear-gradient(90deg,rgba(22,101,52,0.95),rgba(40,140,80,0.95));color:#fff;border-radius:8px;text-decoration:none;font-size:13px;font-weight:600;box-shadow:0 2px 6px rgba(0,0,0,0.15);transition:transform 0.08s,box-shadow 0.08s;}
.setdet-buy-missing:hover{transform:translateY(-1px);box-shadow:0 4px 10px rgba(0,0,0,0.2);}
.setdet-buy-missing-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.setdet-buy-missing-price{font-size:15px;font-weight:700;font-variant-numeric:tabular-nums;display:inline-flex;align-items:baseline;gap:4px;flex-shrink:0;}
.setdet-buy-missing-cta{font-size:12px;font-weight:600;opacity:0.92;padding-left:9px;border-left:1px solid rgba(255,255,255,0.4);white-space:nowrap;}
.setdet-buy-missing-arrow{font-size:12px;opacity:0.85;margin-left:2px;}
/* On narrow screens the left "Shop N missing cards" text already conveys the
   action, so drop the redundant CTA label and keep the bar to $price + arrow. */
@media(max-width:560px){.setdet-buy-missing-cta{display:none;}}
.setdet-view-toggle{display:flex;border:1px solid var(--btn-border);border-radius:5px;overflow:hidden;}
.setdet-view-toggle button{padding:3px 9px;font-size:13px;border:none;border-radius:0;background:var(--btn-bg);color:var(--btn-text);}
.setdet-view-toggle button.active{background:var(--btn-active-bg);color:var(--btn-active-text);}
.setdet-view-toggle button + button{border-left:1px solid var(--btn-border);}

/* Inline counter — [−][N][+] one line, tight ------------------------- */
.inline-counter{display:inline-flex;align-items:center;background:rgba(0,0,0,0.06);border:1px solid rgba(0,0,0,0.08);border-radius:4px;height:22px;overflow:hidden;flex-shrink:0;}
html[data-mode="dark"] .inline-counter{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.1);}
.inline-counter.empty{visibility:hidden;width:56px;}
.inline-counter .ic-btn{width:18px;height:20px;border:none;background:transparent;color:var(--text-dim);font-size:13px;font-weight:700;padding:0;cursor:pointer;line-height:1;display:flex;align-items:center;justify-content:center;}
.inline-counter .ic-btn:hover:not(:disabled){background:rgba(0,0,0,0.06);color:var(--accent);}
html[data-mode="dark"] .inline-counter .ic-btn:hover:not(:disabled){background:rgba(255,255,255,0.08);}
.inline-counter .ic-btn:disabled{opacity:0.25;cursor:not-allowed;}
.inline-counter .ic-qty{min-width:16px;text-align:center;font-weight:600;font-size:11px;font-variant-numeric:tabular-nums;color:var(--text-dim);}
.inline-counter .ic-qty.has{color:var(--text);font-weight:700;}

/* Compact list mode — dense ink-tinted single-line rows -------------- */
/* CSS columns so rows flow TOP-TO-BOTTOM within a column, then start the
   next column — matches dreamborn's collection layout. Always 3 columns on
   wide viewports so each row has enough room for the full card name; steps
   down on narrower screens. break-inside:avoid keeps each row intact. */
.setdet-list-grid{column-count:3;column-gap:10px;}
.setdet-list-grid > *{break-inside:avoid;margin-bottom:3px;display:block;}
@media (max-width:1000px){.setdet-list-grid{column-count:2;}}
@media (max-width:700px){.setdet-list-grid{column-count:1;}}
/* All Cards: rows flow left-to-right (row-major) instead of down-then-across.
   Keeps the default sd-row internals (unlike --promo, which retweaks them). */
.setdet-list-grid--rowflow{column-count:initial;display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));gap:3px 10px;}
.setdet-list-grid--rowflow > *{break-inside:auto;margin-bottom:0;}
@media (max-width:1000px){.setdet-list-grid--rowflow{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (max-width:700px){.setdet-list-grid--rowflow{grid-template-columns:1fr;}}
/* Promo set override: regular grid (rows flow left-to-right) + tighter
   counters so long promo card names fit. Counter widths drop 72→48 to
   buy back ~48px for the name column. */
.setdet-list-grid--promo{column-count:initial;display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));gap:4px 10px;}
.setdet-list-grid--promo > *{break-inside:auto;margin-bottom:0;}
.setdet-list-grid--promo .sd-row{grid-template-columns:48px 48px 16px 14px 1fr auto;}
/* Promo solo mode wins over the global 170px counter — these cards have
   long names ("Mickey Mouse - True Friend") and need the room. */
.setdet-list-grid--promo .sd-row.sd-row-solo{grid-template-columns:88px 16px 14px 1fr auto;min-height:30px;}
.setdet-list-grid--promo .sd-row.sd-row-solo .inline-counter{height:24px;}
.setdet-list-grid--promo .sd-row.sd-row-solo .inline-counter .ic-btn{width:24px;height:24px;font-size:13px;}
.setdet-list-grid--promo .sd-row.sd-row-solo .inline-counter .ic-qty{font-size:12px;}
@media (max-width:1000px){.setdet-list-grid--promo{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media (max-width:700px){.setdet-list-grid--promo{grid-template-columns:1fr;}}
.sd-row{display:grid;grid-template-columns:56px 56px 28px 18px 1fr auto;column-gap:6px;align-items:center;padding:3px 6px;border:1px solid var(--border);border-radius:4px;cursor:pointer;transition:filter 0.1s;min-height:30px;position:relative;}
/* "✦N" graded-ownership count chip — how many slabs (or pending) you own of a
   card. Gold = real slab, muted = sent-for-grading. Read-only; sits by the
   raw counter so a graded-only card no longer reads as "0". */
.sd-graded-mark{display:inline-flex;align-items:center;margin-left:5px;font-size:10.5px;font-weight:700;line-height:1;cursor:help;vertical-align:middle;border-radius:999px;padding:2px 6px;letter-spacing:0.2px;}
.sd-graded-mark.graded{color:var(--accent);background:var(--accent-glow);border:1px solid var(--border-accent);}
.sd-graded-mark.pending{color:var(--text-muted);background:var(--bg-surface);border:1px solid var(--border);}
.sd-tile{position:relative;}
.sd-tile-counters{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
/* "Grade this card" button inside the card-detail modal (premium). */
.card-detail-grade-this{display:inline-flex;align-items:center;gap:6px;margin:4px 0 6px;padding:8px 14px;border:1px solid var(--accent);border-radius:8px;background:var(--accent-glow);color:var(--accent);font-weight:700;font-size:13px;cursor:pointer;}
.card-detail-grade-this:hover{background:var(--accent);color:#fff;}
/* "You also own N graded (PSA 10, …)" note in the card-detail modal. */
.card-detail-graded-note{margin:6px 0;padding:8px 12px;border-radius:8px;font-size:13px;line-height:1.4;background:var(--accent-glow);border:1px solid var(--border-accent);color:var(--text);display:flex;flex-direction:column;gap:5px;}
.card-detail-graded-note.pending{background:var(--bg-surface);border-color:var(--border);}
.card-detail-graded-note .muted{font-size:11.5px;}
.cd-graded-copies{display:flex;flex-wrap:wrap;gap:5px;}
.cd-graded-chip{font-size:12px;font-weight:700;border-radius:999px;padding:2px 9px;background:var(--bg-modal);border:1px solid var(--border-accent);color:var(--accent);}
.cd-graded-chip.pending{color:var(--text-muted);border-color:var(--border);font-weight:600;}
/* Grade-from-raw modal */
.gfr-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.55);display:flex;align-items:center;justify-content:center;z-index:200;padding:16px;}
.gfr-modal{position:relative;background:var(--bg-modal);border:1px solid var(--border);border-radius:12px;padding:18px;width:min(440px,100%);max-height:90vh;overflow:auto;box-shadow:0 12px 40px rgba(0,0,0,0.4);}
.gfr-close{position:absolute;top:8px;right:10px;background:none;border:none;font-size:22px;line-height:1;color:var(--text-muted);cursor:pointer;}
.gfr-head{display:flex;gap:12px;align-items:center;margin-bottom:14px;padding-right:24px;}
.gfr-thumb{width:46px;height:64px;object-fit:cover;border-radius:5px;flex-shrink:0;}
.gfr-title{font-weight:700;font-size:15px;}
.gfr-sub{font-size:12px;color:var(--text-muted);}
.gfr-seg{margin-bottom:12px;}
.gfr-field{display:flex;flex-direction:column;gap:5px;font-size:12px;color:var(--text-muted);margin-bottom:10px;flex:1;min-width:0;}
.gfr-field select,.gfr-field input{padding:7px 8px;border:1px solid var(--border);border-radius:6px;background:var(--bg);color:var(--text);font-size:13px;width:100%;box-sizing:border-box;}
.gfr-row{display:flex;gap:10px;}
.gfr-note{font-size:11.5px;color:var(--text-muted);line-height:1.4;margin:0 0 14px;}
.gfr-actions{display:flex;justify-content:flex-end;gap:8px;}
.gfr-actions button{padding:8px 14px;border:1px solid var(--border);border-radius:7px;background:var(--bg);color:var(--text);cursor:pointer;font-size:13px;}
.gfr-actions button.active{background:var(--accent);color:#fff;border-color:var(--accent);font-weight:600;}
.gfr-actions button:disabled{opacity:0.6;cursor:default;}
/* "Sent for grading" queue box (Graded tab right column). Compact, stacked
   rows: top line = thumb + name + stage + remove; second line = grade inputs. */
.gq-section{border:1px solid var(--border);border-radius:10px;background:var(--bg-card);margin-bottom:14px;overflow:hidden;}
.gq-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;border-bottom:1px solid var(--border);}
.gq-head-toggle{display:flex;align-items:center;gap:7px;background:none;border:none;cursor:pointer;color:var(--text);font-size:13px;font-weight:700;padding:0;}
.gq-caret{font-size:11px;color:var(--text-muted);}
.gq-title{letter-spacing:0.2px;}
.gq-count{background:var(--accent);color:#fff;border-radius:999px;font-size:11px;font-weight:700;padding:1px 8px;}
.gq-gradall{background:var(--bg);border:1px solid var(--accent);color:var(--accent);border-radius:7px;font-size:11px;font-weight:700;padding:4px 9px;cursor:pointer;}
.gq-gradall:hover{background:var(--accent);color:#fff;}
.gq-gradall:disabled{opacity:0.6;cursor:default;}
.gq-list{display:flex;flex-direction:column;}
.gq-row{display:flex;flex-direction:column;gap:6px;padding:8px 10px;border-bottom:1px solid var(--border);}
.gq-row:last-child{border-bottom:none;}
.gq-rowtop{display:flex;align-items:center;gap:8px;}
.gq-thumb{width:28px;height:40px;object-fit:cover;border-radius:4px;flex-shrink:0;}
.gq-rowmain{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.gq-name{font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.gq-status{align-self:flex-start;font-size:10px;font-weight:700;border-radius:999px;padding:2px 8px;cursor:pointer;border:1px solid var(--border);white-space:nowrap;}
.gq-status.to_submit{background:var(--bg-surface);color:var(--text-muted);}
.gq-status.at_grader{background:var(--accent-glow);color:var(--accent);border-color:var(--border-accent);}
.gq-rowgrade{display:flex;align-items:center;gap:6px;}
.gq-rowgrade select{flex:1;min-width:0;padding:5px 6px;border:1px solid var(--btn-border);border-radius:6px;background:var(--bg-solid);color:var(--text);font-size:12px;}
.gq-graduate{font-size:13px;font-weight:700;border:1px solid var(--accent);background:var(--bg);color:var(--accent);border-radius:7px;padding:5px 10px;cursor:pointer;flex-shrink:0;}
.gq-graduate:hover{background:var(--accent);color:#fff;}
.gq-remove{background:none;border:none;color:var(--text-muted);font-size:18px;line-height:1;cursor:pointer;padding:0 4px;flex-shrink:0;}
.gq-remove:hover{color:var(--red);}
/* "Grade from your collection" panel (Graded tab, premium) */
.gfc-modal{position:relative;background:var(--bg-modal);border:1px solid var(--border);border-radius:14px;padding:18px;width:min(820px,100%);max-height:88vh;overflow:auto;box-shadow:0 12px 40px rgba(0,0,0,0.4);}
.gfc-panel{padding-top:2px;}
.gfc-h2{margin:0 0 6px;font-size:18px;}
.gfc-intro{font-size:12.5px;color:var(--text-muted);line-height:1.45;margin-bottom:12px;}
.gfc-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px;}
.gfc-search{flex:1;min-width:140px;padding:8px 12px;border:1px solid var(--btn-border);border-radius:7px;background:var(--bg-solid);color:var(--text);font-size:13px;font-family:'Nunito Sans',sans-serif;}
.gfc-setsel{padding:8px 10px;border:1px solid var(--btn-border);border-radius:7px;background:var(--bg-solid);color:var(--text);font-size:13px;max-width:200px;}
.gfc-chase{white-space:nowrap;}
.gfc-raritychips{display:flex;flex-wrap:wrap;gap:3px;}
.gfc-selrow{display:flex;align-items:center;gap:14px;margin-bottom:10px;font-size:12px;color:var(--text-muted);}
.gfc-selall{display:flex;align-items:center;gap:6px;cursor:pointer;}
.gfc-clearsel{background:none;border:none;color:var(--accent);cursor:pointer;font-size:12px;}
.gfc-empty{padding:40px 12px;text-align:center;color:var(--text-muted);font-size:13px;}
.gfc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;}
.gfc-tile{position:relative;}
.gfc-tile-check{position:absolute;top:6px;left:6px;z-index:2;background:var(--bg-modal);border:1px solid var(--border);border-radius:5px;padding:2px 3px;display:flex;cursor:pointer;}
.gfc-tile-check input{cursor:pointer;margin:0;}
.gfc-tile-btn{width:100%;display:flex;flex-direction:column;gap:6px;padding:8px;border:1px solid var(--border);border-radius:9px;background:var(--bg-card);cursor:pointer;text-align:left;transition:border-color 0.1s,transform 0.06s;}
.gfc-tile-btn:hover{border-color:var(--accent);transform:translateY(-1px);}
.gfc-tile-sel .gfc-tile-btn{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent) inset;}
.gfc-tile-img{width:100%;aspect-ratio:5/7;object-fit:cover;border-radius:6px;background:var(--bg-surface);}
.gfc-noimg{display:block;}
.gfc-tile-name{font-size:12.5px;font-weight:600;line-height:1.25;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.gfc-tile-meta{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:3px;}
.gfc-tile-rar{width:15px;height:15px;object-fit:contain;}
.gfc-own-pill{font-size:10px;font-weight:600;background:var(--bg-surface);color:var(--text-muted);border-radius:999px;padding:1px 7px;}
.gfc-tile-cta{display:inline-block;align-self:flex-start;font-size:11px;font-weight:700;color:var(--accent);background:var(--accent-glow);border:1px solid var(--border-accent);border-radius:6px;padding:3px 8px;margin-top:2px;}
.gfc-tile-btn:hover .gfc-tile-cta{background:var(--accent);color:#fff;}
/* Bulk action bar — sticky at the bottom of the picker when cards are checked. */
.gfc-bulkbar{position:sticky;bottom:-18px;margin:12px -18px -18px;padding:12px 18px;background:var(--bg-modal);border-top:1px solid var(--border);display:flex;flex-wrap:wrap;align-items:center;gap:10px;box-shadow:0 -6px 16px rgba(0,0,0,0.18);}
.gfc-selcount{font-weight:700;font-size:13px;}
.gfc-bulkbar select{padding:7px 9px;border:1px solid var(--btn-border);border-radius:7px;background:var(--bg-solid);color:var(--text);font-size:13px;}
.gfc-bulkapply{padding:8px 16px;border:1px solid var(--accent);border-radius:8px;background:var(--accent);color:#fff;font-weight:700;font-size:13px;cursor:pointer;margin-left:auto;}
.gfc-bulkapply:disabled{opacity:0.6;cursor:default;}
.sd-row-rarity{width:16px;height:16px;object-fit:contain;display:block;flex-shrink:0;}
.sd-row-rarity-slot{display:inline-flex;align-items:center;justify-content:center;min-width:16px;}
.rarity-tag{display:inline-flex;align-items:center;gap:4px;line-height:1;}
.rarity-tag-icon{width:14px;height:14px;object-fit:contain;display:inline-block;flex-shrink:0;}
.rarity-tag-text{line-height:1;}
/* Rarity chip + Screener pill icon. Sized slightly bigger than rarity-tag
   since chips have more padding around them. */
.chip-with-icon{display:inline-flex;align-items:center;gap:5px;}
.chip-rarity-icon{width:18px;height:18px;object-fit:contain;display:inline-block;flex-shrink:0;}
.price-db-raritybtn-icon{display:inline-flex;align-items:center;gap:5px;}
/* Icon-only rarity chip — matches the cost-hex-chip footprint so the
   rarity strip slots cleanly next to the cost numbers in the toolbar. */
.chip-rarity-only{padding:4px 6px;display:inline-flex;align-items:center;justify-content:center;min-width:30px;}
.chip-rarity-only .chip-rarity-icon{width:20px;height:20px;}
.cards-quickfilter-group{display:flex;flex-wrap:wrap;align-items:center;gap:10px;}
/* Each sub-group (inks / costs / rarities / legality) stays together as a
   unit. Only the OUTER group wraps between sub-groups — so when space
   gets tight, you see all 6 inks together on one line, all 9 costs on
   the next, etc. Without nowrap inside, chips would scatter mid-group. */
.cards-quickfilter-sub{display:flex;flex-wrap:nowrap;align-items:center;gap:4px;
  padding-right:6px;border-right:1px solid var(--border);}
.cards-quickfilter-sub:last-child{border-right:none;padding-right:0;}
@media (max-width:520px){
  /* On very narrow phones, allow groups to wrap internally too so a single
     long group (9 costs) doesn't force horizontal scroll. */
  .cards-quickfilter-sub{flex-wrap:wrap;border-right:none;padding-right:0;}
}
/* When only one printing is visible (foilMode = non-foil OR foil), give the
   visible +/- counter both 72px slots so it fills the gap instead of
   leaving an awkward empty column. */
/* Solo mode (foilMode=Non-foil or Foil): the visible +/- counter expands
   to fill both 72px slots — wider hit area on desktop, ~44px buttons for
   easy mobile tapping. */
.sd-row.sd-row-solo{grid-template-columns:90px 28px 18px 1fr auto;min-height:32px;}
.sd-row.sd-row-solo .inline-counter{width:100%;height:24px;justify-content:space-between;}
.sd-row.sd-row-solo .inline-counter .ic-btn{width:26px;height:24px;font-size:13px;}
.sd-row.sd-row-solo .inline-counter .ic-qty{flex:1;font-size:12px;}
/* Same idea for the card grid tile when only one printing is visible: the
   lone counter already flex:1's into the row, just bump the buttons. */
.sd-tile-counters .inline-counter:only-child{height:34px;}
.sd-tile-counters .inline-counter:only-child .ic-btn{height:34px;font-size:17px;}
.sd-tile-counters .inline-counter:only-child .ic-qty{font-size:14px;}
/* Floating card image that follows the cursor on row hover. Portaled into
   body so it never clips against ancestor overflow. */
.sd-row-preview{position:fixed;z-index:9500;pointer-events:none;
  width:210px;border-radius:8px;overflow:hidden;
  box-shadow:0 8px 24px rgba(0,0,0,0.4);background:var(--bg-card);}
.sd-row-preview img{display:block;width:100%;height:auto;}
.setdet-origin-bucket{margin-bottom:18px;}
.setdet-origin-bucket:last-child{margin-bottom:0;}
.setdet-origin-header{font-family:'Cinzel',serif;font-size:13px;font-weight:600;
  color:var(--accent);letter-spacing:0.4px;margin:14px 0 8px;
  padding-bottom:4px;border-bottom:1px solid var(--border);}
.setdet-origin-header strong{color:var(--text);}
.setdet-origin-bucket:first-child .setdet-origin-header{margin-top:0;}
.sd-row-name-wrap{display:flex;flex-direction:column;min-width:0;}
.sd-row-subtitle{font-size:10px;color:var(--text-muted);font-style:italic;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sd-tile-name-wrap{display:flex;flex-direction:column;min-width:0;}
.sd-tile-subtitle{font-size:9px;color:var(--text-muted);font-style:italic;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sd-row:hover{filter:brightness(1.06);}
html[data-mode="dark"] .sd-row:hover{filter:brightness(1.2);}
.sd-row-num{font-size:11px;color:var(--text-muted);font-weight:600;font-variant-numeric:tabular-nums;text-align:right;}
.sd-row-name{font-size:12px;font-weight:600;color:var(--text);min-width:0;display:flex;align-items:center;gap:4px;}
.sd-row-name-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.sd-graded-mark{flex-shrink:0;}
.sd-row-prices{display:flex;gap:4px;align-items:center;flex-shrink:0;}
.sd-row-price{font-size:11px;font-weight:700;text-decoration:none;font-variant-numeric:tabular-nums;padding:2px 6px;border-radius:4px;}
.sd-row-price.normal{color:#0c6b34;background:rgba(22,101,52,0.14);}
.sd-row-price.normal:hover{background:rgba(22,101,52,0.26);}
.sd-row-price.foil{color:#5b3aa0;background:rgba(85,55,140,0.16);}
.sd-row-price.foil:hover{background:rgba(85,55,140,0.30);}
.sd-row-price.muted{color:var(--text-muted);background:transparent;}
/* Brighten the price text on every DARK theme — keyed on data-mode so it
   covers velvet/aurora/black/dark uniformly (a "dark"-only selector left the
   dark base color #0c6b34 on the velvet canvas — unreadable). */
html[data-mode="dark"] .sd-row-price.normal{color:#7fd9a5;}
html[data-mode="dark"] .sd-row-price.foil{color:#c0a3ef;}

/* Card grid mode ----------------------------------------------------- */
.setdet-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;}
.sd-tile{border:1px solid var(--border);border-radius:7px;padding:6px;display:flex;flex-direction:column;gap:5px;}
.sd-tile-img{width:100%;aspect-ratio:5/7;object-fit:cover;border-radius:5px;background:var(--bg-card);cursor:pointer;transition:transform 0.08s;}
.sd-tile-img:hover{transform:translateY(-1px);}
.sd-tile-img-placeholder{width:100%;aspect-ratio:5/7;border-radius:5px;background:var(--bg-card);display:flex;align-items:center;justify-content:center;color:var(--text-muted);font-size:10px;text-align:center;padding:6px;cursor:pointer;}
.sd-tile-info{display:grid;grid-template-columns:auto 1fr auto;column-gap:5px;align-items:baseline;min-width:0;cursor:pointer;}
.sd-tile-num{font-size:10px;color:var(--text-muted);font-weight:600;font-variant-numeric:tabular-nums;}
.sd-tile-name{font-size:11px;font-weight:600;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sd-tile-price{font-size:10px;color:var(--green);font-weight:700;font-variant-numeric:tabular-nums;}
.sd-tile-counters{display:flex;gap:4px;}
.sd-tile-counters .inline-counter{flex:1;justify-content:space-between;}
.sd-tile-counters .inline-counter .ic-btn,
.sd-tile-counters .inline-counter .ic-qty{flex:1;}

@media(max-width:640px){
  .setdet-list-grid{grid-template-columns:1fr;}
  .setdet-card-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr));}
  .setdet-search{flex-basis:100%;}
  .sd-row{grid-template-columns:64px 64px 24px 16px 1fr auto;column-gap:4px;}
}

/* ─── Decks tab ─── */
.deck-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px;}
/* Tiles are <a> elements (so Ctrl/Cmd+Click and right-click → "Open in new
   tab" work natively), but they need to render exactly like the old <div>
   tiles — kill the default link styling. */
.deck-card{background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;
  padding:12px 14px;cursor:pointer;transition:border-color 0.12s,transform 0.08s;
  display:block;text-decoration:none;color:inherit;min-width:0;overflow:hidden;}
.deck-card:hover{border-color:var(--border-accent);}
.deck-card:active{transform:translateY(1px);}
.deck-card:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
/* External decks (favorites + following feed) get a subtle accent strip so
   they read distinct from owned decks at a glance. */
.deck-card.external{border-left:3px solid var(--accent);padding-left:13px;}
.deck-card.external .deck-card-name{font-size:14px;}
/* Last-updated pill on every deck card. */
.deck-card-updated{font-size:10px;color:var(--text-muted);margin:4px 0 8px;
  font-variant-numeric:tabular-nums;}

/* Per-deck ink shields + inkable/uninkable count on the deck-list cards. */
.deck-card-chips{display:flex;align-items:center;gap:10px;margin:6px 0 4px;}
.deck-card-inks{display:inline-flex;gap:3px;}
.deck-card-inks img{width:16px;height:16px;object-fit:contain;display:block;}
.deck-card-inkable{display:inline-flex;align-items:center;gap:6px;}
.deck-ink-chip{display:inline-flex;align-items:center;gap:3px;
  font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;
  padding:2px 6px;border-radius:5px;
  background:var(--bg-surface);border:1px solid var(--border);cursor:default;color:var(--text);}
.deck-ink-chip svg{width:14px;height:14px;flex:0 0 auto;}

/* Favorite-count pill in the deck-editor toolbar. */
.deck-fav-count{font-size:11px;color:var(--accent);padding:3px 9px;
  border-radius:10px;background:var(--accent-glow);border:1px solid var(--border-accent);
  font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600;}

/* Decks tab sub-section strip (Your Decks / Favorites / Following). */
.deck-section-tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap;
  margin-bottom:18px;padding-bottom:10px;border-bottom:1px solid var(--border);}
.deck-section-tab{padding:6px 14px;font-size:13px;font-weight:600;
  background:transparent;color:var(--text-dim);
  border:1px solid transparent;border-radius:6px;cursor:pointer;
  display:inline-flex;align-items:center;gap:6px;
  transition:background 0.1s,color 0.1s,border-color 0.1s;}
.deck-section-tab:hover{color:var(--text);background:var(--bg-surface);}
.deck-section-tab.active{color:var(--accent);background:var(--accent-glow);
  border-color:var(--border-accent);}
.deck-section-tab-count{font-size:10px;font-weight:700;
  padding:1px 6px;border-radius:8px;background:var(--bg-surface);
  color:var(--text-muted);font-variant-numeric:tabular-nums;}
.deck-section-tab.active .deck-section-tab-count{background:var(--accent);color:#fff;}
.deck-section-explainer{font-size:12.5px;color:var(--text-muted);line-height:1.5;
  margin:0 0 14px;padding:10px 14px;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:8px;}
.deck-section-explainer strong{color:var(--text);font-weight:600;}
/* Tournaments tab — tile grid + per-tournament result rows. */
.tournament-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:10px;}
/* "View all decks" toolbar — the events↔all-decks toggle + format/event filters. */
.tournament-alldecks-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px;}
.tournament-alldecks-filters{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-left:auto;}
.tourney-format-seg button{font-size:12px;padding:5px 11px;}
/* Originating-event label on an all-decks tile (tiles span multiple events). */
.deck-card-event{font-size:11px;color:var(--text-muted);font-weight:600;margin:1px 0 4px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* Ink shields become buttons in the all-decks / detail tiles — strip the button
   chrome so they look identical to the plain <img> shields, just clickable. */
.deck-card-ink-btn{background:none;border:0;padding:0;margin:0;cursor:pointer;
  display:inline-flex;line-height:0;border-radius:3px;transition:transform 0.08s,filter 0.12s;}
.deck-card-ink-btn:hover{transform:translateY(-1px);filter:brightness(1.15);}
.deck-card-ink-btn:focus-visible{outline:2px solid var(--accent);outline-offset:1px;}
.tournament-card{padding:14px 16px;background:var(--bg-card);border:1px solid var(--border);
  border-radius:10px;cursor:pointer;text-align:left;font-family:'Nunito Sans',sans-serif;
  color:var(--text);transition:border-color 0.12s,box-shadow 0.12s,transform 0.12s;
  /* <a> tile: kill default link styling. Browser still handles Ctrl/Cmd+Click,
     middle-click, and right-click → "Open in new tab" on the underlying href. */
  display:block;text-decoration:none;}
.tournament-card:hover{border-color:var(--border-accent);box-shadow:0 4px 14px rgba(0,0,0,0.12);transform:translateY(-1px);}
.tournament-card-name{font-family:'Cinzel',serif;font-size:15px;font-weight:700;color:var(--accent);margin-bottom:4px;}
.tournament-card-meta{font-size:11px;}
/* Top-8 list inside each tournament card (replaces single-winner view). */
.tournament-card-top8{list-style:none;margin:8px 0 0;padding:8px 0 0;
  border-top:1px dashed var(--border);display:flex;flex-direction:column;gap:2px;}
.tc-top8-row{display:grid;grid-template-columns:32px 1fr auto;gap:6px;
  align-items:center;font-size:11.5px;padding:2px 0;line-height:1.25;}
.tc-top8-place{font-weight:800;color:var(--accent);font-size:10px;
  letter-spacing:0.3px;text-align:left;}
.tc-top8-player{font-weight:700;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.tc-top8-deck{color:var(--text-dim);font-weight:400;font-size:10.5px;
  margin-left:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tc-top8-row{grid-template-columns:28px 1fr auto;}
/* When deck name is present, give it room by collapsing player+deck into
   a single flexible cell. Implemented by spanning row 1's columns. */
.tc-top8-row:has(.tc-top8-deck){grid-template-columns:28px 1fr auto auto;}
.tc-top8-row:has(.tc-top8-deck) .tc-top8-player{grid-column:2;}
.tc-top8-row:has(.tc-top8-deck) .tc-top8-deck{grid-column:3;}
.tc-top8-row:has(.tc-top8-deck) .tc-top8-inks{grid-column:4;}
.tc-top8-inks{display:inline-flex;gap:1px;flex-shrink:0;}
.tc-top8-inks img{width:13px;height:13px;}
.tournament-card-more{font-size:10.5px;margin-top:6px;text-align:center;
  font-style:italic;}
/* Bulk-upload modal row — 4 inputs + a remove button. */
.tournament-upload-row{display:grid;grid-template-columns:90px 130px 160px 1fr 24px;
  gap:6px;align-items:start;}
.tournament-upload-row input, .tournament-upload-row textarea{
  padding:6px 9px;border:1px solid var(--btn-border);border-radius:5px;
  background:var(--bg-solid);color:var(--text);font-size:12px;font-family:'Nunito Sans',sans-serif;
  width:100%;}
.tournament-upload-row textarea{resize:vertical;min-height:62px;
  font-family:ui-monospace,SFMono-Regular,Consolas,monospace;}
@media (max-width:640px){
  /* Bulk-upload row: stack inputs 2/row, deck textarea full-width. */
  .tournament-upload-row{grid-template-columns:1fr 1fr 24px;
    grid-auto-flow:row dense;}
  .tournament-upload-row > *:nth-child(3){grid-column:1 / 3;}
  .tournament-upload-row > textarea{grid-column:1 / -1;}
}
.tournament-upload-remove{width:24px;height:24px;align-self:start;padding:0;font-size:14px;
  background:transparent;border:1px solid var(--border);border-radius:4px;cursor:pointer;
  color:var(--text-muted);line-height:1;}
.tournament-upload-remove:hover{color:var(--red);border-color:var(--red);}
/* Public-feed sub-tabs (Core / Infinity) inside the Discover section.
   Slightly lighter visual weight than the top-level deck-section-tabs
   so they read as a secondary control. */
.discover-format-tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap;
  margin:6px 0 14px;padding:4px;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:8px;}
.discover-format-tab{padding:5px 12px;font-size:12px;font-weight:600;
  background:transparent;color:var(--text-muted);border:none;
  border-radius:5px;cursor:pointer;transition:all 0.12s;
  display:inline-flex;align-items:center;gap:5px;}
.discover-format-tab:hover{color:var(--text);background:var(--bg-card);}
.discover-format-tab.active{color:var(--accent);background:var(--accent-glow);}
.discover-format-note{margin-left:auto;font-size:11px;padding:0 8px;
  line-height:1.4;text-align:right;}

/* Deck list filter / search / sort row, sits below the section-tab strip. */
.deck-filter-row{display:flex;gap:14px;align-items:center;flex-wrap:wrap;
  margin-bottom:14px;}
.deck-ink-filter{display:flex;align-items:center;gap:4px;flex-wrap:wrap;}
.deck-filter-clear{margin-left:6px;padding:4px 10px;font-size:11px;font-weight:600;
  background:transparent;color:var(--text-muted);
  border:1px solid var(--border);border-radius:14px;cursor:pointer;}
.deck-filter-clear:hover{color:var(--text);border-color:var(--border-accent);}
.deck-search-sort{margin-left:auto;display:flex;gap:6px;align-items:center;}
.deck-search-input{font-size:13px;padding:6px 10px;
  border:1px solid var(--border);background:var(--bg-card);color:var(--text);
  border-radius:6px;outline:none;min-width:200px;}
@media (max-width:640px){.deck-search-input{min-width:0;flex:1;}}
.deck-search-input:focus{border-color:var(--accent);}
.deck-sort-select{font-size:12px;padding:6px 8px;
  border:1px solid var(--border);background:var(--bg-card);color:var(--text);
  border-radius:6px;outline:none;cursor:pointer;}

/* Deck-card header row holding the name + visibility pill side-by-side. */
.deck-card-header{display:flex;align-items:flex-start;justify-content:space-between;
  gap:8px;margin-bottom:4px;}
.deck-card-header .deck-card-name{margin-bottom:0;}
.deck-card-vis{font-size:10px;font-weight:700;padding:2px 7px;border-radius:10px;
  white-space:nowrap;flex-shrink:0;display:inline-flex;align-items:center;gap:3px;
  letter-spacing:0.3px;}
.deck-card-vis.vis-public{background:rgba(22,101,52,0.14);color:var(--green);
  border:1px solid rgba(22,101,52,0.25);}
.deck-card-vis.vis-unlisted{background:rgba(196,128,30,0.14);color:#c4801e;
  border:1px solid rgba(196,128,30,0.30);}
.deck-card-vis.vis-private{background:var(--bg-surface);color:var(--text-dim);
  border:1px solid var(--border);}
html[data-mode="dark"] .deck-card-vis.vis-public{color:#7fd9a5;}
html[data-mode="dark"] .deck-card-vis.vis-unlisted{color:#e8b664;}

/* "Last updated …" pill in the deck-editor toolbar. */
.deck-updated{font-size:11px;color:var(--text-muted);padding:3px 9px;
  border-radius:10px;background:var(--bg-surface);border:1px solid var(--border);
  font-variant-numeric:tabular-nums;white-space:nowrap;}

/* Follow-creator chip in the read-only banner, alongside the "by ..." line. */
.deck-creator-follow{margin-left:8px;padding:2px 9px;font-size:11px;
  font-weight:600;background:transparent;color:var(--accent);
  border:1px solid var(--border-accent);border-radius:10px;cursor:pointer;
  transition:background 0.1s,color 0.1s,border-color 0.1s;}
.deck-creator-follow:hover{background:var(--accent-glow);}
.deck-creator-follow.on{background:var(--accent);color:#fff;border-color:var(--accent);}
.deck-creator-follow.large{padding:7px 18px;font-size:13px;border-radius:8px;}
.deck-readonly-by{display:inline-flex;align-items:center;flex-wrap:wrap;gap:4px;}
/* Clickable creator name in the read-only banner — opens their profile. */
.deck-creator-link{background:transparent;border:none;padding:0;cursor:pointer;
  font:inherit;color:var(--accent);font-weight:600;text-decoration:none;}
.deck-creator-link:hover{text-decoration:underline;}

/* Creator profile page (their public-deck list). */
.creator-profile-header{display:flex;align-items:center;gap:16px;
  padding:18px 20px;margin-bottom:20px;
  background:var(--bg-card);border:1px solid var(--border);border-radius:12px;}
.creator-profile-avatar{width:64px;height:64px;border-radius:50%;
  background:var(--bg-surface);object-fit:cover;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  font-weight:700;color:var(--accent);font-size:28px;}
.creator-profile-info{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1;}
.creator-profile-eyebrow{font-size:10px;font-weight:700;letter-spacing:1px;
  text-transform:uppercase;color:var(--text-muted);}
.creator-profile-name{font-family:'Cinzel',serif;font-size:22px;font-weight:600;
  color:var(--accent);margin:0;line-height:1.1;}
.creator-profile-meta{font-size:12px;color:var(--text-muted);}
.deck-card-name{font-family:'Cinzel',serif;font-size:15px;font-weight:600;color:var(--accent);margin-bottom:4px;}
.deck-card-meta{font-size:11px;color:var(--text-muted);margin-bottom:8px;}
.deck-card-actions{display:flex;gap:6px;flex-wrap:wrap;}
.deck-card-actions button{padding:3px 9px;font-size:11px;font-weight:600;
  background:var(--bg-surface-hover);color:var(--text);border:1px solid var(--border);
  border-radius:4px;cursor:pointer;}
.deck-card-actions button:hover{border-color:var(--accent);}
.deck-card-actions button.danger{color:var(--red);}
.deck-card-actions button.danger:hover{border-color:var(--red);background:rgba(153,27,27,0.08);}

/* Editor: card browser (left) + deck summary panel (right) */
.deck-editor-grid{display:grid;grid-template-columns:minmax(0,1fr) 460px;gap:16px;align-items:start;}
@media (max-width: 1100px){ .deck-editor-grid{grid-template-columns:1fr;} }
/* Mobile Cards/Deck tab toggle. Desktop hides it entirely; on phones the
   inactive panel is removed from layout so users see one full-width view
   at a time instead of scrolling past the whole CardBrowser to reach the
   deck summary below it. */
.deck-editor-mobile-tabs{display:none;}
@media (max-width: 700px){
  /* Deck/Cards toggle as a FIXED bottom bar on mobile (was sticky top:60px
     which got clipped by the two-row top-nav that's ~80-90px tall on
     phones, leaving the toggle perpetually half-hidden under the header
     and impossible to tap). Bottom-fixed keeps the toggle in the thumb
     zone and dodges the variable-height top-nav entirely.
     The bar uses `inset:auto 0 -1px 0` instead of `bottom:0` so it
     overshoots the viewport bottom by 1px. This is defensive against
     subpixel rounding on Android/iOS where the page background was
     visible through a hairline gap between the bar's CSS box and the
     actual screen edge — what the user described as a "sliver of the
     screen behind it". The 1px overshoot is invisible (it's off-screen)
     but guarantees the bar's background bleeds to the true viewport edge.
     padding-bottom doesn't include env(safe-area-inset-bottom) anymore;
     the buttons sit 8px above the bar's bottom edge regardless of device.
     On notched iPhones/Androids the buttons may render in the home-
     indicator zone but the bar's background still covers it cleanly. */
  .deck-editor-mobile-tabs{display:flex;gap:6px;
    position:fixed;left:0;right:0;bottom:-1px;z-index:40;
    margin:0;
    padding:8px max(12px, env(safe-area-inset-left))
            calc(9px + env(safe-area-inset-bottom))
            max(12px, env(safe-area-inset-right));
    background:var(--bg-solid);border-top:1px solid var(--border);
    box-shadow:0 -2px 8px rgba(0,0,0,0.08);}
  .deck-editor-mobile-tab{flex:1;padding:10px 14px;border:1px solid var(--btn-border);
    border-radius:18px;background:var(--btn-bg);color:var(--btn-text);font-weight:700;
    font-size:13px;letter-spacing:0.3px;cursor:pointer;min-height:36px;}
  .deck-editor-mobile-tab.active{background:var(--accent);color:#fff;border-color:var(--accent);}
  .deck-editor-grid.mobile-tab-deck .deck-editor-browser{display:none;}
  .deck-editor-grid.mobile-tab-cards .deck-editor-panel{display:none;}
  /* Read-only mode (viewing a deck, not editing): the second tab is
     "Deck Info" (the stats/charts panel), not "Cards" (the browser doesn't
     exist in this mode). Override the .mobile-tab-cards rule above so the
     panel SHOWS in cards tab when readonly, and hide the deck-view-list
     instead. Higher specificity (.readonly + tab class) wins. */
  .deck-editor-grid.readonly.mobile-tab-cards .deck-editor-panel{display:block;}
  .deck-editor-grid.readonly.mobile-tab-cards .deck-view-list{display:none;}
  .deck-editor-grid.readonly.mobile-tab-deck .deck-editor-panel{display:none;}
  /* Toolbar (Done / Share / Notes / Mulligan / Export / Import / Duplicate /
     Delete) is bulky on phones. When the user is on the Cards tab they're
     focused on adding cards from the browser, so collapse the toolbar to
     just Done and Delete (the two flagged with .deck-toolbar-keep). On the
     Deck tab and on desktop the full set stays visible. */
  .deck-editor-toolbar-actions.hide-on-cards-tab > *:not(.deck-toolbar-keep){
    display:none;}
  /* Reserve space at the bottom of the page so the fixed tab bar doesn't
     cover the last items of the deck content (or the footer that comes
     after the grid). Scoped via :has() so other pages don't gain phantom
     bottom padding. Bar height: 10 (pad) + 36 (button min-height) + 8
     (pad) = ~54px, plus the home-indicator inset. */
  body:has(.deck-editor-mobile-tabs){
    padding-bottom:calc(70px + env(safe-area-inset-bottom));}
}
/* Read-only mode collapses to single column — there's no CardBrowser. */
.deck-editor-grid.readonly{grid-template-columns:1fr;max-width:720px;}

/* ── Deck sharing ─────────────────────────────────────────────────────── */
.deck-readonly-banner{display:flex;align-items:center;gap:12px;
  padding:12px 16px;background:var(--accent-glow);
  border:1px solid var(--border-accent);border-radius:10px;
  margin-bottom:14px;}
.deck-readonly-avatar{width:36px;height:36px;border-radius:50%;
  background:var(--bg-surface);object-fit:cover;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  font-weight:700;color:var(--accent);}
.deck-readonly-avatar-fallback{font-size:16px;}
.deck-readonly-info{display:flex;flex-direction:column;gap:1px;min-width:0;}
.deck-readonly-sub{font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.deck-readonly-by{font-size:14px;font-weight:600;color:var(--text);}

/* Notes / video popover for the deck editor. Same chrome as the share
   popover but wider since the textarea needs room. */
.deck-notes-popover{position:absolute;top:calc(100% + 6px);right:0;z-index:200;
  width:380px;max-width:calc(100vw - 24px);background:var(--bg-modal);
  border:1px solid var(--border);border-radius:10px;
  box-shadow:0 8px 24px rgba(0,0,0,0.35);
  padding:12px;display:flex;flex-direction:column;gap:6px;}
.deck-text-modal{max-width:560px;}
.deck-text-area{width:100%;box-sizing:border-box;min-height:280px;max-height:60vh;
  font-family:'Courier New', monospace;font-size:13px;line-height:1.5;
  padding:10px 12px;background:var(--bg-surface);border:1px solid var(--border);
  border-radius:6px;color:var(--text);resize:vertical;}
.deck-text-area:focus{outline:none;border-color:var(--accent);}
.deck-notes-textarea{width:100%;min-width:0;font-size:13px;padding:8px 10px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:6px;
  color:var(--text);font-family:inherit;resize:vertical;line-height:1.4;}
.deck-notes-textarea:focus{border-color:var(--accent);outline:none;}

/* Notes + embed block rendered in view mode. Sits below the stats sidebar
   when present; collapsed when both description and youtube_url are blank. */
.deck-notes-block{margin-top:14px;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:10px;padding:14px;}
.deck-notes-title{font-family:'Cinzel',serif;font-size:12px;font-weight:600;
  color:var(--accent);margin-bottom:8px;padding-bottom:4px;
  border-bottom:1px solid var(--border);letter-spacing:0.3px;text-transform:uppercase;}
.deck-notes-text{font-size:13px;line-height:1.55;color:var(--text);
  white-space:pre-wrap;word-wrap:break-word;}
.deck-video-wrap{position:relative;width:100%;aspect-ratio:16/9;
  margin-top:10px;border-radius:8px;overflow:hidden;
  background:#000;border:1px solid var(--border);}
.deck-video-wrap iframe{position:absolute;inset:0;width:100%;height:100%;border:0;}

.deck-share-popover{position:absolute;top:calc(100% + 6px);right:0;z-index:200;
  width:320px;max-width:calc(100vw - 24px);background:var(--bg-modal);
  border:1px solid var(--border);border-radius:10px;
  box-shadow:0 8px 24px rgba(0,0,0,0.35);
  padding:12px;display:flex;flex-direction:column;gap:6px;}
@media (max-width:700px){
  /* Below tablet, anchor share + notes popovers to the viewport edges so
     they can't escape the screen on narrow widths. The button's position:
     relative ancestor would otherwise clip them under top-nav scroll. */
  .deck-share-popover,
  .deck-notes-popover{position:fixed;top:auto;right:12px;left:12px;
    /* Anchor to the bottom edge (above the iOS home indicator) instead of
       top:auto's unpredictable static-flow fallback — keeps the notes
       textarea reachable rather than landing under the on-screen keyboard. */
    bottom:calc(12px + env(safe-area-inset-bottom));
    width:auto;max-width:none;
    max-height:70vh;overflow-y:auto;}
}
.deck-share-section-title{font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);margin-top:4px;}
.deck-share-radio{display:flex;align-items:flex-start;gap:10px;
  padding:8px 10px;background:transparent;border:1px solid var(--border);
  border-radius:7px;cursor:pointer;transition:border-color 0.1s,background 0.1s;}
.deck-share-radio:hover{border-color:var(--border-accent);}
.deck-share-radio.active{background:var(--accent-glow);border-color:var(--border-accent);}
.deck-share-radio input{margin-top:3px;cursor:pointer;accent-color:var(--accent);}
.deck-share-radio-title{font-size:13px;font-weight:700;color:var(--text);line-height:1.2;}
.deck-share-radio.active .deck-share-radio-title{color:var(--accent);}
.deck-share-radio-sub{font-size:11px;color:var(--text-muted);line-height:1.35;margin-top:1px;}
.deck-share-divider{height:1px;background:var(--border);margin:6px 0;}
.deck-share-url-row{display:flex;gap:6px;}
.deck-share-url{flex:1;min-width:0;font-size:12px;padding:6px 8px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:5px;
  color:var(--text);font-family:'Courier New',monospace;}
.deck-share-copy{padding:6px 12px;font-size:12px;font-weight:600;cursor:pointer;
  background:var(--accent);color:#fff;border:none;border-radius:5px;}
.deck-share-copy.copied{background:var(--green);}
.deck-share-note{font-size:11px;color:var(--text-muted);line-height:1.4;
  padding:6px 8px;background:var(--bg-surface);border-radius:5px;}
.deck-share-regen-row{margin-top:8px;display:flex;flex-direction:column;}
.deck-share-regen-row .settings-action{align-self:flex-start;font-size:12px;color:var(--accent);}
.deck-search{flex:1;min-width:180px;padding:6px 10px;font-size:13px;
  background:var(--bg-surface);color:var(--text);border:1px solid var(--border);
  border-radius:5px;outline:none;}
.deck-search:focus{border-color:var(--accent);}
/* Right-side deck summary panel. On desktop it's a sidebar that pins as
   the main card-browser column scrolls (sticky + max-height + overflow:auto
   so its inner content scrolls when the deck is large). On mobile the grid
   collapses to a single column at ≤1100px, where sticky+max-height becomes
   a fixed-height scrollable box mid-page that clips the cost-curve / pie
   charts at the bottom even though the page itself has more room below.
   Drop all three properties on mobile so the panel flows naturally with
   the page and the charts render at full height. */
.deck-editor-panel{background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;
  padding:14px;position:sticky;top:8px;max-height:calc(100vh - 20px);overflow-y:auto;}
@media (max-width: 1100px){
  .deck-editor-panel{position:static;max-height:none;overflow-y:visible;}
}
.deck-stat-row{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:14px;
  padding-bottom:14px;border-bottom:1px solid var(--border);}
.deck-stat{background:var(--bg-card);border:1px solid var(--border);border-radius:6px;padding:8px 10px;}
.deck-stat-lbl{font-size:9px;text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);font-weight:700;}
.deck-stat-val{font-size:16px;font-weight:700;color:var(--text);margin-top:2px;font-variant-numeric:tabular-nums;line-height:1.1;}
.deck-stat-val.green{color:var(--green);}
.deck-stat-val.red{color:var(--red);}
.deck-stat-sub{font-size:10px;color:var(--text-muted);margin-top:2px;}
.deck-section{margin-bottom:12px;}
.deck-section-title{font-family:'Cinzel',serif;font-size:12px;font-weight:600;color:var(--accent);
  margin-bottom:6px;padding-bottom:3px;border-bottom:1px solid var(--border);
  letter-spacing:0.3px;text-transform:uppercase;}
.deck-section-title .muted{font-family:inherit;font-size:11px;font-weight:500;margin-left:4px;}
/* Compact deck list rows — 2-column flow when the panel is wide enough.
   Mirrors dreamborn's "one line per card" density. */
.deck-section-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));
  gap:4px 12px;}
.deck-row{display:grid;grid-template-columns:24px 28px minmax(0,1fr) auto auto;gap:5px;align-items:center;
  font-size:12px;padding:4px 6px;background:var(--bg-card);border:1px solid var(--border);
  border-radius:6px;min-width:0;}
.deck-row-costshield{display:inline-flex;align-items:center;justify-content:center;
  flex-shrink:0;color:#c8a846;}
.deck-row-costshield .cost-hex-shield-inkable{height:28px;width:auto;display:block;}
.deck-row-costshield .cost-hex-shield-uninkable{height:24px;width:24px;display:block;}
/* Cost numeral inside the shield — black on light theme, off-white on dark. */
.cost-shield-num{fill:#111;}
html[data-mode="dark"] .cost-shield-num{fill:#f4f1eb;}
.deck-row:hover{border-color:var(--border-accent);}
.deck-row-qty{color:var(--text);font-weight:700;text-align:right;font-variant-numeric:tabular-nums;}
.deck-row-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text);
  min-width:0;font-weight:500;display:flex;align-items:center;}
.deck-row-price{font-variant-numeric:tabular-nums;color:var(--green);font-weight:700;
  font-size:11px;padding:2px 5px;border-radius:5px;background:rgba(22,163,74,0.08);
  border:1px solid transparent;white-space:nowrap;}
.deck-row-counter{display:flex;gap:1px;}
.deck-row-counter button{width:16px;height:18px;border:1px solid var(--border);
  background:var(--bg-card);color:var(--text-dim);font-size:11px;font-weight:700;
  cursor:pointer;border-radius:3px;padding:0;line-height:1;}
.deck-row-counter button:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.deck-row-counter button:disabled{opacity:0.3;cursor:not-allowed;}
/* Mobile compaction: tighter cost-shield column + smaller gap/padding + a
   compact price chip leave enough room for the card name AND the inline
   ink shield to coexist. (An earlier pass hid the inline shield to claw
   back ~30px; turned out unnecessary once the cost shield + paddings
   were trimmed.) The row's tinted background still shows ink color too,
   so the inline shield is a "second visual confirmation" rather than the
   only signal. */
@media (max-width:700px){
  .deck-row{grid-template-columns:24px 26px minmax(0,1fr) auto auto;gap:5px;padding:4px 6px;}
  .deck-row-costshield .cost-hex-shield-inkable{height:24px;}
  .deck-row-costshield .cost-hex-shield-uninkable{height:22px;width:22px;}
  .deck-row-price{padding:2px 5px;font-size:10px;}
  .deck-row-counter button{width:20px;height:20px;}
}

/* Ink swatch shown next to a deck row's card name. Single circle for single-
   ink cards, half-and-half for dual-ink cards. Visual cue that this card
   contributes to one (or two) ink slices in the pie. Sized large enough
   that the dual gradient is clearly readable. */
.deck-row-ink{display:inline-block;width:14px;height:14px;border-radius:50%;
  flex-shrink:0;margin-right:6px;vertical-align:middle;
  border:1px solid rgba(0,0,0,0.35);box-sizing:border-box;}
html[data-mode="dark"] .deck-row-ink{border-color:rgba(255,255,255,0.25);}
/* Hard mid-line on dual swatches so the two colors read instantly. */
.deck-row-ink.dual{position:relative;overflow:hidden;}
.deck-row-ink.dual::after{content:"";position:absolute;top:0;bottom:0;left:50%;
  width:1px;background:rgba(0,0,0,0.4);}
html[data-mode="dark"] .deck-row-ink.dual::after{background:rgba(255,255,255,0.3);}

/* View mode: deck list on the left, stats/charts sidebar on the right
   (mirrors edit mode's CardBrowser-left + panel-right shape). */
.deck-editor-grid.readonly{grid-template-columns:minmax(0,1fr) 340px;max-width:none;}
@media (max-width: 1100px){ .deck-editor-grid.readonly{grid-template-columns:1fr;} }
.deck-view-list{min-width:0;}

/* Missing tile becomes a Shop CTA. */
.deck-stat.shop-cta{background:linear-gradient(180deg,#16a34a 0%,#15803d 100%);
  border-color:#15803d;color:#fff;text-decoration:none;display:flex;flex-direction:column;
  cursor:pointer;transition:transform 0.05s,box-shadow 0.1s;}
.deck-stat.shop-cta:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(21,128,61,0.25);}
.deck-stat.shop-cta .deck-stat-lbl,
.deck-stat.shop-cta .deck-stat-val,
.deck-stat.shop-cta .deck-stat-sub{color:#fff;}
.deck-stat.shop-cta .deck-stat-sub{opacity:0.85;text-decoration:underline;}

/* View dropdown trigger + popover. */
.deck-view-toolbar{display:flex;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap;}
.deck-view-trigger{padding:5px 12px;font-size:12px;font-weight:600;cursor:pointer;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:6px;
  color:var(--text);}
.deck-view-trigger:hover{border-color:var(--accent);}
.deck-view-popover{position:absolute;top:calc(100% + 6px);right:0;z-index:200;
  width:240px;background:var(--bg-modal);border:1px solid var(--border);
  border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,0.35);
  padding:12px;display:flex;flex-direction:column;gap:10px;}
.deck-view-section-title{font-size:10px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-muted);}
.deck-view-layout-row{display:flex;gap:6px;}
.deck-view-layout-row button{flex:1;padding:8px;font-size:14px;cursor:pointer;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:6px;color:var(--text);}
.deck-view-layout-row button.active{background:var(--accent-glow);border-color:var(--border-accent);color:var(--accent);}
.deck-view-select{padding:6px 8px;font-size:12px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:5px;color:var(--text);}

/* Variant picker — small ▾ chevron next to deck cards that have multiple
   versions (set reprints / promos / chase rarities sharing the same Product
   Name). The popover is rendered at editor-level with position:fixed so it
   sits above tiles with overflow:hidden. */
.deck-variant-btn{display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;padding:0;border:1px solid var(--btn-border);
  background:var(--bg-card);color:var(--text-dim);font-size:10px;line-height:1;
  border-radius:4px;cursor:pointer;flex-shrink:0;
  transition:border-color 0.12s,color 0.12s,background 0.12s;}
.deck-variant-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-glow);}
/* Inline row version — sits inside .deck-row-name after the name text. */
.deck-row-name-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  min-width:0;flex:1;}
.deck-variant-btn--row{margin-left:4px;}
/* Tile version — absolutely positioned UNDER the top-right qty badge so the
   ink-cost hex (top-left) stays unobscured. Sized to match the qty badge so
   they read as a vertically-stacked pair. */
.deck-variant-btn--tile{position:absolute;top:32px;right:5px;z-index:3;
  width:22px;height:22px;font-size:11px;
  background:rgba(0,0,0,0.78);border-color:rgba(255,255,255,0.25);color:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,0.35);}
.deck-variant-btn--tile:hover{background:rgba(0,0,0,0.9);border-color:var(--accent);color:var(--accent);}
.deck-stack-top .deck-variant-btn--tile{top:34px;right:7px;}
/* When HIGHLIGHT MISSING is on, the owned-frac badge takes the slot under
   the qty badge — nudge the chevron one row further down to clear it. */
.deck-grid-tile:has(.deck-tile-owned-frac) .deck-variant-btn--tile{top:57px;}
.deck-stack-tile:has(.deck-tile-owned-frac) .deck-variant-btn--tile{top:59px;}
/* Popover dropdown — fixed-positioned, anchored by JS to the clicked chevron. */
.deck-variant-popover{z-index:300;background:var(--bg-modal);border:1px solid var(--border);
  border-radius:10px;box-shadow:0 12px 28px rgba(0,0,0,0.35);
  padding:8px 8px 10px;max-height:min(360px,75vh);overflow:auto;}
.deck-variant-popover-head{font-family:'Cinzel',serif;font-size:11px;font-weight:600;
  letter-spacing:0.3px;color:var(--accent);margin:2px 4px 6px;}
.deck-variant-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px;}
.deck-variant-item{display:flex;width:100%;align-items:center;gap:8px;
  padding:5px 8px;background:none;border:1px solid transparent;border-radius:6px;
  cursor:pointer;color:var(--text);text-align:left;font-family:'Nunito Sans',sans-serif;
  transition:background 0.12s,border-color 0.12s;}
.deck-variant-item:hover:not(:disabled){background:var(--bg-card);border-color:var(--border);}
.deck-variant-item.current{cursor:default;background:var(--accent-glow);border-color:var(--border-accent);}
.deck-variant-item:disabled{cursor:default;}
.deck-variant-thumb{flex-shrink:0;width:34px;height:48px;object-fit:cover;border-radius:3px;
  display:block;background:var(--bg-surface);}
.deck-variant-thumb--placeholder{background:var(--bg-card);border:1px dashed var(--border);}
.deck-variant-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;}
.deck-variant-set{font-size:12px;font-weight:600;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.deck-variant-rarity{font-size:10px;color:var(--text-muted);text-transform:uppercase;
  letter-spacing:0.4px;font-weight:600;}
.deck-variant-check{flex-shrink:0;color:var(--accent);font-size:14px;font-weight:700;}

/* Undo Changes button in the deck-editor toolbar. Two-click confirm pattern:
   default style is muted/destructive-suggestive; once armed (first click) the
   button paints solid red so the second click is obviously the commit. */
.deck-toolbar-undo{color:var(--text-dim);}
.deck-toolbar-undo:hover{border-color:#dc2626;color:#dc2626;}
.deck-toolbar-undo.armed,
.deck-toolbar-undo.armed:hover{background:#dc2626;border-color:#dc2626;color:#fff;
  animation:undo-armed-pulse 1s ease-in-out infinite;}
@keyframes undo-armed-pulse{
  0%, 100%{box-shadow:0 0 0 0 rgba(220,38,38,0.45);}
  50%{box-shadow:0 0 0 4px rgba(220,38,38,0);}
}

/* Highlight-missing toggle pill. */
.deck-highlight-pill{display:inline-flex;align-items:center;gap:6px;
  padding:4px 10px;font-size:11px;font-weight:600;cursor:pointer;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:14px;
  color:var(--text-muted);user-select:none;}
.deck-highlight-pill.on{background:var(--accent-glow);border-color:var(--border-accent);color:var(--accent);}
.deck-highlight-pill .dot{width:8px;height:8px;border-radius:50%;background:currentColor;opacity:0.6;}
.deck-highlight-pill.on .dot{opacity:1;}

/* When HIGHLIGHT MISSING is on: rows you're missing copies of get FADED
   (opacity:0.45) so the owned cards visually pop. Class renamed from
   .owned-dim → .missing-fade 2026-05-26 when the logic flipped (used to
   fade owned cards and highlight missing with a red border; now it's the
   inverse — owned cards render normal, missing cards fade). The X/Y
   fraction badge in the top-right also paints red on missing. */
.deck-row.missing-fade{opacity:0.45;}

/* Per-card price chip becomes an affiliate link. */
a.deck-row-price{text-decoration:none;}
a.deck-row-price:hover{background:rgba(22,163,74,0.18);border-color:rgba(22,163,74,0.5);}

/* Ink shields rendered inline in deck rows (one for single, two for dual). */
.deck-row-ink-shields{display:inline-flex;align-items:center;gap:2px;flex-shrink:0;
  margin-right:8px;vertical-align:middle;}
.deck-row-ink-shield{width:24px;height:24px;display:block;object-fit:contain;}

/* Hover preview — full card image floats near cursor when hovering a list
   row. Portaled to body so overflow:hidden ancestors don't clip it. */
.deck-hover-preview{position:fixed;z-index:1000;pointer-events:none;
  width:200px;border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,0.35);
  border:1px solid var(--border);overflow:hidden;background:var(--bg-card);}
.deck-hover-preview img{width:100%;display:block;}

/* Image-grid layout for the card list. */
.deck-section-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:8px;}
.deck-grid-tile{position:relative;background:var(--bg-card);border:1px solid var(--border);
  border-radius:6px;overflow:hidden;display:flex;flex-direction:column;cursor:pointer;
  transition:transform 0.12s ease-out,box-shadow 0.12s ease-out;}
.deck-grid-tile:hover{transform:translateY(-3px) scale(1.02);
  box-shadow:0 8px 18px -4px rgba(0,0,0,0.25);border-color:var(--accent);}
.deck-grid-tile img{transition:transform 0.12s ease-out;}
.deck-grid-tile.missing-fade{opacity:0.4;}
.deck-grid-tile img{width:100%;aspect-ratio:5/7;object-fit:cover;display:block;}
.deck-grid-tile-qty{position:absolute;top:5px;right:5px;
  background:linear-gradient(180deg, #6d4dd6, #5a3fc4);
  color:#fff;font-size:11px;font-weight:700;padding:3px 8px;border-radius:5px;
  box-shadow:0 1px 3px rgba(0,0,0,0.35);letter-spacing:0.3px;z-index:2;}
.deck-grid-tile-price{position:absolute;bottom:4px;right:4px;background:rgba(22,163,74,0.92);
  color:#fff;font-size:10px;font-weight:700;padding:2px 5px;border-radius:3px;
  text-decoration:none;}
.deck-grid-tile-price:hover{background:rgba(22,163,74,1);}
/* Owned/missing fraction (e.g. "1/4") shown when Highlight missing is on.
   Positioned just under the top-right quantity badge so it doesn't cover
   the ink cost hex (top-left) — the cost is more visually important and
   was getting hidden by the badge when it lived top-left. */
.deck-tile-owned-frac{position:absolute;top:30px;right:5px;
  background:rgba(0,0,0,0.75);color:#fff;font-size:10px;font-weight:700;
  padding:2px 6px;border-radius:4px;letter-spacing:0.3px;z-index:2;}
.deck-tile-owned-frac.complete{background:rgba(22,163,74,0.92);}
.deck-tile-owned-frac.incomplete{background:rgba(220,38,38,0.92);}

/* +/- counter overlaid on grid + stacked deck-list tiles. Bottom-left so
   it doesn't collide with the price chip in the bottom-right. */
.deck-grid-tile-counter,
.deck-stack-counter{position:absolute;bottom:5px;left:5px;z-index:3;
  display:flex;gap:2px;background:rgba(0,0,0,0.78);border-radius:5px;
  padding:2px;box-shadow:0 1px 3px rgba(0,0,0,0.3);}
.deck-grid-tile-counter button,
.deck-stack-counter button{width:20px;height:20px;border:none;background:transparent;
  color:#fff;font-size:13px;font-weight:700;cursor:pointer;border-radius:3px;
  padding:0;line-height:1;display:inline-flex;align-items:center;justify-content:center;}
.deck-grid-tile-counter button:hover:not(:disabled),
.deck-stack-counter button:hover:not(:disabled){background:rgba(255,255,255,0.15);}
.deck-grid-tile-counter button:disabled,
.deck-stack-counter button:disabled{opacity:0.35;cursor:not-allowed;}

/* Stacked-pile layout — each qty renders as a peek-strip above the top card.
   Sized so each peek shows the upper card frame (cost circle + title bar)
   instead of a thin meaningless strip. Strong drop shadows separate the
   layers so the eye reads "physical card stack" not "stacked JPEGs". */
.deck-section-stack{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:22px;}
.deck-stack-tile{position:relative;display:flex;flex-direction:column;cursor:pointer;
  transition:transform 0.12s ease-out;}
.deck-stack-tile:hover{transform:translateY(-4px);}
.deck-stack-tile.missing-fade{opacity:0.4;}
.deck-stack-peek{position:relative;width:96%;margin:0 auto -3px;height:22px;overflow:hidden;
  border-radius:8px 8px 0 0;
  border:1px solid rgba(0,0,0,0.32);border-bottom:none;
  background:var(--bg-card);
  box-shadow:0 4px 6px -3px rgba(0,0,0,0.4),inset 0 -2px 3px -2px rgba(0,0,0,0.25);}
html[data-mode="dark"] .deck-stack-peek{border-color:rgba(255,255,255,0.14);}
.deck-stack-peek img{width:100%;height:auto;display:block;}
/* Stagger each successive peek slightly wider so the stack reads as nested
   cards getting larger toward the front. */
.deck-stack-peek:nth-last-child(2){width:97%;}
.deck-stack-peek:nth-last-child(3){width:98%;}
.deck-stack-peek:nth-last-child(4){width:99%;}
/* Top highlight along each peek's upper edge — sells the "real card" look. */
.deck-stack-peek::after{content:"";position:absolute;inset:0 0 auto 0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,0.45),transparent);
  pointer-events:none;}
.deck-stack-top{position:relative;border:1px solid rgba(0,0,0,0.32);border-radius:10px;
  overflow:hidden;background:var(--bg-card);
  box-shadow:0 8px 18px -4px rgba(0,0,0,0.4),0 3px 6px -2px rgba(0,0,0,0.2);
  transition:box-shadow 0.12s ease-out;}
html[data-mode="dark"] .deck-stack-top{border-color:rgba(255,255,255,0.18);
  box-shadow:0 8px 18px -4px rgba(0,0,0,0.7),0 3px 6px -2px rgba(0,0,0,0.45);}
.deck-stack-tile:hover .deck-stack-top{box-shadow:0 12px 26px -4px rgba(0,0,0,0.5),0 4px 8px -2px rgba(0,0,0,0.25);}
.deck-stack-top img{width:100%;aspect-ratio:5/7;object-fit:cover;display:block;}
.deck-stack-qty{position:absolute;top:7px;right:7px;
  background:linear-gradient(180deg, #6d4dd6, #5a3fc4);
  color:#fff;font-size:12px;font-weight:700;padding:3px 9px;border-radius:5px;z-index:2;
  box-shadow:0 1px 3px rgba(0,0,0,0.4);letter-spacing:0.3px;}
.deck-stack-price{position:absolute;bottom:7px;right:7px;
  background:linear-gradient(180deg,#16a34a,#15803d);
  color:#fff;font-size:11px;font-weight:700;padding:3px 8px;border-radius:5px;
  text-decoration:none;z-index:2;box-shadow:0 1px 3px rgba(0,0,0,0.3);
  transition:transform 0.08s,box-shadow 0.1s;}
.deck-stack-price:hover{transform:translateY(-1px);box-shadow:0 3px 8px rgba(21,128,61,0.4);}

/* Charts inside the right-side view-mode panel: keep the SVG to the panel
   width so it doesn't stretch and pixelate. */
.deck-editor-grid.readonly .deck-charts svg{max-width:100%;height:auto;}

/* View toggle in the CardBrowser toolbar — image grid vs compact list. */
.card-view-toggle{display:inline-flex;border:1px solid var(--border);border-radius:6px;overflow:hidden;}
.card-view-toggle button{background:transparent;color:var(--text-muted);border:none;
  padding:5px 10px;font-size:14px;cursor:pointer;line-height:1;}
.card-view-toggle button:hover{color:var(--text);background:var(--bg-surface-hover);}
.card-view-toggle button.active{background:var(--accent);color:#fff;}

/* Compact list view of cards (alternate to .cards-grid). Auto-fills to
   2-3 columns on wide screens — same 340px tile width as the collection's
   set-detail list so the two list views feel consistent. */
.cards-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:4px;}
@media (max-width: 720px){ .cards-list{grid-template-columns:1fr;} }
.card-row{display:grid;grid-template-columns:36px 1fr auto auto auto auto;column-gap:10px;
  align-items:center;padding:5px 8px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:6px;cursor:pointer;
  transition:border-color 0.1s,background 0.1s;
  content-visibility:auto;contain-intrinsic-size:340px 62px;}
.card-row:hover{border-color:var(--border-accent);background:var(--bg-surface);}
.card-row-img{width:36px;height:50px;object-fit:cover;border-radius:3px;display:block;
  background:var(--bg-surface);}
.card-row-img-placeholder{background:var(--bg-surface);}
.card-row-main{min-width:0;display:flex;flex-direction:column;gap:1px;}
.card-row-name{font-size:13px;font-weight:600;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.card-row-meta{font-size:10px;color:var(--text-muted);display:flex;gap:6px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.card-row-meta .card-row-set{font-style:italic;}
.card-row-prices{display:flex;gap:4px;flex-shrink:0;}
.card-row-price{font-size:11px;font-weight:700;padding:3px 8px;border-radius:4px;
  text-decoration:none;font-variant-numeric:tabular-nums;}
.card-row-price.normal{color:#0c6b34;background:rgba(22,101,52,0.14);}
.card-row-price.normal:hover{background:rgba(22,101,52,0.26);}
.card-row-price.foil{color:#5b3aa0;background:rgba(85,55,140,0.16);}
.card-row-price.foil:hover{background:rgba(85,55,140,0.30);}
html[data-mode="dark"] .card-row-price.normal{color:#7fd9a5;}
html[data-mode="dark"] .card-row-price.foil{color:#c0a3ef;}
.card-row-owned{display:flex;gap:3px;font-size:10px;font-weight:700;}
.card-row-owned .owned-n{background:rgba(22,101,52,0.92);color:#fff;padding:2px 5px;border-radius:3px;}
.card-row-owned .owned-f{background:rgba(85,55,140,0.92);color:#fff;padding:2px 5px;border-radius:3px;}
.card-row-counter{display:flex;align-items:center;gap:2px;
  background:var(--bg-surface);border-radius:4px;padding:2px;}
.card-row-counter button{width:28px;height:24px;border:1px solid var(--border);
  background:var(--bg-card);color:var(--text-dim);font-size:13px;font-weight:700;
  cursor:pointer;border-radius:3px;padding:0;line-height:1;}
.card-row-counter button:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.card-row-counter button:disabled{opacity:0.3;cursor:not-allowed;}
/* Compact deck-builder row: no image, just ink + cost + name + counter.
   Mirrors the real deck list (deck-row): official ink-shield PNG(s) + the
   inkable/uninkable cost shield instead of a bare color dot + plain hex. */
.card-row-compact{grid-template-columns:42px 32px 1fr auto;column-gap:6px;padding:4px 8px;}
.card-row-ink-shields{display:inline-flex;align-items:center;justify-content:center;
  gap:2px;flex-shrink:0;}
.card-row-ink-shield{width:18px;height:18px;display:block;object-fit:contain;}
.card-row-costshield{display:inline-flex;align-items:center;justify-content:center;
  flex-shrink:0;color:#c8a846;}
.card-row-costshield .cost-hex-shield-inkable{height:26px;width:auto;display:block;}
.card-row-costshield .cost-hex-shield-uninkable{height:24px;width:24px;display:block;}
.card-row-name-btn{appearance:none;background:transparent;border:none;padding:0;margin:0;
  font-family:inherit;font-size:13px;font-weight:600;color:var(--text);text-align:left;
  cursor:pointer;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.card-row-name-btn:hover{color:var(--accent);text-decoration:underline;}
@media (max-width:640px){
  .card-row-compact{grid-template-columns:40px 30px 1fr auto;column-gap:6px;padding:3px 6px;}
  .card-row-counter button{width:32px;height:30px;}
  .card-row-ink-shield{width:17px;height:17px;}
  .card-row-costshield .cost-hex-shield-inkable{height:24px;}
  .card-row-costshield .cost-hex-shield-uninkable{height:22px;width:22px;}
}

/* Expand button shown only in deck mode: opens the detail modal so the tile
   body itself can become a one-tap "add to deck" target. */
.tile-expand-btn{position:absolute;bottom:6px;left:6px;width:30px;height:30px;
  display:inline-flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,0.55);color:#fff;border:none;border-radius:6px;
  font-size:18px;line-height:1;cursor:pointer;padding:0;
  box-shadow:0 2px 6px rgba(0,0,0,0.25);opacity:0.82;
  transition:opacity 0.12s,background 0.12s;z-index:2;}
.tile-expand-btn:hover{opacity:1;background:rgba(0,0,0,0.78);}
/* Magnify button — browse mode only. Hidden by default, fades in when the
   tile is hovered (or any descendant is focused, for keyboard nav). Inline
   SVG glyph matches the site's other Lucide-style line icons. On touch
   devices we still surface the button because hover doesn't reliably fire:
   the @media (hover:none) rule below pins opacity to 1. */
.tile-magnify-btn{position:absolute;bottom:5px;left:5px;width:22px;height:22px;
  display:inline-flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,0.6);color:#fff;border:none;border-radius:5px;
  line-height:1;cursor:pointer;padding:0;
  box-shadow:0 1px 4px rgba(0,0,0,0.3);
  opacity:0;pointer-events:none;
  transition:opacity 0.12s,background 0.12s;z-index:2;}
.tile-magnify-btn svg{display:block;}
.card-tile:hover .tile-magnify-btn,
.card-tile:focus-within .tile-magnify-btn{opacity:0.9;pointer-events:auto;}
.tile-magnify-btn:hover{opacity:1 !important;background:rgba(0,0,0,0.82);}
@media (hover:none){
  .tile-magnify-btn{opacity:0.82;pointer-events:auto;}
}
/* When the deck-mode expand button is also present, lift the magnifier above
   it so both icons are tappable. */
.card-tile:has(.tile-expand-btn) .tile-magnify-btn{bottom:42px;}

/* Visual cue while the deferred filter render is catching up — the grid
   gets a faint fade so the click feels acknowledged even if the heavy
   reconciliation hasn't landed yet. Pointer-events stay enabled. */
.cards-pending{opacity:0.78;transition:opacity 0.08s;}

/* Deck-mode +/- counter overlay on the shared CardTile */
.deck-tile-counter{display:flex;align-items:center;gap:2px;
  background:var(--bg-surface);border-top:1px solid var(--border);
  padding:3px;border-radius:0 0 6px 6px;margin-top:4px;}
.deck-tile-counter button{flex:0 0 32px;height:26px;border:1px solid var(--border);
  background:var(--bg-card);color:var(--text-dim);font-size:14px;font-weight:700;
  cursor:pointer;border-radius:4px;padding:0;line-height:1;}
.deck-tile-counter button:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.deck-tile-counter button:disabled{opacity:0.3;cursor:not-allowed;}
.deck-tile-qty{flex:1;text-align:center;font-weight:600;font-size:13px;
  color:var(--text-dim);font-variant-numeric:tabular-nums;}
.deck-tile-qty.has{color:var(--text);}

/* Click-to-edit deck title */
.deck-name-display{margin:0;font-size:18px;color:var(--accent);cursor:text;
  padding:2px 6px;border-radius:4px;border:1px solid transparent;}
.deck-name-display:hover{border-color:var(--border);background:var(--bg-surface);}
.deck-name-input{font-family:'Cinzel',serif;font-size:18px;font-weight:600;
  color:var(--accent);background:var(--bg-surface);
  border:1px solid var(--accent);border-radius:4px;padding:2px 6px;
  outline:none;min-width:200px;}

/* Legality badge + issue list */
.deck-legal-badge{font-size:11px;font-weight:600;padding:3px 8px;border-radius:10px;
  letter-spacing:0.3px;border:1px solid transparent;}
/* Auto-detected format badge — green for Core (strictest), gold for Infinity
   (still legal but not Core), red for Invalid (structural violations). */
.deck-legal-badge.core{background:rgba(22,101,52,0.14);color:var(--green);border-color:rgba(22,101,52,0.25);}
.deck-legal-badge.infinity{background:var(--accent-glow);color:var(--accent);border-color:var(--border-accent);}
.deck-legal-badge.invalid{background:rgba(153,27,27,0.12);color:var(--red);border-color:rgba(153,27,27,0.25);}

/* Bottom-right toast for one-shot action confirmations (e.g. duplicate). */
.deck-toast{position:fixed;bottom:calc(24px + env(safe-area-inset-bottom));right:24px;z-index:9700;
  background:#1a1a1a;color:#f4f1eb;font-size:13px;font-weight:500;
  padding:10px 16px;border-radius:8px;
  box-shadow:0 6px 20px rgba(0,0,0,0.35);
  animation:deck-toast-in 0.18s ease-out;
  max-width:min(360px, calc(100vw - 48px));}
@keyframes deck-toast-in{
  from{opacity:0;transform:translateY(8px);}
  to{opacity:1;transform:translateY(0);}
}

/* "Saved ✓" / "Saving…" indicator. */
.deck-save-status{font-size:11px;font-weight:600;padding:3px 8px;border-radius:10px;
  letter-spacing:0.3px;border:1px solid transparent;}
.deck-save-status.saved{color:var(--text-muted);background:transparent;}
.deck-save-status.saving{color:var(--accent);background:var(--accent-glow);}
.deck-legal-issues{background:rgba(153,27,27,0.06);border:1px solid rgba(153,27,27,0.2);
  border-radius:6px;padding:8px 12px;font-size:12px;color:var(--red);margin-bottom:12px;}
.deck-legal-issues div{margin:2px 0;}

/* Charts: cost curve + pie row in the side panel */
.deck-charts{margin-bottom:14px;padding-bottom:14px;border-bottom:1px solid var(--border);}
.deck-chart{margin-bottom:10px;}
.deck-chart-title{font-size:10px;font-weight:600;color:var(--text-muted);
  letter-spacing:0.5px;text-transform:uppercase;margin-bottom:4px;
  display:flex;align-items:baseline;gap:8px;}
/* Inline card/unique count on the Cost curve header line. Mixed-case, pushed
   to the right edge, never uppercased like the section label. */
.deck-chart-count{margin-left:auto;text-transform:none;letter-spacing:0;
  font-weight:700;color:var(--text-dim);font-variant-numeric:tabular-nums;white-space:nowrap;}
.deck-chart svg{display:block;background:var(--bg-card);border-radius:5px;}
.deck-pie-row{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;}
.deck-pie{background:var(--bg-card);border-radius:5px;padding:6px;
  display:flex;flex-direction:column;align-items:center;gap:4px;min-width:0;}
.deck-pie-title{font-size:10px;font-weight:600;color:var(--text-muted);
  letter-spacing:0.4px;text-transform:uppercase;align-self:stretch;text-align:center;}
.deck-pie-empty{font-size:11px;color:var(--text-muted);padding:20px 0;}
.deck-pie-legend{display:flex;flex-direction:column;gap:1px;width:100%;font-size:9px;}
.deck-pie-legend-row{display:grid;grid-template-columns:8px 1fr auto;gap:4px;align-items:center;min-width:0;}
.deck-pie-swatch{width:8px;height:8px;border-radius:2px;display:inline-block;}
.deck-pie-swatch.dual{width:10px;height:10px;border:1px solid rgba(0,0,0,0.55);box-sizing:border-box;}
html[data-mode="dark"] .deck-pie-swatch.dual{border-color:rgba(255,255,255,0.35);}
.deck-pie-legend-name .dual-tag{flex-shrink:0;font-size:8px;font-weight:700;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--accent);background:var(--accent-glow);
  padding:1px 4px;border-radius:3px;}
/* Flex container: the name text truncates with ellipsis, the dual pill stays
   intact (flex-shrink:0). Previously the pill was inline inside the
   ellipsis-truncating name, so a long dual label (e.g. "Amber/Emerald") clipped
   the pill mid-render and left a stray empty box fragment on mobile. */
.deck-pie-legend-name{display:flex;align-items:center;gap:3px;min-width:0;color:var(--text);}
.deck-pie-legend-name-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.deck-pie-legend-val{color:var(--text-muted);font-variant-numeric:tabular-nums;}

/* Collection sharing controls inside the settings popover. Mirrors the
   visual rhythm of other settings rows: muted label on the left, control
   on the right. The select stretches to fill remaining width so all three
   selects line up vertically regardless of label length. */
.collection-sharing{display:flex;flex-direction:column;gap:8px;}
.collection-sharing-hint{font-size:11px;color:var(--text-dim);line-height:1.4;}
.collection-sharing-row{display:flex;align-items:center;gap:10px;}
.collection-sharing-label{font-size:13px;color:var(--text);min-width:60px;}
.collection-sharing-row select{flex:1;padding:6px 8px;font-size:13px;
  border:1px solid var(--border);background:var(--bg-card);color:var(--text);
  border-radius:6px;font-family:inherit;cursor:pointer;}
.collection-sharing-row select:disabled{opacity:0.6;cursor:wait;}
.collection-sharing-links{display:flex;flex-direction:column;gap:6px;margin-top:4px;}
.collection-sharing-actions{display:flex;flex-direction:column;gap:4px;margin-top:2px;}
.collection-sharing-err{font-size:11px;color:#b91c1c;}

/* Read-only collection viewer banner. Sits above the section tabs in viewer
   mode (?collection=<uuid>). The back button uses the existing link button
   style so it visually matches the deck-detail "← Back". */
.collection-viewer-banner{display:flex;align-items:center;gap:10px 14px;
  flex-wrap:wrap;padding:10px 14px;margin-bottom:14px;
  background:var(--bg-surface);border:1px solid var(--border);
  border-radius:8px;}
.sealed-coll-counter-readonly{justify-content:center;}
.sealed-coll-counter-readonly .sealed-coll-counter-qty{padding:0 12px;}
/* Read-only graded slot: no hover affordance, no pointer cursor. */
.gc-slot.gc-slot-readonly{cursor:default;}
.gc-slot.gc-slot-readonly:hover{background:inherit;}

/* Comparison toggle inside the viewer banner. Inline-block label + select. */
.collection-viewer-compare{margin-left:auto;display:flex;align-items:center;
  gap:6px;font-size:12px;color:var(--text-dim);min-width:0;}
.collection-viewer-compare select{padding:4px 8px;font-size:12px;
  border:1px solid var(--border);background:var(--bg-card);color:var(--text);
  border-radius:6px;font-family:inherit;cursor:pointer;min-width:0;max-width:100%;}

/* Share button + popover anchored to the Collection tab header. Pushes to
   the right of the section tabs (Cards / Sealed / Graded) via margin-left:
   auto, so it sits at the end of the row on wider screens and drops below
   on narrow ones (the tab row already flex-wraps). */
.collection-share-wrap{position:relative;margin-left:auto;}
.collection-share-btn{padding:6px 12px;font-size:13px;
  border:1px solid var(--border);background:var(--bg-card);color:var(--text);
  border-radius:6px;cursor:pointer;font-family:inherit;}
.collection-share-btn:hover{background:var(--bg-surface-hover);}
.collection-share-btn.open{background:var(--accent-glow);border-color:var(--border-accent);color:var(--accent);}
.collection-share-popover{position:absolute;top:calc(100% + 6px);right:0;
  width:300px;padding:14px 14px 12px;
  background:var(--bg-modal);border:1px solid var(--border);
  border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,0.15);
  z-index:50;}

/* Viewer banner: clickable avatar + name → owner's creator profile. */
.collection-viewer-avatar{width:34px;height:34px;border-radius:50%;
  object-fit:cover;object-position:top;cursor:pointer;
  background:var(--bg-surface);flex-shrink:0;}
.collection-viewer-avatar-fallback{display:inline-flex;align-items:center;
  justify-content:center;background:var(--accent-glow);color:var(--accent);
  font-weight:700;font-size:16px;}
.collection-viewer-avatar:hover{outline:2px solid var(--accent);outline-offset:1px;}
.collection-viewer-name{padding:0;font:inherit;border:0;background:transparent;
  color:var(--text);font-size:15px;font-weight:600;cursor:pointer;
  text-decoration:none;}
.collection-viewer-name:hover{color:var(--accent);text-decoration:underline;}

/* Comparison stats strip — shown only when the viewer is signed in. */
.collection-compare-stats{margin:0 0 14px;padding:10px 14px;
  background:var(--bg-surface);border:1px solid var(--border);
  border-radius:8px;display:flex;flex-direction:column;gap:6px;}
.ccs-row{display:flex;flex-wrap:wrap;align-items:center;gap:16px;font-size:13px;}
.ccs-label{font-size:11px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-dim);min-width:50px;}
.ccs-stat{color:var(--text-dim);}
.ccs-stat b{color:var(--text);font-variant-numeric:tabular-nums;font-weight:700;}
.ccs-stat.ccs-shared b{color:var(--green);}
.ccs-stat.ccs-missing b{color:#b91c1c;}

/* Read-only InlineCounter — only renders the qty (no buttons). Center it
   in the cell that was previously occupied by [-, qty, +] so the row's
   grid alignment doesn't shift. */
.inline-counter.inline-counter-readonly{display:inline-flex;align-items:center;
  justify-content:center;min-width:42px;}
.inline-counter.inline-counter-readonly .ic-qty{font-size:14px;
  font-variant-numeric:tabular-nums;}

/* Graded view: clickable set headers (collapse/expand) + clickable cards. */
.gc-set-title-clickable{cursor:pointer;user-select:none;display:flex;
  align-items:center;gap:8px;}
.gc-set-title-clickable:hover{color:var(--accent);}
.gc-set-caret{display:inline-block;width:14px;font-size:12px;color:var(--text-dim);
  transition:transform 0.15s;}
.gc-card.gc-card-clickable{cursor:pointer;}
.gc-card.gc-card-clickable:hover{background:var(--bg-surface-hover);
  border-color:var(--border-accent);}

/* Set Tracking goal: x/X progress bar + label. */
.gc-goal-progress{margin-top:6px;display:flex;align-items:center;gap:8px;}
.gc-goal-progress-bar{flex:1;height:6px;background:var(--bg-surface);
  border-radius:3px;overflow:hidden;}
.gc-goal-progress-fill{height:100%;background:var(--accent);
  transition:width 0.2s ease;}
.gc-goal-progress-text{font-size:11px;font-variant-numeric:tabular-nums;
  color:var(--text-dim);min-width:fit-content;}

/* Graded view header: display-mode toggle next to the Add button. */
.graded-collection-header-actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap;}
/* Uppercase letter-spaced label family — matches the .gc-stat-lbl styling
   for "UNIQUE CARDS OWNED" so the whole header reads as one set of chips. */
.gc-caps-row{font-family:'Nunito Sans',sans-serif;}
.gc-caps-btn,
.gc-caps-cta,
.gc-caps-seg button,
.gc-caps-flag{font-size:10px;font-weight:700;letter-spacing:0.6px;text-transform:uppercase;}
.gc-caps-btn{padding:6px 12px;border-radius:14px;}
.gc-caps-cta{padding:8px 14px;}
.gc-caps-cta-sm{padding:5px 10px;}
.gc-caps-seg button{padding:6px 14px;}
.gc-caps-flag{display:inline-flex;align-items:center;gap:6px;cursor:help;}
.gc-caps-flag input[type="checkbox"]{cursor:pointer;}
.gc-caps-select{font-size:10px;font-weight:700;letter-spacing:0.6px;text-transform:uppercase;
  padding:6px 26px 6px 12px;border-radius:14px;border:1px solid var(--btn-border);
  background:var(--btn-bg);color:var(--btn-text);cursor:pointer;font-family:'Nunito Sans',sans-serif;
  appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--text-muted) 50%),
    linear-gradient(135deg,var(--text-muted) 50%,transparent 50%);
  background-position:calc(100% - 14px) 50%, calc(100% - 9px) 50%;
  background-size:5px 5px, 5px 5px;background-repeat:no-repeat;}
.gc-caps-select:hover{border-color:var(--accent);}
.gc-caps-info{position:relative;font-size:11px;color:var(--text-muted);font-weight:600;
  letter-spacing:0;text-transform:none;cursor:help;display:inline-flex;align-items:center;}
.gc-caps-flag:hover .gc-caps-info{color:var(--accent);}
/* Custom tooltip that pops on hover/focus of the ⓘ icon. More reliable
   than the native title= attribute (which has long delay + browser
   inconsistency) and lets us format the body multi-line. */
.gc-caps-tip{position:absolute;top:calc(100% + 6px);right:0;
  width:300px;max-width:calc(100vw - 24px);padding:10px 12px;background:var(--bg-modal);
  border:1px solid var(--border);border-radius:8px;
  font-size:11px;font-weight:400;color:var(--text);line-height:1.45;
  text-transform:none;letter-spacing:0;text-align:left;
  white-space:normal;
  box-shadow:0 6px 18px rgba(0,0,0,0.35);
  opacity:0;pointer-events:none;transform:translateY(-4px);
  transition:opacity 0.12s, transform 0.12s;z-index:50;}
.gc-caps-info:hover .gc-caps-tip,
.gc-caps-info:focus .gc-caps-tip,
.gc-caps-info:focus-within .gc-caps-tip{opacity:1;transform:translateY(0);pointer-events:auto;}
/* Mobile: pin to viewport so wrapping parents / overflow:hidden ancestors
   can't clip the tooltip. Centered horizontally, just below the header. */
@media (max-width:700px){
  .gc-caps-tip{position:fixed;top:auto;bottom:auto;right:auto;left:12px;right:12px;
    width:auto;max-width:none;margin-top:6px;font-size:12px;line-height:1.5;
    /* Anchor against the ⓘ via a transform — when the icon is near the bottom
       of the screen, the browser already handles scroll. */
    transform:translateY(-4px) translateX(0);}
  .gc-caps-info:hover .gc-caps-tip,
  .gc-caps-info:focus .gc-caps-tip,
  .gc-caps-info:focus-within .gc-caps-tip{transform:translateY(0) translateX(0);}
}
/* Mobile FAB: replaces the inline + Add graded card chip on narrow screens
   so the most-frequent action stays one-tap-reachable even when the
   header wraps to 3 rows of chips. Fixed bottom-right, above the footer. */
/* Goals jumper chip — desktop has the sidebar always visible so we hide
   the chip there. Only useful on mobile where the panel lives at the
   bottom of the page. */
.gc-goals-jumper{display:none;}
@media (max-width:900px){ .gc-goals-jumper{display:inline-flex;} }
.gc-add-fab{display:none;}
.gc-add-fab-wrap{display:contents;}
.gc-fab-backdrop,.gc-fab-menu{display:none;}
@media (max-width:700px){
  .gc-add-cta-desktop{display:none;}
  .gc-add-fab{display:flex;position:fixed;
    bottom:calc(18px + env(safe-area-inset-bottom));
    right:max(18px, env(safe-area-inset-right));
    width:56px;height:56px;
    border-radius:50%;font-size:28px;font-weight:800;align-items:center;justify-content:center;
    padding:0;line-height:1;z-index:62;box-shadow:0 4px 14px rgba(0,0,0,0.35);
    transition:transform 0.18s ease;}
  .gc-add-fab:active{transform:scale(0.94);}
  /* Open state: rotate the + into an × to signal "tap to dismiss the menu". */
  .gc-add-fab-open{transform:rotate(45deg);}
  .gc-add-fab-open:active{transform:rotate(45deg) scale(0.94);}
  /* Transparent full-screen catcher so a tap anywhere closes the menu. */
  .gc-fab-backdrop{display:block;position:fixed;inset:0;z-index:60;background:transparent;}
  /* Action menu anchored just above the FAB, right-aligned to it. */
  .gc-fab-menu{display:flex;position:fixed;z-index:61;flex-direction:column;gap:2px;padding:6px;
    bottom:calc(84px + env(safe-area-inset-bottom));
    right:max(18px, env(safe-area-inset-right));
    min-width:208px;background:var(--bg-modal);border:1px solid var(--border);
    border-radius:12px;box-shadow:0 8px 24px rgba(0,0,0,0.35);
    animation:gcFabMenuIn 0.14s ease;}
  .gc-fab-menu-item{display:flex;align-items:center;gap:10px;width:100%;
    padding:11px 12px;border:none;border-radius:8px;background:transparent;
    color:var(--text);font-size:14px;font-weight:600;cursor:pointer;text-align:left;
    font-family:'Nunito Sans',sans-serif;line-height:1.1;}
  .gc-fab-menu-item:active{background:var(--bg-surface);}
  .gc-fab-menu-icon{display:inline-flex;align-items:center;justify-content:center;
    width:24px;height:24px;flex-shrink:0;color:var(--accent);font-size:20px;font-weight:800;line-height:1;}
}
@keyframes gcFabMenuIn{from{opacity:0;transform:translateY(6px);}to{opacity:1;transform:translateY(0);}}

/* PSA 10 reference price shown on tracked-but-not-owned cards. Renders
   inside the "Tracking" pill as a secondary chip. */
.gc-slot-px-ref{margin-left:6px;padding:1px 6px;border-radius:4px;
  background:var(--bg-surface);color:var(--text-dim);font-size:10px;
  font-variant-numeric:tabular-nums;}

/* Compact display mode: hide images, lay out each card as a tight row.
   Three columns so screens fit way more cards at once. */
.gc-set-grid.gc-compact{display:grid;grid-template-columns:repeat(3,1fr);
  gap:6px;}
@media (max-width:1100px){.gc-set-grid.gc-compact{grid-template-columns:repeat(2,1fr);}}
@media (max-width:700px){.gc-set-grid.gc-compact{grid-template-columns:1fr;}}
.gc-set-grid.gc-compact .gc-card{display:flex;align-items:center;gap:8px;
  padding:6px 10px;border-radius:6px;min-height:38px;}
.gc-set-grid.gc-compact .gc-card-img{display:none;}
/* Uniform stack — name on top, #/rarity below, slots below that — across
   both grid AND compact mode. Previously compact used flex-row which put
   #/rarity to the right of the name, making the layout inconsistent
   between modes. */
.gc-set-grid.gc-compact .gc-card-body{display:flex;align-items:stretch;
  gap:2px;width:100%;flex:1;flex-direction:column;}
.gc-set-grid.gc-compact .gc-card-name{font-size:12px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.gc-set-grid.gc-compact .gc-card-sub{font-size:10px;white-space:nowrap;}
.gc-set-grid.gc-compact .gc-card-raw{display:none;}
.gc-set-grid.gc-compact .gc-card-slots{margin-top:2px;justify-content:flex-start;}

/* Raw-price strip on each Graded tile: tiny inline ref + Buy chip. Lives
   on its own line but heavily compressed so it doesn't compete with the
   slot pills for the user's attention. Buy link is small but still
   tappable thanks to a 4-side padding extender. */
.gc-card-raw{display:flex;align-items:center;gap:6px;font-size:9.5px;
  margin:0 0 1px;color:var(--text-muted);line-height:1.2;flex-wrap:wrap;}
.gc-card-raw-px{font-variant-numeric:tabular-nums;color:var(--text);}
/* Secondary price chip (Market alongside Low on sealed tiles). Slightly
   dimmer than the primary so it reads as "and here's the other reference"
   without pulling focus from the price the user actually picks for total. */
.gc-card-raw-px-secondary{opacity:0.78;}
/* Puzzle tiles have no price — show piece count / exclusivity as muted meta
   instead, so it reads as info rather than a (missing) dollar figure. */
.gc-card-puzzle-meta{color:var(--text-muted);font-weight:600;}
.gc-card-raw-px-lbl{color:var(--text-muted);font-size:8.5px;font-weight:700;
  letter-spacing:0.4px;text-transform:uppercase;margin-right:1px;}
/* 4-window Δ% row on sealed tiles (Show Δ% toggle). Equal-width cells
   like the graded slot delta grid; each cell stacks label above value
   so 1D/1W/1M/1Y read at a glance. */
.gc-card-deltas{display:grid;grid-template-columns:repeat(4, minmax(0, 1fr));
  gap:4px;margin:1px 0 2px;line-height:1.1;}
.gc-card-delta-cell{display:flex;align-items:baseline;gap:2px;min-width:0;}
.gc-card-delta-lbl{font-size:7.5px;font-weight:700;letter-spacing:0.3px;
  color:var(--text-muted);}
.gc-card-delta-val{font-weight:700;font-size:9.5px;font-variant-numeric:tabular-nums;}
.gc-card-buy{margin-left:auto;padding:1px 5px;border-radius:3px;
  background:var(--accent);color:#fff;font-weight:600;font-size:9.5px;
  text-decoration:none;letter-spacing:0.2px;}
.gc-card-buy:hover{filter:brightness(1.1);}

/* Graded portfolio chart panel — sits between the header totals and
   the per-set list. */
.graded-value-chart{padding:14px 16px;margin:0 0 16px;
  background:var(--bg-surface);border:1px solid var(--border);
  border-radius:10px;}
.gvc-header{display:flex;align-items:center;gap:14px;margin-bottom:8px;flex-wrap:wrap;}
.gvc-line-toggles{display:flex;gap:12px;}
.gvc-line-toggles label{display:inline-flex;align-items:center;gap:5px;font-size:11px;color:var(--text-dim);cursor:pointer;}
.gvc-line-toggles input{cursor:pointer;}
.gvc-title{font-size:11px;font-weight:700;letter-spacing:0.5px;
  text-transform:uppercase;color:var(--text-dim);}
.gvc-value{display:flex;align-items:baseline;gap:8px;flex:1;flex-wrap:wrap;}
.gvc-now{font-size:22px;font-weight:700;color:var(--green);
  font-variant-numeric:tabular-nums;}
.gvc-delta{font-size:12px;font-variant-numeric:tabular-nums;}
.gvc-chart{min-height:180px;}

/* Home page section title rendered as a button (e.g. Tournament Results). */
.home-feed-title-link{background:transparent;border:0;padding:0;cursor:pointer;
  font:inherit;color:inherit;text-align:left;}
.home-feed-title-link:hover{color:var(--accent);text-decoration:underline;}

/* Discover tile: trophy line surfaces tournament name + place when the
   deck is sourced from a tournament (user_id = null). Slots between the
   deck name and the regular meta line, with a subtle accent gradient. */
.deck-card-tourney{display:flex;align-items:center;gap:6px;font-size:12px;
  margin:4px 0 6px;padding:4px 8px;border-radius:6px;
  background:var(--accent-glow);color:var(--accent);
  border:1px solid var(--border-accent);}
.deck-card-tourney .dct-trophy{font-size:13px;}
.deck-card-tourney .dct-name{font-weight:600;flex:1;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.deck-card-tourney .dct-place{padding:1px 6px;border-radius:4px;
  background:var(--accent);color:#fff;font-weight:700;font-size:11px;
  letter-spacing:0.3px;}
.deck-card-tourney .muted{color:var(--text-dim);}

/* Clickable Home section headers (Recent set EV, Your Collection, Following
   movers banners). Behave like a link without underline by default; on
   hover bump opacity + subtle underline so the affordance is clear. */
.home-title-link{transition:opacity .12s, text-decoration-color .12s;}
.home-title-link:hover{opacity:0.8;text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;}

/* ── Trade Comparison Tool (Analytics » Trade Compare) ─────────────────── */
.trade-view{max-width:1000px;margin:0 auto;}
.trade-intro{font-size:12.5px;color:var(--text-dim);line-height:1.5;
  margin:4px 0 14px;}
.trade-intro strong{color:var(--text);font-weight:600;}

/* Search + which-side toggle */
.trade-controls{display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  margin-bottom:14px;}
.trade-addtoggle{display:flex;align-items:center;gap:8px;}
.trade-addtoggle-lbl{font-size:11px;font-weight:700;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--text-dim);}
.trade-seg button{max-width:140px;overflow:hidden;text-overflow:ellipsis;}
.trade-searchwrap{position:relative;flex:1;min-width:220px;}
.trade-search{width:100%;box-sizing:border-box;padding:9px 12px;font-size:13px;
  border:1px solid var(--border);border-radius:10px;background:var(--bg-card);
  color:var(--text);}
.trade-search:focus{outline:none;border-color:var(--accent);}
.trade-results{position:absolute;z-index:30;left:0;right:0;top:calc(100% + 4px);
  max-height:340px;overflow-y:auto;background:var(--bg-modal);
  border:1px solid var(--border);border-radius:10px;
  box-shadow:0 8px 28px rgba(0,0,0,0.18);padding:4px;}
.trade-results-empty{padding:14px;text-align:center;font-size:12.5px;
  color:var(--text-dim);}
.trade-result{display:flex;align-items:center;gap:10px;width:100%;
  text-align:left;background:none;border:none;border-radius:7px;
  padding:6px 8px;cursor:pointer;color:var(--text);}
.trade-result:hover{background:var(--bg-surface-hover);}
.trade-result-img{width:30px;height:42px;object-fit:cover;border-radius:3px;
  flex-shrink:0;background:var(--bg-surface);}
.trade-result-text{display:flex;flex-direction:column;min-width:0;flex:1;}
.trade-result-name{font-size:13px;font-weight:600;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.trade-result-sub{font-size:11px;color:var(--text-dim);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.trade-result-px{font-size:12px;font-weight:700;color:var(--green);
  flex-shrink:0;font-variant-numeric:tabular-nums;}
.trade-result-in{flex-shrink:0;font-size:10px;font-weight:800;
  letter-spacing:0.5px;padding:2px 6px;border-radius:10px;
  background:var(--accent-glow);color:var(--accent);
  border:1px solid var(--border-accent);}

/* Difference summary */
.trade-diff{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:12px;padding:12px 14px;margin-bottom:14px;}
.trade-diff-head{display:flex;align-items:center;justify-content:space-between;
  gap:10px;margin-bottom:8px;}
.trade-diff-title{font-size:11px;font-weight:800;letter-spacing:0.6px;
  text-transform:uppercase;color:var(--text-dim);}
.trade-diff-tools{display:flex;align-items:center;gap:8px;flex-shrink:0;}
.trade-share-btn{font-size:11px;font-weight:600;padding:4px 11px;
  border:1px solid var(--btn-border);border-radius:14px;background:var(--btn-bg);
  color:var(--btn-text);cursor:pointer;white-space:nowrap;}
.trade-share-btn:hover{border-color:var(--accent);color:var(--accent);}
.trade-clearall-btn:hover:not(:disabled){border-color:var(--red);color:var(--red);}
.trade-share-btn:disabled{opacity:0.4;cursor:default;}
.trade-layout-seg{flex-shrink:0;}
.trade-layout-seg button{padding:3px 12px;font-size:11px;}
.trade-diff-rows{display:flex;gap:10px;flex-wrap:wrap;}
.trade-diff-row{flex:1;min-width:200px;display:flex;align-items:baseline;
  gap:10px;background:var(--bg-card);border:1px solid var(--border);
  border-radius:8px;padding:8px 12px;}
.trade-diff-lbl{font-size:11px;font-weight:700;letter-spacing:0.3px;
  text-transform:uppercase;color:var(--text-dim);min-width:74px;}
.trade-diff-amt{font-size:20px;font-weight:800;color:var(--text);
  font-variant-numeric:tabular-nums;}
.trade-diff-dir{font-size:12px;font-weight:700;color:var(--accent);
  margin-left:auto;}
.trade-diff-dir.even{color:var(--text-muted);}

/* Sort bar */
.trade-sortbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;
  flex-wrap:wrap;}
.trade-sort-lbl{font-size:11px;font-weight:700;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--text-dim);}
.trade-sort-seg button{padding:3px 12px;font-size:11px;}

/* Two-sided grid */
.trade-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;
  align-items:start;}
.trade-side{background:var(--bg-card);border:1px solid var(--border);
  border-radius:12px;padding:12px;min-width:0;}
.trade-side-head{display:flex;align-items:center;gap:8px;margin-bottom:8px;}
.trade-side-name{flex:1;min-width:0;font-size:15px;font-weight:700;
  background:transparent;border:none;border-bottom:1px dashed transparent;
  color:var(--text);padding:2px 0;}
.trade-side-name:hover{border-bottom-color:var(--border);}
.trade-side-name:focus{outline:none;border-bottom-color:var(--accent);}
.trade-clear-btn{flex-shrink:0;font-size:11px;font-weight:600;
  padding:3px 9px;border:1px solid var(--btn-border);border-radius:12px;
  background:var(--btn-bg);color:var(--btn-text);cursor:pointer;}
.trade-clear-btn:hover{border-color:var(--red);color:var(--red);}
.trade-side-totals{display:flex;gap:8px;}
.trade-tot{flex:1;background:var(--bg-surface);border-radius:8px;
  padding:7px 10px;display:flex;flex-direction:column;gap:1px;}
.trade-tot-lbl{font-size:10px;font-weight:700;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--text-dim);}
.trade-tot-val{font-size:17px;font-weight:800;color:var(--text);
  font-variant-numeric:tabular-nums;}
.trade-side-meta{font-size:11px;color:var(--text-muted);margin:6px 2px 2px;}
.trade-side-body{display:flex;flex-direction:column;gap:8px;margin-top:8px;}
.trade-side-empty{font-size:12px;color:var(--text-dim);line-height:1.5;
  text-align:center;padding:18px 10px;border:1px dashed var(--border);
  border-radius:8px;}

/* Card row inside a side */
.trade-card{display:flex;gap:10px;align-items:flex-start;
  background:var(--bg-surface);border:1px solid var(--border);
  border-radius:9px;padding:8px;position:relative;}
.trade-card-img{width:40px;height:56px;object-fit:contain;border-radius:4px;
  flex-shrink:0;background:var(--bg-card);}
.trade-card-main{flex:1;min-width:0;}
.trade-card-name{font-size:13px;font-weight:600;line-height:1.25;}
.trade-card-sub{font-size:11px;color:var(--text-dim);margin-bottom:6px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.trade-printings{display:flex;flex-direction:column;gap:5px;}
.trade-printing{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.trade-pr-label{font-size:11px;font-weight:700;min-width:58px;
  padding:1px 0;color:var(--text-dim);}
.trade-printing.foil .trade-pr-label{color:#8a6bc7;}
html[data-mode="dark"] .trade-printing.foil .trade-pr-label{color:#c0a3ef;}
.trade-qty{display:flex;align-items:center;gap:4px;flex-shrink:0;}
.trade-qty-btn{width:22px;height:22px;border-radius:6px;
  border:1px solid var(--btn-border);background:var(--btn-bg);
  color:var(--text);font-size:15px;line-height:1;cursor:pointer;
  display:flex;align-items:center;justify-content:center;}
.trade-qty-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.trade-qty-btn:disabled{opacity:0.35;cursor:default;}
.trade-qty-val{min-width:18px;text-align:center;font-size:13px;
  font-weight:700;font-variant-numeric:tabular-nums;}
.trade-pr-prices{display:flex;gap:10px;margin-left:auto;
  font-variant-numeric:tabular-nums;}
.trade-pr-low,.trade-pr-mkt{font-size:12px;font-weight:600;color:var(--text);
  white-space:nowrap;}
.trade-pr-tag{font-size:9px;font-weight:700;letter-spacing:0.3px;
  text-transform:uppercase;color:var(--text-muted);}
.trade-pr-link{flex-shrink:0;font-size:13px;line-height:1;text-decoration:none;
  color:var(--text-muted);padding:2px 4px;border-radius:5px;}
.trade-pr-link:hover{color:var(--accent);background:var(--bg-surface-hover);}
.trade-card-actions{display:flex;flex-direction:column;gap:4px;flex-shrink:0;}
.trade-move,.trade-remove{width:22px;height:22px;border:1px solid transparent;
  background:none;color:var(--text-muted);font-size:15px;line-height:1;
  cursor:pointer;border-radius:6px;display:flex;align-items:center;
  justify-content:center;}
.trade-remove{font-size:17px;}
.trade-move:hover{background:var(--bg-surface-hover);border-color:var(--accent);
  color:var(--accent);}
.trade-remove:hover{background:var(--bg-surface-hover);color:var(--red);}

/* Compact layout — short rows, no card image or set/ink subtitle. Printings
   sit side-by-side (one condensed block per card) on every width, matching the
   mobile layout, so a card takes one row instead of stacking its printings. */
.trade-card.compact{padding:6px 8px;}
.trade-card.compact .trade-card-name{font-size:12.5px;}
.trade-card.compact .trade-card-actions{flex-direction:row;}
.trade-card.compact .trade-printings{display:grid;
  grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:6px 12px;}
.trade-card.compact .trade-printing{flex-direction:column;align-items:flex-start;
  gap:4px;position:relative;padding-right:16px;}
.trade-card.compact .trade-pr-prices{margin-left:0;width:auto;gap:8px;flex-wrap:wrap;}
.trade-card.compact .trade-pr-link{position:absolute;top:0;right:0;}

/* Clicking the card art / name opens the standard card detail modal. */
.trade-card-clickable{cursor:pointer;}
.trade-card-name.trade-card-clickable:hover{text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:1px;}
.trade-card-img.trade-card-clickable:hover{opacity:0.85;}

/* Low vs NM Market verification note */
.trade-note{margin:14px 0 0;font-size:11.5px;line-height:1.55;
  color:var(--text-muted);}
.trade-note strong{color:var(--text-dim);font-weight:600;}
.trade-note-i{color:var(--accent);font-weight:700;}

@media (max-width:760px){
  .trade-grid{grid-template-columns:1fr;}
  .trade-searchwrap{min-width:100%;order:3;}
  .trade-addtoggle{width:100%;justify-content:space-between;}
  .trade-seg{flex:1;}
  .trade-seg button{flex:1;max-width:none;}
  /* Non-Foil + Foil sit side-by-side to save vertical space; each becomes a
     compact vertical block (label, qty stepper, prices) with the TCGplayer
     arrow pinned to its top-right corner. */
  .trade-printings{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));
    gap:8px;}
  .trade-printing{flex-direction:column;align-items:flex-start;gap:4px;
    position:relative;padding-right:16px;}
  .trade-pr-prices{margin-left:0;width:auto;gap:8px;flex-wrap:wrap;}
  .trade-pr-link{position:absolute;top:0;right:0;}
}

/* Sealed-mode chip row in the Screener — product-type filter. Mirrors
   .price-db-collchips (Foil/Non-Foil) layout but lets the chips wrap
   since there are 13 display types. */
.price-db-typechips{display:flex;flex-wrap:wrap;gap:4px;align-items:center;}
.price-db-collchip-clear{font-style:italic;}
/* Display-type label in the screener's Rarity column when showSealed is on.
   Small uppercase chip so "Booster Box" / "Trove" reads as a type rather
   than blending with the Set column. */
.price-db-sealed-type{display:inline-block;padding:2px 7px;font-size:9.5px;
  font-weight:700;letter-spacing:0.4px;text-transform:uppercase;
  background:var(--bg-card);border:1px solid var(--border);
  border-radius:4px;color:var(--text-muted);white-space:nowrap;}

/* ===== SealedDetailModal — popup opened when clicking a sealed tile.
   Reuses .card-detail-overlay / .card-detail / .card-detail-close from
   CardDetailModal so the dismiss/keyboard/animation behavior is
   identical. The sealed-specific classes lay out the contents:
   image on the left, price summary + qty controls on the right, then
   a 6-window Δ% grid (LOW/MKT rows × 1D/1W/1M/3M/6M/1Y cols), then a
   full-width price-history chart. */
.card-detail.sealed-detail{max-width:860px;padding:30px 28px 24px;}
.sealed-detail-head{display:flex;gap:20px;align-items:flex-start;padding-right:48px;}
.sealed-detail-img-wrap{flex:0 0 180px;}
.sealed-detail-img{width:180px;max-height:240px;object-fit:contain;
  border-radius:8px;background:var(--bg-surface);}
.sealed-detail-img-fallback{width:180px;height:180px;display:flex;align-items:center;
  justify-content:center;text-align:center;padding:12px;font-size:11px;
  color:var(--text-muted);background:var(--bg-surface);border-radius:8px;}
.sealed-detail-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:10px;}
.sealed-detail-name{font-family:'Cinzel',serif;font-weight:700;color:var(--text);
  font-size:20px;margin:0;line-height:1.2;}
.sealed-detail-meta{font-size:12px;display:flex;gap:6px;flex-wrap:wrap;}
.sealed-detail-sep{opacity:0.4;}
.sealed-detail-prices{display:flex;gap:16px;align-items:center;flex-wrap:wrap;}
.sealed-detail-price-cell{display:flex;flex-direction:column;align-items:flex-start;}
.sealed-detail-price-lbl{font-size:9.5px;font-weight:700;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--text-muted);}
.sealed-detail-price-val{font-family:'Cinzel',serif;font-size:22px;font-weight:700;
  color:var(--accent);line-height:1.1;}
.sealed-detail-buy{margin-left:auto;padding:7px 14px;border-radius:6px;
  background:var(--accent);color:#fff;font-weight:700;font-size:12px;
  text-decoration:none;letter-spacing:0.2px;white-space:nowrap;}
.sealed-detail-buy:hover{filter:brightness(1.1);}
.sealed-detail-owncounter{display:flex;align-items:center;gap:8px;padding:8px 10px;
  background:var(--bg-card);border:1px solid var(--border);border-radius:6px;
  font-size:12px;}
.sealed-detail-owncounter-lbl{font-weight:700;color:var(--text-muted);
  letter-spacing:0.3px;text-transform:uppercase;font-size:10px;}
.sealed-detail-owncounter button{width:26px;height:26px;border-radius:4px;
  background:var(--bg-solid);border:1px solid var(--border);color:var(--text);
  cursor:pointer;font-size:14px;font-weight:700;display:flex;align-items:center;
  justify-content:center;}
.sealed-detail-owncounter button:hover:not(:disabled){border-color:var(--accent);}
.sealed-detail-owncounter button:disabled{opacity:0.4;cursor:not-allowed;}
.sealed-detail-owned-value{margin-left:auto;font-size:11px;}
.sealed-detail-deltas{margin:20px 0 8px;background:var(--bg-card);
  border:1px solid var(--border);border-radius:6px;padding:8px 10px;}
.sealed-detail-deltas-lblrow,
.sealed-detail-deltas-row{display:grid;grid-template-columns:44px repeat(6, 1fr);
  align-items:center;gap:4px;}
.sealed-detail-deltas-lblrow{padding-bottom:4px;border-bottom:1px solid var(--border);
  margin-bottom:4px;}
.sealed-detail-deltas-side-lbl{font-size:9.5px;font-weight:800;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--text-muted);}
.sealed-detail-deltas-h{font-size:9.5px;font-weight:700;letter-spacing:0.4px;
  text-transform:uppercase;color:var(--text-muted);text-align:center;}
.sealed-detail-deltas-v{font-size:12px;font-weight:700;text-align:center;
  font-variant-numeric:tabular-nums;}
.sealed-detail-chart{margin-top:6px;}
.sealed-detail-chart-title{font-family:'Cinzel',serif;font-weight:700;
  color:var(--accent);font-size:13px;letter-spacing:0.3px;margin-bottom:6px;}
.sealed-detail-chart-titlerow{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;}
.sealed-detail-chart-toggles{display:flex;gap:12px;margin-bottom:6px;}
.sealed-detail-chart-toggles label{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--text-dim);cursor:pointer;}
.sealed-detail-chart-toggles input{cursor:pointer;}
@media (max-width:640px){
  .card-detail.sealed-detail{padding:18px 14px 12px;}
  .sealed-detail-head{flex-direction:column;align-items:stretch;padding-right:36px;gap:14px;}
  .sealed-detail-img-wrap{flex:none;align-self:center;}
  .sealed-detail-img,.sealed-detail-img-fallback{width:140px;max-height:200px;}
  .sealed-detail-name{font-size:16px;}
  .sealed-detail-price-val{font-size:18px;}
  .sealed-detail-buy{margin-left:0;}
  .sealed-detail-deltas-lblrow,
  .sealed-detail-deltas-row{grid-template-columns:36px repeat(6, minmax(0, 1fr));}
  .sealed-detail-deltas-v{font-size:10.5px;}
}

/* =============================================================
   Chicagoland Lorcana ELO leaderboard (hidden /elo tab)
   Uses Packs.Ink theme tokens so the view adapts to every theme.
   Gold/yellow accent for crown + peak hooks is the ONE non-token
   color, by design — matches the Elorcana brand cue.
   ============================================================= */
.elo-view{max-width:1200px;margin:0 auto;padding:20px 18px 60px;color:var(--text);}
.elo-hero{margin-bottom:20px;}
.elo-title{font-family:'Cinzel',serif;font-size:26px;font-weight:700;margin:0 0 4px;color:var(--accent);letter-spacing:0.5px;}
.elo-sub{margin:0 0 18px;color:var(--text-muted);font-size:13px;max-width:680px;line-height:1.5;}
.elo-innertabs{display:flex;gap:4px;border-bottom:1px solid var(--btn-border);}
.elo-innertabs button{background:transparent;border:none;color:var(--text-muted);
  padding:10px 18px;cursor:pointer;font-family:'Cinzel',serif;font-size:14px;
  font-weight:600;letter-spacing:0.4px;border-bottom:2px solid transparent;
  margin-bottom:-1px;transition:color 120ms ease, border-color 120ms ease;}
.elo-innertabs button:hover{color:var(--text);}
.elo-innertabs button.active{color:var(--accent);border-bottom-color:var(--accent);}

/* Roster Scout (admin) — by-day slate + player search over upcoming rosters. */
.elo-scout{margin-top:18px;max-width:820px;}
.elo-scout-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:10px;}
.elo-scout-titlewrap{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;}
.elo-scout-title{font-family:'Cinzel',serif;font-size:18px;font-weight:700;color:var(--accent);margin:0;}
.elo-scout-summary{font-size:12px;}
.elo-scout-orgtoggle{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-dim);cursor:pointer;}
.elo-scout-modes{margin-bottom:14px;}
.elo-scout-search{width:100%;box-sizing:border-box;padding:9px 12px;margin-bottom:12px;border:1px solid var(--border);
  border-radius:8px;background:var(--bg-card);color:var(--text);font-size:14px;}
.elo-scout-days{display:flex;flex-direction:column;gap:16px;}
.elo-scout-day-hdr{font-weight:700;font-size:13px;color:var(--text);margin-bottom:6px;letter-spacing:0.2px;}
.elo-scout-evlist{display:flex;flex-direction:column;gap:5px;}
.elo-scout-ev{border:1px solid var(--border);border-radius:8px;background:var(--bg-card);overflow:hidden;}
.elo-scout-ev.open{border-color:var(--border-accent);}
.elo-scout-ev-row{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;
  text-align:left;background:none;border:none;color:var(--text);cursor:pointer;padding:9px 12px;}
.elo-scout-ev-row:hover{background:var(--bg-surface);}
.elo-scout-ev-main{display:flex;flex-direction:column;min-width:0;gap:1px;}
.elo-scout-ev-store{font-weight:600;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.elo-scout-ev-meta{font-size:11.5px;}
.elo-scout-ev-stats{display:flex;align-items:center;gap:12px;flex-shrink:0;font-size:12px;}
.elo-scout-stat b{color:var(--text);font-variant-numeric:tabular-nums;}
.elo-scout-caret{color:var(--text-muted);width:12px;text-align:center;}
.elo-scout-ev-roster{padding:4px 12px 10px;border-top:1px solid var(--border);}
.elo-scout-rosterlist{list-style:decimal;margin:6px 0 0;padding-left:26px;display:flex;flex-direction:column;gap:3px;}
.elo-scout-rosterlist li,.elo-scout-hit-events li{display:flex;align-items:center;gap:8px;font-size:12.5px;}
.elo-scout-rname{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.elo-scout-noros{font-size:12px;padding:4px 0;}
.elo-scout-elo{font-weight:700;font-variant-numeric:tabular-nums;color:var(--accent);font-size:12px;white-space:nowrap;}
.elo-scout-elo.elo-scout-unrated{color:var(--text-muted);font-weight:400;font-style:italic;}
.elo-scout-namebtn{background:none;border:none;padding:0;color:var(--text);font:inherit;cursor:pointer;text-align:left;}
.elo-scout-namebtn:hover{color:var(--accent);text-decoration:underline;}
.elo-scout-hits{display:flex;flex-direction:column;gap:10px;}
.elo-scout-hit{border:1px solid var(--border);border-radius:8px;background:var(--bg-card);padding:10px 12px;}
.elo-scout-hit-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px;}
.elo-scout-hit-name{font-weight:700;font-size:14px;}
.elo-scout-hit-count{margin-left:auto;font-size:11px;color:var(--text-muted);}
.elo-scout-wl{font-size:11.5px;font-variant-numeric:tabular-nums;}
.elo-scout-hit-events{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px;}
.elo-scout-ev-date{font-weight:600;min-width:120px;}

/* Upcoming Set Championships tab (tracked stores). */
.elo-upcoming{margin-top:18px;max-width:760px;}
.elo-upcoming-sub{margin:0 0 16px;color:var(--text-muted);font-size:13px;}
.elo-up-day{margin-bottom:16px;}
.elo-up-day-head{font-family:'Cinzel',serif;font-size:13px;font-weight:600;color:var(--accent);
  letter-spacing:0.3px;padding-bottom:5px;margin-bottom:7px;border-bottom:1px solid var(--border);}
.elo-up-rows{display:flex;flex-direction:column;gap:5px;}
.elo-up-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:center;
  text-align:left;width:100%;padding:9px 12px;border:1px solid var(--border);border-radius:8px;
  background:var(--bg-surface);color:var(--text);cursor:pointer;font-family:inherit;
  transition:border-color 0.12s,background 0.12s;}
.elo-up-row:hover{border-color:var(--border-accent);background:var(--bg-surface-hover);}
.elo-up-time{font-size:12px;font-weight:700;color:var(--text-dim);white-space:nowrap;
  font-variant-numeric:tabular-nums;min-width:74px;}
.elo-up-main{min-width:0;display:flex;flex-direction:column;}
.elo-up-store{font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.elo-up-loc{font-size:11px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.elo-up-arrow{color:var(--text-muted);font-size:18px;line-height:1;}
.elo-up-strength{display:inline-block;margin-left:7px;font-size:10px;font-weight:800;
  color:var(--accent);background:var(--accent-glow);border:1px solid var(--border-accent);
  border-radius:5px;padding:0 5px;vertical-align:middle;font-variant-numeric:tabular-nums;}
.elo-up-mi{font-size:11px;font-weight:700;color:var(--text-dim);white-space:nowrap;font-variant-numeric:tabular-nums;}
.elo-up-controls{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:14px;}
.elo-up-zip{margin-bottom:0;max-width:230px;}
.elo-up-distopts{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.elo-up-seg.seg-toggle button{padding:5px 11px;font-size:12px;}
.elo-up-radius{font-size:12px;color:var(--text-muted);display:inline-flex;align-items:center;gap:5px;}
.elo-up-radius select{padding:4px 6px;font-size:12px;border:1px solid var(--btn-border);border-radius:5px;
  background:var(--bg-solid);color:var(--text);font-family:inherit;}
@media(max-width:560px){
  .elo-up-time{min-width:64px;font-size:11px;}
  .elo-up-row{padding:8px 10px;gap:9px;}
}

.elo-store-stat--elo{background:var(--accent-glow);border-color:var(--border-accent);}
.elo-store-stat--elo .n{color:var(--accent);}
.elo-exclude-toggle{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-dim);
  cursor:pointer;margin:0 0 16px;padding:5px 9px;border:1px dashed var(--border);border-radius:6px;}
.elo-exclude-toggle input{margin:0;width:14px;height:14px;accent-color:var(--accent);cursor:pointer;}

/* Store scouting report (credential-gated). */
.elo-store{margin-top:6px;}
.elo-store-title{font-family:'Cinzel',serif;font-size:22px;font-weight:700;color:var(--accent);margin:10px 0 14px;}
.elo-store-stats{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:22px;}
.elo-store-stat{background:var(--bg-surface);border:1px solid var(--border);border-radius:8px;
  padding:9px 14px;display:flex;flex-direction:column;gap:2px;min-width:80px;}
.elo-store-stat .n{font-size:18px;font-weight:800;color:var(--text);font-variant-numeric:tabular-nums;}
.elo-store-stat .l{font-size:10px;text-transform:uppercase;letter-spacing:0.4px;color:var(--text-muted);font-weight:600;}
.elo-store-stat--wide .n{font-size:13px;font-weight:700;}
.elo-store-h3{font-family:'Cinzel',serif;font-size:15px;font-weight:600;color:var(--text);margin:24px 0 10px;}
.elo-store-players td{cursor:pointer;}
.elo-store-elo{font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap;}
.elo-store-rank{font-size:10px;color:var(--text-muted);font-weight:600;margin-left:5px;}
.elo-store-pname{font-weight:600;}
.elo-store-players .num{text-align:right;font-variant-numeric:tabular-nums;}
.elo-store-events{display:flex;flex-direction:column;gap:5px;max-width:760px;}
.elo-store-event{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:center;
  text-align:left;width:100%;padding:9px 12px;border:1px solid var(--border);border-radius:8px;
  background:var(--bg-surface);color:var(--text);cursor:pointer;font-family:inherit;
  transition:border-color 0.12s,background 0.12s;}
.elo-store-event:hover{border-color:var(--border-accent);background:var(--bg-surface-hover);}
.elo-se-date{font-size:11px;font-weight:700;color:var(--text-dim);white-space:nowrap;min-width:84px;font-variant-numeric:tabular-nums;}
.elo-se-main{min-width:0;display:flex;flex-direction:column;}
.elo-se-name{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.elo-se-meta{font-size:11px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.elo-se-players{font-size:12px;font-weight:700;color:var(--text-dim);white-space:nowrap;}
.elo-store-link{background:none;border:none;cursor:pointer;font:inherit;padding:0;}
.sc-modal-cta--report{background:var(--accent-glow);color:var(--accent);border:1px solid var(--border-accent);
  width:100%;text-align:center;padding:9px 12px;border-radius:7px;font-size:13px;font-weight:700;
  cursor:pointer;font-family:inherit;margin-bottom:7px;}
.sc-modal-cta--report:hover{background:var(--accent);color:#fff;}

/* Toolbar: platform chips + min-matches + search */
.elo-toolbar{display:flex;flex-wrap:wrap;gap:12px;align-items:center;
  justify-content:space-between;margin:18px 0 12px;}
.elo-chips{display:flex;gap:6px;}
.elo-chip{background:var(--btn-bg);color:var(--text-muted);
  border:1px solid var(--btn-border);border-radius:14px;padding:6px 14px;
  cursor:pointer;font-size:12px;font-weight:600;letter-spacing:0.3px;
  display:inline-flex;align-items:center;gap:6px;
  transition:background 120ms ease, color 120ms ease, border-color 120ms ease;}
.elo-chip:hover{color:var(--text);}
.elo-chip.active{background:var(--accent);color:var(--bg-solid);border-color:var(--accent);}
.elo-toolbar-right{display:flex;gap:10px;align-items:center;}
.elo-min-matches{font-size:11px;color:var(--text-muted);text-transform:uppercase;
  letter-spacing:0.4px;display:inline-flex;align-items:center;gap:6px;}
.elo-min-matches select{background:var(--btn-bg);color:var(--text);
  border:1px solid var(--btn-border);border-radius:6px;padding:4px 8px;
  font-size:12px;cursor:pointer;}
.elo-search{background:var(--btn-bg);color:var(--text);
  border:1px solid var(--btn-border);border-radius:6px;padding:7px 12px;
  font-size:13px;min-width:180px;}
.elo-search:focus{outline:none;border-color:var(--accent);}
.elo-count{font-size:11px;color:var(--text-muted);margin-bottom:8px;letter-spacing:0.3px;text-transform:uppercase;}

/* Table */
.elo-table-wrap{overflow-x:auto;border:1px solid var(--btn-border);border-radius:8px;background:var(--bg-card);}
.elo-table{width:100%;border-collapse:collapse;font-size:13px;font-variant-numeric:tabular-nums;}
.elo-table thead{background:var(--btn-bg);}
.elo-table th{text-align:left;padding:10px 12px;font-size:10.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:0.6px;color:var(--text-muted);
  border-bottom:1px solid var(--btn-border);white-space:nowrap;}
.elo-table th.elo-th-rank,.elo-table td.elo-td-rank{width:80px;}
.elo-table th.elo-th-elo,.elo-table td.elo-td-elo{width:70px;font-weight:700;}
.elo-table th.elo-th-record,.elo-table td.elo-td-record{width:110px;color:var(--text-muted);}
.elo-table th.elo-th-gw,.elo-table td.elo-td-gw{width:80px;color:var(--text-muted);}
.elo-table th.elo-th-peak,.elo-table td.elo-td-peak{width:90px;color:var(--text-muted);}
.elo-table td{padding:9px 12px;border-bottom:1px solid var(--btn-border);}
.elo-table tbody tr:last-child td{border-bottom:none;}
.elo-table tbody tr:hover{background:var(--btn-bg);}

.elo-rank{font-weight:600;color:var(--text-muted);}
.elo-rank-top{color:#e8c547;display:inline-flex;align-items:center;gap:5px;}
.elo-crown{color:#e8c547;flex-shrink:0;}

/* Anchor-based now (was <button>) — strip the default <a> underline so
   the leaderboard doesn't look like a list of hyperlinks. Hover still
   underlines the inner .elo-name as the "this is a link" affordance.
   Also strip from descendant alias / opp spans so neither line under-
   lines without a hover. */
.elo-name-btn{background:transparent;border:none;padding:0;cursor:pointer;
  color:var(--accent);font:inherit;display:inline-flex;align-items:center;gap:8px;
  text-align:left;text-decoration:none;}
.elo-name-btn,.elo-name-btn:visited{text-decoration:none;}
.elo-name-btn:hover .elo-name{text-decoration:underline;}
.elo-name{font-weight:600;}

/* Platform pills (inline SVG-ish) */
.elo-pf{display:inline-block;border-radius:50%;position:relative;overflow:hidden;
  vertical-align:middle;flex-shrink:0;}
.elo-pf-rph{background:radial-gradient(circle at 30% 30%, #ffb947, #d97a1a 70%, #8b4a0c);
  box-shadow:0 0 0 1px rgba(255,255,255,0.08) inset;}
.elo-pf-melee{background:#2a0a0a;display:inline-flex;align-items:center;justify-content:center;gap:1px;padding:0 2px;}
.elo-pf-stripe{width:2px;height:60%;background:#e53935;border-radius:1px;}

/* States */
.elo-loading,.elo-empty,.elo-placeholder{padding:40px 24px;text-align:center;
  color:var(--text-muted);font-size:14px;}
.elo-placeholder h3{font-family:'Cinzel',serif;color:var(--accent);font-size:18px;
  margin:0 0 10px;font-weight:600;}
.elo-placeholder p{margin:6px 0 14px;line-height:1.5;}
.elo-placeholder code{background:var(--btn-bg);padding:2px 6px;border-radius:4px;font-size:12px;}

@media (max-width:600px){
  .elo-view{padding:14px 10px 40px;}
  .elo-title{font-size:22px;}
  /* Title + Pin toggle sit in elo-hero-row. On narrow screens the title takes
     a full line on its own and the pin toggle wraps below it; align both to
     the left so the wrapped pin doesn't float weirdly to the far right. */
  .elo-hero-row{gap:8px;justify-content:flex-start;}
  /* Inner tabs (Leaderboard / Tournaments) need a touch larger tap target. */
  .elo-innertabs button{padding:10px 14px;font-size:13.5px;}
  .elo-toolbar{flex-direction:column;align-items:stretch;}
  /* Filter chips row (All / RPH / Melee) — allow wrap if a 4th chip is
     ever added; gives the pill icons breathing room. */
  .elo-chips{flex-wrap:wrap;}
  /* Min-matches + search row. Previously elo-search had min-width:180px which
     pushed the row past most phones' viewport on landscape-flip + Safari's
     navigation-bar shrinkage. Let it flex-grow to fill whatever's left. */
  .elo-toolbar-right{justify-content:space-between;flex-wrap:wrap;gap:8px;}
  .elo-search{flex:1 1 140px;min-width:0;}
  /* Sort arrows can vanish under the column cap on phones — bump arrow
     emphasis so the user knows a column IS sorted while horizontally
     scrolling. */
  .elo-th-arrow{font-size:10px;}
}

/* ----- condense table: shrink-to-fit instead of stretching to 100% ----- */
.elo-table-wrap{display:flex;justify-content:center;}
.elo-table{width:auto;table-layout:fixed;max-width:100%;}
.elo-table th.elo-th-rank,  .elo-table td.elo-td-rank   { width:64px;  text-align:left; }
.elo-table th.elo-th-elo,   .elo-table td.elo-td-elo    { width:72px;  text-align:right; padding-right:18px; }
.elo-table th.elo-th-player,.elo-table td.elo-td-player { width:300px; text-align:left; padding-left:14px; }
.elo-table th.elo-th-record,.elo-table td.elo-td-record { width:92px;  text-align:right; }
.elo-table th.elo-th-gw,    .elo-table td.elo-td-gw     { width:74px;  text-align:right; }
.elo-table th.elo-th-peak,  .elo-table td.elo-td-peak   { width:80px;  text-align:right; }
.elo-table td{padding:7px 12px;}
.elo-table th{padding:8px 12px;}
.elo-name-btn{justify-content:flex-start;width:auto;}
.elo-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:240px;display:inline-block;vertical-align:middle;}

/* Tournaments + event-detail tables don't use the leaderboard column class
   names — let them flow with auto layout but keep them shrink-to-fit. */
.elo-tournaments .elo-table,
.elo-event-detail .elo-table{table-layout:auto;}

/* ----- sortable headers ----- */
.elo-th-sortable{cursor:pointer;user-select:none;position:relative;}
.elo-th-sortable:hover{color:var(--text);}
.elo-th-sortable.active{color:var(--accent);}
.elo-th-arrow{display:inline-block;width:0.9em;font-size:9px;margin-left:4px;
  color:var(--accent);vertical-align:middle;}

/* ----- back chevron ----- */
.elo-back{background:transparent;border:none;color:var(--accent);cursor:pointer;
  font-size:13px;font-weight:600;padding:0;margin-bottom:18px;
  letter-spacing:0.3px;}
.elo-back:hover{text-decoration:underline;}

/* ----- player profile ----- */
.elo-profile{max-width:1100px;margin:0 auto;}
.elo-profile-hero{background:var(--btn-bg);border:1px solid var(--btn-border);
  border-radius:10px;padding:18px 20px;margin-bottom:22px;}
.elo-profile-name{display:flex;align-items:center;gap:12px;margin-bottom:14px;}
.elo-profile-name h2{font-family:'Cinzel',serif;font-weight:700;font-size:22px;
  margin:0;color:var(--text);letter-spacing:0.4px;}
.elo-stat-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:14px;}
.elo-stat{text-align:center;}
.elo-stat-lbl{font-size:10px;text-transform:uppercase;letter-spacing:0.6px;
  color:var(--text-muted);margin-bottom:4px;}
.elo-stat-val{font-family:'Cinzel',serif;font-weight:700;font-size:22px;
  color:var(--accent);font-variant-numeric:tabular-nums;}

.elo-tourney{background:var(--btn-bg);border:1px solid var(--btn-border);
  border-radius:10px;padding:16px 18px;margin-bottom:14px;}
.elo-tourney-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  justify-content:space-between;margin-bottom:12px;}
.elo-tourney-head h3{margin:0;font-family:'Cinzel',serif;font-size:16px;
  font-weight:600;color:var(--text);}
.elo-tourney-head h3 .elo-name-btn{color:var(--text);}
.elo-tourney-head h3 .elo-name-btn:hover{color:var(--accent);}
.elo-tourney-meta{font-size:11px;color:var(--text-muted);letter-spacing:0.2px;}
/* Per-tournament mini-stats grid. Desktop = 6 columns (added MW% to the
   original 4); responsive overrides live in the @media blocks below
   (≤700px → 3 cols, ≤480px → 2 cols). Consolidated 2026-06-27: the base
   was repeat(4) re-set to repeat(6) further down, and a dead repeat(2)
   sat inside the ≤700px block above its repeat(3) sibling. */
.elo-tourney-stats{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-bottom:12px;}
.elo-stat-mini{background:var(--bg-solid);border:1px solid var(--btn-border);
  border-radius:8px;padding:8px 10px;text-align:center;}
/* Was display:inline-flex which sized to content — on a narrow card (2-col
   mobile grid) the rating + delta would sit on one line that overflowed the
   rounded box boundary. The delta ("+17") was visually leaking outside the
   border. Switch to block-level flex so the row is bounded by the parent's
   width, and flex-wrap lets the delta drop to a new line on the tightest
   widths instead of clipping. Suppress the .elo-delta's own margin-left
   inside here since the flex `gap:6px` handles spacing — otherwise we got
   14px between rating and delta (gap + margin). */
.elo-stat-mini .elo-stat-val{font-size:15px;display:flex;align-items:baseline;
  gap:6px;justify-content:center;flex-wrap:wrap;}
.elo-stat-mini .elo-stat-val .elo-delta{margin-left:0;}
/* Field size after the place ("#5 / 17") — muted + smaller so the rank reads
   primary. Kept inside one .elo-place span so the flex gap/wrap doesn't split
   "#5" from "/ 17". */
.elo-place-field{color:var(--text-muted);font-size:0.72em;font-weight:600;}

.elo-rounds-table{width:100%;border-collapse:collapse;font-size:12.5px;
  font-variant-numeric:tabular-nums;}
.elo-rounds-table th{text-align:left;font-size:10px;text-transform:uppercase;
  letter-spacing:0.5px;color:var(--text-muted);padding:6px 8px;
  border-bottom:1px solid var(--btn-border);}
.elo-rounds-table td{padding:6px 8px;border-bottom:1px solid var(--btn-border);}
.elo-rounds-table tbody tr:last-child td{border-bottom:none;}
.elo-rounds-opp{width:auto;}
.elo-rounds-result{width:130px;}
.elo-rounds-elo{width:130px;text-align:right;}
.elo-opp{font-weight:500;}
.elo-opp-rating{color:var(--text-muted);margin-left:6px;font-size:11px;}
.elo-result{display:inline-block;font-weight:700;font-size:11px;
  padding:1px 8px;border-radius:10px;letter-spacing:0.3px;text-transform:uppercase;}
.elo-result.win{background:rgba(46,160,67,0.18);color:#3fbf57;}
.elo-result.loss{background:rgba(220,67,67,0.18);color:#e25b5b;}
.elo-result.draw{background:rgba(255,193,7,0.15);color:#cda53a;}
.elo-score{color:var(--text-muted);font-size:11px;margin-left:6px;font-weight:500;}
.elo-delta{margin-left:8px;font-size:11px;font-weight:600;}
.elo-delta.up{color:#3fbf57;}
.elo-delta.down{color:#e25b5b;}

/* ----- tournaments / event detail ----- */
.elo-tournaments{}
.elo-event-detail{}
.elo-event-head{margin-bottom:18px;}
.elo-event-head h2{font-family:'Cinzel',serif;font-weight:700;font-size:22px;
  margin:0 0 6px;color:var(--text);letter-spacing:0.3px;}
.elo-event-meta{font-size:12px;color:var(--text-muted);margin:0;
  display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;}
/* Inferred set label next to the event date (ELO list rows + event detail). */
.elo-event-set{color:var(--accent);font-weight:600;}
.elo-event-h3{font-family:'Cinzel',serif;font-size:14px;color:var(--accent);
  text-transform:uppercase;letter-spacing:0.6px;margin:18px 0 8px;font-weight:600;}
.elo-rounds-nav{display:flex;gap:6px;flex-wrap:wrap;margin:18px 0 8px;}
.elo-winner{font-weight:600;}
.elo-winner .elo-name-btn{color:var(--accent);}

@media (max-width:700px){
  .elo-stat-grid{grid-template-columns:repeat(3,1fr);}
  .elo-stat:nth-child(4),.elo-stat:nth-child(5){grid-column:auto;}
  /* .elo-tourney-stats ≤700px override lives in its own consolidated block
     below (repeat(3,1fr)) — it was a dead repeat(2,1fr) here. */
  .elo-rounds-elo,.elo-rounds-result{width:auto;}
}

/* ----- name + alias stacked under the platform pill -----
   The alias used to render as a parenthesized inline chip after the name. On
   mobile, that pushed long display_names into truncation before the alias
   even got a chance. Stacking lets the canonical name keep its full width
   and the alias sits below it in smaller muted text — same vertical space
   on desktop, more horizontal room on mobile. */
.elo-name-stack{display:inline-flex;flex-direction:column;align-items:flex-start;
  gap:0;line-height:1.15;}
.elo-name-stack .elo-name{display:block;}
.elo-alias{color:var(--text-muted);font-weight:400;font-size:11px;
  letter-spacing:0.1px;margin:1px 0 0;display:block;max-width:100%;
  /* Was: nowrap + ellipsis. On mobile that hid the melee handle (e.g.
     "LoL_METALLICFLARE" got clipped to "LoL_METAL…") even though it was
     the most useful disambiguating info. Allow it to wrap to a 2nd line
     so the whole handle is visible; word-break ensures very long handles
     without spaces still wrap cleanly. */
  white-space:normal;word-break:break-word;line-height:1.2;}
.elo-name-btn:hover .elo-alias{color:var(--text);}

/* ----- MOBILE leaderboard table -----
   This block sits AFTER the desktop "condense table" rules above (which set
   .elo-table-wrap { display:flex; justify-content:center } and a fixed table
   layout). The combo above (a) centered the overflowing table inside its
   scroll viewport — leaving rank/ELO clipped behind the left edge with no
   way to scroll into them; and (b) capped the table at 100% of the viewport,
   which squished cell contents to ellipses instead of allowing horizontal
   scroll. Fix LIVES BELOW the desktop rules so the cascade order is right
   — putting this in the @media block above had no effect. */
@media (max-width:600px){
  .elo-alias{font-size:10px;}
  .elo-table-wrap{display:block;justify-content:flex-start;overflow-x:auto;
    -webkit-overflow-scrolling:touch;}
  .elo-table{width:max-content;max-width:none;min-width:520px;}
  .elo-table th.elo-th-rank,  .elo-table td.elo-td-rank   { width:54px;  padding-left:8px;}
  .elo-table th.elo-th-elo,   .elo-table td.elo-td-elo    { width:60px;  padding-right:10px;}
  .elo-table th.elo-th-player,.elo-table td.elo-td-player { width:160px; padding-left:8px;}
  .elo-table th.elo-th-record,.elo-table td.elo-td-record { width:80px;}
  .elo-table th.elo-th-mw,    .elo-table td.elo-td-mw     { width:64px;}
  .elo-table th.elo-th-gw,    .elo-table td.elo-td-gw     { width:64px;}
  .elo-table th.elo-th-peak,  .elo-table td.elo-td-peak   { width:64px; padding-right:8px;}
  .elo-table td{padding:6px 6px;}
  .elo-table th{padding:7px 6px;font-size:10px;letter-spacing:0.4px;}
  .elo-name{max-width:140px;font-size:12.5px;}
}

/* ----- "Also known as" block on player profile ----- */
.elo-profile-aka{font-size:12px;color:var(--text-muted);margin:-8px 0 14px;
  display:flex;align-items:center;flex-wrap:wrap;gap:6px;}
.elo-aka-lbl{text-transform:uppercase;letter-spacing:0.5px;font-size:10px;
  color:var(--text-muted);}
.elo-aka-name{display:inline-flex;align-items:center;gap:4px;color:var(--text);}

/* ----- Player profile hero stat grid bumps from 5 → 6 columns (Events added) ----- */
.elo-stat-grid{grid-template-columns:repeat(6,1fr);}
@media (max-width:780px){ .elo-stat-grid{grid-template-columns:repeat(3,1fr);} }
@media (max-width:420px){ .elo-stat-grid{grid-template-columns:repeat(2,1fr);} }

/* (Per-tournament mini-stats column count is defined below at the 6-column
   rule — the earlier 5-column block was dead, fully overridden, and removed.) */

/* ----- Clickable opponent name in round table ----- */
.elo-rounds-table .elo-name-btn{padding:0;color:var(--accent);font-weight:500;
  background:transparent;}

/* ----- Pin-to-Analytics toggle in the ELO hero ----- */
.elo-hero-row{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;}
.elo-pin-toggle{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  font-size:11px;text-transform:uppercase;letter-spacing:0.5px;
  color:var(--text-muted);padding:6px 12px;border-radius:14px;
  background:var(--btn-bg);border:1px solid var(--btn-border);
  user-select:none;transition:color 120ms ease,border-color 120ms ease;}
.elo-pin-toggle:hover{color:var(--text);}
.elo-pin-toggle input{margin:0;cursor:pointer;}
.elo-pin-toggle:has(input:checked){color:var(--accent);border-color:var(--accent);}

/* ----- MW% column on leaderboard table + 7-col hero grid (added Events earlier) ----- */
.elo-table th.elo-th-mw, .elo-table td.elo-td-mw { width:74px; text-align:right; }
.elo-profile-hero .elo-stat-grid{grid-template-columns:repeat(7,1fr);}
@media (max-width:780px){ .elo-profile-hero .elo-stat-grid{grid-template-columns:repeat(4,1fr);} }
@media (max-width:420px){ .elo-profile-hero .elo-stat-grid{grid-template-columns:repeat(2,1fr);} }

/* Per-tournament mini-stats responsive overrides (base 6-col is set at the
   .elo-tourney-stats definition above): ≤700px → 3 cols, ≤480px → 2 cols. */
@media (max-width:700px){ .elo-tourney-stats{grid-template-columns:repeat(3,1fr);} }
@media (max-width:480px){ .elo-tourney-stats{grid-template-columns:repeat(2,1fr);} }

/* ----- Bye row in profile rounds table ----- */
.elo-rounds-bye td{opacity:0.55;}
.elo-result.bye{background:rgba(120,120,120,0.18);color:var(--text-muted);}
.elo-opp-bye{font-style:italic;}
.elo-rounds-bye-dash{color:var(--text-muted);}

/* External link out to the original tournament page on the event detail header. */
.elo-event-link{margin-left:auto;font-size:12px;color:var(--accent);
  text-decoration:none;font-weight:600;padding:3px 10px;border-radius:12px;
  background:var(--btn-bg);border:1px solid var(--btn-border);
  transition:border-color 120ms ease, color 120ms ease;}
.elo-event-link:hover{border-color:var(--accent);}

/* ----- Head-to-Head section on player profile -----
   Picker lets the viewer drill into "every match I've played vs <opponent>"
   with a summary card + full chronological match list. */
.elo-h2h{margin:18px 0 22px;padding:14px 16px;border:1px solid var(--btn-border);
  border-radius:12px;background:var(--bg-card);}
.elo-h2h-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px;}
.elo-h2h-head h3{margin:0;font-size:15px;letter-spacing:0.4px;text-transform:uppercase;
  color:var(--text-muted);font-weight:600;}

/* Searchable picker: text input + dropdown listbox.
   - Replaces the prior native <select> which (a) rendered an unstyled white
     option panel in dark mode and (b) didn't support incremental typing.
   - Listbox is absolute-positioned beneath the input, capped at ~340px so
     long opponent rosters scroll instead of pushing layout. */
.elo-h2h-picker{position:relative;flex:1;min-width:220px;max-width:480px;}
.elo-h2h-search{width:100%;padding:7px 12px;border-radius:8px;
  border:1px solid var(--btn-border);background:var(--btn-bg);color:var(--text);
  font-size:13px;font-family:inherit;box-sizing:border-box;}
.elo-h2h-search:focus{outline:none;border-color:var(--accent);}
.elo-h2h-list{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;
  margin:0;padding:4px 0;list-style:none;
  background:var(--bg-modal,var(--bg-card));border:1px solid var(--btn-border);
  border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,0.35);
  max-height:340px;overflow-y:auto;}
.elo-h2h-opt{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:7px 12px;cursor:pointer;font-size:13px;color:var(--text);
  transition:background 80ms ease;}
.elo-h2h-opt:hover,.elo-h2h-opt.active{background:var(--btn-active-bg,var(--accent-glow));}
.elo-h2h-opt-name{display:inline-flex;align-items:center;gap:6px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.elo-h2h-opt-stats{color:var(--text-muted);font-size:11.5px;flex:0 0 auto;
  font-variant-numeric:tabular-nums;}
.elo-h2h-opt-more{padding:7px 12px;color:var(--text-muted);font-size:12px;
  font-style:italic;text-align:center;}
.elo-h2h-clear{padding:5px 12px;border-radius:8px;border:1px solid var(--btn-border);
  background:var(--btn-bg);color:var(--text-muted);font-size:12px;cursor:pointer;
  transition:color 120ms ease, border-color 120ms ease;}
.elo-h2h-clear:hover{color:var(--text);border-color:var(--accent);}
.elo-h2h-card{margin-top:6px;}
.elo-h2h-card-head{display:flex;align-items:center;gap:8px;margin-bottom:10px;font-size:15px;}
.elo-h2h-vs{color:var(--text-muted);font-weight:600;text-transform:uppercase;
  letter-spacing:0.5px;font-size:11px;}
.elo-h2h-name{display:inline-flex;align-items:center;gap:6px;text-decoration:none;
  color:var(--text);font-weight:600;font-size:16px;
  padding:3px 8px;border-radius:8px;
  transition:background 120ms ease;}
.elo-h2h-name:hover{background:var(--btn-bg);color:var(--accent);}
.elo-h2h-table .elo-h2h-date{white-space:nowrap;color:var(--text-muted);font-size:12px;width:90px;}
.elo-h2h-table .elo-h2h-event{font-size:12.5px;}
.elo-h2h-table .elo-h2h-event .elo-name-btn{font-size:12.5px;}
@media (max-width:600px){
  .elo-h2h{padding:12px 10px;}
  /* The full event name + date in the same row gets crowded on phones;
     stack them by hiding the date column (kept in the picker summary). */
  .elo-h2h-table .elo-h2h-date{display:none;}
}

/* ===== Keyboard shortcuts cheat sheet (toggled with "?") ===== */
.kbd-shortcuts-modal{position:relative;background:var(--bg-modal);
  border:1px solid var(--border);border-radius:14px;padding:22px 24px;
  width:min(420px, calc(100vw - 32px));box-shadow:0 18px 50px rgba(0,0,0,0.45);}
.kbd-shortcuts-list{display:flex;flex-direction:column;gap:10px;}
.kbd-shortcuts-row{display:flex;align-items:center;gap:14px;}
.kbd-key{flex:0 0 auto;min-width:46px;text-align:center;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;font-weight:700;
  color:var(--text);background:var(--bg-solid);border:1px solid var(--border);
  border-bottom-width:2px;border-radius:6px;padding:4px 8px;}
.kbd-desc{font-size:13.5px;color:var(--text-muted);line-height:1.4;}

/* ===== First-run welcome tour (F3 onboarding) ===== */
.welcome-tour{position:relative;background:var(--bg-modal);border:1px solid var(--border);
  border-radius:16px;padding:30px 28px 22px;width:min(440px, calc(100vw - 32px));
  text-align:center;box-shadow:0 20px 60px rgba(0,0,0,0.5);}
.welcome-tour-emoji{font-size:44px;line-height:1;margin-bottom:12px;}
.welcome-tour-title{margin:0 0 8px;font-size:21px;color:var(--accent);}
.welcome-tour-body{margin:0 0 20px;font-size:14px;line-height:1.55;color:var(--text-muted);min-height:66px;}
.welcome-tour-dots{display:flex;justify-content:center;gap:8px;margin-bottom:20px;}
.welcome-tour-dot{width:8px;height:8px;border-radius:50%;border:none;padding:0;cursor:pointer;
  background:var(--border);transition:background 120ms ease,transform 120ms ease;}
.welcome-tour-dot.active{background:var(--accent);transform:scale(1.25);}
.welcome-tour-nav{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.welcome-tour-nav-right{display:flex;align-items:center;gap:8px;}
.welcome-tour-skip{background:transparent;border:none;color:var(--text-muted);font-size:13px;cursor:pointer;padding:8px 6px;}
.welcome-tour-skip:hover{color:var(--text);}
.welcome-tour-back{background:var(--btn-bg);border:1px solid var(--btn-border);color:var(--text);
  border-radius:8px;padding:8px 16px;font-size:13px;font-weight:600;cursor:pointer;}
.welcome-tour-next{background:var(--accent);border:1px solid var(--accent);color:var(--bg-solid);
  border-radius:8px;padding:8px 18px;font-size:13px;font-weight:700;cursor:pointer;}
.welcome-tour-next:hover{filter:brightness(1.05);}
.faq-tour-btn{display:inline-flex;align-items:center;gap:8px;margin-bottom:18px;
  background:var(--accent);border:1px solid var(--accent);color:var(--bg-solid);
  border-radius:10px;padding:10px 18px;font-size:14px;font-weight:700;cursor:pointer;}
.faq-tour-btn:hover{filter:brightness(1.05);}
/* Help-page tour launcher strip: welcome carousel + one chip per section tour. */
.faq-tours{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:18px;}
.faq-tours .faq-tour-btn{margin-bottom:0;}
.faq-tour-btn--section{background:var(--bg-modal);color:var(--accent);
  border-color:var(--border-accent);font-weight:600;}
.faq-tour-btn--section:hover{background:var(--accent);color:var(--bg-solid);filter:none;}
/* CTA inside the welcome carousel steps ("Open Collection →" etc). */
.welcome-tour-cta{display:inline-flex;align-items:center;gap:6px;margin:0 0 18px;
  background:transparent;border:1px solid var(--accent);color:var(--accent);
  border-radius:8px;padding:7px 16px;font-size:13px;font-weight:600;cursor:pointer;}
.welcome-tour-cta:hover{background:var(--accent);color:var(--bg-solid);}
/* Contextual "Tour" button for the current section (G5). Bottom-left so it
   never collides with the graded add-FAB (bottom-right); z-index below modals
   and the deck-editor mobile bar. */
.section-tour-btn{position:fixed;left:14px;bottom:calc(14px + env(safe-area-inset-bottom));z-index:30;
  display:inline-flex;align-items:center;gap:6px;padding:8px 13px;border-radius:999px;cursor:pointer;
  font-size:12px;font-weight:700;font-family:inherit;
  background:var(--bg-modal);color:var(--accent);border:1px solid var(--border-accent);
  box-shadow:0 4px 14px rgba(0,0,0,0.25);transition:background 0.12s,color 0.12s;}
.section-tour-btn:hover{background:var(--accent);color:var(--bg-solid);border-color:var(--accent);}
/* Phones: no floating tour FAB — it collides with the deck editor's bottom
   bar and the graded add-FAB, and thumb-zone space is precious. Mobile gets
   the one-time auto-fire plus the Help-page launcher list instead. */
@media (max-width:700px){ .section-tour-btn{display:none;} }

/* In-app image saver — bulletproof mobile fallback for copy-image (H4). */
.image-saver-overlay{position:fixed;inset:0;z-index:9700;background:rgba(0,0,0,0.8);
  display:flex;align-items:center;justify-content:center;padding:16px;}
.image-saver-box{position:relative;background:var(--bg-modal);border-radius:14px;
  padding:18px 16px 16px;max-width:min(420px,92vw);max-height:92vh;display:flex;flex-direction:column;
  align-items:center;gap:12px;box-shadow:0 18px 50px rgba(0,0,0,0.5);overflow:auto;}
.image-saver-hint{font-size:13px;font-weight:600;color:var(--text);text-align:center;}
.image-saver-img{max-width:100%;height:auto;border-radius:10px;box-shadow:0 4px 16px rgba(0,0,0,0.3);
  -webkit-touch-callout:default;}
.image-saver-dl{font-size:13px;font-weight:700;color:var(--accent);text-decoration:none;
  border:1px solid var(--border-accent);border-radius:8px;padding:8px 16px;}
.image-saver-dl:hover{background:var(--accent-glow);}
.image-saver-close{position:absolute;top:4px;right:8px;background:none;border:none;
  font-size:24px;line-height:1;color:var(--text-muted);cursor:pointer;}

/* Interactive coachmark tour (H5): spotlight a control + point a tooltip at it. */
.coach-root{position:fixed;inset:0;z-index:9900;}
.coach-dim{position:absolute;inset:0;background:transparent;}
.coach-dim--solid{background:rgba(0,0,0,0.55);}
.coach-spotlight{position:absolute;border-radius:8px;pointer-events:none;
  box-shadow:0 0 0 9999px rgba(0,0,0,0.55), 0 0 0 3px var(--accent);
  transition:top 0.2s ease,left 0.2s ease,width 0.2s ease,height 0.2s ease;}
.coach-tip{position:absolute;background:var(--bg-modal);border:1px solid var(--border-accent);
  border-radius:12px;padding:14px 16px 12px;box-shadow:0 14px 44px rgba(0,0,0,0.5);box-sizing:border-box;}
.coach-tip-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px;}
.coach-tip-kicker{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.7px;color:var(--accent);}
.coach-tip-step{font-size:10px;font-weight:700;color:var(--text-muted);font-variant-numeric:tabular-nums;}
.coach-tip-title{margin:0 0 6px;font-size:16px;color:var(--text);}
.coach-tip-body{margin:0 0 14px;font-size:13px;line-height:1.5;color:var(--text-muted);}
.coach-tip-nav{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.coach-nav-right{display:flex;align-items:center;gap:8px;}
.coach-skip{background:transparent;border:none;color:var(--text-muted);font-size:12px;cursor:pointer;padding:6px 4px;font-family:inherit;}
.coach-skip:hover{color:var(--text);}
.coach-back{background:var(--btn-bg);border:1px solid var(--btn-border);color:var(--text);border-radius:8px;padding:7px 14px;font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;}
.coach-next{background:var(--accent);border:1px solid var(--accent);color:var(--bg-solid);border-radius:8px;padding:7px 16px;font-size:12px;font-weight:700;cursor:pointer;font-family:inherit;}
.coach-next:hover{filter:brightness(1.06);}
.coach-tip--up::before,.coach-tip--down::before{content:"";position:absolute;left:50%;transform:translateX(-50%);
  width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;}
.coach-tip--up::before{top:-8px;border-bottom:8px solid var(--bg-modal);}
.coach-tip--down::before{bottom:-8px;border-top:8px solid var(--bg-modal);}

/* Graded "My Cards" — flat owned-slab grid (mirrors the raw All Cards view) */
.gco-wrap{margin-top:6px;}
.gco-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px;}
.gco-toolbar .setdet-search{flex:1 1 200px;min-width:150px;}
.gco-toolbar .setdet-sort{margin-left:auto;}
.gco-summary{font-size:12px;color:var(--text-muted);margin:0 0 10px 2px;}
.gco-summary .green{color:var(--green);font-weight:600;}
.gco-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;}
.gco-tile{display:flex;flex-direction:column;text-align:left;padding:6px;border:1px solid var(--border);border-radius:10px;background:var(--bg-card);color:var(--text);cursor:pointer;transition:transform .08s ease,border-color .12s;}
.gco-tile:hover{transform:translateY(-2px);border-color:var(--border-accent);}
.gco-img-wrap{position:relative;aspect-ratio:5/7;border-radius:7px;overflow:hidden;background:rgba(0,0,0,0.12);}
.gco-img-wrap img{width:100%;height:100%;object-fit:cover;display:block;}
.gco-noimg{width:100%;height:100%;}
.gco-grade{position:absolute;top:5px;right:5px;font-size:10px;font-weight:700;letter-spacing:.3px;color:#fff;padding:2px 6px;border-radius:6px;box-shadow:0 1px 3px rgba(0,0,0,.35);}
.gco-foil{position:absolute;bottom:5px;left:5px;font-size:9px;font-weight:700;color:#412402;background:#f6d488;padding:1px 5px;border-radius:5px;}
.gco-qty{position:absolute;bottom:5px;right:5px;font-size:10px;font-weight:700;color:#fff;background:rgba(0,0,0,.6);padding:1px 5px;border-radius:5px;}
.gco-name{font-size:12px;font-weight:600;margin-top:5px;line-height:1.25;}
.gco-sub{font-size:11px;color:var(--text-muted);line-height:1.2;}
.gco-val{font-size:13px;font-weight:700;color:var(--green);margin-top:3px;}
.gco-val.custom{color:var(--accent);}
.gco-val.gco-val-raw{color:var(--text-muted);font-weight:600;font-style:italic;}
.gco-val-pair{display:flex;justify-content:center;gap:10px;margin-top:3px;}
.gco-vp-item{display:flex;flex-direction:column;align-items:center;line-height:1.1;}
.gco-vp-num{font-size:12.5px;font-weight:800;color:var(--text);font-variant-numeric:tabular-nums;}
.gco-vp-lbl{font-size:8px;font-weight:700;text-transform:uppercase;letter-spacing:0.3px;color:var(--text-muted);}
.gco-bucket-head{font-size:12px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:var(--accent);margin:14px 2px 6px;}
.gco-bucket:first-child .gco-bucket-head{margin-top:2px;}
/* Compact list: photo-free, very dense, 5 across */
.gco-list{display:grid;grid-template-columns:repeat(5,1fr);gap:5px;}
@media (max-width:1100px){.gco-list{grid-template-columns:repeat(3,1fr);}}
@media (max-width:760px){.gco-list{grid-template-columns:repeat(2,1fr);}}
@media (max-width:480px){.gco-list{grid-template-columns:1fr;}}
.gco-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:6px;align-items:center;width:100%;text-align:left;padding:3px 7px;border:1px solid var(--border);border-radius:6px;background:var(--bg-card);color:var(--text);cursor:pointer;min-height:26px;}
.gco-row:hover{border-color:var(--border-accent);}
.gco-row .gco-grade{position:static;font-size:9px;padding:1px 4px;}
.gco-row-name{font-size:11.5px;font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.gco-row-sub{font-weight:400;color:var(--text-muted);}
.gco-row-foil{margin-left:5px;font-size:8.5px;font-weight:700;letter-spacing:0.3px;text-transform:uppercase;color:var(--accent);border:1px solid var(--accent);border-radius:4px;padding:0 3px;vertical-align:middle;}
.gco-row-val{font-size:11.5px;font-weight:700;color:var(--green);text-align:right;white-space:nowrap;}
.gco-row-val.custom{color:var(--accent);}
.gco-row-qty{font-size:9px;color:var(--text-muted);margin-left:3px;}

/* All Cards: full Filters drawer button — accent when filters are active */
.setdet-filters-btn.has-active{border-color:var(--accent);color:var(--accent);font-weight:600;}

/* Tracking "Posters" mode: full card-image tiles (reuse .gco-tile), grade
   badge(s) stacked top-right, translucent for cards you don't own yet. */
.gc-poster{position:relative;}
.gc-poster .gc-poster-grades{position:absolute;top:5px;right:5px;display:flex;flex-direction:column;gap:3px;align-items:flex-end;z-index:1;}
.gc-poster .gc-poster-grades .gco-grade{position:static;}
.gc-poster .gc-grade-tracked{box-shadow:inset 0 0 0 1px rgba(255,255,255,0.55);}
.gc-poster-unowned{opacity:0.42;filter:saturate(0.85);}
.gc-poster-unowned:hover{opacity:0.74;}
.gco-val.gc-poster-refval{color:var(--text-muted);font-weight:600;}
.gc-poster .gc-card-add-btn{top:5px;left:5px;right:auto;z-index:2;opacity:0;transition:opacity .12s;}
.gc-poster:hover .gc-card-add-btn,.gc-poster:focus-within .gc-card-add-btn{opacity:0.55;}
.gc-poster .gc-card-add-btn:hover{opacity:0.95;}
/* Touch devices have no hover — keep the add button reachable. */
@media (hover:none){.gc-poster .gc-card-add-btn{opacity:0.55;}}

/* Per-player profile flair (Elo): tiny Iconic card badge next to the name.
   Profile page only — never rendered on the leaderboard. */
.elo-name-flair{height:32px;width:auto;border-radius:4px;align-self:center;
  box-shadow:0 1px 5px rgba(0,0,0,0.45);flex-shrink:0;}

/* ── Card scanner (PWA camera matcher) ─────────────────────────────────── */
.scanner-overlay{position:fixed;inset:0;z-index:6000;display:flex;flex-direction:column;
  background:#0b0a12;color:#fff;
  padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);}
.scanner-head{display:flex;align-items:center;justify-content:space-between;
  padding:10px 14px;flex:0 0 auto;}
.scanner-title{font-weight:700;font-size:16px;letter-spacing:.02em;}
.scanner-close{background:rgba(255,255,255,0.12);border:none;color:#fff;width:36px;height:36px;
  border-radius:50%;font-size:22px;line-height:1;cursor:pointer;}
.scanner-close:hover{background:rgba(255,255,255,0.2);}
.scanner-stage{position:relative;flex:1 1 auto;min-height:0;overflow:hidden;background:#000;
  display:flex;align-items:center;justify-content:center;}
.scanner-video,.scanner-overlay-cv{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;}
.scanner-overlay-cv{pointer-events:none;}
/* soft, forgiving framing hint — not something to precisely line up to;
   the matcher finds & crops the card wherever it is in this rough area. */
.scanner-softframe{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  height:82%;aspect-ratio:5/7;max-width:94%;border:2px solid rgba(255,255,255,0.3);
  border-radius:18px;pointer-events:none;
  box-shadow:0 0 0 100vmax rgba(0,0,0,0.22);}
.scanner-detbadge{position:absolute;top:12px;left:50%;transform:translateX(-50%);
  background:rgba(0,0,0,0.5);color:rgba(255,255,255,0.85);font-size:12px;font-weight:600;
  padding:5px 12px;border-radius:20px;letter-spacing:.02em;display:flex;align-items:center;gap:6px;}
.scanner-detbadge::before{content:"";width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,0.4);}
.scanner-detbadge.on{background:rgba(40,120,55,0.65);color:#fff;}
.scanner-detbadge.on::before{background:#67e08a;box-shadow:0 0 6px #67e08a;}
.scanner-busy{position:absolute;bottom:14px;left:50%;transform:translateX(-50%);
  background:rgba(0,0,0,0.6);color:#fff;font-size:13px;font-weight:600;padding:7px 16px;border-radius:20px;}
.scanner-starting{position:absolute;color:rgba(255,255,255,0.85);font-size:15px;}
/* bottom panels */
.scanner-scanbar,.scanner-result-wrap,.scanner-msg{flex:0 0 auto;
  background:linear-gradient(0deg,#13111d,#0b0a12);padding:14px 14px calc(16px + env(safe-area-inset-bottom));}
.scanner-scanbar{display:flex;flex-direction:column;align-items:center;gap:8px;}
.scanner-subhint{font-size:11px;color:rgba(255,255,255,0.5);}
.scanner-shutter{width:74px;height:74px;border-radius:50%;background:#fff;cursor:pointer;
  border:5px solid rgba(255,255,255,0.5);box-shadow:0 0 0 3px rgba(0,0,0,0.45) inset, 0 2px 10px rgba(0,0,0,0.4);}
.scanner-shutter:disabled{opacity:.55;cursor:default;}
.scanner-shutter:not(:disabled):active{transform:scale(0.93);}
.scanner-result-wrap{display:flex;flex-direction:column;gap:12px;}
.scanner-result{display:flex;gap:14px;align-items:flex-start;}
.scanner-result-img{width:108px;aspect-ratio:5/7;object-fit:cover;border-radius:8px;flex:0 0 auto;
  background:#222;box-shadow:0 3px 12px rgba(0,0,0,0.5);}
.scanner-result-info{flex:1 1 auto;min-width:0;}
.scanner-result-name{font-weight:700;font-size:17px;line-height:1.25;}
.scanner-result-meta{font-size:12px;color:rgba(255,255,255,0.6);margin:2px 0 10px;}
.scanner-alts-label{font-size:12px;color:rgba(255,255,255,0.6);margin-bottom:7px;}
.scanner-hint{text-align:center;font-size:13px;color:rgba(255,255,255,0.66);margin-bottom:10px;}
.scanner-cand-row{display:flex;gap:8px;justify-content:center;align-items:stretch;min-height:96px;}
.scanner-cand{flex:1 1 0;max-width:120px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);
  border-radius:10px;padding:6px;display:flex;flex-direction:column;align-items:center;gap:5px;
  cursor:pointer;color:#fff;font:inherit;}
.scanner-cand.top{border-color:var(--accent,#e8c850);background:rgba(232,200,80,0.12);}
.scanner-cand img{width:100%;aspect-ratio:5/7;object-fit:cover;border-radius:6px;background:#222;}
.scanner-cand-name{font-size:11px;line-height:1.2;text-align:center;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
/* confirm panel */
.scanner-confirm{display:flex;gap:14px;align-items:flex-start;}
.scanner-add-row{display:flex;gap:8px;flex-wrap:wrap;}
.scanner-btn{background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.18);color:#fff;
  border-radius:9px;padding:9px 14px;font-size:14px;font-weight:600;cursor:pointer;}
.scanner-btn.primary{background:var(--accent,#e8c850);color:#1a1205;border-color:transparent;}
.scanner-btn:hover{filter:brightness(1.08);}
.scanner-owned{opacity:.7;font-weight:500;}
.scanner-added{color:var(--accent,#e8c850);font-size:13px;font-weight:600;margin-top:8px;}
.scanner-confirm-actions{display:flex;gap:16px;margin-top:12px;}
.scanner-link{background:none;border:none;color:rgba(255,255,255,0.75);text-decoration:underline;
  font-size:13px;cursor:pointer;padding:0;}
.scanner-link:hover{color:#fff;}
.scanner-msg{text-align:center;}
.scanner-msg-title{font-weight:700;font-size:18px;margin-bottom:6px;}
.scanner-msg-body{font-size:14px;color:rgba(255,255,255,0.7);max-width:420px;margin:0 auto 14px;line-height:1.5;}
.theme-toggle--scan.active{color:var(--accent);}

/* scanner v3: "locked on" ready state + confidence */
.scanner-hint.ready{color:#6ef08c;font-weight:700;}
.scanner-shutter.ready{border-color:#6ef08c;
  box-shadow:0 0 0 3px rgba(0,0,0,0.45) inset, 0 0 16px 3px rgba(110,235,150,0.75);
  animation:scanShutterPulse 1.1s ease-in-out infinite;}
@keyframes scanShutterPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
.scanner-lowconf{color:#f0b84a;font-weight:600;}

/* scanner v4: mode toggle + ambient "stack scan" (hover→ping→value→session list) */
.scanner-mode-seg{display:flex;gap:2px;background:rgba(255,255,255,0.12);border-radius:9px;padding:2px;}
.scanner-mode-btn{border:none;background:transparent;color:rgba(255,255,255,0.8);padding:6px 12px;
  border-radius:7px;font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;line-height:1;}
.scanner-mode-btn.active{background:var(--accent,#e8c850);color:#1a1320;}
.scanner-flash{position:absolute;inset:0;background:rgba(90,240,130,0.18);pointer-events:none;
  animation:scannerFlash .23s ease-out;}
@keyframes scannerFlash{from{opacity:1}to{opacity:0}}
.scanner-ambient{flex:0 0 auto;background:linear-gradient(0deg,#13111d,#0b0a12);
  padding:12px 14px calc(12px + env(safe-area-inset-bottom));
  display:flex;flex-direction:column;min-height:0;max-height:54vh;}
.scanner-amb-bar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:10px;}
.scanner-amb-now{display:flex;flex-direction:column;min-width:0;justify-self:start;}
.scanner-amb-now-name{font-size:13px;font-weight:700;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.scanner-amb-now-price{font-size:15px;font-weight:800;color:var(--accent,#e8c850);}
.scanner-amb-now-empty{font-size:13px;color:rgba(255,255,255,0.55);}
.scanner-amb-mid{justify-self:center;display:flex;align-items:center;gap:10px;}
.scanner-amb-add{display:flex;align-items:center;justify-content:center;
  font-size:40px;font-weight:300;color:#1a1205;line-height:1;padding:0;}
/* QA snap button (admin testing) — saves photo + reasoning, never stages. */
.scanner-amb-snap{display:inline-flex;align-items:center;gap:4px;font-size:19px;line-height:1;
  width:46px;height:46px;justify-content:center;border-radius:50%;
  background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.28);color:#fff;
  cursor:pointer;transition:background 0.12s,transform 0.08s;flex:0 0 auto;}
.scanner-amb-snap:hover{background:rgba(255,255,255,0.18);}
.scanner-amb-snap:active{transform:translateY(1px);}
.scanner-amb-snap-n{font-size:11px;font-weight:800;color:var(--accent,#e8c850);}
/* flashlight toggle (Android exposes torch; button hidden when unsupported) */
.scanner-torch{display:inline-flex;align-items:center;justify-content:center;font-size:17px;line-height:1;
  width:40px;height:40px;border-radius:50%;background:rgba(255,255,255,0.1);
  border:1px solid rgba(255,255,255,0.28);color:#fff;cursor:pointer;flex:0 0 auto;
  transition:background 0.12s,box-shadow 0.12s;}
.scanner-torch:hover{background:rgba(255,255,255,0.18);}
.scanner-torch.on{background:rgba(232,200,80,0.28);border-color:var(--accent,#e8c850);
  box-shadow:0 0 10px rgba(232,200,80,0.45);}
/* staged-row printing chip + review-time Non-Foil ⇄ Foil flip */
.scanner-session-pr{font-size:10px;font-weight:800;color:#1a1320;background:var(--accent,#e8c850);
  border-radius:4px;padding:0 4px;margin-left:5px;vertical-align:middle;letter-spacing:.02em;}
.scanner-session-foilbtn{background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.25);
  color:#fff;border-radius:7px;padding:5px 10px;font-size:11.5px;font-weight:700;cursor:pointer;
  font-family:inherit;margin-bottom:7px;}
.scanner-session-foilbtn:hover{background:rgba(255,255,255,0.18);}
/* QA-only testing layout. */
.scanner-qa-count{justify-self:end;font-size:11px;font-weight:700;color:rgba(255,255,255,0.7);white-space:nowrap;}
.scanner-qa-note{font-size:11px;line-height:1.45;color:rgba(255,255,255,0.6);text-align:center;
  padding:6px 8px;margin-top:8px;background:rgba(255,255,255,0.05);border-radius:7px;}
.scanner-qa-note b{color:#ffd86a;}
.scanner-qa-rowinfo{display:flex;flex-direction:column;align-items:flex-start;min-width:0;flex:1 1 auto;
  overflow:hidden;text-align:left;gap:2px;}
.scanner-qa-rowinfo .scanner-session-name{white-space:normal;max-width:100%;line-height:1.25;}
.scanner-qa-alts{font-size:10.5px;color:rgba(255,255,255,0.5);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;max-width:100%;}
/* point-snap-next rework: rows land instantly and resolve in place */
/* QA row: [your snap][matched card art][info][price] — side-by-side photo vs
   catalog art makes a wrong version obvious at a glance. The compound selector
   BEATS the later-defined base `.scanner-session-row` 5-column template (equal
   specificity → source order would otherwise win and the name floated in the
   staging grid's auto column, overlapping the card art). */
.scanner-session-row.scanner-qa-row{grid-template-columns:34px 34px minmax(0,1fr) auto;align-items:start;}
.scanner-qa-cardimg{border:1px solid rgba(232,200,80,0.55);}
.scanner-qa-cardimg.empty{display:inline-block;background:rgba(255,255,255,0.04);
  border:1px dashed rgba(255,255,255,0.15);}
.scanner-qa-row .scanner-session-price{white-space:nowrap;}
/* live bar: matched-card thumb inline with the name + price */
.scanner-amb-now:has(.scanner-amb-now-img){flex-direction:row;align-items:center;gap:8px;}
.scanner-amb-now-img{width:30px;height:42px;object-fit:cover;border-radius:4px;flex:0 0 auto;
  border:1px solid rgba(232,200,80,0.55);}
.scanner-qa-conf{display:inline-block;min-width:15px;text-align:center;border-radius:5px;
  font-size:10px;font-weight:800;padding:1px 3px;margin-right:4px;vertical-align:1px;}
.scanner-qa-conf.lock,.scanner-qa-conf.high{background:#6ef08c;color:#1a1320;}
.scanner-qa-conf.med{background:#e8c850;color:#1a1320;}
.scanner-qa-conf.low{background:rgba(255,255,255,0.18);color:rgba(255,255,255,0.75);}
.scanner-qa-pending{opacity:0.8;}
.scanner-qa-identifying{color:rgba(255,255,255,0.65);animation:scanner-qa-pulse 1.1s ease-in-out infinite;}
@keyframes scanner-qa-pulse{0%,100%{opacity:0.55;}50%{opacity:1;}}
.scanner-qa-thumb-empty{display:inline-block;}
/* tester review controls: per-row edit/confirm/foil/remove + review-&-save screen */
.scanner-qa-conf.user{background:#7ecbff;color:#1a1320;}
.scanner-qa-side{display:flex;flex-direction:column;align-items:flex-end;gap:3px;}
.scanner-qa-actions{display:flex;gap:4px;}
.scanner-qa-editbtn{width:26px;height:26px;border-radius:6px;border:1px solid rgba(255,255,255,0.25);
  background:rgba(255,255,255,0.08);color:rgba(255,255,255,0.85);font-size:12px;line-height:1;
  cursor:pointer;padding:0;font-family:inherit;}
.scanner-qa-editbtn:hover{background:rgba(255,255,255,0.16);}
.scanner-qa-delbtn{font-size:15px;}
.scanner-qa-delbtn:hover{color:#f0816a;}
.scanner-qa-savedchip{font-size:9.5px;font-weight:800;color:#6ef08c;white-space:nowrap;}
.scanner-qa-foilseg{display:inline-flex;margin-top:4px;border:1px solid rgba(255,255,255,0.22);
  border-radius:7px;overflow:hidden;width:max-content;}
.scanner-qa-foilbtn{border:none;background:transparent;color:rgba(255,255,255,0.6);font-size:10px;
  font-weight:700;padding:4px 9px;cursor:pointer;min-height:24px;font-family:inherit;}
.scanner-qa-foilbtn.on{background:var(--accent,#e8c850);color:#1a1320;}
.scanner-qa-pronly{font-size:10px;color:#e8c850;font-weight:700;margin-top:2px;}
.scanner-qa-row.editing{background:rgba(255,255,255,0.04);border-radius:8px;}
.scanner-qa-edit{grid-column:1 / -1;display:flex;flex-direction:column;gap:8px;
  padding:8px 2px 6px;border-top:1px dashed rgba(255,255,255,0.18);margin-top:4px;}
.scanner-qa-okbtn{align-self:flex-start;border:1px solid rgba(110,240,140,0.6);
  background:rgba(110,240,140,0.14);color:#6ef08c;font-weight:800;font-size:12px;
  border-radius:8px;padding:7px 14px;cursor:pointer;font-family:inherit;}
.scanner-qa-okbtn:hover{background:rgba(110,240,140,0.24);}
.scanner-qa-search{width:100%;box-sizing:border-box;background:rgba(255,255,255,0.07);
  border:1px solid rgba(255,255,255,0.25);border-radius:8px;color:#fff;font-size:13px;
  padding:8px 10px;font-family:inherit;}
.scanner-qa-search::placeholder{color:rgba(255,255,255,0.4);}
.scanner-qa-search-list{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto;}
.scanner-qa-search-row{display:grid;grid-template-columns:26px minmax(0,1fr) auto;gap:8px;
  align-items:center;background:rgba(255,255,255,0.05);border:1px solid transparent;
  border-radius:7px;padding:4px 6px;cursor:pointer;color:#fff;text-align:left;font-family:inherit;}
.scanner-qa-search-row:hover{border-color:rgba(232,200,80,0.55);}
.scanner-qa-search-row img{width:26px;border-radius:3px;display:block;}
.scanner-qa-search-name{font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.scanner-qa-search-meta{font-size:10px;color:rgba(255,255,255,0.5);white-space:nowrap;}
.scanner-qa-search-none{font-size:11.5px;color:rgba(255,255,255,0.55);}
/* review-&-save screen (replaces the camera stage while open) */
.scanner-qa-review{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:8px;
  padding:10px 14px calc(12px + env(safe-area-inset-bottom));background:linear-gradient(0deg,#13111d,#0b0a12);}
.scanner-qa-review-head{display:flex;align-items:center;gap:12px;flex:0 0 auto;}
.scanner-qa-review-head .scanner-session-total{margin-left:auto;}
.scanner-qa-review-tools{display:flex;align-items:center;gap:7px;flex-wrap:wrap;flex:0 0 auto;
  font-size:11px;color:rgba(255,255,255,0.6);}
.scanner-qa-flipall{border:1px solid rgba(255,255,255,0.25);background:rgba(255,255,255,0.08);
  color:#fff;font-size:11px;font-weight:700;border-radius:8px;padding:6px 11px;cursor:pointer;
  font-family:inherit;}
.scanner-qa-flipall:hover{background:rgba(255,255,255,0.16);}
.scanner-qa-review-list{flex:1 1 auto;}
.scanner-qa-unread{color:#f0b86a;font-style:italic;}
.scanner-qa-clear{color:rgba(255,255,255,0.55);}
.scanner-qa-clear.armed{color:#f0816a;font-weight:800;}
.scanner-saved-msg .scanner-link{color:inherit;text-decoration:underline;}
.scanner-qa-review-actions{display:flex;gap:8px;flex:0 0 auto;padding-top:8px;}
.scanner-qa-review-actions .scanner-btn{flex:1 1 auto;}
.scanner-qa-review .scanner-qa-note{margin-top:0;flex:0 0 auto;}
.scanner-shutter.locked{box-shadow:0 0 0 3px rgba(110,240,140,0.55),0 0 14px rgba(110,240,140,0.45);}
.scanner-amb-auto{justify-self:end;display:flex;align-items:center;gap:5px;font-size:11px;
  color:rgba(255,255,255,0.72);cursor:pointer;white-space:nowrap;}
.scanner-session{display:flex;flex-direction:column;min-height:0;flex:1 1 auto;
  border-top:1px solid rgba(255,255,255,0.1);margin-top:11px;}
.scanner-session-head{display:flex;align-items:center;gap:12px;padding:8px 2px;flex:0 0 auto;}
.scanner-session-count{font-weight:700;font-size:14px;color:#fff;}
.scanner-session-total{font-weight:800;font-size:15px;color:var(--accent,#e8c850);margin-left:auto;}
.scanner-session-head .scanner-link{margin-left:4px;}
.scanner-session-list{overflow-y:auto;flex:1 1 auto;min-height:0;}
.scanner-session-empty{color:rgba(255,255,255,0.5);font-size:12px;text-align:center;padding:16px 8px;line-height:1.55;}
.scanner-session-row{display:grid;grid-template-columns:34px minmax(0,1fr) auto auto auto;gap:9px;align-items:center;
  padding:5px 2px;border-bottom:1px solid rgba(255,255,255,0.06);}
.scanner-session-rm{background:none;border:none;color:rgba(255,255,255,0.4);font-size:18px;line-height:1;
  cursor:pointer;padding:2px 4px;}
.scanner-session-rm:hover{color:#f0816a;}
.scanner-save-btn{background:var(--accent,#e8c850);color:#1a1320;border:none;border-radius:8px;
  padding:7px 14px;font-size:13px;font-weight:800;cursor:pointer;font-family:inherit;margin-left:2px;}
.scanner-save-btn:hover{filter:brightness(1.08);}
.scanner-saved-msg{color:#6ef08c;font-size:13px;font-weight:700;text-align:center;padding:6px 0;}
.scanner-session-row.valuable{border-left:3px solid var(--accent,#e8c850);padding-left:6px;}
.scanner-session-thumb{width:34px;height:47px;object-fit:cover;border-radius:3px;background:#222;cursor:pointer;}
.scanner-session-name{font-size:12px;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;}
.scanner-session-qty{font-size:12px;color:rgba(255,255,255,0.7);}
.scanner-session-price{font-size:13px;font-weight:700;color:var(--accent,#e8c850);}
.scanner-session-alts{grid-column:1 / -1;padding:6px 0 4px;}
.scanner-session-alts-lbl{font-size:11px;color:rgba(255,255,255,0.6);margin-bottom:6px;}
/* ambient coaching banner (move closer / shiny) + text-confirmed badge */
.scanner-coach{position:absolute;left:50%;bottom:14px;transform:translateX(-50%);
  background:rgba(0,0,0,0.62);color:#fff;font-size:12px;font-weight:600;
  padding:6px 14px;border-radius:18px;max-width:90%;text-align:center;
  border:1px solid rgba(255,255,255,0.14);}
.scanner-amb-ok{font-size:10px;font-weight:700;color:#1a1320;background:#6ef08c;
  border-radius:5px;padding:1px 5px;margin-left:6px;vertical-align:middle;letter-spacing:.02em;}
.scanner-reviewlink{background:rgba(255,255,255,0.12);border:none;color:#fff;border-radius:7px;
  padding:6px 11px;font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;}
.scanner-reviewlink:hover{background:rgba(255,255,255,0.2);}

/* Scan Review panel (admin testing tool) */
.scanrev-overlay{position:fixed;inset:0;z-index:6001;display:flex;flex-direction:column;
  background:#0b0a12;color:#fff;
  padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);}
.scanrev-meta{display:flex;align-items:center;gap:12px;margin-left:auto;margin-right:10px;}
.scanrev-acc{font-size:13px;font-weight:700;color:var(--accent,#e8c850);white-space:nowrap;}
.scanrev-toggle{display:flex;align-items:center;gap:5px;font-size:11px;color:rgba(255,255,255,0.7);white-space:nowrap;cursor:pointer;}
.scanrev-body{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;padding:12px;overflow:auto;}
.scanrev-empty{color:rgba(255,255,255,0.6);text-align:center;font-size:15px;line-height:1.6;max-width:340px;}
.scanrev-card{display:flex;flex-direction:column;align-items:center;gap:14px;width:100%;max-width:420px;}
.scanrev-img-wrap{width:min(74vw,300px);aspect-ratio:5/7;border-radius:10px;overflow:hidden;background:#1a1a22;
  box-shadow:0 6px 20px rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center;}
.scanrev-img{width:100%;height:100%;object-fit:contain;background:#000;}
.scanrev-img-ph{color:rgba(255,255,255,0.4);font-size:13px;}
.scanrev-guess{text-align:center;font-size:14px;color:rgba(255,255,255,0.7);line-height:1.5;}
.scanrev-guess b{color:#fff;font-size:17px;}
.scanrev-tag{display:inline-block;font-size:10px;font-weight:700;border-radius:5px;padding:1px 6px;margin-left:6px;}
.scanrev-tag.r{background:#6ef08c;color:#13301d;}
.scanrev-tag.w{background:#f0816a;color:#3a1208;}
/* QA "thought process" panel — the scanner's full reasoning for a saved snap. */
.scanrev-debug{width:100%;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.12);
  border-radius:8px;font-size:11.5px;color:rgba(255,255,255,0.78);}
.scanrev-debug>summary{cursor:pointer;padding:7px 10px;font-weight:700;color:#fff;list-style:none;}
.scanrev-debug>summary::-webkit-details-marker{display:none;}
.scanrev-debug-conf{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:0.4px;
  color:var(--accent,#e8c850);margin-left:6px;}
.scanrev-debug-body{padding:0 10px 9px;display:flex;flex-direction:column;gap:5px;}
.scanrev-debug-row{line-height:1.45;word-break:break-word;}
.scanrev-debug-row b{color:#fff;}
.scanrev-debug-row i{color:rgba(255,255,255,0.6);}
.scanrev-debug-cands{margin:0;padding-left:18px;display:flex;flex-direction:column;gap:2px;}
.scanrev-debug-cands li.top{color:#fff;font-weight:700;}
.scanrev-debug-cands em{color:var(--accent,#e8c850);font-style:normal;font-size:10px;}
.scanrev-actions{display:flex;gap:12px;width:100%;}
.scanrev-btn{flex:1;border:none;border-radius:12px;padding:15px;font-size:16px;font-weight:800;cursor:pointer;font-family:inherit;}
.scanrev-btn.right{background:#6ef08c;color:#13301d;}
.scanrev-btn.wrong{background:rgba(240,129,106,0.18);color:#f0a48f;border:1px solid rgba(240,129,106,0.4);}
.scanrev-btn:hover{filter:brightness(1.08);}
.scanrev-btn:disabled{opacity:.5;cursor:default;}
.scanrev-pick{width:100%;display:flex;flex-direction:column;gap:8px;}
.scanrev-search{width:100%;box-sizing:border-box;background:var(--bg-modal,#1a1824);border:1px solid rgba(255,255,255,0.2);
  color:#fff;border-radius:9px;padding:11px 13px;font-size:14px;}
.scanrev-results{display:flex;flex-direction:column;gap:4px;max-height:38vh;overflow-y:auto;}
.scanrev-result{display:flex;align-items:center;gap:9px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);
  border-radius:8px;padding:5px 9px;cursor:pointer;color:#fff;font:inherit;font-size:13px;text-align:left;}
.scanrev-result:hover{background:rgba(232,200,80,0.16);border-color:var(--accent,#e8c850);}
.scanrev-result img,.scanrev-result-ph{width:28px;height:39px;object-fit:cover;border-radius:3px;background:#222;flex:0 0 auto;}
.scanrev-noresult{color:rgba(255,255,255,0.5);font-size:13px;padding:8px;text-align:center;}
.scanrev-foot{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px 16px calc(12px + env(safe-area-inset-bottom));border-top:1px solid rgba(255,255,255,0.1);}
.scanrev-pos{font-size:12px;color:rgba(255,255,255,0.55);}
.scanrev-link{background:none;border:none;color:rgba(255,255,255,0.8);font-size:13px;cursor:pointer;padding:6px 4px;font-family:inherit;}
.scanrev-link:hover{color:#fff;}
.scanrev-link:disabled{opacity:.4;cursor:default;}
.scanrev-cancel{align-self:center;}

/* ============================================================
   Season Review — standalone, link-only Elo season recap page
   (?season=<slug>). Self-contained palette so it renders
   correctly outside the app's data-theme system.
   ============================================================ */
html.season-standalone,html.season-standalone body{background:#0d0912;margin:0;}
.season-review{
  --sr-ink:#0d0912;--sr-ink2:#150e1f;--sr-card:#1c1428;--sr-line:#2c2137;--sr-line2:#3a2c4c;
  --sr-gold:#e7b74e;--sr-gold-hi:#f6d27a;--sr-gold-dim:#b58a3e;--sr-amethyst:#9a78ff;
  --sr-parch:#ece2cf;--sr-parch2:#cdc2b3;--sr-muted:#a196b0;--sr-muted2:#7a7089;
  --sr-gain:#6fc79a;--sr-loss:#d98f8f;
  --sr-serif:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,"Times New Roman",serif;
  --sr-sans:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  min-height:100dvh;color:var(--sr-parch);font-family:var(--sr-sans);line-height:1.55;
  -webkit-font-smoothing:antialiased;
  background:
    radial-gradient(1200px 620px at 50% -8%,rgba(154,120,255,0.10),transparent 60%),
    radial-gradient(900px 480px at 88% 2%,rgba(231,183,78,0.07),transparent 55%),
    var(--sr-ink);
  padding:0 clamp(14px,4vw,24px) 64px;
}
.season-review *{box-sizing:border-box}
.sr-inner{max-width:1120px;margin:0 auto}
.sr-tnum{font-variant-numeric:tabular-nums}

/* header */
.sr-header{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:18px 2px 8px;max-width:1120px;margin:0 auto}
.sr-brand{display:flex;align-items:center;gap:11px;text-decoration:none;color:inherit}
.sr-brand img{height:34px;width:auto;display:block}
.sr-brand .sr-brand-txt{font-family:var(--sr-serif);font-size:17px;color:var(--sr-parch);font-weight:600;letter-spacing:.01em}
.sr-badge{font-size:10.5px;text-transform:uppercase;letter-spacing:.22em;color:var(--sr-gold);
  border:1px solid var(--sr-gold-dim);border-radius:999px;padding:6px 13px;font-weight:600;white-space:nowrap}

/* hero */
.sr-hero{padding:26px 2px 6px}
.sr-eyebrow{display:flex;align-items:center;gap:10px;text-transform:uppercase;letter-spacing:.28em;
  font-size:11px;font-weight:600;color:var(--sr-gold);margin-bottom:16px}
.sr-dia{width:7px;height:7px;background:var(--sr-gold);transform:rotate(45deg);flex:0 0 auto;
  box-shadow:0 0 10px rgba(231,183,78,.5)}
.sr-rule{height:1px;background:linear-gradient(90deg,var(--sr-line2),transparent);flex:1;max-width:340px}
.sr-hero h1{font-family:var(--sr-serif);font-weight:600;font-size:clamp(34px,7vw,66px);line-height:1.0;
  letter-spacing:-.015em;margin:0;color:var(--sr-parch);text-wrap:balance}
.sr-hero h1 .amp{color:var(--sr-gold);font-style:italic;font-weight:500}
.sr-hero .sr-sub{font-family:var(--sr-serif);font-style:italic;font-size:clamp(16px,2.6vw,22px);
  color:var(--sr-gold-hi);margin:14px 0 0}
.sr-hero .sr-metaline{display:flex;flex-wrap:wrap;gap:6px 20px;margin-top:12px;color:var(--sr-muted);font-size:13.5px}
.sr-hero .sr-metaline b{color:var(--sr-parch2);font-weight:600}

/* section scaffolding */
.season-review section{margin-top:clamp(38px,6vw,60px)}
.sr-h2{font-family:var(--sr-serif);font-weight:600;font-size:clamp(20px,3vw,27px);margin:12px 0 4px;
  color:var(--sr-parch);text-wrap:balance}
.sr-h2-sub{color:var(--sr-muted);font-size:13.5px;margin:0 0 20px;max-width:62ch}

/* summary stat cards */
.sr-stats{display:grid;grid-template-columns:repeat(5,1fr);gap:12px}
.sr-stat{background:linear-gradient(180deg,var(--sr-card),var(--sr-ink2));border:1px solid var(--sr-line);
  border-radius:13px;padding:18px 14px 15px;text-align:center;position:relative;overflow:hidden}
.sr-stat::before{content:"";position:absolute;inset:0 0 auto 0;height:2px;
  background:linear-gradient(90deg,transparent,var(--sr-gold),transparent);opacity:.6}
.sr-stat .num{font-family:var(--sr-serif);font-weight:700;font-size:clamp(24px,4vw,34px);line-height:1;
  color:var(--sr-gold-hi);font-variant-numeric:tabular-nums}
.sr-stat .lab{margin-top:9px;font-size:10.5px;text-transform:uppercase;letter-spacing:.11em;
  color:var(--sr-parch2);font-weight:600}
.sr-stat .sub{margin-top:2px;font-size:11px;color:var(--sr-muted2)}

/* superlatives */
.sr-supers{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px}
.sr-super{background:var(--sr-ink2);border:1px solid var(--sr-line);border-left:3px solid var(--sr-gold);
  border-radius:12px;padding:15px 17px}
.sr-super .k{font-size:10.5px;text-transform:uppercase;letter-spacing:.13em;color:var(--sr-muted);font-weight:600}
.sr-super .who{font-family:var(--sr-serif);font-size:19px;color:var(--sr-gold-hi);font-weight:600;margin-top:5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sr-super .v{font-size:13px;color:var(--sr-parch2);margin-top:3px}
.sr-super .v b{color:var(--sr-parch);font-weight:700}

/* table */
.sr-tabletop{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px}
.sr-search{display:flex;align-items:center;gap:9px;background:var(--sr-ink2);border:1px solid var(--sr-line2);
  border-radius:999px;padding:9px 16px;flex:1;min-width:240px;max-width:420px}
.sr-search input{background:none;border:none;outline:none;color:var(--sr-parch);font-family:inherit;font-size:14px;flex:1;width:100%}
.sr-search input::placeholder{color:var(--sr-muted2)}
.sr-search .ic{color:var(--sr-gold);font-size:14px;flex:0 0 auto}
.sr-count{font-size:12.5px;color:var(--sr-muted);white-space:nowrap}
.sr-resetbtn{background:none;border:none;color:var(--sr-gold);font-family:inherit;font-size:12.5px;cursor:pointer;padding:0}
.sr-resetbtn:hover{text-decoration:underline}
.sr-tablewrap{overflow-x:auto;border:1px solid var(--sr-line);border-radius:14px;background:var(--sr-ink2)}
table.sr-table{border-collapse:collapse;width:100%;min-width:820px;font-variant-numeric:tabular-nums}
.sr-table thead th{position:sticky;top:0;background:var(--sr-ink2);font-family:var(--sr-sans);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.08em;color:var(--sr-muted);font-weight:600;text-align:right;
  padding:14px 12px 11px;border-bottom:1px solid var(--sr-line2);white-space:nowrap;cursor:pointer;user-select:none;z-index:2}
.sr-table thead th.l{text-align:left}
.sr-table thead th.nosort{cursor:default}
.sr-table thead th:hover:not(.nosort){color:var(--sr-gold)}
.sr-table thead th .arw{color:var(--sr-gold);margin-left:3px}
.sr-table tbody td{padding:10px 12px;font-size:13.5px;text-align:right;
  border-bottom:1px solid rgba(255,255,255,0.04);color:var(--sr-parch2)}
.sr-table tbody td.l{text-align:left}
.sr-table tbody tr:last-child td{border-bottom:none}
.sr-table tbody tr:hover td{background:rgba(255,255,255,0.025)}
.sr-table tbody tr.me td{background:rgba(231,183,78,0.09)}
.sr-rank{color:var(--sr-muted);font-family:var(--sr-serif);font-weight:700;width:38px}
.sr-rank.top{color:var(--sr-gold-hi)}
.sr-pname{font-family:var(--sr-serif);font-size:15px;color:var(--sr-parch);font-weight:600}
.sr-plat{font-size:10px;color:var(--sr-muted2);text-transform:uppercase;letter-spacing:.06em;margin-left:7px}
.sr-titles{color:var(--sr-gold-hi);font-weight:700}
.sr-z{color:var(--sr-muted2)}
.sr-pos{color:var(--sr-gain);font-weight:600}
.sr-neg{color:var(--sr-loss);font-weight:600}
.sr-empty{padding:40px 16px;text-align:center;color:var(--sr-muted);font-size:14px}

/* loading / error */
.sr-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px;color:var(--sr-muted)}
.sr-spin{width:34px;height:34px;border:3px solid var(--sr-line2);border-top-color:var(--sr-gold);
  border-radius:50%;animation:sr-spin 0.8s linear infinite}
@keyframes sr-spin{to{transform:rotate(360deg)}}

/* footer */
.sr-foot{margin-top:56px;padding-top:22px;border-top:1px solid var(--sr-line);display:flex;flex-wrap:wrap;
  justify-content:space-between;gap:12px;align-items:center;color:var(--sr-muted2);font-size:12px;max-width:1120px;margin-left:auto;margin-right:auto}
.sr-foot a{color:var(--sr-gold);text-decoration:none}
.sr-foot a:hover{text-decoration:underline}
.sr-foot .sr-fbrand{font-family:var(--sr-serif);color:var(--sr-gold);font-size:14px}
.sr-foot .sr-fbrand b{color:var(--sr-parch)}

@media (max-width:820px){
  .sr-stats{grid-template-columns:repeat(3,1fr)}
  .sr-supers{grid-template-columns:1fr}
}
@media (max-width:520px){
  .sr-stats{grid-template-columns:repeat(2,1fr)}
  .sr-badge{display:none}
}
@media (prefers-reduced-motion:reduce){.sr-spin{animation:none}}

/* ── Cold-boot error state (App bootFailed — catalog never loaded) ────── */
.boot-error{max-width:440px;margin:56px auto 80px;text-align:center;padding:34px 26px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:14px}
.boot-error-logo{height:92px;width:auto;margin-bottom:12px}
.boot-error h2{margin:0 0 10px;font-size:20px}
.boot-error p{font-size:13px;line-height:1.55;margin:0 0 18px}
.boot-error-retry{background:var(--accent);color:#17110a;border:none;border-radius:8px;
  padding:9px 22px;font-size:14px;font-weight:700;cursor:pointer}
.boot-error-retry:hover{filter:brightness(1.08)}
.boot-error-detail{margin-top:14px;font-size:11px;opacity:.65;word-break:break-word}

/* ── 2026-07-14 launch UX review additions ───────────────────────────── */
/* Cold-boot loading card (App bootLoading — first visit, catalog in flight) */
.boot-loading-spinner{width:28px;height:28px;margin:2px auto 14px;border-radius:50%;
  border:3px solid var(--border);border-top-color:var(--accent);
  animation:bootspin 0.9s linear infinite}
@keyframes bootspin{to{transform:rotate(360deg)}}

/* Signed-in-but-empty collection CTA */
.collection-empty-cta{max-width:520px;margin:18px auto;text-align:center;padding:26px 22px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:14px}
.collection-empty-cta h3{margin:0 0 8px;font-size:18px}
.collection-empty-cta p{font-size:13px;margin:0 0 14px}
.collection-empty-cta-actions{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.collection-empty-cta-actions button{padding:9px 18px;font-size:13px}

/* One-tap collection quick-add on browse tiles (signed-in, browser mode).
   Hover-reveal on desktop like the magnify button; always visible on touch. */
.tile-quickadd-btn{position:absolute;right:6px;bottom:34px;width:24px;height:24px;
  border-radius:50%;border:1px solid var(--border-accent);background:var(--bg-modal);
  color:var(--accent);font-size:16px;font-weight:700;line-height:1;padding:0;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  opacity:0;pointer-events:none;transition:opacity 0.12s,background 0.12s}
.card-tile:hover .tile-quickadd-btn,.card-tile:focus-within .tile-quickadd-btn{
  opacity:0.92;pointer-events:auto}
.tile-quickadd-btn:hover{background:var(--accent);color:var(--bg-solid)}
@media (hover:none){.tile-quickadd-btn{opacity:0.92;pointer-events:auto}}

/* Small ⓘ glyph used inside Tip triggers (EV strip, Master Set label). */
.tip-info-glyph{font-size:11px;opacity:0.65;cursor:help}

/* Consistent keyboard focus ring — previously only 4 ad-hoc :focus-visible
   rules existed; default browser rings were inconsistent across controls. */
button:focus-visible,a:focus-visible,[role="button"]:focus-visible,
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.card-tile:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ── Offline mode ─────────────────────────────────────────────────────────
   Persistent pill shown while navigator.onLine is false. Fixed to the
   bottom-center (above the deck editor's mobile tab bar when present),
   opaque background so it reads over any scrolled content, safe-area aware. */
.offline-pill{position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(14px + env(safe-area-inset-bottom));z-index:120;
  background:var(--bg-modal);border:1px solid var(--border-accent);
  color:var(--accent);border-radius:999px;padding:7px 16px;
  font-size:12px;font-weight:600;letter-spacing:0.02em;white-space:nowrap;
  box-shadow:0 4px 14px rgba(0,0,0,0.35);pointer-events:none}
body:has(.deck-editor-mobile-tabs) .offline-pill{
  bottom:calc(74px + env(safe-area-inset-bottom))}

/* Offline image pack (settings popover) */
.offline-img-actions{display:flex;flex-direction:column;gap:6px;align-items:stretch}
.offline-img-progress{display:flex;flex-direction:column;gap:6px}
.offline-img-bar{height:8px;border-radius:999px;background:var(--bg-surface);
  border:1px solid var(--border);overflow:hidden}
.offline-img-bar-fill{height:100%;background:var(--accent);border-radius:999px;
  transition:width 0.25s ease}
.offline-img-meta{font-size:11px;display:flex;align-items:center;gap:8px;
  flex-wrap:wrap;line-height:1.5}
.offline-img-meta .settings-action.link{padding:0;font-size:11px}
