@import url('/static/fonts.css');

:root {
  /* ── Redesign: cool near-black surfaces + refined gold ── */
  /* Surfaces (layered) */
  --bg:            #0a0c11;
  --surface-0:     #0e1117;
  --surface-1:     #141823;
  --surface-2:     #1b2030;
  --surface-3:     #232a3c;
  --line:          #262d3d;
  --line-soft:     #1c2230;

  /* Semantic surface aliases (existing names → new palette) */
  --panel:         #141823;
  --panel-hover:   #1b2030;
  --border:        #262d3d;
  --border-hover:  #38415a;

  /* Text */
  --text:          #eef1f7;
  --text-2:        #aeb7c8;
  --muted:         #6f7a90;
  --faint:         #3a4254;

  /* Brand — refined gold (replaces the old purple accent) */
  --gold:          #f2c14e;
  --gold-deep:     #d9a637;
  --gold-soft:     #3a2f12;
  --accent:        #f2c14e;
  --accent-dim:    #d9a637;
  --accent-glow:   rgba(242,193,78,0.20);
  --accent-subtle: rgba(242,193,78,0.08);

  /* TradeupSpy filter controls: cool-slate translucent border, transparent fill */
  --filter-border:       rgba(101,136,156,0.22);
  --filter-border-hover: rgba(101,136,156,0.42);
  --filter-fill:         rgba(101,136,156,0.06);

  /* Verdict */
  --green:         #34d99b;
  --green-glow:    rgba(52,217,155,0.14);
  --red:           #ff6b6b;
  --red-glow:      rgba(255,107,107,0.13);

  /* Rarity (CS2 tiers) */
  --r-consumer:    #b0b6c4;
  --r-industrial:  #6aa0d8;
  --r-milspec:     #4b69ff;
  --r-restricted:  #8847ff;
  --r-classified:  #d32ee6;
  --r-covert:      #eb4b4b;
  --r-contraband:  #e4ae39;
  --r-gold:        #ffd06b;

  /* Shared 40%-alpha gold border, used by both the markets toggle-pill and
     the dashboard bar chart — was inlined as rgba(242,193,78,0.4) in both
     places before this pass. Named as if it tracks --accent, so it MUST be
     overridden alongside --accent/--accent-subtle in the light theme below
     (missed on first pass: a light-theme enabled toggle-pill got dark-theme
     gold on a light-gold fill; verified with getComputedStyle). */
  --accent-border-40: rgba(242,193,78,0.4);

  /* Dashboard bar-chart mark colour — a distinct name from --accent so a
     future chart-only palette change doesn't also recolor buttons/links.
     Solid (not the ~8%-opacity --accent-subtle wash) because a lone bar mark
     needs ≥3:1 contrast against the panel on its own, per the dataviz skill;
     validated at 10.6:1 (scripts/validate_palette.js contrast()). */
  --chart-1:       var(--accent);

  --shadow-sm:     0 2px 8px rgba(0,0,0,0.45);
  --shadow-md:     0 8px 24px -12px rgba(0,0,0,0.7);
  --shadow-lg:     0 24px 60px -20px rgba(0,0,0,0.8);
  --radius-sm:     6px;
  --radius-md:     10px;
  --radius-lg:     14px;
  --transition:    0.15s ease;

  --font-ui:       "Archivo", "Segoe UI", system-ui, sans-serif;
  --font-num:      "IBM Plex Mono", ui-monospace, monospace;

  /* Aliases used by skin_detail.html */
  --text-dim:      #6f7a90;   /* same as --muted */
  --surface:       #0e1117;   /* darkest layered surface */
}

/* Light theme (toggle in the header; persisted in localStorage) */
/* Nav bar surface + the active nav pill — dark defaults, overridden for light below.
   These are the values that were tuned against a permanently-dark bar. */
:root {
  --header-bg:         rgba(12,14,19,0.92);
  --nav-active-fg:     var(--accent);
  --nav-active-border: rgba(242,193,78,0.3);
}

html[data-theme="light"] {
  --bg:            #f4f3f9;
  --panel:         #ffffff;
  --panel-hover:   #f0edf8;
  --border:        #e4e1ef;
  --border-hover:  #d2cce6;
  --text:          #1b1828;
  --text-2:        #45506a;
  --muted:         #71708f;
  --accent:        #c08a1e;
  --accent-dim:    #a8761a;
  --gold:          #c08a1e;
  --gold-deep:     #a8761a;
  --accent-glow:   rgba(192,138,30,0.18);
  --accent-subtle: rgba(192,138,30,0.09);
  --accent-border-40: rgba(192,138,30,0.4);
  --filter-border:       rgba(70,100,120,0.32);
  --filter-border-hover: rgba(70,100,120,0.55);
  --filter-fill:         rgba(70,100,120,0.05);
  --green:         #119a6a;
  --green-glow:    rgba(17,154,106,0.12);
  --red:           #dc4646;
  --red-glow:      rgba(220,70,70,0.10);
  --shadow-sm:     0 2px 8px rgba(20,16,40,0.08);
  --shadow-md:     0 4px 20px rgba(20,16,40,0.12);
  --shadow-lg:     0 8px 40px rgba(20,16,40,0.16);
  --text-dim:      #71708f;
  --surface:       #ffffff;
  --surface-0:     #f4f3f9;
  --surface-1:     #ffffff;
  --surface-2:     #f0edf8;
  --surface-3:     #e7e3f1;
  --line:          #e4e1ef;
  --line-soft:     #eeebf6;
  --header-bg:     rgba(255,255,255,0.92);
  /* Darker than --accent so the label clears AA on the pale --accent-subtle pill
     (measured 4.88:1, vs 2.77:1 for --accent); border themed so the pill has an edge. */
  --nav-active-fg:     #8a6410;
  --nav-active-border: var(--accent-border-40);
}
html[data-theme="light"] ::-webkit-scrollbar-thumb { background: #cfc9e6; }

* { box-sizing: border-box; margin: 0; padding: 0; }

::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-hover); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: var(--muted); }

body {
  font-family: var(--font-ui);
  /* Subtle gold "spotlight" depth behind the top of every page, fading into the
     near-black surface — premium ambience without washing out content. */
  background: radial-gradient(940px 520px at 50% -140px, rgba(242,193,78,0.06), transparent 70%), var(--bg);
  background-attachment: fixed;
  color: var(--text);
  min-height: 100vh;
  line-height: 1.5;
  letter-spacing: -0.01em;
  /* Deliberately NOT setting -webkit-font-smoothing: antialiased. On macOS that
     switches text off subpixel (LCD) antialiasing onto grayscale, which renders
     glyphs thinner and visibly rougher — worst on non-Retina desktop displays,
     where it reads as "pixelated". It is a no-op on Windows and redundant on
     mobile, so it only ever cost us quality. The browser default
     (subpixel-antialiased) is correct; please don't re-add it.
     text-rendering: optimizeLegibility is likewise dropped — MDN advises against
     it site-wide (it can degrade rendering and trip kerning/ligature bugs). */
}
/* Light theme: drop the glow (gold-on-light reads muddy) — flat surface only. */
html[data-theme="light"] body { background: var(--bg); }
::selection { background: rgba(242,193,78,0.26); color: #0a0c11; }

/* Numeric / data text uses the mono face (prices, ROI, stats). */
.num, .v, .stat-value, .price, .roi { font-family: var(--font-num); font-feature-settings: "tnum" 1; letter-spacing: -0.02em; }

/* ── Header ── */
header {
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
  height: 56px;
  display: flex;
  align-items: center;
  gap: 16px;
  /* Themed, not hardcoded. This was a flat rgba(12,14,19,0.92) with no light-theme
     override, so in light mode the bar stayed dark while --text flipped to near-black:
     .header-logo-title measured 1.11:1 against it — the wordmark was invisible, not
     merely low-contrast. Everything in the bar draws from theme vars, so the bar has
     to as well. */
  background: var(--header-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  position: sticky;
  top: 0;
  z-index: 200;
}

.header-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex-shrink: 0;
}
.header-logo-icon {
  width: 30px;
  height: 30px;
  background: linear-gradient(135deg, var(--accent), var(--accent-dim));
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 800;
  color: #fff;
  letter-spacing: -0.5px;
  flex-shrink: 0;
  box-shadow: 0 0 16px var(--accent-glow);
}
.header-logo-text { display: flex; flex-direction: column; }
.header-logo-title { font-size: 0.92rem; font-weight: 700; color: var(--text); letter-spacing: -0.01em; line-height: 1; }
.header-logo-sub { font-size: 0.62rem; color: var(--muted); margin-top: 2px; line-height: 1; }

.badge-live {
  font-size: 0.62rem;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 99px;
  border: 1px solid rgba(242,193,78,0.3);
  background: rgba(242,193,78,0.08);
  color: var(--accent);
  letter-spacing: 0.03em;
  flex-shrink: 0;
}

/* Mobile filter toggle */
.filter-toggle {
  display: none;
  align-items: center;
  gap: 6px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 7px 13px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color var(--transition);
}
.filter-toggle:hover { border-color: var(--border-hover); }
.filter-toggle svg { width: 15px; height: 15px; stroke: var(--muted); }

/* ── Drawer overlay ── */
.drawer-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.65);
  z-index: 149;
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.drawer-overlay.visible { display: block; }

/* ── Layout ── */
.layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  min-height: calc(100vh - 56px);
}
/* Collapsed (filters hidden) on desktop — content takes the full width */
.layout.sidebar-hidden { grid-template-columns: 1fr; }
.layout.sidebar-hidden > aside { display: none; }

aside {
  border-right: 1px solid var(--border);
  padding: 0 14px 80px;
  background: var(--panel);
  overflow-y: auto;
  position: sticky;
  top: 56px;
  height: calc(100vh - 56px);
}

/* Centred content column */
main { padding: 20px 24px; overflow-y: auto; width: 100%; max-width: 1200px; margin-inline: auto; }

/* Filter toggle is hidden on desktop (the sidebar is always shown); it returns
   on mobile (≤640px) as the only way to open the filter drawer. */
.filter-toggle { display: none; }

/* ── Sidebar sections ── */
/* Each section is a <details class="section"> whose <summary class="section-title">
   is the clickable header (see index.html). Native disclosure gives keyboard
   support and a working sidebar with JS disabled; finder-filters.js only
   persists the open/closed state and fills the badge. */
.section {
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.section:last-of-type { border-bottom: none; }

.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.64rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  list-style: none;               /* drop the native disclosure triangle … */
  transition: color var(--transition);
}
.section-title::-webkit-details-marker { display: none; }   /* … Safari/older Chrome */
.section-title:hover { color: var(--accent); }
.section-title:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Count of non-default filters inside a section — visible while collapsed, so
   a folded-away filter can never silently shape the results. */
.section-badge {
  min-width: 16px;
  padding: 0 5px;
  border-radius: 8px;
  background: var(--accent);
  color: #14110a;
  font-size: 0.6rem;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
  letter-spacing: 0;
}

/* Chevron sits hard right and rotates with the open state. */
.section-title .chev {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--muted);
  transition: transform 0.2s;
}
.section[open] > .section-title .chev { transform: rotate(90deg); }

.section-body { padding-top: 12px; }

/* ── Form controls ── */
label {
  display: block;
  font-size: 0.64rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-2);
  margin-bottom: 6px;
  margin-top: 12px;
  text-align: center;
}
label:first-child { margin-top: 0; }
/* Inline toggle/checkbox labels opt out of the centered field-label styling */
.toggle-pill, .source-row label, .st-label, .arb-toggle, .arb-mkt-opt {
  margin-top: 0;
  margin-bottom: 0;
  text-align: left;
}

input, select {
  width: 100%;
  padding: 9px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--filter-border);
  background: var(--filter-fill);
  color: var(--text);
  font-size: 0.82rem;
  font-family: inherit;
  transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
  outline: none;
}
input:hover, select:hover { border-color: var(--filter-border-hover); }
input:focus, select:focus {
  border-color: var(--accent);
  background: var(--surface-1);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
input::placeholder { color: var(--muted); font-style: italic; }

/* TradeupSpy-style custom dropdown caret on filter selects */
aside select,
.filter-row select,
.section select,
.picker-filterbar select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236f7a90' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  cursor: pointer;
}

/* Native checkboxes / radios pick up the gold accent (was the browser default). */
input[type="checkbox"], input[type="radio"] { width: auto; accent-color: var(--accent); }

.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px; }
.row2 label { margin-top: 0; }

/* ── Toggle pill ── */
.toggle-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  flex-shrink: 0;
  user-select: none;
}
.toggle-pill input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-pill .track {
  width: 36px; height: 20px;
  background: var(--border);
  border-radius: 10px;
  position: relative;
  transition: background var(--transition), box-shadow var(--transition);
  border: 1px solid var(--border-hover);
  flex-shrink: 0;
}
.toggle-pill input:checked + .track {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 8px var(--accent-glow);
}
.toggle-pill .thumb {
  position: absolute;
  width: 12px; height: 12px;
  background: var(--muted);
  border-radius: 50%;
  top: 3px; left: 3px;
  transition: transform var(--transition), background var(--transition);
}
.toggle-pill input:checked + .track .thumb {
  transform: translateX(16px);
  background: #fff;
}

/* ── Source rows ── */
.source-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  font-size: 0.8rem;
}
.source-name { flex: 1; }
.hint {
  font-size: 0.63rem;
  color: var(--muted);
  line-height: 1.5;
  margin-top: 4px;
}

/* ── Segmented control (pricing source) ── */
.seg {
  display: flex;
  gap: 4px;
  background: var(--filter-fill);
  border: 1px solid var(--filter-border);
  border-radius: var(--radius-md);
  padding: 4px;
}
.seg button {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--text-2);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 6px 6px;
  border-radius: calc(var(--radius-md) - 3px);
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
  white-space: nowrap;
}
.seg button:hover { color: var(--text); background: rgba(101,136,156,0.12); }
.seg button.active {
  background: var(--accent);
  color: #14110a;
  box-shadow: 0 0 10px var(--accent-glow);
}
.seg button.active:hover { background: var(--accent); color: #14110a; }
.seg button.active.custom {
  background: var(--accent-subtle);
  color: var(--accent);
  box-shadow: none;
}

.adv-toggle {
  margin-top: 12px;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  transition: color var(--transition);
}
.adv-toggle:hover { color: var(--text); }
.adv-toggle .chev { display: inline-block; transition: transform 0.2s; }
.adv-toggle.open .chev { transform: rotate(90deg); }

/* Per-row pricing source badge */
.src-badge {
  font-size: 0.58rem;
  font-weight: 700;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0 4px;
  margin-left: 4px;
  vertical-align: middle;
}
.src-badge.missing { color: var(--red); border-color: var(--red); opacity: 0.8; }

/* ── Chip / applied-filter chips ── */
/* One chip per non-default filter, above the results. The whole chip is the
   remove button (a 4px "×" hit target is unusable on a phone), so it gets
   button affordances rather than a nested control. */
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 14px;
}
.filter-chips[hidden] { display: none; }

.chips-label {
  font-size: 0.6rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-right: 2px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--accent-subtle, var(--border));
  border-radius: 999px;
  background: var(--surface-1);
  color: var(--text);
  font-family: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--transition), background var(--transition), color var(--transition);
}
.chip:hover { border-color: var(--red); color: var(--red); }
.chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.chip .chip-x {
  font-size: 0.95rem;
  line-height: 1;
  color: var(--muted);
  transition: color var(--transition);
}
.chip:hover .chip-x { color: var(--red); }

/* Clear-all and copy-link are actions, not removable filters — neutral hover. */
.chip-clear, .chip-share { color: var(--text-2); }
.chip-clear:hover, .chip-share:hover { border-color: var(--accent); color: var(--accent); }

/* ── Hero section ── */
.hero-section {
  margin-bottom: 24px;
}
.hero-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 14px;
  gap: 12px;
}
.hero-title {
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
}
.hero-subtitle {
  font-size: 0.72rem;
  color: var(--muted);
}
.hero-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.hero-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition), transform 0.1s;
}
.hero-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
  opacity: 0.7;
}
.hero-card.hero-profit { border-left: 3px solid var(--green); }
.hero-card.hero-loss   { border-left: 3px solid var(--red); }
.hero-card:hover {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-glow), 0 4px 24px rgba(0,0,0,0.5);
  transform: translateY(-2px);
}
.hero-card-name {
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.4;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hero-card-meta {
  font-size: 0.64rem;
  color: var(--muted);
  margin-bottom: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hero-metrics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 12px;
}
.hero-metric-label {
  font-size: 0.55rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 2px;
}
.hero-metric-value {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}
.hero-metric-value.positive { color: var(--green); }
.hero-metric-value.negative { color: var(--red); }
.hero-rank {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent-subtle);
  border: 1px solid var(--accent-glow);
  color: var(--accent);
  font-size: 0.65rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── Stats bar ── */
.stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}
.stat {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 13px;
  transition: border-color var(--transition);
}
.stat:hover { border-color: var(--border-hover); }
.stat .k { font-size: 0.56rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.07em; }
.stat .v { font-size: 1.1rem; font-weight: 700; margin-top: 3px; letter-spacing: -0.01em; }

/* ── Section divider ── */
.results-section-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.results-section-title {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
}
.results-divider {
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ── Status bar ── */
.status {
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  background: var(--panel);
  border: 1px solid var(--border);
  font-size: 0.8rem;
  margin-bottom: 10px;
  color: var(--muted);
}

/* ── Progress bar ── */
.progress-wrap { margin-bottom: 14px; }
.progress-track {
  height: 3px;
  background: var(--border);
  border-radius: 99px;
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  width: 0%;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--accent), #c084fc);
  transition: width 0.35s ease;
  box-shadow: 0 0 8px var(--accent-glow);
}
.progress-fill.indeterminate {
  width: 30%;
  animation: progress-slide 1.5s ease-in-out infinite;
}
@keyframes progress-slide {
  0%   { margin-left: 0%;   width: 30%; }
  50%  { margin-left: 60%;  width: 30%; }
  100% { margin-left: 0%;   width: 30%; }
}
.progress-label {
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: 5px;
  text-align: right;
}

/* ── Result cards ── */
.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: 5px;
  overflow: hidden;
  border-left: 3px solid var(--border);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.card.profit { border-left-color: var(--green); }
.card.loss   { border-left-color: var(--red); }
.card:hover  { border-color: var(--border-hover); }
.card.highlighted {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-glow);
}

.card-head {
  padding: 11px 14px;
  cursor: pointer;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
  transition: background var(--transition);
}
.card-head:hover   { background: var(--panel-hover); }
.card.open .card-head { background: var(--panel-hover); }

.card-title { font-weight: 600; font-size: 0.88rem; letter-spacing: -0.01em; }
.card-meta  { font-size: 0.66rem; color: var(--muted); margin-top: 2px; }

/* The card's ONE metrics row. It stays mounted and in place when the card is
   opened — an earlier version hid it and revealed a second, larger copy inside
   the body, so the numbers a user was reading were destroyed and redrawn at a
   different size while every card below jumped. Fixed min-widths plus tabular
   figures keep the cells from reflowing as digits change. */
.metrics {
  display: flex;
  gap: 12px;
  font-size: 0.82rem;
  text-align: right;
  flex-shrink: 0;
  align-items: center;
  font-variant-numeric: tabular-nums;
}
.metrics > div { display: flex; flex-direction: column; min-width: 58px; }
/* Label styling is bound to .mlabel, never to "any span inside .metrics" — the
   values are spans too, and the uppercase/letter-spacing used to leak onto
   them. Values inherit the row's size; only the label is small. */
.metrics .mlabel { display: block; font-size: 0.56rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.metrics .mval   { display: block; font-size: inherit; }

/* Expansion animates the row height (0fr -> 1fr) instead of flipping `display`,
   so the cards below slide rather than teleport. The wrapper owns the collapse;
   the body itself is always laid out, just clipped to zero height when closed. */
.card-body-wrap {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 220ms ease;
}
.card.open .card-body-wrap { grid-template-rows: 1fr; }

.card-body {
  display: grid;
  grid-template-columns: 1fr;          /* Inputs section above, Outputs below */
  gap: 10px;
  padding: 0 14px;
  background: var(--bg);
  font-size: 0.78rem;
  min-height: 0;                        /* required for the 0fr row to collapse */
  overflow: hidden;
}
/* Padding and the divider live on the open state only — a closed card must
   collapse to exactly zero height, and a border would still paint at 0fr. */
.card.open .card-body { padding: 10px 14px; border-top: 1px solid var(--border); }

@media (prefers-reduced-motion: reduce) {
  .card-body-wrap { transition: none; }
}

/* ── Result density: cards vs table ──────────────────────────────────────────
   Both densities render the SAME cards. Table mode is a class on #results that
   re-lays the card head into one aligned row, so expanding, saving, logging and
   the outcome grid all keep working and there is no second render path.
   `--row-grid` is defined once and shared by the column header and every row —
   two copies would drift apart the first time a column is resized.

   Every column is a fixed width except the contract name. The action column in
   particular must NOT be `auto`: it resolves to 0 in the header's empty cell
   and ~113px in a real row, which slides every number out from under its
   label. */
body[data-page="index"] main { --row-grid: minmax(0, 1fr) 72px 72px 84px 70px 116px; }

.results-toolbar { display: flex; justify-content: flex-end; margin: 0 0 6px; }
.results-toolbar[hidden] { display: none; }

.density-toggle {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--panel);
}
.density-btn {
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.68rem;
  font-weight: 600;
  padding: 4px 10px;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.density-btn + .density-btn { border-left: 1px solid var(--border); }
.density-btn:hover { background: var(--panel-hover); color: var(--text); }
.density-btn.on { background: var(--accent-subtle); color: var(--text); }

/* Column labels. Padding matches a row's content box: the card's 3px left
   accent border + 12px head padding on the left, 12px + 1px border right. */
.results-thead {
  display: grid;
  grid-template-columns: var(--row-grid);
  gap: 10px;
  align-items: center;
  padding: 2px 13px 4px 15px;
  font-size: 0.56rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}
.results-thead[hidden] { display: none; }
.results-thead > span + span { text-align: right; }

/* Table mode only exists at tablet width and up — a six-column row is
   unreadable on a phone, so narrow screens stay on cards no matter what the
   stored preference says. */
@media (min-width: 641px) {
  /* Rows butt against each other: one shared separator, square middles. */
  #results.table-mode .card { margin-bottom: 0; border-radius: 0; border-top-width: 0; }
  #results.table-mode .card:first-child {
    border-top-width: 1px;
    border-top-left-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
  }
  #results.table-mode .card:last-child {
    border-bottom-left-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
  }

  #results.table-mode .card-head { grid-template-columns: var(--row-grid); padding: 6px 12px; gap: 10px; }
  /* `display: contents` promotes the four metric cells and the action row into
     the head's own grid, so they land in the columns the header names — without
     a second markup shape for table mode. */
  #results.table-mode .metrics { display: contents; }
  #results.table-mode .metrics > div { display: block; min-width: 0; text-align: right; }
  #results.table-mode .metrics .mlabel { display: none; }

  /* Title + meta collapse onto one line and truncate rather than wrap. */
  #results.table-mode .card-head > div:first-child {
    display: flex; align-items: baseline; gap: 8px; min-width: 0;
  }
  #results.table-mode .card-title {
    font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  #results.table-mode .card-meta {
    margin-top: 0; flex: 0 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }

  #results.table-mode .card-acts { gap: 4px; justify-content: flex-end; overflow: hidden; }
  #results.table-mode .card-act-btn { padding: 3px 7px; font-size: 0.66rem; }

  /* A locked Pro row has only two metrics, so it cannot fill the six columns —
     keep it on the card head's own layout instead of misaligning the grid. */
  #results.table-mode .card.locked .card-head { grid-template-columns: 1fr auto; }
  #results.table-mode .card.locked .metrics { display: flex; }
  #results.table-mode .card.locked .metrics > div { display: flex; flex-direction: column; min-width: 58px; }
  #results.table-mode .card.locked .metrics .mlabel { display: block; }
}

