:root {
  --bg: #111113;
  --bg-panel: #202023;
  --bg-panel-alt: #2e2e30;
  --border: #2b2b2e;
  --text: #f0f0f0;
  --text-dim: #96969a;
  --accent: hsl(353, 63%, 26%);
  /* Separate from --accent: prose links on the credits page used to just be
     var(--accent), same red as every button/nav-active-state/focus-ring in
     the app, easy to miss as clickable text. Cool icy blue reads
     unambiguously as "hyperlink" and doesn't sit near --accent or the
     orange/red tier-2x/tier-4x weakness colors. */
  --link: #6fc7ff;
  --tier-4x: #9c0113;
  --tier-2x: #e07a1f;
  --tier-1x: #4c4c50;
  --tier-half: #2f8f5b;
  --tier-quarter: #1f6b45;
  --tier-immune: #6a4bc9;
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

/* ---- accessibility baseline (Phase 5 of the 1.0 roadmap) ----
   Global, not per-page-CSS-file, since it has to apply everywhere: the skip
   link and focus ring are cross-cutting concerns, not specific to any one
   route's own visual design. */

/* Screen-reader-only text -- present in the accessibility tree and reachable
   by keyboard/AT, but takes up no visual space and never shows for a sighted
   pointer user. The clip-path + 1px-box technique (not display:none/
   visibility:hidden, which would remove it from the accessibility tree too,
   defeating the entire purpose) is the standard approach: keeps the element
   laid out (so it can still receive focus) while making it visually
   undetectable. Used for each page's own <h1> (this app's visual design
   never had on-page titles, and adding big visible ones now would be a
   whole separate design change outside this pass's scope) and for a
   handful of icon-only controls whose accessible name needs to be richer
   than their aria-label alone conveys.
   `.visually-hidden-focusable` is the same idea but REVEALS itself once
   focused -- used for the skip link, which is exactly the one case where a
   sighted keyboard user (not just a screen reader) needs to see it appear. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 0;
  left: 8px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--accent);
  color: #fff;
  border-radius: 0 0 6px 6px;
  font-weight: 600;
  /* translateY(-100%) hides it by exactly its own rendered height, whatever
     that turns out to be -- a fixed `top: -40px` (the original approach)
     silently under-hid it whenever the actual box (padding + font metrics)
     came out taller than 40px, leaving a sliver visible at the very top of
     the page even with nothing focused. Percentage transforms are relative
     to the element's own box, so this can't drift out of sync the same way. */
  transform: translateY(-100%);
  transition: transform 0.15s ease;
}
.skip-link:focus {
  transform: translateY(0);
}

/* A consistent, clearly-visible keyboard focus ring across every custom
   interactive element in the app (dex cards, evo-tree nodes, filter-
   clickable badges, sortable column heads, ...) -- most of these are
   <div>/<span> with `tabindex="0"` rather than a real <button>/<a> (see
   helpers.js's wireActivate), and while modern browsers DO apply their own
   default :focus-visible ring to any focusable element regardless of tag,
   this makes that ring consistent (same color/offset as the rest of the
   app's own accent color) rather than leaving it to whatever the browser's
   own default happens to look like. :focus-visible (not a plain :focus)
   specifically so this only shows for keyboard/AT navigation, not for a
   mouse click landing on a focusable element -- the same distinction
   browsers already draw natively. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  /* The detail page's carousel rewrites the ENTIRE #app-root subtree
     (container.innerHTML = ...) on every single Pokemon-to-Pokemon step,
     destroying every element the browser's scroll anchoring feature might
     have been tracking as "the thing currently under the viewport's top
     edge" and replacing it with all-new nodes. Chrome/Firefox's automatic
     scroll anchoring was fighting detail.js's own explicit
     window.scrollTo() restore after that replacement, quietly shifting the
     page back toward the top after our own script had already set the
     scroll position -- a well-known gotcha with any app that replaces
     large chunks of the DOM and also wants to manage scroll position
     itself. Disabling it here (rather than only on #app-root) covers the
     whole page consistently. */
  overflow-anchor: none;
}

a { color: inherit; text-decoration: none; }

