/* =======================================================================
   ETS2 Guessr

   Mile Zero's palette and its labelled card headers; Win95's square edges
   and physical button press; GtaGuessr's refusal to get in the way of the
   map. Montserrat throughout.

   Spacing rule, so nothing drifts: a card owns its padding, its first and
   last children have no outer margin, and every block below uses the same
   vertical step. Never add a margin that fights that.
   ======================================================================= */

:root {
  --void:    #0d0d11;
  --panel:   #16161c;
  --raise:   #1d1d25;
  --sink:    #101015;
  --line:    #2a2a35;
  --bevel:   #35354a;

  --ink:     #ecebf2;
  --dim:     #8d8d9e;

  --indigo:  #6c4bf6;
  --indigo2: #a68cff;
  /* The old orange is gone. Everything that used it now resolves to the
     soft indigo, so the whole site runs on one accent instead of two that
     never agreed with each other. Change --indigo2 and this follows. */
  --amber:   var(--indigo2);
  --red:     #ff6b6b;

  --pad:  20px;   /* inside a card */
  --step: 16px;   /* between blocks */
  --tight: 8px;

  --font: "Montserrat", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Aliases kept so older inline styles still resolve. */
  --face: var(--panel); --light: var(--bevel); --shadow: var(--line);
  --edge: var(--line); --dark: #000; --text: var(--ink); --muted: var(--dim);
  --link: var(--indigo2); --desktop: var(--void);
  --title: var(--indigo); --title2: #4a2fd0;
}

* { box-sizing: border-box; }

/* The hidden attribute is applied by the browser as display:none, which any
   author rule setting display will beat. Several things here are laid out
   with grid or flex and toggled with hidden, so state this explicitly once
   rather than remembering it at every call site. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font: 400 15px/1.6 var(--font);
  -webkit-font-smoothing: antialiased;
}

/* ---------- backdrop ---------- */

#backdrop { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: var(--void); }
#backdrop img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; opacity: 0;
  transition: opacity 2s ease-in-out;
  transform: scale(1.06);
}
#backdrop img.on { opacity: 1; }
#backdrop::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(13,13,17,.80) 0%, rgba(13,13,17,.93) 55%, #0d0d11 100%);
}
@media (prefers-reduced-motion: reduce) { #backdrop img { transition: none; } }

body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}
.wrap, .game { position: relative; z-index: 1; }

.wrap { max-width: 760px; margin: 0 auto; padding: 40px 18px 64px; }

/* The home page runs full height so the links and the logo strip settle at
   the foot of the screen rather than floating halfway up on a short page.
   On a long page they just follow the content as normal. */
/* The home page runs full height. The main block takes the middle, and the
   footer settles at the foot: auto margins above and below the block share
   the leftover space evenly, which centres it without pinning anything. */
.wrap.tall { min-height: 100vh; display: flex; flex-direction: column; }
.wrap.tall .page-main { margin: auto 0; width: 100%; }
.wrap.tall .page-bottom { padding-top: 40px; }

/* ---------- type ---------- */

h1 { font-size: 32px; font-weight: 800; letter-spacing: -.02em; text-transform: uppercase; margin: 0; }
h2 {
  font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--dim); margin: 0 0 var(--tight);
}
h3 { font-size: 15px; font-weight: 700; letter-spacing: -.01em; margin: 0 0 var(--tight); }
p  { margin: 0 0 var(--step); }
p:last-child { margin-bottom: 0; }

.eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--amber); margin: 0 0 var(--tight);
}
.muted { color: var(--dim); }
.small { font-size: 13px; }
a { color: var(--indigo2); text-underline-offset: 2px; }

.num, .stat strong, td.n {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  letter-spacing: -.01em;
}

/* ---------- cards ---------- */

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-top-color: var(--bevel);
  padding: var(--pad);
  margin: 0 0 var(--step);
}
.card > *:first-child { margin-top: 0; }
.card > *:last-child  { margin-bottom: 0; }

/* A card's first heading becomes its title bar, breaking out of the padding. */
.card > h2:first-child {
  margin: calc(var(--pad) * -1) calc(var(--pad) * -1) var(--pad);
  padding: 11px var(--pad);
  background: var(--raise);
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  position: relative;
}
.card > h2:first-child::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--indigo);
}

/* Section headings that sit outside a card need air above them. */
.wrap > h2 { margin-top: 28px; }
.wrap > h2:first-child { margin-top: 0; }

