/* ══ PalTracker ══════════════════════════════════════════════════════════
   Every rule below uses only the semantic tokens declared per theme, so all
   three themes work from one stylesheet. Set data-theme on <html>.          */

:root {
  /* Geometry. --r/-sm/-lg are the historical names; --r-card/-chip/-pill are
     what the mockup speaks. They're the same three values either way. */
  --r-card: 14px;
  --r-chip: 9px;
  --r-pill: 999px;
  --r-lg: 18px;
  --r: var(--r-card);
  --r-sm: var(--r-chip);
  --pad: 1.15rem;

  /* Type. No webfont is fetched — the app makes a point of never touching the
     network — so each stack names the mockup's face first and falls through to
     what Windows/macOS/Linux already have. See MISMATCHES.md. */
  --f-dis:  "Space Grotesk", "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
  --f-body: Manrope, "Segoe UI Variable Text", "Segoe UI", Inter, system-ui, -apple-system, sans-serif;
  --num:    "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
  --dis-w: 700;
  --dis-ls: -.03em;

  /* Shell metrics. --label flips the rail between icon+text and icons only. */
  --side: 220px;
  --label: inline;
  --foot: block;
  --shell: 1.5rem;
  --mast-h: 360px;
  --field-h: 128px;
  --gmin: 174px;
  --gap: .65rem;
  --ad-w: 728px;
  --ad-h: 90px;

  /* Element colours are constant across themes — always dark ink on top. */
  --el-neutral:  #cbd5e1;
  --el-fire:     #ff7a45;
  --el-water:    #4aa8ff;
  --el-grass:    #5ecb64;
  --el-electric: #f5cf3a;
  --el-ice:      #6fd8ea;
  --el-ground:   #cf9a5c;
  --el-dark:     #a077ee;
  --el-dragon:   #f0714f;
  --on-el:       #1a1206;

  /* Older rules were written against --text-dim/--text-faint/--shadow; the
     themes below declare --dim/--faint/--sh. Alias rather than rename 200
     call sites. */
  --text-dim:   var(--dim);
  --text-faint: var(--faint);
  --shadow:     var(--sh);
  --page-tint:  none;
}

/* ── Daylight — warm paper, savanna noon (default) ───────────────────── */
[data-theme="daylight"] {
  --page:       #f4f1ea;
  --surface:    #fffdf8;
  --surface-2:  #efeade;
  --surface-3:  #e4ddcd;
  --line:       #ddd5c4;
  --line-soft:  #e9e2d4;
  --text:       #1b1814;
  --dim:        #5c564c;
  --faint:      #8d8676;
  --accent:     #e2620d;
  --accent-ink: #fffdf8;
  --accent-2:   #1f6f66;
  --accent-soft: rgba(226,98,13,.12);
  --good:       #2f7d4f;
  --warn:       #a2650a;
  --bad:        #c23a26;
  --male:       #2f5fd4;
  --female:     #c2437f;
  --art:        #efeade;
  --scrim:      rgba(27,24,20,.42);
  --sh:         0 14px 34px rgba(27,24,20,.14);
  --shadow-sm:  0 2px 8px rgba(27,24,20,.08);
  --card-bg:    var(--surface);
  --card-bd:    1px solid var(--line);
  --card-sh:    none;
  /* masthead scene */
  --sky-a: #f6d9a4; --sky-b: #f2efe0;
  --hill-1: #c9c9a0; --hill-2: #a2a678; --hill-3: #767c52;
  --orb: #f7bc45; --orb-glow: rgba(247,188,69,.4); --orb-x: 11%; --orb-y: 16%;
  --stars: 0; --gsh: .3;
  --band-fg: #241d12; --band-dim: #6f6450; --band-line: rgba(36,29,18,.22);
}

/* ── Nightfall — moonlit blue hour, pal-orange accents ───────────────── */
[data-theme="nightfall"] {
  --page:       #0e131c;
  --surface:    #151c28;
  --surface-2:  #1b2433;
  --surface-3:  #242f42;
  --line:       #2b3649;
  --line-soft:  #212b3b;
  --text:       #e9eff8;
  --dim:        #9ca9bf;
  --faint:      #6d7a92;
  --accent:     #ff9a3c;
  --accent-ink: #251404;
  --accent-2:   #56c3d2;
  --accent-soft: rgba(255,154,60,.14);
  --good:       #58c381;
  --warn:       #e6b34c;
  --bad:        #e87461;
  --male:       #6d95f0;
  --female:     #ef77ab;
  --art:        #1c2534;
  --scrim:      rgba(5,8,14,.74);
  --sh:         0 14px 34px rgba(0,0,0,.42);
  --shadow-sm:  0 3px 10px rgba(0,0,0,.3);
  --card-bg:    var(--surface);
  --card-bd:    1px solid var(--line);
  --card-sh:    none;
  --sky-a: #20364f; --sky-b: #0a101d;
  --hill-1: #1b2c44; --hill-2: #12203a; --hill-3: #0a1426;
  --orb: #e8eef8; --orb-glow: rgba(232,238,248,.28); --orb-x: 13%; --orb-y: 14%;
  --stars: .9; --gsh: .55;
  --band-fg: #f0f4fb; --band-dim: #93a1b8; --band-line: rgba(240,244,251,.18);
}

/* ── Ember — campfire dusk, warm charcoal ────────────────────────────── */
[data-theme="ember"] {
  --page:       #161009;
  --surface:    #1e1610;
  --surface-2:  #261c13;
  --surface-3:  #332617;
  --line:       #3d2e1c;
  --line-soft:  #2e2213;
  --text:       #f6ebd9;
  --dim:        #b5a289;
  --faint:      #82735d;
  --accent:     #ff7d2e;
  --accent-ink: #250f02;
  --accent-2:   #57b7a4;
  --accent-soft: rgba(255,125,46,.14);
  --good:       #71bf80;
  --warn:       #e2a94a;
  --bad:        #e0705c;
  --male:       #6f96e0;
  --female:     #e57aa4;
  --art:        #251a10;
  --scrim:      rgba(10,6,3,.74);
  --sh:         0 14px 34px rgba(0,0,0,.46);
  --shadow-sm:  0 3px 10px rgba(0,0,0,.34);
  --card-bg:    var(--surface);
  --card-bd:    1px solid var(--line);
  --card-sh:    none;
  --sky-a: #59280e; --sky-b: #170d06;
  --hill-1: #331b0a; --hill-2: #22120a; --hill-3: #140a05;
  --orb: #ffab5e; --orb-glow: rgba(255,150,66,.4); --orb-x: 20%; --orb-y: 38%;
  --stars: .35; --gsh: .55;
  --band-fg: #f8eee0; --band-dim: #b29c80; --band-line: rgba(248,238,224,.18);
}

* { box-sizing: border-box; }

/* Any class that sets `display` outranks the UA rule for [hidden], which
   silently breaks every hidden-attribute toggle. Settle it once. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--page);
  background-image: var(--page-tint);
  background-attachment: fixed;
  color: var(--text);
  font: 15px/1.55 var(--f-body);
  -webkit-font-smoothing: antialiased;
}
body { padding-bottom: 0; }

h1, h2, h3 {
  margin: 0;
  font-family: var(--f-dis);
  font-weight: var(--dis-w);
  letter-spacing: var(--dis-ls);
}
.num, .lvl-badge, .iv-row, .statbar .val, .stat b {
  font-family: var(--num);
  font-variant-numeric: tabular-nums;
}
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent); }

/* ══ shell: left rail + masthead column ══════════════════════════════════ */
.shell { display: flex; align-items: stretch; min-height: 100vh; }
.col { flex: 1; min-width: 0; }

.rail {
  position: sticky; top: 0; align-self: flex-start;
  flex: 0 0 var(--side); width: var(--side); height: 100vh;
  display: flex; flex-direction: column; gap: 2px;
  padding: .85rem .5rem;
  border-right: 1px solid var(--line);
  background: var(--page);
  z-index: 20;
}
.rail button[data-tab] {
  display: flex; align-items: center; gap: .62rem;
  border: 0; background: none; border-radius: var(--r-chip);
  padding: .55rem .6rem;
  color: var(--dim); font-weight: 600; font-size: .93rem;
  text-align: left; cursor: pointer;
  transition: background .13s, color .13s;
}
.rail button[data-tab]:hover { background: var(--surface-2); color: var(--text); }
.rail button[data-tab].active { background: var(--accent-soft); color: var(--text); }
.rail .glyph { width: 18px; flex-shrink: 0; text-align: center; color: var(--faint); }
.rail button[data-tab].active .glyph { color: var(--accent); }
.rail .rlabel { display: var(--label); white-space: nowrap; overflow: hidden; }

.rail-foot { margin-top: auto; display: var(--foot); }
.rail-card {
  padding: .62rem;
  border-radius: var(--r-chip);
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
}
.rail-card + .rail-card { margin-top: .5rem; }
.rail-title {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--faint); font-weight: 700;
}
.rail-note, .save-state { font-size: .69rem; color: var(--dim); line-height: 1.5; margin-top: .18rem; }
.save-state.ok { color: var(--good); }
.save-state.warn { color: var(--warn); }

/* Overlapping portraits — the six highest-level pals in the box. */
.lineup { display: flex; align-items: center; padding: .45rem 2px 0; }
.lineup .portrait { border: 2px solid var(--surface-2); margin-left: -9px; }
.lineup .portrait:first-child { margin-left: 0; }
.lineup .more { margin-left: .55rem; font-size: .68rem; color: var(--dim); font-family: var(--num); }

/* ══ masthead ════════════════════════════════════════════════════════════ */
.masthead {
  position: relative;
  min-height: var(--mast-h);
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, var(--sky-b), var(--sky-a));
  color: var(--band-fg);
  overflow: hidden;
}
.scene { position: absolute; inset: 0; pointer-events: none; }
.scene .stars {
  position: absolute; inset: 0; opacity: var(--stars);
  background-image:
    radial-gradient(1.6px 1.6px at  8% 18%, rgba(255,255,255,.95), transparent 55%),
    radial-gradient(1.2px 1.2px at 17% 42%, rgba(255,255,255,.80), transparent 55%),
    radial-gradient(1.8px 1.8px at 26% 12%, rgba(255,255,255,.90), transparent 55%),
    radial-gradient(1.1px 1.1px at 37% 30%, rgba(255,255,255,.70), transparent 55%),
    radial-gradient(1.5px 1.5px at 47%  8%, rgba(255,255,255,.85), transparent 55%),
    radial-gradient(1.2px 1.2px at 58% 24%, rgba(255,255,255,.75), transparent 55%),
    radial-gradient(1.7px 1.7px at 67% 14%, rgba(255,255,255,.90), transparent 55%),
    radial-gradient(1.1px 1.1px at 76% 34%, rgba(255,255,255,.65), transparent 55%),
    radial-gradient(1.5px 1.5px at 86% 10%, rgba(255,255,255,.85), transparent 55%),
    radial-gradient(1.2px 1.2px at 93% 28%, rgba(255,255,255,.70), transparent 55%);
}
.scene .orb {
  position: absolute; right: var(--orb-x); top: var(--orb-y);
  width: 58px; height: 58px; border-radius: 50%;
  background: var(--orb); box-shadow: 0 0 64px 26px var(--orb-glow);
}
.scene .hill { position: absolute; border-radius: 50%; }
.scene .h1 { left: -45%; bottom: -44%; width: 190%; height: 64%; background: var(--hill-1); }
.scene .h2 { left: -25%; bottom: -50%; width: 190%; height: 66%; background: var(--hill-2); }
.scene .h3 { left: -60%; bottom: -57%; width: 220%; height: 70%; background: var(--hill-3); }
.scene-pals {
  position: absolute; right: 4%; bottom: 4%;
  display: flex; align-items: flex-end; gap: 5px;
}
.scene-pal { position: relative; display: block; aspect-ratio: 1 / 1; }
.scene-pal img { position: relative; width: 100%; height: 100%; object-fit: contain; }
.scene-pal .gsh {
  position: absolute; left: 12%; right: 12%; bottom: -3%; height: 9%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0,0,0,var(--gsh)), transparent 72%);
}

