/* ============================================================
   vegerank — retro arcade design system
   Palette is derived from the vegetable sprite palette itself
   (internal/catalog Palette) so the UI chrome and the pixel art
   read as one unified system, not icons on a generic template.
   ============================================================ */

@font-face {
  font-family: "Press Start 2P";
  src: url("/static/fonts/press-start-2p.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Space Mono";
  src: url("/static/fonts/space-mono-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Space Mono";
  src: url("/static/fonts/space-mono-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light dark;

  --bg: #f2ede2;
  --surface: #fffaf0;
  --ink: #241c12;
  --muted: #6b6151;
  --border: #241c12;
  --shadow: rgba(36, 28, 18, 0.9);

  --green: #4f9a3f;
  --orange: #e8892f;
  --red: #d13a3a;
  --purple: #7d4a94;

  --accent: var(--green);
  --radius: 2px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14110d;
    --surface: #1f1911;
    --ink: #f5ecd8;
    --muted: #a89c86;
    --border: #f5ecd8;
    --shadow: rgba(0, 0, 0, 0.9);

    --green: #7dc45a;
    --orange: #f5ab55;
    --red: #e86a6a;
    --purple: #a97dc2;
  }
}

* {
  box-sizing: border-box;
}

html {
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  font-family: "Space Mono", ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 16px;
  line-height: 1.55;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Center short pages (the vote arena, home) vertically on tall or wide
     viewports, so they read as a composed screen rather than content
     stranded at the top of a large void. This only has an effect while
     the page is shorter than the viewport: flex only distributes space
     that actually exists, so a page whose content already exceeds
     100dvh — results, the gallery — sizes to its content as normal and
     scrolls from the top exactly as before. */
  justify-content: center;
  /* Top padding reserves room for the fixed .site-nav bar present on
     every page, so page content never starts underneath it. */
  padding: 5.5rem 1.25rem 3.5rem;
}

h1,
h2,
h3,
.pixel {
  font-family: "Press Start 2P", "Space Mono", monospace;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0.02em;
}

a {
  color: var(--ink);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ---------- shell ---------- */

main {
  width: 100%;
  max-width: 640px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 1.25rem;
}

main.wide {
  max-width: 820px;
}

.eyebrow {
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.site-title {
  font-size: 1.6rem;
  color: var(--ink);
}

.tagline {
  color: var(--muted);
  font-size: 0.95rem;
  max-width: 32rem;
}

/* ---------- site nav bar ----------
   A single persistent nav bar, fixed to the top of the viewport on
   every page — including the quiz, where it has to stay reachable
   independent of where the vote arena itself sits once body
   vertical-centers short pages (see `body { justify-content: center }`
   above — a plain in-flow nav would drift down the page along with
   everything else). Body's top padding reserves room for it site-wide. */
.site-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  /* flex-end (not space-between) so the toggle/links cluster stays
     pinned right regardless of whether the logo is present — the home
     page omits it (see nav-no-logo in nav.html), and space-between
     with a single remaining flex item would otherwise collapse to the
     left edge instead of staying right-aligned like every other page. */
  justify-content: flex-end;
  gap: 1rem;
  padding: 0.9rem 1.25rem;
  background: var(--bg);
  border-bottom: 3px solid var(--border);
  font-size: 0.9rem;
}
.site-nav-logo {
  font-family: "Press Start 2P", monospace;
  font-size: 0.85rem;
  color: var(--ink);
  text-decoration: none;
  flex-shrink: 0;
  margin-right: auto;
}

/* ---------- nav links: collapsible drawer below 40rem ----------
   Below tablet width, the link row doesn't get shrunk to fit anymore
   (that read as "everything is tiny", not "tidy") — it collapses into
   a full-width drawer under the bar instead, toggled by a pixel-styled
   MENU button (nav.js), so the logo and the links it does show can both
   stay a legible size. .site-nav-links sits absolutely positioned off
   .site-nav's own fixed box (top: 100%), so it tracks the bar's real
   height automatically rather than a hardcoded offset. */
.site-nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: "Press Start 2P", monospace;
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 0.55rem 0.75rem;
  cursor: pointer;
}
.site-nav-toggle:hover,
.site-nav-toggle:focus-visible {
  border-color: var(--accent);
}

.site-nav-links {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border-bottom: 3px solid var(--border);
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.15s ease;
}
.site-nav-links.is-open {
  max-height: 16rem;
}
.site-nav-links a {
  padding: 0.9rem 1.25rem;
  font-size: 1rem;
  color: var(--muted);
  text-decoration: none;
  border-top: 1px solid var(--border);
}
.site-nav-links a:hover,
.site-nav-links a:focus-visible {
  color: var(--accent);
}

@media (min-width: 40rem) {
  .site-nav-toggle {
    display: none;
  }
  .site-nav-links {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-end;
    column-gap: 1.25rem;
    row-gap: 0.3rem;
    max-height: none;
    overflow: visible;
    background: transparent;
    border-bottom: none;
  }
  .site-nav-links a {
    padding: 0;
    font-size: 0.9rem;
    border-top: none;
  }
}

@media (min-width: 60rem) {
  .site-nav {
    padding: 1.15rem 2rem;
  }
  .site-nav-logo {
    font-size: 1rem;
  }
  .site-nav-links {
    column-gap: 1.75rem;
  }
  .site-nav-links a {
    font-size: 1rem;
  }
}

/* Both the quiz and results states render inside this same wrapper div
   (matchup.html / results.html both use id="matchup"). It has no
   explicit width, so as a flex item of `main { align-items: center }`
   it shrink-wraps to its widest child's own natural content size
   instead of filling main — on the results state that widest child is
   `.subtitle` (capped at 30rem), so the ranking list and chart were
   silently stuck around 480px no matter how wide the viewport was.
   `width: 100%` makes it resolve against main's real (definite) width
   like every other page's content instead. */
#matchup {
  width: 100%;
}

/* The results state — recognizable by its chart — reads as a report
   (your ranking), not a game screen, so it anchors top-down like the
   leaderboard rather than vertically centering like the quiz. Without
   this, a short "common"-list ranking on a tall viewport would center
   with dead space above and below, reading as if the page had stopped
   partway rather than simply being a short report. */
body:has(.chart-panel) {
  justify-content: flex-start;
}

/* ---------- pixel panel / button primitives ---------- */

.panel {
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 5px 5px 0 var(--shadow);
  padding: 1.5rem;
}

.button {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-family: "Space Mono", monospace;
  font-weight: 700;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  text-decoration: none;
  color: var(--ink);
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1.4rem;
  cursor: pointer;
  box-shadow: 4px 4px 0 var(--shadow);
  transition: transform 0.08s ease, box-shadow 0.08s ease;
}
.button:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--shadow);
}
.button:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--shadow);
}
.button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  box-shadow: 4px 4px 0 var(--shadow);
}
.button.accent {
  background: var(--accent);
  color: var(--bg);
}
.button small {
  font-family: "Space Mono", monospace;
  font-weight: 400;
  text-transform: none;
  color: var(--muted);
  letter-spacing: 0;
  font-size: 0.72rem;
}
.button.accent small {
  color: var(--bg);
  opacity: 0.85;
}