/* ---------- buttons ---------- */

button, .btn {
  display: inline-block;
  background: var(--indigo);
  color: #fff;
  border: 1px solid #4a2fd0;
  border-top-color: var(--indigo2);
  padding: 11px 20px;
  font: 700 12px/1 var(--font);
  letter-spacing: .1em; text-transform: uppercase;
  cursor: pointer; text-decoration: none;
}
button:hover, .btn:hover { background: #7d5eff; }
button:active, .btn:active { transform: translateY(1px); }
button.ghost, .btn.ghost {
  background: var(--raise); color: var(--ink);
  border: 1px solid var(--line); border-top-color: var(--bevel);
}
button.ghost:hover, .btn.ghost:hover { background: #26262f; }

/* Second billing. Outlined rather than filled, so it reads as the other
   thing worth doing without competing with the solid primary button
   sitting next to it. */
button.ghost.accent, .btn.ghost.accent {
  border-color: var(--indigo);
  color: var(--indigo2);
}
button.ghost.accent:hover, .btn.ghost.accent:hover {
  background: rgba(108, 75, 246, .14);
  color: var(--ink);
}
button:disabled { opacity: .4; cursor: not-allowed; transform: none; }
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible {
  outline: 2px solid var(--amber); outline-offset: 2px;
}

/* ---------- fields ---------- */

label {
  display: block; margin: 0 0 6px;
  font-size: 11px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim);
}
.field { margin: 0 0 var(--step); }
.field:last-child { margin-bottom: 0; }

input[type=text], input[type=password], input[type=number], input[type=date],
input[type=file], select, textarea {
  width: 100%;
  background: var(--sink); color: var(--ink);
  border: 1px solid var(--line); border-top-color: #22222c;
  padding: 11px 12px;
  font: 400 15px var(--font);
}
input:focus, select:focus, textarea:focus { border-color: var(--indigo); outline: none; }
textarea { font-size: 14px; line-height: 1.5; }
input[type=checkbox] { width: auto; accent-color: var(--indigo); margin: 0 6px 0 0; }

/* Two fields side by side, with the same step between rows. */
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--step); }
.grid2 > * { min-width: 0; }

.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.row.tight { gap: var(--tight); }

/* ---------- feedback ---------- */

.notice {
  background: rgba(108,75,246,.08);
  border-left: 3px solid var(--indigo);
  padding: 12px 15px;
  margin: 0 0 var(--step);
}
.error { color: var(--red); font-size: 14px; margin: var(--step) 0 0; }
.error:empty, .muted:empty { display: none; }

code, kbd {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: .86em;
  background: var(--sink); border: 1px solid var(--line);
  padding: 1px 5px;
}

/* ---------- tables ---------- */

table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; padding: 0 10px 9px;
  font-size: 11px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim);
  border-bottom: 1px solid var(--line);
}
td { padding: 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
tr.top td.rank { color: var(--amber); font-weight: 700; }

/* Wide tables get a horizontal scroller rather than bursting the layout. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.scroll-x table { min-width: 460px; }

/* ---------- tabs ---------- */

nav.tabs, nav.seg { display: flex; gap: 1px; flex-wrap: wrap; margin: 0 0 var(--step); }
nav.tabs a, nav.seg button {
  background: var(--panel); color: var(--dim);
  border: 1px solid var(--line);
  padding: 11px 16px;
  font: 700 11px/1 var(--font);
  letter-spacing: .12em; text-transform: uppercase;
  text-decoration: none;
}
nav.tabs a { border-bottom: none; }
nav.tabs a:hover, nav.seg button:hover { color: var(--ink); }
nav.tabs a.on, nav.seg button[aria-pressed="true"] {
  background: var(--raise); color: var(--ink);
  border-top: 2px solid var(--indigo); padding-top: 10px;
}

/* ---------- the game screen ---------- */

.game { display: flex; height: 100vh; }
.panel {
  /* Wide enough that the screenshot is worth looking at before you open it
     full size, and that the readout does not feel cramped. */
  width: 440px; flex: 0 0 440px;
  padding: var(--pad); overflow-y: auto;
  background: var(--panel); border-right: 1px solid var(--line);
}
.panel > * { margin-bottom: var(--step); }
.panel > *:last-child { margin-bottom: 0; }
.panel .shot-wrap {
  aspect-ratio: 16 / 9;
  background: #000;
  border: 1px solid var(--line);
}
.panel img.shot {
  width: 100%; height: 100%; display: block;
  /* contain, never cover: cropping hides the road signs the game turns on. */
  object-fit: contain;
}
#map { flex: 1; background: var(--void); }

.stat {
  display: flex; gap: 34px;
  padding: 16px 18px;
  background: var(--sink);
  border: 1px solid var(--line); border-top-color: var(--bevel);
}
.stat div span {
  display: block; font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--dim); margin-bottom: 2px;
}
.stat div strong { font-size: 30px; font-weight: 700; color: var(--ink); line-height: 1.1; }