/* Per-contract risk / outcome strip. Carries the divider the (removed) duplicate
   metrics bar used to draw between the Inputs and Outputs sections. */
.risk-strip { margin: 2px -14px; padding: 8px 14px 6px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.risk-stats {
  display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center;
  font-size: 0.7rem; color: var(--muted); margin-bottom: 5px;
}
.risk-win { font-weight: 700; }
.risk-win.good { color: var(--green); }
.risk-win.mid { color: #e0a23a; }
.risk-win.bad { color: var(--red); }
.risk-bar {
  display: flex; height: 7px; border-radius: 4px; overflow: hidden;
  background: #0d0b14; border: 1px solid var(--border);
}
.risk-seg { height: 100%; min-width: 1px; }
.risk-seg.win  { background: var(--green); }
.risk-seg.lose { background: var(--red); }
.risk-seg + .risk-seg { box-shadow: -1px 0 0 rgba(0,0,0,0.25); }

/* Section header (Inputs / Outputs) */
.sk-section-head {
  font-weight: 600;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.sk-count {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--text);
  background: var(--panel-hover);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 7px;
}
/* Names the outcome list's ordering. Without it, a 3%-chance skin sitting
   above a 60%-chance one reads as a bug rather than as the point. */
.sk-sort-note {
  font-size: 0.6rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
  border-bottom: 1px dotted var(--border-hover);
  cursor: help;
}

/* Items laid out next to each other in a responsive grid of tiles */
.sk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
}

/* ── Skin tile (reference card style) ───────────────────────────────────── */
.tile {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel);
  overflow: hidden;
  transition: border-color var(--transition), transform var(--transition);
}
.tile:hover { border-color: var(--accent); transform: translateY(-1px); }

