/* Pokepro — a Pokédex-style handheld: red moulded shell with engraved circuit
   traces, a blue scanner lens, and a recessed LCD panel carrying the tool.

   The shell keeps its colour in both themes because a physical casing does not
   repaint itself at dusk; only the screen behind the glass switches. */
:root{
  color-scheme:light;
  /* casing */
  --shell:#c4102b; --shell-lit:#e8384c; --shell-dim:#8d0a1e; --shell-edge:#450612;
  --seam:rgba(0,0,0,.34);
  --hood-ink:#ffe2e5; --hood-ink-2:#f0a2a9;

  /* readout strip above the tabs — always dark, it is the device's own display */
  --readout:#141a1d; --readout-2:#1e262a; --readout-ink:#e9f3f1; --readout-ink-2:#8fa3a7;

  /* lcd */
  --screen:#eef1e9; --screen-2:#fafbf6; --screen-3:#e0e5d9;
  --ink:#15191a; --ink-2:#545c5c; --ink-3:#858d8c;
  --line:#c9cfc1;

  --accent:#12659f;        /* the scanner lens blue */
  --amber:#9e6402; --red:#bc2a20; --green:#27704a; --violet:#5f4a91;
  --on-accent:#fff;
  --radius:5px;
}
@media (prefers-color-scheme:dark){ :root:not([data-theme="light"]){
  --shell:#8e0c20; --shell-lit:#b9182f; --shell-dim:#5d0715; --shell-edge:#25040c;
  --hood-ink:#ffd2d7; --hood-ink-2:#d18d95;
  --readout:#0b0f11; --readout-2:#161d20;
  --screen:#14181b; --screen-2:#1c2226; --screen-3:#242c31;
  --ink:#e2e9e8; --ink-2:#a3b0b1; --ink-3:#74807f;
  --line:#2f383d;
  --accent:#59aef5; --amber:#edab42; --red:#ff7d6c; --green:#61c186; --violet:#a893da;
  --on-accent:#08131a;
  color-scheme:dark;
}}
:root[data-theme="dark"]{
  --shell:#8e0c20; --shell-lit:#b9182f; --shell-dim:#5d0715; --shell-edge:#25040c;
  --hood-ink:#ffd2d7; --hood-ink-2:#d18d95;
  --readout:#0b0f11; --readout-2:#161d20;
  --screen:#14181b; --screen-2:#1c2226; --screen-3:#242c31;
  --ink:#e2e9e8; --ink-2:#a3b0b1; --ink-3:#74807f;
  --line:#2f383d;
  --accent:#59aef5; --amber:#edab42; --red:#ff7d6c; --green:#61c186; --violet:#a893da;
  --on-accent:#08131a;
  color-scheme:dark;
}
*{box-sizing:border-box}
/* iOS inflates text inside any block it decides is wide enough to deserve it,
   which is how a 12px button caption becomes an 18px one and a row that fitted
   in the layout stops fitting. Everything here is already sized for a phone. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{background:var(--shell-edge);color:var(--ink);
  font-family:"Source Sans 3",system-ui,sans-serif;line-height:1.45;
  padding-block:20px;padding-left:16px;padding-right:16px}
@media(max-width:600px){body{padding-block:0;padding-left:0;padding-right:0}}

/* ---- casing ------------------------------------------------------------ */
/* The casing clips its own contents, so nothing inside it can widen the page.
   This belongs here and not on html or body: overflow on the root moves iOS
   Safari's scroll container onto the body, and the page then pans sideways —
   the opposite of what the rule was for. */
.device{position:relative;overflow-x:clip;max-width:1680px;margin:0 auto;border-radius:26px;
  background:
    linear-gradient(163deg,var(--shell-lit) 0%,var(--shell) 38%,var(--shell-dim) 100%);
  padding:16px;
  box-shadow:
    0 1px 0 rgba(255,255,255,.32) inset,
    0 -2px 0 rgba(0,0,0,.3) inset,
    0 0 0 1px var(--shell-edge),
    0 18px 44px rgba(0,0,0,.5)}
@media(min-width:1100px){.device{padding:28px}}
/* engraved traces, clipped to the casing and kept off the screen by z-order */
.device::before{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:url(circuit.svg) 0 0/200px 200px;opacity:.24;mix-blend-mode:overlay}
/* four corner screws */
.device::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background-repeat:no-repeat;
  background-image:
    radial-gradient(circle at 50% 45%,rgba(255,255,255,.5),rgba(0,0,0,.45) 62%,transparent 68%),
    radial-gradient(circle at 50% 45%,rgba(255,255,255,.5),rgba(0,0,0,.45) 62%,transparent 68%),
    radial-gradient(circle at 50% 45%,rgba(255,255,255,.5),rgba(0,0,0,.45) 62%,transparent 68%),
    radial-gradient(circle at 50% 45%,rgba(255,255,255,.5),rgba(0,0,0,.45) 62%,transparent 68%);
  background-size:13px 13px;
  background-position:11px 11px,calc(100% - 11px) 11px,11px calc(100% - 11px),
    calc(100% - 11px) calc(100% - 11px)}