/* The one button you press every round. Full width so it is unmissable
   and easy to hit without aiming. */
#guess-box button, #result-box button {
  width: 100%;
  padding: 14px 20px;
  font-size: 13px;
}
/* The two end-of-game buttons share the width rather than stacking. */
#final-box .row { gap: var(--tight); }
#final-box .btn { flex: 1 1 0; padding: 13px 12px; }
#guess-box #hint { font-size: 13px; }

/* ---------- enlarging the screenshot ---------- */

.shot-wrap { position: relative; }

.zoom {
  position: absolute; top: 8px; right: 8px;
  width: 34px; height: 34px; min-width: 0; padding: 0;
  display: grid; place-items: center;
  background: rgba(13,13,17,.78); color: var(--ink);
  border: 1px solid var(--line);
}
.zoom:hover { background: rgba(13,13,17,.95); }
.shot { cursor: zoom-in; }

.lightbox {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(6,6,9,.96);
  overflow: hidden;
}

/* The stage is inset rather than the lightbox being padded: the stage is
   absolutely positioned, so padding on the parent would be ignored, which
   is why this used to run edge to edge. The margin leaves the picture
   sitting in a frame and gives the toolbar somewhere to live. */
.lightbox-stage {
  position: absolute;
  top: 72px; right: 72px; bottom: 56px; left: 72px;
  display: grid; place-items: center;
  cursor: zoom-in;
  touch-action: none;
  overflow: hidden;
}
.lightbox-stage.zoomed { cursor: grab; }
.lightbox-stage.zoomed.dragging { cursor: grabbing; }
.lightbox img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  transform-origin: 0 0;
  will-change: transform;
  user-select: none; -webkit-user-drag: none;
}
.lightbox-bar {
  position: fixed; top: 16px; right: 16px; z-index: 2001;
  display: flex; gap: 8px; align-items: center;
}
.lightbox-hint {
  position: fixed; bottom: 20px; left: 0; right: 0; z-index: 2001;
  text-align: center; color: var(--dim); font-size: 12px;
  pointer-events: none;
}

@media (max-width: 900px) {
  .lightbox-stage { top: 60px; right: 12px; bottom: 44px; left: 12px; }
  .lightbox-bar { top: 12px; right: 12px; }
}

/* ---------- shareable result ---------- */

.share-preview {
  margin: 0 0 var(--step);
  padding: 12px 14px;
  background: var(--sink);
  border: 1px solid var(--line);
  font: 400 14px/1.6 var(--font);
  white-space: pre-wrap; word-break: break-word;
  user-select: all;   /* one click selects the lot */
}

/* ---------- the round clock ---------- */

#timer .clock {
  display: flex; justify-content: space-between;
  font-size: 10px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--dim); margin-bottom: 6px;
}
#timer .clock span:last-child { color: var(--ink); font-variant-numeric: tabular-nums; }
.clock-track { height: 4px; background: var(--sink); border: 1px solid var(--line); }
.clock-fill { height: 100%; background: var(--indigo); transition: width 1s linear; }
#timer.low .clock-fill { background: var(--red); }
#timer.low .clock span:last-child { color: var(--red); }

/* ---------- party: standings in the corner ---------- */

.game { position: relative; }

.mini {
  position: absolute; left: 16px; bottom: 16px; z-index: 600;
  width: 220px;
  background: rgba(22,22,28,.94);
  border: 1px solid var(--line); border-top-color: var(--bevel);
  backdrop-filter: blur(3px);
}
.mini-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 10px; background: var(--raise);
  border-bottom: 1px solid var(--line);
  font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}