.tile-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 6px;
  padding: 8px 10px 5px;
}
.tile-name { display: flex; flex-direction: column; line-height: 1.18; min-width: 0; }
.tile-weapon { font-weight: 700; font-size: 0.82rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile-finish { font-size: 0.72rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile-corner { font-size: 0.72rem; font-weight: 700; color: var(--muted); flex-shrink: 0; padding-top: 1px; }
.tile-corner.prob { color: var(--accent); }

.tile-img-wrap {
  position: relative;
  padding: 6px 10px;
  min-height: 92px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tile-img, .tile-img-ph {
  width: 100%;
  height: 92px;
  object-fit: contain;
}
.tile-img-ph { background: #050409; border-radius: 6px; }

.tile-badge {
  position: absolute;
  top: 2px;
  left: 10px;
  font-size: 0.54rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: 3px;
  z-index: 1;
}
.tile-badge.st { background: #b85c00; color: #fff; }
.tile-badge.sv { background: #c97f00; color: #1a1206; }

.tile-mkts {
  position: absolute;
  top: 2px;
  right: 6px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  z-index: 1;
}
.tile-mkt {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 8, 18, 0.72);
  border: 1.5px solid transparent;
  overflow: hidden;
  transition: transform var(--transition), border-color var(--transition);
}
.tile-mkt:hover { transform: scale(1.12); }
.tile-mkt.cheapest { border-color: var(--green); }
.tile-mkt.steam { border-color: #4a90d9; }
.tile-mkt-logo { width: 13px; height: 13px; object-fit: contain; }
.tile-mkt .cmkt-abbr { font-size: 0.5rem; font-weight: 700; color: var(--text); }

.tile-watch {
  position: absolute; top: 2px; left: 50%; transform: translateX(-50%);
  width: 24px; height: 22px; padding: 0; z-index: 2;
  background: rgba(10,8,18,0.6); border: 1px solid var(--border); border-radius: 5px;
  color: var(--muted); cursor: pointer; display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity var(--transition), color var(--transition), border-color var(--transition);
}
.tile:hover .tile-watch { opacity: 1; }
.tile-watch svg { width: 13px; height: 13px; }
.tile-watch:hover { color: var(--text); border-color: var(--accent); }
.tile-watch.on { opacity: 1; color: #e0a23a; border-color: #e0a23a; }
.tile-watch.on svg { fill: #e0a23a; }

.tile-float {
  position: absolute;
  bottom: 4px;
  left: 8px;
  font-size: 0.6rem;
  color: var(--muted);
  background: rgba(0, 0, 0, 0.45);
  padding: 1px 5px;
  border-radius: 3px;
}

.tile-foot {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 7px 10px 9px;
  text-decoration: none;
  background: linear-gradient(180deg, rgba(124, 77, 255, 0.10), rgba(124, 77, 255, 0.24));
  border-top: 1px solid var(--border);
}
/* Outcome EV-contribution bar (outputs only): chance × net sale value, drawn
   as a share of the contract's total. This is the sort key made visible. */
.tile-ev {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 0;
  font-size: 0.6rem;
  font-variant-numeric: tabular-nums;
  cursor: help;
}
.tile-ev-label { color: var(--muted); font-weight: 700; letter-spacing: 0.05em; }
.tile-ev-bar {
  flex: 1;
  min-width: 0;
  height: 4px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}
.tile-ev-fill { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.tile-ev-val { color: var(--text); font-weight: 700; flex-shrink: 0; }

.tile-wear { font-size: 0.64rem; color: var(--muted); display: flex; align-items: center; }
.tile-price { font-size: 0.98rem; font-weight: 700; color: var(--text); }
.tile-foot:hover .tile-price { color: var(--accent); }

.sk-row {
  display: flex;
  justify-content: space-between;
  padding: 3px 0;
  border-bottom: 1px solid #0d0b14;
  gap: 8px;
}
.sk-row span:last-child { color: var(--muted); white-space: nowrap; }

.sk-row-img {
  align-items: center;
  padding: 5px 0;
  gap: 10px;
  justify-content: flex-start;
}

/* Tile styling for grid items */
.sk-grid .sk-row-img {
  align-items: flex-start;
  padding: 8px;
  gap: 9px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
  transition: border-color var(--transition);
}
.sk-grid .sk-row-img:hover { border-color: var(--border-hover, #2a2638); }
.skin-thumb {
  width: 54px;
  height: 40px;
  object-fit: contain;
  border-radius: 5px;
  background: #050409;
  flex-shrink: 0;
  border: 1px solid var(--border);
}
.skin-thumb-placeholder {
  width: 54px;
  height: 40px;
  background: #050409;
  border-radius: 5px;
  flex-shrink: 0;
  border: 1px solid var(--border);
}
.sk-info { flex: 1; min-width: 0; }
.sk-name-row {
  font-size: 0.77rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sk-sub { font-size: 0.67rem; color: var(--muted); margin-top: 2px; }

/* Inside grid tiles the name has less width — let it wrap instead of truncating */
.sk-grid .sk-name-row {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.25;
}

.buy-link { color: var(--text); text-decoration: none; transition: color var(--transition); }
.buy-link:hover { color: var(--accent); }

.output-price-link {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px dotted var(--border);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
}
.output-price-link:hover { color: var(--accent); border-bottom-color: var(--accent); }

.src-badge, .buy-badge {
  display: inline-block;
  font-size: 0.55rem;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
  background: #110f1e;
  color: var(--muted);
  text-decoration: none;
  letter-spacing: 0.03em;
  margin-left: 3px;
  vertical-align: middle;
  transition: background var(--transition), color var(--transition);
}
.buy-badge:hover { background: var(--accent); color: #fff; }

/* ── Currency selector (header) ── */
.currency-select {
  width: auto;            /* override the global input,select { width:100% } */
  flex-shrink: 0;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 5px 8px;
  font-size: 0.78rem;
  font-family: inherit;
  cursor: pointer;
  outline: none;
  transition: border-color var(--transition);
}
.currency-select:focus { border-color: var(--accent); }

/* ── Bigger skin image + market strip on contract rows ── */
.sk-row-img .skin-thumb,
.sk-row-img .skin-thumb-placeholder { width: 90px; height: 68px; }

.cmkt-strip {
  display: flex;
  gap: 4px;
  margin-top: 6px;
  flex-wrap: wrap;
}
.cmkt {
  display: flex;
  align-items: center;
  gap: 5px;
  background: rgba(255,255,255,0.04);
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 2px 7px 2px 3px;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--transition), transform 0.1s;
}
.cmkt:hover { border-color: var(--accent); transform: translateY(-1px); }

/* Liquidity dot (availability: green = many listings, red = few) */
.liq-dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  margin-right: 5px;
  vertical-align: middle;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
}

/* Top Picks rendered as detailed cards */
.hero-cards.detailed { display: flex; flex-direction: column; gap: 10px; }
.hero-rank-inline {
  display: inline-block;
  font-size: 0.7rem; font-weight: 800;
  color: var(--accent);
  background: var(--accent-subtle);
  border: 1px solid rgba(242,193,78,0.3);
  border-radius: 5px;
  padding: 0 6px;
  margin-right: 4px;
  vertical-align: middle;
}
.cmkt.steam    { border-color: rgba(96,165,250,0.35); background: rgba(96,165,250,0.07); }
.cmkt.cheapest { border-color: rgba(34,197,94,0.35);  background: rgba(34,197,94,0.07); }
.cmkt-logo {
  width: 18px; height: 18px;
  object-fit: contain; border-radius: 3px;
  background: rgba(255,255,255,0.06);
  flex-shrink: 0;
}
.cmkt-abbr {
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.5rem; font-weight: 700; color: var(--muted);
  background: #110f1e; border-radius: 3px; flex-shrink: 0;
}
.cmkt-price { font-size: 0.72rem; font-weight: 700; color: var(--text); white-space: nowrap; }
.cmkt.steam    .cmkt-price { color: #60a5fa; }
.cmkt.cheapest .cmkt-price { color: #22c55e; }

/* ── Pagination ── */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 24px 0 8px;
  flex-wrap: wrap;
}
.pager button {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 6px 11px;
  font-size: 0.8rem;
  font-family: inherit;
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.pager button:hover:not(:disabled) { border-color: var(--accent); background: var(--panel-hover); }
.pager button:disabled { opacity: 0.4; cursor: default; }
.pager button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.pager .pager-info { color: var(--muted); font-size: 0.75rem; margin: 0 8px; }

.tag-st {
  font-size: 0.6rem;
  font-weight: 600;
  background: rgba(242,193,78,0.1);
  color: var(--accent);
  padding: 1px 6px;
  border-radius: 3px;
  margin-left: 5px;
  border: 1px solid rgba(242,193,78,0.25);
}
.tag-feasible {
  font-size: 0.58rem; font-weight: 600;
  background: rgba(74,222,128,0.1); color: var(--green);
  padding: 1px 6px; border-radius: 3px; margin-left: 6px;
  border: 1px solid rgba(74,222,128,0.2);
}
.tag-infeasible {
  font-size: 0.58rem; font-weight: 600;
  background: rgba(248,113,113,0.1); color: var(--red);
  padding: 1px 6px; border-radius: 3px; margin-left: 6px;
  border: 1px solid rgba(248,113,113,0.2);
}
.tag-suspicious {
  font-size: 0.58rem;
  font-weight: 600;
  background: rgba(251,191,36,0.1);
  color: #f59e0b;
  padding: 1px 6px;
  border-radius: 3px;
  margin-left: 6px;
  border: 1px solid rgba(251,191,36,0.25);
  cursor: default;
}
.avail-tag {
  font-size: 0.63rem; padding: 1px 5px; border-radius: 3px;
  margin-left: 5px; font-weight: 600;
}
.avail-ok  { background: rgba(74,222,128,0.1);  color: var(--green); border: 1px solid rgba(74,222,128,0.2); }
.avail-low { background: rgba(248,113,113,0.1); color: var(--red);   border: 1px solid rgba(248,113,113,0.2); }

/* "+N similar" on a Top Pick — variants of the same trade collapsed below */
.tag-similar {
  font-size: 0.58rem; font-weight: 600;
  background: var(--panel-hover); color: var(--muted);
  padding: 1px 6px; border-radius: 3px; margin-left: 6px;
  border: 1px solid var(--border); cursor: default;
}

/* ── Contract card actions (★ Save / ✎ Log run) ── */
.card-acts { display: flex; gap: 6px; flex-shrink: 0; }
.card-act-btn {
  background: none; border: 1px solid var(--border); color: var(--muted);
  border-radius: 5px; padding: 3px 8px; cursor: pointer;
  font-size: 0.7rem; font-family: inherit; white-space: nowrap; flex-shrink: 0;
  text-decoration: none; line-height: 1.5;
  transition: border-color var(--transition), color var(--transition);
}
.card-act-btn:hover { border-color: var(--accent); color: var(--text); }

/* Collection set icon shown next to a contract card's title. */
.collection-icon {
  width: 17px; height: 17px; object-fit: contain; vertical-align: -3px;
  margin-right: 5px; border-radius: 3px;
}

/* ── Custom icon dropdown (.cdd) ──────────────────────────────────────────────
   A select-like widget that can show an icon beside each option. Built by
   icon-dropdown.js; also used inline by the calculator. */
.cdd { position: relative; }
.cdd-toggle {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; border-radius: var(--radius-md);
  border: 1px solid var(--filter-border); background: var(--filter-fill);
  color: var(--text); font-size: 0.82rem; font-family: inherit; cursor: pointer;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.cdd-toggle:hover { border-color: var(--filter-border-hover); }
.cdd.open .cdd-toggle { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); }
.cdd-cur { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.cdd-cur-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cdd-chev { width: 12px; height: 12px; stroke: var(--muted); flex-shrink: 0; transition: transform var(--transition); }
.cdd.open .cdd-chev { transform: rotate(180deg); }
.cdd-menu {
  display: none; position: absolute; z-index: 60; top: calc(100% + 5px); left: 0; right: 0;
  max-height: 256px; overflow-y: auto; padding: 4px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.cdd.open .cdd-menu { display: block; }
.cdd-opt { display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: var(--radius-sm); cursor: pointer; font-size: 0.8rem; }
.cdd-opt:hover { background: var(--surface-3); }
.cdd-ic { width: 28px; height: 21px; object-fit: contain; border-radius: 3px; background: var(--bg); flex-shrink: 0; }
.cdd-cur .cdd-ic { width: 22px; height: 17px; }
.cdd-ic-svg { width: 22px; height: 17px; stroke: var(--muted); flex-shrink: 0; }
.cdd-cur .cdd-ic-svg { width: 18px; height: 14px; }
.cdd-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 7px -1px currentColor; }
.cdd-dot-any { background: var(--muted); box-shadow: none; }
.cdd-opt-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Small rarity-colored dot before a card's rarity label (set inline per card). */
.rarity-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 6px; vertical-align: 1px;
  box-shadow: 0 0 6px -1px currentColor;
}

/* ── Site-wide footer (injected by nav.js on every page) ── */
.site-footer {
  margin-top: 56px;
  border-top: 1px solid var(--border);
  background: var(--panel);
  color: var(--muted); font-size: 0.8rem;
}
.site-footer-inner {
  max-width: 1200px; margin: 0 auto;
  display: grid; grid-template-columns: 1.7fr 1fr 1fr 1fr; gap: 30px 40px;
  padding: 38px 24px 26px;
}
.site-footer .foot-col { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; }
.site-footer .foot-col h4 {
  color: var(--text); font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em; margin: 0 0 2px;
}
.site-footer a { color: var(--muted); text-decoration: none; transition: color var(--transition); }
.site-footer a:hover { color: var(--accent); }
.site-footer .foot-brand { gap: 13px; }
.site-footer .foot-logo-name { color: var(--text); font-weight: 700; font-size: 0.96rem; }
.site-footer .foot-tag { margin: 0; max-width: 38ch; line-height: 1.55; font-size: 0.77rem; }
.site-footer-bar {
  max-width: 1200px; margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; justify-content: space-between;
  padding: 15px 24px 30px; border-top: 1px solid var(--border);
  font-size: 0.72rem; opacity: 0.85;
}
@media (max-width: 760px) {
  .site-footer-inner { grid-template-columns: 1fr 1fr; gap: 26px 24px; }
  .site-footer .foot-brand { grid-column: 1 / -1; }
}

/* ── Legal pages (Impressum / AGB / Datenschutz / Widerruf) ── */
.legal { max-width: 820px; margin: 0 auto; padding: 32px 20px 60px; }
.legal h1 { font-size: 1.5rem; margin-bottom: 6px; }
.legal h2 { font-size: 1.05rem; margin: 26px 0 8px; color: var(--text); }
.legal p, .legal li { color: var(--text-2, #c9cdd6); font-size: 0.9rem; line-height: 1.7; }
.legal ul { padding-left: 22px; margin: 6px 0; }
.legal address { font-style: normal; }
.legal .ph { color: var(--accent); font-weight: 600; }   /* fill-in placeholder */
.legal .legal-draft {
  background: rgba(235,75,75,0.12); border: 1px solid rgba(235,75,75,0.5);
  color: #f3b1b1; border-radius: 10px; padding: 14px 18px; margin: 18px 0 28px;
  font-size: 0.84rem; line-height: 1.6;
}

/* ── Paywall: locked Pro trade-up card (free users, ROI > cap) ── */
.card.locked { border-left: 3px solid var(--accent); }
.card.locked .locked-title { color: var(--accent); }
.unlock-pro-btn {
  background: var(--accent); color: #0a0c11; border-color: var(--accent);
  font-weight: 700;
}
.unlock-pro-btn:hover { filter: brightness(1.08); color: #0a0c11; }
.locked-blur {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
  padding: 10px 14px 16px;
}
.locked-tile {
  height: 84px; border-radius: 8px; opacity: 0.5; filter: blur(3px);
  background: repeating-linear-gradient(135deg,
    var(--surface-2, #1a1d27) 0 12px, var(--surface-3, #232734) 12px 24px);
}

/* ── Shopping list (consolidated buy list on a contract card) ── */
.shoplist-toggle {
  margin-left: auto; background: none; border: 1px solid var(--border);
  color: var(--muted); border-radius: 5px; padding: 2px 8px; cursor: pointer;
  font-size: 0.66rem; font-family: inherit;
  transition: border-color var(--transition), color var(--transition);
}
.shoplist-toggle:hover { border-color: var(--accent); color: var(--text); }
.shoplist {
  margin: 8px 0 10px; padding: 10px 12px;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 0.74rem;
}
.shop-row { display: flex; gap: 8px; align-items: baseline; padding: 3px 0; flex-wrap: wrap; }
.shop-qty { font-family: var(--font-num); font-weight: 700; color: var(--accent); flex-shrink: 0; }
.shop-name { color: var(--text); }
.shop-wear { color: var(--muted); }
.shop-float { font-family: var(--font-num); font-size: 0.68rem; color: var(--muted); }
.shop-price { margin-left: auto; font-family: var(--font-num); color: var(--text-2); white-space: nowrap; }
.shop-foot {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  border-top: 1px solid var(--border); margin-top: 8px; padding-top: 8px;
}
.shop-note { font-size: 0.66rem; color: var(--muted); flex: 1; min-width: 180px; }
.shop-total { font-family: var(--font-num); font-weight: 700; color: var(--text); }
.shop-copy {
  background: var(--accent-subtle); border: 1px solid rgba(242,193,78,0.4); color: var(--accent);
  border-radius: 5px; padding: 4px 10px; cursor: pointer; font-size: 0.7rem; font-family: inherit;
}
.shop-copy:hover { border-color: var(--accent); }

/* ── Pinned contract (handoff from inventory / home cards) ── */
.pinned-section { margin-bottom: 22px; }
.pinned-section .hero-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pin-dismiss {
  background: none; border: 1px solid var(--border); color: var(--muted);
  border-radius: var(--radius-sm); padding: 5px 11px; cursor: pointer; font-size: 0.74rem;
  font-family: inherit; flex-shrink: 0;
}
.pin-dismiss:hover { border-color: var(--red); color: var(--red); }

.empty { color: var(--muted); text-align: center; padding: 48px 20px; font-size: 0.88rem; }

/* ── Tooltip ── */
.tooltip-box {
  position: fixed;
  background: #1a1727;
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  font-size: 0.72rem;
  color: var(--text);
  line-height: 1.55;
  max-width: 260px;
  z-index: 1000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s;
  box-shadow: var(--shadow-md);
}

/* ── Header nav ── */
.header-nav { display: flex; gap: 4px; margin-left: auto; }
.header-nav a {
  color: var(--muted);
  font-size: 0.78rem;
  text-decoration: none;
  padding: 5px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.header-nav a:hover { border-color: var(--border); color: var(--text); background: var(--panel-hover); }
/* Themed, not hardcoded — same reason as --header-bg above. The active pill used
   var(--accent) text on a rgba(242,193,78,0.3) border, both tuned for the dark bar.
   Once the bar follows the theme, on the near-white light bar that pairing measured
   2.77:1 (below AA for 12.5px text) and the border washed out to near-invisible. */
.header-nav a.active { color: var(--nav-active-fg); border-color: var(--nav-active-border); background: var(--accent-subtle); }

/* ── Mobile nav (burger + slide-down menu) ── */
.nav-burger {
  display: none;
  align-items: center; justify-content: center;
  width: 34px; height: 34px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--muted); cursor: pointer; flex-shrink: 0;
  transition: border-color var(--transition), color var(--transition);
}
.nav-burger:hover { border-color: var(--accent); color: var(--text); }
.nav-burger svg { width: 17px; height: 17px; }

.mobile-menu-backdrop {
  display: none;
  position: fixed; inset: 0; z-index: 194;
  background: rgba(0,0,0,0.45);
}
.mobile-menu-backdrop.visible { display: block; }

.mobile-menu {
  display: none;
  position: fixed; top: 56px; left: 0; right: 0; z-index: 195;
  flex-direction: column; gap: 2px;
  padding: 10px 14px 14px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 18px 40px rgba(0,0,0,0.55);
  max-height: calc(100dvh - 56px); overflow-y: auto;
  opacity: 0; transform: translateY(-8px); pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.mobile-menu.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.mobile-menu a {
  color: var(--text); text-decoration: none;
  font-size: 0.9rem; font-weight: 600;
  padding: 11px 12px; border-radius: var(--radius-sm);
  border: 1px solid transparent;
}
.mobile-menu a:hover { background: var(--panel-hover); }
.mobile-menu a.active { color: var(--accent); background: var(--accent-subtle); border-color: rgba(242,193,78,0.3); }
.mobile-menu-divider { height: 1px; background: var(--border); margin: 8px 0; }
.mobile-menu-currency {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 4px 12px 2px; color: var(--muted); font-size: 0.78rem; font-weight: 600;
}

/* The header never wraps, so trim it as space runs out instead of clipping. */
@media (max-width: 1280px) {
  .header-nav a { padding: 5px 9px; }
  .header-logo-sub { display: none; }
  header .badge-live { display: none; }
}
/* Below ~1140px the full link row can't fit (the finder header is the widest) —
   switch to the burger menu. */
@media (max-width: 1140px) {
  .header-nav { display: none; }
  .nav-burger { display: flex; }
  .mobile-menu { display: flex; }
}

/* ── Header right / user area ── */
.header-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.user-area { position: relative; }

/* Round account button: silhouette placeholder signed out, Steam avatar signed
   in. The dropdown hangs off .user-area (position: relative). */
.user-round-btn {
  position: relative;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0; flex-shrink: 0;
  transition: border-color var(--transition), color var(--transition);
}
.user-round-btn:hover { border-color: var(--accent); color: var(--text); }
.user-avatar-ph { width: 17px; height: 17px; }

.user-avatar {
  width: 100%; height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

/* Tracked-contract alert count, pinned to the button's corner */
.user-alert-badge {
  position: absolute;
  top: -4px; right: -4px;
  min-width: 15px; height: 15px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--red, #ef4444);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
  pointer-events: none;
}

.user-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--panel);
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-md);
  min-width: 175px;
  z-index: 300;
  padding: 6px;
  flex-direction: column;
  gap: 2px;
  box-shadow: var(--shadow-lg);
}
.user-dropdown.open { display: flex; }
.dropdown-name {
  font-size: 0.72rem; color: var(--muted);
  padding: 6px 10px 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.user-dropdown button,
.user-dropdown a {
  display: flex; align-items: center; gap: 8px;
  background: none; border: none; color: var(--text);
  cursor: pointer; padding: 8px 10px;
  border-radius: var(--radius-sm);
  font-size: 0.8rem; font-family: inherit;
  text-align: left; width: 100%;
  text-decoration: none;
  transition: background var(--transition), color var(--transition);
}
.user-dropdown button:hover,
.user-dropdown a:hover { background: var(--panel-hover); color: var(--accent); }
.user-dropdown button svg,
.user-dropdown a svg { color: var(--muted); transition: color var(--transition); flex-shrink: 0; }
.user-dropdown button:hover svg,
.user-dropdown a:hover svg { color: var(--accent); }
.dropdown-divider { height: 1px; background: var(--border); margin: 5px 4px; }

/* ── Modal ── */
.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.7);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 1000;
  align-items: center;
  justify-content: center;
}
.modal-overlay.open { display: flex; }

.modal {
  background: var(--panel);
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-lg);
  padding: 26px 26px 22px;
  width: min(440px, 95vw);
  position: relative;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
}
.modal-wide { width: min(700px, 95vw); }

.modal-close {
  position: absolute; top: 13px; right: 15px;
  background: none; border: none; color: var(--muted);
  font-size: 1.3rem; cursor: pointer; line-height: 1;
  padding: 3px 7px; border-radius: var(--radius-sm);
  transition: background var(--transition), color var(--transition);
}
.modal-close:hover { background: var(--panel-hover); color: var(--text); }

.modal-title {
  font-size: 1rem; font-weight: 700; margin-bottom: 18px;
  padding-right: 26px; letter-spacing: -0.01em;
}

.modal-tabs {
  display: flex; gap: 0; margin-bottom: 20px;
  border-bottom: 1px solid var(--border);
}
.modal-tab-btn {
  background: none; border: none;
  border-bottom: 2px solid transparent;
  color: var(--muted); cursor: pointer;
  font-size: 0.82rem; font-family: inherit;
  padding: 6px 14px 8px; margin-bottom: -1px;
  transition: color var(--transition), border-color var(--transition);
}
.modal-tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.modal-tab-btn:hover:not(.active) { color: var(--text); }

.modal-tab-pane { display: flex; flex-direction: column; gap: 10px; }
.modal-tab-pane input[type="email"],
.modal-tab-pane input[type="password"] {
  width: 100%; background: var(--bg); border: 1px solid var(--border);
  color: var(--text); border-radius: var(--radius-sm);
  padding: 10px 12px; font-size: 0.85rem; font-family: inherit;
}

.auth-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 16px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg);
  color: var(--text); cursor: pointer; font-size: 0.85rem;
  font-family: inherit; text-decoration: none; text-align: center;
  transition: background var(--transition), border-color var(--transition);
}
.auth-btn:hover { background: var(--panel-hover); border-color: var(--border-hover); }
.auth-btn.primary {
  background: var(--accent); color: #fff; border-color: var(--accent);
  font-weight: 700; box-shadow: 0 2px 12px var(--accent-glow);
}
.auth-btn.primary:hover { background: var(--accent-dim); box-shadow: 0 4px 20px rgba(242,193,78,0.4); }
.steam-btn  { background: #1b2838; border-color: #2a475e; color: #c7d5e0; }
.steam-btn:hover  { background: #233244; }
.google-btn { background: #fff; border-color: #e5e7eb; color: #374151; }
.google-btn:hover { background: #f9fafb; }

.auth-divider {
  text-align: center; color: var(--muted); font-size: 0.72rem; position: relative;
}
.auth-divider::before, .auth-divider::after {
  content: ""; position: absolute; top: 50%; width: 40%; height: 1px; background: var(--border);
}
.auth-divider::before { left: 0; }
.auth-divider::after  { right: 0; }

.auth-desc  { font-size: 0.78rem; color: var(--muted); line-height: 1.65; }
.auth-error { color: var(--red); font-size: 0.78rem; min-height: 18px; }

/* ── Inventory ── */
.inv-count { font-size: 0.8rem; color: var(--muted); font-weight: 400; margin-left: 6px; }
.inv-controls { display: flex; gap: 8px; margin: 10px 0 12px; flex-wrap: wrap; }
.inv-controls input {
  flex: 1; min-width: 200px;
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: var(--radius-sm); padding: 8px 11px; font-size: 0.8rem;
}
.inv-controls input:focus { outline: none; border-color: var(--accent); }
.inv-controls button {
  background: var(--panel); border: 1px solid var(--border); color: var(--text);
  border-radius: var(--radius-sm); padding: 8px 14px; font-size: 0.8rem;
  font-weight: 600; cursor: pointer; transition: border-color var(--transition);
}
.inv-controls button:hover { border-color: var(--accent); }

/* ── Fetcher health ── */
.fh-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px;
  margin-bottom: 16px;
}
.fh-stats > div {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 9px 11px;
  display: flex; flex-direction: column; gap: 2px;
}
.fh-stats span { font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); font-weight: 700; }
.fh-stats strong { font-size: 0.84rem; font-weight: 600; }
.fh-h { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); font-weight: 700; margin-bottom: 8px; }
.fh-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 4px 14px; }
.fh-row { display: flex; justify-content: space-between; gap: 8px; font-size: 0.74rem; padding: 3px 0; border-bottom: 1px solid var(--border); }
.fh-mkt { color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Theme toggle ── */
.theme-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--muted); cursor: pointer; flex-shrink: 0;
  transition: border-color var(--transition), color var(--transition);
}
.theme-toggle:hover { border-color: var(--accent); color: var(--text); }
.theme-toggle svg { width: 17px; height: 17px; }

/* ── Watchlist ── */
.watchlist-btn {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--muted); cursor: pointer;
  transition: border-color var(--transition), color var(--transition);
}
.watchlist-btn:hover { border-color: var(--accent); color: var(--text); }
.watchlist-btn svg { width: 17px; height: 17px; }
.watchlist-count {
  position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px; padding: 0 4px;
  background: var(--accent); color: #fff; border-radius: 999px; font-size: 0.6rem;
  font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.wl-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px; margin-bottom: 8px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
}
.wl-row.met { border-color: var(--green); }
.wl-name { flex: 1; min-width: 0; }
.wl-name a { color: var(--text); text-decoration: none; font-size: 0.84rem; font-weight: 600; }
.wl-name a:hover { color: var(--accent); }
.wl-sub { font-size: 0.68rem; color: var(--muted); margin-top: 2px; }
.wl-row.met .wl-sub { color: var(--green); }
.wl-target { font-size: 0.72rem; color: var(--muted); display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.wl-target input {
  width: 76px; background: var(--bg); border: 1px solid var(--border); color: var(--text);
  border-radius: 5px; padding: 5px 7px; font-size: 0.74rem; text-align: right;
}
.wl-target input:focus { outline: none; border-color: var(--accent); }
.wl-del {
  background: none; border: 1px solid var(--border); color: var(--muted);
  border-radius: 5px; padding: 5px 10px; cursor: pointer; font-size: 0.72rem;
}
.wl-del:hover { border-color: var(--red); color: var(--red); }

/* ── Saved contracts ── */
.saved-contract { margin-bottom: 14px; }
.saved-contract-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 6px;
}
.saved-contract-meta { font-size: 0.7rem; color: var(--muted); }
.saved-contract-actions { display: flex; gap: 6px; }
.saved-contract-actions button {
  background: none; border: 1px solid var(--border); color: var(--muted);
  border-radius: 5px; padding: 4px 10px; cursor: pointer; font-size: 0.72rem;
  transition: border-color var(--transition), color var(--transition);
}
.saved-contract-actions button:hover { border-color: var(--accent); color: var(--text); }
.saved-contract .card { cursor: default; }

/* ── Inline price editing, on the skin tiles ──
   Prices are edited on the cards themselves (owner instruction 2026-08-08:
   "edit prices on saved contract should make you able to edit them right on
   the skin card"), so there is no second list of skin names to style — just a
   field per tile and one metrics/actions bar under the card. */
.tile-edit {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; border-top: 1px solid var(--border);
  background: var(--panel);
}
.tile-edit-label {
  font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--muted); font-weight: 700; white-space: nowrap;
}
.tile-edit input {
  flex: 1; min-width: 0;             /* min-width:0 — a flex item's default
                                        min-width:auto refuses to shrink below
                                        the number field's intrinsic size and
                                        would push the tile wider than its
                                        grid column. */
  background: var(--bg); border: 1px solid var(--border);
  color: var(--text); border-radius: 5px; padding: 4px 6px;
  font-size: 0.74rem; text-align: right; font-variant-numeric: tabular-nums;
}
.tile-edit input:focus { outline: none; border-color: var(--accent); }
/* While editing, the tile's own price row is the stale number — mute it so the
   field below is unmistakably the live one. */
.card.editing-prices .tile-foot .tile-price { opacity: 0.45; }

.saved-edit-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 18px;
  border: 1px solid var(--accent); border-top: none;
  border-radius: 0 0 10px 10px; background: var(--bg);
  padding: 10px 14px; margin-top: -8px;
}
.saved-edit-bar[hidden] { display: none; }
.saved-contract-actions .saved-editprices-btn.active {
  border-color: var(--accent); color: var(--accent);
}
.se-metrics {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  font-size: 0.78rem; color: var(--muted);
}
.se-metrics strong { color: var(--text); }
.se-actions { display: flex; gap: 8px; }
.se-actions button {
  border: 1px solid var(--border); border-radius: 6px; padding: 6px 14px;
  font-size: 0.74rem; font-weight: 600; cursor: pointer; transition: border-color var(--transition);
}
.se-actions .se-save { background: var(--accent); color: #fff; border-color: var(--accent); }
.se-actions .se-reset { background: none; color: var(--muted); }
.se-actions button:hover { border-color: var(--accent); }
.inv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(125px, 1fr));
  gap: 9px; max-height: 60vh; overflow-y: auto; padding-right: 4px;
}
.inv-item {
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 8px;
  display: flex; flex-direction: column; gap: 5px;
  transition: border-color var(--transition);
}
.inv-item:hover { border-color: var(--border-hover); }
.inv-img { width: 100%; aspect-ratio: 4/3; display: flex; align-items: center; justify-content: center; }
.inv-img img { width: 100%; height: 100%; object-fit: contain; border-radius: 4px; }
.inv-thumb-placeholder { width: 100%; height: 100%; background: var(--panel); border-radius: 4px; }
.inv-name { font-size: 0.68rem; font-weight: 500; line-height: 1.4; word-break: break-word; }
.inv-wear { font-size: 0.63rem; color: var(--muted); }

/* ── Price data section ── */
.price-data-info { display: flex; flex-direction: column; gap: 5px; margin-top: 2px; }
.price-data-row { display: flex; justify-content: space-between; align-items: center; font-size: 0.76rem; }
.price-data-label { color: var(--muted); flex-shrink: 0; }
.price-data-val { color: var(--text); text-align: right; max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.refresh-prices-btn {
  margin-top: 10px; width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  background: transparent; border: 1px solid var(--border-hover);
  color: var(--muted); border-radius: var(--radius-sm);
  padding: 7px 12px; font-size: 0.78rem; font-family: inherit;
  cursor: pointer; transition: var(--transition);
}
.refresh-prices-btn:hover { border-color: var(--accent); color: var(--accent); }
.refresh-prices-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ── Toast ── */
.auth-toast {
  position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%);
  background: var(--panel); border: 1px solid var(--border-hover);
  border-radius: var(--radius-sm); padding: 9px 18px;
  font-size: 0.82rem; font-family: inherit; z-index: 2000;
  box-shadow: var(--shadow-md); white-space: nowrap;
  animation: toastIn 0.2s ease;
}
@keyframes toastIn {
  from { opacity: 0; transform: translateX(-50%) translateY(8px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* ── Mobile FAB ── */
.fab {
  display: none;
  position: fixed; bottom: 20px; right: 20px; z-index: 300;
  background: var(--accent); color: #fff;
  border: none; border-radius: 50px; padding: 13px 22px;
  font-weight: 700; font-size: 0.9rem; font-family: inherit;
  cursor: pointer; box-shadow: 0 4px 24px var(--accent-glow);
  transition: opacity var(--transition), transform 0.1s;
}
.fab:hover { box-shadow: 0 6px 30px rgba(242,193,78,0.5); }
.fab:active { transform: scale(0.96); }

/* ── Animations ── */
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.spin { animation: spin 1s linear infinite; }

/* ── Sliders ── */
input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 4px; border-radius: 2px;
  background: var(--border); border: none; padding: 0; margin-top: 6px;
  cursor: pointer; box-shadow: none;
}
input[type="range"]:focus { box-shadow: none; border: none; }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); cursor: pointer;
  border: 2px solid var(--bg);
  box-shadow: 0 0 0 1px var(--accent), 0 0 8px var(--accent-glow);
}
input[type="range"]::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); cursor: pointer;
  border: 2px solid var(--bg);
  box-shadow: 0 0 0 1px var(--accent), 0 0 8px var(--accent-glow);
}

/* The assumed-float summary under the estimation dropdown: the exact float
   each wear is currently evaluated at. Tabular figures so the five numbers
   line up rather than jittering as the strategy changes. */
.float-assumed {
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

/* ── Tablet ── */
@media (max-width: 1024px) {
  .hero-cards { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
  .layout { grid-template-columns: 1fr; }
  aside { position: static; height: auto; border-right: none; border-bottom: 1px solid var(--border); }
  .stats { grid-template-columns: repeat(3, 1fr); }
  .card-body { grid-template-columns: 1fr; }
}

/* ── Mobile ── */
@media (max-width: 640px) {
  header { padding: 0 16px; gap: 10px; }
  .header-logo-sub { display: none; }
  .badge-live { display: none; }
  .filter-toggle { display: flex; }

  /* Declutter the header: currency moves into the burger menu, the Filters
     button collapses to its icon, and the crowded finder header drops the
     logo text (the icon still links home). */
  header .header-right > .currency-select { display: none; }
  .filter-toggle .ft-label { display: none; }
  header:has(.filter-toggle) .header-logo-text { display: none; }

  .layout { grid-template-columns: 1fr; }
  aside {
    position: fixed; top: 0; left: 0;
    width: min(88vw, 310px); height: 100dvh;
    z-index: 150; border-right: 1px solid var(--border); border-bottom: none;
    transform: translateX(-110%);
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    padding: 64px 14px 100px; overflow-y: auto;
  }
  aside.drawer-open { transform: translateX(0); box-shadow: 4px 0 40px rgba(0,0,0,0.7); }

  main { padding: 12px 12px 90px; }
  .stats { grid-template-columns: repeat(2, 1fr); gap: 6px; }
  .hero-cards { grid-template-columns: 1fr; }
  .card-head { grid-template-columns: 1fr; gap: 6px; }
  .metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 10px; text-align: left; }
  .metrics > div { flex-direction: row; align-items: baseline; gap: 5px; }
  /* Padding stays on the open state only, or a closed card can't collapse to 0. */
  /* Horizontal padding stays 14px so .risk-strip's full-bleed -14px margin
     still lines up exactly with the card edge. */
  .card-body { grid-template-columns: 1fr; padding: 0 14px; font-size: 0.79rem; }
  .card.open .card-body { padding: 11px 14px; }
  /* Table mode does not exist below 641px — hide its controls rather than
     offer a switch that visibly does nothing. */
  .results-toolbar, .results-thead { display: none; }
  .fab { display: flex; align-items: center; gap: 8px; }
}

/* ══ Phase 1: shared components ══════════════════════════════════════════════
   One definition per component.  Everything below used to live in a per-page
   <style> block; the duplicates are gone and the survivors live here.

   Page-scoped rules use :where(body[data-page="…"]) — :where() adds ZERO
   specificity, so a scoped rule keeps exactly the weight it had when it was
   inline and still wins on source order.  That is what makes this migration
   render-identical rather than "close enough".
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Button ──────────────────────────────────────────────────────────────────
   Was defined three times over: .btn + .btn.primary in home.html, .db-gate
   a.btn in dashboard.html, and .btn-ghost twice in profile.html and
   settings.html. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--panel);
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 600;
  font-family: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: all var(--transition);
}
.btn:hover { border-color: var(--border-hover); transform: translateY(-1px); }

.btn.primary {
  background: linear-gradient(135deg, var(--gold), var(--gold-deep));
  border-color: transparent;
  color: #1a1407;
  box-shadow: 0 8px 28px -10px var(--accent-glow);
}
.btn.primary:hover { box-shadow: 0 12px 34px -8px var(--accent-glow); }
/* The author-origin `display: inline-flex` above beats the UA
   [hidden]{display:none} rule (same specificity, later in source), so
   `el.hidden = true` on a .btn is a no-op — inventory.html's Clear button
   toggles exactly that way. Five other components already carry the identical
   fix (search this file for `[hidden] { display: none; }`); this is the sixth,
   and it lives on the SHARED component so the next .btn to be toggled is
   covered for free. */
.btn[hidden] { display: none; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-size: 0.82rem;
  font-family: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--transition);
}
.btn-ghost:hover { border-color: var(--accent); }

/* ── Item card ───────────────────────────────────────────────────────────────
   Was home.html + inventory.html carrying near byte-identical copies of this
   whole block. The redesign plan §4.7 moved home off card grids entirely
   (onto `.dtable`, like its siblings) — inventory.html still uses `.card` for
   its "trade-ups you can build" / "top flips" sections, so the block stays,
   scoped to inventory only. `.sec-head` is the one piece home still shares
   (its "Top Trade-Ups"/"Top Flips" table headers use the same recipe).
   `.card` is ALSO the finder's contract card — a different component that
   happens to share the name; the two must not be merged. */
:where(body[data-page="home"], body[data-page="inventory"]) .sec-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 38px 0 16px;
}
:where(body[data-page="home"], body[data-page="inventory"]) .sec-head h2 {
  font-size: 1.3rem;
  font-weight: 700;
}
:where(body[data-page="home"], body[data-page="inventory"]) .sec-head .sub {
  font-size: 0.8rem;
  color: var(--muted);
}
:where(body[data-page="inventory"]) .cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
:where(body[data-page="inventory"]) .card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  text-decoration: none;
  transition: border-color var(--transition), transform var(--transition);
}
:where(body[data-page="inventory"]) .card:hover {
  border-color: var(--border-hover);
  transform: translateY(-2px);
}
:where(body[data-page="inventory"]) .card-img {
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-0);
  border-radius: var(--radius-md);
}
:where(body[data-page="inventory"]) .card-img img {
  max-height: 88px;
  max-width: 92%;
  object-fit: contain;
}
:where(body[data-page="inventory"]) .card-name {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
:where(body[data-page="inventory"]) .card-sub,
:where(body[data-page="inventory"]) .card-flip-route {
  font-size: 0.7rem;
  color: var(--muted);
}
:where(body[data-page="inventory"]) .card-cost {
  font-size: 0.74rem;
  color: var(--text-2);
  font-family: var(--font-num);
}
:where(body[data-page="inventory"]) .card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
}
:where(body[data-page="inventory"]) .roi-badge {
  font-family: var(--font-num);
  font-weight: 700;
  font-size: 1rem;
  color: var(--green);
}
:where(body[data-page="inventory"]) .home-status {
  grid-column: 1 / -1;
  padding: 30px;
  text-align: center;
  color: var(--muted);
}

/* ── Account shell ───────────────────────────────────────────────────────────
   Identical in faq.html, profile.html and settings.html apart from faq's wider
   measure. */
:where(body[data-page="faq"], body[data-page="profile"], body[data-page="settings"]) .acct {
  max-width: 760px;
  margin: 0 auto;
  padding: 32px 20px 90px;
}
:where(body[data-page="faq"]) .acct { max-width: 800px; }
:where(body[data-page="faq"], body[data-page="profile"], body[data-page="settings"]) .acct h1 {
  font-size: 1.5rem;
  font-weight: 700;
}
:where(body[data-page="faq"], body[data-page="profile"], body[data-page="settings"]) .acct > p.lead {
  margin-top: 6px;
  color: var(--muted);
  font-size: 0.88rem;
}

/* ── page: arbitrage ─────────────────────────────────────────────── */
:where(body[data-page="arbitrage"]) .page-header {
      border-bottom: 1px solid var(--border);
      padding: 14px 24px; display: flex; align-items: center; gap: 16px;
      background: var(--panel); position: sticky; top: 0; z-index: 100;
    }
:where(body[data-page="arbitrage"]) .page-header a { color: var(--muted); font-size: 0.82rem; text-decoration: none; }
:where(body[data-page="arbitrage"]) .page-header a:hover, :where(body[data-page="arbitrage"]) .page-header a.active { color: var(--text); }
:where(body[data-page="arbitrage"]) .page-header h1 { font-size: 1.1rem; font-weight: 600; }
:where(body[data-page="arbitrage"]) .page-header .spacer { flex: 1; }
:where(body[data-page="arbitrage"]) .arb-wrap { max-width: 1100px; margin: 0 auto; padding: 18px 20px 60px; }
/* The control panel. Previously one flat wrapping row of inputs and bare
   checkboxes with no grouping, which read as a debug form. Now a single
   surface split into three bands — what to rank by, what range to keep, and
   the on/off switches — so the eye lands on the sliders, which are the part
   the user actually manipulates. */
:where(body[data-page="arbitrage"]) .arb-panel {
      display: flex; flex-direction: column; gap: 14px;
      background: var(--surface-1); border: 1px solid var(--border);
      border-radius: 12px; padding: 14px 16px; margin-bottom: 12px;
    }
:where(body[data-page="arbitrage"]) .arb-row { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: end; }
:where(body[data-page="arbitrage"]) .arb-row-spacer { flex: 1 1 auto; }
:where(body[data-page="arbitrage"]) .arb-row-sliders {
      display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
      gap: 12px 28px; align-items: start;
      padding: 12px 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
    }
:where(body[data-page="arbitrage"]) .arb-row-toggles { gap: 8px 18px; align-items: center; }
:where(body[data-page="arbitrage"]) .arb-field { display: flex; flex-direction: column; gap: 4px; }
:where(body[data-page="arbitrage"]) .arb-field label { font-size: 0.66rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
:where(body[data-page="arbitrage"]) .arb-field select, :where(body[data-page="arbitrage"]) .arb-field input {
      background: var(--bg); border: 1px solid var(--border); color: var(--text);
      border-radius: 6px; padding: 7px 9px; font-size: 0.8rem; width: 110px;
    }
:where(body[data-page="arbitrage"]) .arb-field input:focus, :where(body[data-page="arbitrage"]) .arb-field select:focus { outline: none; border-color: var(--accent); }
:where(body[data-page="arbitrage"]) .arb-btn {
      background: var(--bg); border: 1px solid var(--border); color: var(--text-2);
      border-radius: 6px; padding: 7px 12px; font-size: 0.78rem; cursor: pointer;
    }
:where(body[data-page="arbitrage"]) .arb-btn:hover { color: var(--text); border-color: var(--border-hover); }
:where(body[data-page="arbitrage"]) .arb-btn-primary { color: var(--text); border-color: var(--border-hover); }
:where(body[data-page="arbitrage"]) .arb-btn-primary:hover { border-color: var(--accent); }
/* The global `label` rule is uppercase/800 — right for the micro-labels above
   a field, wrong for a sentence sitting next to a checkbox, which came out as
   three lines of shouting. Opt these back into normal sentence case. */
:where(body[data-page="arbitrage"]) .arb-toggle {
      display: flex; align-items: center; gap: 7px; cursor: pointer;
      font-size: 0.8rem; font-weight: 500; text-transform: none; letter-spacing: 0;
      color: var(--text-2);
    }
:where(body[data-page="arbitrage"]) .arb-toggle:hover { color: var(--text); }
:where(body[data-page="arbitrage"]) .arb-toggle input { width: auto; margin: 0; accent-color: var(--accent); }
/* The <select> and the markets <summary> are different elements with different
   intrinsic heights; without a shared height they sit a couple of pixels apart
   and the row reads as misaligned. */
:where(body[data-page="arbitrage"]) .arb-field select,
:where(body[data-page="arbitrage"]) .arb-markets > summary,
:where(body[data-page="arbitrage"]) .arb-btn { height: 34px; }
:where(body[data-page="arbitrage"]) .arb-field select { padding-block: 0; }
:where(body[data-page="arbitrage"]) .arb-markets > summary { display: flex; align-items: center; }
:where(body[data-page="arbitrage"]) .arb-markets > summary::after { margin-left: auto; float: none; }
:where(body[data-page="arbitrage"]) .arb-note { font-size: 0.72rem; line-height: 1.6; color: var(--muted); margin-bottom: 12px; max-width: 90ch; }
:where(body[data-page="arbitrage"]) .arb-note strong { color: var(--text-2); }

/* ── Component: dual-handle range slider (static/dual-range.js) ──────────────
   Two <input type="range"> stacked over one painted track. The inputs are
   pointer-events:none so the track below stays visually in charge; only the
   thumbs take the pointer back, which is what lets the two overlap without
   the upper input swallowing every click meant for the lower one. */
.rng { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.rng-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.rng-label { font-size: 0.66rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
.rng-value { font-size: 0.78rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rng.is-set .rng-value { color: var(--accent); font-weight: 600; }
.rng-slider { position: relative; height: 20px; }
.rng-track {
  position: absolute; left: 0; right: 0; top: 50%; height: 4px; margin-top: -2px;
  background: var(--surface-3); border-radius: 99px;
}
.rng-fill { position: absolute; top: 0; bottom: 0; background: var(--accent); border-radius: 99px; }
.rng-handle {
  position: absolute; left: 0; top: 0; width: 100%; height: 20px; margin: 0;
  -webkit-appearance: none; appearance: none; background: transparent;
  pointer-events: none;   /* the thumbs re-enable it below */
}
.rng-from { z-index: 2; }
.rng-to   { z-index: 3; }
/* Once the handles coincide the lower one is unreachable underneath the upper.
   Lifting it restores the only escape the user has left — dragging back left. */
.rng.rng-from-on-top .rng-from { z-index: 4; }
.rng-handle::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; pointer-events: auto;
  width: 16px; height: 16px; border-radius: 50%; cursor: grab;
  background: var(--panel); border: 2px solid var(--accent);
  box-shadow: 0 1px 4px rgba(0,0,0,0.45);
}
.rng-handle::-moz-range-thumb {
  pointer-events: auto; box-sizing: border-box;
  width: 16px; height: 16px; border-radius: 50%; cursor: grab;
  background: var(--panel); border: 2px solid var(--accent);
  box-shadow: 0 1px 4px rgba(0,0,0,0.45);
}
.rng-handle:active::-webkit-slider-thumb { cursor: grabbing; }
.rng-handle:active::-moz-range-thumb { cursor: grabbing; }
.rng-handle:focus { outline: none; }
.rng-handle:focus-visible::-webkit-slider-thumb { border-color: var(--text); box-shadow: 0 0 0 3px var(--surface-3); }
.rng-handle:focus-visible::-moz-range-thumb { border-color: var(--text); box-shadow: 0 0 0 3px var(--surface-3); }
:where(body[data-page="arbitrage"]) .arb-note a { color: var(--accent); }
:where(body[data-page="arbitrage"]) .arb-markets { position: relative; }
:where(body[data-page="arbitrage"]) .arb-markets > summary {
      list-style: none; cursor: pointer; background: var(--bg); border: 1px solid var(--border);
      color: var(--text); border-radius: 6px; padding: 7px 9px; font-size: 0.8rem; width: 150px;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
:where(body[data-page="arbitrage"]) .arb-markets > summary::-webkit-details-marker { display: none; }
:where(body[data-page="arbitrage"]) .arb-markets > summary::after { content: "▾"; float: right; color: var(--muted); }
:where(body[data-page="arbitrage"]) .arb-markets-panel {
      position: absolute; z-index: 200; margin-top: 6px; width: 230px; max-height: 320px; overflow-y: auto;
      background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 8px;
      box-shadow: 0 12px 32px rgba(0,0,0,0.45);
    }
:where(body[data-page="arbitrage"]) .arb-markets-actions { display: flex; gap: 6px; margin-bottom: 6px; }
:where(body[data-page="arbitrage"]) .arb-markets-actions button {
      flex: 1; background: var(--bg); border: 1px solid var(--border); color: var(--muted);
      border-radius: 5px; padding: 4px; font-size: 0.7rem; cursor: pointer;
    }
:where(body[data-page="arbitrage"]) .arb-markets-actions button:hover { color: var(--text); border-color: var(--accent); }
:where(body[data-page="arbitrage"]) .arb-mkt-opt { display: flex; align-items: center; gap: 7px; padding: 4px 5px; border-radius: 5px; font-size: 0.78rem; }
:where(body[data-page="arbitrage"]) .arb-mkt-opt:hover { background: rgba(255,255,255,0.04); }
:where(body[data-page="arbitrage"]) .arb-mkt-opt img.mkt-logo-sm { width: 16px; height: 16px; border-radius: 50%; object-fit: contain; background: rgba(255,255,255,0.06); }
:where(body[data-page="arbitrage"]) .tag-sv { background:#c97f0033; color:#e8c97f; border:1px solid #c97f0066; border-radius:4px; padding:0 4px; white-space:nowrap; }
:where(body[data-page="arbitrage"]) .arb-status { color: var(--muted); font-size: 0.85rem; padding: 10px 0 4px; }

/* ── The arbitrage dense table — plan §4.3 ───────────────────────────────────
   Built on the shared `.dtable` component (see "Component: dense data table"
   below); these rules are only the parts specific to Buy/Sell/Spread/
   Liquidity/Confidence. Rows aren't globally clickable here (unlike /skins) —
   the Item name and each market leg carry their own link, so the shared
   `.dtable tbody tr { cursor: pointer }` would be misleading. */
:where(body[data-page="arbitrage"]) .arb-dtable tbody tr { cursor: default; }
:where(body[data-page="arbitrage"]) .arb-dtable tbody tr:hover td { background: var(--panel-hover); }

/* Market logo / typographic fallback chip — shared by the Buy/Sell cells and
   the market-chooser panel. get_all_logos()'s docstring promises this
   fallback exists (B2); this is what makes that true. */
:where(body[data-page="arbitrage"]) .mkt-logo { width: 18px; height: 18px; border-radius: 50%; object-fit: contain; background: rgba(255,255,255,0.06); flex: none; }
:where(body[data-page="arbitrage"]) .mkt-chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px; flex: none;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text-2); font-size: 0.55rem; font-weight: 700; letter-spacing: 0.02em;
}

:where(body[data-page="arbitrage"]) .mkt-cell {
  display: flex; flex-direction: column; gap: 2px;
  text-decoration: none; color: inherit; min-width: 0;
}
:where(body[data-page="arbitrage"]) .mkt-row { display: flex; align-items: center; gap: 5px; min-width: 0; }
:where(body[data-page="arbitrage"]) .mkt-name {
  font-size: 0.68rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 88px;
}
a.mkt-cell:hover .mkt-name { color: var(--text-2); }
:where(body[data-page="arbitrage"]) .mkt-price {
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 0.84rem; font-weight: 600; color: var(--text); white-space: nowrap;
}
:where(body[data-page="arbitrage"]) .mkt-fee { font-size: 0.62rem; color: var(--muted); white-space: nowrap; }

/* Spread — the dominant visual element on the row (plan §4.3). Colour is
   applied to the NUMBER only (redesign plan §2.1), never to the row or a
   rarity-style fill, and always paired with an explicit +/− sign so it
   survives colour-blindness. */
:where(body[data-page="arbitrage"]) .cell-spread { text-align: right; }
:where(body[data-page="arbitrage"]) .spread-pct {
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 1.02rem; font-weight: 700; white-space: nowrap;
}
:where(body[data-page="arbitrage"]) .spread-pct.num-pos { color: var(--green); }
:where(body[data-page="arbitrage"]) .spread-pct.num-neg { color: var(--red); }
/* A standout ROI reads slightly larger — an intensity cue, not a second hue. */
:where(body[data-page="arbitrage"]) .spread-pct.tone-hot { font-size: 1.12rem; }
:where(body[data-page="arbitrage"]) .spread-profit {
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 0.72rem; color: var(--muted); margin-top: 1px; white-space: nowrap;
}

/* Liquidity — plain tabular text, no colour coding (it's a count, not a
   verdict; Confidence is the verdict). */
:where(body[data-page="arbitrage"]) .cell-liq {
  font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-2); font-size: 0.76rem;
}

/* Confidence pill — a NEUTRAL scale on purpose (redesign plan §2.1): this is
   a transparency label, not a profit/loss verdict, so it must never borrow
   the green/red pair or a rarity hue. Believability is read from weight +
   fill opacity, and the text label always ships (never colour alone), so the
   grade survives colour-blindness and doesn't get mistaken for a P/L signal.
   Shared with home.html's Top Flips preview table (§4.7 fix) — reused, not
   redefined, so the two pages can never disagree on what "Low" looks like. */
:where(body[data-page="arbitrage"], body[data-page="home"]) .cell-conf { text-align: right; }
:where(body[data-page="arbitrage"], body[data-page="home"]) .conf-pill {
  display: inline-block; min-width: 34px; text-align: center;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em;
  padding: 3px 8px; border-radius: 999px; cursor: default;
  border: 1px solid var(--border);
}
:where(body[data-page="arbitrage"], body[data-page="home"]) .conf-pill.conf-high { background: var(--surface-3); color: var(--text); border-color: var(--border-hover); }
:where(body[data-page="arbitrage"], body[data-page="home"]) .conf-pill.conf-medium { background: var(--surface-2); color: var(--text-2); }
:where(body[data-page="arbitrage"], body[data-page="home"]) .conf-pill.conf-low { background: var(--surface-1); color: var(--muted); }

/* ── Responsive — hide the lowest-value columns before the row is asked to
   squeeze. The shared `.dtable-wrap` only becomes a horizontal scroller at
   <=820px (see "Component: dense data table" below); above that there is NO
   scroller to catch overflow, so any incompressible width above 820px
   escapes to the DOCUMENT instead — the exact regression the last table PR
   shipped, caught at 825px specifically. Dropping Liquidity well before that
   band, then Confidence, then finally the thumbnail, is what keeps the table
   inside the viewport through 825–900px without ever handing it a scroller. */
@media (max-width: 900px) {
  :where(body[data-page="arbitrage"]) .arb-dtable .col-liq { display: none; }
}
@media (max-width: 700px) {
  :where(body[data-page="arbitrage"]) .arb-dtable .col-conf { display: none; }
  :where(body[data-page="arbitrage"]) .arb-dtable .mkt-name { max-width: 60px; }
}
@media (max-width: 480px) {
  :where(body[data-page="arbitrage"]) .arb-dtable .col-thumb { display: none; }
}


/* ── page: calculator ────────────────────────────────────────────── */
:where(body[data-page="calculator"]) .page-header {
      border-bottom: 1px solid var(--border);
      padding: 14px 24px;
      display: flex;
      align-items: center;
      gap: 16px;
      background: var(--panel);
      position: sticky;
      top: 0;
      z-index: 100;
    }
:where(body[data-page="calculator"]) .page-header a { color: var(--muted); font-size: 0.82rem; text-decoration: none; white-space: nowrap; flex-shrink: 0; }
:where(body[data-page="calculator"]) .page-header a:hover { color: var(--text); }
:where(body[data-page="calculator"]) .page-header h1 { font-size: 1.05rem; font-weight: 600; flex: 1; white-space: nowrap; }
:where(body[data-page="calculator"]) .page-header .theme-toggle { flex-shrink: 0; }
    /* 460px, not the original 340px: the "Possible Outputs" table needs
       thumb + name + chance + price + net + hit-profit + EV-contribution to
       fit without a horizontal scroller (the panel itself scrolls
       vertically only — see .calc-table-wrap below). Measured against the
       column widths declared there: ~460px is the narrowest this fits all
       seven columns at a legible size. */
    /* The results side is no longer FIXED at 460px: on a wide monitor
       `1fr 460px` gave the ten input slots ~1000px of mostly-empty grid while
       the outputs table — the answer the page exists to produce — stayed pinned
       at its minimum. Owner, 2026-08-08: "the input side is too big compared to
       the results side."

       Even columns instead, with 460px as the results FLOOR rather than its
       ceiling. `minmax(0, …)` on the inputs side is load-bearing: a bare `1fr`
       floors at min-content, and the slot grid's own min-content is wide enough
       to shove the results column back below its 460px minimum. */
:where(body[data-page="calculator"]) .calc-layout {
      display: grid;
      grid-template-columns: minmax(0, 1fr) minmax(460px, 1fr);
      gap: 0;
      min-height: calc(100vh - 54px);
    }

    /* ── Inputs panel ── */
:where(body[data-page="calculator"]) .inputs-panel {
      padding: 20px;
      border-right: 1px solid var(--border);
    }
:where(body[data-page="calculator"]) .inputs-panel h2 { font-size: 0.85rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 14px; }
:where(body[data-page="calculator"]) .slot-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 8px;
      margin-bottom: 16px;
    }
:where(body[data-page="calculator"]) .slot {
      background: var(--panel);
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 10px;
      display: flex;
      align-items: center;
      gap: 8px;
      min-height: 64px;
      cursor: pointer;
      transition: border-color 0.15s;
      position: relative;
    }
:where(body[data-page="calculator"]) .slot:hover { border-color: var(--accent); }
:where(body[data-page="calculator"]) .slot.filled { border-color: #2a3a5a; }
:where(body[data-page="calculator"]) .slot.filled:hover { border-color: var(--accent); }
:where(body[data-page="calculator"]) .slot-num {
      font-size: 0.65rem;
      color: var(--muted);
      font-weight: 600;
      min-width: 18px;
      text-align: center;
    }
:where(body[data-page="calculator"]) .slot-img { width: 42px; height: 32px; flex-shrink: 0; }
:where(body[data-page="calculator"]) .slot-img img { width: 100%; height: 100%; object-fit: contain; border-radius: 3px; }
:where(body[data-page="calculator"]) .slot-img-placeholder { width: 42px; height: 32px; background: var(--bg); border-radius: 3px; border: 1px dashed var(--border); display: flex; align-items: center; justify-content: center; }
:where(body[data-page="calculator"]) .slot-info { flex: 1; min-width: 0; }
:where(body[data-page="calculator"]) .slot-name { font-size: 0.68rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:where(body[data-page="calculator"]) .slot-sub { font-size: 0.62rem; color: var(--muted); margin-top: 1px; }
:where(body[data-page="calculator"]) .slot-price { font-size: 0.7rem; color: var(--accent); font-weight: 600; }
:where(body[data-page="calculator"]) .slot-fill, :where(body[data-page="calculator"]) .slot-copy1, :where(body[data-page="calculator"]) .slot-clear {
      position: absolute; top: 4px; background: none; border: none; cursor: pointer;
      line-height: 1; padding: 2px 4px; border-radius: 4px; color: var(--muted);
      transition: background var(--transition), color var(--transition);
    }
:where(body[data-page="calculator"]) .slot-clear { right: 6px;  font-size: 0.95rem; }
:where(body[data-page="calculator"]) .slot-copy1 { right: 28px; font-size: 0.66rem; font-weight: 700; }
:where(body[data-page="calculator"]) .slot-fill { right: 50px; font-size: 0.82rem; }
:where(body[data-page="calculator"]) .slot-clear:hover { color: var(--red); background: rgba(235,75,75,0.12); }
:where(body[data-page="calculator"]) .slot-fill:hover, :where(body[data-page="calculator"]) .slot-copy1:hover { color: var(--accent); background: var(--accent-subtle, rgba(242,193,78,0.12)); }

    /* Per-slot exact float + price editing */
:where(body[data-page="calculator"]) .slot { flex-wrap: wrap; align-items: flex-start; cursor: default; }
:where(body[data-page="calculator"]) .slot.filled .slot-img, :where(body[data-page="calculator"]) .slot.filled .slot-info { cursor: pointer; }
:where(body[data-page="calculator"]) .slot-edit { display: flex; gap: 6px; width: 100%; margin-top: 6px; }
:where(body[data-page="calculator"]) .slot-edit .ef { flex: 1; display: flex; flex-direction: column; gap: 2px; }
:where(body[data-page="calculator"]) .slot-edit label { font-size: 0.55rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
:where(body[data-page="calculator"]) .slot-edit input {
      background: var(--bg); border: 1px solid var(--border); color: var(--text);
      border-radius: 5px; padding: 5px 7px; font-size: 0.8rem; font-weight: 600; font-family: var(--font-num); width: 100%;
    }
:where(body[data-page="calculator"]) .slot-edit input:focus { outline: none; border-color: var(--accent); }
:where(body[data-page="calculator"]) .slot-edit input.bad { border-color: var(--red); }
:where(body[data-page="calculator"]) .add-to-all {
      margin-bottom: 8px;
      font-size: 0.75rem;
      color: var(--muted);
    }
:where(body[data-page="calculator"]) .calc-actions { display: flex; gap: 8px; margin-top: 12px; }
:where(body[data-page="calculator"]) .calc-btn {
      flex: 1;
      padding: 11px;
      border-radius: 7px;
      border: none;
      font-size: 0.85rem;
      font-weight: 600;
      cursor: pointer;
      transition: opacity 0.15s;
    }
:where(body[data-page="calculator"]) .calc-btn:disabled { opacity: 0.4; cursor: not-allowed; }
:where(body[data-page="calculator"]) .calc-btn.primary { background: var(--accent); color: #000; }
:where(body[data-page="calculator"]) .calc-btn.secondary { background: var(--panel); color: var(--text); border: 1px solid var(--border); }
:where(body[data-page="calculator"]) .validation-msg { font-size: 0.75rem; color: var(--red); margin-top: 8px; min-height: 18px; }

    /* ── Results panel ── */
:where(body[data-page="calculator"]) .results-panel {
      padding: 20px;
      display: flex;
      flex-direction: column;
      gap: 14px;
    }
:where(body[data-page="calculator"]) .results-panel h2 { font-size: 0.85rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }
:where(body[data-page="calculator"]) .calc-empty {
      display: flex; flex-direction: column; align-items: center; text-align: center;
      gap: 8px; padding: 48px 20px; color: var(--muted);
      border: 1px dashed var(--border); border-radius: 12px; margin-top: 8px;
    }
:where(body[data-page="calculator"]) .calc-empty svg { width: 44px; height: 44px; color: var(--accent); opacity: 0.85; }
:where(body[data-page="calculator"]) .calc-empty-title { font-size: 0.95rem; font-weight: 600; color: var(--text); margin-top: 4px; }
:where(body[data-page="calculator"]) .calc-empty p { font-size: 0.78rem; line-height: 1.5; max-width: 300px; }
:where(body[data-page="calculator"]) .calc-empty-tip { font-size: 0.7rem; opacity: 0.8; }
:where(body[data-page="calculator"]) .summary-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 8px;
    }
:where(body[data-page="calculator"]) .summary-card {
      background: var(--panel);
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 10px 12px;
    }
:where(body[data-page="calculator"]) .summary-card .k { font-size: 0.65rem; color: var(--muted); }
:where(body[data-page="calculator"]) .summary-card .v { font-size: 1rem; font-weight: 600; margin-top: 2px; }
    /* ── Skin picker modal ── */
:where(body[data-page="calculator"]) .picker-modal { width: min(660px, 95vw); max-height: 82vh; display: flex; flex-direction: column; }

    /* TradeupSpy-style filter bar — matches the Finder filter system */
:where(body[data-page="calculator"]) .picker-filterbar {
      display: flex;
      flex-wrap: wrap;
      gap: 12px 14px;
      align-items: flex-end;
      margin-bottom: 14px;
    }
:where(body[data-page="calculator"]) .picker-filterbar .pf-field { display: flex; flex-direction: column; gap: 6px; }
:where(body[data-page="calculator"]) .picker-filterbar .pf-field > label { margin: 0; }
:where(body[data-page="calculator"]) .picker-filterbar .pf-skin { flex: 1 1 200px; min-width: 170px; }
:where(body[data-page="calculator"]) .picker-filterbar .pf-col, :where(body[data-page="calculator"]) .picker-filterbar .pf-rarity, :where(body[data-page="calculator"]) .picker-filterbar .pf-sort { flex: 1 1 130px; min-width: 120px; }
:where(body[data-page="calculator"]) .picker-filterbar .pf-condition { flex: 1 1 100%; }
:where(body[data-page="calculator"]) .picker-filterbar .pf-fillall { align-items: center; gap: 8px; }
:where(body[data-page="calculator"]) .pf-search { position: relative; display: flex; align-items: center; }
:where(body[data-page="calculator"]) .pf-search svg { position: absolute; left: 11px; width: 15px; height: 15px; stroke: var(--muted); pointer-events: none; }
:where(body[data-page="calculator"]) .pf-search input { padding-left: 34px; }

    /* Skin results — card grid (à la TradeupSpy) */
:where(body[data-page="calculator"]) .picker-list {
      overflow-y: auto; flex: 1;
      display: grid; grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
      grid-auto-rows: max-content; align-items: start; align-content: start;
      gap: 10px; padding: 2px;
    }
:where(body[data-page="calculator"]) .picker-card {
      display: flex; flex-direction: column;
      background: var(--panel); border: 1px solid var(--border);
      border-top: 3px solid var(--rc, var(--border));
      border-radius: 9px;
      transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
    }
:where(body[data-page="calculator"]) .pc-head { border-radius: 6px 6px 0 0; }
:where(body[data-page="calculator"]) .pc-wears { border-radius: 0 0 8px 8px; }
:where(body[data-page="calculator"]) .picker-card:hover { border-color: var(--border-hover); transform: translateY(-2px); box-shadow: var(--shadow-md); }
:where(body[data-page="calculator"]) .pc-head { padding: 8px 8px 4px; text-align: center; }
:where(body[data-page="calculator"]) .pc-weapon { font-size: 0.74rem; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:where(body[data-page="calculator"]) .pc-finish { font-size: 0.68rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:where(body[data-page="calculator"]) .pc-img {
      position: relative; height: 76px; display: flex; align-items: center; justify-content: center;
      padding: 2px 8px;
      background: radial-gradient(ellipse at 50% 60%, color-mix(in srgb, var(--rc, #000) 16%, transparent), transparent 70%);
    }
:where(body[data-page="calculator"]) .pc-img img { max-width: 100%; max-height: 100%; object-fit: contain; }
:where(body[data-page="calculator"]) .pc-rdot { position: absolute; top: 6px; right: 7px; width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 7px -1px currentColor; }
:where(body[data-page="calculator"]) .pc-meta {
      display: flex; align-items: center; gap: 5px;
      padding: 5px 8px; border-top: 1px solid var(--line-soft);
      font-size: 0.6rem; color: var(--muted);
    }
:where(body[data-page="calculator"]) .pc-coll { width: 18px; height: 18px; object-fit: contain; flex-shrink: 0; }
:where(body[data-page="calculator"]) .pc-coll-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:where(body[data-page="calculator"]) .pc-float { margin-left: auto; font-family: var(--font-num); white-space: nowrap; flex-shrink: 0; }
:where(body[data-page="calculator"]) .pc-wears { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px 8px; }
:where(body[data-page="calculator"]) .wear-chip {
      display: block; text-align: center;
      padding: 5px 8px; border-radius: 5px;
      background: var(--filter-fill); border: 1px solid var(--border);
      color: var(--text-2); cursor: pointer; font-size: 0.68rem; font-weight: 600;
      transition: border-color 0.12s, color 0.12s, background 0.12s;
    }
:where(body[data-page="calculator"]) .wear-chip:hover { border-color: var(--accent); color: var(--text); background: var(--accent-subtle); }
:where(body[data-page="calculator"]) .wear-chip.st { border-color: rgba(201,127,0,0.4); color: var(--accent-dim); }
:where(body[data-page="calculator"]) .wear-chip.no-price { opacity: 0.4; cursor: not-allowed; }
:where(body[data-page="calculator"]) .wear-chip.no-price:hover { border-color: var(--border); color: var(--text-2); background: var(--filter-fill); }
:where(body[data-page="calculator"]) .picker-hint { grid-column: 1 / -1; font-size: 0.78rem; color: var(--muted); text-align: center; padding: 28px 0; }
    /* 900px, not the original 700px — raised together with the 460px results
       panel above. At the historically-regressed 821–900px band (see
       .dtable-wrap's own comment elsewhere in this file) this page is now
       single-column, so the results table gets the full content width
       instead of being squeezed into a narrow side column at exactly the
       width that has broken twice before. */
@media (max-width: 900px) {
:where(body[data-page="calculator"]) .calc-layout { grid-template-columns: 1fr; }
:where(body[data-page="calculator"]) .inputs-panel { border-right: none; border-bottom: 1px solid var(--border); }
}
    /* Independent of the 900px layout collapse above — a phone-width slot
       still wants one column regardless of whether the results panel is
       beside it or stacked below it. */
@media (max-width: 480px) {
:where(body[data-page="calculator"]) .slot-grid { grid-template-columns: 1fr; }
}

    /* ── Slot progress bar (filled / 10) ── */
:where(body[data-page="calculator"]) .slot-progress { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
:where(body[data-page="calculator"]) .slot-progress-bar { flex: 1; height: 3px; background: var(--border); border-radius: 99px; overflow: hidden; }
:where(body[data-page="calculator"]) .slot-progress-fill { height: 100%; background: var(--accent); border-radius: 99px; transition: width 0.3s ease; }
:where(body[data-page="calculator"]) .slot-progress-label { font-size: 0.72rem; color: var(--muted); white-space: nowrap; font-family: var(--font-num); min-width: 40px; text-align: right; }

    /* ── Rarity accent on filled slots (matches picker-card style) ── */
:where(body[data-page="calculator"]) .slot.filled { border-top: 3px solid var(--slot-rc, var(--border)); padding-top: 7px; }

    /* ── Empty slots: dashed "add" affordance ── */
:where(body[data-page="calculator"]) .slot.empty { border-style: dashed; background: transparent; }
:where(body[data-page="calculator"]) .slot.empty:hover { background: var(--accent-subtle); }
:where(body[data-page="calculator"]) .slot.empty .slot-name { color: var(--muted); transition: color 0.15s; }
:where(body[data-page="calculator"]) .slot.empty:hover .slot-name { color: var(--accent); }
:where(body[data-page="calculator"]) .slot.empty svg { stroke: var(--border); transition: stroke 0.15s; }
:where(body[data-page="calculator"]) .slot.empty:hover svg { stroke: var(--accent); }

    /* ── Verdict banner (profit / ROI hero) ── */
:where(body[data-page="calculator"]) .verdict-banner {
      display: flex; align-items: center; justify-content: space-between; gap: 12px;
      padding: 13px 16px; border-radius: 10px; border: 1px solid var(--border);
    }
:where(body[data-page="calculator"]) .verdict-banner.pos { background: var(--green-glow); border-color: color-mix(in srgb, var(--green) 45%, transparent); }
:where(body[data-page="calculator"]) .verdict-banner.neg { background: var(--red-glow); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
:where(body[data-page="calculator"]) .verdict-banner .vb-label { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); margin-bottom: 2px; }
:where(body[data-page="calculator"]) .verdict-banner .vb-profit { font-size: 1.45rem; font-weight: 700; font-family: var(--font-num); line-height: 1.1; }
:where(body[data-page="calculator"]) .verdict-banner .vb-roi { font-size: 0.9rem; font-weight: 700; font-family: var(--font-num); padding: 5px 12px; border-radius: 99px; background: var(--panel); border: 1px solid var(--border); white-space: nowrap; }
:where(body[data-page="calculator"]) .verdict-banner.pos .vb-profit, :where(body[data-page="calculator"]) .verdict-banner.pos .vb-roi { color: var(--green); }
:where(body[data-page="calculator"]) .verdict-banner.neg .vb-profit, :where(body[data-page="calculator"]) .verdict-banner.neg .vb-roi { color: var(--red); }

    /* Summary cards: numeric face for values */
:where(body[data-page="calculator"]) .summary-card .v { font-family: var(--font-num); font-weight: 700; }

    /* ── Sticky results panel (desktop) ──
       Breakpoint matches the .calc-layout two-column media query below (901px)
       — the two must move together, or the panel would try to stick/scroll
       independently while the page is still in its single-column stack.

       `top: 56px`, not `0` — the known trap this component has to avoid: the
       site's own nav <header> (styles.css:137) is ALSO `position: sticky;
       top: 0; height: 56px; z-index: 200`. A panel stuck at literal top:0
       sticks to the true viewport top and ends up VISUALLY BEHIND the first
       56px of the nav header (proven with a scroll probe + elementFromPoint:
       the panel's own rect reported top:0 while elementFromPoint at that
       point still resolved to the nav header, not the panel — a plain
       screenshot of the page TOP would never have caught this, because
       nothing is scrolled yet at that vantage point). `max-height` drops by
       the same 56px so the panel's own internal scroll area doesn't extend
       past the visible viewport at the bottom. */
@media (min-width: 901px) {
:where(body[data-page="calculator"]) .results-panel { position: sticky; top: 56px; align-self: start; max-height: calc(100vh - 56px); overflow-y: auto; }
}

    /* ── Possible-outputs table (.dtable) ──────────────────────────────────
       Every rule below chains BOTH the shared class and the page-scoped one
       on the same element (`.dtable-wrap.calc-table-wrap`, `.dtable.calc-
       dtable`, …) ON PURPOSE — the exact discipline results.html's own
       `.rs-dtable` block documents. `:where()` contributes zero specificity,
       so a rule written as a BARE page-scoped class (`.calc-table-wrap`
       alone) ties the shared component's own selector on specificity, and
       since the shared block is defined LATER in this file, the tie is
       resolved by source order — in the shared rule's favour. Every
       selector here is deliberately built to OUTRANK the shared one on
       specificity alone, so none of this depends on where either block sits
       in the file. */
:where(body[data-page="calculator"]) .dtable-wrap.calc-table-wrap {
      max-width: none; padding: 0; margin-top: 8px;
      /* The panel itself scrolls (results-panel's own `overflow-y: auto`),
         so unlike /skins and /flips this wrapper is never the horizontal
         scroller — there's no room for one at 460px regardless. Columns are
         dropped instead (below), narrowest viewport first. */
      overflow-x: visible;
    }
    /* `table-layout: fixed` — same load-bearing reason results.html's
       `.rs-dtable` uses it: this table lives in a column far narrower than
       the page (460px desktop, full-width when stacked below 901px), so the
       default `auto` layout would let one long output name hold every
       column open and push the table past its container. Fixed layout makes
       the declared widths below authoritative and leaves the name column,
       deliberately unwidthed, to absorb whatever space remains. */
:where(body[data-page="calculator"]) .dtable.calc-dtable { min-width: 0; table-layout: fixed; font-size: 0.72rem; }
:where(body[data-page="calculator"]) .dtable.calc-dtable thead th { padding: 5px 6px; }
:where(body[data-page="calculator"]) .dtable.calc-dtable tbody td { padding: 5px 6px; }
    /* `.dtable.calc-dtable tbody td` above and the shared `.dtable tbody
       td:first-child { padding-left: 10px; border-left: 3px solid var(--rc,
       transparent); }` both resolve to specificity (0,2,2) — a genuine tie,
       so without this line the shared rule's LATER position in the file
       would win it and the first column would keep 10px instead of this
       table's 6px. One more class than either op alone is enough to
       outrank both unconditionally, matching every other `.calc-dtable`
       override's own "outrank on specificity" rule (see the block comment
       above) rather than leaving a documented exception to it. */
:where(body[data-page="calculator"]) .dtable.calc-dtable tbody td:first-child { padding-left: 6px; }
    /* This `top: 0` ONLY holds at >=901px, matching the .results-panel media
       query above — that is when the panel is its OWN independently-
       scrolling column (own `overflow-y: auto`) and the shared `.dtable
       thead th { top: 56px }` rule (which clears the SITE header for a
       page-scrolling table) would leave a 56px gap here instead. Below
       901px the panel stacks full-width and the PAGE itself is what
       scrolls — there the shared 56px rule is exactly right and must NOT be
       overridden, or the column headers stick under the site's own nav
       header (proven with the same scroll-probe + elementFromPoint
       technique used for the panel fix above: at 768px, scrolling past
       Possible Outputs pinned the header row at the true viewport top,
       behind the opaque nav). Selector still outranks the shared rule on
       specificity (.dtable.calc-dtable thead th = 2 classes vs .dtable
       thead th = 1), so this only takes effect where the media query lets
       it match at all — never a source-order race. */
@media (min-width: 901px) {
:where(body[data-page="calculator"]) .dtable.calc-dtable thead th { top: 0; }
}
:where(body[data-page="calculator"]) .dtable.calc-dtable thead th.col-thumb { width: 34px; padding-left: 8px; padding-right: 4px; }
:where(body[data-page="calculator"]) .calc-dtable .dtable-thumb, :where(body[data-page="calculator"]) .calc-dtable .dtable-thumb-empty { width: 30px; height: 22px; }
:where(body[data-page="calculator"]) .calc-dtable th.col-chance { width: 44px; }
:where(body[data-page="calculator"]) .calc-dtable th.col-price { width: 54px; }
:where(body[data-page="calculator"]) .calc-dtable th.col-net { width: 54px; }
:where(body[data-page="calculator"]) .calc-dtable th.col-hit { width: 60px; }
:where(body[data-page="calculator"]) .calc-dtable th.col-evc { width: 82px; }
:where(body[data-page="calculator"]) .dtable.calc-dtable td.cell-name { max-width: none; }
:where(body[data-page="calculator"]) .calc-dtable .dtable-name { font-size: 0.72rem; }
:where(body[data-page="calculator"]) .calc-dtable .dtable-sub { font-size: 0.6rem; }
:where(body[data-page="calculator"]) .calc-dtable td.col-chance,
:where(body[data-page="calculator"]) .calc-dtable td.col-price,
:where(body[data-page="calculator"]) .calc-dtable td.col-net,
:where(body[data-page="calculator"]) .calc-dtable td.col-hit {
      font-family: var(--font-num); font-variant-numeric: tabular-nums; white-space: nowrap;
    }
:where(body[data-page="calculator"]) .calc-dtable td.col-hit.pos { color: var(--green); }
:where(body[data-page="calculator"]) .calc-dtable td.col-hit.neg { color: var(--red); }
    /* EV-contribution cell: the finder's own `.tile-ev*` bar classes
       (global, unscoped — see the finder card component), reused verbatim
       rather than a second bar implementation. */
:where(body[data-page="calculator"]) .calc-dtable .col-evc .tile-ev { padding: 0; justify-content: flex-end; cursor: default; }
:where(body[data-page="calculator"]) .calc-dtable .col-evc .tile-ev-bar { flex: 0 0 28px; }
:where(body[data-page="calculator"]) .calc-dtable .col-evc .tile-ev-val { font-size: 0.68rem; }
:where(body[data-page="calculator"]) .dtable.calc-dtable tbody tr:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

@media (max-width: 560px) {
  :where(body[data-page="calculator"]) .calc-dtable .col-price { display: none; }
}
@media (max-width: 460px) {
  :where(body[data-page="calculator"]) .calc-dtable .col-chance { display: none; }
}
@media (max-width: 400px) {
  :where(body[data-page="calculator"]) .calc-dtable .col-thumb { display: none; }
}

    /* ── Calculating state (brief, while the auto-recalc request is in flight) ── */
:where(body[data-page="calculator"]) #resultsArea.calculating { opacity: 0.45; pointer-events: none; }
:where(body[data-page="calculator"]) #resultsArea { transition: opacity 0.15s; }


/* ── page: dashboard ─────────────────────────────────────────────── */
:where(body[data-page="dashboard"]) .db-wrap { max-width: 1180px; margin: 0 auto; padding: 24px 20px 80px; }
:where(body[data-page="dashboard"]) .db-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
:where(body[data-page="dashboard"]) .db-head h1 { font-size: 1.4rem; font-weight: 700; }
:where(body[data-page="dashboard"]) .db-head .sub { color: var(--muted); font-size: 0.8rem; }
:where(body[data-page="dashboard"]) .db-head .spacer { flex: 1; }
:where(body[data-page="dashboard"]) .db-section-title { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); margin: 26px 0 10px; }
/* .db-card is gone (→ the shared .stat-tile). .stat-tile only ships .pos/.neg
   as colour hooks; "Pro (active)" reuses the dashboard's own gold highlight,
   which nothing else needs, so it stays page-scoped rather than joining the
   shared component's contract. */
:where(body[data-page="dashboard"]) .stat-tile .accent { color: var(--accent); }
:where(body[data-page="dashboard"]) .db-panel {
      background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg);
      padding: 16px 18px;
    }
:where(body[data-page="dashboard"]) .db-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 760px) {
:where(body[data-page="dashboard"]) .db-grid2 { grid-template-columns: 1fr; }
}

    /* Bar charts (14-day signups, 30-day traffic) — geometry now comes from
       the shared static/dashboard-charts.js, not two copies of inline math. */
:where(body[data-page="dashboard"]) .db-trend { display: flex; align-items: flex-end; gap: 5px; height: 120px; padding-top: 8px; }
:where(body[data-page="dashboard"]) .db-bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
:where(body[data-page="dashboard"]) .db-bar-track { flex: 1; width: 100%; display: flex; align-items: flex-end; }
:where(body[data-page="dashboard"]) .db-bar { width: 100%; border-radius: 4px 4px 0 0; transition: filter var(--transition), background var(--transition), border-color var(--transition); }
/* A real value: a solid mark (10.6:1 contrast on its own — see the --chart-1
   comment in :root), never the old ~8%-opacity wash propped up by a border. */
:where(body[data-page="dashboard"]) .db-bar.has { background: var(--chart-1); min-height: 2px; }
:where(body[data-page="dashboard"]) .db-bar.has:hover { filter: brightness(1.15); }
/* An explicit zero: a small solid baseline mark in a neutral (non-accent)
   ink — present and legible, but never confusable with a real magnitude. */
:where(body[data-page="dashboard"]) .db-bar.zero { height: 4px; background: var(--muted); border-radius: 2px; }
/* No data at all for that day: a hollow dashed outline — deliberately the
   most recessive of the three states, and never a solid fill of any colour,
   so it can never be mistaken for "zero" (a bug this replaces: both used to
   render as the same near-invisible 2px sliver). */
:where(body[data-page="dashboard"]) .db-bar.nodata { height: 4px; background: transparent; border: 1px dashed var(--line-soft); border-radius: 2px; }
:where(body[data-page="dashboard"]) .db-bar-day { font-size: 0.58rem; color: var(--muted); font-family: var(--font-num); }
:where(body[data-page="dashboard"]) .db-dtable { font-size: 0.82rem; }
:where(body[data-page="dashboard"]) .db-pill { font-size: 0.62rem; padding: 1px 7px; border-radius: 99px; }
:where(body[data-page="dashboard"]) .db-pill.pro { background: rgba(242,193,78,0.13); color: var(--accent); }
:where(body[data-page="dashboard"]) .db-pill.steam { background: rgba(52,217,155,0.13); color: var(--green); }
/* `.dtable tbody td` (specificity 0,1,2) beats a bare `.db-empty` (0,1,0),
   so padding/text-align here were silently dead — verified with
   getComputedStyle (rendered flush right at 6px/10px). Raised via the cell
   itself (`.dtable tbody td.db-empty`, specificity 0,2,2) instead of
   !important. */
:where(body[data-page="dashboard"]) .dtable tbody td.db-empty { color: var(--muted); font-size: 0.8rem; padding: 14px 8px; text-align: left; }
:where(body[data-page="dashboard"]) .db-status { color: var(--muted); padding: 60px 20px; text-align: center; }
:where(body[data-page="dashboard"]) .db-gate { max-width: 460px; margin: 60px auto; text-align: center; background: var(--panel);
      border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 32px 28px; }
:where(body[data-page="dashboard"]) .db-gate h2 { font-size: 1.1rem; margin-bottom: 8px; }
:where(body[data-page="dashboard"]) .db-gate p { color: var(--muted); font-size: 0.85rem; margin-bottom: 18px; }


/* ── page: faq ───────────────────────────────────────────────────── */
:where(body[data-page="faq"]) .faq-list { margin-top: 24px; display: flex; flex-direction: column; gap: 10px; }
:where(body[data-page="faq"]) .faq-item {
      background: var(--panel); border: 1px solid var(--border);
      border-radius: var(--radius-lg); overflow: hidden;
      transition: border-color var(--transition);
    }
:where(body[data-page="faq"]) .faq-item.open { border-color: var(--border-hover); }
:where(body[data-page="faq"]) .faq-q {
      display: flex; align-items: center; justify-content: space-between; gap: 14px;
      width: 100%; text-align: left; cursor: pointer;
      background: none; border: none; color: var(--text);
      font-size: 0.92rem; font-weight: 600; font-family: inherit;
      padding: 16px 18px;
    }
:where(body[data-page="faq"]) .faq-q:hover { color: var(--accent); }
:where(body[data-page="faq"]) .faq-chev { flex-shrink: 0; transition: transform var(--transition); color: var(--muted); }
:where(body[data-page="faq"]) .faq-item.open .faq-chev { transform: rotate(180deg); color: var(--accent); }
:where(body[data-page="faq"]) .faq-a {
      max-height: 0; overflow: hidden;
      transition: max-height var(--transition), padding var(--transition);
      padding: 0 18px;
      color: var(--text-2); font-size: 0.86rem; line-height: 1.6;
    }
:where(body[data-page="faq"]) .faq-item.open .faq-a { max-height: 420px; padding: 0 18px 18px; }
:where(body[data-page="faq"]) .faq-a a { color: var(--accent); }
:where(body[data-page="faq"]) .faq-a code {
      background: var(--surface-2); border: 1px solid var(--border);
      border-radius: 4px; padding: 1px 5px; font-size: 0.82em;
    }


/* ── page: home — redesign plan §4.7 ─────────────────────────────────
   Rebuilt from a hero + 7-link grid + two card grids into a single-screen
   sell: hero → live proof (a real contract) → trust strip → how-it-works →
   compact top-trade-ups/top-flips tables → one closing CTA. The old `.ql`
   quick-link grid and the home half of the shared `.cards`/`.card` recipe
   (moved above, now inventory-only) are deleted here, not migrated — the
   same rule §4.3/§4.5 used when `.igrid` was replaced by `.dtable`. */
:where(body[data-page="home"]) .home { max-width: 1180px; margin: 0 auto; padding: 0 20px 90px; }

    /* Hero */
:where(body[data-page="home"]) .hero {
      position: relative; text-align: center; padding: 70px 20px 40px; overflow: hidden;
    }
:where(body[data-page="home"]) .hero::before {
      content: ""; position: absolute; inset: -40% 0 auto 0; height: 420px; z-index: -1;
      background: radial-gradient(60% 100% at 50% 0%, var(--accent-glow), transparent 70%);
      pointer-events: none;
    }
:where(body[data-page="home"]) .hero-eyebrow {
      display: inline-block; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.12em;
      text-transform: uppercase; color: var(--accent); padding: 5px 12px; border-radius: 99px;
      border: 1px solid rgba(242,193,78,0.3); background: var(--accent-subtle); margin-bottom: 20px;
    }
:where(body[data-page="home"]) .hero h1 { font-size: clamp(2rem, 5vw, 3.2rem); font-weight: 800; line-height: 1.05; letter-spacing: -0.02em; }
:where(body[data-page="home"]) .hero h1 .grad { background: linear-gradient(120deg, var(--gold), var(--gold-deep)); -webkit-background-clip: text; background-clip: text; color: transparent; }
:where(body[data-page="home"]) .hero p { color: var(--text-2); font-size: 1.02rem; max-width: 620px; margin: 18px auto 0; }
:where(body[data-page="home"]) .hero-cta { display: flex; gap: 12px; justify-content: center; margin-top: 30px; flex-wrap: wrap; }
    /* The one demoted text link the spec allows alongside the primary CTA —
       deliberately NOT a second `.btn` (two buttons of equal visual weight
       would undercut the "one CTA" rule). */
:where(body[data-page="home"]) .hero-secondary {
      display: block; text-align: center; margin-top: 12px; font-size: 0.82rem;
      color: var(--muted); text-decoration: none;
    }
:where(body[data-page="home"]) .hero-secondary:hover { color: var(--accent); }

:where(body[data-page="home"]) .sec-head a { margin-left: auto; font-size: 0.8rem; color: var(--accent); text-decoration: none; }
:where(body[data-page="home"]) .sec-head a:hover { text-decoration: underline; }

    /* Sign colour, page-scoped like every sibling (results.html/calculator.html
       each define their own — a shared global would be too broad a change). */
:where(body[data-page="home"]) .pos { color: var(--green); }
:where(body[data-page="home"]) .neg { color: var(--red); }

    /* A plain status line (loading/empty/error) that isn't tied to a grid —
       distinct from inventory's `.home-status` above, which still assumes a
       `.cards` grid parent to span. */
:where(body[data-page="home"]) .home-status {
      padding: 30px; text-align: center; color: var(--muted); font-size: 0.85rem;
    }

    /* ── Live proof panel — the centrepiece ──────────────────────────────
       One real, currently-#1 contract (or an honestly-labelled fallback),
       laid out as inputs → output with the metric row underneath. */
:where(body[data-page="home"]) .proof { margin: 44px 0 28px; }
:where(body[data-page="home"]) .proof-head {
      display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
    }
:where(body[data-page="home"]) .proof-head h2 { font-size: 1.3rem; font-weight: 700; }
:where(body[data-page="home"]) .proof-sub { font-size: 0.8rem; color: var(--muted); }
:where(body[data-page="home"]) .proof-empty {
      padding: 40px; text-align: center; color: var(--muted); background: var(--panel);
      border: 1px dashed var(--border); border-radius: var(--radius-lg);
    }
:where(body[data-page="home"]) .proof-empty a { color: var(--accent); }
:where(body[data-page="home"]) .proof-panel {
      background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg);
      padding: 22px; display: flex; flex-direction: column; gap: 18px;
    }
    /* The fallback (no contract clears break-even) must be UNMISTAKABLE, not
       an 8% opacity tweak against `.proof-panel`'s own default border (that
       first version was a visual no-op — proved live, every roi<=0 contract
       still rendered as a normal-looking "win" panel). A dashed border plus
       an explicit badge is the same "this is an honest-truth signal, not a
       verdict" mechanism `.card.buildable`'s left accent uses elsewhere,
       kept off colour on purpose (§2.1 reserves green/red for profit/loss). */
:where(body[data-page="home"]) .proof-panel-flat { border-style: dashed; border-color: var(--border-hover); }
:where(body[data-page="home"]) .proof-flat-badge {
      align-self: flex-start; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.06em;
      text-transform: uppercase; color: var(--muted); background: var(--surface-2);
      border: 1px solid var(--border); border-radius: 99px; padding: 4px 10px;
    }
:where(body[data-page="home"]) .proof-io {
      display: grid; grid-template-columns: 1fr auto 1fr; gap: 20px; align-items: start;
    }
:where(body[data-page="home"]) .proof-io-label {
      font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted);
      margin-bottom: 10px;
    }
:where(body[data-page="home"]) .proof-arrow {
      align-self: center; font-size: 1.4rem; color: var(--accent); margin-top: 20px;
    }
:where(body[data-page="home"]) .proof-stacks { display: flex; flex-direction: column; gap: 8px; }
:where(body[data-page="home"]) .proof-stack {
      display: flex; align-items: center; gap: 10px; background: var(--surface-0);
      border: 1px solid var(--line-soft); border-radius: var(--radius-sm); padding: 7px 10px;
    }
:where(body[data-page="home"]) .proof-stack-img {
      width: 40px; height: 30px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
    }
:where(body[data-page="home"]) .proof-stack-img img { max-width: 100%; max-height: 100%; object-fit: contain; }
:where(body[data-page="home"]) .proof-stack-info { min-width: 0; }
:where(body[data-page="home"]) .proof-stack-name {
      font-size: 0.8rem; font-weight: 600; color: var(--text);
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
:where(body[data-page="home"]) .proof-stack-sub { font-size: 0.68rem; color: var(--muted); }
:where(body[data-page="home"]) .proof-in-total {
      margin-top: 10px; font-size: 0.82rem; color: var(--text-2);
    }
:where(body[data-page="home"]) .proof-in-total b { font-family: var(--font-num); color: var(--text); }
:where(body[data-page="home"]) .proof-out-tile {
      background: var(--surface-0); border: 1px solid var(--line-soft); border-radius: var(--radius-md);
      padding: 16px; text-align: center;
    }
:where(body[data-page="home"]) .proof-out-img { height: 76px; display: flex; align-items: center; justify-content: center; }
:where(body[data-page="home"]) .proof-out-img img { max-height: 72px; max-width: 90%; object-fit: contain; }
:where(body[data-page="home"]) .proof-out-name { font-weight: 700; font-size: 0.92rem; margin-top: 8px; }
:where(body[data-page="home"]) .proof-out-wear { font-weight: 400; color: var(--muted); }
:where(body[data-page="home"]) .proof-out-prob { font-size: 0.74rem; color: var(--accent); margin-top: 4px; }
:where(body[data-page="home"]) .proof-metrics { margin: 0; }
:where(body[data-page="home"]) .proof-honest { font-size: 0.76rem; color: var(--muted); line-height: 1.5; margin: 0; }
:where(body[data-page="home"]) .proof-cta { align-self: flex-start; }

@media (max-width: 700px) {
  :where(body[data-page="home"]) .proof-io { grid-template-columns: 1fr; }
  :where(body[data-page="home"]) .proof-arrow { display: none; }
  :where(body[data-page="home"]) .proof-cta { align-self: stretch; justify-content: center; }
}

    /* ── How it works ──────────────────────────────────────────────────── */
:where(body[data-page="home"]) .how { margin: 44px 0; }
:where(body[data-page="home"]) .how h2 { font-size: 1.3rem; font-weight: 700; margin-bottom: 16px; }
:where(body[data-page="home"]) .how-steps {
      list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
    }
:where(body[data-page="home"]) .how-steps li {
      display: flex; gap: 12px; align-items: flex-start; background: var(--panel);
      border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px;
    }
:where(body[data-page="home"]) .how-num {
      flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%; background: var(--accent-subtle);
      color: var(--accent); font-weight: 700; font-size: 0.82rem; display: flex; align-items: center;
      justify-content: center;
    }
:where(body[data-page="home"]) .how-steps p { font-size: 0.84rem; color: var(--text-2); line-height: 1.5; margin: 0; }
@media (max-width: 700px) {
  :where(body[data-page="home"]) .how-steps { grid-template-columns: 1fr; }
}

    /* ── Top Trade-Ups / Top Flips tables — chain BOTH classes on the same
       element so this never ties `.dtable` on specificity (see inventory's
       identical note above); ~5/~3 preview rows, no pagination/sort. */
:where(body[data-page="home"]) .dtable-wrap.home-table-wrap { max-width: none; padding: 0; }
:where(body[data-page="home"]) .dtable.home-dtable { min-width: 0; table-layout: fixed; }
:where(body[data-page="home"]) .home-dtable th.col-thumb { width: 46px; }
:where(body[data-page="home"]) .home-dtable th.col-conf { width: 52px; }
:where(body[data-page="home"]) .home-dtable th:not(.col-thumb):not(.col-name):not(.col-conf) { width: 96px; }
    /* Below ~560px the fixed metric columns (up to 3 × 96px + a 46px thumb)
       outweigh the viewport and squeeze the name column to 0 — measured on a
       360px phone, the exact "Trade-up"/"Item" column this table exists to
       show. The capital figure (Cost / Buy) must STAY on screen here — a
       five/six-figure profit claim with no visible cost anywhere reads as
       fabricated, especially now that Top Flips shows real dollar spreads
       (§4.7 fix). Drop the thumbnail and the confidence pill instead
       (mirrors /arbitrage's own `.col-conf` drop at <=700px) and shrink the
       remaining metric columns — the same column-hiding move inventory.html's
       `.inv-dtable` makes at 480px, just choosing a different column. */
@media (max-width: 560px) {
  :where(body[data-page="home"]) .home-dtable th:not(.col-thumb):not(.col-name):not(.col-conf) { width: 64px; }
  :where(body[data-page="home"]) .home-dtable .col-thumb,
  :where(body[data-page="home"]) .home-dtable .col-conf { display: none; }
}

    /* ── Final CTA band ───────────────────────────────────────────────── */
:where(body[data-page="home"]) .final-cta {
      margin: 60px 0 10px; padding: 40px 20px; text-align: center; background: var(--panel);
      border: 1px solid var(--border); border-radius: var(--radius-lg);
    }
:where(body[data-page="home"]) .final-cta h2 { font-size: 1.3rem; font-weight: 700; margin-bottom: 16px; }


/* ── page: inventory ─────────────────────────────────────────────── */
:where(body[data-page="inventory"]) .inv { max-width: 1180px; margin: 0 auto; padding: 24px 20px 90px; }
:where(body[data-page="inventory"]) .inv-head h1 { font-size: 1.4rem; font-weight: 700; }
:where(body[data-page="inventory"]) .inv-head p { color: var(--muted); font-size: 0.85rem; margin-top: 6px; }
:where(body[data-page="inventory"]) .inv-bar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 16px 0 8px; }
:where(body[data-page="inventory"]) .inv-bar input {
      flex: 1; min-width: 220px; background: var(--bg); border: 1px solid var(--border); color: var(--text);
      border-radius: var(--radius-sm); padding: 9px 11px; font-size: 0.82rem;
    }
:where(body[data-page="inventory"]) .inv-bar button {
      background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
      border-radius: var(--radius-sm); padding: 9px 16px; font-size: 0.82rem; cursor: pointer;
    }
:where(body[data-page="inventory"]) .inv-bar button:hover { border-color: var(--accent); }
:where(body[data-page="inventory"]) .inv-summary { font-size: 0.82rem; color: var(--text-2); margin: 4px 0 18px; }
:where(body[data-page="inventory"]) .inv-summary b { color: var(--text); font-family: var(--font-num); }
:where(body[data-page="inventory"]) .notice {
      background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg);
      padding: 28px; text-align: center; color: var(--text-2);
    }
:where(body[data-page="inventory"]) .notice.good { border-color: rgba(52,217,155,0.3); background: var(--green-glow); }
:where(body[data-page="inventory"]) .notice a { color: var(--accent); }

/* Client-side inventory IMPORT panel — the user's own browser fetches Steam's
   JSON and pastes/drops it here; our server only parses it (never fetches),
   see /api/user/inventory/import. */
:where(body[data-page="inventory"]) .inv-import {
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 18px 20px; margin: 16px 0 18px;
}
:where(body[data-page="inventory"]) .inv-import-steps {
  margin: 4px 0 14px 20px; padding: 0; color: var(--text-2); font-size: 0.8rem; line-height: 1.6;
}
:where(body[data-page="inventory"]) .inv-paste {
  width: 100%; min-height: 84px; resize: vertical; background: var(--bg); border: 1px solid var(--border);
  color: var(--text); border-radius: var(--radius-sm); padding: 10px 11px; font-size: 0.8rem;
  font-family: var(--font-num); margin-bottom: 10px;
}
:where(body[data-page="inventory"]) .inv-paste:focus { outline: none; border-color: var(--accent); }
:where(body[data-page="inventory"]) .inv-drop {
  border: 1px dashed var(--border); border-radius: var(--radius-sm); padding: 14px; text-align: center;
  color: var(--muted); font-size: 0.8rem; cursor: pointer; margin-bottom: 12px;
}
:where(body[data-page="inventory"]) .inv-drop.drag { border-color: var(--accent); color: var(--text); }
:where(body[data-page="inventory"]) .inv-drop-browse { color: var(--accent); text-decoration: underline; }
:where(body[data-page="inventory"]) .inv-import-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* Import/Clear reuse the shared .btn component, dialled down to this panel's
   compact scale so they sit level with `.inv-bar button` (9px 16px / 0.82rem)
   directly above them instead of towering over it. */
:where(body[data-page="inventory"]) .inv-import-actions .btn { padding: 9px 18px; font-size: 0.82rem; }
:where(body[data-page="inventory"]) .inv-import-msg { font-size: 0.8rem; color: var(--text-2); }
:where(body[data-page="inventory"]) .inv-import-msg.error { color: var(--red); }
:where(body[data-page="inventory"]) .inv-import-note { font-size: 0.72rem; color: var(--muted); margin-top: 12px; }

    /* ── All Items dense table — plan §4.6 ───────────────────────────────
       Built on the shared `.dtable` component (replaces the old `.igrid` card
       grid, which duplicated the home-card recipe pixel-for-pixel — deleted
       here, not migrated, per the same rule §4.3/§4.5 deleted their dead
       rules). Every override chains BOTH classes on the same element
       (`.dtable-wrap.inv-table-wrap`, `.dtable.inv-dtable`) — see results.html's
       block for why a bare page-scoped class ties `.dtable` on specificity and
       silently loses on source order. */
:where(body[data-page="inventory"]) .dtable-wrap.inv-table-wrap { max-width: none; padding: 0; }
:where(body[data-page="inventory"]) .dtable.inv-dtable { min-width: 0; table-layout: fixed; }
:where(body[data-page="inventory"]) .inv-dtable th.col-count { width: 64px; }
:where(body[data-page="inventory"]) .inv-dtable th.col-unit { width: 92px; }
:where(body[data-page="inventory"]) .inv-dtable th.col-total { width: 100px; }
:where(body[data-page="inventory"]) .inv-dtable td.col-count,
:where(body[data-page="inventory"]) .inv-dtable td.col-unit,
:where(body[data-page="inventory"]) .inv-dtable td.col-total {
  font-family: var(--font-num); font-variant-numeric: tabular-nums; white-space: nowrap;
}
:where(body[data-page="inventory"]) .inv-dtable td.col-total { font-weight: 700; }
:where(body[data-page="inventory"]) .inv-status { font-size: 0.74rem; color: var(--muted); margin: 12px 0 6px; }
:where(body[data-page="inventory"]) .inv-empty {
  color: var(--muted); text-align: center; padding: 40px; background: var(--panel);
  border: 1px dashed var(--border); border-radius: var(--radius-lg); margin-top: 12px;
}
/* Souvenir tag — the same small-pill recipe as the global `.tag-st`, kept
   page-scoped because souvenir items only ever appear in an owned inventory. */
:where(body[data-page="inventory"]) .tag-sov {
  font-size: 0.6rem; font-weight: 600; background: rgba(242,193,78,0.1); color: #f2c14e;
  padding: 1px 6px; border-radius: 3px; margin-left: 5px; border: 1px solid rgba(242,193,78,0.25);
}

/* A fully-ownable trade-up reads as a stronger promise than a partial "N of
   10 owned" match — colour is never used for this (§2.1 reserves green/red for
   profit/loss), so the distinction is a left accent, same mechanism rarity
   already uses elsewhere on the site. */
:where(body[data-page="inventory"]) .card.buildable { border-left: 3px solid var(--accent); }

/* Locked Pro match — the SAME shared home/inventory mini-card (`.card` etc.)
   the unlocked cards use, not the finder's unrelated `.card-head`/`.metrics`
   component of the same name (see finder-results.js's buildLockedCard()). */
:where(body[data-page="inventory"]) .card.locked-mini { opacity: 0.85; }
:where(body[data-page="inventory"]) .locked-mini-icon { font-size: 1.6rem; }

@media (max-width: 480px) {
  :where(body[data-page="inventory"]) .inv-dtable .col-count { display: none; }
}


/* ── page: markets ───────────────────────────────────────────────── */
/* A non-rarity, non-profit accent for the "trade" market-type badge, kept
   distinct from --r-restricted (§2.1: rarity is item-only). This is a single
   page-scoped badge colour, not a brand token — it used to sit in :root next
   to --accent, which invited reuse of the exact hue the redesign retired
   the old global purple accent for. Page-scoped here instead. */
:where(body[data-page="markets"]) {
  --purple:      #b58bff;
  --purple-glow: rgba(136,71,255,0.16);
}
:where(body[data-page="markets"]) .mk-wrap { max-width: 1180px; margin: 0 auto; padding: 24px 20px 80px; }
:where(body[data-page="markets"]) .mk-head { margin-bottom: 18px; }
:where(body[data-page="markets"]) .mk-head h1 { font-size: 1.4rem; font-weight: 700; }
:where(body[data-page="markets"]) .mk-head p { color: var(--muted); font-size: 0.85rem; margin-top: 6px; max-width: 720px; }
:where(body[data-page="markets"]) .stat-row { margin: 16px 0; }
:where(body[data-page="markets"]) .mk-toolbar { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; margin: 0 0 16px; }
:where(body[data-page="markets"]) .mk-toolbar .spacer { flex: 1; }
:where(body[data-page="markets"]) #mkSaveStatus { font-size: 0.76rem; color: var(--green); }

/* Market cell: logo/abbrev chip + name + type badge, inside the dense
   table's name column (replaces the old .mk-card grid). */
:where(body[data-page="markets"]) .mk-market-cell { display: flex; align-items: center; gap: 10px; min-width: 0; }
:where(body[data-page="markets"]) .mk-logo { width: 26px; height: 26px; border-radius: 7px; object-fit: contain; background: rgba(255,255,255,0.05); padding: 3px; flex-shrink: 0; }
/* The typographic fallback: 10 of 41 markets legitimately have no logo source
   (get_all_logos()'s docstring), and any <img> that 404s swaps to this too —
   see attachLogoFallback() in markets.html. Sized/coloured identically to the
   <img> slot it replaces so neither state shifts the row's layout. */
:where(body[data-page="markets"]) .mk-abbr {
      width: 26px; height: 26px; border-radius: 7px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: var(--surface-2); border: 1px solid var(--line);
      color: var(--text-2); font-size: 0.6rem; font-weight: 700; letter-spacing: 0.02em;
    }
:where(body[data-page="markets"]) .mk-market-info { min-width: 0; }
:where(body[data-page="markets"]) .mk-type { font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.06em; padding: 1px 6px; border-radius: 99px; margin-top: 2px; display: inline-block; }
:where(body[data-page="markets"]) .mk-type.p2p { background: var(--green-glow); color: var(--green); }
:where(body[data-page="markets"]) .mk-type.instant { background: var(--accent-subtle); color: var(--accent); }
:where(body[data-page="markets"]) .mk-type.trade { background: var(--purple-glow); color: var(--purple); }

:where(body[data-page="markets"]) .mk-dtable td.col-fee,
:where(body[data-page="markets"]) .mk-dtable td.col-items,
:where(body[data-page="markets"]) .mk-dtable td.col-updated { font-family: var(--font-num); font-variant-numeric: tabular-nums; white-space: nowrap; }
:where(body[data-page="markets"]) .mk-dtable th.col-enabled,
:where(body[data-page="markets"]) .mk-dtable td.col-enabled { width: 70px; text-align: center; }
:where(body[data-page="markets"]) .mk-dtable th.col-caret,
:where(body[data-page="markets"]) .mk-dtable td.col-caret { width: 24px; padding-left: 0; padding-right: 10px; }
:where(body[data-page="markets"]) .mk-row.off { opacity: 0.55; }
:where(body[data-page="markets"]) .mk-caret { color: var(--muted); font-size: 0.7rem; }
:where(body[data-page="markets"]) .mk-row.open .mk-caret { color: var(--accent); }
:where(body[data-page="markets"]) .mk-row.open td { background: var(--panel-hover); border-bottom-color: transparent; }

/* Expandable detail row: deposit/withdraw method chips, same pattern as
   /results' .rs-detail-row (click-to-expand, no role="button" on the <tr> —
   see markets.html for why). */
:where(body[data-page="markets"]) .mk-detail-row { cursor: default; }
:where(body[data-page="markets"]) .mk-detail-row:hover td { background: var(--panel); }
/* `.mk-detail-row > td` (0,1,1) loses to `.dtable tbody td` (0,1,2) — the
   expanded panel sat inset by the base cell's 6px/10px padding, so its
   `border-left` on .mk-detail below didn't sit flush with the row edge.
   Raised via the cell's own class (`.mk-detail-cell`, added in markets.html's
   detailHTML()) rather than !important — but `.dtable tbody td.mk-detail-cell`
   alone (0,2,2) TIES `.dtable tbody td:first-child` (0,2,2, further down this
   file, sets padding-left: 10px for the rarity-border column), so the tie
   went to whichever comes later in source and padding-left stayed 10px —
   caught with getComputedStyle, not by reading the cascade. This colspan'd
   detail cell is always its row's sole/first child, so `:first-child` is
   always true for it too; adding it here (0,3,2) wins outright regardless of
   source order. */
:where(body[data-page="markets"]) .dtable tbody td.mk-detail-cell:first-child { padding: 0; text-align: left; background: var(--panel); }
:where(body[data-page="markets"]) .mk-detail { padding: 12px 14px 14px; border-left: 2px solid var(--accent-subtle); display: flex; flex-direction: column; gap: 8px; }
:where(body[data-page="markets"]) .mk-detail-row-item { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
:where(body[data-page="markets"]) .mk-detail-row-item .lbl { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); width: 64px; flex-shrink: 0; }
:where(body[data-page="markets"]) .mk-chip { font-size: 0.68rem; padding: 2px 8px; border-radius: 99px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); }
:where(body[data-page="markets"]) .mk-chip-empty { color: var(--muted); background: transparent; border-color: var(--line-soft); }

/* Reuse the finder's toggle-pill look — kept page-scoped and deliberately NOT
   merged with the global .toggle-pill (redesign-plan-2026-07-31.md §3 already
   flags markets-vs-global .toggle-pill as a "same thing styled twice" pair
   left for a later phase; unifying it here would be an uncalled-for visual
   decision beyond this task). */
:where(body[data-page="markets"]) .toggle-pill { position: relative; display: inline-flex; cursor: pointer; }
:where(body[data-page="markets"]) .toggle-pill input { position: absolute; opacity: 0; }
:where(body[data-page="markets"]) .toggle-pill .track { width: 38px; height: 21px; border-radius: 99px; background: var(--surface-3); border: 1px solid var(--border); transition: background var(--transition); position: relative; }
:where(body[data-page="markets"]) .toggle-pill .thumb { position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: var(--muted); transition: transform var(--transition), background var(--transition); }
:where(body[data-page="markets"]) .toggle-pill input:checked + .track { background: var(--accent-subtle); border-color: var(--accent-border-40); }
:where(body[data-page="markets"]) .toggle-pill input:checked + .track .thumb { transform: translateX(17px); background: var(--accent); }
:where(body[data-page="markets"]) .mk-status { color: var(--muted); padding: 40px; text-align: center; }


/* ── page: pro ───────────────────────────────────────────────────── */
:where(body[data-page="pro"]) .pro-wrap { max-width: 1000px; margin: 0 auto; padding: 36px 20px 70px; }
:where(body[data-page="pro"]) .pro-hero { text-align: center; margin-bottom: 14px; }
:where(body[data-page="pro"]) .pro-hero h1 { font-size: 1.7rem; margin-bottom: 8px; }
:where(body[data-page="pro"]) .pro-hero p { color: var(--text-2, #c9cdd6); font-size: 0.95rem; }
:where(body[data-page="pro"]) .pro-note {
      max-width: 640px; margin: 10px auto 28px; text-align: center;
      color: var(--accent); font-size: 0.8rem;
    }
:where(body[data-page="pro"]) .pro-feats {
      display: flex; flex-wrap: wrap; gap: 10px 22px; justify-content: center;
      margin: 0 auto 32px; max-width: 760px; color: var(--text-2, #c9cdd6); font-size: 0.86rem;
    }
:where(body[data-page="pro"]) .pro-feats span::before { content: "✓ "; color: var(--green, #22c55e); font-weight: 700; }
:where(body[data-page="pro"]) .pro-grid {
      display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
      gap: 14px; max-width: 880px; margin: 0 auto;
    }
/* .plan reuses .card for background/border/hover (§4.8 pass B) — the two
   properties that would otherwise change the look are overridden back:
   .card's 3px profit/loss left-accent doesn't apply to a pricing tier, and
   its --radius-md is smaller than the 14px these cards have always used. */
:where(body[data-page="pro"]) .plan {
      border-left: 1px solid var(--border); border-radius: 14px; margin-bottom: 0;
      /* .card clips overflow for its own content; the "BEST VALUE" badge
         deliberately pokes out above the card (top: -10px) and would be
         silently clipped invisible without this override. */
      overflow: visible;
      padding: 20px 18px; text-align: center; position: relative;
    }
:where(body[data-page="pro"]) .plan.best { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-glow); }
:where(body[data-page="pro"]) .plan-badge {
      position: absolute; top: -10px; left: 50%; transform: translateX(-50%);
      background: var(--accent); color: #0a0c11; font-size: 0.62rem; font-weight: 800;
      padding: 3px 10px; border-radius: 20px; letter-spacing: 0.04em;
    }
:where(body[data-page="pro"]) .plan-name { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
:where(body[data-page="pro"]) .plan-price { font-size: 1.7rem; font-weight: 800; margin: 8px 0 2px; }
:where(body[data-page="pro"]) .plan-price small { font-size: 0.8rem; font-weight: 500; color: var(--muted); }
:where(body[data-page="pro"]) .plan-sub { font-size: 0.74rem; color: var(--muted); min-height: 16px; }
/* .plan-cta is now a real <button class="btn plan-cta"> (ghost tiers) or
   <button class="btn primary plan-cta"> (the best-value tier) — see
   pro.html. .btn/.btn.primary supply the colour/border/hover; only the
   full-width block layout is page-specific. A ghost tier's `.btn` sits on
   this card's `--panel` background (inherited from .card above), which is
   the exact colour the old `background: transparent` ghost override
   rendered as — so dropping that override is render-identical, not just a
   simplification. */
:where(body[data-page="pro"]) .plan-cta { display: block; width: 100%; margin-top: 16px; }
:where(body[data-page="pro"]) .plan-paypal {
      display: block; width: 100%; margin-top: 8px; padding: 0;
      background: none; border: none; font: inherit; font-size: 0.74rem;
      color: var(--muted); text-decoration: none; cursor: pointer;
    }
:where(body[data-page="pro"]) .plan-paypal:hover { color: var(--accent); }


/* ── page: profile ───────────────────────────────────────────────── */
/* .profile-hero reuses .card for background/border/hover (§4.8 pass B);
   overridden back to a uniform 1px left border (.card's 3px accent is a
   profit/loss marker, not applicable here) and the page's own --radius-lg
   (.card defaults to the smaller --radius-md). */
:where(body[data-page="profile"]) .profile-hero {
      display: flex; align-items: center; gap: 20px;
      border-left: 1px solid var(--border);
      border-radius: var(--radius-lg); margin-bottom: 0; padding: 24px; margin-top: 22px;
    }
:where(body[data-page="profile"]) .profile-hero .pf-avatar {
      width: 84px; height: 84px; border-radius: 50%; object-fit: cover;
      border: 2px solid var(--border-hover); flex-shrink: 0;
      background: var(--surface-0);
    }
:where(body[data-page="profile"]) .profile-hero .pf-avatar.placeholder {
      display: flex; align-items: center; justify-content: center;
      font-size: 2rem; font-weight: 700; color: var(--muted);
    }
:where(body[data-page="profile"]) .pf-name { font-size: 1.3rem; font-weight: 700; }
:where(body[data-page="profile"]) .pf-email { color: var(--muted); font-size: 0.85rem; margin-top: 3px; }
:where(body[data-page="profile"]) .pf-badges { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
:where(body[data-page="profile"]) .pf-badge {
      font-size: 0.68rem; font-weight: 600; padding: 4px 10px; border-radius: 99px;
      border: 1px solid var(--border); color: var(--text-2);
    }
:where(body[data-page="profile"]) .pf-badge.on { border-color: rgba(52,217,155,0.35); background: var(--green-glow); color: var(--green); }
/* .info-grid also reuses .card, but keeps its own `background: var(--border)`
   — that's not a duplicate of .card's --panel, it's the mechanism that makes
   the 1px `gap` between rows read as hairline dividers (each .info-row below
   paints its own --panel fill over it). Border-left and radius are
   re-overridden for the same reason as .profile-hero above. */
:where(body[data-page="profile"]) .info-grid {
      margin-top: 22px; margin-bottom: 0; display: grid; gap: 1px; background: var(--border);
      border-left: 1px solid var(--border); border-radius: var(--radius-lg);
    }
:where(body[data-page="profile"]) .info-row { display: flex; justify-content: space-between; gap: 16px; padding: 14px 18px; background: var(--panel); }
:where(body[data-page="profile"]) .info-row .k { color: var(--muted); font-size: 0.82rem; }
:where(body[data-page="profile"]) .info-row .v { color: var(--text); font-size: 0.85rem; font-family: var(--font-num); text-align: right; word-break: break-all; }
:where(body[data-page="profile"]) .gate {
      background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg);
      padding: 40px 28px; text-align: center; color: var(--text-2); margin-top: 24px;
    }
:where(body[data-page="profile"]) .gate h2 { font-size: 1.1rem; color: var(--text); margin-bottom: 8px; }
:where(body[data-page="profile"]) .steam-btn {
      display: inline-flex; align-items: center; gap: 9px; margin-top: 18px;
      background: linear-gradient(135deg, #1b2838, #2a475e); color: #fff;
      border: 1px solid #3c6e91; padding: 11px 20px; border-radius: var(--radius-md);
      font-size: 0.9rem; font-weight: 600; text-decoration: none;
      transition: filter var(--transition);
    }
:where(body[data-page="profile"]) .steam-btn:hover { filter: brightness(1.15); }
:where(body[data-page="profile"]) .acct-actions { margin-top: 22px; display: flex; gap: 10px; flex-wrap: wrap; }


/* ── page: results ───────────────────────────────────────────────── */
:where(body[data-page="results"]) .rs { max-width: 1080px; margin: 0 auto; padding: 24px 20px 90px; }
:where(body[data-page="results"]) .rs-head h1 { font-size: 1.4rem; font-weight: 700; }
:where(body[data-page="results"]) .rs-head p { color: var(--muted); font-size: 0.85rem; margin-top: 6px; max-width: 720px; }
:where(body[data-page="results"]) .stat-row { margin-top: 18px; }
:where(body[data-page="results"]) .rs-filter-note { font-size: 0.72rem; color: var(--muted); margin-top: 8px; }

/* ── cumulative P/L chart ──────────────────────────────────────────────────
   The time dimension redesign plan §4.4 says this page is missing entirely.
   The line's colour is the running total's sign — a profit/loss colour on a
   number, never on an item (§2.1) — and the dashed zero rule is what keeps it
   readable without relying on that colour at all. */
:where(body[data-page="results"]) .rs-chart-panel {
      background: var(--panel); border: 1px solid var(--border);
      border-radius: var(--radius-lg); padding: 14px 16px 8px; margin-top: 18px;
    }
:where(body[data-page="results"]) .rs-chart-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
:where(body[data-page="results"]) .rs-chart-head h2 { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); font-weight: 700; }
:where(body[data-page="results"]) .rs-chart-read { font-family: var(--font-num); font-variant-numeric: tabular-nums; font-size: 1rem; font-weight: 700; }
:where(body[data-page="results"]) .rs-chart-read-sub { font-size: 0.7rem; color: var(--muted); font-weight: 400; margin-left: 8px; }
:where(body[data-page="results"]) .rs-chart-box { margin-top: 6px; }
:where(body[data-page="results"]) .rs-chart { display: block; max-width: 100%; }
:where(body[data-page="results"]) .rs-chart-note { font-size: 0.68rem; color: var(--muted); padding-bottom: 6px; }
:where(body[data-page="results"]) .rs-grid { stroke: var(--line-soft); stroke-width: 1; }
:where(body[data-page="results"]) .rs-grid.zero { stroke: var(--border-hover); stroke-dasharray: 3 3; }
:where(body[data-page="results"]) .rs-axis { fill: var(--muted); font-size: 10px; font-family: var(--font-num); }
:where(body[data-page="results"]) .rs-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
:where(body[data-page="results"]) .rs-line.pos { stroke: var(--green); }
:where(body[data-page="results"]) .rs-line.neg { stroke: var(--red); }
:where(body[data-page="results"]) .rs-area { stroke: none; opacity: 0.13; }
:where(body[data-page="results"]) .rs-area.pos { fill: var(--green); }
:where(body[data-page="results"]) .rs-area.neg { fill: var(--red); }
:where(body[data-page="results"]) .rs-dot { fill: var(--panel); stroke-width: 1.6; }
:where(body[data-page="results"]) .rs-dot.pos { stroke: var(--green); }
:where(body[data-page="results"]) .rs-dot.neg { stroke: var(--red); }
:where(body[data-page="results"]) .rs-cursor { fill: none; stroke: none; }
:where(body[data-page="results"]) .rs-cursor.show { stroke-width: 2; fill: var(--panel); }
:where(body[data-page="results"]) .rs-cursor.show.pos { stroke: var(--green); }
:where(body[data-page="results"]) .rs-cursor.show.neg { stroke: var(--red); }
/* The hover target spans the whole plot, so the readout tracks the nearest
   day instead of demanding a 2.6px dot be hit exactly. */
:where(body[data-page="results"]) .rs-hit { fill: transparent; cursor: crosshair; }

:where(body[data-page="results"]) .rs-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
:where(body[data-page="results"]) .rs-actions button {
      background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
      border-radius: var(--radius-sm); padding: 9px 16px; font-size: 0.82rem; cursor: pointer;
    }
:where(body[data-page="results"]) .rs-actions button.primary { background: linear-gradient(135deg, var(--gold), var(--gold-deep)); color: #1a1407; border-color: transparent; font-weight: 600; }
:where(body[data-page="results"]) .rs-actions button:hover { border-color: var(--accent); }

/* ── filter bar ──────────────────────────────────────────────────────────── */
:where(body[data-page="results"]) .rs-toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
:where(body[data-page="results"]) .rs-toolbar input, :where(body[data-page="results"]) .rs-toolbar select {
      background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
      border-radius: var(--radius-sm); padding: 8px 10px; font-size: 0.8rem; font-family: inherit;
    }
:where(body[data-page="results"]) .rs-toolbar input { flex: 1 1 220px; min-width: 0; }
:where(body[data-page="results"]) .rs-toolbar input:focus, :where(body[data-page="results"]) .rs-toolbar select:focus { outline: none; border-color: var(--accent); }
:where(body[data-page="results"]) .rs-toolbar #fClear {
      background: none; border: 1px solid var(--border); color: var(--muted);
      border-radius: var(--radius-sm); padding: 8px 12px; font-size: 0.78rem; cursor: pointer;
    }
:where(body[data-page="results"]) .rs-toolbar #fClear:hover { border-color: var(--accent); color: var(--text); }
:where(body[data-page="results"]) .rs-status { font-size: 0.74rem; color: var(--muted); margin: 12px 0 6px; }

/* ── entries table ───────────────────────────────────────────────────────── */
/* The shared `.dtable-wrap` centres itself at 1400px with its own padding;
   inside `.rs` that would double the gutter and break the 1080px column.

   Every override in this block chains the shared class (`.dtable-wrap.rs-table-wrap`,
   not `.rs-table-wrap`) ON PURPOSE. `:where()` contributes zero specificity, so
   a bare `:where(body[data-page="results"]) .rs-table-wrap` ties `.dtable-wrap`
   at (0,1,0) and loses on source order — the component block is defined LATER in
   this file. Measured: the un-chained version left `min-width: 720px` in force,
   so the table overflowed its wrapper at every width below 860px. */
:where(body[data-page="results"]) .dtable-wrap.rs-table-wrap { max-width: none; padding: 0; }
/* min-width 0, unlike /skins and /flips: this table has half their columns and
   drops three of them below 960px, so it genuinely fits a phone. Keeping the
   shared 720px floor would force a horizontal scroller that isn't needed. */
:where(body[data-page="results"]) .dtable.rs-dtable { min-width: 0; }
/* `table-layout: fixed`, and this is the load-bearing line of the whole block.
   Under the default `auto` layout a cell's min-content width comes from its
   text, and neither `max-width: 0` nor `text-overflow: ellipsis` lowers it —
   measured, a single long trade-up name held the table at 607px inside a 320px
   column and pushed the document into a horizontal scroll at every width up to
   600px. Fixed layout makes the declared column widths authoritative: the name
   column takes whatever is left and ellipsises inside it, and the table can
   never exceed its container. Every column below therefore needs an explicit
   width, and the name column deliberately gets none — `auto` is what makes it
   the one that absorbs the slack. */
:where(body[data-page="results"]) .dtable.rs-dtable { table-layout: fixed; }
:where(body[data-page="results"]) .rs-dtable th.col-date { width: 82px; }
:where(body[data-page="results"]) .rs-dtable th.col-runs { width: 58px; }
:where(body[data-page="results"]) .rs-dtable th.col-invested { width: 92px; }
:where(body[data-page="results"]) .rs-dtable th.col-returned { width: 92px; }
:where(body[data-page="results"]) .rs-dtable th.col-profit { width: 104px; }
:where(body[data-page="results"]) .rs-dtable th.col-roi { width: 72px; }
/* Fixed layout clips rather than widens, so a long currency string (a JPY total,
   say) must be told to ellipsise instead of spilling into its neighbour. */
:where(body[data-page="results"]) .rs-dtable td { overflow: hidden; text-overflow: ellipsis; }
:where(body[data-page="results"]) .rs-dtable td.col-date { font-family: var(--font-num); font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-2); }
:where(body[data-page="results"]) .rs-dtable td.col-runs,
:where(body[data-page="results"]) .rs-dtable td.col-invested,
:where(body[data-page="results"]) .rs-dtable td.col-returned,
:where(body[data-page="results"]) .rs-dtable td.col-profit,
:where(body[data-page="results"]) .rs-dtable td.col-roi {
      font-family: var(--font-num); font-variant-numeric: tabular-nums; white-space: nowrap;
    }
:where(body[data-page="results"]) .rs-dtable td.col-profit { font-weight: 700; }
:where(body[data-page="results"]) .rs-dtable th.col-caret, :where(body[data-page="results"]) .rs-dtable td.col-caret { width: 26px; padding-left: 0; }
:where(body[data-page="results"]) .rs-caret { color: var(--muted); font-size: 0.7rem; }
:where(body[data-page="results"]) .rs-row.open .rs-caret { color: var(--accent); }
:where(body[data-page="results"]) .rs-row.open td { background: var(--panel-hover); border-bottom-color: transparent; }
/* An entry with no rolled output yet: the money is out but nothing has come
   back, so its P/L is provisional. Marked, never silently counted as a loss. */
:where(body[data-page="results"]) .rs-open-dot { color: var(--accent); font-size: 0.9rem; line-height: 0; }

:where(body[data-page="results"]) .rs-detail-row { cursor: default; }
:where(body[data-page="results"]) .rs-detail-row:hover td { background: var(--panel); }
:where(body[data-page="results"]) .rs-detail-row > td { padding: 0; text-align: left; background: var(--panel); }
:where(body[data-page="results"]) .rs-detail { padding: 14px 12px 16px; border-left: 2px solid var(--accent-subtle); }
:where(body[data-page="results"]) .rs-detail-grid { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
:where(body[data-page="results"]) .fld { display: flex; flex-direction: column; gap: 3px; }
:where(body[data-page="results"]) .fld label { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
:where(body[data-page="results"]) .fld.sm { width: 118px; }
:where(body[data-page="results"]) .fld.grow { flex: 1 1 200px; min-width: 0; }
:where(body[data-page="results"]) .rs-detail input {
      background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
      border-radius: var(--radius-sm); padding: 8px 10px; font-size: 0.82rem; font-family: inherit; width: 100%;
    }
:where(body[data-page="results"]) .rs-detail input:focus { outline: none; border-color: var(--accent); }
:where(body[data-page="results"]) .outcomes { border-top: 1px solid var(--line-soft); padding-top: 12px; }
:where(body[data-page="results"]) .outcomes-h { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin-bottom: 8px; }
:where(body[data-page="results"]) .outcome { display: grid; grid-template-columns: 1fr 110px 90px 30px; gap: 8px; margin-bottom: 7px; align-items: center; }
:where(body[data-page="results"]) .outcome .del { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 1rem; }
:where(body[data-page="results"]) .outcome .del:hover { color: var(--red); }
:where(body[data-page="results"]) .add-outcome { background: none; border: 1px dashed var(--border); color: var(--muted); border-radius: var(--radius-sm); padding: 6px; width: 100%; cursor: pointer; font-size: 0.78rem; }
:where(body[data-page="results"]) .add-outcome:hover { border-color: var(--accent); color: var(--text); }
/* The editable input list. Same row rhythm as .outcome, but the name is static
   text and the right-hand cell is a computed line total, not a control. */
/* The detail lives in a <td>, and .dtable td's `text-align: center` is declared
   later in this file at equal specificity, so it wins over .rs-detail-row > td's
   `left`. Everything in here is prose or a labelled row, so it is re-anchored
   left explicitly rather than left reading as centred headings. */
:where(body[data-page="results"]) .rs-detail .outcomes-h,
:where(body[data-page="results"]) .rs-detail .in-name,
:where(body[data-page="results"]) .rs-detail .rs-recon,
:where(body[data-page="results"]) .rs-detail .entry-pred { text-align: left; }
:where(body[data-page="results"]) .inputs { border-top: 1px solid var(--line-soft); padding-top: 12px; margin-bottom: 14px; }
:where(body[data-page="results"]) .in-h-sub { text-transform: none; letter-spacing: 0; margin-left: 8px; color: var(--muted); }
:where(body[data-page="results"]) .in-row { display: grid; grid-template-columns: 1fr 70px 110px 84px; gap: 8px; margin-bottom: 7px; align-items: center; }
:where(body[data-page="results"]) .in-name { font-size: 0.8rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:where(body[data-page="results"]) .in-was { color: var(--muted); font-size: 0.7rem; margin-left: 6px; }
:where(body[data-page="results"]) .in-row.over .in-price { border-color: var(--accent); }
:where(body[data-page="results"]) .in-line { font-family: var(--font-num); font-size: 0.8rem; text-align: right; color: var(--muted); }
:where(body[data-page="results"]) .rs-detail input.derived { color: var(--muted); cursor: default; }
:where(body[data-page="results"]) .in-foot:empty { display: none; }
:where(body[data-page="results"]) .in-reset,
:where(body[data-page="results"]) .rs-recon-fix {
  background: none; border: 1px solid var(--border); color: var(--muted);
  border-radius: var(--radius-sm); padding: 5px 10px; cursor: pointer; font-size: 0.75rem;
}
:where(body[data-page="results"]) .in-reset:hover,
:where(body[data-page="results"]) .rs-recon-fix:hover { border-color: var(--accent); color: var(--text); }
/* The runs-vs-outcomes reconciliation line. :empty collapses it entirely, so a
   brand-new entry with no runs yet doesn't carry an empty band of padding. */
:where(body[data-page="results"]) .rs-recon { font-size: 0.75rem; color: var(--muted); margin-top: 10px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
:where(body[data-page="results"]) .rs-recon:empty { display: none; }
:where(body[data-page="results"]) .rs-recon .warn { color: var(--accent); }
:where(body[data-page="results"]) .rs-recon .pos, :where(body[data-page="results"]) .rs-recon .neg { font-family: var(--font-num); font-weight: 600; }

:where(body[data-page="results"]) .entry-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; border-top: 1px solid var(--line-soft); margin-top: 12px; padding-top: 12px; flex-wrap: wrap; }
:where(body[data-page="results"]) .entry-verdict { font-family: var(--font-num); font-variant-numeric: tabular-nums; font-weight: 700; font-size: 1.1rem; }
:where(body[data-page="results"]) .entry-verdict .sub { font-size: 0.72rem; color: var(--muted); font-weight: 400; margin-left: 8px; }
:where(body[data-page="results"]) .entry-pred { font-size: 0.72rem; color: var(--muted); margin-top: 4px; }
:where(body[data-page="results"]) .entry-pred .pos, :where(body[data-page="results"]) .entry-pred .neg { font-family: var(--font-num); font-weight: 600; }
:where(body[data-page="results"]) .del-entry { background: none; border: 1px solid var(--border); color: var(--muted); border-radius: var(--radius-sm); padding: 6px 12px; font-size: 0.76rem; cursor: pointer; }
:where(body[data-page="results"]) .del-entry:hover { border-color: var(--red); color: var(--red); }
:where(body[data-page="results"]) .pos { color: var(--green); }
:where(body[data-page="results"]) .neg { color: var(--red); }
:where(body[data-page="results"]) .rs-empty { color: var(--muted); text-align: center; padding: 40px; background: var(--panel); border: 1px dashed var(--border); border-radius: var(--radius-lg); margin-top: 12px; }
:where(body[data-page="results"]) .modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: none; align-items: center; justify-content: center; z-index: 300; padding: 20px; }
:where(body[data-page="results"]) .modal-overlay.show { display: flex; }
:where(body[data-page="results"]) .modal { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; max-width: 560px; width: 100%; max-height: 80vh; overflow-y: auto; }
:where(body[data-page="results"]) .modal h3 { font-size: 1.05rem; margin-bottom: 12px; }
:where(body[data-page="results"]) .imp-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 8px; }
:where(body[data-page="results"]) .imp-row button { background: var(--accent-subtle); border: 1px solid rgba(242,193,78,0.4); color: var(--accent); border-radius: var(--radius-sm); padding: 6px 12px; cursor: pointer; font-size: 0.78rem; }
:where(body[data-page="results"]) .modal-close { float: right; background: none; border: none; color: var(--muted); font-size: 1.3rem; cursor: pointer; }

/* Columns yield in order of how little they answer on a small screen:
   "Returned" is recoverable from Invested + Net P/L, "Runs" and "Invested"
   are context. Date, name, Net P/L and ROI — the whole point of the page —
   survive to the narrowest width. The shared `.dtable-wrap` turns into a
   horizontal scroller below 820px; this table drops columns instead, so it
   keeps its sticky header and never sends the page sideways. */
/* 960px, not 900px. Measured on the real page: with all 8 columns the table's
   min-content width is ~872px, while `.rs` gives it viewport − 40px of gutter.
   At 905px that is 865px — the table overflowed by 7px, and because the shared
   `.dtable-wrap` only becomes a scroller below 820px there was nothing to catch
   it, so the whole document gained a horizontal scrollbar. Same failure the
   /skins 821–900px band had, one notch higher. Dropping "Returned" before the
   squeeze starts is what keeps the page from ever scrolling sideways. */
@media (max-width: 960px) {
  :where(body[data-page="results"]) .rs-dtable .col-returned { display: none; }
  /* The table now fits, so it must NOT inherit the shared scroller — that would
     make the wrapper a scrollport and the sticky header would stop sticking. */
  :where(body[data-page="results"]) .dtable-wrap.rs-table-wrap { overflow-x: visible; }
}
@media (max-width: 760px) {
  :where(body[data-page="results"]) .rs-dtable .col-runs { display: none; }
  :where(body[data-page="results"]) .rs-detail .outcome { grid-template-columns: 1fr 84px 66px 26px; }
  :where(body[data-page="results"]) .rs-detail .in-row { grid-template-columns: 1fr 52px 78px 62px; }
}
/* On a phone the fixed columns are trimmed too, so the name keeps a readable
   share of a 320px content column instead of being ellipsised to a few glyphs. */
@media (max-width: 600px) {
  :where(body[data-page="results"]) .rs-dtable .col-invested { display: none; }
  :where(body[data-page="results"]) .rs-dtable thead th, :where(body[data-page="results"]) .rs-dtable tbody td { padding-left: 6px; padding-right: 6px; }
  :where(body[data-page="results"]) .rs-dtable th.col-date { width: 68px; }
  :where(body[data-page="results"]) .rs-dtable th.col-profit { width: 88px; }
  :where(body[data-page="results"]) .rs-dtable th.col-roi { width: 60px; }
  :where(body[data-page="results"]) .rs-dtable th.col-caret, :where(body[data-page="results"]) .rs-dtable td.col-caret { width: 22px; }
  :where(body[data-page="results"]) .fld.sm { width: 100%; }
}


/* ── page: settings ──────────────────────────────────────────────── */
:where(body[data-page="settings"]) .set-card {
      background: var(--panel); border: 1px solid var(--border);
      border-radius: var(--radius-lg); padding: 20px 22px; margin-top: 20px;
    }
:where(body[data-page="settings"]) .set-card h2 { font-size: 1rem; font-weight: 700; margin-bottom: 4px; }
:where(body[data-page="settings"]) .set-card .desc { font-size: 0.8rem; color: var(--muted); margin-bottom: 16px; }
:where(body[data-page="settings"]) .set-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 0; border-top: 1px solid var(--border); }
:where(body[data-page="settings"]) .set-row:first-of-type { border-top: none; }
:where(body[data-page="settings"]) .set-row .lbl { font-size: 0.86rem; color: var(--text); }
:where(body[data-page="settings"]) .set-row .hint { font-size: 0.74rem; color: var(--muted); margin-top: 2px; }
/* .seg (the theme toggle) used to have its own settings-only look — one of
   the 3 "same thing styled twice" pairs the redesign plan flagged (§3, "What
   Phase 1 did and did not do"). It's unified now: this page reuses the one
   global `.seg` / `.seg button` definition (pricing-source segmented
   control) instead of a second, page-scoped copy. */
:where(body[data-page="settings"]) .set-select {
      /* --panel, not --bg: every other control on this site (.currency-select,
         the global input/select rule) sits on --panel so it reads as a
         raised control, not the page background. */
      background: var(--panel); border: 1px solid var(--border); color: var(--text);
      border-radius: var(--radius-sm); padding: 8px 11px; font-size: 0.82rem; min-width: 140px;
    }
:where(body[data-page="settings"]) .acct-status { font-size: 0.82rem; color: var(--text-2); }
:where(body[data-page="settings"]) .acct-status b { color: var(--text); }
:where(body[data-page="settings"]) .ok { color: var(--green); }


/* ── page: skin_detail ───────────────────────────────────────────── */
    /* ── Skin Detail Page ──────────────────────────────────────────────── */
:where(body[data-page="skin_detail"]) .sd-wrap {
      max-width: 980px;
      margin: 0 auto;
      padding: 24px 16px 60px;
    }

    /* hero */
:where(body[data-page="skin_detail"]) .sd-hero {
      display: flex;
      align-items: center;
      gap: 24px;
      margin-bottom: 32px;
      background: var(--panel);
      border: 1px solid var(--border);
      border-radius: 12px;
      padding: 24px;
    }
:where(body[data-page="skin_detail"]) .sd-hero-img {
      width: 160px;
      height: 120px;
      object-fit: contain;
      border-radius: 8px;
      background: rgba(255,255,255,0.04);
      flex-shrink: 0;
    }
:where(body[data-page="skin_detail"]) .sd-hero-img-placeholder {
      width: 160px; height: 120px;
      display: flex; align-items: center; justify-content: center;
      font-size: 3rem;
      background: var(--surface);
      border-radius: 8px;
      flex-shrink: 0;
    }
:where(body[data-page="skin_detail"]) .sd-hero-meta h1 { font-size: 1.4rem; font-weight: 700; margin-bottom: 4px; }
:where(body[data-page="skin_detail"]) .sd-hero-meta .sd-sub { color: var(--text-dim); font-size: 0.85rem; }
:where(body[data-page="skin_detail"]) .sd-rarity-chip {
      display: inline-block;
      font-size: 0.72rem; font-weight: 600;
      padding: 2px 10px; border-radius: 20px;
      margin-top: 8px;
    }

    /* wear tabs toolbar */
:where(body[data-page="skin_detail"]) .sd-wear-tabs {
      display: flex; gap: 6px; flex-wrap: wrap;
      margin-bottom: 20px;
      background: var(--panel);
      border: 1px solid var(--border);
      border-radius: 10px;
      padding: 6px;
    }
:where(body[data-page="skin_detail"]) .sd-sparkline {
      display: flex; align-items: center; gap: 16px;
      background: var(--panel); border: 1px solid var(--border);
      border-radius: 8px; padding: 10px 14px; margin-bottom: 18px;
    }
:where(body[data-page="skin_detail"]) .sd-spark-svg { width: 200px; height: 36px; flex-shrink: 0; }
:where(body[data-page="skin_detail"]) .sd-spark-meta { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 0.75rem; color: var(--text-dim); }
:where(body[data-page="skin_detail"]) .sd-wear-tab {
      padding: 7px 18px; border-radius: 7px;
      font-size: 0.82rem; font-weight: 600; cursor: pointer;
      border: 1px solid transparent;
      background: transparent; color: var(--text-dim);
      transition: background .15s, color .15s, border-color .15s;
      white-space: nowrap;
    }
:where(body[data-page="skin_detail"]) .sd-wear-tab:hover { background: var(--surface); color: var(--text); border-color: var(--border); }
:where(body[data-page="skin_detail"]) .sd-wear-tab.active {
      background: var(--accent); border-color: var(--accent);
      color: #fff;
    }
:where(body[data-page="skin_detail"]) .sd-wear-tab.no-data { opacity: .35; cursor: default; }

    /* comparison table */
:where(body[data-page="skin_detail"]) .sd-section-title {
      font-size: 0.75rem; font-weight: 600; letter-spacing: .08em;
      color: var(--text-dim); text-transform: uppercase;
      margin: 24px 0 10px;
    }
:where(body[data-page="skin_detail"]) .sd-table {
      width: 100%;
      border-collapse: collapse;
    }
:where(body[data-page="skin_detail"]) .sd-table th {
      text-align: left;
      font-size: 0.72rem; font-weight: 600; color: var(--text-dim);
      text-transform: uppercase; letter-spacing: .06em;
      padding: 8px 12px;
      border-bottom: 1px solid var(--border);
    }
:where(body[data-page="skin_detail"]) .sd-table td {
      padding: 10px 12px;
      border-bottom: 1px solid rgba(255,255,255,0.04);
      vertical-align: middle;
    }
:where(body[data-page="skin_detail"]) .sd-table tr:hover td { background: var(--surface); }
:where(body[data-page="skin_detail"]) .sd-table tr.steam-row td { background: rgba(96,165,250,0.1); }
:where(body[data-page="skin_detail"]) .sd-table tr.cheapest-row td { background: rgba(34,197,94,0.1); }

    /* pills for steam / cheapest rows */
:where(body[data-page="skin_detail"]) .row-pill {
      display: inline-flex; align-items: center;
      font-size: 0.62rem; font-weight: 700; letter-spacing: .05em;
      padding: 1px 6px; border-radius: 20px;
      margin-left: 6px; vertical-align: middle;
      line-height: 1.6;
    }
:where(body[data-page="skin_detail"]) .row-pill.steam-pill { background: rgba(96,165,250,0.18); color: #60a5fa; border: 1px solid rgba(96,165,250,0.35); }
:where(body[data-page="skin_detail"]) .row-pill.cheapest-pill { background: rgba(34,197,94,0.18); color: #22c55e; border: 1px solid rgba(34,197,94,0.35); }
:where(body[data-page="skin_detail"]) .mkt-cell {
      display: flex; align-items: center; gap: 10px;
    }
:where(body[data-page="skin_detail"]) .mkt-logo {
      width: 28px; height: 28px;
      object-fit: contain; border-radius: 4px;
      background: rgba(255,255,255,0.06); padding: 2px;
      flex-shrink: 0;
    }
:where(body[data-page="skin_detail"]) .mkt-logo-placeholder {
      width: 28px; height: 28px; border-radius: 4px;
      background: rgba(255,255,255,0.08);
      display: flex; align-items: center; justify-content: center;
      font-size: 0.65rem; color: var(--text-dim); font-weight: 700;
      flex-shrink: 0;
    }
:where(body[data-page="skin_detail"]) .mkt-name { font-size: 0.9rem; font-weight: 500; }
:where(body[data-page="skin_detail"]) .price-cell {
      font-size: 1.15rem; font-weight: 700; color: var(--text);
      white-space: nowrap;
    }
:where(body[data-page="skin_detail"]) .price-cell.cheapest { color: #22c55e; }
:where(body[data-page="skin_detail"]) .price-cell.steam { color: #60a5fa; }
:where(body[data-page="skin_detail"]) .buy-btn {
      display: inline-flex; align-items: center; gap: 4px;
      padding: 4px 12px; border-radius: 6px; font-size: 0.78rem; font-weight: 600;
      background: var(--accent-subtle); color: var(--accent);
      border: 1px solid rgba(242,193,78,0.25);
      text-decoration: none; cursor: pointer;
      transition: all .15s;
    }
:where(body[data-page="skin_detail"]) .buy-btn:hover { background: var(--accent); color: #fff; }
:where(body[data-page="skin_detail"]) .buy-btn.disabled { opacity: .3; pointer-events: none; }
:where(body[data-page="skin_detail"]) .ts-cell { font-size: 0.72rem; color: var(--text-dim); white-space: nowrap; }

    /* rank badge */
:where(body[data-page="skin_detail"]) .rank-badge {
      display: inline-flex; align-items: center; justify-content: center;
      width: 20px; height: 20px; border-radius: 50%;
      font-size: 0.68rem; font-weight: 700;
      background: rgba(255,255,255,0.08); color: var(--text-dim);
    }
:where(body[data-page="skin_detail"]) .rank-badge.r1 { background: rgba(34,197,94,0.2); color: #22c55e; }
:where(body[data-page="skin_detail"]) .rank-badge.r2 { background: rgba(242,193,78,0.2); color: var(--accent); }
:where(body[data-page="skin_detail"]) .rank-badge.r3 { background: rgba(251,191,36,0.15); color: #f59e0b; }

    /* loading / error */
:where(body[data-page="skin_detail"]) .sd-loading {
      text-align: center; padding: 60px 0;
      color: var(--text-dim); font-size: 0.95rem;
    }
:where(body[data-page="skin_detail"]) .sd-spinner {
      width: 36px; height: 36px; margin: 0 auto 16px;
      border: 3px solid var(--border);
      border-top-color: var(--accent);
      border-radius: 50%;
      animation: spin .8s linear infinite;
    }

    /* snipe status bar */
:where(body[data-page="skin_detail"]) .snipe-bar {
      display: flex; align-items: center; gap: 10px;
      background: var(--panel); border: 1px solid var(--border);
      border-radius: 8px; padding: 10px 14px;
      font-size: 0.78rem; color: var(--text-dim);
      margin-bottom: 20px;
    }
:where(body[data-page="skin_detail"]) .snipe-dot {
      width: 8px; height: 8px; border-radius: 50%;
      background: #22c55e; flex-shrink: 0;
      animation: pulse 1.5s ease infinite;
    }
:where(body[data-page="skin_detail"]) .snipe-dot.idle { background: var(--border); animation: none; }
    @keyframes pulse {
      0%, 100% { opacity: 1; } 50% { opacity: .4; }
    }
:where(body[data-page="skin_detail"]) .back-link {
      display: inline-flex; align-items: center; gap: 6px;
      color: var(--text-dim); font-size: 0.85rem;
      text-decoration: none; margin-bottom: 20px;
      transition: color .15s;
    }
:where(body[data-page="skin_detail"]) .back-link:hover { color: var(--accent); }

    /* doppler phase picker */
:where(body[data-page="skin_detail"]) .sd-phase-picker {
      display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px;
    }
:where(body[data-page="skin_detail"]) .sd-phase {
      display: flex; flex-direction: column; align-items: center; gap: 4px;
      padding: 4px; border-radius: 8px; cursor: pointer;
      border: 1px solid var(--border); background: var(--panel);
      transition: border-color .15s, transform .1s;
      width: 64px;
    }
:where(body[data-page="skin_detail"]) .sd-phase:hover { border-color: var(--accent); transform: translateY(-1px); }
:where(body[data-page="skin_detail"]) .sd-phase.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
:where(body[data-page="skin_detail"]) .sd-phase img { width: 52px; height: 40px; object-fit: contain; }
:where(body[data-page="skin_detail"]) .sd-phase span {
      font-size: 0.6rem; font-weight: 600; color: var(--text-dim);
      text-align: center; line-height: 1.1; white-space: nowrap;
    }
:where(body[data-page="skin_detail"]) .sd-phase.active span { color: var(--accent); }


/* ── Component: hero search ──────────────────────────────────────────────────
   A single prominent search field at the top of a browse page. Global, not
   page-scoped: the redesign plan's §3 component system is what replaces the
   per-page stylesheets, so anything a second browse page would want is defined
   once, here. */
.hero-search { padding: 28px 24px 18px; max-width: 700px; margin: 0 auto; }
.hero-search-wrap { position: relative; display: flex; align-items: center; }
.hero-search-wrap svg {
  position: absolute;
  left: 16px;
  color: var(--muted);
  pointer-events: none;
  flex-shrink: 0;
}
.hero-search-input {
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-lg);
  padding: 14px 20px 14px 46px;
  font-size: 0.95rem;
  font-family: inherit;
  outline: none;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.hero-search-input::placeholder { color: var(--muted); }
.hero-search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); }
.hero-stats { text-align: center; font-size: 0.72rem; color: var(--muted); margin-top: 10px; }
.hero-stats strong { color: var(--text); }

/* ── Component: category chips ── */
.cat-section { padding: 0 20px 14px; max-width: 1400px; margin: 0 auto; }
.cat-chips { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
.cat-chips::-webkit-scrollbar { display: none; }
.cat-chip {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  min-width: 84px;
  transition: border-color var(--transition), background var(--transition),
              box-shadow var(--transition), transform 0.1s;
  text-align: center;
  user-select: none;
}
.cat-chip:hover { border-color: var(--border-hover); background: var(--panel-hover); transform: translateY(-1px); }
.cat-chip.active { border-color: var(--accent); background: var(--accent-subtle); box-shadow: 0 0 0 1px var(--accent-glow); }
.cat-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cat-chip-img { width: 50px; height: 36px; object-fit: contain; filter: drop-shadow(0 2px 6px rgba(0,0,0,0.5)); }
.cat-chip-img-placeholder {
  width: 50px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  font-size: 20px;
}
.cat-chip-name { font-size: 0.72rem; font-weight: 600; color: var(--text); white-space: nowrap; }
.cat-chip.active .cat-chip-name { color: var(--accent); }
.cat-chip-count { font-size: 0.6rem; color: var(--muted); margin-top: -4px; font-variant-numeric: tabular-nums; }

/* ── Component: browse filter row ── */
.browse-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 20px 14px;
  max-width: 1400px;
  margin: 0 auto;
  align-items: center;
}
.browse-filters select {
  width: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 6px 30px 6px 10px;
  font-size: 0.78rem;
  cursor: pointer;
}
.browse-filters .st-label {
  display: flex; align-items: center; gap: 6px;
  cursor: pointer; font-size: 0.75rem; color: var(--muted);
  padding: 6px 10px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--panel);
  white-space: nowrap; user-select: none;
  transition: border-color var(--transition), color var(--transition);
}
.browse-filters .st-label:hover { border-color: var(--border-hover); color: var(--text); }
.browse-filters .st-label input { width: auto; padding: 0; min-height: auto; }
.filter-spacer { flex: 1; }
.result-count { font-size: 0.72rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.result-count strong { color: var(--text); }

/* ── Component: custom select (colour swatch / thumbnail options) ── */
.csel { position: relative; }
.csel-btn {
  display: flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--border); color: var(--text);
  border-radius: var(--radius-sm); padding: 6px 10px; font-size: 0.78rem;
  font-family: inherit; cursor: pointer; min-width: 150px;
  transition: border-color var(--transition);
}
.csel-btn:hover { border-color: var(--border-hover); }
.csel.open .csel-btn { border-color: var(--accent); }
.csel-cur { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0; }
.csel-cur .csel-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.csel-chev { margin-left: auto; color: var(--muted); transition: transform 0.2s; flex-shrink: 0; }
.csel.open .csel-chev { transform: rotate(180deg); }
.csel-panel {
  display: none; position: absolute; top: calc(100% + 4px); left: 0; z-index: 200;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0,0,0,0.5); padding: 4px;
  max-height: 340px; overflow-y: auto; min-width: 100%; width: max-content; max-width: 300px;
}
.csel.open .csel-panel { display: block; }
.csel-opt {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border-radius: var(--radius-sm); cursor: pointer; font-size: 0.78rem; white-space: nowrap;
}
.csel-opt:hover { background: var(--panel-hover); }
.csel-opt.sel { background: var(--accent-subtle); }
.csel-dot { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.csel-thumb { width: 24px; height: 24px; object-fit: contain; flex-shrink: 0; }
.csel-label { overflow: hidden; text-overflow: ellipsis; }

/* ── Component: StatTile ─────────────────────────────────────────────────────
   The `StatTile` redesign plan §3 lists as missing. One headline number with a
   label above and a quiet qualifier below. Digits are tabular and lining (§2.3)
   so a live-updating value never changes its own width as it counts — the
   jitter that made the old per-page stat strips feel unfinished. Profit/loss
   colour goes on the number only, never the tile (§2.1). */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}
/* The author-origin `display: grid` above beats the UA [hidden]{display:none}
   rule (same specificity, later in source) — without this, `el.hidden = true`
   is a no-op and a page that toggles this row (inventory.html) can show a
   stale/empty StatTile strip stacked above an error message. Four other
   components already carry the identical fix (search this file for
   `[hidden] { display: none; }`); this is the fifth. */
.stat-row[hidden] { display: none; }
.stat-tile {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 13px 15px;
  min-width: 0;
}
.stat-tile-k {
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat-tile-v {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1;
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1.2;
  margin-top: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Holds its own line height even when empty, so a tile with no qualifier is
   exactly as tall as its neighbours and the row's baselines stay aligned. */
.stat-tile-sub {
  font-size: 0.68rem;
  color: var(--muted);
  margin-top: 3px;
  min-height: 1em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat-tile .pos { color: var(--green); }
.stat-tile .neg { color: var(--red); }


/* ── Component: dense data table ─────────────────────────────────────────────
   The `Table` the redesign plan §3 lists as missing. Density scales with list
   length (§2.2): this is the browse/compare mode a trader scans, so rows are
   tight, numbers are tabular, and rarity is a left border rather than a fill. */
.dtable-wrap {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 20px;
  /* Deliberately NOT `overflow-x: auto` here. `overflow-y` would then compute
     to `auto` as well (CSS Overflow 3), making this element the scrollport for
     the sticky header inside it — and since the wrapper has no height cap it
     never scrolls, so the header would never stick to anything. The table has
     a min-width, so only narrow viewports need to scroll sideways; that is
     switched on in the media query below, where losing sticky is a better
     trade than losing three price columns. */
}
.dtable {
  width: 100%;
  min-width: 720px;
  /* `separate` (not `collapse`) is what lets the sticky header keep its own
     background and bottom border while rows scroll underneath it. */
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.8rem;
}
.dtable thead th {
  position: sticky;
  /* Clears the site header, which is itself `sticky; top: 0; height: 56px;
     z-index: 200`. At top:0 this row would be pinned underneath it and never
     seen. 56px is the offset `aside` already uses for the same reason. */
  top: 56px;
  z-index: 5;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: right;
  padding: 9px 10px;
  white-space: nowrap;
}
.dtable thead th.col-thumb { width: 46px; padding-left: 13px; }
.dtable thead th.col-name { text-align: left; }
.dtable th.sortable { cursor: pointer; user-select: none; }
.dtable th.sortable:hover { color: var(--text); }
.dtable th.sortable:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dtable th.sorted { color: var(--accent); }
/* The indicator holds its own width so a column header doesn't shift when the
   neutral ↕ becomes a directional arrow. */
.dtable .sort-ind { display: inline-block; width: 10px; margin-left: 4px; opacity: 0.55; }
.dtable th.sorted .sort-ind { opacity: 1; }

.dtable tbody td {
  border-bottom: 1px solid var(--border);
  padding: 6px 10px;
  text-align: right;
  vertical-align: middle;
}
.dtable tbody tr { cursor: pointer; transition: background var(--transition); }
.dtable tbody tr:hover td { background: var(--panel-hover); }
/* Rarity lives on the row's leading edge — never as a background fill (§2.1).
   The border sits on the first cell because `border-collapse: separate` drops
   borders set on the <tr> itself. */
.dtable tbody td:first-child { border-left: 3px solid var(--rc, transparent); padding-left: 10px; }
.dtable tbody tr:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* `.static` — for a dtable embedded outside the page's own scroll context
   (e.g. the dashboard's small in-card tables): read-only, so no row-click
   cursor; not the page's primary list, so its header shouldn't stick to the
   viewport the way the full-page tables' does (there's no scrolling ancestor
   here for `position: sticky` to stick within, so it would otherwise pin to
   the viewport at an arbitrary point inside a small card); and no wide
   min-width, since a compact 2–3 column table doesn't need the guard that
   protects a multi-column price table from getting squished on a phone. */
.dtable.static { min-width: 0; }
.dtable.static tbody tr { cursor: default; }
.dtable.static thead th { position: static; }
/* `.dtable thead th { background: var(--bg) }` is needed for the sticky
   header elsewhere, but inside a `.static` table (embedded in a `.db-panel`
   card) it painted all four dashboard table headers a darker band that
   didn't match their card — verified with getComputedStyle
   (rgb(10,12,17) vs the panel's rgb(20,24,35)). `.dtable.static thead th`
   (0,2,2) beats `.dtable thead th` (0,1,2), so this isn't dead. */
.dtable.static thead th { background: transparent; }

.dtable-thumb { width: 44px; height: 33px; object-fit: contain; display: block; }
.dtable-thumb-empty {
  width: 44px; height: 33px;
  display: flex; align-items: center; justify-content: center;
  color: var(--border-hover);
}
.dtable td.cell-name { text-align: left; max-width: 340px; }
.dtable-name {
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dtable-sub {
  font-size: 0.68rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dtable td.cell-price {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dtable td.cell-price.best { color: var(--accent); }
.dtable .no-price { color: var(--border-hover); }

.dtable td.cell-trend { font-variant-numeric: tabular-nums; white-space: nowrap; }
.trend-arrow { margin-right: 3px; }
.trend-up   { color: var(--green); }
.trend-down { color: var(--red); }
.trend-flat, .trend-none { color: var(--muted); }

/* The 7d cell pairs a shape with a number: the sparkline shows the path the
   price took over the window, the arrow + signed % carry direction and size.
   The line strokes currentColor, so it inherits the same trend-up/down/flat
   colour as the number — one rule, never a second palette to keep in sync. */
/* Spark pinned to the column's left edge, number pushed to its right edge by
   the auto margin. Every cell in a table column is already the same width, so
   anchoring to the two edges aligns both down the page for free — no reserved
   min-width to keep in step with the font. Padding the number to a fixed width
   instead looks equivalent and is not: a three-digit move (+382.2%) overflows
   whatever number you picked and shunts that row's line out of column. */
.dtable .trend-inner {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 7px;
}
.dtable .cell-spark { display: block; flex: none; }
/* Rows with no history still reserve the line's slot, so the numbers beside
   them don't slide left out of the column. */
.dtable .cell-spark-empty { width: 52px; height: 16px; }
.dtable .trend-num { margin-left: auto; text-align: right; }

/* Below the table's min-width the columns can no longer all fit, so the wrapper
   becomes a horizontal scroller. That costs the sticky header (see above) —
   accepted here, because a phone that can't reach the BS column is worse. */
@media (max-width: 820px) {
  .dtable-wrap { overflow-x: auto; }
}

/* The sparkline is the first thing to yield when the table runs out of room:
   the arrow and the % survive, which is the part answering "is this moving, and
   by how much".

   900px, not 640px, and the gap between the two breakpoints above is exactly
   why. The line adds ~59px of INCOMPRESSIBLE width to the trend column. Under
   820px that lands in the wrapper's own scroller and costs nothing. Over ~900px
   the table has slack and absorbs it. Between the two the table is already at
   its min-content width with no scroller to catch the overflow, so the extra
   width escapes to the document and the whole page gains a horizontal
   scrollbar, dragging the header and hero out of alignment. Measured on the
   real page at 825px sorted by Factory New descending (the longest price
   strings on the site): table 785px -> 807px, document 827px against an 825px
   viewport. A phone check and a desktop check both step straight over this
   band. */
@media (max-width: 900px) {
  .dtable .cell-spark { display: none; }
}

@media (max-width: 640px) {
  .hero-search { padding: 20px 16px 12px; }
  .cat-section, .browse-filters { padding-left: 12px; padding-right: 12px; }
  /* The table runs edge-to-edge: every pixel is another price column reachable
     before the user has to swipe. */
  .dtable-wrap { padding-left: 0; padding-right: 0; }
}
