/* Pico CSS (loaded from the CDN in each template) styles buttons, inputs,
   headings, links and the dark theme. This file only adds what Pico can't
   know about: the Pokémon box layout. */

/* --- The box ------------------------------------------------------------ */
/* Boxes flow in a grid: auto-fill makes as many columns of at least 340px as fit,
   so a phone gets 1 column and a wide screen gets 2-3 - no media queries needed. */
.box-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 1rem;
  align-items: start;
}
.box-list .load-more { grid-column: 1 / -1; }    /* the sentinel spans the whole row */

/* Same trick for the cards on the home page. */
.dex-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1rem;
  align-items: start;   /* don't stretch cards to the row's tallest: opening one card's Edit
                           grows only that card. Collapsed cards are all the same height anyway
                           (see .card-top below), so their Edit rows still line up. */
}
/* The card has no padding of its own: the clickable top part and the Edit section
   each add theirs, so the link reaches the card's edges. */
.dex-card { margin: 0; padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.card-top {
  flex: 1;                     /* grow to fill spare height, pushing Edit to the card's bottom */
  display: block;
  padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal);
  text-align: center;
  color: inherit;
  text-decoration: none;
}
.card-top:hover { background: var(--pico-form-element-background-color); }
.card-title { font-size: 1.15rem; font-weight: bold; color: var(--pico-primary); }
.card-top .hint { margin: 0.25rem 0 0; }
.card-top .hint:nth-of-type(2) { margin-bottom: 0.75rem; }
/* One line each; anything longer is cut with an ellipsis, so every card has the same height. */
.card-top .card-title, .card-top .line {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-top progress { margin-bottom: 0.5rem; }
.counts { line-height: 1.5; min-height: 3em; }   /* room for two lines, so regular-only and shiny-only cards match the "both" card */
.card-actions { display: flex; gap: 0.5rem; }              /* Rename | Delete on one row, sharing the width */
.card-actions button { flex: 1; margin: 0; white-space: nowrap; }
.dex-card details form { margin: 0.5rem 0 0; }
/* Desktop only (768px and up): a mouse is precise, so the Edit controls can be smaller.
   On phones they stay at full size for fingers. A media query switches rules on by screen width. */
@media (min-width: 768px) {
  .dex-card details input[name="name"],
  .dex-card .card-actions button {
    font-size: 0.8rem;
    padding: 0.3rem 0.6rem;
  }
  /* Pico gives inputs an explicit height, so padding alone wouldn't shrink the box. */
  .dex-card details input[name="name"] { height: auto; margin-bottom: 0.5rem; }
}
.dex-card details {
  margin: 0;
  padding: 0.5rem var(--pico-block-spacing-horizontal);
  border-top: 1px solid var(--pico-muted-border-color);
}

.box {
  padding: 0.75rem;
  border-radius: var(--pico-border-radius);
  background: var(--pico-card-background-color);
  box-shadow: var(--pico-card-box-shadow);
}

/* Three columns (empty | title | button) so the title stays centred while Mark all sits on the right. */
.box-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  margin-bottom: 0.5rem;
  text-align: center;
  font-weight: bold;
}
.box-title { grid-column: 2; }
.box-bulk {
  grid-column: 3; justify-self: end;
  width: auto; margin: 0; padding: 0.15rem 0.55rem;
  font-size: 0.7rem; font-weight: normal; white-space: nowrap;
}

/* Pinned under the title while scrolling. sticky = behaves normally until it would
   scroll off the top, then sticks at top: 0. It needs an opaque background (or the
   boxes show through) and a z-index so it paints above them. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: grid;
  /* back arrow | counters | tools (Hide caught, Mark all), then the search box on a row of its
     own. The outer columns are equal (1fr), so the counters stay centred. On a phone there is no
     room for three things in a row: the tools drop to a second line under the counters. */
  grid-template-columns: 2.25rem 1fr;
  grid-template-areas: "back progress" "tools tools" "search search";
  align-items: center;
  row-gap: 0.25rem;
  padding: 0.2rem 0 0.35rem;
  margin-bottom: 0.5rem;
  background: var(--pico-background-color);
  border-bottom: 1px solid var(--pico-muted-border-color);
}
@media (min-width: 768px) {
  .topbar { grid-template-columns: 1fr auto 1fr; grid-template-areas: "back progress tools" "search search search"; }
}
.topbar .back { grid-area: back; justify-self: start; }
.topbar .progress { grid-area: progress; }