.mini-head button {
  background: none; border: 0; color: var(--dim);
  min-width: 0; min-height: 0; padding: 0 4px; font-size: 15px; line-height: 1; width: auto;
}
.mini.collapsed .mini-list { display: none; }
.mini-list { list-style: none; margin: 0; padding: 6px 0; max-height: 200px; overflow-y: auto; }
.mini-list li { display: flex; gap: 8px; align-items: baseline; padding: 4px 10px; font-size: 13px; }
.mini-list .pos { color: var(--dim); width: 14px; font-variant-numeric: tabular-nums; }
.mini-list .who { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-list .pts { color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 600; }

/* ---------- party: between rounds ---------- */

.standings-overlay {
  position: fixed; inset: 0; z-index: 1500;
  background: rgba(6,6,9,.86);
  display: grid; place-items: center; padding: 20px;
}
.standings-box {
  width: min(440px, 100%);
  background: var(--panel);
  border: 1px solid var(--line); border-top-color: var(--bevel);
}
.standings-box .bar {
  padding: 11px 18px; background: var(--raise);
  border-bottom: 1px solid var(--line);
  font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}
.standings-box .body { padding: 18px; }
.standings-list { list-style: none; margin: 0 0 var(--step); padding: 0; }
.standings-list li {
  display: flex; gap: 10px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.standings-list li:last-child { border-bottom: none; }
.standings-list .pos { color: var(--dim); width: 18px; font-variant-numeric: tabular-nums; }
.standings-list .who { flex: 1; font-weight: 600; }
.standings-list .pts { color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 700; }
.standings-list li:first-child .who { color: var(--indigo2); }
.standings-box button { width: 100%; }

/* ---------- the logo ---------- */

.brand { text-align: center; margin: 0 0 30px; }
.brand img {
  display: block; margin: 0 auto;
  max-width: min(360px, 78%);
  height: auto;
}

/* ---------- the running costs dock ---------- */

.dock {
  position: fixed; right: 18px; bottom: 18px; z-index: 900;
  width: min(330px, calc(100vw - 36px));
  background: var(--panel);
  border: 1px solid var(--line); border-top-color: var(--bevel);
  box-shadow: 0 14px 40px rgba(0,0,0,.5);
}
.dock-bar {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  width: 100%; padding: 11px 14px;
  background: var(--raise); color: var(--ink);
  border: 0; border-bottom: 1px solid var(--line);
  font: 700 11px/1 var(--font); letter-spacing: .14em; text-transform: uppercase;
  cursor: pointer; text-align: left;
}
.dock-bar:hover { background: #26262f; }
.dock-bar:active { transform: none; }
.dock-chevron { font-size: 15px; line-height: 1; color: var(--dim); }
.dock-body { padding: 16px; }
.dock-body .btn { font-size: 11px; padding: 10px 14px; }

@media (max-width: 620px) {
  /* On a phone it spans the width, so it does not crowd the thumb. */
  .dock { right: 10px; left: 10px; bottom: 10px; width: auto; }
}

/* ---------- notification bell ---------- */

.bell {
  position: fixed; top: 18px; right: 18px; z-index: 1000;
  min-width: 0; height: 46px;
  padding: 0 16px 0 13px;
  display: flex; align-items: center; gap: 9px;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-top-color: var(--bevel);
}
.bell svg { flex: none; }

.bell-label {
  font-size: 11px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; white-space: nowrap;
}
.bell.has-news .bell-label { color: var(--indigo2); }
.bell:hover { background: var(--raise); }

.bell .dot {
  position: absolute; top: -7px; right: -7px;
  min-width: 20px; height: 20px; padding: 0 5px;
  display: grid; place-items: center;
  background: var(--indigo); color: #fff;
  font-size: 11px; font-weight: 700;
  border: 2px solid var(--void);
}

/* Pulses only while there is something unread, and stops the moment you
   open it. A permanent animation stops meaning anything by the second visit. */
.bell.has-news { animation: bell-pulse 2.4s ease-in-out infinite; }
.bell.has-news svg { animation: bell-ring 2.4s ease-in-out infinite; transform-origin: 50% 4px; }

@keyframes bell-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(108,75,246,0); }
  35%      { box-shadow: 0 0 0 1px var(--indigo), 0 0 16px rgba(108,75,246,.5); }
}
@keyframes bell-ring {
  0%, 22%, 100% { transform: rotate(0); }
  6%  { transform: rotate(12deg); }
  10% { transform: rotate(-10deg); }
  14% { transform: rotate(6deg); }
  18% { transform: rotate(-4deg); }
}
@media (prefers-reduced-motion: reduce) {
  .bell.has-news, .bell.has-news svg { animation: none; }
  .bell.has-news { box-shadow: 0 0 0 1px var(--indigo); }
}

.bell-panel {
  position: fixed; top: 72px; right: 18px; z-index: 1000;
  width: min(420px, calc(100vw - 36px));
  max-height: min(70vh, 560px); overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line); border-top-color: var(--bevel);
  box-shadow: 0 18px 44px rgba(0,0,0,.55);
}
.bell-panel .bar {
  position: sticky; top: 0;
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 10px 14px;
  background: var(--raise); border-bottom: 1px solid var(--line);
  font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}