/* ---------- home ---------- */

.list-choice {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  width: 100%;
}
.list-choice .button {
  height: 100%;
  padding: 1.75rem 1.25rem;
}
@media (max-width: 32rem) {
  .list-choice {
    grid-template-columns: 1fr;
  }
}

.leaderboard-link {
  font-size: 0.8rem;
  color: var(--muted);
  text-decoration-style: dotted;
}

/* ---------- vote arena ---------- */

.progress-pill {
  font-family: "Press Start 2P", monospace;
  font-size: 0.65rem;
  color: var(--bg);
  background: var(--ink);
  border: 3px solid var(--border);
  border-radius: 999px;
  padding: 0.5rem 1rem;
  letter-spacing: 0.05em;
}

.arena {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  width: 100%;
  align-items: stretch;
}
@media (max-width: 34rem) {
  .arena {
    grid-template-columns: 1fr;
  }
}

.fighter {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 5px 5px 0 var(--shadow);
  padding: 1.75rem 1rem;
  cursor: pointer;
  font-family: "Space Mono", monospace;
  color: var(--ink);
  transition: transform 0.08s ease, box-shadow 0.08s ease;
}
.fighter svg {
  image-rendering: pixelated;
  width: 96px;
  height: 96px;
}
.fighter span {
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.85rem;
  letter-spacing: 0.03em;
}
.fighter:hover:not(:disabled) {
  transform: translate(-3px, -3px);
  box-shadow: 8px 8px 0 var(--shadow);
  border-color: var(--accent);
}
.fighter:active:not(:disabled) {
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--shadow);
}
.fighter:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.vs-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3.2rem;
  height: 3.2rem;
  background: var(--orange);
  color: var(--bg);
  border: 3px solid var(--border);
  border-radius: 50%;
  font-family: "Press Start 2P", monospace;
  font-size: 0.65rem;
  box-shadow: 3px 3px 0 var(--shadow);
  animation: pulse 1.6s ease-in-out infinite;
}
@media (max-width: 34rem) {
  .vs-badge {
    position: static;
    transform: none;
    margin: -0.4rem auto;
  }
}
@keyframes pulse {
  0%,
  100% {
    transform: translate(-50%, -50%) scale(1);
  }
  50% {
    transform: translate(-50%, -50%) scale(1.12);
  }
}
@media (max-width: 34rem) {
  @keyframes pulse {
    0%,
    100% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.12);
    }
  }
}