.util {
  position: relative; z-index: 3;
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  padding: .55rem var(--shell);
  border-bottom: 1px solid var(--band-line);
  font-size: .8rem;
}
.util-save { font-family: var(--num); color: var(--band-dim); }
.util-link {
  border: 1px solid var(--band-line); background: transparent; color: var(--band-dim);
  border-radius: var(--r-pill); padding: .08rem .62rem;
  font-size: .78rem; cursor: pointer; line-height: 1.4;
}
.util-link:hover { color: var(--band-fg); border-color: var(--band-fg); }
.util-right { margin-left: auto; display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.util-btn {
  border: 0; background: transparent; color: var(--band-dim);
  font-weight: 600; font-size: .8rem; padding: 0; cursor: pointer;
}
.util-btn:hover { color: var(--band-fg); }
.util-sync {
  display: inline-flex; align-items: center; gap: .35rem;
  border: 1px solid var(--band-fg); background: var(--band-fg); color: var(--page);
  border-radius: var(--r-pill); padding: .28rem .95rem;
  font-weight: 700; font-size: .8rem; white-space: nowrap; cursor: pointer;
  transition: background .13s, color .13s;
}
.util-sync:hover { background: transparent; color: var(--band-fg); }
.util-sync[disabled] { opacity: .7; cursor: default; }

.mast-body { position: relative; z-index: 2; padding: 1.75rem var(--shell) 0; max-width: 620px; }
.mast-body h1 { font-size: clamp(42px, 6.4vw, 80px); line-height: .92; letter-spacing: -.045em; }
.mast-line { margin: .7rem 0 0; font-size: .97rem; font-weight: 600; }
.mast-sub { margin: .22rem 0 0; font-size: .8rem; color: var(--band-dim); }
.mast-stats { display: flex; flex-wrap: wrap; gap: 1.6rem; margin: 1.25rem 0 2rem; }
.mstat .mnum {
  display: block; font-family: var(--num); font-size: 1.9rem; font-weight: 700;
  line-height: 1; font-variant-numeric: tabular-nums;
}
.mstat .of { font-style: normal; font-size: 1rem; color: var(--band-dim); }
.mstat .mcap {
  display: block; margin-top: .28rem;
  font-size: .65rem; text-transform: uppercase; letter-spacing: .14em;
  color: var(--band-dim); font-weight: 700;
}
.mstat .bar {
  display: block; height: 3px; margin-top: .35rem;
  background: var(--band-line); border-radius: 2px; overflow: hidden;
}
.mstat .bar i { display: block; height: 100%; width: 0; background: var(--band-fg); opacity: .6; transition: width .35s ease; }

.drop-zone {
  position: fixed; inset: 0; z-index: 70;
  background: color-mix(in srgb, var(--page) 82%, transparent);
  backdrop-filter: blur(4px);
  display: grid; place-items: center;
}
.drop-card {
  display: flex; flex-direction: column; align-items: center; gap: .4rem;
  padding: 3rem 4rem;
  border: 2px dashed var(--accent);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow);
  text-align: center;
}
.drop-card b { font-size: 1.2rem; }
.drop-card span { color: var(--text-dim); font-size: .88rem; }
.drop-icon { font-size: 2.2rem; color: var(--accent); line-height: 1; }


/* ══ buttons ═════════════════════════════════════════════════════════════ */
.btn {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: .4rem .85rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .13s, border-color .13s, transform .08s;
}
.btn:hover { background: var(--surface-3); border-color: var(--text-faint); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; font-weight: 700; }
.btn.primary:hover { filter: brightness(1.08); background: var(--accent); }
.btn.teal { background: var(--accent-2); color: var(--accent-ink); border-color: transparent; font-weight: 700; }
.btn.teal:hover { filter: brightness(1.08); background: var(--accent-2); }
.btn.danger { background: transparent; color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); }
.btn.danger:hover { background: color-mix(in srgb, var(--bad) 15%, transparent); border-color: var(--bad); }
.btn.sm { padding: .2rem .55rem; font-size: .78rem; }

/* ══ tab panels ══════════════════════════════════════════════════════════ */
main { padding: var(--shell); max-width: 1680px; margin: 0 auto; }
.tab { display: none; }
.tab.active { display: block; animation: fade .2s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(6px); } }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }

/* ══ controls ════════════════════════════════════════════════════════════ */
.filters { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-bottom: 1.4rem; }

/* Two selects that mean one thing (work skill + minimum rank) read better
   welded together than as two loose dropdowns. */
.ctl-group { display: inline-flex; }
.ctl-group > select:first-child {
  border-top-right-radius: 0; border-bottom-right-radius: 0; border-right-width: 0;
}
.ctl-group > select:last-child {
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  padding-left: .5rem; padding-right: .4rem;
  color: var(--text-dim);
  background: var(--surface-2);
}
.ctl-group > select:focus { position: relative; z-index: 1; }
input[type=search], input[type=text], input[type=number], select, textarea {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: .42rem .7rem;
  outline: none;
  font-weight: 500;
}
input::placeholder { color: var(--text-faint); }
input:focus, select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.filters input[type=search] { min-width: 230px; }
.field { display: flex; flex-direction: column; gap: .22rem; font-size: .66rem; color: var(--text-faint); text-transform: uppercase; letter-spacing: .08em; font-weight: 700; }
.field input { min-width: 260px; }
.inline-check { display: flex; align-items: center; gap: .42rem; font-size: .85rem; color: var(--text-dim); cursor: pointer; }
input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.result-count { margin-left: auto; color: var(--text-faint); font-size: .82rem; }

/* ══ custom dropdowns — work skill + target pal ═════════════════════════
   Native <select>s stay in the DOM (hidden) as the state carriers; the dd
   writes to them and fires change, so every existing listener keeps working. */
.dd { position: relative; display: inline-flex; align-items: center; }
.dd-native { display: none; }
.dd-btn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .42rem .7rem;
  border-radius: var(--r-chip);
  border: 1px solid var(--line);
  background: var(--surface); color: var(--text);
  font-weight: 600; font-size: .85rem; white-space: nowrap;
  cursor: pointer;
}
.dd-btn:hover { border-color: var(--accent); }
.dd-btn .car { color: var(--text-faint); font-size: .62rem; }
.dd-btn .wicon { width: 18px; height: 18px; object-fit: contain; }
/* Work skill + minimum rank: two menus, one control. The first keeps its left
   corners, the last keeps its right, and the seam between them is a single
   shared line. */
.ctl-group .dd:first-child .dd-btn {
  border-top-right-radius: 0; border-bottom-right-radius: 0; border-right-width: 0;
}
.ctl-group .dd:last-child .dd-btn {
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  background: var(--surface-2); color: var(--text-dim);
}
.ctl-group .dd:last-child .dd-panel { left: auto; right: 0; min-width: 190px; }
.ctl-group .dd-btn:hover { position: relative; z-index: 1; }
.dd-right .dd-panel { left: auto; right: 0; }
/* Set by enhanceSelect when a left-anchored panel would overflow the viewport. */
.dd-panel.flip { left: auto; right: 0; }
.dd-panel { max-width: calc(100vw - 1.5rem); }
.dd-scrim { position: fixed; inset: 0; z-index: 29; border: 0; background: transparent; padding: 0; cursor: default; }
.dd-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  min-width: 220px; max-height: 330px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); box-shadow: var(--shadow);
  padding: .38rem;
  animation: rise .15s ease;
}
.dd-item {
  display: flex; align-items: center; gap: .55rem; width: 100%;
  border: 0; background: none; border-radius: var(--r-chip);
  padding: .42rem .55rem;
  font-weight: 600; font-size: .85rem; color: var(--dim);
  text-align: left; cursor: pointer;
}
.dd-item:hover { background: var(--surface-2); color: var(--text); }
.dd-item.on { background: var(--accent-soft); color: var(--text); }
.dd-item .wicon { width: 18px; height: 18px; object-fit: contain; }
.dd-item .tick { margin-left: auto; color: var(--accent); font-weight: 800; }
.dd-note {
  padding: .35rem .55rem .25rem;
  font-size: .62rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--text-faint); font-weight: 700;
}
.dd-search { width: 100%; margin-bottom: .38rem; background: var(--surface-2); }
.dd-list { display: flex; flex-direction: column; }
.dd-item .portrait { width: 30px; height: 30px; }
.dd-name { flex: 1; min-width: 0; }
.dd-dex { color: var(--text-faint); font-family: var(--num); font-size: .66rem; }
.dd-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.dd-empty { padding: .5rem .55rem; color: var(--text-faint); font-size: .82rem; }
.dd-target .portrait { width: 34px; height: 34px; }
.dd-target .dd-label { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.dd-target .dd-cap { font-size: .68rem; color: var(--text-faint); font-weight: 600; }
.dd-target .dd-name-big { font-family: var(--f-dis); font-weight: var(--dis-w); letter-spacing: var(--dis-ls); font-size: 1.05rem; }

.chips { display: flex; gap: .25rem; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text-dim);
  border-radius: 999px;
  padding: .24rem .72rem;
  font-size: .76rem;
  font-weight: 600;
  cursor: pointer;
  transition: .13s;
}
.chip:hover { border-color: var(--text-faint); }
.chip[data-on="1"] { color: var(--on-el); border-color: transparent; font-weight: 700; }
.chip.removable::after { content: " ×"; opacity: .6; }

.empty { color: var(--text-faint); padding: 2.5rem 0; text-align: center; }
.section-title {
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--text-faint);
  margin: 1.9rem 0 .75rem;
  font-weight: 700;
}

/* ══ surfaces ════════════════════════════════════════════════════════════ */
.panel, .step, .reach-row, .box-row, .advice, .route-summary, .guide-card, .pp-row {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-sm);
}

/* ══ paldex — art-forward cards ══════════════════════════════════════════
   Each card leads with a field of the pal's own element colours, the pal
   stood on it. The dex number sits on the field; ownership sits opposite. */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--gmin), 1fr)); gap: var(--gap); }

.card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--card-bg);
  border: var(--card-bd);
  border-radius: var(--r-card);
  box-shadow: var(--card-sh);
  overflow: hidden;
  transition: transform .16s cubic-bezier(.2,.7,.3,1), box-shadow .16s, border-color .16s;
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--line));
}
.card.owned-full { border-color: color-mix(in srgb, var(--good) 45%, var(--line)); }

.card-top { display: block; cursor: pointer; }
/* Named card-field: bare .field is the form-label class. */
.card-field {
  position: relative;
  height: var(--field-h);
  display: grid; place-items: center;
}
/* A soft sun on the field, so the pal reads as lit from the front. */
.card-field::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 68%, rgba(255,255,255,.34), transparent 64%);
}
.dexno {
  position: absolute; top: 8px; left: 10px;
  font-family: var(--num); font-size: .62rem; font-weight: 700;
  color: rgba(22,15,4,.62);
}
.card .portrait { position: relative; width: 92px; height: 92px; border: 0; background: transparent; }
.cbody { padding: .6rem .7rem .7rem; display: flex; flex-direction: column; gap: .38rem; }

.card-tag {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .08rem .5rem;
  border-radius: var(--r-pill);
  font-family: var(--num); font-size: .62rem; font-weight: 700;
  white-space: nowrap;
}
.card-tag.own { background: var(--good); color: var(--page); }
.card-tag.steps {
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  border: 1px solid var(--line-soft);
  color: var(--dim);
  backdrop-filter: blur(4px);
}

.portrait {
  width: 104px; height: 104px;
  border-radius: 50%;
  background: var(--art);
  border: 1px solid var(--line);
  display: grid; place-items: center;
  overflow: hidden;
  flex-shrink: 0;
  transition: transform .16s cubic-bezier(.2,.7,.3,1);
}
.card:hover .portrait, .box-row:hover .portrait { transform: scale(1.06); }
.portrait img { width: 86%; height: 86%; object-fit: contain; filter: drop-shadow(0 3px 6px rgba(0,0,0,.35)); }
.portrait.lg { width: 100px; height: 100px; }
/* Full square art tile — the circle crop reads as a chopped head on the
   big drawer/edit portraits, so those show the whole icon instead. */
.portrait.square { border-radius: 14px; }
.portrait.square img { width: 100%; height: 100%; filter: drop-shadow(0 3px 6px rgba(0,0,0,.35)); }
.portrait.md { width: 62px; height: 62px; }
.portrait.sm { width: 44px; height: 44px; }
.portrait.xs { width: 30px; height: 30px; }
.portrait.tiny { width: 34px; height: 34px; }

