/* Géomission — palette sampled from the real brand assets:
   graphisme/poster 11x17.jpg and graphisme/geomission.png
   forest #205C00 · grass #42AE01 · gold #FFCF06 · white · red #ED2900 */
:root {
  --forest: #205C00;   /* the dominant field colour of the poster */
  --grass: #42AE01;    /* the brighter panel green */
  --grass-lt: #6FD12E; /* lifted for text on dark */
  --gold: #FFCF06;
  --gold-warm: #FDD302;
  --red: #ED2900;      /* the poster reserves this for one thing only */

  /* sunrise ramp for the home screen's sunburst */
  --sun-deep: #F05423;
  --sun: #F47320;
  --sun-lt: #FDB515;

  --night: #0E2A00;    /* forest, darkened for page background */
  --deep: #143A00;

  --panel: #205c00a8;
  --line: #ffffff26;

  --ink: #F4F8EF;
  --dim: #A9C79A;

  --ok: var(--grass-lt);
  --warn: var(--gold);
  --bad: #FF6A4D;      /* the poster red, lifted for legibility on dark */
  --accent: var(--gold);
}
* { box-sizing: border-box; }

body {
  margin: 0;
  color: var(--ink);
  background: var(--night);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
  /* crisper type on the dark scene: smoothed glyphs + kerning/ligatures */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-kerning: normal;
}
/* consistent, brand-coloured keyboard focus — visible but only for keyboard use */
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 4px; }
:focus:not(:focus-visible) { outline: none; }
/* branded text selection */
::selection { background: var(--gold); color: #1B3D00; }
body.scenic {
  background: var(--night) url("backdrop.svg") center / cover fixed no-repeat;
}
/* Home screen: sunburst over the ridgeline, with a forest below it.
   The image lives on a fixed layer (.parallax-bg) that pans down slowly as the
   page scrolls, so the forest at the foot is revealed on the way down. */
body.dawn { background: var(--night); }
/* WEBSITE BUILD — the LOOPING VIDEO backdrop.
   The layer is pinned to the viewport and the video fills it. Nothing here depends
   on JavaScript: the backdrop must survive a failed script, and it must cover the
   page at ANY scroll position and any window size.

   REGRESSION THIS FIXES (2026-08-05). The rule that used to live here was replaced
   wholesale by the APP build's still-image rule during the 2026-08-04 video
   rebuild. Two things broke at once and neither threw an error:
     1. it pointed at `geo-app-bg.jpg`, which exists in geomission-app but has
        never existed in this website folder -> a silent 404 on every page load;
     2. it took the `> video` / `> .plane` sizing rules with it, so the <video>
        fell back to being a plain inline element: position static, object-fit
        contain, its natural 1280x720. The result was a video sitting in the
        document flow with the page running off the bottom of it onto bare
        background — which is exactly what "the background is broken" looked like.
   The sizing rules below are what was lost; keep them next to the layer they size. */
body.dawn .parallax-bg {
  position: fixed; top: 0; left: 0; z-index: -1; pointer-events: none;
  /* Explicit, not JS-assigned. The old layer was measured and sized in script; when
     that script went away the box had no height at all and the whole backdrop
     collapsed. A backdrop should not need JavaScript to have a size. */
  width: 100%; height: 100%;
  background: var(--night);
  will-change: transform;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
}
/* Everything mounted into the layer registers pixel-for-pixel in the same box, so
   DOM order alone decides what hides what. `cover` (not `contain`) is the whole
   point: contain letterboxes and leaves bare ground at the edges. */
body.dawn .parallax-bg > video,
body.dawn .parallax-bg > picture,
body.dawn .parallax-bg > picture > img,
body.dawn .parallax-bg > svg {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
/* The multiplane stack: the terrain cut-out and the scene.js canvases. Absolutely
   positioned in the same box as the video so the birds still pass BEHIND the
   ridgeline instead of floating over it. */
body.dawn .parallax-bg > .plane,
body.dawn .parallax-bg > .scene-life {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; object-fit: cover;
}
body.dawn .parallax-bg > .plane-fg { display: block; }
/* Freeze every CSS animation in the scene when it's off-screen or the tab is
   hidden (JS toggles .gm-paused); SMIL is paused separately via pauseAnimations().
   This is a no-op today (no JS toggles .gm-paused; kept for a future animated bg) — nothing animates while nothing's watching. */
body.dawn .parallax-bg.gm-paused * { animation-play-state: paused !important; }
/* Scrim: kept DELIBERATELY light so the artwork reads at its true brightness — a
   heavy scrim was washing it out and making it look darker than the source. Just
   enough tint low on the screen to seat the copy; the cards carry their own
   backgrounds, and text over the art leans on its own shadow (below). */
body.dawn::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background: linear-gradient(180deg, #0a220014 0%, #0a220030 50%, #0a220070 100%);
}
/* With the scrim this light, text sitting directly on the artwork earns its own
   contrast instead of dimming the whole picture to get it. */
body.dawn .hero .sub,
body.dawn .lead,
body.dawn .body { text-shadow: 0 1px 3px #000c, 0 0 10px #000a; }
/* Lift the content above the scrim WITHOUT touching .appbar — a `> *` rule here
   would out-specify `.appbar { position: sticky }` and silently unstick it. */
body.dawn > .wrap { position: relative; z-index: 1; }

/* ============ decorative brass frame (from the toolkit's .frame-ornate) ============
   A fixed double hairline + corner flourishes that frame the screen like the edge of
   an engraved compass case. Sits ABOVE the content (z 30) but is pointer-events:none
   and aria-hidden, so it can never swallow a tap or be announced. It hugs the safe
   area so it isn't clipped by a notch or the home indicator on an installed phone. */
body.dawn .frame-ornate {
  position: fixed; pointer-events: none; z-index: 15;   /* was 30 — UNDER the app bar
     (z 20) so the brass can never draw over the header panel */
  /* The top edge clears the app bar instead of crossing it. --frame-top is set in JS
     from the bar's real on-screen bottom, because that moves: the alpha notice pushes
     the bar down ~57px at rest, and it returns to 0 once the page scrolls and the bar
     sticks. No fixed offset can satisfy both, so the frame tracks it. The fallback keeps
     the original full-bleed look if JS never runs. */
  top: var(--frame-top, calc(6px + env(safe-area-inset-top)));
  right: calc(6px + env(safe-area-inset-right));
  bottom: calc(6px + env(safe-area-inset-bottom));
  left: calc(6px + env(safe-area-inset-left));
  border: 1.5px solid rgba(214, 172, 84, .8);
  border-radius: 20px;
  box-shadow: inset 0 0 0 1px #ffffff1a, inset 0 0 30px #0a1c0066, 0 0 12px #d9b55e26;
}
body.dawn .frame-ornate::before {
  content: ""; position: absolute; inset: 4px;
  border: 1px solid rgba(198, 154, 70, .38); border-radius: 16px;
}
.corner-fl { position: absolute; width: clamp(54px, 16vw, 104px); opacity: .6; }
.corner-fl.tl { top: 1px; left: 1px; }
.corner-fl.tr { top: 1px; right: 1px; transform: scaleX(-1); }
.corner-fl.bl { bottom: 1px; left: 1px; transform: scaleY(-1); }
.corner-fl.br { bottom: 1px; right: 1px; transform: scale(-1, -1); }

h1 { font-size: 18px; margin: 0; }
h2 {
  font-size: 12px; margin: 0 0 12px; color: var(--grass-lt);
  text-transform: uppercase; letter-spacing: .12em; font-weight: 700;
}
a { color: var(--gold); }

/* --- the lockup: white lowercase "géo", gold "MISSION", inside a white frame --- */
.wordmark {
  font-weight: 900; letter-spacing: -.02em; line-height: .95;
  text-transform: uppercase; color: var(--gold);
}
/* "Géo" / "Geo" comes from i18n with its own capital G — do not transform it. */
.wordmark .geo { color: #fff; text-transform: none; }
.logo-frame {
  display: inline-block; border: 3px solid #fff; border-radius: 3px;
  padding: 10px 20px 12px;
}
.tagline { color: #fff; font-style: italic; letter-spacing: .01em; }

button {
  min-height: 42px; padding: 0 15px; border: 0; border-radius: 10px;
  background: #2c6f06; color: var(--ink); font: inherit; font-weight: 600;
  cursor: pointer; transition: background .12s, transform .06s;
}
button:hover:not(:disabled) { background: #37850a; }
button:active:not(:disabled) { transform: translateY(1px); }
button.primary {
  background: var(--gold); color: #1B3D00; font-weight: 800; letter-spacing: .02em;
}
button.primary:hover:not(:disabled) { background: #ffd93a; }
button.danger { background: #4a1505; color: #ffb4a4; }
button.ghost { background: transparent; border: 1px solid var(--line); color: var(--ink); }
button.ghost:hover:not(:disabled) { background: #ffffff12; border-color: #fff; }
button:disabled { opacity: .38; cursor: not-allowed; }
button.sm { min-height: 32px; padding: 0 10px; font-size: 13px; }

input, textarea, select {
  width: 100%; padding: 10px 11px; border-radius: 9px;
  border: 1px solid var(--line); background: #0b2400; color: var(--ink);
  font: inherit;
}
input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--gold); box-shadow: 0 0 0 3px #ffcf0626;
}
input[type="range"] { padding: 0; border: 0; background: transparent; accent-color: var(--gold); }
textarea { resize: vertical; min-height: 76px; }
label { display: block; font-size: 12px; color: var(--dim); margin: 12px 0 5px; }

.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 14px; padding: 16px;
  backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px);
  /* lift the glass off the scene + a faint top highlight for a crisper edge */
  box-shadow: 0 10px 28px -12px #000a, inset 0 1px 0 #ffffff14;
}
.row { display: flex; gap: 8px; align-items: center; }
.grow { flex: 1; }
.muted { color: var(--dim); font-size: 13px; }

.tag {
  font-size: 10px; padding: 3px 8px; border-radius: 99px; font-weight: 800;
  letter-spacing: .08em; background: #ffffff14; color: var(--dim);
}
.tag.ar { background: #ffcf0626; color: var(--gold); }
.tag.popup { background: #42ae0133; color: var(--grass-lt); }

.err { color: var(--bad); font-size: 13px; }
.ok { color: var(--grass-lt); }
.mono {
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}

/* the X that marks the spot */
.xmark { color: var(--gold); font-weight: 900; transform: rotate(-8deg);
         display: inline-block; }

/* ---------------------------------------------------------------- app bar
   The logo pins to the top-left on every screen and always goes home. */
.appbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  background: #061a00d9;
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
/* Header controls must never wrap: at phone width "Sign in" was breaking onto two
   lines, which doubled the app bar's height and shoved the whole page down. */
.appbar button, .appbar .brand, .appbar .section-chip { white-space: nowrap; }
.brand {
  display: inline-flex; align-items: baseline; gap: 6px;
  text-decoration: none; padding: 4px 8px; border-radius: 8px;
  border: 2px solid #fff; line-height: 1;
}
.brand:hover { background: #ffffff12; }
.brand .wordmark { font-size: 17px; }
.brand .xmark { font-size: 12px; }

/* The current section, glued to the right of the logo and carried down the scroll. */
.section-chip {
  flex: none; align-self: center;
  font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gold); background: #ffcf061f; border: 1px solid #ffcf0647;
  padding: 5px 11px; border-radius: 99px; white-space: nowrap;
}
.section-chip:empty { display: none; }
/* Phone widths: the bar was overflowing — the section chip pushed the EN language
   button off the edge. The chip only names the section the tab bar already shows
   selected two rows below, so it's the cheapest thing to drop on a narrow screen. */
@media (max-width: 500px) {
  .section-chip { display: none; }
  .appbar { gap: 7px; padding: 10px 10px; }
  .brand { padding: 3px 6px; }
  .brand .wordmark { font-size: 15px; }
}

.langswitch { display: inline-flex; border: 1px solid var(--line); border-radius: 8px;
  overflow: hidden; }
.langswitch button {
  min-height: 30px; padding: 0 10px; border-radius: 0; background: transparent;
  font-size: 12px; font-weight: 800; letter-spacing: .06em; color: var(--dim);
}
.langswitch button[aria-pressed="true"] { background: var(--gold); color: #1B3D00; }

/* ---------------------------------------------------------------- tabs */
/* Wide screens: all 7 fit in one centred row inside a glass tray. */
/* WRAP, don't scroll. `nowrap` was fine at 7 tabs; adding Groups made 9 and pushed
   "Account" off the right edge on desktop. The standing rule for this strip is that every
   tab is reachable WITHOUT sideways scrolling — so it wraps to a second row instead. */
/* BALANCED wrap. Left unconstrained, 9 tabs fit 8-on-one-line and stranded "Account"
   alone on a second row, which reads as a bug rather than a design. Capping the strip
   well below the page width makes it break into two even rows at every desktop size;
   it still collapses gracefully on a phone. Same look, just not lopsided. */
.tabs { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center;
  max-width: 680px; margin: 0 auto;
  padding: 5px; border-radius: 13px; background: #0a2400cc; border: 1px solid #ffffff24;
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px); }


/* ---------------------------------------------------------------- our mission */
.pledge-banner { display: flex; align-items: baseline; gap: 12px; justify-content: center;
  flex-wrap: wrap; margin: 18px auto 0; max-width: 520px; padding: 14px 18px;
  border-radius: 14px; background: #ffcf0614; border: 1px solid #ffcf0640; }
.pledge-banner b { font-size: 40px; font-weight: 900; color: var(--gold); line-height: 1;
  font-variant-numeric: tabular-nums; }
.pledge-banner span { color: var(--ink); font-size: 14px; max-width: 22ch; }
/* Tabs are BRASS BUTTONS set into the engraved panel behind them: a warm metal rim,
   a lit top edge and a shadowed lower inside, so each one reads as a cast fitting
   rather than a flat chip. 44px min-height meets the touch-target guideline. */
.tab {
  flex: none; white-space: nowrap; scroll-snap-align: center;
  min-height: 44px; padding: 0 15px; border-radius: 10px;
  color: #EEE2BC; font-weight: 700; font-size: 13.5px;
  border: 1px solid rgba(198, 154, 70, .5);
  background: linear-gradient(180deg, #1a3d1299 0%, #0a2206cc 100%);
  box-shadow: inset 0 1px 0 #ffffff1f, inset 0 -3px 8px #00000057, 0 2px 4px #0000006b;
  text-shadow: 0 1px 2px #000a;
  transition: background .14s, color .14s, border-color .14s, box-shadow .14s;
}
.tab:hover { color: #fff; border-color: rgba(214, 172, 84, .85);
  background: linear-gradient(180deg, #24501899 0%, #0e2c08cc 100%); }
/* selected: the button lights up gold, like brass catching the sun */
.tab[aria-selected="true"] {
  color: var(--gold); border-color: rgba(255, 207, 6, .78);
  background: linear-gradient(180deg, #ffcf0e38 0%, #ffcf0e12 100%);
  box-shadow: inset 0 1px 0 #ffffff33, inset 0 -3px 8px #0000004d, 0 0 14px #ffcf0647;
}

/* PHONES: every tab reachable WITHOUT swiping sideways, so the row wraps to exactly
   two — 4 on top, 3 centred below. Each tab takes a fixed quarter-width so the grid
   is square instead of ragged, and a fixed min-height keeps both rows level even
   though "The experience" needs two lines. The glass tray drops away so the buttons
   sit directly on the engraved metal.
   NOTE: this block must stay AFTER the base `.tab` rule — same specificity, so
   source order decides, and `flex:none`/`nowrap` above would otherwise win. */
@media (max-width: 640px) {
  .tabbar { margin-bottom: 20px; }
  .tabs {
    flex-wrap: wrap; justify-content: center; gap: 7px;
    padding: 0; background: none; border: 0;
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .tab {
    flex: 0 1 calc(25% - 7px);
    min-width: 0; min-height: 50px; padding: 5px 6px;
    white-space: normal; font-size: 11.5px; line-height: 1.15; letter-spacing: .01em;
  }
}
.tabpanel[hidden] { display: none; }

/* --------------------------------------------------- difficulty + badges */
.diff-chip {
  display: inline-block; font-size: 10.5px; font-weight: 800; letter-spacing: .02em;
  padding: 1px 8px; border-radius: 99px; vertical-align: middle; text-transform: uppercase;
}
.diff-easy   { background: #2f7a1a33; color: #7fd94e; border: 1px solid #7fd94e55; }
.diff-medium { background: #d8a12a26; color: #ffcf06; border: 1px solid #ffcf0655; }
.diff-hard   { background: #ed290026; color: #ff7a5c; border: 1px solid #ed290066; }
.diff-extreme { background: #a21caf26; color: #e879f9; border: 1px solid #c026d366; }

/* family egg hunt */
.callout { background: #ffcf060f; border: 1px solid #ffcf0640; border-radius: 12px;
  padding: 14px 16px; color: var(--ink); font-size: 13.5px; line-height: 1.5; }
.kid-count { display: flex; gap: 6px; flex-wrap: wrap; }
.kc-btn { min-height: 34px; width: 38px; padding: 0; border-radius: 9px; font-weight: 800;
  background: #0b240066; color: var(--dim); border: 1px solid var(--line); }
.kc-btn.is-on { background: #ffcf0618; color: var(--gold); border-color: #ffcf0640; }
.kids { display: grid; gap: 12px; }
.kid-card { display: grid; gap: 6px; }
.player-no { font-weight: 800; color: var(--gold); font-size: 13px; white-space: nowrap;
  background: #ffcf0614; border: 1px solid #ffcf0640; border-radius: 99px; padding: 3px 11px; }
.cache-list { display: grid; gap: 7px; }
.cache-row { display: grid; grid-template-columns: 1fr 88px 88px auto; gap: 7px; align-items: center; }
.cache-row .coord { min-width: 0; }
@media (max-width: 560px) { .cache-row { grid-template-columns: 1fr 1fr auto; }
  .cache-row input:first-child { grid-column: 1 / -1; } }

/* mission comment threads */
.comments { margin-top: 10px; }
.comments summary { cursor: pointer; font-size: 12.5px; font-weight: 700; color: var(--grass-lt);
  list-style: none; padding: 4px 0; user-select: none; }
.comments summary::-webkit-details-marker { display: none; }
.cmt-body { padding: 4px 0 2px; }
.cmt { border-top: 1px solid var(--line); padding: 8px 0; }
.cmt:first-child { border-top: 0; }
.cmt-head { display: flex; align-items: center; gap: 8px; }
.cmt-head b { font-size: 12.5px; }
.cmt-at { color: var(--dim); font-size: 11px; }
.cmt-del { min-width: 24px; min-height: 24px; padding: 0 6px; margin-left: auto; background: transparent;
  color: var(--dim); font-size: 12px; }
.cmt-del:hover { color: var(--red); background: transparent; }
.cmt p { margin: 3px 0 0; font-size: 13px; color: var(--ink); }
.cmt-add { display: flex; gap: 8px; margin-top: 10px; }
.cmt-add input { flex: 1; min-width: 0; }

/* builder difficulty picker (kids → athletes) */
.diff-picker { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.diff-opt {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  min-height: 0; padding: 12px 6px; border-radius: 12px; cursor: pointer;
  border: 1px solid var(--line); background: #0b240066; color: var(--dim);
}
.diff-opt .diff-fig { width: 30px; height: 40px; color: var(--dim); }
.diff-opt b { font-size: 14px; color: var(--ink); }
.diff-opt small { font-size: 10.5px; color: var(--dim); }
.diff-opt.is-on { border-color: var(--gold); background: #ffcf0614; }
.diff-opt.is-on .diff-fig, .diff-opt.is-on b { color: var(--gold); }

/* the "your badges" strip */
.badge-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.badge-card {
  display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center;
  padding: 12px 6px; border-radius: 12px; border: 1px solid var(--line); background: #0b240066;
}
.badge-card b { font-size: 13.5px; }
.badge-card small { font-size: 11px; color: var(--dim); }
.badge-card.is-locked { opacity: .45; filter: grayscale(.7); }
.badge-svg { display: block; }

/* hoverable / tappable collectible badges + their popup card */
.badge-wrap { display: inline-flex; cursor: pointer; border-radius: 50%; outline: none;
  transition: transform .12s; }
.badge-wrap:hover, .badge-wrap:focus-visible { transform: translateY(-2px) scale(1.08); }
.badge-wrap.is-locked { opacity: .5; filter: grayscale(.65); }
.badge-backdrop { position: fixed; inset: 0; z-index: 59; background: #000a; opacity: 0;
  pointer-events: none; transition: opacity .14s; }
.badge-backdrop.show { opacity: 1; pointer-events: auto; }
.badge-pop { position: fixed; z-index: 60; width: 264px; max-width: calc(100vw - 24px);
  background: #0c2a00f5; border: 1px solid #ffffff2e; border-radius: 16px; padding: 16px 16px 14px;
  text-align: center; box-shadow: 0 18px 50px #000b; opacity: 0; pointer-events: none;
  transform: scale(.96); transition: opacity .12s, transform .12s;
  backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px); }
.badge-pop.show { opacity: 1; transform: scale(1); }
.badge-pop.as-modal { left: 50% !important; top: 50% !important;
  transform: translate(-50%, -50%) scale(1); pointer-events: auto; }
.badge-pop-art { display: flex; justify-content: center; margin-bottom: 8px;
  filter: drop-shadow(0 8px 16px #000a); }
.badge-pop-art.is-locked { opacity: .55; filter: grayscale(.7) drop-shadow(0 8px 16px #0007); }
.badge-pop-title { font-weight: 800; font-size: 17px; color: #fff; }
.badge-pop-sub { font-size: 12.5px; color: var(--gold); font-weight: 700; margin: 2px 0 8px; }
.badge-pop-desc { font-size: 13px; color: #cfe3bf; line-height: 1.45; }
.badge-pop-tag { margin-top: 11px; font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); }

/* the collectibles modal opened from the account menu */
.coll-card { max-width: 540px; width: 100%; max-height: 86vh; overflow: auto; }
.coll-h { margin: 16px 0 8px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--gold); }
/* the "Collectibles" item in the member dropdown */
.mm-coll, .mm-invite { display: flex; align-items: center; gap: 8px; width: 100%;
  justify-content: flex-start; min-height: 0; padding: 9px 10px; margin: 4px 0 2px;
  border-radius: 9px; font-weight: 700; }
.mm-coll { background: #ffcf0614; color: var(--gold); border: 1px solid #ffcf0640; }
.mm-coll:hover { background: #ffcf0622; }
.mm-invite { background: #42ae0114; color: var(--grass-lt); border: 1px solid #42ae0140; }
.mm-invite:hover { background: #42ae0122; }

/* welcome walkthrough */
.tour-back { position: fixed; inset: 0; z-index: 70; background: #04140acc; display: flex;
  align-items: center; justify-content: center; padding: 22px;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.tour-back[hidden] { display: none; }   /* author display:flex beats the UA [hidden] rule, so restate it */
.tour-card { position: relative; width: 380px; max-width: 100%; text-align: center;
  background: #0c2a00f5; border: 1px solid #ffffff26; border-radius: 18px; padding: 26px 22px 20px;
  box-shadow: 0 20px 60px #000b; }
.tour-card h2 { font-size: 20px; margin: 4px 0 8px; color: #fff; text-transform: none; letter-spacing: 0; }
.tour-card p { color: #cfe3bf; font-size: 14px; line-height: 1.55; margin: 0; }
.tour-icon { font-size: 46px; line-height: 1; }
.tour-skip { position: absolute; top: 12px; right: 12px; min-height: 0; padding: 4px 10px;
  background: transparent; color: var(--dim); font-size: 12px; }
.tour-dots { display: flex; gap: 7px; justify-content: center; margin: 18px 0 16px; }
.tour-dot { width: 7px; height: 7px; border-radius: 99px; background: #ffffff33; }
.tour-dot.on { background: var(--gold); width: 20px; }
.tour-nav { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tour-nav .primary { min-width: 120px; }

/* invite / share modal */
.invite-card { max-width: 420px; width: 100%; }
/* why the link goes to the site, not the app — stated where the link is copied */
.invite-hint { font-size: 11.5px; line-height: 1.5; margin: 6px 0 0; }
/* the app is opt-in: said plainly, in brand green rather than as a warning */
.invite-appnote {
  margin: 10px 0 0; padding: 10px 12px; border-radius: 10px;
  background: #42ae0114; border: 1px solid #42ae0140;
  color: var(--grass-lt); font-size: 12px; line-height: 1.55;
}
.invite-link { display: flex; gap: 8px; margin: 12px 0 14px; }
.invite-link input { flex: 1; min-width: 0; font: inherit; padding: 9px 11px; border-radius: 10px;
  border: 1px solid var(--line); background: #0b2400; color: var(--dim); }
.invite-btns { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px; }
.invite-b { display: flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer;
  min-height: 42px; padding: 0 12px; border-radius: 10px; font-weight: 700; font-size: 13.5px;
  background: #0b240066; border: 1px solid var(--line); color: var(--ink); text-decoration: none; }
.invite-b:hover { background: #205c0033; border-color: var(--grass); }

/* timed invite preview: a countdown chip, then a sign-in lock (z 55, under the
   auth modal at 60 so signing in still surfaces above the lock) */
.preview-chip { position: fixed; bottom: 14px; left: 50%; transform: translateX(-50%); z-index: 52;
  background: #0b2400e6; border: 1px solid #ffcf0640; color: var(--gold); font-weight: 700;
  font-size: 12.5px; padding: 6px 14px; border-radius: 99px; pointer-events: none;
  font-variant-numeric: tabular-nums;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.preview-lock { position: fixed; inset: 0; z-index: 55; display: flex; align-items: center;
  justify-content: center; padding: 24px; background: #04140af2;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.preview-card { max-width: 380px; width: 100%; text-align: center; background: #0c2a00;
  border: 1px solid #ffffff26; border-radius: 18px; padding: 30px 24px; box-shadow: 0 20px 60px #000c; }
.preview-card h2 { font-size: 20px; text-transform: none; letter-spacing: 0; color: #fff; margin: 6px 0 8px; }
.preview-card p { color: #cfe3bf; font-size: 14px; line-height: 1.55; margin: 0 0 18px; }
.preview-icon { font-size: 44px; }
.preview-card .primary { width: 100%; }

/* the hero medal in the popup comes alive: spinning sunburst, twinkles, glint */
.badge-hero .badge-rays { transform-box: fill-box; transform-origin: center;
  animation: badge-spin 16s linear infinite; }
.badge-hero .badge-spark { transform-box: fill-box; transform-origin: center;
  animation: badge-tw 2.4s ease-in-out infinite; }
.badge-hero .badge-spark:nth-of-type(2) { animation-delay: .5s; }
.badge-hero .badge-spark:nth-of-type(3) { animation-delay: 1s; }
.badge-hero .badge-spark:nth-of-type(4) { animation-delay: 1.5s; }
.badge-hero .badge-shine { animation: badge-glint 3.2s ease-in-out infinite; }
@keyframes badge-spin { to { transform: rotate(360deg); } }
@keyframes badge-tw { 0%, 100% { opacity: .25; transform: scale(.6); } 50% { opacity: 1; transform: scale(1.15); } }
@keyframes badge-glint { 0%, 100% { opacity: .18; } 50% { opacity: .4; } }
@media (prefers-reduced-motion: reduce) { .badge-hero * { animation: none !important; } }
.score-pill {
  font-weight: 800; color: var(--gold); background: #ffcf0614;
  border: 1px solid #ffcf0640; border-radius: 99px; padding: 3px 12px; font-size: 13px;
}

/* auto-difficulty readout in the builder */
.diff-readout { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.diff-readout .muted { font-size: 12px; }
.badge-grid-4 { grid-template-columns: repeat(auto-fit, minmax(94px, 1fr)); }

/* the leaderboard table */
.board-head, .board-row {
  display: grid; grid-template-columns: 40px 1fr auto; gap: 10px; align-items: center;
}
.board-head { padding: 0 14px 6px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--dim); }
.board-row { padding: 11px 14px; }
.board-row.is-you { border-color: var(--gold); background: #ffcf060d; }
.board-pos { font-size: 16px; font-weight: 800; text-align: center; }
.board-id { min-width: 0; }
.board-name { font-weight: 700; display: flex; align-items: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; }
.ach-mini { display: inline-flex; gap: 2px; flex: none; }
.board-sub { display: flex; align-items: center; gap: 5px; margin-top: 4px; flex-wrap: wrap; }
.board-time { font-size: 11.5px; color: var(--dim); }
.board-score { text-align: right; font-weight: 800; color: var(--gold); font-size: 17px; }
.board-score small { display: block; font-size: 9.5px; color: var(--dim); font-weight: 700;
  letter-spacing: .04em; }

/* ---------------------------------------------------------------- gallery */
.gallery {
  display: flex; gap: 14px; overflow-x: auto; scroll-snap-type: x mandatory;
  padding: 4px 0 14px; scrollbar-width: thin;
}
.gallery figure {
  flex: none; margin: 0; scroll-snap-align: center;
  width: min(78vw, 420px); border-radius: 14px; overflow: hidden;
  border: 1px solid var(--line); background: #0b2400; position: relative;
  box-shadow: 0 10px 28px -14px #000b;
}
.gallery img { display: block; width: 100%; height: 260px; object-fit: cover;
  transition: transform .5s ease; }
.gallery figure:hover img { transform: scale(1.05); }
@media (prefers-reduced-motion: reduce) { .gallery img { transition: none; } }
.gallery figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 26px 12px 10px;
  font-size: 12px; font-weight: 600; color: #fff;
  background: linear-gradient(#0000, #061a00e6);
}
.gallery-dots { display: flex; gap: 7px; justify-content: center; margin-top: 4px; }
.gallery-dots button {
  width: 24px; height: 24px; min-height: 0; padding: 0; background: none; border: 0;
  display: grid; place-items: center; cursor: pointer;
}
.gallery-dots button::before { content: ""; width: 8px; height: 8px; border-radius: 99px;
  background: #ffffff33; transition: width .2s; }
.gallery-dots button[aria-current="true"]::before { background: var(--gold); width: 22px; }

/* ---------------------------------------------------------------- stars */
.stars { display: inline-flex; gap: 2px; }
.stars button, .stars span {
  min-width: 24px; min-height: 24px; padding: 3px; background: none; border: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 17px; color: #ffffff33; cursor: pointer;
}
.stars span { cursor: default; }
.stars .on { color: var(--gold); }
.stars button:hover ~ button { color: #ffffff33; }

.mission-row { display: flex; gap: 14px; align-items: center; }
.mission-row .meta { flex: 1; min-width: 0; }
.mission-row h3 { margin: 0 0 3px; font-size: 16px; }
.mission-row .sub { color: var(--dim); font-size: 12.5px; }
.mission-row .mission-story { color: var(--ink); font-size: 13px; line-height: 1.5;
  margin: 8px 0 4px; max-width: 60ch;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* ------------------------------------------------- waypoint settings rows */
.wp-row {
  display: flex; align-items: center; gap: 8px; padding: 8px 9px;
  border: 1px solid var(--line); border-radius: 10px; background: #0b2400;
}
.wp-row.sel { border-color: var(--gold); background: #ffcf060d; }
.wp-row .idx {
  width: 24px; height: 24px; flex: none; display: grid; place-items: center;
  border-radius: 99px; background: #ffcf0618; color: var(--gold);
  font-weight: 800; font-size: 12px;
}
.wp-row { flex-wrap: wrap; }
.wp-row select { width: auto; flex: none; padding: 6px 8px; font-size: 12.5px; }
.wp-row .nm {
  flex: 1 1 90px; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: 13.5px;
}
/* the clue prompt, per waypoint */
.wp-row .clue-in {
  flex: 3 1 220px; min-width: 160px; width: auto;
  padding: 6px 9px; font-size: 12.5px; background: #061a00;
  border-color: #ffffff1f;
}
.wp-row .clue-in::placeholder { color: #6f8b63; }
.wp-row .clue-in:focus { border-color: var(--gold); box-shadow: 0 0 0 3px #ffcf0626; }
.wp-row .clue-in.missing { border-color: #ff6a4d80; }
.wp-row .x {
  min-height: 26px; width: 26px; padding: 0; border-radius: 7px;
  background: #4a1505; color: #ffb4a4; font-weight: 900; line-height: 1;
}
.wp-row .x:hover { background: #6b1f07; }

.panel-gold { border-color: #ffcf0640; }
.panel-gold h2 { color: var(--gold); }
.count-chip {
  font-size: 11px; font-weight: 800; letter-spacing: .06em;
  background: #ffcf0618; color: var(--gold); padding: 3px 9px; border-radius: 99px;
}

/* ---------------------------------------------------------------- info popover */
.info {
  width: 24px; height: 24px; min-height: 0; padding: 0; border-radius: 99px;
  background: #ffffff14; color: var(--gold); font-weight: 900; font-size: 12px;
}
.info-body {
  margin-top: 10px; padding: 10px 12px; border-radius: 10px;
  background: #0b2400; border: 1px solid var(--line);
  font-size: 12.5px; color: var(--dim); line-height: 1.6;
}
.info-body[hidden] { display: none; }

/* ------------------------------------------------- worked-examples popup
   A "?" beside the field it explains, opening a scrollable card of real examples.
   The row keeps the button on the label's line (labels are display:block). */
.ex-row { display: flex; align-items: center; gap: 8px; }
.ex-row label { margin-bottom: 0; }
.ex-back {
  position: fixed; inset: 0; z-index: 70; display: flex;
  align-items: center; justify-content: center; padding: 20px;
  background: #04140acc;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}
.ex-back[hidden] { display: none; }   /* author display:flex beats the UA [hidden] rule */
.ex-card {
  position: relative; width: 560px; max-width: 100%; max-height: 84vh; overflow: auto;
  background: #0c2a00f5; border: 1px solid #ffffff26; border-radius: 18px;
  padding: 22px 22px 18px; box-shadow: 0 20px 60px #000b;
}
.ex-card h2 { font-size: 13px; margin: 0 0 4px; }
.ex-close {
  position: absolute; top: 10px; right: 10px; min-height: 0;
  padding: 4px 10px; background: transparent; color: var(--dim); font-size: 13px;
}
.ex-close:hover { color: var(--ink); background: #ffffff12; }
.ex-intro { color: #cfe3bf; font-size: 13.5px; line-height: 1.55; margin: 0 0 14px; }
.ex-item {
  border-top: 1px solid var(--line); padding: 12px 0 2px;
}
.ex-item h3 { margin: 0 0 4px; font-size: 13.5px; color: var(--gold); line-height: 1.35; }
.ex-item p { margin: 0; font-size: 13px; color: #cfe3bf; line-height: 1.55; }
/* a line the author can lift straight into their clue box */
.ex-eg {
  margin-top: 7px !important; padding: 8px 11px; border-radius: 9px;
  background: #ffcf060f; border-left: 2px solid #ffcf0666;
  color: var(--ink) !important; font-style: italic;
}
.ex-tip {
  margin: 16px 0 0; padding: 10px 12px; border-radius: 10px;
  background: #42ae0114; border: 1px solid #42ae0140;
  color: var(--grass-lt); font-size: 12.5px; line-height: 1.55;
}

/* ------------------------------------------------- auth: the two front doors
   Signing in and creating an account are the two reasons anyone opens this dialog,
   so they're a segmented control at the top — equal weight, both visible — instead
   of one being a footnote link under the other. */
.au-seg {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  padding: 4px; margin-bottom: 16px;
  background: #0b240099; border: 1px solid var(--line); border-radius: 11px;
}
.au-seg[hidden] { display: none; }
.au-seg button {
  min-height: 38px; padding: 0 8px; border-radius: 8px;
  background: transparent; color: var(--dim); font-size: 13.5px; font-weight: 700;
}
.au-seg button:hover { color: var(--ink); background: #ffffff0d; }
.au-seg button[aria-selected="true"] {
  background: #ffcf0e26; color: var(--gold);
  box-shadow: inset 0 0 0 1px #ffcf0666;
}
/* a text link that happens to be a <button> (keyboard + a11y for free) */
.linkish {
  min-height: 0; padding: 6px 0; margin-top: 10px;
  background: transparent; color: var(--gold);
  font-size: 12.5px; font-weight: 600; text-decoration: underline;
  text-underline-offset: 3px;
}
.linkish:hover { background: transparent; color: #ffe25e; }
.linkish[hidden] { display: none; }
/* neutral, non-alarming feedback (a reset link is on its way — not an error) */
.notebox {
  margin-top: 12px; padding: 11px 13px; border-radius: 10px;
  background: #42ae0114; border: 1px solid #42ae0140;
  color: var(--grass-lt); font-size: 12.5px; line-height: 1.55;
}
.notebox[hidden] { display: none; }

/* ---------------------------------------------------------------- auth */
.authbtn { min-height: 30px; padding: 0 11px; font-size: 12px; font-weight: 800;
  letter-spacing: .04em; }
.whoami { display: inline-flex; align-items: center; gap: 7px; font-size: 12px;
  color: var(--dim); white-space: nowrap; }
.whoami .role { font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  font-size: 10px; padding: 3px 8px; border-radius: 99px; }
.role.owner { background: #ffcf0626; color: var(--gold); }
.role.member { background: #42ae0133; color: var(--grass-lt); }
.role.visitor { background: #ffffff14; color: var(--dim); }

/* The red lock a visitor meets on a gated control.
   Dimming is a scrim, never `opacity` — opacity on the parent would also fade
   the tooltip and the lock badge, and there's no way to undo it on a child. */
.locked { position: relative; cursor: not-allowed; border-radius: 10px; }
.locked > * { pointer-events: none; }
.locked::before {
  content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit;
  background: #0e2a00b0;
}
/* a red "no entry" disc: red circle, white bar */
.locked::after {
  content: ""; position: absolute; z-index: 2; top: 50%; left: 50%;
  width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 99px;
  background: var(--red) linear-gradient(#fff, #fff) center / 12px 2.5px no-repeat;
  opacity: 0; transition: opacity .12s; box-shadow: 0 2px 8px #0007;
}
.locked:hover, .locked:focus-visible {
  outline: 2px solid var(--red); outline-offset: 2px;
}
.locked:hover::after, .locked:focus-visible::after { opacity: 1; }
.locked:hover .lock-tip, .locked:focus-visible .lock-tip { opacity: 1; }
/* Small red writing, not a filled pill — it reads as a warning, not a button. */
.lock-tip {
  position: absolute; z-index: 3; left: 50%; bottom: calc(100% + 6px);
  transform: translateX(-50%); pointer-events: none; opacity: 0; transition: opacity .12s;
  color: #FF6A4D; font-size: 11px; font-weight: 700; letter-spacing: .02em;
  white-space: nowrap; text-shadow: 0 1px 3px #000c, 0 0 10px #000a;
}

/* full-screen gate on builder / player */
.gatewall {
  position: fixed; inset: 0; z-index: 50; display: grid; place-items: center;
  background: #061a00f2; padding: 24px; text-align: center;
}
.gatewall > div { max-width: 360px; }
.gatewall .lockmark { font-size: 44px; color: var(--red); line-height: 1; }
.gatewall h1 { font-size: 24px; margin: 14px 0 8px; }

/* ---------------------------------------------------------------- modal */
.modal { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center;
  background: #041200e0; padding: 20px; }
.modal[hidden] { display: none; }
.modal .card { width: 100%; max-width: 380px; background: var(--panel-solid, #0b2400);
  border: 1px solid var(--line); border-radius: 16px; padding: 20px; }
.modal h2 { color: var(--gold); font-size: 13px; }
.modal .switch { background: none; border: 0; color: var(--gold); font-size: 12.5px;
  min-height: 0; padding: 6px 0; text-decoration: underline; cursor: pointer; }

/* ---------------------------------------------------------------- account */
.balance { font-size: 34px; font-weight: 900; color: var(--gold); line-height: 1;
  font-variant-numeric: tabular-nums; }
.balance small { font-size: 13px; font-weight: 600; color: var(--dim);
  margin-left: 6px; letter-spacing: .04em; }
.shop { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (max-width: 640px) { .shop { grid-template-columns: 1fr; } }
.shop .item { border: 1px solid var(--line); border-radius: 12px; padding: 12px;
  background: #0b2400; text-align: center; }
.shop .item b { display: block; font-size: 18px; color: var(--gold); }
.shop .item span { font-size: 12px; color: var(--dim); }
.shop .item { position: relative; }
.shop .item button { width: 100%; margin-top: 10px; }
.shop .item .per { display: block; font-size: 11px; color: var(--dim);
  font-variant-numeric: tabular-nums; margin-top: 2px; }
.shop .item .best { position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
  font-size: 9px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  background: var(--gold); color: #1B3D00; padding: 2px 8px; border-radius: 99px;
  white-space: nowrap; }

.paybox { margin-top: 12px; display: grid; gap: 6px; }
.payrow { display: flex; align-items: center; gap: 10px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 9px; background: #0b2400; }
.payrow span { color: var(--dim); font-size: 12px; }
.payrow b { margin-left: auto; font-family: ui-monospace, monospace; color: var(--gold);
  font-size: 14px; user-select: all; }

/* builder: how-to steps */
#howto .steps { counter-reset: step; list-style: none; margin: 0; padding: 0;
  display: grid; gap: 10px; }
#howto .steps li { position: relative; padding-left: 34px; font-size: 13.5px;
  line-height: 1.5; color: var(--ink); }
#howto .steps li::before { counter-increment: step; content: counter(step);
  position: absolute; left: 0; top: -1px; width: 24px; height: 24px;
  display: grid; place-items: center; border-radius: 99px;
  background: #ffcf0618; color: var(--gold); font-weight: 800; font-size: 12px; }
#howto p { margin: 14px 0 0; }

/* builder: trail-icon picker */
.iconpick { display: flex; gap: 8px; flex-wrap: wrap; }
.iconbtn { width: 44px; height: 44px; padding: 0; border-radius: 10px;
  background: #0b2400; border: 1px solid var(--line); color: var(--dim);
  display: grid; place-items: center; cursor: pointer; }
.iconbtn:hover { border-color: var(--gold); color: var(--ink); }
.iconbtn.on { border-color: var(--gold); background: #ffcf0618; color: var(--gold); }

.ledger { display: grid; gap: 6px; max-height: 260px; overflow-y: auto; }
.ledger .tx { display: flex; align-items: baseline; gap: 10px; font-size: 12.5px;
  padding: 7px 9px; border-radius: 8px; background: #0b2400; }
.ledger .tx .when { color: var(--dim); font-size: 11px; font-variant-numeric: tabular-nums; }
.ledger .tx .amt { margin-left: auto; font-weight: 800; font-variant-numeric: tabular-nums; }
.ledger .tx .amt.pos { color: var(--grass-lt); }
.ledger .tx .amt.neg { color: var(--bad); }

.warnbox { border: 1px solid #ff6a4d55; background: #ff6a4d12; border-radius: 10px;
  padding: 10px 12px; font-size: 12.5px; color: #ffb9a8; }

/* ---------------------------------------------------------------- owner: access */
.panel-owner { border-color: #ffcf0666; box-shadow: inset 0 0 0 1px #ffcf0614; }
.panel-owner h2 { color: var(--gold); }

.usertable { display: grid; gap: 6px; }
.usertable .u {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 9px; background: #0b2400;
  font-size: 13px; flex-wrap: wrap;
}
.usertable .u .em { flex: 1 1 160px; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.usertable .u .bal { font-variant-numeric: tabular-nums; color: var(--gold);
  font-weight: 800; }
.usertable .u .code { font-family: ui-monospace, monospace; font-size: 11px;
  color: var(--dim); letter-spacing: .08em; }

.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
@media (max-width: 640px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stats .s { border: 1px solid var(--line); border-radius: 10px; padding: 10px;
  background: #0b2400; text-align: center; }
.stats .s b { display: block; font-size: 20px; color: var(--gold);
  font-variant-numeric: tabular-nums; }
.stats .s span { font-size: 11px; color: var(--dim); text-transform: uppercase;
  letter-spacing: .06em; }

/* ---------------------------------------------------------------- referrals */
/* ------------------------------------------------- pending transfer queue */
.pending-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px; border-radius: 10px; background: #0b2400;
  border: 1px solid #ffcf0640;
}
.pending-row .who { flex: 1 1 180px; min-width: 0; }
.pending-row .who b { display: block; font-size: 13.5px; }
.pending-row .who span { font-size: 11.5px; color: var(--dim);
  font-family: ui-monospace, monospace; }
.pending-row .amt { font-size: 18px; font-weight: 900; color: var(--gold);
  font-variant-numeric: tabular-nums; }

/* The flashing Send button: it should nag. */
@keyframes sendpulse {
  0%, 100% { box-shadow: 0 0 0 0 #ffcf0699; }
  50%      { box-shadow: 0 0 0 7px #ffcf0600; }
}
button.flash { animation: sendpulse 1.25s ease-out infinite; }
@media (prefers-reduced-motion: reduce) {
  button.flash { animation: none; outline: 2px solid var(--gold); outline-offset: 2px; }
}

/* the count badge on the owner's queue heading */
.queue-badge {
  font-size: 11px; font-weight: 800; letter-spacing: .06em;
  background: var(--red); color: #fff; padding: 3px 9px; border-radius: 99px;
}
.queue-badge:empty { display: none; }

.pending-note { color: var(--gold); font-size: 12.5px; font-weight: 600; }
.balance small.pending { color: var(--gold); opacity: .75; }

/* ---------------------------------------------------------------- member menu */
.authbox { position: relative; }
.member { position: relative; }
.memberchip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 30px; padding: 0 10px; border-radius: 8px;
  background: #ffcf0618; border: 1px solid #ffcf0647; color: var(--gold);
  font-size: 12px; font-weight: 800; letter-spacing: .04em; cursor: pointer;
}
.memberchip.owner { background: #ffcf0626; }
.memberchip.member { background: #42ae0126; border-color: #42ae0155; color: var(--grass-lt); }
.memberchip.visitor { background: #ffffff10; border-color: var(--line); color: var(--dim); }
.memberchip .caret { font-size: 10px; opacity: .8; }

.membermenu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 40;
  width: min(300px, 92vw); padding: 14px;
  background: #04190a; border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 44px #0009; text-align: left;
}
.membermenu[hidden] { display: none; }
.mm-id { display: flex; align-items: center; gap: 8px; }
.mm-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: 14px; font-weight: 700; color: var(--ink); }
.mm-bal { margin: 12px 0; padding: 12px; border-radius: 10px; background: #0b2400;
  border: 1px solid var(--line); }
.mm-bal span.mm-bal-label { font-size: 11px; color: var(--dim);
  text-transform: uppercase; letter-spacing: .08em; }
.mm-bal b { display: block; margin-top: 2px; font-size: 26px; color: var(--gold);
  font-variant-numeric: tabular-nums; }
.mm-bal b small { font-size: 12px; font-weight: 600; color: var(--dim); }
.mm-send h4 { margin: 0 0 4px; font-size: 13px; color: var(--gold); }
.mm-send .muted { margin: 0 0 8px; font-size: 12px; }
.mm-foot { display: flex; align-items: center; gap: 10px; margin-top: 12px;
  padding-top: 12px; border-top: 1px solid var(--line); }
.mm-foot .mm-account { flex: 1; font-size: 13px; }

.refcode {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: ui-monospace, monospace; font-size: 22px; font-weight: 800;
  letter-spacing: .22em; color: var(--gold);
  background: #ffcf0614; border: 1px dashed #ffcf0666; border-radius: 10px;
  padding: 10px 16px;
}

/* --- owner tools inside the member dropdown (mint + grant) --- */
.mm-owner { margin: 12px 0; padding: 12px; border-radius: 10px;
  background: #1c130033; border: 1px solid #ffcf0633; }
.mm-owner-h { margin: 0 0 8px; font-size: 11px; color: var(--gold);
  text-transform: uppercase; letter-spacing: .08em; }
.mm-owner .muted { font-size: 12px; }
.mm-owner select { margin-top: 6px; }
.mm-owner .mm-grant { padding-top: 10px; border-top: 1px dashed #ffffff1f; }
.mm-console { display: block; margin: 8px 0 2px; padding: 8px 10px; border-radius: 9px;
  font-size: 13px; font-weight: 700; color: var(--gold);
  background: #ffcf060f; border: 1px solid #ffcf0630; text-align: center; }
.mm-console:hover { background: #ffcf061c; }

/* --- welcome toast (invited friend redeems a code) --- */
.gm-toast { position: fixed; left: 50%; bottom: 22px; transform: translate(-50%, 24px);
  z-index: 80; max-width: min(380px, 92vw); padding: 14px 18px; border-radius: 14px;
  background: linear-gradient(160deg, #10380a, #0a2600); color: #fff; cursor: pointer;
  border: 1px solid #ffcf0655; box-shadow: 0 16px 44px #000b; opacity: 0;
  transition: transform .38s cubic-bezier(.2,.9,.3,1.2), opacity .38s; }
.gm-toast.in { transform: translate(-50%, 0); opacity: 1; }
.gm-toast b { display: block; font-size: 15px; color: var(--gold); }
.gm-toast span { display: block; margin-top: 4px; font-size: 13px; color: #d6ebc9; line-height: 1.45; }

/* --- invite modal: code row, direct-send, redeem note --- */
.invite-lbl { display: block; margin: 12px 0 5px; font-size: 12px; color: var(--dim); }
.invite-code-row { display: flex; align-items: center; gap: 10px; }
.invite-code { flex: 1; font-family: ui-monospace, monospace; font-size: 20px; font-weight: 800;
  letter-spacing: .2em; color: var(--gold); background: #ffcf0614;
  border: 1px dashed #ffcf0666; border-radius: 10px; padding: 8px 14px; text-align: center; }
.invite-send { display: flex; gap: 8px; }
.invite-send input { flex: 1; min-width: 0; }
.invite-vialabel { margin: 12px 0 8px; font-size: 12px; }
.invite-note { margin: 12px 0 4px; font-size: 12px; line-height: 1.5;
  padding: 10px 12px; border-radius: 10px; background: #42ae010f; border: 1px solid #42ae0130; }

/* --- owner registries: scroll once they outgrow the panel, saving screen space --- */
.owner-scroll { max-height: 300px; overflow-y: auto; padding-right: 4px; }
.owner-scroll::-webkit-scrollbar { width: 8px; }
.owner-scroll::-webkit-scrollbar-thumb { background: #ffffff1f; border-radius: 8px; }

/* --- get-the-app band (QR + install button) --- */
.install-band { display: flex; align-items: center; gap: 22px; margin: 22px auto 6px;
  max-width: 640px; flex-wrap: wrap; justify-content: center; text-align: left;
  background: linear-gradient(150deg, #12360033, #0b240055);
  border: 1px solid #ffcf0633; }
.install-copy { flex: 1; min-width: 240px; }
.install-copy h2 { color: var(--gold); }
.install-copy .primary { margin-top: 14px; min-width: 180px; }
.install-hint { margin-top: 12px; font-size: 13px; line-height: 1.5; max-width: 40ch; }
.install-qr { flex: none; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.qr-card { background: #fff; padding: 12px; border-radius: 14px; line-height: 0;
  box-shadow: 0 8px 24px #0007; }
.qr-card img { display: block; width: 150px; height: 150px; }
.install-qr span { font-size: 12px; }
@media (max-width: 520px) {
  .install-band { flex-direction: column-reverse; text-align: center; }
  .install-copy { min-width: 0; }
  .install-hint { margin-left: auto; margin-right: auto; }
}

/* ── Alpha notice ──────────────────────────────────────────────────────────────
   A slim red bar above the header. Deliberately NOT a modal: it must set
   expectations without standing between a tester and the product. Dismiss is
   session-only, so every fresh visit re-states that this is early software. */
.alpha-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  background: #7f1d1d;              /* deep red — reads as "notice", not "error" */
  color: #fee2e2;
  font-size: 13px;
  line-height: 1.35;
  border-bottom: 1px solid #b91c1c;
  position: relative;
  z-index: 60;                      /* above the appbar's own stacking */
}
.alpha-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #f87171;
  flex: none;
  box-shadow: 0 0 0 3px rgba(248, 113, 113, .22);
}
/* Only the MESSAGE span grows. This used to be span:not(.alpha-dot), which also
   caught the version pill and stretched it into an empty rounded box. */
.alpha-bar span:not(.alpha-dot):not(.alpha-ver) { flex: 1; min-width: 0; }
.alpha-x {
  flex: none;
  background: none;
  border: 0;
  color: #fecaca;
  font-size: 15px;
  line-height: 1;
  padding: 4px 6px;
  cursor: pointer;
  border-radius: 6px;
}
.alpha-x:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.alpha-x:focus-visible { outline: 2px solid #fecaca; outline-offset: 1px; }
@media (max-width: 480px) {
  .alpha-bar { font-size: 12px; padding: 6px 10px; }
}

/* ── Merch ────────────────────────────────────────────────────────────────────
   Line-art mock-ups rather than photos: nothing has been printed yet, and a
   photoreal render of a product that doesn't exist reads as a promise. */
.merch-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px; margin-top: 14px;
}
.merch-card { text-align: center; padding: 14px; }
.merch-art { display: flex; justify-content: center; margin-bottom: 8px; }
.merch-svg { width: 120px; height: 100px; }
.merch-card b { display: block; color: var(--gold); margin-bottom: 2px; }
.merch-card small { display: block; line-height: 1.45; }
.merch-note {
  margin: 14px 0 0; padding: 10px 12px; border-radius: 10px;
  background: #42ae0114; border: 1px solid #42ae0140;
  color: var(--grass-lt); font-size: 12.5px; line-height: 1.55; text-align: center;
}

/* Build id — quiet by design: useful to a tester, invisible to everyone else. */
.build-chip {
  margin: 0 0 14px; font-size: 11.5px; color: #ffffff6b;
  display: flex; align-items: center; gap: 6px;
}
.build-chip code {
  font-family: ui-monospace, monospace; font-size: 11px;
  background: #ffffff12; padding: 2px 7px; border-radius: 6px; color: #ffffff9e;
}

/* Version pill inside the alpha bar — sets the "which build" expectation up front. */
.alpha-ver {
  /* flex:none alone still lets it inherit a stretched basis in some layouts — width:auto
     + align-self keeps it hugging the text instead of trailing an empty rounded box. */
  flex: 0 0 auto; width: auto; align-self: center;
  font-weight: 700; font-size: 11px; letter-spacing: .3px;
  background: #fecaca24; color: #fee2e2; padding: 2px 7px; border-radius: 999px;
  border: 1px solid #fecaca3d;
}

/* Report action — quiet until needed. */
.report-btn { margin-top: 8px; opacity: .75; }
.cmt-report { background: none; border: 0; color: #ffb4b4; font-size: 13px;
  cursor: pointer; padding: 2px 6px; margin-left: 4px; border-radius: 6px; }
.cmt-report:hover { background: #ffffff14; }

/* ── Accessibility ─────────────────────────────────────────────────────────────
   WCAG 2.2 (2.5.8): interactive targets >= 24x24. Visuals stay small; the tap area
   grows via padding/min-size. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: 8px; top: -60px; z-index: 100; background: var(--gold);
  color: #1b3d00; font-weight: 800; padding: 10px 14px; border-radius: 10px;
  transition: top .15s; }
.skip-link:focus { top: 8px; }

/* Completions wall — quiet social proof under a mission's title. */
.wall-line { margin-top: 4px; font-size: 12.5px; color: var(--grass-lt);
  display: flex; gap: 6px; align-items: center; }

/* Build guidance cards — teaching, not a picker. */
.sug-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px; margin-top: 10px; }
.sug-card { background: #ffffff0d; border: 1px solid #ffffff1a; border-radius: 12px;
  padding: 11px 12px; }
.sug-card b { color: var(--gold); display: block; margin-bottom: 3px; }
.sug-what { margin: 0 0 4px; font-size: 13px; line-height: 1.45; }
.sug-tip { margin: 0 0 4px; font-size: 12px; line-height: 1.45; }
.sug-eg { margin: 0; font-size: 12px; font-style: italic; color: var(--grass-lt); }
.sug-derived { margin-top: 10px; font-size: 12.5px; }

/* Groups — plain and legible: a leader reads this outdoors, on a phone, in gloves. */
.grp-private { margin: 6px 0 0; padding: 9px 12px; border-radius: 10px;
  background: #42ae0114; border: 1px solid #42ae0140; color: var(--grass-lt);
  font-size: 12.5px; line-height: 1.55; }
.grp-row { display: flex; gap: 8px; flex-wrap: wrap; }
.grp-row input { flex: 1; min-width: 120px; min-height: 42px; }
.grp-codein { max-width: 110px; text-align: center; letter-spacing: 3px;
  text-transform: uppercase; font-weight: 800; }
.grp-card { margin-bottom: 10px; }
.grp-code { font-family: ui-monospace, monospace; font-size: 18px; font-weight: 800;
  letter-spacing: 3px; color: var(--gold); background: #ffffff12;
  padding: 4px 10px; border-radius: 8px; }
.grp-stats { margin: 6px 0 0; font-size: 12.5px; }
.grp-board { margin: 8px 0 0; padding-left: 20px; font-size: 13px; }
.grp-board li { display: flex; gap: 8px; justify-content: space-between; margin: 3px 0; }
.grp-you { margin: 8px 0 6px; font-size: 12.5px; color: var(--grass-lt); }

/* ── Closed-testing gate ──────────────────────────────────────────────────────
   .gate-locked is set on <html> IN THE MARKUP, not by script. That matters: it
   means the app is hidden from the very first paint, and it stays hidden if
   JavaScript fails or is disabled — the gate fails CLOSED. Script only ever
   REMOVES the class, after a correct code. */
html.gate-locked body > *:not(.gate) { display: none !important; }
html.gate-locked { background: #0E2A00; }

.gate {
  position: fixed; inset: 0; z-index: 99999;
  display: grid; place-items: center; padding: 24px;
  background: radial-gradient(120% 90% at 50% 30%, #17420a 0%, #0E2A00 60%, #071900 100%);
}
.gate-card {
  width: min(380px, 100%); text-align: center;
  background: rgba(0, 0, 0, .34);
  border: 1px solid rgba(255, 207, 6, .30);
  border-radius: 16px; padding: 28px 24px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .45);
}
.gate-card h1 {
  margin: 0 0 2px; font-size: 26px; letter-spacing: .5px; color: #FFCF06;
}
.gate-sub { margin: 0 0 20px; font-size: 12.5px; color: #cfe3c0; opacity: .85; }
.gate-card label {
  display: block; text-align: left; font-size: 12px;
  color: #cfe3c0; margin: 0 0 6px; letter-spacing: .3px;
}
.gate-card input {
  width: 100%; box-sizing: border-box; padding: 13px 14px; font-size: 16px;
  border-radius: 10px; border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(0, 0, 0, .35); color: #fff;
}
.gate-card input:focus { outline: 2px solid #FFCF06; outline-offset: 1px; }
.gate-card button {
  width: 100%; margin-top: 14px; padding: 13px; font-size: 15px; font-weight: 700;
  border: 0; border-radius: 10px; cursor: pointer;
  background: #FFCF06; color: #123000;
}
.gate-card button:hover { filter: brightness(1.06); }
.gate-err { margin: 12px 0 0; font-size: 13px; color: #ffb4a8; }
@media (prefers-reduced-motion: reduce) { .gate * { transition: none !important; } }

/* ── Family egg hunt ──────────────────────────────────────────────────────────
   This panel was unreadable because its text sat DIRECTLY on the animated
   backdrop with nothing behind it — light type over a bright sunrise. Every other
   panel in the app has a bed to sit on; this one never got one. */
#p-family .callout {
  background: linear-gradient(180deg, rgba(20, 58, 8, .92), rgba(11, 34, 4, .94));
  border: 1px solid rgba(255, 207, 6, .34);
  border-left: 4px solid #FFCF06;
  border-radius: 12px;
  padding: 16px 18px;
  color: #eaf5e2;
  font-size: 14.5px;
  line-height: 1.62;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .34);
}
#family-setup {
  background: linear-gradient(180deg, rgba(16, 46, 6, .90), rgba(9, 28, 3, .93));
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 14px;
  padding: 18px 18px 20px;
  margin-top: 16px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .32);
}
#p-family h2 {
  color: #FFCF06;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .65);   /* legible over any backdrop frame */
}
#family-setup label {
  color: #eaf5e2; font-size: 14px; font-weight: 600; letter-spacing: .2px;
}
#p-family .kid-count button {
  min-width: 44px; min-height: 44px;            /* WCAG 2.5.8 target size */
  border-radius: 10px;
  border: 1px solid rgba(255, 207, 6, .38);
  background: rgba(0, 0, 0, .30); color: #fff; font-weight: 700;
}
#p-family .kid-count button[aria-pressed="true"],
#p-family .kid-count button.on { background: #FFCF06; color: #123000; border-color: #FFCF06; }
#p-family .kids input {
  background: rgba(0, 0, 0, .34);
  border: 1px solid rgba(255, 255, 255, .20);
  color: #fff; border-radius: 9px; padding: 11px 12px; font-size: 16px;
}
#p-family .kids input:focus { outline: 2px solid #FFCF06; outline-offset: 1px; }
#p-family #family-gate {
  background: rgba(9, 28, 3, .90);
  border: 1px dashed rgba(255, 207, 6, .40);
  border-radius: 12px; padding: 22px; color: #eaf5e2;
}