@media(min-width:1100px){.device::after{background-position:
    14px 14px,calc(100% - 14px) 14px,14px calc(100% - 14px),calc(100% - 14px) calc(100% - 14px)}}
.device>*{position:relative;z-index:1}
@media(max-width:600px){.device{border-radius:0;padding:0;min-height:100vh}
  .device::after{display:none}}

.hood{display:flex;align-items:center;gap:15px;padding:6px 6px 16px;color:var(--hood-ink)}
@media(min-width:1100px){.hood{gap:18px;padding:4px 8px 20px}}
@media(max-width:600px){.hood{padding:12px 14px;gap:11px}}

/* the big blue scanner lens */
.lens{flex:none;width:46px;height:46px;border-radius:50%;
  background:
    radial-gradient(circle at 34% 28%,#cfeaff 0%,#5aa9e8 22%,#1b6fc0 55%,#0c3c74 100%);
  box-shadow:
    0 0 0 3px rgba(255,255,255,.5),
    0 0 0 4px var(--shell-dim),
    0 2px 5px rgba(0,0,0,.45),
    0 0 16px rgba(90,169,232,.45)}
@media(max-width:600px){.lens{width:34px;height:34px}}
@media(min-width:1100px){.lens{width:58px;height:58px}
  .led{width:13px;height:13px}
  .brand h1{font-size:23px}
  .brand .sub{font-size:11px}}

.leds{flex:none;display:flex;flex-direction:column;gap:5px}
.led{width:11px;height:11px;border-radius:50%;box-shadow:0 0 0 1px rgba(0,0,0,.4),0 0 7px currentColor}
.led.r{color:#ff5d4d;background:radial-gradient(circle at 34% 30%,#ffd3cc,#ff5d4d 60%,#a8291b)}
.led.y{color:#ffd34e;background:radial-gradient(circle at 34% 30%,#fff3c9,#ffd34e 60%,#a8801a)}
.led.g{color:#5fe08a;background:radial-gradient(circle at 34% 30%,#d2ffe1,#5fe08a 60%,#1d8043)}
@media(max-width:600px){.leds{flex-direction:row}}

.brand{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px}
.brand h1{font-family:"Chakra Petch",system-ui,sans-serif;font-weight:700;font-size:19px;
  letter-spacing:.13em;text-transform:uppercase;margin:0;line-height:1.1;color:#fff;
  text-shadow:0 1px 0 rgba(0,0,0,.4)}
.brand .sub{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--hood-ink-2)}
@media(max-width:600px){.brand .sub{display:none}}
.hood .game select{background:rgba(0,0,0,.26);color:#fff;border-color:rgba(255,255,255,.34);
  font-family:"Chakra Petch",sans-serif;font-weight:600;letter-spacing:.04em}
.hood .game select:focus-visible{outline:2px solid #fff;outline-offset:1px}

/* ---- screen ------------------------------------------------------------ */
.screen{background:var(--screen);border-radius:12px;overflow:hidden;
  border:4px solid var(--shell-edge);
  box-shadow:
    0 0 0 1px rgba(255,255,255,.16),
    0 4px 16px rgba(0,0,0,.5) inset,
    0 2px 3px rgba(0,0,0,.35)}
@media(max-width:600px){.screen{border-radius:0;border-left:0;border-right:0}}

/* status strip reads as the device's own segment display, dark in both themes */
.statusbar{display:flex;flex-wrap:wrap;align-items:center;gap:9px 14px;
  padding:11px 15px;color:var(--readout-ink);
  background:linear-gradient(var(--readout-2),var(--readout));
  border-bottom:1px solid #000}
.statusbar .where{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:19px;
  letter-spacing:.02em;margin:0;line-height:1.15;flex:1 1 auto;min-width:0;color:#fff}
.clock{display:flex;align-items:center;gap:8px;font-family:"IBM Plex Mono",monospace;
  font-size:12px;color:var(--readout-ink-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.slot{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:11px;letter-spacing:.11em;
  text-transform:uppercase;padding:2px 8px;border-radius:3px;background:#2a8f86;color:#04211f;
  box-shadow:0 0 9px rgba(42,143,134,.55)}
.slot[data-slot="night"]{background:#7e6bc4;color:#0c0620;box-shadow:0 0 9px rgba(126,107,196,.55)}
.slot[data-slot="morning"]{background:#e0a32e;color:#241700;box-shadow:0 0 9px rgba(224,163,46,.55)}

/* mode buttons, moulded into the bezel */
nav.modes{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--line);border-bottom:1px solid var(--line)}
nav.modes button{border:0;background:var(--screen-2);padding:12px 6px;cursor:pointer;
  font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:12.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);position:relative;
  box-shadow:0 1px 0 rgba(255,255,255,.5) inset}
nav.modes button:hover{color:var(--ink-2)}
nav.modes button[aria-selected="true"]{background:var(--screen-3);color:var(--ink);
  box-shadow:inset 0 -3px 0 var(--accent),inset 0 2px 5px rgba(0,0,0,.13)}
nav.modes button:focus-visible{outline:2px solid var(--accent);outline-offset:-3px}

main{padding:16px;display:flex;flex-direction:column;gap:18px;min-height:340px}
@media(min-width:1100px){main{padding:20px 22px;gap:22px}}
/* main's gap falls between panels, and only one panel is ever visible — so the
   blocks *inside* a panel need their own rhythm. Without this the travel row
   and the encounter tabs sit directly on top of each other. */
section[role="tabpanel"]{display:flex;flex-direction:column;gap:20px}
@media(min-width:1100px){section[role="tabpanel"]{gap:24px}}
section[hidden]{display:none!important}
h2.sect{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:12px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-3);margin:0 0 9px;display:flex;align-items:baseline;
  gap:9px;justify-content:space-between}
h2.sect .hint{font-family:"Source Sans 3",sans-serif;font-size:12px;letter-spacing:0;
  text-transform:none;color:var(--ink-3);font-weight:400}

/* travel */
.travel{display:flex;flex-wrap:wrap;gap:9px;align-items:center}
.go{border:1px solid var(--line);background:var(--screen-2);color:var(--ink);border-radius:var(--radius);
  padding:7px 12px;cursor:pointer;font:inherit;font-size:13.5px;display:inline-flex;align-items:center;gap:7px}
.go:hover,.go:focus-visible{border-color:var(--accent);color:var(--accent);outline:none}
.go .n{font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--ink-3)}
select{font:inherit;font-size:13.5px;padding:7px 10px;border-radius:var(--radius);
  border:1px solid var(--line);background:var(--screen-2);color:var(--ink);max-width:100%}
select:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* encounter groups */
/* Multi-column rather than grid: the method blocks are wildly uneven in height
   (a gift list of three against a surf table of twelve), and a grid leaves the
   short ones stranded beside dead space. Columns balance the total height and
   pack the board tight. */
#here,#items{columns:390px;column-gap:12px}
.method,#items .spot{break-inside:avoid}
.method{border:1px solid var(--line);border-radius:var(--radius);
  background:var(--screen-2);padding:9px 11px 4px;margin-bottom:12px}
.mh{display:flex;align-items:baseline;gap:9px;margin-bottom:6px;flex-wrap:wrap;
  padding-bottom:5px;border-bottom:1px solid var(--line)}
.mh .name{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:13px;letter-spacing:.06em;
  text-transform:uppercase}
.tod{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.07em;text-transform:uppercase;
  border:1px solid var(--line);border-radius:2px;padding:1px 6px;color:var(--ink-3)}
.tod.now{border-color:var(--accent);color:var(--accent);font-weight:500}
.method.later{opacity:.62}

.mon{display:grid;grid-template-columns:24px 60px 1fr auto;gap:12px;align-items:center;
  padding:7px 2px;border-bottom:1px solid var(--line)}
.mon:last-child{border-bottom:0}
.mon.have{opacity:.55}
.mon input[type=checkbox]{width:17px;height:17px;accent-color:var(--accent);cursor:pointer;margin:0}
.mon .nm{font-weight:600;font-size:14.5px}
.mon .lv{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--ink-3);margin-left:7px}
.mon .verdict{font-size:12px;color:var(--ink-2);display:block;margin-top:1px}
.mon .pct{font-family:"IBM Plex Mono",monospace;font-size:14px;font-variant-numeric:tabular-nums;
  text-align:right;color:var(--ink-2)}

/* Where a gift really comes from, and the catch. The address sits with the rest
   of the detail; the catch is set apart, because "you have to give it back" is
   not something to read past. */
.gift{font-size:12px;line-height:1.45;margin-top:3px}
.gift .where{color:var(--ink-3)}
.gift .caveat{display:block;color:var(--amber);margin-top:1px}
/* hoisted above the list, it is the heading's second line rather than a row's */
.method > .gift{margin:-2px 0 7px;padding-left:1px}
.tag{display:inline-block;font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:10px;
  letter-spacing:.09em;text-transform:uppercase;padding:1.5px 6px;border-radius:2px;margin-right:6px;
  vertical-align:1px}
.tag.only{background:var(--red);color:var(--on-accent)}
.tag.best{background:var(--green);color:var(--on-accent)}
.tag.elsewhere{background:transparent;color:var(--amber);border:1px solid var(--amber)}
.tag.got{background:transparent;color:var(--ink-3);border:1px solid var(--line)}

.empty{color:var(--ink-3);font-size:13.5px;padding:10px 0}

/* dex */
.dexbar{display:flex;flex-wrap:wrap;gap:9px;align-items:center;margin-bottom:11px}
.meter{flex:1 1 170px;min-width:140px;height:9px;border-radius:5px;background:var(--screen-3);
  overflow:hidden;box-shadow:0 1px 2px rgba(0,0,0,.22) inset}
.meter i{display:block;height:100%;background:linear-gradient(90deg,var(--accent),var(--green))}
.count{font-family:"IBM Plex Mono",monospace;font-size:13px;font-variant-numeric:tabular-nums;white-space:nowrap}
.dexgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));gap:5px}
.dexcell{display:flex;align-items:center;gap:8px;padding:5px 8px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--screen-2);cursor:pointer;text-align:left;font:inherit;
  font-size:13px;color:var(--ink)}
.dexcell:hover,.dexcell:focus-visible{border-color:var(--accent);outline:none}
.dexcell[data-have="1"]{background:var(--screen-3);color:var(--ink-3)}
.dexcell .no{font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--ink-3);
  font-variant-numeric:tabular-nums;min-width:26px}