.card-id { font-size: .66rem; color: var(--text-faint); font-weight: 600; display: flex; align-items: center; gap: .3rem; }
.card-name { font-family: var(--f-dis); font-weight: var(--dis-w); letter-spacing: var(--dis-ls); line-height: 1.15; font-size: .97rem; }
.card-meta { display: flex; gap: .22rem; flex-wrap: wrap; }

.el {
  font-size: .61rem;
  font-weight: 700;
  padding: .1rem .44rem;
  border-radius: 999px;
  color: var(--on-el);
  letter-spacing: .01em;
}

.gender-row { display: flex; gap: .3rem; width: 100%; }
/* The mockup drops the paldex ♂/♀ ticks; they stay because they're the
   fastest way to record a collection by hand. See MISMATCHES.md. */
.card .gender-row { margin-top: auto; padding: 0 .7rem .7rem; }
.gbtn {
  flex: 1;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: .3rem 0;
  cursor: pointer;
  color: var(--text-faint);
  font-size: .8rem;
  font-weight: 700;
  transition: .13s;
}
.gbtn:hover { border-color: var(--text-faint); color: var(--text-dim); }
.gbtn[data-on="1"].m { background: var(--male);   color: #fff; border-color: transparent; }
.gbtn[data-on="1"].f { background: var(--female); color: #fff; border-color: transparent; }

.steps-pill {
  font-size: .62rem; font-weight: 700;
  color: var(--text-faint);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .02rem .45rem;
}
.steps-pill.own { background: var(--good); color: var(--page); border-color: transparent; }

/* ══ my pals ═════════════════════════════════════════════════════════════ */
.box-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: .7rem; }
.box-row { padding: .7rem; display: flex; gap: .7rem; align-items: flex-start; transition: border-color .13s; }
.box-row:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.box-main { flex: 1; min-width: 0; }
.box-head { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.box-nick { font-weight: 700; font-size: 1rem; }
.box-species { font-size: .78rem; color: var(--text-dim); display: flex; align-items: center; gap: .3rem; flex-wrap: wrap; margin-top: .15rem; }
.box-actions { display: flex; flex-direction: column; gap: .25rem; }
.gender-badge { font-size: .76rem; font-weight: 700; padding: .04rem .42rem; border-radius: 999px; color: #fff; }
.gender-badge.m { background: var(--male); }
.gender-badge.f { background: var(--female); }
.lvl-badge {
  font-size: .68rem; font-weight: 700; letter-spacing: .03em;
  background: var(--surface-3); color: var(--text-dim);
  border-radius: 999px; padding: .04rem .45rem;
}
.passive-list { display: flex; flex-wrap: wrap; gap: .22rem; margin-top: .4rem; }
.passive {
  display: inline-flex; align-items: baseline; gap: .22rem;
  font-size: .68rem; font-weight: 700; border-radius: 999px;
  padding: .05rem .45rem; color: var(--on-el);
}
.passive .stars { font-style: normal; font-size: .58rem; opacity: .65; letter-spacing: -.5px; }
.passive.want { outline: 2px solid var(--text); outline-offset: 1px; }
.passive.lost { opacity: .45; text-decoration: line-through; }

.trait-picker {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  margin: -.4rem 0 1.2rem;
}
.trait-picker > summary {
  cursor: pointer; padding: .6rem .9rem;
  display: flex; align-items: center; gap: .6rem;
  font-weight: 700; font-size: .88rem;
  list-style: none;
}
.trait-picker > summary::-webkit-details-marker { display: none; }
.trait-picker > summary::before {
  content: "▸"; color: var(--text-faint); transition: transform .15s; display: inline-block;
}
.trait-picker[open] > summary::before { transform: rotate(90deg); }
.trait-count { color: var(--text-faint); font-weight: 500; font-size: .8rem; margin-left: auto; }
.trait-count.on { color: var(--accent); font-weight: 700; }
.trait-picker-body { padding: 0 .9rem .9rem; border-top: 1px solid var(--line-soft); }
.trait-opt { opacity: .55; }
.trait-opt[data-on="1"] { opacity: 1; outline: 2px solid var(--text); outline-offset: 1px; }
.trait-opt.unreachable { opacity: .3; filter: grayscale(.7); }
.trait-opts-head {
  display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap;
  margin: .2rem 0 .5rem;
}
.trait-hidden { font-size: .74rem; color: var(--text-faint); margin-left: auto; }

.step-need {
  display: flex; align-items: center; gap: .3rem; flex-wrap: wrap;
  margin-top: .5rem; padding: .45rem .55rem;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-radius: var(--r-sm);
  font-size: .78rem;
}
.step-need-label {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--accent); font-weight: 800; margin-right: .1rem;
}
.from-who { color: var(--text-dim); font-size: .74rem; }

.gender-fix {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-top: .4rem; padding: .5rem .6rem;
  background: color-mix(in srgb, var(--good) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--good) 30%, transparent);
  border-radius: var(--r-sm);
}
.gender-fix .gf-pair { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.gender-fix .portrait { width: 30px; height: 30px; }
.gender-fix .pname { font-size: .82rem; }
.gender-fix .psub, .gender-fix .works { display: none; }
.gender-fix.nofix, .gender-fix.partial {
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border-color: color-mix(in srgb, var(--warn) 32%, transparent);
}
.trait-plan { margin-bottom: 1.2rem; }
.trait-row {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .45rem .2rem; border-bottom: 1px solid var(--line-soft); font-size: .85rem;
}
.trait-row:last-child { border-bottom: 0; }
.trait-row .where { color: var(--text-dim); }
.trait-row .missing { color: var(--bad); font-weight: 600; }
.odds-big { font-size: 1.3rem; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.iv-row { display: flex; gap: .55rem; margin-top: .4rem; font-size: .7rem; color: var(--text-faint); }
.iv-row b { color: var(--text); }

/* ══ route ═══════════════════════════════════════════════════════════════ */
.route-summary {
  padding: 1.1rem 1.3rem;
  margin-bottom: 1.2rem;
  display: flex;
  align-items: center;
  gap: 1.2rem;
  flex-wrap: wrap;
  border-radius: var(--r-lg);
  position: relative;
  overflow: hidden;
}
.route-summary .big { font-size: 1.5rem; font-weight: 800; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.psub { font-size: .75rem; color: var(--text-faint); display: block; }

.step { padding: .7rem .9rem; margin-bottom: .5rem; transition: border-color .13s; }
.step:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.step-line { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.step-pool {
  display: flex; align-items: center; gap: .25rem; flex-wrap: wrap;
  margin-top: .55rem; padding-top: .5rem;
  border-top: 1px solid var(--line-soft);
}
.step-pool-label {
  font-size: .64rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--text-faint); font-weight: 700; margin-right: .15rem;
}
.pool-odds { font-size: .7rem; color: var(--text-faint); margin-left: auto; font-weight: 600; }
.pool-odds.impossible { color: var(--red); max-width: 34ch; text-align: right; font-weight: 500; }
.step-no {
  width: 26px; height: 26px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center;
  font-size: .76rem; font-weight: 800;
}
.step-parent { display: flex; align-items: center; gap: .45rem; cursor: pointer; }
.step .arrow, .step .plus { color: var(--text-faint); font-size: 1.1rem; }
.pname { font-weight: 700; }
.tag {
  font-size: .65rem; font-weight: 700;
  border-radius: 999px; padding: .05rem .5rem;
  border: 1px solid var(--line); color: var(--text-faint);
  white-space: nowrap;
}
.tag.have  { background: var(--good); color: var(--page); border-color: transparent; }
.tag.catch { background: var(--warn); color: var(--page); border-color: transparent; }
.tag.m { background: var(--male);   color: #fff; border-color: transparent; }
.tag.f { background: var(--female); color: #fff; border-color: transparent; }
.tag.needs {
  background: transparent;
  color: var(--warn);
  border: 1px dashed var(--warn);
  font-weight: 800;
}
.tag.needs i { font-style: normal; font-size: .85em; margin-left: .15rem; }
.step-warn {
  flex-basis: 100%;
  font-size: .78rem;
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 13%, transparent);
  border-radius: var(--r-sm);
  padding: .4rem .6rem;
  font-weight: 500;
}
.advice {
  border-radius: var(--r-lg);
  padding: 1rem 1.2rem;
  margin-bottom: 1.2rem;
  font-size: .92rem;
  color: var(--text-dim);
  background: color-mix(in srgb, var(--warn) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--warn) 32%, var(--line));
}
.advice b { color: var(--warn); }

/* ══ reachable ═══════════════════════════════════════════════════════════ */
.reach-group { margin-bottom: 1.6rem; }
.reach-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(214px, 1fr)); gap: .5rem; }
.reach-row { display: flex; align-items: center; gap: .55rem; padding: .4rem .5rem; cursor: pointer; transition: .13s; }
.reach-row:hover { border-color: var(--accent); transform: translateX(3px); }

/* ══ combos ══════════════════════════════════════════════════════════════ */
.lookup { margin-top: 2.2rem; }
.lookup > summary {
  cursor: pointer; font-weight: 700; color: var(--text-faint);
  text-transform: uppercase; font-size: .72rem; letter-spacing: .12em;
  padding: .5rem 0;
}
.lookup > summary:hover { color: var(--accent); }
.combo-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: .8rem; }
@media (max-width: 900px) { .combo-panels { grid-template-columns: 1fr; } }
.panel { padding: var(--pad); }
.panel h2 { font-size: .98rem; margin-bottom: .8rem; }
.panel input { width: 100%; }
.two-up { display: flex; align-items: center; gap: .5rem; }
.two-up input { flex: 1; }
.plus { color: var(--text-faint); font-weight: 700; }
.combo-out { margin-top: .8rem; max-height: 60vh; overflow-y: auto; }
.combo-row {
  display: flex; align-items: center; gap: .35rem;
  padding: .3rem .25rem;
  border-bottom: 1px solid var(--line-soft);
  font-size: .83rem;
}
.combo-row .sep { color: var(--text-faint); }
.combo-row.ready { background: color-mix(in srgb, var(--good) 11%, transparent); }

/* ══ passive planner ═════════════════════════════════════════════════════ */
.pp-row { padding: .85rem 1rem; margin-bottom: .55rem; display: flex; gap: .9rem; align-items: center; flex-wrap: wrap; }
.pp-parent { display: flex; align-items: center; gap: .5rem; min-width: 0; cursor: pointer; }
.odds { margin-left: auto; text-align: right; min-width: 140px; }
.odds b { font-size: 1.45rem; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.pool-note {
  font-size: .76rem; color: var(--text-faint); flex-basis: 100%;
  border-top: 1px solid var(--line-soft); padding-top: .5rem;
  display: flex; align-items: center; gap: .3rem; flex-wrap: wrap;
}

/* ══ drawer + modal ══════════════════════════════════════════════════════ */
.drawer-scrim, .modal-scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 40; backdrop-filter: blur(3px); }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(480px, 100%);
  background: var(--surface);
  border-left: 1px solid var(--line);
  z-index: 41;
  overflow-y: auto;
  padding: 0 1.3rem 1.3rem;
  box-shadow: -18px 0 44px rgba(0,0,0,.35);
}
/* Element-colour banner; the pal's portrait spills out of it into the body. */
.drawer-band { position: relative; height: 132px; margin: 0 -1.3rem; }
.drawer-band::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 88%, rgba(255,255,255,.38), transparent 66%);
}
.drawer-band .portrait {
  position: absolute; left: 50%; top: calc(100% - 52px);
  transform: translateX(-50%);
  width: 118px; height: 118px;
  box-shadow: 0 10px 26px rgba(0,0,0,.28);
}
.drawer-head {
  display: flex; gap: 1rem; align-items: flex-start;
  position: relative; padding-top: 4.6rem; text-align: center;
}
.drawer h2 { font-size: 1.4rem; font-weight: 800; }
.drawer .close, .modal .close {
  margin-left: auto; background: none; border: 0;
  color: var(--text-faint); font-size: 1.5rem; cursor: pointer; line-height: 1;
}
.drawer .close { position: absolute; top: 4.7rem; right: 0; margin: 0; }
.drawer .close:hover, .modal .close:hover { color: var(--text); }
.kv { display: grid; grid-template-columns: auto 1fr; gap: .3rem .9rem; font-size: .85rem; margin-top: .6rem; }
.kv dt { color: var(--text-faint); }
.kv dd { margin: 0; font-weight: 600; }