.app-header {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 12px 20px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.app-title { font-weight: 600; font-size: 1.05rem; }

.app-nav { display: flex; gap: 16px; }
.app-nav a { padding: 6px 10px; border-radius: 6px; color: var(--text-dim); }
.app-nav a.active { background: var(--accent); color: #fff; }

/* The closed control is styled as its own colored badge -- same pill
   treatment as the Info link nearby -- rather than plain dim label text,
   since which mode is active changes what's banned/swapped throughout the
   whole app and deserves to stand out. The "Mode:" label next to it stays
   plain, unstyled text; only the actual mode value gets the colored
   panel/border (an earlier version colored the whole wrapper, label
   included, which read as if "Mode:" itself were part of the selected
   mode rather than just naming the control next to it). Background/border
   color reflects the selected mode (see .mode-normal/.mode-restricted/
   .mode-hardcore below), toggled in main.js whenever a row is picked.

   This used to be a native <select>. A native select's own OPEN POPUP is
   drawn by the OS/browser, not this stylesheet -- background-color can be
   nudged but which row reads as "highlighted" is largely out of CSS's
   hands, and different browsers/platforms disagreed on how legible that
   highlight was against a dark custom-styled popup. Rebuilt as the same
   button+in-page-dropdown pattern the rest of the app already uses (see
   .team-stage-dropdown/.team-stage-row and .cond-location-dropdown/
   .cond-location-row) -- every row is now normal painted DOM this
   stylesheet fully controls, so both the "hovering" and "currently
   selected" states are exactly as legible and as consistent with the rest
   of the app as everywhere else. */
.mode-select {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
}
.mode-select-label { color: var(--text-dim); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.mode-picker-wrap { position: relative; }
.mode-toggle-btn {
  font-size: 0.8rem;
  font-weight: 700;
  padding: 7px 26px 7px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg-panel-alt);
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
/* Small triangle instead of the &#9662; glyph other dropdown buttons in
   this app use in their own text content -- this button's own text is
   the mode name, with no room left over for a trailing glyph without
   widening the pill more than the mode name itself needs. */
.mode-toggle-btn::after {
  content: "";
  position: absolute; top: 50%; right: 10px; transform: translateY(-50%);
  width: 0; height: 0;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.75;
}
/* The translucent mode-tinted look on the closed pill (deliberately rgba,
   not solid, per instruction) -- white text here, since it reads clearly
   against these translucent tints once composited over the header's own
   dark background. */
.mode-select.mode-normal .mode-toggle-btn { background: color-mix(in srgb, var(--tier-half) 28%, transparent); border-color: var(--tier-half); color: #fff; }
.mode-select.mode-restricted .mode-toggle-btn { background: color-mix(in srgb, var(--tier-2x) 28%, transparent); border-color: var(--tier-2x); color: #fff; }
.mode-select.mode-hardcore .mode-toggle-btn { background: color-mix(in srgb, var(--tier-4x) 28%, transparent); border-color: var(--tier-4x); color: #fff; }
.mode-toggle-btn:hover { filter: brightness(1.15); }

/* The OPEN dropdown -- same panel construction as .team-stage-dropdown/
   .cond-location-dropdown (dark opaque panel, its own border/shadow,
   rounded rows), right-aligned under the button since this control sits
   at the right edge of the header and a left-aligned popup would overhang
   off-screen. width: max-content (not a flat min-width guess like 150px,
   which was wider than it needed to be whenever the closed button was
   showing a short name like "Normal") -- shrinks to fit whichever row's
   text is actually longest ("RESTRICTED"), same "no wider than it has to
   be" sizing .cond-location-btn's own dropdown effectively gets for free
   from its rows' natural width. */
.mode-toggle-dropdown {
  position: absolute; top: 100%; right: 0; margin-top: 4px; z-index: 20;
  width: max-content;
  background: var(--bg-panel-alt); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.4); padding: 4px;
}
.mode-toggle-row {
  padding: 8px 10px;
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text);
  border-radius: 6px;
  cursor: pointer;
}
/* Always-legible text (var(--text), same as every other dropdown row in
   the app) plus two DELIBERATELY DIFFERENT-HUED states, so "which one am I
   about to pick" and "which one is active right now" can never be mistaken
   for each other the way they could under the old native popup's single
   ambiguous hover color: hovering/keyboard-focusing a row tints it accent
   blue (stronger than .team-stage-row's own plain darker-gray hover --
   this dropdown's rows are otherwise closer in tone to each other, so a
   gray-on-gray hover read as too subtle here), while the CURRENTLY
   SELECTED mode keeps its own mode-colored tint plus a trailing checkmark,
   visible even while a different row is being hovered. */
.mode-toggle-row:hover, .mode-toggle-row:focus-visible { background: color-mix(in srgb, var(--accent) 22%, transparent); outline: none; }
.mode-toggle-row.active { font-weight: 700; position: relative; padding-right: 26px; }
.mode-toggle-row.active::after {
  content: "\2713"; position: absolute; top: 50%; right: 10px; transform: translateY(-50%);
  font-size: 0.75rem;
}
.mode-toggle-row[data-mode="normal"].active { background: color-mix(in srgb, var(--tier-half) 24%, transparent); }
.mode-toggle-row[data-mode="restricted"].active { background: color-mix(in srgb, var(--tier-2x) 24%, transparent); }
.mode-toggle-row[data-mode="hardcore"].active { background: color-mix(in srgb, var(--tier-4x) 24%, transparent); }

/* The "N Pokemon loaded" status text that used to live here has been
   removed from the header entirely, per feedback that it was just clutter
   once the Info button existed. */

/* Styled like the "+ Add filter group" button rather than plain text, so
   it reads as an action in the header instead of a stray label. No
   margin-left:auto here (an earlier version had one) -- .mode-select right
   before it already claims that auto margin to push the pair away from the
   nav links, and having BOTH elements claim their own auto margin split the
   leftover header space between the two of them, leaving a visible gap
   between Mode and Info instead of sitting flush next to each other. */
.credits-link {
  padding: 7px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg-panel-alt);
  color: var(--text);
  font-size: 0.8rem;
  cursor: pointer;
}
.credits-link:hover { filter: brightness(1.15); }
.credits-link.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Team Builder Export/Import -- same pill treatment as .credits-link (they
   sit right next to it in the header), kept as a distinct class rather than
   reusing .credits-link directly since these are <button>s toggled via the
   `hidden` attribute from main.js's route(), not nav links with an `.active`
   state. */
.header-data-btn {
  padding: 7px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg-panel-alt);
  color: var(--text);
  font-size: 0.8rem;
  font-family: inherit;
  cursor: pointer;
}
.header-data-btn:hover { filter: brightness(1.15); }

/* Fullscreen toggle -- shares .header-data-btn's pill (border/background/
   hover) but is icon-only, so it gets its own square footprint/centering
   layered on top rather than the text button's horizontal padding. */
.fullscreen-toggle-btn {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 30px; padding: 0;
}
.fullscreen-toggle-btn svg { width: 16px; height: 16px; }