.dexcell .sprite{margin:-6px 0}
.dexcell .dot{width:7px;height:7px;border-radius:50%;background:var(--line);flex:none}
.dexcell[data-have="1"] .dot{background:var(--green);box-shadow:0 0 5px var(--green)}

/* training */
.trainer{border:1px solid var(--line);border-radius:var(--radius);background:var(--screen-2);
  padding:12px;margin-bottom:11px}
.trow{display:flex;flex-wrap:wrap;gap:9px;align-items:flex-end}
.addrow{max-width:660px;align-items:center}
.addrow .note{margin:0}

/* Both dialogs sit in the top layer, over whichever page you were on and
   outside the casing that clips everything else — so they are the only things
   here that can push the document sideways, and they are pinned rather than
   sized to stop them.
   Pinned, specifically: left and right against the viewport instead of a width
   of 100vw. A box whose right edge is the screen's right edge cannot stick out
   past it whatever the viewport turns out to measure, and iOS measures it
   differently from everyone else. The auto margins re-centre it once max-width
   takes over on a wider screen, and the height comes from the dynamic viewport,
   because a phone with the keyboard up has half a screen to give. */
#addMon,#pickGame{position:fixed;left:8px;right:8px;width:auto;margin:0 auto;
  top:50%;transform:translateY(-50%);
  max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);
  overflow:auto;overscroll-behavior:contain}