.bell-panel .bar button { padding: 4px 10px; font-size: 10px; min-height: 0; width: auto; }
.bell-panel .body { padding: 16px; }

@media (max-width: 900px) {
  /* No room for the wording on a phone, so fall back to the icon alone. */
  .bell { top: 12px; right: 12px; height: 44px; width: 44px; padding: 0;
          justify-content: center; }
  .bell-label { display: none; }
  .bell-panel { top: 64px; right: 12px; left: 12px; width: auto; }
}

/* ---------- a button that wants noticing ---------- */

/* Used on the Challenges link while one is running. The glow breathes
   rather than flashes: enough to catch the eye on a dark page, not enough
   to be irritating on every visit. */
.btn.glow {
  border-color: var(--indigo);
  color: var(--ink);
  animation: breathe 2.6s ease-in-out infinite;
}
.btn.glow:hover { animation: none; box-shadow: 0 0 0 1px var(--indigo), 0 0 18px rgba(108,75,246,.55); }

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 0 rgba(108,75,246,.00); }
  50%      { box-shadow: 0 0 0 1px var(--indigo), 0 0 16px rgba(108,75,246,.45); }
}

@media (prefers-reduced-motion: reduce) {
  .btn.glow { animation: none; box-shadow: 0 0 0 1px var(--indigo); }
}

/* ---------- VIP ---------- */

.tag.vip {
  color: #fff; background: var(--indigo); border-color: var(--indigo);
  font-weight: 700;
}

/* Testers get a nod, not a badge. Deliberately smaller and quieter than VIP
   so the two never compete when they appear on the same line. */
.tag.tester {
  font-size: 9px; letter-spacing: .1em; padding: 1px 5px;
  color: var(--dim); border-color: var(--line);
  position: relative; top: -1px;
}

.claim { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.claim code {
  font-size: 18px; font-weight: 700; letter-spacing: .18em;
  color: var(--indigo2); background: var(--sink);
  border: 1px solid var(--line); padding: 9px 14px;
}

/* ---------- Discord ---------- */

/* Blurple, Discord's own colour, so the button reads as what it is
   rather than as another generic link. */
.btn.discord {
  background: #5865f2;
  border-color: #4752c4;
  border-top-color: #7983f5;
  color: #fff;
}
.btn.discord:hover { background: #6b76f4; }

/* ---------- footer ---------- */

.footer {
  margin-top: var(--step); padding-top: 26px;
  border-top: 1px solid var(--line);
  text-align: center;
}
.footer .logos { justify-content: center; }

/* ---------- logos ---------- */

/* One treatment for the whole strip, so nothing shouts over anything else.
   The site mark is a little larger because it is ours, but it carries the
   same restraint as the games beside it. Brightening on hover keeps them
   present without demanding attention while you are reading the page. */
.logos { display: flex; gap: 26px; align-items: center; flex-wrap: wrap; }

.logos img {
  height: 30px; width: auto;
  opacity: .42;
  filter: grayscale(1);
  transition: opacity .2s, filter .2s;
}
.logos img:hover { opacity: .85; filter: grayscale(.4); }

.logos .site-mark { height: 40px; opacity: .55; }
.logos .site-mark:hover { opacity: 1; filter: none; }

/* ---------- donation goal ---------- */

.goal .track {
  height: 8px; background: var(--sink);
  border: 1px solid var(--line);
  margin: 0 0 var(--tight);
}
.goal .fill { height: 100%; background: var(--indigo); }
.goal .figures { display: flex; justify-content: space-between; font-size: 13px; color: var(--dim); }
.goal .figures strong { color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---------- party ---------- */

.code {
  display: block; text-align: center;
  font: 700 34px/1 var(--font);
  letter-spacing: .28em; text-indent: .28em;
  color: var(--amber); background: var(--sink);
  border: 1px solid var(--line); border-top-color: var(--bevel);
  padding: 18px 10px;
}
.member {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line);
}
.member:last-child { border-bottom: none; padding-bottom: 0; }
.member:first-child { padding-top: 0; }
.member .who { display: flex; gap: 9px; align-items: center; }
.tag {
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  padding: 3px 8px; border: 1px solid var(--line); color: var(--dim);
}
.tag.host { color: var(--amber); border-color: var(--amber); }

/* ---------- challenges ---------- */

.challenge {
  background: var(--panel);
  border: 1px solid var(--line); border-top-color: var(--bevel);
  margin: 0 0 var(--step);
}
.challenge .bar {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 11px 16px 11px 19px;
  background: var(--raise); border-bottom: 1px solid var(--line);
  font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  position: relative;
}
.challenge .bar::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--amber);
}
.challenge .bar span:last-child { color: var(--dim); }
.challenge .body { padding: var(--pad); }

