:root {
  /* Sticky-stack heights — tweak together with header/tabs padding so the
     subtabs land flush below the global nav. */
  --header-h: 64px;
  --tabs-h: 50px;
  /* Default = light theme. Dark theme overrides via [data-theme="dark"]
     below. Theme is selected by app.js based on localStorage / OS pref. */
  --bg-primary: #f5f6f8;
  --bg-secondary: #ffffff;
  --bg-card: #ffffff;
  --bg-card-hover: #f0f3f7;
  --border: #d8dde4;
  --text-primary: #1a1f2c;
  --text-muted: #5d6878;
  --accent: #a37516;
  --accent-bright: #c89b3c;
  --accent-glow: rgba(163, 117, 22, 0.2);
  --modal-bg: rgba(20, 25, 35, 0.55);
  --error: #c0392b;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.06);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.18);
}

[data-theme="dark"] {
  --bg-primary: #0f1419;
  --bg-secondary: #1a1f2c;
  --bg-card: #1a1f2c;
  --bg-card-hover: #242a39;
  --border: #2a3140;
  --text-primary: #e6e9ef;
  --text-muted: #9aa3b3;
  --accent: #c89b3c;
  --accent-bright: #f0c674;
  --accent-glow: rgba(200, 155, 60, 0.25);
  --modal-bg: rgba(0, 0, 0, 0.7);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.6);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
[hidden] { display: none !important; }

body {
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: 'Segoe UI', system-ui, -apple-system, "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, sans-serif;
  line-height: 1.5;
  min-height: 100vh;
}

button { font-family: inherit; }

code {
  background: var(--bg-card);
  padding: 0.1em 0.4em;
  border-radius: 3px;
  font-size: 0.9em;
}

/* ---------- Top bar (sticky wrapper) ---------- */
/* Single sticky container holds the site header AND the main tab strip.
   Wrapping them avoids the issue where putting `position: sticky` directly
   on `.tabs` (which also needs `overflow-x: auto` for horizontal scrolling
   of overflowing tab labels) made the sticky behaviour unreliable on
   mobile — the bar would visually disappear or detach from the header
   during scroll. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg-secondary);
  box-shadow: var(--shadow-sm);
}

/* ---------- Header ---------- */
.site-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 2rem;
  min-height: var(--header-h);
  border-bottom: 1px solid var(--border);
  background: var(--bg-secondary);
}

.site-title {
  /* ワイポケ mark + "ワイリフPocket" wordmark lockup. The mark anchors
     the brand identity (visible in favicon / app icon / og-image too);
     the wordmark carries the formal name + JP/EN switch. */
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  /* Logo doubles as a "back to home" link — reset native button chrome
     so it visually reads as the original heading. */
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  color: inherit;
  text-align: left;
  transition: opacity 0.15s;
}

.site-title-mark {
  /* Sized to the full wordmark stack: site-title-main (1.5rem) + gap
     (0.1rem) + patch-badge (0.7rem) = 2.3rem. Stays at this size even
     when patch-badge is hidden — slight visual surplus then, but the
     badge is the normal state once meta.json loads. */
  width: 2.3rem;
  height: 2.3rem;
  flex-shrink: 0;
  display: block;
}

.site-title-text {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  min-width: 0;
}

.site-title-main {
  font-family: 'Chakra Petch', 'Segoe UI', system-ui, sans-serif;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1;
}

.site-title-tag {
  font-family: 'Chakra Petch', 'Segoe UI', system-ui, sans-serif;
  font-size: 0.65rem;
  font-weight: 600;
  /* Tracked-out caps so the tagline reads as a brand mark, not body text.
     letter-spacing applies to the space character too, so the gap between
     WILD and RIFT would otherwise read as ~1.5 letter widths. word-spacing
     pulls it back so the inter-word break matches the inter-letter rhythm. */
  letter-spacing: 0.4em;
  word-spacing: -0.5em;
  color: var(--text-muted);
  line-height: 1;
}

.site-title:hover .accent {
  color: var(--accent-bright);
}

.site-title:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 3px;
}

.accent {
  color: var(--accent);
  text-shadow: 0 0 20px var(--accent-glow);
}