.error {
  font-size: 0.85rem;
  color: var(--red);
  border: 2px dashed var(--red);
  border-radius: var(--radius);
  padding: 0.6rem 1rem;
}

/* ---------- results / scoreboard ---------- */

.page-title {
  font-size: 1.15rem;
}

.subtitle {
  color: var(--muted);
  font-size: 0.85rem;
  max-width: 30rem;
}

.scoreboard {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.scoreboard li {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 0.5rem 0.9rem;
  text-align: left;
}
.scoreboard li svg {
  image-rendering: pixelated;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
}
.scoreboard li span {
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.85rem;
}
.scoreboard li::before {
  content: counter(rank);
  counter-increment: rank;
  font-family: "Press Start 2P", monospace;
  font-size: 0.75rem;
  color: var(--muted);
  width: 1.6em;
  flex-shrink: 0;
}
.scoreboard {
  counter-reset: rank;
}
.scoreboard li:nth-child(1) {
  border-color: var(--accent);
  box-shadow: 4px 4px 0 var(--accent);
}
.scoreboard li:nth-child(1)::before {
  color: var(--accent);
}

.chart-panel {
  position: relative;
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  width: 100%;
  max-width: 280px;
  margin-inline: auto;
}
.chart-panel svg {
  width: 100%;
  height: auto;
  display: block;
}
.chart-axis {
  color: var(--muted);
}
.chart-data {
  color: var(--accent);
}

.chart-spoke {
  color: var(--muted);
}
/* Axis names are positioned on the chart itself (see radar.Labels), so
   they read against their own axis rather than as a detached list. */
.chart-label {
  fill: var(--muted);
  font-family: "Space Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.02em;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.9rem;
}
/* On the results page, .chart-panel and .actions are both plain divs
   sitting inside #matchup's normal block flow (not a flex/gap
   container), so with no margin of their own they end up touching —
   scoped to this exact adjacency so the shared .actions class on the
   About/Gallery pages, which already gets its spacing from main's own
   gap, isn't affected. */
.chart-panel + .actions {
  margin-top: 2rem;
}
/* Same reasoning as above, the other side of the chart: .scoreboard has
   margin: 0 (its own <li> items are gapped instead), so the "your taste
   profile" eyebrow right after it had only a <p>'s small default margin
   to work with — visually tight next to the panel's own 2rem below it.
   Scoped the same way: .scoreboard is always the last element on the
   leaderboard/share pages, so this only ever matches on results. */
.scoreboard + .eyebrow {
  margin-top: 2rem;
}

/* ---------- leaderboard ---------- */

.last-updated {
  font-size: 0.72rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* A fused two-way selector, not two floating buttons — same HUD
   language as .progress-pill (Press Start 2P, small caps) and the same
   accent-fill used for the "common" card in .list-choice on the home
   page, so picking a list reads as the same action in both places. */
.list-toggle {
  display: inline-flex;
  border: 3px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 4px 4px 0 var(--shadow);
  overflow: hidden;
}
.list-toggle-option {
  font-family: "Press Start 2P", monospace;
  font-size: 0.58rem;
  letter-spacing: 0.03em;
  text-decoration: none;
  color: var(--muted);
  padding: 0.75rem 1.1rem;
  transition: color 0.08s ease, background 0.08s ease;
}
.list-toggle-option + .list-toggle-option {
  border-left: 3px solid var(--border);
}
.list-toggle-option:hover {
  color: var(--ink);
}
.list-toggle-option.active {
  color: var(--bg);
  background: var(--accent);
}
.list-toggle-option.active:hover {
  color: var(--bg);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
}
.empty-state-title {
  font-family: "Press Start 2P", monospace;
  font-size: 0.85rem;
  color: var(--ink);
}
.empty-state .subtitle {
  max-width: 26rem;
}

.leaderboard-delta {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.leaderboard-delta li {
  background: var(--surface);
  border: 2px dashed var(--accent);
  border-radius: var(--radius);
  padding: 0.5rem 0.8rem;
  font-size: 0.78rem;
}

/* ---------- share page ---------- */

.share-image {
  width: 100%;
  max-width: 320px;
  border: 3px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 5px 5px 0 var(--shadow);
  image-rendering: pixelated;
}

/* ---------- about ---------- */

.about-body {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  width: 100%;
  text-align: left;
}
.about-section {
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
}
.about-section .section-title {
  font-size: 0.75rem;
  color: var(--accent);
  margin-bottom: 0.55rem;
}
.about-section p {
  font-size: 0.85rem;
  line-height: 1.65;
  color: var(--muted);
  margin: 0;
}

/* ---------- category intro (home) + vegetable gallery ---------- */

.section-title {
  font-family: "Press Start 2P", monospace;
  font-size: 0.95rem;
  color: var(--ink);
}

.categories-intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  width: 100%;
  margin-top: 1.5rem;
  padding-top: 1.75rem;
  border-top: 3px solid var(--border);
}

.category-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0.75rem;
  width: 100%;
  text-align: left;
}
.category-cards li {
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 0.8rem 0.9rem;
}
.category-cards h3 {
  font-family: "Press Start 2P", monospace;
  font-size: 0.62rem;
  line-height: 1.6;
  margin-bottom: 0.45rem;
  color: var(--accent);
}
.category-cards p {
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--muted);
}