.statbar { display: flex; align-items: center; gap: .55rem; margin: .22rem 0; font-size: .8rem; }
.statbar span:first-child { width: 84px; color: var(--text-faint); }
.statbar .track { flex: 1; height: 7px; background: var(--surface-3); border-radius: 4px; overflow: hidden; }
.statbar .track i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-2), var(--accent)); border-radius: 4px; }
.statbar .val { width: 44px; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

.work-grid { display: flex; flex-wrap: wrap; gap: .3rem; }
.work-pill {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: .74rem; font-weight: 600;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: .12rem .55rem .12rem .3rem;
}
.work-pill img { width: 16px; height: 16px; object-fit: contain; }
.work-pill b { color: var(--accent); font-variant-numeric: tabular-nums; }

table.moves { width: 100%; border-collapse: collapse; font-size: .8rem; }
table.moves th { text-align: left; color: var(--text-faint); font-weight: 600; padding: .25rem .3rem; }
table.moves td { padding: .25rem .3rem; border-top: 1px solid var(--line-soft); }
table.moves td.lv { color: var(--text-faint); width: 34px; }

.modal {
  position: fixed; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(580px, calc(100% - 2rem));
  max-height: 88vh; overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 26px 70px rgba(0,0,0,.5);
  z-index: 41;
  padding: 1.4rem;
}
.modal h2 { font-size: 1.2rem; }
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .75rem; }
.form-grid label, .form-full {
  display: flex; flex-direction: column; gap: .22rem;
  font-size: .65rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-faint); font-weight: 700;
}
.form-full { grid-column: 1 / -1; }
.form-grid input, .form-grid select, .form-full input { width: 100%; }
.seg { display: flex; gap: .35rem; }
.seg button {
  flex: 1; padding: .38rem; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-2); color: var(--text-dim); font-weight: 700; cursor: pointer;
  transition: .13s;
}
.seg button[data-on="1"].m { background: var(--male); color: #fff; border-color: transparent; }
.seg button[data-on="1"].f { background: var(--female); color: #fff; border-color: transparent; }
.modal-actions { display: flex; gap: .5rem; margin-top: 1.3rem; }
.modal-actions .spacer { margin-left: auto; }

/* ══ guide ═══════════════════════════════════════════════════════════════ */
.guide-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 1rem; align-items: start; }
/* The egg guide holds a pal list per size, so it gets the full width. */
.guide-card.wide { grid-column: 1 / -1; }
.guide-card { padding: var(--pad); }
.guide-card h2 { font-size: 1.05rem; margin-bottom: .7rem; color: var(--accent); }
.guide-card h3 { font-size: .85rem; margin: 1rem 0 .35rem; }
.guide-card p, .guide-card li { color: var(--text-dim); font-size: .87rem; }
.guide-card ul { padding-left: 1.15rem; margin: .4rem 0; }
.guide-card table { width: 100%; border-collapse: collapse; font-size: .83rem; margin-top: .45rem; }
.guide-card th { text-align: left; color: var(--text-faint); font-weight: 600; padding: .25rem .3rem; }
.guide-card td { padding: .25rem .3rem; border-top: 1px solid var(--line-soft); }
.guide-card .scroll { max-height: 430px; overflow-y: auto; }
.guide-card input { width: 100%; }
.rank-pill { font-size: .65rem; padding: .05rem .42rem; border-radius: 999px; font-weight: 800; color: var(--on-el); }
kbd {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 5px; padding: .05rem .35rem; font-size: .8rem;
  font-family: ui-monospace, Consolas, monospace;
}
code { font-family: ui-monospace, Consolas, monospace; font-size: .88em; }

/* ══ work suitability chips ══════════════════════════════════════════════ */
.works { display: inline-flex; flex-wrap: wrap; gap: .18rem; align-items: center; }
.work {
  display: inline-flex; align-items: center; gap: .1rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .05rem .3rem .05rem .12rem;
  font-size: .66rem;
  line-height: 1.3;
}
.work img { width: 14px; height: 14px; object-fit: contain; }
.work b { font-weight: 800; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.work.hit { background: color-mix(in srgb, var(--accent) 22%, var(--surface-2)); border-color: var(--accent); }
.work.hit b { color: var(--text); }
.work.more { padding: .05rem .32rem; color: var(--text-faint); font-weight: 700; }
.card .works { justify-content: flex-start; }

.owner-badge {
  font-size: .66rem; font-weight: 700;
  background: color-mix(in srgb, var(--accent-2) 18%, var(--surface-2));
  color: var(--text-dim);
  border: 1px solid color-mix(in srgb, var(--accent-2) 40%, transparent);
  border-radius: 999px; padding: .04rem .45rem;
}

.lvl-badge.own {
  background: color-mix(in srgb, var(--accent-2) 22%, var(--surface-2));
  color: var(--text);
  border: 1px solid color-mix(in srgb, var(--accent-2) 55%, transparent);
}

/* ══ ad slots ════════════════════════════════════════════════════════════ */
.ad-slot {
  display: block;
  margin: 1.6rem auto;
  max-width: 970px;
  text-align: center;
  /* No reserved height: an unfilled or blocked unit collapses instead of
     leaving a gap where content should be. */
}
.ad-label {
  display: block;
  font-size: .6rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--text-faint); margin-bottom: .3rem;
}
.ad-slot .adsbygoogle { min-height: 0; }
/* AdSense stamps data-ad-status on the <ins> once it has answered. No fill, no
   slot: without this the label still prints "ADVERTISEMENT" over an empty box.
   Browsers without :has() lose nothing — the slot has no reserved height. */
.ad-slot:has(.adsbygoogle[data-ad-status="unfilled"]) { display: none; }
.ad-placeholder {
  border: 1px dashed var(--line);
  border-radius: var(--r);
  padding: 1.6rem 1rem;
  color: var(--text-faint);
  background: color-mix(in srgb, var(--surface) 55%, transparent);
}
/* Never let an ad crowd the thing someone came to read. */
.drawer .ad-slot, .modal .ad-slot, .step .ad-slot, .trait-picker .ad-slot { display: none; }

/* ══ first run ═══════════════════════════════════════════════════════════ */
.welcome { max-width: 980px; margin: 1rem auto 0; text-align: center; }
.welcome h2 { font-size: 1.9rem; font-weight: 800; letter-spacing: -.02em; }
.welcome .lede {
  color: var(--text-dim); max-width: 62ch; margin: .6rem auto 1.8rem; font-size: 1rem;
}
.welcome-ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: .8rem; }
.way {
  display: flex; flex-direction: column; align-items: flex-start; gap: .35rem;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 1.1rem;
  cursor: pointer;
  color: inherit;
  font: inherit;
  transition: transform .14s cubic-bezier(.2,.7,.3,1), border-color .14s, box-shadow .14s;
}
.way:hover { transform: translateY(-3px); border-color: var(--accent); box-shadow: var(--shadow); }
.way.primary { border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); }
.way-icon {
  width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 10px; margin-bottom: .2rem;
  background: var(--surface-2); color: var(--accent); font-size: 1.05rem;
}
.way.primary .way-icon { background: var(--accent); color: var(--accent-ink); }
.way b { font-size: 1.02rem; }
.way span { color: var(--text-dim); font-size: .87rem; line-height: 1.45; }
.way i { color: var(--text-faint); font-size: .76rem; font-style: normal; margin-top: .15rem; }
/* The drag card is a sibling of the .way buttons but isn't one — it explains a
   gesture rather than taking a click, so it drops the lift and the pointer and
   wears the same dashed edge as the drop overlay it's describing. */
.way-drop { cursor: default; border-style: dashed; background: var(--surface-2); }
.way-drop:hover { transform: none; border-color: var(--line); box-shadow: none; }
.way-drop .way-icon { background: var(--surface); color: var(--accent); }
.way-steps { line-height: 1.7; }
.way-steps kbd { word-break: break-all; }
.way-acts { margin-top: auto; padding-top: .5rem; font-size: .82rem !important; }
.welcome-foot { color: var(--text-faint); font-size: .86rem; margin-top: 1.6rem; }

.linky {
  background: none; border: 0; padding: 0;
  color: var(--accent); font: inherit; font-weight: 600;
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.linky:hover { filter: brightness(1.15); }

/* ══ sync button + toasts ════════════════════════════════════════════════ */
#btnSync { display: inline-flex; align-items: center; gap: .35rem; }
#btnSync[disabled] { opacity: .75; cursor: default; }
#btnSync[disabled] .sync-icon { animation: spin .8s linear infinite; }
.sync-icon { display: inline-block; font-size: 1.05em; line-height: 1; }
@keyframes spin { to { transform: rotate(360deg); } }

.toast-wrap {
  position: fixed;
  right: 1.2rem; bottom: 1.2rem;
  z-index: 60;
  display: flex; flex-direction: column; gap: .5rem;
  align-items: flex-end;
  pointer-events: none;
}
.toast {
  background: var(--surface);
  color: var(--text);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  border-radius: var(--r);
  box-shadow: var(--shadow);
  padding: .75rem 1rem;
  max-width: 380px;
  font-size: .87rem;
  pointer-events: auto;
  animation: toast-in .22s cubic-bezier(.2,.7,.3,1);
}
.toast.good { border-color: color-mix(in srgb, var(--good) 45%, var(--line)); }
.toast.bad  { border-color: color-mix(in srgb, var(--bad) 45%, var(--line)); }
.toast b { display: block; margin-bottom: .15rem; }
.toast .detail { color: var(--text-faint); font-size: .78rem; white-space: pre-line; }
.toast .toast-act { margin-top: .55rem; }
.toast.leaving { animation: toast-out .2s ease forwards; }
@keyframes toast-in  { from { opacity: 0; transform: translateY(10px); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px); } }

/* ══ scrollbars ══════════════════════════════════════════════════════════ */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 6px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: content-box; }

/* ══ responsive ══════════════════════════════════════════════════════════
   The shell reflows off the tokens: the rail drops its labels and the
   masthead loses height before anything inside a tab has to change.       */
@media (max-width: 1080px) {
  :root { --gmin: 148px; --side: 64px; --label: none; --foot: none; --shell: 1rem; --mast-h: 320px; }
  .rail button[data-tab] { justify-content: center; padding: .6rem 0; }
  .rail .glyph { font-size: 1.05rem; }
  .brand { justify-content: center; padding: .55rem 0; }
  .brand-word { display: none; }
}
@media (max-width: 720px) {
  :root {
    --gmin: 126px; --gap: .5rem; --shell: .8rem;
    --ad-w: 320px; --ad-h: 100px;
    --mast-h: 250px; --field-h: 102px;
  }
  .util-right { flex-basis: 100%; margin-left: 0; justify-content: flex-end; }
  .mast-stats { gap: 1.1rem; margin-bottom: 1.4rem; }
  .mstat .mnum { font-size: 1.5rem; }
  .box-list { grid-template-columns: 1fr; }
  .combo-panels { grid-template-columns: 1fr; }
}
@media (max-width: 430px) {
  :root { --gmin: 106px; --mast-h: 228px; }
  .mast-sub { display: none; }
}

/* ══ nest mark / brand ══════════════════════════════════════════════════ */
.brand {
  display: flex; align-items: center; gap: .55rem;
  border: 0; background: none; cursor: pointer;
  padding: .35rem .55rem .8rem; margin-bottom: .3rem;
  border-bottom: 1px solid var(--line-soft);
  color: var(--text);
}
.brand-mark { width: 30px; height: 30px; flex: 0 0 auto; color: var(--text); }
.brand-mark.pop { animation: brandpop .3s cubic-bezier(.2, .7, .3, 1); }
@keyframes brandpop { from { transform: scale(.7); } }
.brand-word {
  font-family: var(--f-dis); font-weight: 700; letter-spacing: -.035em;
  font-size: 1.05rem; line-height: 1;
}
.brand-word b { color: var(--accent); font-weight: 700; }


/* ══ confirm modal ══════════════════════════════════════════════════════ */
.ask-modal { width: min(440px, calc(100% - 2rem)); }
.ask-body { color: var(--text-dim); font-size: .88rem; line-height: 1.55; margin-top: .5rem; }