#addMon{border:1px solid var(--accent);border-radius:var(--radius);background:var(--screen);
  color:var(--ink);padding:17px 19px;max-width:560px;
  box-shadow:0 18px 48px rgb(0 0 0 / .45)}
#addMon::backdrop{background:rgb(8 10 12 / .62)}
#addMon .sect{margin:0 0 12px}
#addMon label.f select{font:inherit;font-size:14px;font-family:"Source Sans 3",sans-serif;
  text-transform:none;letter-spacing:0;color:var(--ink);background:var(--screen-2);
  border:1px solid var(--line);border-radius:var(--radius);padding:7px 9px;
  width:100%;min-width:0}
#addMon .row{max-width:100%}
#addMon .note{margin:6px 0 0;flex:1 1 200px}
#addMon .sprite{flex:0 0 auto}
.addMonButtons{margin-top:15px;gap:9px}

/* first visit: which cartridge is this about */
#pickGame{border:1px solid var(--accent);border-radius:var(--radius);background:var(--screen);
  color:var(--ink);padding:19px 21px;max-width:560px;
  box-shadow:0 18px 48px rgb(0 0 0 / .45)}
#pickGame::backdrop{background:rgb(8 10 12 / .72)}
#pickGame .sect{margin:0 0 15px}
.genrow{display:flex;align-items:baseline;gap:11px;padding:7px 0;
  border-top:1px solid var(--line)}
.genrow:first-child{border-top:0;padding-top:0}
.genlabel{flex:0 0 3.4rem;font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:10.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
.gengames{display:flex;flex-wrap:wrap;gap:6px;flex:1 1 auto}
.gamebtn{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:12.5px;
  letter-spacing:.03em;padding:7px 11px;border-radius:var(--radius);cursor:pointer;
  border:1px solid var(--line);background:var(--screen-2);color:var(--ink)}
.gamebtn:hover{border-color:var(--accent);color:var(--accent)}
.gamebtn:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@media(max-width:480px){
  #pickGame{padding:15px 15px}
  .genrow{flex-direction:column;gap:5px;padding:8px 0}
  .genlabel{flex:none}
  .gamebtn{font-size:12px;padding:8px 10px;flex:1 1 auto}
}
.trainer .met{margin-top:2px}
.trainer .met.home{color:var(--green)}
/* the two multipliers that ride on the Pokémon itself */
.toggle.small{display:inline-flex;align-items:center;gap:6px;font-size:12px;
  color:var(--ink-3);cursor:pointer;white-space:nowrap;padding:5px 9px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--screen-2)}
.toggle.small.on{border-color:var(--green);color:var(--green)}
.toggle.small input{margin:0}
/* min-width:0 because a flex item will not shrink below its content's own
   minimum unless told to, and a form control's minimum is generous: an input is
   as wide as twenty characters and a select is as wide as its longest option.
   Without this the "Met at" row on a phone is as wide as the longest place name
   in the game, and takes the dialog holding it with it. */