/* The bar's tools: small buttons side by side. */
.bar-tools { grid-area: tools; display: flex; flex-wrap: wrap; gap: 0.4rem; justify-content: center; align-items: center; }
@media (min-width: 768px) { .bar-tools { justify-content: flex-end; } }
.hide-filters { margin: 0; }
.bar-button, .topbar button.bar-button {
  display: inline-flex; align-items: center; gap: 0.35rem;
  width: auto; margin: 0; padding: 0.2rem 0.6rem;
  font-size: 0.75rem; font-weight: normal; line-height: 1.4; white-space: nowrap;
  border: 1px solid var(--pico-secondary-border); border-radius: 6px;
  background: transparent; color: var(--pico-secondary); cursor: pointer;
}
/* "Hide caught": a label drawn as a button, with its checkbox inside. Pico draws checkboxes big;
   shrink it to the text. The button looks pressed while the box is ticked. */
.check-button input[type="checkbox"] { width: 1em; height: 1em; margin: 0; }
.check-button:has(input:checked) { border-color: var(--pico-primary); color: var(--pico-color); background: var(--pico-form-element-background-color); }
.topbar button.bar-button:disabled { opacity: 0.4; cursor: not-allowed; }

/* The search box: short, on its own row, centred. */
.topbar input.dex-search {
  grid-area: search; justify-self: center;
  width: min(100%, 22rem); height: auto; margin: 0; padding: 0.3rem 0.75rem 0.3rem 2.2rem;
  font-size: 0.85rem;
}
.no-results { grid-column: 1 / -1; margin: 2rem 0; text-align: center; color: var(--pico-muted-color); }
/* During a search a slot that does not match keeps its place (so the box keeps its layout) but
   is not shown and cannot be tapped. */
.slot.no-match { visibility: hidden; }

/* Hiding caught Pokémon: no JavaScript. `body:has(#hide-caught:checked)` means "the page contains
   a ticked #hide-caught", so ticking it instantly hides every caught slot, shiny or not (also
   ones loaded later by scrolling or swapped in after a tap). visibility:hidden keeps the slot's
   place in the grid, so the boxes keep their in-game layout and nothing shifts under your cursor
   as you mark things. */