/* ---------- admin ---------- */

.thumb { width: 104px; height: 58px; object-fit: cover; background: #000; border: 1px solid var(--line); }

/* =======================================================================
   Mobile

   Two things matter on a phone. Touch targets have to be big enough to hit,
   and on the game screen the map has to be the thing you see, with the
   action button always within thumb reach rather than scrolled off above.
   ======================================================================= */

@media (hover: none) {
  /* Fingers are not mice. */
  button, .btn, nav.tabs a, nav.seg button { min-height: 44px; }
  input, select, textarea { min-height: 44px; }
}

@media (max-width: 1200px) {
  .panel { width: 380px; flex: 0 0 380px; }
  .stat { gap: 24px; }
  .stat div strong { font-size: 26px; }
}

@media (max-width: 900px) {
  /* The corner standings would sit on top of the map, so dock it in the panel. */
  .mini { position: static; width: auto; margin: 0 0 var(--step); backdrop-filter: none;
          background: var(--panel); }
  .mini-list { max-height: 140px; }

  .wrap { padding: 26px 14px 48px; }
  .brand { margin-bottom: 24px; }
  .brand img { max-width: 70%; }
  #under-play { justify-content: flex-start; }
  .wrap.tall .page-bottom { padding-top: 30px; }
  h1 { font-size: 25px; }
  .grid2 { grid-template-columns: 1fr; }
  .stat { gap: 20px; flex-wrap: wrap; }
  .logos { gap: 16px; }
  .logos img { height: 26px; }
  .challenge .bar { flex-wrap: wrap; gap: 4px; }
  .code { font-size: 26px; letter-spacing: .2em; text-indent: .2em; }
  nav.tabs, nav.seg { gap: 2px; }
  nav.tabs a, nav.seg button { flex: 1 1 auto; text-align: center; padding: 11px 10px; }
}

@media (max-width: 900px) {
  /* ---- the game screen ---- */
  .game { flex-direction: column; height: auto; }

  .panel {
    width: 100%; flex: none;
    border-right: 0; border-bottom: 1px solid var(--line);
    padding: 12px;
    overflow: visible;
  }
  /* The screenshot is the puzzle, so keep it big but never crop it. */
  .panel .shot-wrap { max-height: 34vh; }
  .panel img.shot { max-height: 34vh; object-fit: contain; }

  #map { height: 56vh; }

  /* Put the action within thumb reach instead of above the map. */
  #guess-box, #result-box {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
    background: var(--panel);
    border-top: 1px solid var(--bevel);
    padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
    max-height: 46vh; overflow-y: auto;
    margin: 0;
  }
  #guess-box button, #result-box button { width: 100%; }
  #guess-box #hint { margin-bottom: 8px; }

  /* Room underneath so the bar never covers the last of the map. */
  .game { padding-bottom: 118px; }

  .stat { padding: 12px; }
  .stat div strong { font-size: 20px; }
}

@media (max-width: 560px) {
  .wrap { padding: 20px 12px 40px; }
  h1 { font-size: 22px; }
  .card { padding: 16px; }
  .card > h2:first-child { margin: -16px -16px 16px; padding: 11px 16px; }
  .challenge .body { padding: 16px; }
  .row > button, .row > .btn { flex: 1 1 auto; }
  .member { flex-wrap: wrap; gap: 6px; }
  .goal .figures { font-size: 12px; }
  .code { font-size: 21px; }
  .thumb { width: 76px; height: 43px; }
}

/* Landscape phones have almost no height, so give the map most of it. */
@media (max-width: 900px) and (orientation: landscape) {
  .panel .shot-wrap, .panel img.shot { max-height: 42vh; }
  #map { height: 72vh; }
}