label.f{display:flex;flex-direction:column;gap:3px;font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);font-family:"Chakra Petch",sans-serif;
  font-weight:600;min-width:0}
label.f input,label.f select{max-width:100%}
label.f input{font:inherit;font-size:14px;font-family:"Source Sans 3",sans-serif;text-transform:none;
  letter-spacing:0;padding:6px 9px;border-radius:var(--radius);border:1px solid var(--line);
  background:var(--screen);color:var(--ink);width:100%}
.btn{border:1px solid var(--accent);background:var(--accent);color:var(--on-accent);border-radius:var(--radius);
  padding:7px 14px;cursor:pointer;font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:12.5px;
  letter-spacing:.09em;text-transform:uppercase}
.btn.ghost{background:transparent;color:var(--ink-2);border-color:var(--line)}
.btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:8px;margin-top:11px}
.stat{border:1px solid var(--line);border-radius:var(--radius);padding:7px 9px;background:var(--screen)}
.stat .k{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:10.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3)}
.stat .v{display:flex;align-items:flex-end;gap:7px;margin-top:5px}
/* each number carries its own caption — "0  0" said nothing about which box
   takes the stat experience and which takes the DV */
.subf{display:flex;flex-direction:column;gap:2px;min-width:0}
.subf:first-child{flex:1 1 auto}
.subf:last-child{flex:0 0 60px}
.subf:only-child{flex:1 1 auto}
.subk{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
/* A stat is copied off the game's own screen and then nudged a point at a time,
   so it gets buttons of its own — bigger than the browser's spinner arrows,
   present on a phone where those do not exist at all, and no keyboard. */
.spin{display:flex;align-items:stretch;gap:3px;min-width:0}
.spin input{text-align:center;min-width:0;
  -moz-appearance:textfield;appearance:textfield}
.spin input::-webkit-outer-spin-button,
.spin input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.step{flex:0 0 auto;width:27px;padding:0;border:1px solid var(--line);border-radius:3px;
  background:var(--screen-2);color:var(--ink-2);font-family:"IBM Plex Mono",monospace;
  font-size:14px;line-height:1;cursor:pointer}
.step:hover{border-color:var(--ink-3);color:var(--ink)}
.step:active{background:var(--screen-3)}
.step:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.stat input[readonly]{color:var(--ink-3);cursor:default}
.stat input{font-family:"IBM Plex Mono",monospace;font-size:13px;width:100%;padding:4px 6px;
  border-radius:3px;border:1px solid var(--line);background:var(--screen-2);color:var(--ink);
  font-variant-numeric:tabular-nums}
.spots{margin-top:8px}
.spot{display:flex;justify-content:space-between;gap:10px;padding:6px 9px;
  border-bottom:1px solid var(--line);font-size:13.5px}
.spot:last-child{border-bottom:0}
.spot .v{font-family:"IBM Plex Mono",monospace;font-size:12.5px;color:var(--ink-2);font-variant-numeric:tabular-nums}

.note{font-size:12.5px;color:var(--ink-2);margin:0;max-width:68ch}
.warn{border-left:2px solid var(--amber);padding:7px 0 7px 11px;font-size:12.5px;color:var(--ink-2);margin:0}
textarea{width:100%;min-height:118px;font-family:"IBM Plex Mono",monospace;font-size:11.5px;
  padding:9px;border-radius:var(--radius);border:1px solid var(--line);background:var(--screen-2);
  color:var(--ink);resize:vertical}
.row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}

/* ---- footplate --------------------------------------------------------- */
.footplate{display:flex;align-items:center;gap:14px;padding:11px 10px 4px}
.vents{flex:1 1 auto;height:9px;border-radius:3px;
  background:repeating-linear-gradient(90deg,
    var(--shell-edge) 0 3px,transparent 3px 9px);
  opacity:.5}
.stamp{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.17em;
  color:var(--hood-ink-2);opacity:.8;white-space:nowrap}
@media(max-width:600px){.footplate{padding:10px 14px 12px}}

@media(prefers-reduced-motion:reduce){*{transition:none!important}}

/* boot-failure message */
.empty .cmd{font-family:"IBM Plex Mono",monospace;font-size:12.5px;background:var(--screen-3);
  border:1px solid var(--line);border-radius:3px;padding:1px 6px;color:var(--ink)}
.empty a{color:var(--accent)}
.empty .sub2{font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:var(--ink-3);
  display:inline-block;margin:3px 0}

/* encounter-method tabs */
/* tabs and the outstanding count share one row where the Here heading used to be */
.herebar{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;margin-bottom:12px}
.subtabs{display:flex;flex-wrap:wrap;gap:6px;align-items:stretch}
/* what is lying around and who is standing around are not encounter methods,
   so they get a line of their own rather than running on from the ones that are */
.tabsep{flex:0 0 100%;height:0;margin:1px 0}
.subtabs[hidden]{display:none}
.subtab{border:1px solid var(--line);background:var(--screen-2);color:var(--ink-2);
  border-radius:var(--radius);padding:6px 12px;cursor:pointer;display:inline-flex;
  align-items:center;gap:8px;font-family:"Chakra Petch",sans-serif;font-weight:600;
  font-size:12px;letter-spacing:.1em;text-transform:uppercase}