/* ══ help / transfer / parse modals ═════════════════════════════════════ */
.html-modal { width: min(640px, calc(100% - 2rem)); }
.help-head { padding-top: 0; text-align: left; }
.help-head .close { position: static; margin-left: auto; }
.help-sec { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--line-soft); }
.help-sec h3 { font-size: .95rem; margin: 0 0 .4rem; color: var(--accent); }
.help-sec p, .help-sec li { color: var(--text-dim); font-size: .85rem; line-height: 1.55; }
.help-list { padding-left: 1.1rem; margin: .3rem 0; display: grid; gap: .3rem; }
.help-note { color: var(--text-faint); font-size: .78rem; }
.help-steps { padding-left: 1.2rem; margin: .5rem 0 .7rem; display: grid; gap: .45rem; }
.help-steps li { line-height: 1.6; }
.help-steps kbd { word-break: break-all; }
.help-btns { display: flex; gap: .45rem; margin-top: .6rem; flex-wrap: wrap; }
.path-list { display: grid; gap: .55rem; margin: .5rem 0; }
.path-list dt { font-weight: 700; font-size: .8rem; }
.path-list dd { margin: .15rem 0 0; }
.path-list code { display: inline-block; word-break: break-all; font-size: .74rem; }
.path-list dd span { display: block; color: var(--text-faint); font-size: .78rem; margin-top: .15rem; }

.sync-code {
  display: flex; gap: .4rem; justify-content: center; margin: 1rem 0 .6rem;
  flex-wrap: wrap;
}
.sync-code span {
  font-family: var(--num); font-size: 1.7rem; font-weight: 700;
  width: 2.2rem; height: 2.6rem; display: grid; place-items: center;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
/* The group separator in a 12-character backup code: a mark to read by, not a
   box, so it never looks like a character you are meant to type. */
.sync-code i {
  display: grid; place-items: center; width: .5rem; font-style: normal;
  color: var(--text-faint); font-size: 1.2rem;
}
/* Twelve characters plus separators will not sit on one line on a phone. */
@media (max-width: 30rem) {
  .sync-code { gap: .25rem; }
  .sync-code span { width: 1.7rem; height: 2.1rem; font-size: 1.25rem; }
}
.send-lede { color: var(--text-dim); font-size: .88rem; }

/* The database-backed extras on the route tab. Both are hidden unless the host
   has a database, so the row collapses to nothing on a plain static deploy. */
.route-extras {
  display: flex; align-items: center; gap: .75rem;
  margin: .2rem 0 .8rem; flex-wrap: wrap;
}
.community-line {
  flex: 1 1 22rem; margin: 0; font-size: .8rem; color: var(--text-dim);
  padding: .45rem .7rem; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.community-line b { color: var(--text); }
.share-url {
  margin: .8rem 0; padding: .5rem .6rem; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow-wrap: anywhere; font-size: .8rem;
}
.shared-steps { margin: .8rem 0; padding-left: 1.4rem; line-height: 1.9; }
.shared-steps .arrow, .shared-steps .plus { color: var(--text-faint); margin: 0 .15rem; }
#subForm { display: grid; gap: .6rem; margin: .8rem 0; }
#subForm textarea {
  width: 100%; font: inherit; padding: .5rem .6rem; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  resize: vertical;
}
.send-timer { text-align: center; font-family: var(--num); color: var(--text-faint); font-size: .8rem; }
.recv-form { display: flex; gap: .5rem; margin: .7rem 0; }
.recv-form input {
  flex: 1; font-family: var(--num); font-size: 1.2rem; letter-spacing: .35em;
  text-transform: uppercase; text-align: center;
}
.form-err {
  color: var(--danger, #cf5340); font-size: .8rem; font-weight: 600;
  margin: .2rem 0 .5rem;
}

/* parse card */
.parse-card { width: min(480px, calc(100% - 2rem)); }
.parse-head { display: flex; align-items: center; gap: .8rem; }
.parse-head b { display: block; font-family: var(--f-dis); font-size: 1.1rem; }
.parse-file { font-family: var(--num); font-size: .75rem; color: var(--text-faint); }
.parse-spin { display: inline-block; font-size: 1.5rem; color: var(--accent); animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.parse-bar {
  position: relative; height: 6px; border-radius: 4px;
  background: var(--surface-3); overflow: hidden; margin: 1.1rem 0 1rem;
}
.parse-bar i {
  position: absolute; inset: 0; width: 30%; border-radius: 4px;
  background: linear-gradient(90deg, var(--accent-2), var(--accent));
  animation: sweep 1.4s cubic-bezier(.5, 0, .5, 1) infinite;
}
@keyframes sweep { 0% { left: -30%; } 100% { left: 100%; } }
.parse-steps { display: flex; flex-direction: column; gap: .55rem; font-size: .84rem; }
.parse-steps .dot { display: inline-block; width: 1.2em; color: var(--text-faint); }
.parse-steps div { color: var(--text-faint); }
.parse-steps div.now { color: var(--text); font-weight: 600; }
.parse-steps div.now .dot { color: var(--accent); }
.parse-steps div.done { color: var(--dim, var(--text-dim)); }
.parse-steps div.done .dot { color: var(--good); }
.parse-steps .pct { margin-left: auto; font-family: var(--num); color: var(--text-faint); font-weight: 400; }
.parse-note {
  margin: 1.1rem 0 0; padding-top: .8rem; border-top: 1px solid var(--line-soft);
  color: var(--text-faint); font-size: .78rem; line-height: 1.5;
}

/* ══ redesigned edit modal ══════════════════════════════════════════════ */
#editModal { padding: 0; }
.edit-band {
  position: relative; height: 96px;
  background: var(--surface-3);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.edit-band::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 92%, rgba(255,255,255,.35), transparent 66%);
  border-radius: inherit;
}
.edit-band .close { position: absolute; top: .6rem; right: .8rem; margin: 0; color: rgba(255,255,255,.85); text-shadow: 0 1px 4px rgba(0,0,0,.4); }
.edit-band .close:hover { color: #fff; }
.edit-band .portrait {
  position: absolute; left: 1.2rem; bottom: -44px;
  width: 96px; height: 96px;
  box-shadow: 0 8px 22px rgba(0,0,0,.3);
}
.edit-body { padding: 3.4rem 1.4rem 1.4rem; }
.edit-title { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.edit-title h2 { margin: 0; }
.edit-el { display: inline-flex; gap: .3rem; }
.form-cap {
  display: block; font-size: .65rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-faint); font-weight: 700; margin-bottom: .3rem;
}
.form-cap i { text-transform: none; letter-spacing: 0; font-style: normal; font-weight: 500; }
.passive-row { display: flex; align-items: center; gap: .45rem; margin-bottom: .4rem; }
.passive-row input { flex: 1; }
.passive-row .rank-pill { flex: 0 0 auto; }
.iv-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem; }
.iv-cell { display: flex; flex-direction: column; gap: .25rem; }
.iv-cell b { font-size: .7rem; color: var(--text-faint); text-transform: uppercase; letter-spacing: .06em; }
.iv-cell .track { height: 5px; background: var(--surface-3); border-radius: 3px; overflow: hidden; }
.iv-cell .track i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-2), var(--accent)); }

/* ══ footer ════════════════════════════════════════════════════════════ */
.site-foot {
  padding: 1.1rem var(--shell) 1.6rem;
  border-top: 1px solid var(--line-soft);
  margin-top: 1.5rem;
}
.foot-legal { color: var(--text-faint); font-size: .74rem; line-height: 1.6; margin: 0; max-width: 78ch; }
.foot-links { color: var(--text-faint); font-size: .78rem; margin: .5rem 0 0; }
.foot-links a { color: inherit; text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--line); }
.foot-links a:hover { color: var(--text); text-decoration-color: currentColor; }

/* ══ standalone pages (privacy, terms, contact) ═════════════════════════
   These ship without the app shell — no rail, no paldata, no app.js — but
   they wear the masthead scene so they read as part of the site rather than
   a legal document parked on the same domain. legal.js only carries the
   theme across. */
.legal-page .col { max-width: none; }
.legal-mast { min-height: auto; justify-content: flex-end; }
.legal-head { position: relative; z-index: 1; padding: 1.5rem var(--shell) 1.3rem; }
.legal-back {
  display: inline-block; margin-bottom: .55rem;
  color: var(--band-fg); opacity: .85; text-decoration: none;
  font: 600 .78rem/1 var(--f-body);
}
.legal-back:hover { opacity: 1; text-decoration: underline; }
.legal-head h1 {
  margin: 0; color: var(--band-fg);
  font: var(--dis-w) clamp(1.7rem, 4vw, 2.4rem)/1.05 var(--f-dis); letter-spacing: var(--dis-ls);
}
.legal-date { margin: .35rem 0 0; color: var(--band-fg); opacity: .78; font-size: .78rem; }

.legal { padding: 1.6rem var(--shell) 0; max-width: 74ch; }
.legal h2 {
  margin: 2rem 0 .55rem;
  font: var(--dis-w) 1.12rem/1.2 var(--f-dis); letter-spacing: var(--dis-ls); color: var(--text);
}
.legal h3 { margin: 1.4rem 0 .4rem; font: 700 .92rem/1.3 var(--f-body); color: var(--text); }
.legal p, .legal li, .legal dd { color: var(--text-dim); font-size: .89rem; line-height: 1.72; }
.legal p { margin: 0 0 .8rem; }
.legal ul, .legal ol { margin: 0 0 .9rem; padding-left: 1.15rem; }
.legal li { margin-bottom: .38rem; }
.legal a { color: var(--accent); text-underline-offset: 2px; }
.legal b { color: var(--text); }
.legal code { font: 600 .84em/1 var(--num); background: var(--surface-2); padding: .12rem .3rem; border-radius: 5px; }
.legal section:first-of-type h2 { margin-top: 1.4rem; }

/* the lede card: the honest answer, before the paragraphs that qualify it */
.legal-tldr { padding: 1rem 1.1rem .85rem; border-left: 3px solid var(--accent); }
.legal-tldr h2 { margin: 0 0 .5rem; font-size: 1rem; }
.legal-tldr p:last-child { margin-bottom: 0; }
.legal-tldr .btn { margin-top: .3rem; }

.legal-dl { margin: 0; }
.legal-dl dt { margin-top: 1rem; font: 700 .89rem/1.4 var(--f-body); color: var(--text); }
.legal-dl dd { margin: .2rem 0 0; }

/* ══ saved breeding goals ═══════════════════════════════════════════════
   A goal is a destination, so it gets the same treatment as one on the map:
   the pal standing on a field of its own element colours, and the live
   distance underneath. A row of these should read as "here's what I'm
   chasing", never as a list of saved queries. */
.goal-strip { margin: .2rem 0 1rem; }
.goal-head { display: flex; align-items: baseline; gap: .5rem; margin-bottom: .45rem; }
.goal-note { font: 600 .66rem/1 var(--f-body); color: var(--text-faint); }
.goal-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); gap: .55rem; }