.lang-toggle {
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border);
  padding: 0 1rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.85rem;
  /* Inline-flex + fixed min-height so the height doesn't depend on the
     content's intrinsic line metrics — emojis like ☀/🌙 render at
     different glyph heights from "JP / EN", and without this the two
     header chips would drift to different sizes. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.25rem;
  transition: all 0.2s;
}

.lang-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.header-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

/* Patch label sits BELOW the logo as a small sub-line. Earlier we
   parked it next to the toggles, but on narrow viewports it competed
   for header width and pushed the toggles to wrap. Stacking it under
   the logo turns the title block into a tidy two-line lockup with
   the patch-version reading like a sub-title rather than a chip. */
.patch-badge {
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--text-secondary);
  letter-spacing: 0.05em;
  line-height: 1;
  white-space: nowrap;
  cursor: default;
}

/* Same min-height + flex centering as .lang-toggle so the two header
   chips line up regardless of the rendered glyph (☀/🌙 differ from
   the "JP / EN" text in intrinsic height). */
.theme-toggle {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.85rem;
  padding: 0 0.7rem;
  color: var(--text-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.25rem;
  transition: border-color 0.2s, color 0.2s;
}

.theme-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ---------- Tabs ---------- */
/* The horizontal scroll lives on .tabs-scroll (the wrapper inside .topbar).
   .tabs itself only handles flex layout + the indicator anchor. */
.tabs-scroll {
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}

.tabs {
  display: flex;
  align-items: stretch;
  gap: 0.25rem;
  padding: 0 2rem;
  min-height: var(--tabs-h);
  position: relative;
}

.tab-btn {
  background: transparent;
  color: var(--text-muted);
  border: none;
  padding: 0.85rem 1.5rem;
  cursor: pointer;
  font-size: 0.95rem;
  font-weight: 600;
  position: relative;
  transition: color 0.2s;
  white-space: nowrap;
}

.tab-btn:hover { color: var(--text-primary); }

.tab-btn.active { color: var(--accent); }

/* Single sliding underline that animates between active tabs.
   Position + width are set imperatively from app.js after layout. */
.tab-indicator {
  position: absolute;
  bottom: -1px;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--accent);
  transform: translateX(0);
  transition: transform 0.25s ease, width 0.25s ease;
  pointer-events: none;
  will-change: transform, width;
}

.tabs { position: relative; }

/* ---------- Main ---------- */
.main {
  max-width: 1400px;
  margin: 0 auto;
  padding: 1.5rem 2rem;
}

.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* Sub-tab host lives inside .topbar so the subtab strip rides along
   with the rest of the sticky chrome — never moves on scroll. Each
   tab has its own .subtabs node; only the active one is visible
   (others have [hidden] toggled by app.js on tab switch). */
.subtabs-host {
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
}

.subtabs {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.4rem;
  margin: 0;
  padding: 0.5rem 2rem 0.6rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Match the .main padding so subtab buttons line up horizontally
     with the grid below them; .main has padding 1.5rem 2rem. */
}

.subtab-btn {
  flex-shrink: 0;
  padding: 0.4rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-primary);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.15s;
}

.subtab-btn:hover,
.subtab-btn:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}

.subtab-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.75rem;
}

.list {
  display: grid;
  /* Mobile: single column. Tablet (>=720px): 2 cols. Desktop (>=1100px):
     3 cols. Card content (image + name + subtitle + meta) is fixed-
     width-friendly so the grid wraps naturally; meta column on the
     right floats with `justify-self: end`. */
  grid-template-columns: 1fr;
  gap: 0.5rem;
}

@media (min-width: 720px) {
  .list { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1100px) {
  .list { grid-template-columns: repeat(3, 1fr); }
}

.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem;
  cursor: pointer;
  transition: all 0.2s;
  box-shadow: var(--shadow-sm);
}

.card:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.card-img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 6px;
  margin-bottom: 0.5rem;
  display: block;
}

.card-img-placeholder {
  background: var(--bg-primary);
  border: 1px solid var(--border);
}

.card-name {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.card-name-sub {
  font-size: 0.75rem;
  color: var(--text-muted);
  font-weight: 400;
}

/* Items All view: tier section is the outermost container
   (アップグレード済み / 中級 / 基本 / エンチャント) and wraps nested
   category sections (物理 / 魔法 / ...). Sub-tab views render flat
   tier sections without the category nesting. */
.tier-section + .tier-section {
  margin-top: 2rem;
}

.tier-heading {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text);
  margin: 0 0 0.85rem 0;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--border);
}