body:has(#hide-caught:checked) .slot.caught,
body:has(#hide-caught:checked) .slot.shiny { visibility: hidden; }

/* A box whose slots are ALL hidden disappears completely (display: none, so the other boxes
   close up). :not(:has(visible slot)) reads "contains no slot that is still shown"; a slot is
   shown unless it is caught or shiny (hidden above) or does not match the search. */
body:has(#hide-caught:checked) .box:not(:has(.slot:not(.caught):not(.shiny):not(.no-match))) {
  display: none;
}

.back {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
}
.back:hover { background: var(--pico-form-element-background-color); }

.progress {
  display: flex;
  justify-content: center;
  gap: 1.5rem;
  font-size: 0.85rem;
}
.shiny-count { color: #f5b301; }

.hint, .load-more {
  text-align: center;
  font-size: 0.8rem;
  color: var(--pico-muted-color);
}
.load-more { padding: 2rem 0; }

/* --- The grid ----------------------------------------------------------- */
/* 6 equal columns. Each slot is forced square with aspect-ratio, and the
   sprite is told to fit inside the slot (width: 100%), so the grid shrinks
   to fit any screen width instead of the sprites' natural size deciding it.
   minmax(0, 1fr) matters: plain 1fr lets a big image stretch its column. */
.box-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 4px;
}

.slot {
  position: relative;
  aspect-ratio: 1;
  border-radius: 8px;
  background: var(--pico-form-element-background-color);
  border: 1px solid var(--pico-muted-border-color);
  cursor: pointer;
  user-select: none;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
}

/* An empty cell that keeps a short box as tall as a full one (see _box.html). */
.slot-spacer { aspect-ratio: 1; }
/* A blank the dex file asked for: an empty tile that keeps its place in the box. Dashed, so it
   does not look like a Pokémon that failed to load. */
.slot-blank { aspect-ratio: 1; border-radius: 8px; border: 1px dashed var(--pico-muted-border-color); opacity: 0.6; }

.slot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Stand-in tile for an entry with no sprite: a "?" and the (clipped) name. Dim while empty,
   brighter once caught/shiny (the border colour also changes) so progress is still visible. */
.no-sprite {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 2px 2px 12px; gap: 0.1rem; text-align: center; line-height: 1.05;
  color: var(--pico-muted-color);
}
.no-sprite b { font-size: 1.4rem; opacity: 0.55; }
.no-sprite small {
  max-width: 100%; font-size: 0.55rem; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;   /* at most two lines */
}
.slot.caught .no-sprite, .slot.shiny .no-sprite { color: var(--pico-color); }

/* empty = not caught yet: show a dim silhouette */
/* brightness(0) turns every pixel black, invert(1) flips that to white,
   opacity then dims it to a soft grey shape on the dark slot. */
.slot.empty img { filter: brightness(0) invert(1) opacity(0.2); }

.slot.caught { border-color: #4caf50; }
.slot.shiny  { border-color: #f5b301; box-shadow: inset 0 0 6px #f5b30199; }

/* Shiny-locked entries (a Pikachu in a cap can never be shiny). They carry a padlock:
   - in a mixed dex they can still be caught, so only a small badge in the corner;
   - in a shiny-only dex nothing can be marked, so the slot is greyed out with a big padlock on top
     (the .disabled slot also has no click layers for marking, see _entry.html). */
.slot .lock { position: absolute; display: block; pointer-events: none; color: var(--pico-muted-color); }
.slot .lock svg { display: block; width: 100%; height: 100%; fill: currentColor; }
.slot.shiny-blocked .lock { right: 3px; top: 3px; width: 13px; height: 13px; }
.slot.disabled { cursor: not-allowed; border-style: dashed; }
.slot.disabled img { filter: grayscale(1) brightness(0.75) opacity(0.4); }
.slot.disabled .no-sprite { opacity: 0.4; }
.slot.disabled .lock {
  inset: 0; margin: auto; width: 38%; height: 38%;
  color: rgba(255, 255, 255, 0.9); filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7));
}
.panel-lock { display: flex; align-items: center; gap: 0.35rem; margin: 0.25rem 0 0; }
.panel-lock svg { width: 1em; height: 1em; fill: currentColor; flex: none; }

.slot .num {
  position: absolute;
  left: 3px;
  bottom: 1px;
  font-size: 0.6rem;
  color: var(--pico-muted-color);
}
.slot .star {
  position: absolute;
  right: 3px;
  top: 1px;
  font-size: 0.8rem;
  color: #f5b301;
}

/* --- Small bits --------------------------------------------------------- */
.page-heading {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  column-gap: 0.5rem;
  align-items: center;
  margin: 1rem 0;
}
.page-heading h1 { grid-column: 2; margin: 0; text-align: center; font-size: 1.4rem; }
.page-heading .menu { grid-column: 1; justify-self: start; }       /* menu: left cell */
/* The dex pages' heading row: the same grid, just less tall. */
.page-heading.compact { margin: 0.25rem 0 0.1rem; }
.page-heading.compact h1 { font-size: 1.25rem; }
/* The one-line "HOME reward" note under a dex's title */
.home-reward { margin: 0 0 0.35rem; text-align: center; font-size: 0.8rem; color: var(--pico-muted-color); }
.home-reward strong { color: #f5b301; font-weight: 600; }
.home-reward .needs { display: block; }                               /* what it takes: on its own line */

/* The golden present that marks a HOME reward (_gift.html). Sized by the text around it. */
.gift-icon { display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -0.2em; flex: none; }
.gift-icon .box { fill: #e0a51f; }
.gift-icon .lid { fill: #f5c542; }
.gift-icon .ribbon, .gift-icon .bow { fill: #b3261e; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* in the "add a dex" picker: pushed to the right end of the row */
.preset-list .choice .gift { margin-left: auto; padding-left: 0.5rem; flex: none; line-height: 1; }
/* on a home-page card: a small gold line under the counters. The height is fixed, and a card
   without a reward has the same line empty, so all cards are the same height. */
.card-reward { display: flex; align-items: center; justify-content: center; gap: 0.3rem; margin-top: 0.4rem; height: 1.5em; line-height: 1.5; font-size: 0.75rem; color: #f5b301; }
.card-reward span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.page-heading.compact .menu summary.menu-button { width: 2rem; height: 2rem; }
.page-heading [role="button"] {
  grid-column: 3; justify-self: end;                                 /* New Dex: right cell */
  margin: 0; width: auto;
  white-space: nowrap;                 /* never wrap the label onto several lines */
  padding: 0.4rem 0.7rem; font-size: 0.85rem;
}

/* The inline "add a dex" panel on the home page. */
.add-panel { margin: 0 0 1rem; }
/* Two columns when there's room (each at least 270px wide), one column on a phone. */
.add-layout {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: 0 1.5rem;
  align-items: start;
}

/* The dex picker: a fixed-height box that scrolls, one full-width button per preset.
   No padding or gaps inside the box, so every pixel of it is a button (no dead space)
   and overflow + border-radius clips the rows to the rounded corners. A one-column
   grid with width: 100% makes every row the same width regardless of its text. */
.preset-list {
  display: grid;
  grid-template-columns: 1fr;
  align-content: start;
  max-height: 16rem;
  overflow-y: auto;
  margin-bottom: 1rem;
  padding: 0;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
}
/* The legend is kept for screen readers but not drawn, so it isn't a dead strip in the list. */
.preset-list legend {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}
.preset-list .choice { width: 100%; font-size: 0.8rem; line-height: 1.25; }
.preset-list .choice span {
  border-width: 0 0 1px;                 /* just a divider line under each row */
  border-radius: 0;
}
.preset-list .choice:last-of-type > span { border-bottom-width: 0; }
/* A row is "<game> · <dex name>". The game sits in a fixed-width column (one width for regional
   dexes, another for the living dexes: the fieldset's --game-* values) so the dex names line up
   in a straight left edge. The inner pieces must not pick up the row's own border or padding. */
.preset-list .choice > span { display: flex; align-items: baseline; text-align: left; }
.preset-list .choice > span > * { border: 0; padding: 0; background: none; font-style: normal; }
.preset-list .choice .game { flex: none; font-weight: 600; }
.preset-list .choice.kind-regional .game { min-width: calc(var(--game-regional) + 1ch); }   /* +1ch: bold capitals run wider than digits */
.preset-list .choice.kind-living .game { min-width: calc(var(--game-living) + 1ch); }
.preset-list .choice .sep { flex: none; margin: 0 0.5em; color: var(--pico-muted-color); }
.preset-list .choice .dex { min-width: 0; }
.preset-list .choice.soon { cursor: not-allowed; }
.preset-list .choice.soon span { opacity: 0.45; font-style: italic; }
.preset-list .choice.soon:hover input + span { background: var(--pico-form-element-background-color); }   /* no hover lift: it's not clickable */
.preset-list .choice:hover input:not(:checked) + span { background: var(--pico-muted-border-color); }

/* Radio buttons drawn as buttons: the real <input> stays in the page (so keyboard
   and form submission work) but is invisible; the <span> next to it is what you see,
   and `input:checked + span` styles the selected one. */
.choice { position: relative; display: block; margin: 0; cursor: pointer; }
.choice input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
}
.choice span {
  display: block;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  background: var(--pico-form-element-background-color);
}
.choice:hover span { border-color: var(--pico-primary); }
.choice input:checked + span {
  background: var(--pico-primary-background);
  border-color: var(--pico-primary-background);
  color: var(--pico-primary-inverse);
}
.choice input:focus-visible + span { outline: 2px solid var(--pico-primary); outline-offset: 2px; }
/* Bottom row of the options column: mode choices on the left, buttons on the right.
   flex-end lines the two stacks up along their bottom edge. */
.add-bottom { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; }
.add-modes { display: grid; grid-template-columns: 1fr; gap: 0.5rem; border: 0; padding: 0; margin: 0; }   /* one shared column = equal-width buttons */
.add-modes .choice { font-size: 0.85rem; width: 100%; }
.add-modes .choice span { text-align: center; white-space: nowrap; }
.add-actions { display: flex; flex-direction: column; gap: 0.5rem; }
.add-actions button { margin: 0; width: auto; min-width: 6.5rem; white-space: nowrap; }

/* --- Hamburger menu (home page, top right) ---------------------------------------------------
   Pico dresses <details>/<summary> as an accordion (border, chevron), so this resets that and
   draws a plain round icon button with a small panel that drops down from it. */
.menu { position: relative; margin: 0; padding: 0; border: 0; }
.menu summary.menu-button {
  display: flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; margin: 0; padding: 0;
  list-style: none; border-radius: 50%; cursor: pointer;
}
.menu summary.menu-button::after,
.menu summary.menu-button::marker { content: none; display: none; }      /* no accordion chevron / default triangle */
.menu summary.menu-button::-webkit-details-marker { display: none; }
.menu summary.menu-button:hover, .menu[open] summary.menu-button { background: var(--pico-form-element-background-color); }

.menu-panel {
  position: absolute; top: calc(100% + 0.25rem); left: 0; z-index: 30;   /* drops down from the icon, aligned to its left edge */
  min-width: 11rem; padding: 0.65rem 0.75rem;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
}
.menu-user { display: block; margin-bottom: 0.6rem; font-size: 0.85rem; color: var(--pico-muted-color); }
.menu-user strong { color: var(--pico-color); }
.menu-panel form { margin: 0; }
.menu-panel button { width: auto; margin: 0; padding: 0.25rem 0.85rem; font-size: 0.8rem; }   /* compact, not full width */

/* --- Tapping a slot, and the details panel ------------------------------------------------- */
/* Every slot has one invisible click layer, the same on phones and desktops: a click or tap opens
   the Pokemon in the details panel, a double-click or double-tap marks it (see _entry.html).
   touch-action: manipulation switches off the browser's double-tap-to-zoom on the slots, which is
   what lets a phone report a double-tap as a double-click (it also removes the tap delay). */
.hit { position: absolute; inset: 0; cursor: pointer; }
.slot { touch-action: manipulation; }
.panel { display: none; }
@media (min-width: 768px) {
  .dex-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;      /* boxes take the rest, the panel is 340px */
    gap: 1.5rem;
    align-items: start;
  }
  .panel {
    display: block;
    position: sticky;                                  /* follows you as the boxes scroll */
    top: 6.6rem;                                       /* just below the pinned bar (counters + search) */
    max-height: calc(100vh - 7.4rem);
    overflow-y: auto;
  }
}

.panel-empty { margin-top: 3rem; }
.panel-card {
  position: relative;
  padding: 0.75rem 1rem 1rem;
  border-radius: var(--pico-border-radius);
  background: var(--pico-card-background-color);
  box-shadow: var(--pico-card-box-shadow);
  text-align: center;
}
.panel-close {
  position: absolute; top: 0.4rem; right: 0.4rem;
  width: 2rem; height: 2rem; margin: 0; padding: 0;
  border-radius: 50%; line-height: 1;
  background: transparent; border: 0; color: var(--pico-muted-color);
}
.panel-close:hover { background: var(--pico-form-element-background-color); color: inherit; }
/* Sprite height follows the window height (min() takes the smaller), so on a short window the
   buttons below it stay on screen instead of being pushed out of view. */
.panel-sprite { display: block; width: 100%; height: min(240px, 26vh); margin: 0 auto; object-fit: contain; }
.panel-sprite.no-sprite {                       /* the "?" version of the big panel sprite */
  position: static; border-radius: var(--pico-border-radius);
  background: var(--pico-form-element-background-color); font-size: 3rem;
}
.panel-sprite.no-sprite b { font-size: inherit; }
.panel-id { min-width: 0; }
.genus { display: block; }
.more-toggle { position: absolute; opacity: 0; width: 1px; height: 1px; }   /* hidden; the label toggles it */
/* Only used in the docked bar. The selector is deliberately specific ("checkbox + label"):
   Pico styles any label that follows a checkbox, and a plain .more-label would lose to it. */
.more-toggle + .more-label { display: none; }
.panel-name { margin: 0.25rem 0 0; font-size: 1.4rem; }
.panel-numbers { margin: 0 0 0.5rem; line-height: 1.4; }

.type-row { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 0.75rem; }
.type { padding: 0.1rem 0.7rem; border-radius: 999px; font-size: 0.75rem; font-weight: bold; color: #fff; }
.type-normal { background: #a8a77a; }  .type-fire { background: #ee8130; }   .type-water { background: #6390f0; }
.type-electric { background: #d9a800; } .type-grass { background: #5aa83c; } .type-ice { background: #4fb8b4; }
.type-fighting { background: #c22e28; } .type-poison { background: #a33ea1; } .type-ground { background: #b58f3a; }
.type-flying { background: #8e75e0; }  .type-psychic { background: #f95587; } .type-bug { background: #8a9d12; }
.type-rock { background: #a38c21; }    .type-ghost { background: #735797; }  .type-dragon { background: #6f35fc; }
.type-dark { background: #705746; }    .type-steel { background: #8a8ab0; }  .type-fairy { background: #d685ad; }

/* Caught / Shiny / Clear: the current state is filled, the others outlined */
.panel-actions { display: flex; gap: 0.4rem; margin-bottom: 0.75rem; }
.panel-actions button { flex: 1; margin: 0; padding: 0.35rem 0.4rem; font-size: 0.8rem; white-space: nowrap; }

/* Markings: six shapes in a row. Grey = off; blue and pink are the two HOME marking colours. */
.panel-marks { display: flex; align-items: center; justify-content: center; gap: 0.1rem; margin-bottom: 0.75rem; }
.marks-label { margin-right: 0.5rem; font-size: 0.7rem; color: var(--pico-muted-color); text-transform: uppercase; letter-spacing: 0.03em; }
.panel-marks button.mark {
  display: flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; margin: 0; padding: 0; border: 0; border-radius: 6px;
  background: transparent;
}
.panel-marks button.mark svg { width: 1.3rem; height: 1.3rem; fill: currentColor; }   /* every shape the same size */
.panel-marks button.mark:not(:disabled):hover { background: var(--pico-form-element-background-color); }
.mark-0 { color: #6b7280; }
.mark-1 { color: #5b86ff; }
.mark-2 { color: #ff5fa8; }
.panel-marks button.mark:disabled { opacity: 0.3; cursor: not-allowed; }

/* Status labels (Pokérus, cured, Alpha): the pictures (_tags.html), the corner badges on a slot,
   and the panel's three on/off buttons. */
.tag-icon { display: block; width: 100%; height: 100%; }
.tag-pokerus circle, .tag-cured circle { fill: #e84393; }              /* Pokérus pink */
.tag-pokerus .arms { fill: none; stroke: #e84393; stroke-width: 3.2; stroke-linecap: round; }
.tag-shiny path { fill: #f5b301; }                                     /* the shiny gold */
.tag-alpha path { fill: #f2372f; }                                     /* Alpha red */
.tag-icon .ink { fill: #fff; }                                         /* eyes and mouth */
.slot .tag { position: absolute; display: block; pointer-events: none; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.6)); }
.slot .tag-virus { left: 2px; top: 2px; width: 26%; height: 26%; }               /* top left */
.slot .tag-alpha-corner { right: 2px; bottom: 2px; width: 26%; height: 26%; }   /* bottom right */
/* The panel's three buttons: pictures only, the same size as the marking shapes above them. An
   off button is the picture in grey; on, it has its colour. */
.panel-tags { display: flex; align-items: center; justify-content: center; gap: 0.35rem; margin: -0.35rem 0 0.75rem; }
.panel-tags button.tag-button {
  display: flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; margin: 0; padding: 0.25rem; border: 0; border-radius: 6px;
  background: transparent;
}
.panel-tags button.tag-button .tag-icon { opacity: 0.3; filter: grayscale(1) brightness(1.6); }
.panel-tags button.tag-button.on .tag-icon { opacity: 1; filter: none; }
.panel-tags button.tag-button:not(:disabled):hover { background: var(--pico-form-element-background-color); }
.panel-tags button.tag-button:disabled { opacity: 0.5; cursor: not-allowed; }

.panel-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 0.75rem; margin: 0 0 0.75rem; text-align: left; font-size: 0.8rem; }
.panel-facts div { margin: 0; }
.panel-facts .wide { grid-column: 1 / -1; }
.panel-facts dt { color: var(--pico-muted-color); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.03em; }
.panel-facts dd { margin: 0; }

.panel-stats { margin-bottom: 0.5rem; }
.stat-row { display: grid; grid-template-columns: 3.5rem 2rem 1fr; align-items: center; gap: 0.4rem; font-size: 0.75rem; line-height: 1.6; text-align: left; }
.stat-label { color: var(--pico-muted-color); }
.stat-value { text-align: right; font-weight: bold; }
.stat-bar { height: 6px; border-radius: 3px; background: var(--pico-form-element-background-color); overflow: hidden; }
.stat-bar span { display: block; height: 100%; background: var(--pico-primary); }

.panel-heading { margin: 0.75rem 0 0.25rem; font-size: 0.85rem; text-align: left; }
.panel-links { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0; padding: 0; list-style: none; }
.panel-links li { margin: 0; padding: 0; }
.panel-links a {
  display: inline-block; padding: 0.25rem 0.7rem; font-size: 0.8rem; text-decoration: none;
  border: 1px solid var(--pico-muted-border-color); border-radius: var(--pico-border-radius);
}
.panel-links a:hover { border-color: var(--pico-primary); }

/* --- Wide but SHORT windows: drop the details so the panel doesn't need its own scrollbar ----
   The full panel is about 890px of content (measured; it fits in a window of about 960px), so
   under ~1000px of window height we keep sprite -> name -> types -> Caught/Shiny/Clear ->
   Markings and hide the facts, stats and links. */
@media (min-width: 1100px) and (max-height: 1000px) {
  .panel-more { display: none; }
}

/* --- Everything narrower than 1100px (narrow desktop windows AND phones): dock the panel along
   the bottom. A side column would squeeze the boxes, and a slide-over would hide the slot you just
   clicked (breaking click-then-double-click). A slim bar at the window's bottom edge does neither:
   the boxes keep the full width and nearly every slot stays reachable. The chevron expands the details
   upward. (A slot in the bottom strip is covered once the bar opens: scroll it up a little.) */
@media (max-width: 1099px) {
  .dex-layout { grid-template-columns: minmax(0, 1fr); }
  .dex-layout:has(.panel-card) { padding-bottom: 10.5rem; }  /* room so the bar (about 160px with the chevron strip and the markings row) never covers the last boxes */

  .panel {
    display: block;                                          /* (phones hide the panel by default, see above) */
    position: fixed;
    top: auto; left: 0; right: 0; bottom: 0;
    z-index: 20;                                             /* above the pinned counter bar (10) */
    max-height: 70vh;
    background: var(--pico-card-background-color);
    border-top: 1px solid var(--pico-muted-border-color);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.45);
  }
  .panel:not(:has(.panel-card)) { display: none; }           /* nothing selected -> no bar at all */

  .panel-card { padding: 1.9rem 3.5rem 0.5rem 1rem; border-radius: 0; box-shadow: none; text-align: left; }   /* top: the chevron strip; right: room for the X */
  .panel-close { top: 1.9rem; right: 0.9rem; }

  .panel-main { display: flex; align-items: center; gap: 1rem; }
  .panel-sprite { flex: none; width: 64px; height: 64px; margin: 0; }
  .panel-sprite.no-sprite { font-size: 1.6rem; }
  .panel-id { flex: 1; }
  .panel-name { margin: 0; font-size: 1.1rem; }
  .panel-numbers { margin: 0; }
  .genus { display: inline; }
  .type-row { justify-content: flex-start; margin: 0.25rem 0 0; }
  .panel-actions { flex: none; width: 17rem; margin: 0; }

  /* The expander: a chevron tab centred along the very top edge of the bar. Up arrow = tap to
     expand, down arrow = tap to compact. The arrow is two borders of an empty box, turned 45 or
     225 degrees (no icon file, no text); the label's words are hidden for sighted users but kept
     for screen readers. */
  .more-toggle + .more-label {
    display: flex; align-items: center; justify-content: center;
    position: absolute; top: 0; left: 50%; transform: translateX(-50%);
    width: 6rem; height: 1.7rem; margin: 0; padding: 0;
    color: var(--pico-muted-color); cursor: pointer;
  }
  .more-toggle + .more-label:hover { color: var(--pico-color); }
  .more-label span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .more-label::after {
    content: ""; width: 0.65rem; height: 0.65rem;
    border: solid currentColor; border-width: 2px 0 0 2px;
    transform: translateY(0.15rem) rotate(45deg);           /* ^ pointing up: expand */
  }
  .more-toggle:checked + .more-label::after { transform: translateY(-0.15rem) rotate(225deg); }   /* v pointing down: compact */
  .more-toggle:focus-visible + .more-label { outline: 2px solid var(--pico-primary); border-radius: 6px; }

  .panel-more { display: none; }                             /* collapsed until the chevron is ticked */
  .more-toggle:checked ~ .panel-more {
    display: grid;
    grid-template-columns: 1fr 1.3fr 1fr;
    gap: 1.25rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--pico-muted-border-color);
  }
  .more-links .panel-heading { margin-top: 0; }
}

/* --- Phones (under 768px): the same docked bar, arranged for a ~375px-wide screen --------------
   The chevron along the top edge expands and compacts the bar. Row 1: picture, name, types (with
   the X at the right). Row 2: Caught / Shiny / Clear across the full width. The markings are
   tucked into the expanded part to keep the bar short. */
@media (max-width: 767px) {
  .dex-layout:has(.panel-card) { padding-bottom: 9.5rem; }   /* room so the bar never covers the last boxes */
  .panel-card { padding: 1.9rem 0.75rem 0.6rem; }
  .panel-main { flex-wrap: wrap; gap: 0.4rem 0.75rem; }
  .panel-sprite { width: 56px; height: 56px; }
  .panel-id { padding-right: 2.5rem; }                       /* keeps the name clear of the X */
  .panel-name { font-size: 1rem; }
  .panel-actions { flex: 1 1 100%; width: auto; }            /* the buttons get a row of their own */
  .panel-marks { display: none; }
  .panel-card:has(.more-toggle:checked) .panel-marks { display: flex; margin-top: 0.5rem; }
  .panel-tags { display: none; }                             /* the Status row: same treatment */
  .panel-card:has(.more-toggle:checked) .panel-tags { display: flex; margin-top: 0.5rem; }
  .more-toggle:checked ~ .panel-more { grid-template-columns: 1fr; }
}

/* Password box with a Show/Hide button beside it (login / register) */
.password-field { display: flex; gap: 0.5rem; align-items: flex-start; }
.password-field input { flex: 1; margin-bottom: 0; }
.password-field .show-password { width: auto; margin: 0; padding: 0.75rem 1rem; }