.category-jump {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem 0.6rem;
  font-size: 0.72rem;
}
.category-jump a {
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 0.25rem 0.5rem;
  text-decoration: none;
  color: var(--muted);
}
.category-jump a:hover,
.category-jump a:focus-visible {
  color: var(--ink);
  border-color: var(--accent);
}

.category {
  width: 100%;
  text-align: left;
  /* Anchor jumps land below the heading without it hugging the top edge. */
  scroll-margin-top: 1rem;
}
.category-name {
  font-family: "Press Start 2P", monospace;
  font-size: 0.8rem;
  color: var(--accent);
  margin-bottom: 0.5rem;
}
.category-detail {
  font-size: 0.85rem;
  line-height: 1.65;
  color: var(--muted);
  margin-bottom: 0.9rem;
}

.veg-grid {
  list-style: none;
  margin: 0 0 0.5rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 0.6rem;
}
.veg-grid li {
  position: relative;
  background: var(--surface);
  border: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 0.6rem 0.4rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  text-align: center;
}
.veg-grid svg {
  width: 48px;
  height: 48px;
  image-rendering: pixelated;
}
.veg-name {
  font-size: 0.68rem;
  line-height: 1.4;
  color: var(--ink);
}
/* A dot marks membership of the shorter common list, so the two rounds
   on the home page are legible without a second listing. */
.veg-grid li[data-common="true"]::after,
.common-dot {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  background: var(--accent);
  border-radius: 50%;
}
.veg-grid li[data-common="true"]::after {
  position: absolute;
  top: 6px;
  right: 6px;
}
.common-dot {
  vertical-align: 0.05em;
  margin-inline: 0.15em;
}

/* ---------- fluid scale-up for laptop/desktop viewports ----------
   Everything above this point was tuned mobile-first against a ~640px
   content column. Below 60rem that column already sits comfortably
   inside the viewport; above it, without change, the column stays
   pinned at its mobile size and the extra width just becomes margin —
   readable, but it stops looking like a page that was actually designed
   for the space. This tier widens the column a little and grows the
   pieces a visitor actually looks at (the wordmark, the vote cards,
   the sprites) so a laptop or desktop viewport feels intentional
   rather than a phone layout adrift on a big background. Sizes use
   clamp() where the growth should read as continuous rather than a
   single jump at the breakpoint. */
@media (min-width: 60rem) {
  main {
    max-width: 46rem;
  }
  main.wide {
    max-width: 64rem;
  }

  .site-title {
    font-size: clamp(1.6rem, 1.1rem + 1.6vw, 2.4rem);
  }
  .page-title {
    font-size: clamp(1.15rem, 0.9rem + 0.8vw, 1.5rem);
  }
  .section-title {
    font-size: clamp(0.95rem, 0.8rem + 0.5vw, 1.2rem);
  }
  .tagline {
    font-size: 1.05rem;
    max-width: 36rem;
  }

  /* The vote arena is the page a visitor spends the most time on, so
     it gets the most headroom: bigger cards, bigger sprites, a bigger
     click target — not just more empty space around a small one. */
  .arena {
    gap: 2rem;
  }
  .fighter {
    padding: 2.5rem 1.5rem;
  }
  .fighter svg {
    width: 128px;
    height: 128px;
  }
  .fighter span {
    font-size: 1rem;
  }
  .vs-badge {
    width: 3.8rem;
    height: 3.8rem;
    font-size: 0.75rem;
  }

  .chart-panel {
    max-width: 360px;
  }

  .scoreboard li {
    padding: 0.65rem 1.1rem;
  }
  .scoreboard li svg {
    width: 48px;
    height: 48px;
  }
  .scoreboard li span {
    font-size: 0.95rem;
  }

  .veg-grid {
    grid-template-columns: repeat(auto-fill, minmax(136px, 1fr));
    gap: 0.85rem;
  }
  .veg-grid svg {
    width: 60px;
    height: 60px;
  }
}