/* When a category section sits inside a tier section, demote its
   heading visually so the tier label reads as the primary divider. */
.tier-section .category-section + .category-section {
  margin-top: 1rem;
}

.tier-section .category-heading {
  /* keep existing category-heading defaults, but ensure there's a
     comfortable gap from the preceding card list */
  margin-top: 0.25rem;
}

/* Category section in tab panels */
.category-section + .category-section {
  margin-top: 1.5rem;
}

.category-heading {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  text-transform: uppercase;
  margin: 0 0 0.6rem 0.1rem;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--border);
}

/* Rune slot subgroup: each minor slot (0/1/2) is rendered as a separate
   block within the path so mutually-exclusive runes read as one cluster. */
.rune-slot + .rune-slot {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--border);
}

.card-meta {
  margin-top: 0.5rem;
  font-size: 0.85rem;
  color: var(--accent);
}

.list-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  cursor: pointer;
  transition: all 0.2s;
  box-shadow: var(--shadow-sm);
}

.list-card:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
}

.list-card-inner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.list-card-img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  flex-shrink: 0;
}

.list-card-img-placeholder {
  background: var(--bg-primary);
  border: 1px solid var(--border);
}

.card-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0; /* let card-name truncate inside flexbox */
}

.card-subtitle {
  font-size: 0.78rem;
  color: var(--text-muted);
  line-height: 1.25;
}

/* Right-side meta block on item list rows: price + (optional) gold
   efficiency stacked, right-aligned. Gold efficiency is suppressed for
   non-core items in items.js because the input data is unreliable. */
.list-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.15rem;
  text-align: right;
  white-space: nowrap;
  flex-shrink: 0;
}

.list-meta-price {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--accent-gold, var(--accent));
}

.list-meta-eff {
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* Champion list right meta: per-lane CN Diamond+ win rate stack
   (data/raw/cn_hero_rank.json → distribute → site_data). Multi-row
   when the champion plays multiple lanes. */
.rank-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.1rem;
  font-size: 0.72rem;
  white-space: nowrap;
}

.rank-line {
  display: flex;
  gap: 0.4rem;
  align-items: baseline;
}

.rank-lane {
  color: var(--text-muted);
  font-size: 0.65rem;
  letter-spacing: 0.04em;
}

.rank-wr-label {
  color: var(--text-muted);
  font-size: 0.62rem;
  letter-spacing: 0.05em;
}

.rank-wr {
  color: var(--accent);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.loading {
  text-align: center;
  padding: 2rem;
  color: var(--text-muted);
}

.error-banner {
  background: #fdecea;
  border: 1px solid var(--error);
  color: var(--error);
  padding: 1rem;
  border-radius: 6px;
  margin-bottom: 1rem;
}

/* ---------- Modal ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: var(--modal-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1rem;
  z-index: 100;
  animation: fadeIn 0.15s ease-out;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.modal {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 12px;
  width: 100%;
  max-width: 800px;
  /* Always the same vertical size regardless of content — short items
     and long items both render in the same frame, contents scroll
     internally. Reserves room below for the outer close button. */
  height: calc(100% - 4.25rem);
  overflow-y: auto;
  position: relative;
  padding: 2rem;
  animation: slideUp 0.2s ease-out;
  box-shadow: var(--shadow-lg);
}

@keyframes slideUp {
  from { transform: translateY(20px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* Close button lives outside the modal frame, below it. Sized for thumb
   reach on phones (>= 44 px touch target per Apple/Google HIG). */
.modal-close {
  flex-shrink: 0;
  background: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--border);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-lg);
}

.modal-close:hover,
.modal-close:focus-visible {
  background: var(--bg-primary);
  color: var(--accent);
  outline: none;
}

/* Back-to-top: floating action button at the bottom-right. Only shows
   after the user has scrolled past the first viewport (controlled by
   the `hidden` attribute toggled in app.js). */
.back-to-top {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  color: var(--accent);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow-lg);
  transition: opacity 0.2s, transform 0.2s, background 0.2s;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
}

.back-to-top[hidden] {
  display: none;
}

.back-to-top:hover,
.back-to-top:focus-visible {
  background: var(--bg-primary);
  outline: none;
  transform: translateY(-2px);
}

/* Modal header: thumbnail on the left, metadata stacked vertically and
   bounded by the thumbnail's height. Stack from top: category badge,
   title/epithet (champions), primary name, optional secondary name. */