.subtab:hover{border-color:var(--ink-3);color:var(--ink)}
.subtab[aria-selected="true"]{background:var(--accent);border-color:var(--accent);
  color:var(--on-accent)}
/* nothing in this family is catchable at the current time of day */
.subtab.later{opacity:.62}
.subtab .n{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:0;
  background:var(--screen-3);color:var(--ink-2);border-radius:9px;padding:0 6px;
  min-width:19px;text-align:center}
.subtab[aria-selected="true"] .n{background:rgba(255,255,255,.24);color:var(--on-accent)}
.subtab:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* how much of this location is still outstanding */
.need{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:14px;
  letter-spacing:.04em;color:var(--amber);font-variant-numeric:tabular-nums;
  white-space:nowrap}
.need[data-done="1"]{color:var(--green)}

/* battle logger on a trainee card */
.logger{margin-top:11px;padding:10px 11px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--screen)}
.logger .row{gap:7px}
.logger input{font:inherit;font-size:14px;padding:6px 9px;border-radius:var(--radius);
  border:1px solid var(--line);background:var(--screen-2);color:var(--ink)}
.logger input[list]{flex:1 1 200px;max-width:260px}
.logger .times{color:var(--ink-3);font-size:13px}
.logged{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:9px}
.chip{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);
  background:var(--screen-2);color:var(--ink-2);border-radius:20px;padding:3px 10px;
  font:inherit;font-size:12.5px;cursor:pointer}
.chip:hover{border-color:var(--red);color:var(--red)}
.chip .x{font-size:10px;opacity:.65}
.logged .note{margin-left:4px}

/* derived, non-editable values in the stat table */
.subf.ro{gap:1px}
.rov{font-family:"IBM Plex Mono",monospace;font-size:14px;font-variant-numeric:tabular-nums;
  color:var(--ink);padding:3px 0;white-space:nowrap}
.subf.ro .rov[title]{cursor:help;text-decoration:underline dotted var(--ink-3);
  text-underline-offset:3px}
.stat{display:flex;flex-direction:column;gap:6px}
.stat .v{display:none}

/* Training ranking as a real column grid. It used to be one flex row with
   space-between, which on a wide panel threw the location to the far left and
   the numbers to the far right with a void between them, and read as broken. */
.spots{max-width:840px}
.spots .spot{display:grid;grid-template-columns:minmax(0,1fr) 4.6rem 4.4rem 3.2rem 4.2rem;
  gap:10px;align-items:baseline}
.spots .num{font-family:"IBM Plex Mono",monospace;font-size:12.5px;text-align:right;
  font-variant-numeric:tabular-nums;color:var(--ink-2)}
.spots .spot.hd{font-family:"Chakra Petch",sans-serif;font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3);border-bottom-color:var(--ink-3);
  align-items:end;padding-bottom:5px}
.spots .spot.hd span{line-height:1.25}
.spots .spot.hd .num{font-family:inherit;font-size:inherit;color:inherit}
@media(max-width:600px){
  .spots .spot{grid-template-columns:minmax(0,1fr) 4.6rem 4.2rem}
  .spots .spot > :nth-child(3),.spots .spot > :nth-child(4){display:none}
}

/* battle logging */
.fightrow{display:flex;flex-wrap:wrap;align-items:center;gap:9px 12px;margin-bottom:10px}
.flabel{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:11px;
  letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
.fightrow input,.fightrow select{font:inherit;font-size:14px;padding:6px 9px;
  border-radius:var(--radius);border:1px solid var(--line);background:var(--screen-2);
  color:var(--ink)}
.chip.pick{cursor:pointer}
.chip.pick:hover{border-color:var(--accent);color:var(--accent)}
.chip.pick.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.toggle{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--ink-2);
  white-space:nowrap;cursor:pointer}
.toggle input{width:16px;height:16px;accent-color:var(--accent);margin:0;padding:0}
#box .spot{align-items:center}
#box .row{gap:7px}
/* display:inline-flex beats the hidden attribute on its own */
.toggle[hidden]{display:none}