.goal-card {
  position: relative;
  border: var(--card-bd); border-radius: var(--r-card);
  background: var(--surface); overflow: hidden;
  transition: border-color .14s, transform .14s;
}
.goal-card:hover { transform: translateY(-2px); border-color: var(--faint); }
.goal-card.on { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.goal-card.done { opacity: .72; }
.goal-card.done:hover { opacity: 1; }

.goal-open {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  padding: 0 .6rem 0 0; border: 0; background: none; cursor: pointer; text-align: left;
}
/* the field: the same painted scene the masthead and the map cards use */
.goal-field {
  position: relative; width: 78px; height: 76px; flex: 0 0 auto;
  background: var(--gf); overflow: hidden;
  display: grid; place-items: center;
}
.goal-field .hill {
  position: absolute; left: -20%; right: -20%; bottom: -46%;
  height: 78%; border-radius: 50% 50% 0 0; background: rgba(0,0,0,.16);
}
.goal-field .hill.h2 { bottom: -54%; background: rgba(0,0,0,.1); }
.goal-field .portrait {
  position: relative; z-index: 1; background: none; border: 0;
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.4));
}
.goal-body { display: grid; gap: .16rem; min-width: 0; padding: .5rem 0; }
.goal-name {
  font: var(--dis-w) .92rem/1.15 var(--f-dis); letter-spacing: var(--dis-ls); color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.goal-state { font: 600 .68rem/1 var(--num); color: var(--accent); }
.goal-state.ok { color: var(--good); }
.goal-traits { display: flex; flex-wrap: wrap; gap: .2rem; margin-top: .1rem; }
.goal-traits i {
  font-style: normal; font: 600 .58rem/1 var(--f-body);
  padding: .18rem .32rem; border-radius: 5px;
  background: var(--surface-2); color: var(--text-dim);
  max-width: 9ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.goal-traits.none { font: 600 .6rem/1 var(--f-body); color: var(--text-faint); }
.goal-drop {
  position: absolute; top: .3rem; right: .3rem;
  width: 20px; height: 20px; border-radius: 50%;
  border: 0; background: rgba(0,0,0,.32); color: #fff;
  font: 700 .8rem/1 var(--f-body); cursor: pointer;
  opacity: 0; transition: opacity .14s, background .14s;
}
.goal-card:hover .goal-drop, .goal-drop:focus-visible { opacity: 1; }
.goal-drop:hover { background: var(--bad); }

#btnSaveGoal.on { border-color: var(--accent); color: var(--accent); }

/* ══ shared boxes and pals ══════════════════════════════════════════════ */
.share-what { margin: .2rem 0 .9rem; padding-left: 1.1rem; }
.share-what li { font-size: .82rem; line-height: 1.6; color: var(--text-dim); margin-bottom: .2rem; }

/* The read-only banner is not decoration — it is the answer to "can they
   edit my box?", so it sits above the pals and looks like a notice. */
.shared-ro {
  margin: 0 0 .8rem; padding: .55rem .7rem;
  border-radius: 10px;
  background: color-mix(in srgb, var(--good) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--good) 30%, transparent);
  font-size: .8rem; line-height: 1.55; color: var(--text-dim);
}
.shared-list { max-height: 56vh; overflow-y: auto; }
/* no Edit / ✕ column: a shared row has no actions at all */
.box-row.shared { cursor: default; }

/* ══ in-feed ad tiles ═══════════════════════════════════════════════════ */
.ad-slot.ad-in-grid {
  border-radius: var(--r-card);
  display: flex; align-items: center; justify-content: center;
}
/* The card framing lands only once an ad has actually filled the tile (and in
   dev, on the placeholder). Reserving 190px unconditionally is what leaves a
   dashed hole mid-grid when a unit comes back empty or gets blocked. */
.ad-slot.ad-in-grid:has(.adsbygoogle[data-ad-status="filled"]),
.ad-slot.ad-in-grid.ad-placeholder {
  border: 1px dashed var(--line);
  background: var(--surface);
  min-height: 190px;
}
.ad-slot.ad-in-list { margin: .6rem 0; }
.ad-slot .ad-label {
  position: static; display: block; text-align: center;
  font-size: .62rem; text-transform: uppercase; letter-spacing: .14em;
  color: var(--text-faint); padding: .5rem;
}
.ad-slot { position: relative; }
.ad-slot:not(.ad-in-grid):not(.ad-in-list) .ad-label { position: absolute; top: 2px; left: 4px; padding: 0; }

/* ══ egg field guide ════════════════════════════════════════════════════ */
.egg-guide { display: grid; gap: 0; margin-top: .7rem; border-top: 1px solid var(--line-soft); }
.egg-acc { border-bottom: 1px solid var(--line-soft); }
.egg-acc summary {
  display: flex; align-items: center; gap: .55rem;
  padding: .45rem .2rem; cursor: pointer; list-style: none;
}
.egg-acc summary::-webkit-details-marker { display: none; }
.egg-acc summary::after {
  content: "▸"; margin-left: auto; color: var(--text-faint);
  transition: transform .15s;
}
.egg-acc[open] summary::after { transform: rotate(90deg); }
.egg-acc summary:hover b { color: var(--accent); }
.egg-ico { width: 30px; height: 30px; flex: 0 0 auto; color: var(--text); }
.egg-acc summary b { font-size: .85rem; }
.egg-count { font-family: var(--num); font-size: .72rem; color: var(--text-faint); }
.egg-body { min-width: 0; padding: .1rem .2rem .55rem 2.35rem; }
.egg-where { display: block; color: var(--text-faint); font-size: .76rem; font-style: italic; margin: 0 0 .3rem; }
.egg-tier { padding: .5rem 0 .3rem; border-top: 1px solid var(--line-soft); }
.egg-tier-head {
  display: flex; align-items: baseline; gap: .5rem;
  font-size: .78rem; margin-bottom: .35rem;
}
.egg-tier-head b { color: var(--text-dim); }
.egg-tier-head span { color: var(--text-faint); font-family: var(--num); font-size: .72rem; }

.egg-pals {
  display: grid; gap: .25rem;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
}
.egg-pal {
  display: flex; align-items: center; gap: .45rem; min-width: 0;
  padding: .22rem .35rem;
  border: 1px solid transparent; border-radius: 10px;
  background: transparent; color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
  transition: background .12s, border-color .12s;
}
.egg-pal:hover { background: var(--surface-2); border-color: var(--line); }
.egg-pal .portrait { flex: 0 0 auto; }
.egg-pal > span { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.egg-pal b { font-size: .78rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.egg-pal i { font-style: normal; font-family: var(--num); font-size: .68rem; color: var(--text-faint); }

/* ══ form + dropdown polish ═════════════════════════════════════════════ */
.filters select, .filters input[type="search"],
.form-grid input, .form-grid select, .form-full input,
.recv-form input, .guide-card input {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  padding: .44rem .65rem;
  font: inherit;
  font-size: .82rem;
  transition: border-color .12s, box-shadow .12s;
}
.filters select, .form-grid select, .util-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 1.7rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23908a7c' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .6rem center;
  cursor: pointer;
}
.filters select:hover, .filters input[type="search"]:hover,
.form-grid input:hover { border-color: var(--text-faint); }
.filters select:focus-visible, .filters input:focus-visible,
.form-grid input:focus-visible, .form-full input:focus-visible,
.recv-form input:focus-visible, .util-select:focus-visible, .guide-card input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.filters select option { background: var(--surface); color: var(--text); }

/* header profile picker */
.util-select {
  border: 1px solid var(--band-line);
  background-color: transparent;
  color: var(--band-dim);
  border-radius: var(--r-pill);
  font-size: .78rem;
  font-weight: 600;
  padding: .14rem 1.6rem .14rem .7rem;
  max-width: 230px;
  background-position: right .55rem center;
}
.util-select:hover { color: var(--band-fg); border-color: var(--band-fg); }
.util-select option { background: var(--surface); color: var(--text); font-weight: 500; }

/* ══ util bar controls ══════════════════════════════════════════════════
   Theme picker, the collection buttons and Sync all sit on the masthead
   band, so they share one height, one radius and the --band-* palette. */
:root { --util-h: 28px; }

.dot {
  width: 12px; height: 12px; flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--band-fg) 32%, transparent);
}
.dot[data-swatch="daylight"]  { background: #f4f1ea; }
.dot[data-swatch="nightfall"] { background: #0e131c; }
.dot[data-swatch="ember"]     { background: #161009; }
.dot[data-swatch="auto"]      { background: conic-gradient(#f4f1ea 0 40%, #161009 40% 70%, #0e131c 70% 100%); }

/* theme picker: the shared .dd dropdown, dressed for the masthead band */
.dd-theme .dd-btn {
  height: var(--util-h); padding: 0 .6rem 0 .5rem; gap: .45rem;
  border-color: var(--band-line); border-radius: var(--r-pill);
  background: transparent; color: var(--band-dim);
  font-size: .78rem;
}
.dd-theme .dd-btn:hover, .dd-theme .dd-btn[aria-expanded="true"] {
  color: var(--band-fg); border-color: var(--band-fg);
}
.dd-theme .dd-btn .car { color: inherit; }
.dd-theme .dd-panel { left: auto; right: 0; min-width: 232px; }
/* Two lines per row here, so the tick has to sit against the top line. */
.dd-theme .dd-item { align-items: flex-start; }
.dd-theme .dd-name { display: flex; flex-direction: column; gap: .05rem; }
/* --text-faint lands around 3.6:1 here, short of AA for 11px text, so the
   description line uses --text-dim in every state. */
.dd-theme .dd-name small { font-size: .7rem; font-weight: 500; color: var(--text-dim); }

/* The button sits mid-row on a phone, so a right-anchored menu would hang off
   the left edge. Pin it to the viewport instead. */
@media (max-width: 430px) {
  .dd-theme { position: static; }
  .dd-theme .dd-panel { right: var(--shell); left: var(--shell); min-width: 0; }
}

/* Collection buttons. Each group is welded into one control, and the groups
   sit closer to each other than to the theme picker and Sync either side, so
   they read as three related actions rather than five loose ones. */
.util-groups { display: inline-flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.util-set-solo .util-set-btn { padding-inline: .8rem; }
.util-set {
  display: inline-flex; align-items: stretch; height: var(--util-h);
  border: 1px solid var(--band-line); border-radius: var(--r-pill);
  overflow: hidden;
}
.util-set-btn {
  display: inline-flex; align-items: center;
  padding: 0 .72rem;
  border: 0; background: transparent; color: var(--band-dim);
  font: inherit; font-size: .78rem; font-weight: 600; white-space: nowrap; cursor: pointer;
  transition: background .13s, color .13s;
}
.util-set-btn:not([hidden]) + .util-set-btn:not([hidden]) {
  box-shadow: inset 1px 0 0 var(--band-line);
}
.util-set-btn:hover { background: color-mix(in srgb, var(--band-fg) 12%, transparent); color: var(--band-fg); }
.util-set-btn.danger:hover { background: color-mix(in srgb, var(--bad) 22%, transparent); color: var(--band-fg); }
.util-set-btn:focus-visible { outline: 2px solid var(--band-fg); outline-offset: -2px; }

.util-sync { height: var(--util-h); padding-inline: .95rem; }

/* ══ centred footer ═════════════════════════════════════════════════════ */
.site-foot { text-align: center; }
.foot-legal { margin-inline: auto; }

/* The ad consent bar used to live here. Consent is served by Google's own
   certified CMP from the AdSense account instead, so the app has no bar of
   its own to style. */

/* ══ controls: one shape for every field ════════════════════════════════
   Text fields, number fields and the .dd buttons are the same height, the
   same radius and the same border, so a filter row reads as one row of
   controls rather than a pile of browser defaults. --ctl-h is the contract;
   change it here and everything follows. */
:root {
  --ctl-h: 34px;
  --ctl-r: 10px;
}

.filters input[type=search], .filters input[type=text], .filters input[type=number],
.form-grid input, .form-full input, .guide-card input, .recv-form input,
.dd-btn, .dd-search {
  height: var(--ctl-h);
  border-radius: var(--ctl-r);
  font-size: .84rem;
}
.dd-btn { padding-block: 0; }
.util-set { border-radius: var(--r-pill); }
/* A button standing in a filter row is one of the controls, not a visitor. */
.filters .btn, .trait-picker-body .btn { height: var(--ctl-h); border-radius: var(--ctl-r); padding-block: 0; }
/* The gender toggle is a field like the ones above and below it. */
#eGender button { height: var(--ctl-h); border-radius: var(--ctl-r); padding-block: 0; }

/* Idle fields sit back; hovering one shows it is live before you commit a
   click, which the old flat borders never did. */
.filters input, .form-grid input, .form-full input, .guide-card input, .recv-form input {
  background: var(--surface-2);
  border: 1px solid var(--line);
  transition: border-color .13s, background .13s, box-shadow .13s;
}
.filters input:hover, .form-grid input:hover, .form-full input:hover,
.guide-card input:hover, .recv-form input:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
}
.filters input:focus, .form-grid input:focus, .form-full input:focus,
.guide-card input:focus, .recv-form input:focus,
.dd-btn:focus-visible, .inline-check input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
::placeholder { color: var(--text-faint); opacity: 1; }

/* A magnifier on the fields that are genuinely searches. Deliberately not on
   the narrow passive slots or the transfer-code box, where the glyph would
   crowd the value. */
.filters input[type=search]:not(.dd-search),
.guide-card input[type=search] {
  padding-left: 2rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23948b7c' stroke-width='1.6'%3E%3Ccircle cx='7' cy='7' r='4.4'/%3E%3Cpath d='M10.4 10.4 14 14' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left .62rem center;
  background-size: 14px 14px;
}
/* The native clear cross is a tiny grey X that vanishes on dark themes. */
input[type=search]::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; cursor: pointer;
  background: currentColor;
  opacity: .35;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
}
input[type=search]::-webkit-search-cancel-button:hover { opacity: .8; }

/* Spinners only appear on hover, so a level field reads as a number rather
   than as a widget. */
input[type=number] { -moz-appearance: textfield; }
input[type=number]::-webkit-inner-spin-button { opacity: 0; transition: opacity .13s; }
input[type=number]:hover::-webkit-inner-spin-button,
input[type=number]:focus::-webkit-inner-spin-button { opacity: 1; }

/* Checkboxes: the label is the hit target, and the whole thing lights up. */
.inline-check {
  padding: 0 .55rem; height: var(--ctl-h);
  border: 1px solid transparent; border-radius: var(--ctl-r);
  transition: background .13s, border-color .13s;
}
.inline-check:hover { background: var(--surface-2); border-color: var(--line); }

/* ══ scrollbars ═════════════════════════════════════════════════════════
   Themed rather than left to the OS, so a dark theme doesn't get a bright
   grey bar down the side of every panel. */
* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--text) 22%, transparent) transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text) 22%, transparent);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--text) 38%, transparent); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* Scrollable panels fade at the clipped edge, so a cut-off list looks cut off
   rather than finished. The two solid layers scroll with the content and mask
   the two shadow layers when there is nothing to scroll, which is what makes
   the fades appear and disappear on their own.

   Only for scrollers whose parent is --surface: the covers are painted in that
   colour, so a scroller sitting on the page background (.route-out) would get
   two permanent bands instead of nothing. */