.modal-header {
  display: flex;
  align-items: stretch;
  gap: 1rem;
  margin: 0 0 0.5rem;
}

.modal-thumb {
  width: 96px;
  height: 96px;
  flex-shrink: 0;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
}

.modal-thumb-placeholder { display: block; }

.modal-header-text {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.15rem;
  /* Cap stack height to the thumbnail so all rows fit alongside it. */
  max-height: 96px;
  overflow: hidden;
}

.modal-category {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--accent);
  text-transform: uppercase;
  line-height: 1.2;
}

.modal-title-epithet {
  font-size: 0.85rem;
  font-style: italic;
  color: var(--text-muted);
  margin: 0;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.modal-title {
  font-size: 1.4rem;
  margin: 0;
  word-break: break-word;
  line-height: 1.2;
}

.modal-name-sub {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin: 0;
  line-height: 1.2;
}

/* base / upgrade tabs in the item modal. Only rendered when the item
   has a growth_form pair (Manamune→Muramana, Relic Shield→Bulwark, …).
   Mirrors the main G-nav (.tabs / .tab-indicator) interaction —
   sliding underline animates between active tabs, content swap is a
   hard cut. Keeps the swipe feel consistent with the top-level nav. */
.modal-tabs {
  position: relative;
  display: flex;
  gap: 0.5rem;
  margin: 0 0 0.25rem 0;
  border-bottom: 1px solid var(--border);
}
.modal-tab {
  background: transparent;
  border: none;
  padding: 0.5rem 1rem;
  cursor: pointer;
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.95rem;
  transition: color 0.15s;
}
.modal-tab:hover { color: var(--text-primary); }
.modal-tab.active { color: var(--accent); }

.modal-tab-indicator {
  position: absolute;
  bottom: -1px;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--accent);
  transform: translateX(0);
  transition: transform 0.25s ease, width 0.25s ease;
  pointer-events: none;
  will-change: transform, width;
}

.modal-pane[hidden] { display: none !important; }

.modal-section { margin-top: 1.5rem; }

.modal-section-title {
  color: var(--accent);
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0 0 0.5rem 0;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.25rem;
}

.modal-description {
  white-space: pre-wrap;
  color: var(--text-primary);
  font-size: 0.95rem;
  margin: 0;
}

.modal-description.cn-fallback {
  font-family: "Noto Sans JP", "Noto Sans SC", sans-serif;
  color: var(--text-secondary);
}

.cn-fallback-badge {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.65rem;
  font-weight: normal;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-secondary);
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: 3px;
  vertical-align: middle;
}

.ability {
  margin-bottom: 0.75rem;
  padding: 0.75rem;
  background: var(--bg-primary);
  border-radius: 6px;
  border-left: 3px solid var(--accent);
}

.ability-header {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  flex-wrap: wrap;
}

.ability-key {
  color: #fff;
  background: var(--accent);
  font-weight: 700;
  font-size: 0.8rem;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
}

.ability-name { font-weight: 600; }

.ability-name-sub {
  color: var(--text-muted);
  font-size: 0.8rem;
}

.ability-description {
  white-space: pre-wrap;
  color: var(--text-primary);
  font-size: 0.9rem;
}

/* CD / Cost summary pulled to its own row above the ability body so
   the numeric metadata reads as separate metadata, not prose. */
.ability-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.3rem 0 0.5rem 0;
}
.ability-meta-tag {
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--accent);
  background: var(--bg-card-hover);
  border: 1px solid var(--border);
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  letter-spacing: 0.02em;
}

.stats-control {
  margin-bottom: 1rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}

.stats-control label {
  color: var(--text-muted);
  font-size: 0.9rem;
  min-width: 1.5rem;
}

#stats-level {
  flex: 1;
  accent-color: var(--accent);
}

#level-display {
  color: var(--accent);
  font-weight: 700;
  min-width: 6ch;
  text-align: right;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.5rem;
}

.stat-item {
  background: var(--bg-primary);
  border: 1px solid var(--border);
  padding: 0.5rem 0.75rem;
  border-radius: 4px;
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
}

.stat-label { color: var(--text-muted); }

.stat-value {
  color: var(--accent);
  font-weight: 600;
}

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  /* Reserve space even when empty (upgrade tab has no separate price)
     so swapping tabs doesn't shift the rest of the modal vertically. */
  min-height: 1.75rem;
}