/* ---- travel: where you came from, where you are, where you can go -------- */
.travelbar{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.travelbar .side{display:flex;flex-wrap:wrap;gap:7px;align-items:center}
.travelbar .side.to{flex:1 1 auto}
select.atnow{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:14px;
  letter-spacing:.02em;padding:8px 11px;border-color:var(--accent);color:var(--ink);
  background:var(--screen-2)}
.go .arrow{color:var(--ink-3);font-size:13px;line-height:1}
.go:hover .arrow,.go:focus-visible .arrow{color:var(--accent)}
.go .dest{white-space:nowrap}
/* the way back is a retreat, not a choice: quieter than the onward options */
.go.back{background:transparent;border-style:dashed}
@media(max-width:600px){
  .travelbar{gap:8px}
  .travelbar .side.to{flex-basis:100%}
}

/* ---- sprites ------------------------------------------------------------ */
/* Positioned by scripts/fetch-sprites.mjs's measured bounds, so each one fills
   its box regardless of how much padding its own set left around it. */
.sprite{display:block;flex:none;background-repeat:no-repeat}
.sprite.crisp{image-rendering:pixelated;image-rendering:crisp-edges}
.mon.have .sprite{filter:grayscale(.6);opacity:.7}
.dexcell[data-have="1"] .sprite{filter:grayscale(.75);opacity:.6}
.sprite.big{margin-right:4px}

/* items lying around a location */
.itemrow{padding:7px 2px;border-bottom:1px solid var(--line)}
.itemrow:last-child{border-bottom:0}
.itemrow .nm{font-weight:600;font-size:14.5px}
.itemrow .verdict{display:block;margin-top:1px}
.itemrow{display:grid;grid-template-columns:24px 1fr;gap:10px;align-items:center}
.itemrow input[type=checkbox]{width:17px;height:17px;accent-color:var(--accent);
  cursor:pointer;margin:0}
.itemrow.have{opacity:.55}

/* how to get a species the wild will not give you */
.dexcell .who{display:flex;flex-direction:column;gap:1px;min-width:0}
.dexcell .who .nm{font-weight:400}
.dexcell .how{font-size:10.5px;color:var(--ink-3);line-height:1.25;
  overflow:hidden;text-overflow:ellipsis}

/* trainers standing at a location */
.trainercard .mh{gap:8px}
.trainercard .mh input[type=checkbox]{width:17px;height:17px;accent-color:var(--accent);
  cursor:pointer;margin:0}
.trainercard.have{opacity:.55}
.trainercard .mon{grid-template-columns:8px 44px 1fr auto}
.trainercard .pct{font-size:12px}
/* the rival's team is decided by your own starter, not by which of him it is */
.trainercard .tod.picked{border-color:var(--violet);color:var(--violet);text-transform:none;
  letter-spacing:.02em;font-size:11px}

/* the gym is a run of battles in one building, ending with the one that pays a
   badge — worth telling apart from the people standing about on the routes */
.trainercard.gym{border-left:3px solid var(--ink-3)}
.trainercard.leader{border-left:3px solid var(--amber);background:var(--screen)}
.trainercard .tod.gymtag{border-color:var(--ink-3);color:var(--ink-3)}
.trainercard.leader .tod.gymtag{border-color:var(--amber);color:var(--amber)}
.trainercard.leader .mh .name{color:var(--amber)}

/* the four move slots a Pokémon actually has */
.moves{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:11px}
.moveslot{font:inherit;font-size:13.5px;padding:6px 9px;border-radius:var(--radius);
  border:1px solid var(--line);background:var(--screen-2);color:var(--ink);
  flex:0 1 150px;min-width:0}
.moveslot:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* the move picker's own popup, anchored to whichever slot has focus */
.mcombo{position:fixed;z-index:60;overflow-y:auto;border:1px solid var(--accent);
  border-radius:var(--radius);background:var(--screen);color:var(--ink);
  box-shadow:0 14px 34px rgb(0 0 0 / .38);padding:4px 0}
.mcombo .mgroup{font-family:"Chakra Petch",sans-serif;font-weight:600;font-size:10px;
  letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3);
  padding:8px 11px 4px;border-top:1px solid var(--line);margin-top:4px}
.mcombo .mgroup:first-child{border-top:0;margin-top:0;padding-top:5px}
.mcombo .mopt{display:flex;gap:9px;align-items:baseline;padding:5px 11px;cursor:pointer;
  font-size:13.5px}
.mcombo .mopt.on{background:var(--accent);color:var(--on-accent)}
.mcombo .mtag{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--ink-3);
  flex:0 0 44px;font-variant-numeric:tabular-nums}
.mcombo .mopt.on .mtag{color:var(--on-accent);opacity:.75}
.mcombo .mname{flex:1 1 auto}

/* what the party is missing, above the places it can actually get to */
.spots .locked{margin:0 0 9px}

/* things the estimate cannot see, kept beside the estimate anyway */
.spots .tips{margin-top:14px;padding:13px 15px;border:1px solid var(--line);
  border-left:2px solid var(--accent);border-radius:var(--radius);background:var(--screen-2)}
.spots .tiph{font-family:"Chakra Petch",sans-serif;font-size:10.5px;font-weight:600;
  letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3);margin:0 0 7px}
.spots .tip{font-size:12.5px;color:var(--ink-2);margin:0 0 5px;max-width:74ch;line-height:1.5}
.spots .tip:last-child{margin-bottom:0}
.spots .tip b{color:var(--ink);font-weight:600}
.spots .tips.switch{border-left-color:var(--green)}

/* levelling up or evolving, which both invalidate the stats on screen */
.levelform{margin-top:12px;padding:12px;border:1px solid var(--accent);
  border-radius:var(--radius);background:var(--screen);display:flex;
  flex-direction:column;gap:10px}