.scroll, .combo-out, .dd-panel {
  background-image:
    linear-gradient(var(--surface) 30%, transparent),
    linear-gradient(transparent, var(--surface) 70%),
    linear-gradient(color-mix(in srgb, var(--text) 13%, transparent), transparent),
    linear-gradient(transparent, color-mix(in srgb, var(--text) 13%, transparent));
  background-position: 0 0, 0 100%, 0 0, 0 100%;
  background-repeat: no-repeat;
  background-size: 100% 34px, 100% 34px, 100% 11px, 100% 11px;
  background-attachment: local, local, scroll, scroll;
}

/* ══ world map — the Field Guide ═════════════════════════════════════════
   Left pane: player goals + destination cards, each a miniature masthead
   scene (the site's own --sky/--hill tokens) with the region's resident
   pals standing on it. Right: the canvas stage — atlas choropleth at rest,
   real markers inside an opened place. The stage stays dark in every theme
   because the tiles are dark aerial game art; the pane follows the theme
   like any other card. Canvas-side colours are read from the CSS vars
   below via getComputedStyle, so themes can restyle the map itself. */
#tab-map {
  --map-sea: #0a2836;
  --map-area: #f0d9a0;
  --map-site: #c3cbd8;
  --map-pin: #f4b740;
  --glass: rgba(14, 18, 26, .82);
  --glass-line: rgba(255, 255, 255, .1);
}
[data-theme="daylight"] #tab-map { --glass: rgba(255, 253, 248, .93); --glass-line: rgba(27, 24, 20, .14); }

.mapg-shell { display: flex; gap: var(--gap); align-items: stretch; height: min(82vh, 980px); min-height: 520px; }
.mapg-pane {
  flex: 0 0 400px; min-width: 0; display: flex; flex-direction: column; min-height: 0;
  background: var(--card-bg); border: var(--card-bd); border-radius: var(--r-card);
  box-shadow: var(--card-sh); overflow: hidden;
}
.mapg-stage {
  position: relative; flex: 1; min-width: 0; overflow: hidden;
  background: #050508; border-radius: var(--r-card); border: var(--card-bd);
}
.mapg-stage canvas { display: block; touch-action: none; cursor: grab; }
.mapg-stage canvas:active { cursor: grabbing; }
.map-credit { margin: .55rem .2rem 0; font-size: .72rem; color: var(--faint); }

/* ── pane hero: the guide wears the site's sky ─────────────────────────── */
.mapg-hero {
  position: relative; overflow: hidden; flex: 0 0 auto;
  background: linear-gradient(180deg, var(--sky-b), var(--sky-a));
  color: var(--band-fg);
  padding: .85rem .95rem 2.3rem;
}
.mapg-hero .stars {
  position: absolute; inset: 0; opacity: var(--stars); pointer-events: none;
  background-image:
    radial-gradient(1.6px 1.6px at 12% 22%, rgba(255,255,255,.95), transparent 55%),
    radial-gradient(1.2px 1.2px at 30% 48%, rgba(255,255,255,.8), transparent 55%),
    radial-gradient(1.7px 1.7px at 52% 14%, rgba(255,255,255,.9), transparent 55%),
    radial-gradient(1.1px 1.1px at 71% 38%, rgba(255,255,255,.7), transparent 55%),
    radial-gradient(1.5px 1.5px at 88% 18%, rgba(255,255,255,.85), transparent 55%);
}
.mapg-hero .orb {
  position: absolute; right: 12%; top: 18%; width: 30px; height: 30px;
  border-radius: 50%; background: var(--orb); box-shadow: 0 0 36px 14px var(--orb-glow);
}
.mapg-hero .hill { position: absolute; border-radius: 50%; pointer-events: none; }
.mapg-hero .h1 { left: -45%; bottom: -58%; width: 190%; height: 68%; background: var(--hill-1); }
.mapg-hero .h2 { left: -20%; bottom: -66%; width: 190%; height: 70%; background: var(--hill-2); }
.mapg-hero .h3 { left: -60%; bottom: -74%; width: 220%; height: 74%; background: var(--hill-3); }
.mapg-hero .pals { position: absolute; right: 5%; bottom: 2%; display: flex; align-items: flex-end; gap: 2px; z-index: 1; }
.mapg-hero .pals img { width: 38px; height: 38px; object-fit: contain; filter: drop-shadow(0 2px 3px rgba(0,0,0,.4)); }
.mapg-hero h2 {
  position: relative; z-index: 2; margin: 0;
  font: var(--dis-w) 1.4rem/1 var(--f-dis); letter-spacing: var(--dis-ls);
}
.mapg-hero .sub { position: relative; z-index: 2; margin: .28rem 0 0; font: 600 .72rem/1.4 var(--f-body); color: var(--band-dim); }

/* goal pills ride the hero's bottom edge */
.mapg-goals {
  position: relative; z-index: 3; display: flex; flex-wrap: wrap; gap: .28rem;
  padding: 0 .9rem; margin-top: -1.05rem;
}
.mapg-goal {
  display: inline-flex; align-items: center; gap: .34rem;
  padding: .36rem .6rem .36rem .4rem; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--surface); color: var(--dim);
  font: 700 .7rem/1 var(--f-body);
  box-shadow: var(--shadow-sm);
  transition: transform .13s, border-color .13s, color .13s;
}
.mapg-goal:hover { transform: translateY(-1px); border-color: var(--faint); color: var(--text); }
.mapg-goal.on { background: var(--accent); border-color: transparent; color: var(--accent-ink); }
.mapg-goal .gp {
  width: 19px; height: 19px; border-radius: 50%; background: var(--art);
  display: grid; place-items: center; overflow: hidden; flex: 0 0 auto;
}
.mapg-goal .gp img { width: 88%; height: 88%; object-fit: contain; }
.mapg-goal.on .gp { background: color-mix(in srgb, var(--accent-ink) 18%, transparent); }

/* goal-specific controls */
.mapg-subctl { padding: .55rem .9rem .15rem; flex: 0 0 auto; }
.mapg-subctl:empty { display: none; }
.mapg-searchwrap { position: relative; }
.mapg-hits {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 3px);
  background: var(--surface); border: var(--card-bd); border-radius: var(--r-chip);
  box-shadow: var(--sh); overflow: hidden;
}
.mapg-hits:empty { display: none; }
.mapg-hits button {
  display: flex; align-items: center; gap: .5rem; width: 100%;
  border: 0; background: none; cursor: pointer; text-align: left;
  padding: .4rem .55rem; color: var(--text); font: 500 .78rem/1 var(--f-body);
}
.mapg-hits button:hover, .mapg-hits button.sel { background: var(--surface-2); }
.mapg-hits img { width: 22px; height: 22px; border-radius: 50%; background: var(--art); }
.mapg-hits .elx { margin-left: auto; font-size: .66rem; color: var(--faint); }
.mapg-suggest { display: flex; gap: .45rem; flex-wrap: wrap; margin: .4rem 0 .1rem; }
.mapg-suggest button {
  border: 0; background: none; cursor: pointer; padding: 0;
  display: grid; justify-items: center; gap: .16rem;
  font: 600 .6rem/1 var(--f-body); color: var(--dim);
}
.mapg-suggest .portrait { transition: transform .15s cubic-bezier(.2,.7,.3,1); }
.mapg-suggest button:hover .portrait { transform: scale(1.08); }
/* the dex lens: a pill switch in the same family as the goal pills, with a
   radio-dot that fills accent when the lens is on.

   `.lens-check` is the same switch wrapping a real <input type=checkbox> —
   used by the filter bars on My Pals and Breed to…, so a boolean filter reads
   the same everywhere instead of a native tickbox on one screen and a pill on
   another. The map's version is a <button role=switch> and carries `.on`; the
   form version reads the input, hence the doubled selectors. */
.mapg-lens, .lens-check {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .34rem .68rem .34rem .42rem;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--dim);
  font: 600 .7rem/1 var(--f-body); cursor: pointer;
  transition: border-color .13s, color .13s, transform .13s, background .13s;
}
.mapg-lens { margin-top: .5rem; }
/* the filter bars are a row of --ctl-h controls; the pill has to sit on that line */
.lens-check { height: var(--ctl-h); }
/* the checkbox itself is replaced by .tick, but it stays in the DOM (and
   focusable) so the label, keyboard and form semantics all still work */
.lens-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.mapg-lens:hover, .lens-check:hover { color: var(--text); border-color: var(--faint); transform: translateY(-1px); }
.lens-check:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.mapg-lens .tick, .lens-check .tick {
  width: 15px; height: 15px; border-radius: 50%; flex: 0 0 auto;
  border: 1.5px solid var(--faint); display: grid; place-items: center;
  transition: border-color .13s;
}
.mapg-lens .tick::after, .lens-check .tick::after {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: transparent; transition: background .13s, transform .13s;
  transform: scale(.6);
}
.mapg-lens.on, .lens-check:has(input:checked) { background: var(--accent-soft); border-color: var(--accent); color: var(--text); }
.mapg-lens.on .tick, .lens-check:has(input:checked) .tick { border-color: var(--accent); }
.mapg-lens.on .tick::after,
.lens-check:has(input:checked) .tick::after { background: var(--accent); transform: scale(1); }
.mapg-lens .ct, .lens-check .ct { font: 600 .62rem/1 var(--num); color: var(--faint); font-variant-numeric: tabular-nums; }
.mapg-lens.on .ct, .lens-check:has(input:checked) .ct { color: var(--dim); }
.lens-check .ct:empty { display: none; }
.mapg-tags { display: flex; flex-wrap: wrap; gap: .25rem; }
.mapg-tag {
  padding: .28rem .52rem; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--dim); font: 600 .68rem/1 var(--f-body);
}
.mapg-tag:hover { color: var(--text); border-color: var(--faint); }
.mapg-tag.on { background: var(--accent); border-color: transparent; color: var(--accent-ink); }

/* ── the guide: destination cards ──────────────────────────────────────── */
.mapg-guide { flex: 1; min-height: 0; overflow-y: auto; padding: .5rem .7rem .9rem; }
.mapg-guide::-webkit-scrollbar, .mapg-drill::-webkit-scrollbar { width: 9px; }
.mapg-guide::-webkit-scrollbar-thumb, .mapg-drill::-webkit-scrollbar-thumb { background: var(--line); border-radius: 9px; }
.mapg-count { margin: .1rem .15rem .45rem; font: 600 .68rem/1.3 var(--f-body); color: var(--faint); }
.mapg-count:empty { display: none; }
.mapg-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }

.mapg-card { cursor: pointer; text-align: left; padding: 0; border: var(--card-bd); }
/* danger lives in the sky: the level colour mixes into the horizon itself */
.mapg-field {
  position: relative; height: 72px; overflow: hidden;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--zt) 14%, var(--sky-b)),
    color-mix(in srgb, var(--zt) 44%, var(--sky-a)));
}
.mapg-field .hill { position: absolute; border-radius: 50%; }
.mapg-field .h1 { left: -40%; bottom: -52%; width: 180%; height: 75%; background: var(--hill-1); }
.mapg-field .h2 { left: -15%; bottom: -62%; width: 180%; height: 78%; background: color-mix(in srgb, var(--zt) 16%, var(--hill-2)); }
.mapg-field .sun { position: absolute; inset: 0; background: radial-gradient(circle at 50% 74%, rgba(255,255,255,.3), transparent 62%); }
.mapg-card.tree .mapg-field {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent-2) 28%, var(--sky-b)),
    color-mix(in srgb, var(--accent-2) 46%, var(--sky-a)));
}
.mapg-rank {
  position: absolute; top: 5px; left: 7px; z-index: 2;
  font: 700 .58rem/1 var(--num); color: rgba(255,255,255,.92);
  background: rgba(8,10,14,.5); backdrop-filter: blur(3px);
  border-radius: var(--r-pill); padding: .15rem .4rem;
}
.mapg-rank.gold { background: var(--accent); color: var(--accent-ink); }
.mapg-lvchip {
  position: absolute; top: 5px; right: 7px; z-index: 2;
  display: inline-flex; align-items: center; gap: .26rem;
  font: 700 .58rem/1 var(--num); color: rgba(255,255,255,.94);
  background: rgba(8,10,14,.5); backdrop-filter: blur(3px);
  border-radius: var(--r-pill); padding: .15rem .4rem;
}
.mapg-lvchip i { width: 7px; height: 7px; border-radius: 50%; }
/* residents stand ON the field, like the masthead's scene-pals */
.mapg-residents { position: absolute; left: 7px; bottom: -1px; display: flex; align-items: flex-end; z-index: 1; }
.mapg-residents img {
  width: 42px; height: 42px; object-fit: contain;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.45));
  margin-left: -10px;
}
.mapg-residents img:first-child { margin-left: 0; }
.mapg-cbody { padding: .45rem .55rem .5rem; }
.mapg-cbody .nm { font: var(--dis-w) .82rem/1.15 var(--f-dis); letter-spacing: var(--dis-ls); color: var(--text); }
.mapg-cbody .st { margin-top: .2rem; font: 600 .66rem/1.3 var(--f-body); color: var(--dim); display: flex; align-items: baseline; gap: .28rem; flex-wrap: wrap; }
.mapg-cbody .st b { font: 700 .78rem/1 var(--num); color: var(--text); font-variant-numeric: tabular-nums; }
.mapg-card.hot { border-color: var(--accent); transform: translateY(-3px); box-shadow: var(--shadow); }

/* pal dossier (Find pals) */
.mapg-dossier {
  display: flex; gap: .65rem; align-items: center;
  margin: 0 0 .5rem; padding: .55rem .6rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-card);
}
.mapg-dossier .info { flex: 1; min-width: 0; }
.mapg-dossier h3 { margin: 0; font: var(--dis-w) 1rem/1.1 var(--f-dis); letter-spacing: var(--dis-ls); color: var(--text); }
.mapg-dossier .facts { margin-top: .28rem; display: flex; flex-wrap: wrap; gap: .22rem .5rem; font: 600 .66rem/1.4 var(--f-body); color: var(--dim); align-items: center; }
.mapg-dossier .drop { border: 0; background: none; cursor: pointer; color: var(--faint); font-size: 1rem; align-self: flex-start; }
.mapg-dossier .drop:hover { color: var(--text); }

/* ── drill: one opened place ───────────────────────────────────────────── */
.mapg-drill { flex: 1; min-height: 0; overflow-y: auto; padding: 0 0 .9rem; }
.mapg-dhero {
  position: relative; overflow: hidden; padding: .85rem .95rem 2rem;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--zt) 14%, var(--sky-b)),
    color-mix(in srgb, var(--zt) 44%, var(--sky-a)));
  color: var(--band-fg);
}
.mapg-dhero .hill { position: absolute; border-radius: 50%; }
.mapg-dhero .h1 { left: -40%; bottom: -56%; width: 180%; height: 70%; background: var(--hill-1); }
.mapg-dhero .h2 { left: -12%; bottom: -64%; width: 180%; height: 72%; background: var(--hill-2); }
.mapg-dhero .back {
  position: relative; z-index: 2; border: 1px solid var(--band-line); background: transparent;
  color: var(--band-dim); border-radius: var(--r-pill); padding: .18rem .65rem; cursor: pointer;
  font: 600 .68rem/1.4 var(--f-body);
}
.mapg-dhero .back:hover { color: var(--band-fg); border-color: var(--band-fg); }
.mapg-dhero h3 { position: relative; z-index: 2; margin: .5rem 0 0; font: var(--dis-w) 1.3rem/1.05 var(--f-dis); letter-spacing: var(--dis-ls); }
.mapg-dhero .dsub { position: relative; z-index: 2; margin: .28rem 0 0; font: 600 .7rem/1.4 var(--f-body); color: var(--band-dim); }
.mapg-dhero .dpals { position: absolute; right: 4%; bottom: 0; display: flex; align-items: flex-end; z-index: 1; }
.mapg-dhero .dpals img { width: 50px; height: 50px; object-fit: contain; filter: drop-shadow(0 2px 4px rgba(0,0,0,.45)); margin-left: -12px; }
.mapg-drill section { padding: .65rem .9rem 0; }
.mapg-drill section h4 {
  margin: 0 0 .45rem; font: 700 .62rem/1 var(--f-body);
  letter-spacing: .08em; text-transform: uppercase; color: var(--faint);
}
.mapg-resgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: .45rem; }
.mapg-resitem { display: grid; justify-items: center; gap: .2rem; text-align: center; }
.mapg-resitem .rn { font: 600 .62rem/1.15 var(--f-body); color: var(--text); }
.mapg-resitem .rc { font: 600 .58rem/1 var(--num); color: var(--faint); }
.mapg-resitem .portrait.boss { border-color: var(--bad); }

/* ── dex state on a pal ────────────────────────────────────────────────
   Two channels, not one: a corner mark carries the meaning for anyone who
   can't separate the ring colours, and the owned pals recede so a wall of
   residents reads as "these are the gaps" at a glance. */
.mapg-resitem .portrait { position: relative; overflow: visible; }
.mapg-resitem .portrait img { border-radius: 50%; }
.mapg-resitem .dexmark {
  position: absolute; right: -2px; bottom: -2px;
  width: 16px; height: 16px; border-radius: 50%;
  display: grid; place-items: center;
  font: 700 .6rem/1 var(--f-body); font-style: normal;
  border: 2px solid var(--surface);
}
.mapg-resitem.miss .portrait { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.mapg-resitem.miss .dexmark { background: var(--accent); color: var(--accent-ink); }
.mapg-resitem.own { opacity: .55; }
.mapg-resitem.own .dexmark { background: var(--good); color: var(--surface); }
.mapg-resitem.own:hover { opacity: 1; }

/* the same accent ring on the three faces standing on a destination card */
.mapg-residents img.miss {
  filter: drop-shadow(0 0 0 var(--accent)) drop-shadow(0 0 3px var(--accent))
          drop-shadow(0 2px 3px rgba(0,0,0,.45));
}

.mapg-dexlegend { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .55rem; margin: -.1rem 0 .5rem; }
.mapg-lens.sm { margin-top: 0; padding: .24rem .55rem .24rem .32rem; font-size: .64rem; }
.mapg-lens.sm .tick { width: 13px; height: 13px; }
.mapg-lens[disabled] { opacity: .45; pointer-events: none; }
.dexkey { display: inline-flex; align-items: center; gap: .28rem; font: 600 .62rem/1 var(--f-body); color: var(--faint); }
.dexkey .dexdot { width: 9px; height: 9px; border-radius: 50%; }
.dexdot.miss { background: var(--accent); }
.dexdot.own { background: var(--good); }

.mapg-more {
  grid-column: 1 / -1; justify-self: center; margin-top: .25rem;
  padding: .3rem .7rem; cursor: pointer;
  border: 1px dashed var(--line); border-radius: var(--r-pill);
  background: none; color: var(--dim); font: 600 .66rem/1 var(--f-body);
}
.mapg-more:hover { color: var(--text); border-color: var(--faint); }
.mapg-empty { grid-column: 1 / -1; font: 600 .68rem/1.4 var(--f-body); color: var(--faint); margin: .2rem 0; }
.mapg-statrow {
  display: flex; align-items: center; gap: .5rem; padding: .26rem 0;
  font: 500 .74rem/1 var(--f-body); color: var(--dim);
  border-bottom: 1px solid var(--line-soft);
}
.mapg-statrow .dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.mapg-statrow .sn { flex: 1; }
.mapg-statrow b { font: 700 .76rem/1 var(--num); color: var(--text); font-variant-numeric: tabular-nums; }

/* ── stage overlays ────────────────────────────────────────────────────── */
.mapg-ov { position: absolute; z-index: 5; display: flex; gap: .4rem; align-items: flex-start; }
.mapg-ov.tl { top: .6rem; left: .6rem; flex-wrap: wrap; max-width: calc(100% - 5rem); }
.mapg-ov.br { right: .6rem; bottom: .6rem; align-items: center; }
.mapg-seg {
  display: inline-flex; overflow: hidden; border-radius: var(--r-pill);
  background: var(--glass); border: 1px solid var(--glass-line);
  backdrop-filter: blur(10px);
}
.mapg-seg button {
  border: 0; background: none; cursor: pointer;
  font: 600 .66rem/1 var(--f-body); letter-spacing: .03em;
  padding: .4rem .62rem; color: #b7b1a6; white-space: nowrap;
}
[data-theme="daylight"] .mapg-seg button { color: var(--dim); }
.mapg-seg button.on { background: var(--accent); color: var(--accent-ink); }
.mapg-seg button:not(.on):hover { color: var(--text); }
/* tooltip + shared bits (ids/classes the engine writes into) */
.mt-input {
  width: 100%; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-chip); color: var(--text); font: 500 .8rem/1.3 var(--f-body);
  padding: .42rem .55rem; outline: none;
}
.mt-input:focus { border-color: var(--accent); }
.map-tip {
  position: absolute; z-index: 6; max-width: 270px; pointer-events: auto;
  background: rgba(16,15,13,.94); color: #ececee; border: 1px solid #3a3630;
  border-radius: 10px; padding: .55rem .65rem; font: 500 .76rem/1.45 var(--f-body);
  box-shadow: 0 10px 26px rgba(0,0,0,.45);
}
.map-tip b { font-weight: 700; }
.mt-sub { color: #9a958c; font-size: .7rem; }
.mt-row { display: flex; justify-content: space-between; gap: .8rem; }
.mt-row .mt-sub { white-space: nowrap; }
.mt-found { margin-top: .45rem; }
.mt-add { width: 100%; margin-top: .4rem; }
.map-coords {
  font: 600 .7rem/1 var(--f-body); color: #cfc9be; letter-spacing: .03em;
  background: rgba(16,15,13,.88); border: 1px solid #3a3630; border-radius: var(--r-chip);
  padding: .4rem .55rem; min-width: 74px; text-align: center;
}
.map-coords:empty { display: none; }
.map-zoomctl { display: flex; gap: .3rem; }
.map-load {
  position: absolute; inset: 0; z-index: 7; display: grid; place-items: center;
  color: #cfc9be; font: 600 .82rem/1.5 var(--f-body); text-align: center; padding: 2rem;
  background: rgba(5,5,8,.82);
}

@media (max-width: 1000px) {
  .mapg-shell { flex-direction: column; height: auto; }
  .mapg-pane { flex: 0 0 auto; order: 2; max-height: 56vh; }
  .mapg-stage { flex: 0 0 60vh; order: 1; }
  .mapg-grid { grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); }
}
@media (max-width: 430px) {
  .mapg-grid { grid-template-columns: 1fr 1fr; }
  .mapg-pane { flex-basis: auto; }
  .mapg-goal { font-size: .66rem; }
}