.tag {
  background: var(--bg-primary);
  border: 1px solid var(--border);
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.tag.gold {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  font-weight: 600;
}

/* ---------- Footer ---------- */
.site-footer {
  padding: 2rem 1.5rem;
  color: var(--text-muted);
  font-size: 0.75rem;
  line-height: 1.5;
  border-top: 1px solid var(--border);
  margin-top: 3rem;
  max-width: 960px;
  margin-left: auto;
  margin-right: auto;
}

.site-footer p {
  margin: 0 0 0.6rem;
}

.footer-attribution {
  text-align: center;
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

.footer-sources {
  text-align: center;
}

.footer-disclaimer {
  font-size: 0.7rem;
  color: var(--text-muted);
  opacity: 0.85;
}

/* ---------- Responsive ---------- */
@media (max-width: 600px) {
  /* Mobile shrinks header + tabs — keep the sticky stack offsets in sync. */
  :root {
    --header-h: 52px;
    --tabs-h: 44px;
  }
  .site-header { padding: 0.75rem 1rem; }
  .site-title-main { font-size: 1.25rem; }
  .site-title-mark { width: 2.05rem; height: 2.05rem; }
  .site-title-tag { font-size: 0.55rem; letter-spacing: 0.35em; }
  .tabs { padding: 0 0.5rem; }
  .tab-btn { padding: 0.75rem 1rem; font-size: 0.85rem; }
  .main { padding: 1rem; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 0.5rem; }
  .modal-overlay {
    padding: 1rem 0.75rem;
    align-items: stretch;
  }
  .modal {
    padding: 1.5rem;
    /* Mobile: shrink modal so the outer close button stays in the
       thumb zone above the bottom edge. Fixed height for visual
       consistency regardless of item complexity. */
    height: calc(100% - 4.25rem);
  }
  .modal-close {
    align-self: center;
  }
  .modal-title { font-size: 1.25rem; }
}

/* ---------- Scouter (Phase A: items-only build calculator) ---------- */
.scouter-root {
  /* Inherit from .main's 1400px max-width and 2rem padding — the
     scouter wants to feel like a full workspace, not a narrow column,
     especially once the stats panel + multi-build comparison land. */
  width: 100%;
  padding: 1rem 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  /* Block horizontal overflow from any wide child (eg. the 3-column
     stats table on narrow viewports) so the global swipe-nav handler
     in app.js doesn't fight a native horizontal scroll. */
  overflow-x: clip;
  touch-action: pan-y;
}

.scouter-champ-header {
  display: flex;
  gap: 1rem;
  align-items: stretch;
  /* nowrap + flex-shrink:0 on the level badge keeps "Lv 15" on the
     same row as the champion card; the card itself shrinks via
     min-width:0 so its long titles truncate before the row wraps. */
  flex-wrap: nowrap;
}

.scouter-champ-pick {
  flex: 1 1 0;
  min-width: 0;
  min-height: 72px;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  color: var(--text-primary);
  font-size: 1.1rem;
  text-align: left;
  transition: background 0.15s, border-color 0.15s;
}
.scouter-champ-pick:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent);
}
.scouter-champ-pick.scouter-champ-empty {
  justify-content: center;
  color: var(--text-muted);
  font-style: italic;
}
.scouter-champ-img {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.scouter-champ-meta {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1 1 auto;
  min-width: 0;
}
.scouter-champ-name { font-weight: 700; }
.scouter-champ-title {
  color: var(--text-muted);
  font-size: 0.85rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Stats panel header: title on the left, level pill on the right.
   Lives inside .scouter-stats so the level indicator sits above the
   number table (where it's most relevant) instead of competing with
   the champion title up top. */
.scouter-stats-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.scouter-stats-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Level badge: compact "Lv 15" inline pill placed in the stats header.
   Single horizontal line; nowrap + flex-shrink:0 keep it intact. */
.scouter-level-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  flex-shrink: 0;
  padding: 0.25rem 0.6rem;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 999px;
  white-space: nowrap;
  cursor: default;
}
.scouter-level-label {
  font-size: 0.7rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.scouter-level-val {
  color: var(--accent);
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
}

/* Slot rows: 5 regular items in one row + boots/enchant pair below.
   Sized so 5 × slot + 4 × gap fits inside ~320px (= the narrowest
   smartphone in landscape after side padding); on roomier viewports the
   container caps at the .scouter-root max-width and stays one row.
   `nowrap` is intentional — reflowing item slots into 2 lines breaks the
   "this is your inventory" mental model. */
.scouter-slots { display: flex; flex-direction: column; gap: 0.5rem; }
.scouter-slots-row {
  display: flex;
  gap: 0.4rem;
  flex-wrap: nowrap;
}
/* Accessory row hosts two visual groups: boots + enchant on the left,
   summoner-spell pair on the right. The wider gap between groups
   communicates that they're separate loadout sections (mirrors WR's
   in-game champion-select layout where boots/enchant and spells are
   distinct UI clusters). */
.scouter-accessory-row {
  gap: 1.2rem;
  flex-wrap: wrap;
}
.scouter-slots-group {
  display: flex;
  gap: 0.4rem;
  flex-wrap: nowrap;
}
.scouter-slot.locked {
  cursor: default;
  border-style: solid;
}
.scouter-slot.locked:hover {
  border-color: var(--border);
  background: var(--bg-card);
}

.scouter-slot {
  position: relative;
  flex: 0 0 auto;
  /* clamp(min, preferred, max). At 320px viewport (iPhone SE / 12 mini)
     `.main` padding is 1rem → 32px usable lost, leaving 288px for the
     row. 5 slots + 4 gaps must fit, so the preferred width caps at
     ~16vw (51.2px @320), and we clamp the min low enough that even a
     280px viewport doesn't push the 5th slot off the right edge. */
  width: clamp(44px, 16vw, 64px);
  aspect-ratio: 1 / 1;
  border: 1px dashed var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 1.5rem;
  transition: border-color 0.15s, background 0.15s;
}
.scouter-slot:hover {
  border-color: var(--accent);
  background: var(--bg-card-hover);
}
.scouter-slot.filled {
  border-style: solid;
  padding: 0;
}
.scouter-slot-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 7px;
}
/* Ghost variant: empty boots / enchant slots show their canonical
   item icon at low opacity + grayscale, communicating the category
   without needing a glyph. */
.scouter-slot-img.scouter-slot-ghost {
  filter: grayscale(1);
  opacity: 0.3;
  transition: opacity 0.15s, filter 0.15s;
}
.scouter-slot:hover .scouter-slot-img.scouter-slot-ghost {
  opacity: 0.55;
}
.scouter-slot-clear {
  /* Anchored INSIDE the slot rather than protruding outside (-6px /
     -6px) — the rightmost item slot's × would otherwise get clipped
     by .scouter-root's overflow-x: clip. */
  position: absolute;
  top: 2px;
  right: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  font-size: 0.7rem;
  color: var(--text-muted);
  line-height: 14px;
  text-align: center;
  cursor: pointer;
  /* Sit above the slot icon so the × is always tappable. */
  z-index: 1;
}
.scouter-slot-clear:hover {
  background: var(--error);
  color: #fff;
  border-color: var(--error);
}
.scouter-slot-tip {
  position: absolute;
  bottom: -22px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.7rem;
  color: var(--text-muted);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}
.scouter-slot.filled:hover .scouter-slot-tip {
  opacity: 1;
}
.scouter-slot-placeholder { user-select: none; }
.scouter-slot-boots,
.scouter-slot-bootsEnchant {
  background: linear-gradient(135deg, var(--bg-card), var(--bg-card-hover));
}

.scouter-stats {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem;
}
.scouter-empty {
  text-align: center;
  color: var(--text-muted);
  padding: 2rem 1rem;
}
.scouter-stats-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.scouter-stats-table th,
.scouter-stats-table td {
  padding: 0.5rem 0.6rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
.scouter-stats-table thead th {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.scouter-stats-table tbody th {
  font-weight: 500;
  color: var(--text-primary);
}
.scouter-stats-table tbody td {
  font-weight: 700;
  color: var(--text-primary);
  text-align: right;
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
}
.scouter-stats-table tr.scouter-final-row th,
.scouter-stats-table tr.scouter-final-row td {
  color: var(--accent);
  border-top: 1px solid var(--accent);
}
.scouter-cap-warn {
  color: #d99e3e;
  font-size: 0.85em;
  margin-left: 0.3em;
}

/* Δ column shown when the user has staged a what-if swap. Increases
   read green, decreases read red — universally signed regardless of
   stat semantics, since "more cooldown = bad" is too domain-specific
   to colour automatically at this stage. */
.scouter-stats-table.has-delta {
  /* table-layout: auto so columns size to content; this prevents the
     Δ values (e.g. "+2,316") from overflowing a fixed-width column.
     The wrapping container below clips/scrolls if the whole table
     can't fit at very narrow viewports. */
  table-layout: auto;
}
.scouter-stats-wrap {
  overflow-x: auto;
  /* Respect the global swipe handler — only scroll horizontally when
     content actually overflows, never on small drags. */
  overscroll-behavior-x: contain;
}
.scouter-stats-table.has-delta th,
.scouter-stats-table.has-delta td {
  padding-right: 0.4rem;
}
.scouter-delta-h {
  text-align: right;
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
}
.scouter-stats-table .scouter-delta {
  text-align: right;
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
  font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
  padding-left: 0.5rem;
}
.scouter-stats-table .scouter-delta.pos {
  color: #27a35e;
}
.scouter-stats-table .scouter-delta.neg {
  color: var(--error);
}
[data-theme="dark"] .scouter-stats-table .scouter-delta.pos {
  color: #4ec97f;
}

/* Alt-comparison accordion: renders directly below the main loadout
   slots and contains a parallel slot grid that writes to build.alts.
   Native `<details>` so keyboard / SR support comes for free. */
/* No border, no horizontal padding — the alt slot row needs the same
   effective width as the main loadout so 5 slots still fit in a single
   line at narrow viewports (the main row has no border or pad and
   sits edge-to-edge). Visual grouping comes from a top divider line +
   the summary header alone. */
.scouter-alts {
  border-top: 1px dashed var(--border);
  padding-top: 0.5rem;
}
.scouter-alts > .scouter-slots {
  padding: 0;
}
.scouter-alts-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.25rem;
  cursor: pointer;
  user-select: none;
  font-size: 0.9rem;
  color: var(--text-muted);
  font-weight: 600;
  letter-spacing: 0.02em;
  list-style: none;
}
.scouter-alts-summary::-webkit-details-marker { display: none; }
.scouter-alts-summary::before {
  content: '▶';
  display: inline-block;
  font-size: 0.6rem;
  color: var(--text-muted);
  transition: transform 0.15s;
}
.scouter-alts[open] > .scouter-alts-summary::before {
  transform: rotate(90deg);
}
.scouter-alts-icon { font-size: 1rem; }
.scouter-alts-summary:hover { color: var(--text-primary); }

.scouter-note {
  margin-top: 0.75rem;
  margin-bottom: 0;
  font-size: 0.8rem;
  color: var(--text-muted);
  line-height: 1.4;
}

/* Picker modals (champion / item) */
.scouter-picker { padding: 0.5rem 0; }
.scouter-picker-search {
  width: 100%;
  padding: 0.5rem 0.75rem;
  margin: 0.5rem 0 0.75rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-size: 1rem;
}

/* Lane-filter chip strip — sits between the search box and the section
   list inside the champion picker. Clicking a chip narrows the visible
   lanes (the section grid lazily re-renders). */
.scouter-picker-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}
.scouter-picker-chip {
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-secondary);
  color: var(--text-muted);
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.scouter-picker-chip:hover {
  background: var(--bg-card-hover);
  color: var(--text-primary);
}
.scouter-picker-chip.active {
  background: var(--accent-glow);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

/* Lane sections inside the picker. Stacks vertically with a sticky-ish
   header so the "▼ TOP (48)" label stays anchored while the user
   skims the grid below. */
.scouter-picker-sections {
  max-height: 60vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding-right: 0.25rem;
}
.scouter-picker-section { display: flex; flex-direction: column; gap: 0.4rem; }
.scouter-picker-section-title {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.2rem;
}
.scouter-picker-section-count {
  font-family: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
  font-size: 0.75rem;
  color: var(--text-muted);
  text-transform: none;
}
.scouter-picker-empty {
  padding: 1.5rem 0.5rem;
  text-align: center;
  color: var(--text-muted);
  font-style: italic;
}

.scouter-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 0.6rem;
}
.scouter-picker-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.5rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  color: var(--text-primary);
  font-size: 0.8rem;
  text-align: center;
  transition: background 0.15s, border-color 0.15s;
}
.scouter-picker-card:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent);
}
.scouter-picker-card img {
  width: 56px;
  height: 56px;
  border-radius: 6px;
  object-fit: cover;
}