.levelform .row{gap:9px}
.levelform input[type=number]{font:inherit;font-size:14px;padding:6px 9px;
  border-radius:var(--radius);border:1px solid var(--line);
  background:var(--screen-2);color:var(--ink);width:100%}
.levelform input[list]{font:inherit;font-size:14px;padding:6px 9px;
  border-radius:var(--radius);border:1px solid var(--line);
  background:var(--screen-2);color:var(--ink);flex:0 1 180px}
#trackToggle{margin-top:9px}

/* which of a trainer's Pokémon you actually faced */
.foeteam{display:flex;flex-wrap:wrap;gap:7px;margin:-2px 0 8px}
.foeteam[hidden]{display:none}
.foemon{display:inline-flex;align-items:center;gap:7px;padding:4px 10px 4px 7px;
  border:1px solid var(--line);border-radius:20px;background:var(--screen-2);
  cursor:pointer;font-size:13px}
.foemon input{width:15px;height:15px;accent-color:var(--accent);margin:0;cursor:pointer}
.foemon .lv{font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--ink-3)}

/* ---------------------------------------------------------------- phone ----
   A 393pt screen leaves about 345 inside the bezel and the page gutter, which
   is a third of what the desktop layout was drawn for. Nothing here changes
   what is on the page — it changes how much of it fits on one screen, because
   a training card that takes five scrolls to read is a card nobody reads. */
@media (max-width: 480px) {
  main{padding:12px 12px;gap:14px}
  .sect{font-size:11px}

  /* travel: the dropdown is the control, the buttons are the shortcuts */
  .travel select{font-size:15px;padding:8px 10px}
  .travel .btn,.travel button{font-size:12px;padding:7px 9px}

  /* method tabs and the count that follows them */
  .subtabs{gap:6px}
  .subtabs button{font-size:10.5px;padding:6px 9px}
  .need{font-size:14px}

  /* encounter rows: the sprite and the tick keep their size, everything
     around them gives up its margins so the text has somewhere to go */
  .method{padding:8px 9px 3px}
  .mon{grid-template-columns:20px 52px 1fr auto;gap:8px;padding:6px 0}
  .mon .nm{font-size:14.5px}
  .mon .verdict,.mon .gift{font-size:11.5px;line-height:1.4}
  .mon .pct{font-size:12.5px}

  /* the training card, which was the worst of it: one stat per row, five rows */
  .trainer{padding:10px}
  .trow{gap:7px}
  .stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-top:9px;
    align-items:start}
  /* label and field on one line: stacking them cost a third of the screen to
     five boxes that hold one number each */
  .stat{flex-direction:row;flex-wrap:wrap;align-items:center;gap:5px 9px;padding:7px 9px}
  .stat .k{flex:1 1 auto}
  .stat .subf{flex:0 0 74px}
  /* the box with the buttons needs room for them */
  .stat .subf:has(.spin){flex:0 0 auto}
  .spin input{width:62px}
  .step{width:34px}
  /* and with one field the caption only repeats what the box is called */
  .stat:not(:has(.subf + .subf)) .subk{display:none}
  .stat input{font-size:12.5px;padding:3px 5px}
  .subk{font-size:9px}
  .rov{font-size:13px}

  /* four move slots, two to a line, with the label above rather than beside */
  .moves{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;
    align-items:stretch}
  .moves .flabel{grid-column:1 / -1;margin-bottom:-2px}
  .moveslot{flex:none;width:100%;font-size:13px;padding:5px 7px}

  /* buttons in a card heading wrap rather than squeeze */
  .btn{padding:6px 11px;font-size:11.5px}
  .toggle.small{padding:4px 7px;font-size:11.5px}

  /* the training table drops to three columns already; tighten what is left */
  .spots .spot{padding:6px 2px}
  .spots .tips{padding:11px 12px}
  .spots .tip{font-size:12px}

  /* trainers and items */
  .trainercard .mon{grid-template-columns:20px 44px 1fr auto}
  .itemrow{padding:6px 0}

  /* the add/level forms, which are the only things on the page you type into */
  #addMon{padding:14px 15px}
  .levelform{padding:10px}
  .levelform .row{gap:7px}

  /* iOS zooms the page in when it focuses a control whose text is under 16px,
     and a zoomed page pans sideways. That is what "the modal makes the page
     scroll sideways" was: the dialog opens, puts the caret in the level box,
     and Safari zooms to it. Nothing here is typed into often enough to be worth
     that, so every control that takes a caret is 16px on a phone. The classes
     are spelled out because each of them already sets a smaller size. */
  input,select,textarea,
  label.f input,label.f select,#addMon label.f select,
  .stat input,.travel select,.logger input,.fightrow input,.fightrow select,
  select.atnow,.levelform input[type=number],.levelform input[list],
  .moveslot{font-size:16px}
  /* a finger, not a mouse: the row is as tall as something worth tapping, and
     the buttons stretch to match the box they sit either side of */
  .stat input{padding:7px 5px}
}
