*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{margin:0;height:100%;overflow:hidden}
body{background:#0b0c0f;color:#ece8df;font:14px/1.5 system-ui,sans-serif;-webkit-font-smoothing:antialiased}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;padding:0}
#map{position:fixed;inset:0}
#map:focus{outline:0}
#map:focus-visible{outline:2px solid #d6ff5c;outline-offset:-2px}
#tabs{position:fixed;z-index:25;display:flex;gap:2px;padding:3px;border-radius:9px;background:rgba(14,15,18,.86);border:1px solid #30343c;backdrop-filter:blur(8px)}
#tabs a{flex:none;padding:4px 10px;border-radius:6px;text-decoration:none;color:inherit;font-size:12px;white-space:nowrap}
#tabs a[aria-current]{font-weight:600}
/* The links (Lima spec §3): when they don't fit (below 1100 px) the strip scrolls sideways inside
   itself, never the page. main.js's placeStrip caps its width to the room it has and keeps the active tab in view. */
#tabs{overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
#tabs::-webkit-scrollbar{display:none}
/* The Buenos Aires pill (Lima spec §4): main.js shows it on a national tab zoomed into Buenos Aires, beside the tab strip or under it (placeStrip). */
#ba-pill{position:fixed;z-index:25;display:inline-flex;align-items:center;gap:.4em;min-height:44px;padding:0 18px;border-radius:99px;background:#ffb703;color:#0e2238;border:1px solid #0e2238;font:600 14px/1 system-ui,sans-serif;text-decoration:none;white-space:nowrap;box-shadow:0 8px 20px -8px rgba(0,0,0,.5)}
#notice{position:fixed;z-index:40;left:50%;bottom:16px;transform:translateX(-50%);max-width:min(560px,90vw);padding:8px 14px;border-radius:8px;background:#ffb000;color:#111;font-size:13px}
#notice button{font-weight:700;text-decoration:underline;min-height:24px}
#offline-chip{float:right;clear:both;margin:0 10px 10px 0;pointer-events:auto;display:flex;align-items:center;gap:10px;padding:4px 4px 4px 14px;border-radius:21px;flex-wrap:wrap;justify-content:center;background:rgba(14,15,18,.9);border:1px solid #30343c;color:#ece8df;font-size:13px;white-space:nowrap} /* the laptop's: a map control in the bottom-right corner, which each tab keeps clear of its panels (main.js) */
body[data-tab="expedition"] #offline-chip{max-width:calc(100vw - var(--sw) - 58px)}
body[data-tab="expedition"].ex-paged #offline-chip{max-width:calc(100vw - var(--sw) - var(--pw) - 74px)}
body[data-tab="table"] #offline-chip{max-width:calc(100vw - var(--in) - var(--sw) - 46px)}
body[data-tab="table"].paged #offline-chip{max-width:calc(100vw - var(--in) - var(--sw) - var(--pagew) - 70px)}
body[data-tab="ba"] #offline-chip{max-width:calc(100vw - var(--lw) - 20px)}
@media (max-width:1099px){body:is([data-tab="expedition"].ex-paged,[data-tab="table"].paged) .maplibregl-ctrl-bottom-right{display:none}} /* the page leaves too little map: the corner's controls (Find my location, the attribution, the chip) go under the panels, so none shows and none is a tab stop (the zoom cap stays); display:none, as MapLibre sets an open attribution visibility:visible */
#offline-chip button{min-height:32px;padding:0 12px;border-radius:999px;border:1px solid #30343c}
#map-error{position:fixed;z-index:50;inset:0;display:grid;place-content:center;gap:8px;text-align:center;background:#0b0c0f;color:#ece8df;padding:24px}
#map-error a{color:#d6ff5c}
#map-error button{border:1px solid currentColor;border-radius:7px;padding:6px 14px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.pe-photo .nophoto{display:block;width:100%;height:100%}
.nophoto .ic{display:block;position:relative;top:50%;translate:0 -50%;width:36%;height:auto;max-width:56px;margin:0 auto;color:#fff}
.img-ph{display:grid;place-items:center;padding:8px;text-align:center;background:#1a1d22;color:#8b909a;font-size:12px;overflow:hidden}
.pe-dialog,.pe-lightbox{border:0;padding:0;color:#ece8df;background:#0e0f12}
.pe-dialog{max-width:420px;border-radius:12px;border:1px solid #30343c}
.pe-dialog form{padding:20px 22px}
.pe-dialog h2{margin:0 0 8px;font-size:18px}
.pe-dialog .acts{display:flex;gap:8px;margin-top:16px}
.pe-dialog .btn{height:36px;padding:0 14px;border-radius:8px;border:1px solid #30343c}
.pe-dialog .btn.pri{background:#d6ff5c;color:#08090b;border-color:#d6ff5c}
/* The share dialog (M3). The QR code aims for 3 CSS px per module (--qr, set by share.js) and never leaves the screen: its
   side is also bounded by the viewport, so the whole symbol, quiet zone included, shows without scrolling.
   Portrait: stacked, the dialog widens to --qr (+ 46 px: the form's 2 × 22 px padding and the 2 × 1 px border) up to the
   viewport, and the code gives up height to the text and buttons (about 320 px).
   Landscape: the code on the left at --side, the text and buttons in a 270 px column on the right. */
.pe-dialog.pe-share{width:min(100vw - 16px, max(420px, var(--qr) + 46px));max-width:none;max-height:calc(100dvh - 16px)}
.pe-share .qr svg{display:block;width:100%;max-width:max(160px, 100dvh - 320px);height:auto;margin:12px auto}
.pe-share .link{width:100%;padding:6px 8px;border-radius:8px;border:1px solid #30343c;background:#08090b;color:inherit;font:16px/1.3 ui-monospace,monospace}
.pe-share .acts{flex-wrap:wrap}
.pe-share .note{margin:10px 0 0;min-height:1.5em;font-size:13px}
@media (orientation:landscape){
  .pe-dialog.pe-share{--side:min(max(var(--qr), 320px), 100dvh - 42px, 100vw - 330px);width:min(100vw - 16px, var(--side) + 314px)}
  .pe-share form{display:grid;grid-template-columns:var(--side) minmax(0,1fr);grid-template-rows:repeat(4,auto) 1fr;column-gap:20px;align-items:start;padding:12px 16px}
  .pe-share form>*{grid-column:2}
  .pe-share .qr{grid-column:1;grid-row:1 / span 5}
  .pe-share .qr svg{width:var(--side);max-width:none;margin:0}
}
/* No code (a route too long for one, share.js): the plain 420 px column, in landscape too. */
.pe-dialog.pe-share.no-qr{width:min(100vw - 16px, 420px)}
.pe-share.no-qr form{display:block;padding:20px 22px}
::backdrop{background:rgba(0,0,0,.6)}
.pe-lightbox{width:100vw;height:100vh;max-width:none;max-height:none;background:rgba(5,6,8,.96)}
.pe-lightbox figure{margin:0;height:100%;display:grid;grid-template-rows:1fr auto;place-items:center;padding:48px 72px 16px}
.pe-lightbox img,.pe-lightbox .img-ph{width:100%;height:calc(100vh - 120px);object-fit:contain}
.pe-lightbox figcaption{font-size:13px;color:#cfcbc2;padding-top:10px}
.pe-lightbox .cr{display:block;font-size:11px;color:#8b909a}
.pe-lightbox .cr a{color:#8b909a}
.pe-lightbox button{position:fixed;width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.08);font-size:18px}
.pe-lightbox .lb-prev{left:16px;top:50%}.pe-lightbox .lb-next{right:16px;top:50%}.pe-lightbox .lb-close{right:16px;top:16px}
:focus-visible{outline:2px solid #d6ff5c;outline-offset:2px}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}
.ic{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex:none}
/* Shared marker skins (markers.js); tabs restyle them under their scope. No position here: MapLibre's
   .maplibregl-marker is absolute, which also anchors the absolute children. MapLibre writes the element's transform,
   so scaling goes on children. */
.pe-photo,.pe-token{display:block;border:0;padding:0;cursor:pointer;--c:#ece8df}
.pe-photo .fr{display:block;width:46px;height:46px;border-radius:8px;overflow:hidden;border:3px solid var(--c);background:var(--c);box-shadow:0 6px 16px rgba(0,0,0,.35)}
.pe-photo img,.pe-photo .img-ph{width:100%;height:100%;object-fit:cover;display:block;font-size:8px;padding:2px}
/* a failed photo's name: centred and wrapped inside the frame (the marker keeps its full aria-label) */
.pe-photo .img-ph{display:grid;overflow-wrap:anywhere;line-height:1}
.pe-photo .ico{position:absolute;left:-6px;bottom:-6px;display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--c);color:#111;font-size:12px}
.pe-photo .ct{display:none}
.pe-photo.stack .ct{display:grid;place-items:center;position:absolute;right:-8px;top:-8px;min-width:22px;height:22px;padding:0 5px;border-radius:11px;background:#111;color:#fff;font:600 11px/1 system-ui}
.pe-photo.stack .fr{box-shadow:4px 4px 0 -1px #fff,4px 4px 0 1px var(--c),8px 8px 0 -1px #fff,8px 8px 0 1px var(--c)}
.pe-token{display:grid;place-items:center;width:26px;height:26px;border-radius:50%;background:var(--c);color:#111;border:2px solid #fff;font-size:14px;box-shadow:0 3px 8px rgba(0,0,0,.35)}
.pe-token .ico{display:grid}
.pe-num{display:grid;place-items:center;min-width:18px;height:18px;padding:0 4px;border-radius:9px;background:var(--c);color:#08090b;border:1.5px solid #fff;font:700 10px/1 system-ui;pointer-events:none}
.pe-photo.gone,.pe-token.gone,.pe-photo.under{visibility:hidden;pointer-events:none}
.pe-photo.cur .fr,.pe-token.cur{outline:3px solid #fff;outline-offset:2px}
.pe-photo.on .fr,.pe-token.on .ico{transform:scale(1.15)}
/* Ranking (docs/superpowers/specs/2026-10-05-poi-ranking-design.md). .rank: a row's or card's context rank; .rankline:
   the place page's fixed ranks; .pe-pop .rk: the popup's; .chip.ranks: the "# Ranks" toggle (each tab styles .chip). */
.rank{display:inline-block;margin-right:.1em;padding:0 .35em;border:1px solid currentColor;border-radius:4px;font-size:.75em;font-weight:700;line-height:1.4;vertical-align:.12em;font-variant-numeric:tabular-nums;opacity:.85}
.rankline{list-style:none;padding:0;margin:10px 0 0;font-size:12.5px;line-height:1.55;font-variant-numeric:tabular-nums;opacity:.85}
.rankline li{margin:0;padding:0}
.pe-pop .rk{display:block;margin-top:-6px;padding:0 12px 10px;font:600 11px/1.3 system-ui;font-variant-numeric:tabular-nums;opacity:.8}
.chip.ranks b{font-weight:800}
/* Marker rank badges (markers.js .pe-rk, empty unless showRanks) clear the route numbers (.pe-num top left, pins' inr
   top right). 'best' (the 10 best context ranks shown) is weaker than lit/dim/cur/inr/hover: each tab's rules win ties. */
.pe-rk{position:absolute;z-index:1;display:grid;place-items:center;min-width:20px;height:16px;padding:0 4px;border-radius:4px;background:#111;color:#fff;box-shadow:0 0 0 1.5px #fff;font:700 10px/1 system-ui;font-variant-numeric:tabular-nums;white-space:nowrap;pointer-events:none}
.pe-rk:empty{display:none}
.pe-pin .pe-rk{right:17px;top:3px}
.pe-photo .pe-rk{right:-9px;top:-9px}
.pe-token .pe-rk{right:-14px;top:-10px}
body[data-tab] .pe-pin.best .dot{opacity:1;transform:scale(1.45);box-shadow:0 0 0 1.5px #fff,0 0 8px 1px var(--c)}
body[data-tab] .pe-photo.best .fr{transform:scale(1.12);box-shadow:0 0 0 2px #fff,0 0 0 4px var(--c),0 8px 18px -6px rgba(0,0,0,.6)}
body[data-tab] .pe-token.best{width:34px;height:34px;font-size:17px}
/* The ranking scale's legend (ui.js ranksToggle): a popover, centred in the top layer by the UA, one look in every tab. */
.rankctl{flex:none;display:flex;gap:4px;min-width:0}
.rankctl .ranks{flex:1}
.chip.scale{flex:none;justify-content:center;min-width:26px;padding-left:0;padding-right:0;font-weight:700}
.pe-scale{width:min(330px,calc(100vw - 32px));padding:14px 16px;border:1px solid #30343c;border-radius:12px;background:#14161a;color:#ece8df;font:13px/1.45 system-ui,sans-serif;text-align:left;box-shadow:0 18px 40px -12px rgba(0,0,0,.6)}
.pe-scale::backdrop{background:none}
.pe-scale b{font-size:14px}
.pe-scale ul{list-style:none;margin:8px 0 10px;padding:0;display:grid;grid-template-columns:auto 1fr;gap:2px 12px}
.pe-scale li{display:contents}
.pe-scale li span:first-child{font-variant-numeric:tabular-nums;color:#b9b4aa;white-space:nowrap}
.pe-scale p{margin:4px 0 0;font-size:12px;color:#b9b4aa}
.nav{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.nav a{padding:4px 12px;border-radius:999px;border:1px solid currentColor;color:inherit;text-decoration:none;font-size:13px}
.nav .mono{font:12px ui-monospace,monospace;user-select:all}
.wpts{margin:10px 0;padding-left:1.5em}
.wpts li{margin:0 0 10px}
.wpts li::marker{font-weight:700}
.wpts .nav{margin:4px 0 0;gap:6px}
.wpts .nav a{padding:2px 10px;font-size:12px}

/* ---------- phone mode (phone spec §2): a bottom bar of five targets; the map runs from the top to the bar.
   (1,2,1)+ specificity: beats every tab's own #map and #tabs rules, their narrow-window @media ones included.
   Buenos Aires keeps its own phone layout (Lima spec §3): a full-screen map, the strip at the top, its own bottom bar and sheet.
   The Buenos Aires pill sits top left over the phone's map, where the offline chip (only offline) and a full sheet take precedence. ---------- */
body[data-mode="phone"]{--bar:calc(64px + env(safe-area-inset-bottom))}
body[data-mode="phone"][data-tab]:not([data-tab="ba"]) #map{inset:0 0 var(--bar) 0;border:0;border-radius:0;box-shadow:none}
body[data-mode="phone"][data-tab]:not([data-tab="ba"]) #tabs{inset:auto 0 0 0;height:var(--bar);display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:0;padding:0 4px env(safe-area-inset-bottom);border:0;border-top:1px solid rgba(255,226,180,.14);border-radius:0;background:#1c1611;backdrop-filter:none;-webkit-backdrop-filter:none;box-shadow:none;font:600 12px 'Figtree',system-ui,sans-serif;transition:none}
body[data-mode="phone"][data-tab]:not([data-tab="ba"]) #tabs a{display:grid;place-items:center;align-content:center;gap:2px;min-height:44px;padding:0;border-radius:0;background:none;color:#bba98e;font:inherit;text-decoration:none}
body[data-mode="phone"][data-tab]:not([data-tab="ba"]) #tabs a i{font-style:normal;font-size:20px;line-height:1}
body[data-mode="phone"][data-tab]:not([data-tab="ba"]) #tabs a:hover{background:none;color:#f6ead8}
body[data-mode="phone"][data-tab]:not([data-tab="ba"]) #tabs a[aria-current]{background:none;color:#f2b45a}
body[data-mode="phone"] #ba-pill{top:calc(env(safe-area-inset-top) + 12px);left:12px}
body[data-mode="phone"]:is([data-tab="table"],:has(#offline-chip:not([hidden])),:has(.go-sheet[data-size="full"])) #ba-pill{display:none}
body[data-mode="phone"] #notice{bottom:calc(var(--bar) + 12px)}
body[data-mode="phone"] #notice button{min-height:44px}
body[data-mode="phone"] #offline-chip{position:fixed;z-index:30;top:calc(env(safe-area-inset-top) + 12px);left:12px;right:68px;width:fit-content;margin:0 auto;float:none;flex-wrap:wrap;justify-content:center;white-space:normal;border-radius:22px} /* clear of the 44 px locate button (go.css: right 12px), wrapping at 320 px */
body[data-mode="phone"][data-tab="table"] #offline-chip,body[data-mode="phone"] #tab-root:has(.go-sheet[data-size="full"]) ~ #offline-chip{display:none} /* only over a visible map: not on the Board (no map), not over the full sheet's handle */
body[data-mode="phone"] #offline-chip button{min-height:44px}
body[data-mode="phone"][data-tab="ba"] #offline-chip{top:auto;bottom:calc(var(--ph) + 8px);left:max(8px,env(safe-area-inset-left));right:auto;margin:0;max-width:calc(100vw - 60px)} /* Buenos Aires: above its sheet (ba.js sets --ph), left of the credits; the strip and the clock hold the top */
body[data-mode="phone"]:has(.l-panel[data-sheet="full"]) #offline-chip{display:none}
body[data-mode="phone"] .pe-share .btn{min-height:44px} /* 44 px on every phone tab (M3): history can switch tabs under the dialog; the laptop keeps 36 px */
/* the photo lightbox: sized to the visible viewport, its controls clear of the notch and the home indicator */
body[data-mode="phone"] .pe-lightbox{height:100dvh}
body[data-mode="phone"] .pe-lightbox figure{padding:calc(env(safe-area-inset-top) + 60px) 12px calc(env(safe-area-inset-bottom) + 12px)}
body[data-mode="phone"] .pe-lightbox :is(img,.img-ph){height:calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 150px)}
body[data-mode="phone"] .pe-lightbox .lb-close{top:calc(env(safe-area-inset-top) + 8px);right:12px}
body[data-mode="phone"] .pe-lightbox .lb-prev{left:8px}
body[data-mode="phone"] .pe-lightbox .lb-next{right:8px}
