/*
 * Beacon UI.
 *
 * The layout is a grid, not a stack of absolutely-positioned cards. The old map
 * had a floating panel that grew over its own controls and, on a phone, covered
 * the map it was annotating. Nothing here overlaps the map except the two
 * elements that are meant to: the history bar and the toast.
 */

:root {
  --bg: #0f1418;
  --panel: #161d23;
  --panel-2: #1b242b;
  --text: #e8eef2;
  --muted: #93a5b1;
  --border: #26323a;
  --accent: #4ea3d6;
  --live: #5ac47e;
  --warn: #e0b357;
  --alert: #e0785a;
  --sidebar-w: 360px;
  --radius: 12px;
  --safe-b: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}

button, input, select { font: inherit; color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 650; }
.muted { color: var(--muted); font-size: 12.5px; margin: 0; }

/* ----------------------------------------------------------------- shell */

#shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  height: 100%;
}

#mapwrap { position: relative; overflow: hidden; }
#map { position: absolute; inset: 0; }

#sidebar {
  display: grid;
  grid-template-rows: auto auto 1fr;   /* header, tabs, scrolling panes */
  min-height: 0;                        /* lets the pane scroll, not the page */
  background: var(--panel);
  border-right: 1px solid var(--border);
  z-index: 2;
}

/* ---------------------------------------------------------------- header */

#side-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 10px;
  border-bottom: 1px solid var(--border);
}
.brand { flex: 1; min-width: 0; }
.brand h1 { font-size: 17px; letter-spacing: .2px; }

#sheet-toggle { display: none; }

.conn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
  margin-top: 2px;
}
.conn::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--muted);
}
.conn[data-state="live"] { color: var(--live); }
.conn[data-state="live"]::before { background: var(--live); animation: pulse 2s infinite; }
.conn[data-state="reconnecting"] { color: var(--warn); }
.conn[data-state="reconnecting"]::before { background: var(--warn); }
.conn[data-state="error"] { color: var(--alert); }
.conn[data-state="error"]::before { background: var(--alert); }

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(90,196,126,.55); }
  70%      { box-shadow: 0 0 0 6px rgba(90,196,126,0); }
}

.icon-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 8px;
  width: 32px; height: 32px;
  cursor: pointer;
  flex: none;
}
.icon-btn:hover { color: var(--text); border-color: #3b4a55; }

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

#tabs {
  display: flex;
  gap: 2px;
  padding: 8px 10px 0;
  border-bottom: 1px solid var(--border);
}
#tabs button {
  flex: 1;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  padding: 8px 4px 9px;
  cursor: pointer;
  border-radius: 6px 6px 0 0;
  font-size: 13px;
}
#tabs button:hover { color: var(--text); background: rgba(255,255,255,.03); }
#tabs button.active { color: var(--text); border-bottom-color: var(--accent); }

.panes { position: relative; min-height: 0; overflow: hidden; }
.pane {
  display: none;
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 10px 12px calc(16px + var(--safe-b));
}
.pane.active { display: block; }

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

.card {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.card:hover { border-color: #3b4a55; }
.card.selected { border-color: var(--accent); background: #1d2933; }
.card.is-stale { opacity: .82; }

.card__top { display: flex; align-items: center; gap: 10px; }

.avatar {
  width: 38px; height: 38px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 13px;
  color: #08131a;
  background: var(--who, var(--accent));
  flex: none;
  position: relative;
}
.avatar.is-self { box-shadow: 0 0 0 2px var(--panel-2), 0 0 0 4px var(--who, var(--accent)); }

.card__id { flex: 1; min-width: 0; }
.card__name {
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card__where { color: var(--text); font-size: 13px; margin-top: 1px; }

.badge {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(255,255,255,.08);
  flex: none;
}
.badge.you { background: rgba(78,163,214,.18); color: var(--accent); }
.badge.approx { background: rgba(224,179,87,.15); color: var(--warn); }

/* Freshness gets its own row, always present. Whether the data is current is
   never a detail you have to hunt for. */
.fresh {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--muted);
}
.fresh::before {
  content: "";
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--muted);
  flex: none;
}
.fresh[data-level="live"] { color: var(--live); }
.fresh[data-level="live"]::before { background: var(--live); animation: pulse 2s infinite; }
.fresh[data-level="recent"]::before { background: var(--accent); }
.fresh[data-level="stale"] { color: var(--warn); }
.fresh[data-level="stale"]::before { background: var(--warn); }

.detail { color: var(--muted); font-size: 12px; margin-top: 4px; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.chip {
  font-size: 11.5px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,.05);
  color: var(--muted);
  border: 1px solid transparent;
  white-space: nowrap;
}
.chip.warn { background: rgba(224,179,87,.14); color: var(--warn); }
.chip.alert { background: rgba(224,120,90,.16); color: var(--alert); }

.card__actions { display: flex; gap: 8px; margin-top: 10px; }
.card__actions button {
  flex: 1;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 7px;
  font-size: 12.5px;
  cursor: pointer;
}
.card__actions button:hover { background: rgba(255,255,255,.09); }
.card__actions button.on { background: rgba(78,163,214,.18); border-color: var(--accent); color: var(--accent); }

/* ------------------------------------------------------------- timeline */

.day-head {
  position: sticky;
  top: -10px;               /* cancels the pane's own top padding */
  background: var(--panel);
  padding: 8px 0 6px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--muted);
  z-index: 1;
}

.event {
  display: flex;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(255,255,255,.04);
}
.event__time { color: var(--muted); font-size: 12px; width: 62px; flex: none; text-align: right; }
.event__body { min-width: 0; }
.event__what { font-size: 13px; }
.event__what strong { font-weight: 650; }
.event__sub { color: var(--muted); font-size: 12px; }
.event__icon { width: 18px; text-align: center; flex: none; }

/* --------------------------------------------------------------- places */

.place-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-2);
  margin-bottom: 8px;
}
.place-row__icon { font-size: 18px; flex: none; }
.place-row__body { flex: 1; min-width: 0; }
.place-row__name { font-weight: 600; }
.place-row__here { color: var(--live); font-size: 12px; }

/* Inline delete confirmation. window.confirm() is unavailable in the app's
   WebView, so the confirmation lives in the page. */
.place-row { flex-wrap: wrap; }
.confirm {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--muted);
}
.confirm span { flex: 1; }
.confirm button { border-radius: 8px; padding: 7px 12px; font-size: 12.5px; cursor: pointer; }
.confirm .danger {
  background: rgba(224,120,90,.18);
  border: 1px solid var(--alert);
  color: var(--alert);
  font-weight: 600;
}
.confirm .danger:disabled { opacity: .5; cursor: default; }

/* --------------------------------------------------------- address search */

.search { position: relative; margin-bottom: 10px; }
.search input {
  width: 100%;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #0d1317;
}
.search input:focus { outline: none; border-color: var(--accent); }

.search__results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0; right: 0;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.55);
  z-index: 5;
  max-height: 300px;
  overflow-y: auto;
}
.search__hit {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid rgba(255,255,255,.05);
  padding: 9px 11px;
  cursor: pointer;
}
.search__hit:hover { background: rgba(255,255,255,.06); }
.search__name { display: block; font-size: 13px; }
.search__sub {
  display: block;
  color: var(--muted);
  font-size: 11.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.search__empty { padding: 11px; color: var(--muted); font-size: 12.5px; }

.empty {
  text-align: center;
  color: var(--muted);
  padding: 26px 12px;
  font-size: 13px;
}
.empty strong { display: block; color: var(--text); margin-bottom: 4px; font-size: 14px; }

.primary, .ghost {
  border-radius: 9px;
  padding: 9px 14px;
  cursor: pointer;
  border: 1px solid var(--border);
  background: rgba(255,255,255,.05);
}
.primary { background: var(--accent); border-color: var(--accent); color: #06131c; font-weight: 650; }
.full { width: 100%; }

/* ------------------------------------------------------------- trackbar */

#trackbar {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  width: min(420px, calc(100% - 24px));
  background: rgba(22,29,35,.94);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
  z-index: 3;
  box-shadow: 0 8px 28px rgba(0,0,0,.5);
}
.trackbar__row { display: flex; align-items: center; gap: 8px; }
#trackbar-who { flex: 1; font-weight: 600; font-size: 13px; }
#trackbar .chips { margin-top: 8px; }
#trackbar .chips button {
  background: rgba(255,255,255,.05);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 999px;
  padding: 4px 11px;
  font-size: 12px;
  cursor: pointer;
}
#trackbar .chips button.active { background: rgba(78,163,214,.2); border-color: var(--accent); color: var(--accent); }
#trackbar-summary { margin-top: 8px; }

#toast {
  position: absolute;
  bottom: 18px; left: 50%;
  transform: translateX(-50%);
  background: rgba(22,29,35,.96);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 13px;
  z-index: 4;
  box-shadow: 0 6px 20px rgba(0,0,0,.5);
}

/* ----------------------------------------------------------- map markers */

.map-pin {
  display: flex;
  align-items: center;
  gap: 5px;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.6));
}
.map-pin__dot {
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--pin-color, var(--accent));
  border: 2.5px solid #0f1418;
  flex: none;
}
.map-pin__label {
  background: rgba(15,20,24,.85);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 11.5px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  white-space: nowrap;
}
.map-pin.is-fresh .map-pin__dot { animation: pinpulse 2.4s infinite; }
.map-pin.is-stale { opacity: .55; }
.map-pin.is-stale .map-pin__dot { background: #7c8a95; }
.map-pin.is-selected .map-pin__dot { box-shadow: 0 0 0 3px rgba(255,255,255,.35); }
.map-pin.is-self .map-pin__dot { border-color: #fff; }
/* A fuzzed position has no meaningful centre, so it gets no dot at all — the
   area on the map is the entire claim. The label stays, as a click target. */
.map-pin.is-fuzzed .map-pin__dot { display: none; }

@keyframes pinpulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(120,200,255,.5); }
  70%      { box-shadow: 0 0 0 9px rgba(120,200,255,0); }
}

.place-pin {
  font-size: 15px;
  line-height: 1;
  opacity: .85;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.7));
  cursor: default;
}

.maplibregl-popup.bc-popup .maplibregl-popup-content {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 12.5px;
  padding: 9px 11px;
  box-shadow: 0 8px 24px rgba(0,0,0,.55);
}
.maplibregl-popup.bc-popup .maplibregl-popup-tip { border-top-color: var(--panel); }

/* -------------------------------------------------------------- dialogs */

dialog {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--panel);
  color: var(--text);
  padding: 20px;
  width: min(400px, calc(100vw - 32px));
}
dialog::backdrop { background: rgba(0,0,0,.6); }
dialog h2 { font-size: 16px; margin-bottom: 6px; }
dialog label { display: block; margin: 12px 0 0; font-size: 12.5px; color: var(--muted); }
dialog input, dialog select {
  width: 100%;
  margin-top: 5px;
  padding: 9px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: #0d1317;
}
.dialog-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 18px; }

/* --------------------------------------------------------------- mobile */

/*
 * On a phone this stops being a two-pane desktop layout and becomes what a maps
 * app on a phone actually is: a full-bleed map with a draggable sheet over it.
 *
 * The sheet is `position: fixed`, not a grid row. As a row it competed with the
 * map for height, and a tall list of people won — the map collapsed to nothing.
 * Overlaying it also matches the platform: the map stays whole behind the sheet
 * and you drag the sheet down to see more of it, which is the gesture people
 * already have in their hands.
 *
 * Three snap points: peek (header only), half, and full.
 */
@media (max-width: 820px) {
  #shell {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
  }
  #mapwrap { grid-area: 1 / 1; }

  #sidebar {
    grid-area: 1 / 1;
    /* Above MapLibre's own controls, which are position:absolute inside the map
       and were drawing over the sheet — the attribution pill landed on top of
       the History button and the zoom buttons over the person card. Raising the
       sheet is the fix rather than nudging each control, because every control
       MapLibre adds later would need nudging too. */
    z-index: 20;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    height: 92vh;
    /* dvh tracks the mobile URL bar collapsing; vh above is the fallback. */
    height: 92dvh;
    grid-template-rows: auto auto 1fr;
    border-right: none;
    border-top: 1px solid var(--border);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -10px 34px rgba(0,0,0,.55);
    transform: translateY(var(--sheet-y, 50%));
    transition: transform .28s cubic-bezier(.32,.72,0,1);
    touch-action: none;   /* the drag is ours, not the browser's */
  }
  /* While a finger is down the sheet must track it exactly; a transition here
     makes the drag feel like it is lagging behind the thumb. */
  body.sheet-dragging #sidebar { transition: none; }

  /* vh first, dvh only where supported. An unsupported unit inside calc()
     invalidates the whole declaration, which would drop the peek stop entirely
     and leave the sheet stuck at its default — on an older WebView that reads
     as "the map is gone" all over again. */
  body.sheet-peek #sidebar { --sheet-y: calc(92vh - 132px); }
  body.sheet-half #sidebar { --sheet-y: 46%; }
  body.sheet-full #sidebar { --sheet-y: 0%; }

  @supports (height: 100dvh) {
    body.sheet-peek #sidebar { --sheet-y: calc(92dvh - 132px); }
  }

  #side-head {
    position: relative;
    padding-top: 18px;
    cursor: grab;
  }
  #sheet-toggle {
    display: block;
    position: absolute;
    top: 7px; left: 50%;
    transform: translateX(-50%);
    width: 42px; height: 4px;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: #46565f;
    cursor: grab;
  }

  /* Panes scroll internally, and only once the sheet is tall enough to show
     them. At peek the list underneath would scroll behind the header. */
  .pane { padding-bottom: calc(28px + var(--safe-b)); }
  body.sheet-peek .panes { overflow: hidden; }

  /* Keep MapLibre's own controls clear of the sheet at its peek height. They
     are also below it now, so an expanded sheet simply covers them. */
  .maplibregl-ctrl-bottom-right,
  .maplibregl-ctrl-bottom-left { bottom: 146px; z-index: 1; }
  /* The attribution is legally required to be visible, so it moves rather than
     hiding — the peek height is where it stays readable. */
  .maplibregl-ctrl-bottom-left { bottom: 146px; }

  #trackbar {
    top: calc(10px + env(safe-area-inset-top, 0px));
    width: calc(100% - 20px);
  }
  #toast { bottom: 150px; }

  /* Touch targets: 32px is fine for a mouse and mean on a thumb. */
  .icon-btn { width: 38px; height: 38px; }
  #tabs button { padding: 11px 4px 12px; }
  .card__actions button { padding: 11px; }
  .card { padding: 13px; }
}

/* A short landscape phone has no room for a half stop worth having. */
@media (max-width: 820px) and (max-height: 480px) {
  body.sheet-half #sidebar { --sheet-y: 20%; }
}

/* ---------------------------------------------------- health, you, playback */

/* Shown only when a device is unhealthy, so it is allowed to be loud. */
.health {
  margin: 9px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.4;
}
.health.warn  { background: rgba(224,179,87,.12); color: var(--warn); }
.health.alert { background: rgba(224,120,90,.14); color: var(--alert); }

#pane-you h3 {
  font-size: 13px;
  margin: 18px 0 4px;
  letter-spacing: .2px;
}
#pane-you h3:first-child { margin-top: 2px; }
#pane-you .muted { margin-bottom: 8px; }

.share {
  border: 1px solid var(--border);
  background: var(--panel-2);
  border-radius: 10px;
  padding: 10px;
  margin-bottom: 8px;
}
.share__who { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.share__who .muted { margin: 0; }
.share .chips button {
  flex: 1;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 999px;
  padding: 6px 10px;
  font-size: 12px;
  cursor: pointer;
}
.share .chips button.active {
  background: rgba(78,163,214,.2);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

.alert-row {
  border: 1px solid var(--border);
  background: var(--panel-2);
  border-radius: 10px;
  padding: 10px;
  margin-bottom: 8px;
}
.toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--muted);
  margin-top: 7px;
  flex-wrap: wrap;
}
.toggle input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--accent); }
input.tiny {
  width: 66px;
  padding: 5px 7px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #0d1317;
}

.linkish {
  background: none;
  border: none;
  color: var(--accent);
  cursor: pointer;
  padding: 0;
  font: inherit;
  text-decoration: underline;
}

.quick { display: flex; gap: 8px; margin-bottom: 8px; }
.quick button {
  flex: 1;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 9px;
  padding: 10px 8px;
  font-size: 12.5px;
  cursor: pointer;
}
.quick button:hover { background: rgba(255,255,255,.09); }

.bookmarks { margin-top: 18px; }
.bookmarks h3 { font-size: 13px; margin: 0 0 2px; }

.playback {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 9px;
}
.playback button {
  background: rgba(255,255,255,.06);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 5px 10px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.playback input[type="range"] { flex: 1; accent-color: var(--accent); min-width: 0; }
#play-time { min-width: 52px; text-align: right; }

/* Circle membership editing, added with the circles write path in 0.7.6.
   Members and the add-a-person control sit inside .place-row__body, so these
   only handle the internal layout — the card chrome is already there. */
.circle-members {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 6px;
}
.circle-member {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 12.5px;
}
.circle-add {
  display: flex;
  gap: 6px;
  margin-top: 9px;
  flex-wrap: wrap;
}
.circle-add input {
  flex: 1 1 11em;
  min-width: 0;          /* or a long email overflows the card instead of shrinking */
  padding: 6px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #0d1317;
  color: inherit;
  font: inherit;
}

/* ====================================================================== game
 *
 * The pane is used outdoors, one-handed, in a hurry, on both platforms. Three
 * things follow from that and are not negotiable in here:
 *
 *   1. Everything tappable is at least 44px tall. That is Apple's floor and a
 *      sensible one; a 30px button is a button you miss while walking.
 *   2. No hover-only affordance. There is no hover on a phone, and the desktop
 *      view is the secondary one for this feature.
 *   3. The clock uses tabular figures, so it does not jitter as digits change
 *      width once a second.
 */

/* Five tabs now, so they have to be narrower. Tightened rather than scrolled:
   a tab strip that scrolls hides the tab somebody is looking for. */
#tabs button { padding: 8px 2px 9px; font-size: 12.5px; }

.tab-dot {
  display: inline-block;
  min-width: 7px;
  height: 7px;
  margin-left: 4px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--alert);
  color: #21100c;
  font-size: 9.5px;
  line-height: 7px;
  font-weight: 700;
  vertical-align: 2px;
}

#pane-game h3.game-name { font-size: 15px; margin: 2px 0 10px; }
#pane-game h4 {
  font-size: 13px;
  margin: 18px 0 6px;
  letter-spacing: .2px;
}
#pane-game section:first-of-type h4 { margin-top: 4px; }
#pane-game label {
  display: block;
  margin: 10px 0 0;
  font-size: 12.5px;
  color: var(--muted);
}
#pane-game label input,
#pane-game label select,
.game-pick select {
  display: block;
  width: 100%;
  margin-top: 4px;
  min-height: 44px;
  padding: 0 10px;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text);
}
#pane-game .primary,
#pane-game .ghost { min-height: 44px; }
#pane-game .full + .full { margin-top: 8px; }
.ghost.danger { color: var(--alert); border-color: rgba(224,120,90,.4); }

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

.round {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 12px;
}
.round__clock {
  font-size: 38px;
  font-weight: 650;
  letter-spacing: .5px;
  /* Without this the whole line shifts every time a 1 becomes a 0. */
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  margin: 6px 0 2px;
}
.round__clock em {
  display: block;
  font-size: 12px;
  font-style: normal;
  color: var(--warn);
  letter-spacing: .3px;
}
.round__clock.is-paused span { color: var(--muted); }
.round__controls { display: flex; gap: 8px; margin-top: 10px; }
.round__controls button { flex: 1; }

/* The single most important line in the pane: whether the person holding the
   phone is being hunted or doing the hunting. */
.role-banner {
  border-radius: 9px;
  padding: 9px 11px;
  font-size: 13px;
  line-height: 1.35;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--border);
}
.role-banner.hiding {
  background: rgba(90,196,126,.13);
  border-color: rgba(90,196,126,.35);
  color: #b6e8c8;
}
.role-banner.seeking {
  background: rgba(224,120,90,.13);
  border-color: rgba(224,120,90,.35);
  color: #f0c2b2;
}

/* ------------------------------------------------------------ chips/teams */

#pane-game .chips button,
.ask__kinds button {
  min-height: 40px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(255,255,255,.05);
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
}
#pane-game .chips button.active {
  border-color: var(--team, var(--accent));
  color: var(--text);
  background: color-mix(in srgb, var(--team, var(--accent)) 22%, transparent);
}
/* color-mix is recent; without the fallback an older WebView renders an active
   chip identically to an inactive one, which makes the selection invisible. */
@supports not (background: color-mix(in srgb, red 20%, transparent)) {
  #pane-game .chips button.active { background: rgba(78,163,214,.2); color: var(--text); }
}

.team {
  border: 1px solid var(--border);
  border-left: 3px solid var(--team, var(--accent));
  border-radius: 9px;
  background: var(--panel-2);
  padding: 9px 10px;
  margin-bottom: 8px;
}
.team__head { display: flex; align-items: center; justify-content: space-between; }
.team__name { font-weight: 600; font-size: 13.5px; }
.team__member {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 34px;
  font-size: 13px;
}
.team .ghost.full { margin-top: 8px; min-height: 40px; }
.team-new { display: flex; gap: 8px; margin-top: 8px; }
.team-new input {
  flex: 1;
  min-height: 44px;
  padding: 0 10px;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text);
}
.unplaced {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 44px;
  font-size: 13px;
}
.unplaced select {
  min-height: 40px;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text);
  padding: 0 8px;
}

/* ---------------------------------------------------------- ask and answer */

.ask { margin-bottom: 4px; }
.walking {
  margin: 10px 0 0;
  padding: 9px 11px;
  border-radius: 9px;
  background: rgba(224,179,87,.12);
  color: var(--warn);
  font-size: 12.5px;
}
.walking p { margin: 0; }

/* An unanswered question is the loudest thing on a hider's screen, on purpose:
   it is the only element in the app with someone waiting on the other end. */
.answer-card {
  border: 1px solid var(--q, var(--accent));
  border-left-width: 3px;
  border-radius: 10px;
  background: var(--panel-2);
  padding: 11px;
  margin-top: 10px;
}
.answer-card__head {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: baseline;
  justify-content: space-between;
  font-size: 13px;
}
.answer-card__ask { margin: 6px 0 0; font-size: 14px; line-height: 1.35; }
.answer-card__btns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.answer-card__btns button { flex: 1 1 46%; min-height: 46px; }

.qlog { margin-top: 10px; }
.qrow {
  display: flex;
  align-items: center;
  gap: 8px;
  border-left: 3px solid var(--q, var(--accent));
  background: var(--panel-2);
  border-radius: 8px;
  padding: 8px 10px;
  margin-bottom: 6px;
}
.qrow__body { flex: 1; min-width: 0; }
.qrow__top {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: space-between;
  font-size: 12px;
}
.qkind { color: var(--q, var(--accent)); font-weight: 600; }
.qrow__answer { font-size: 13.5px; margin-top: 2px; }

.game-new { margin-top: 20px; }
.game-new summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--muted);
  min-height: 32px;
  line-height: 32px;
}
.game-new[open] summary { color: var(--text); }
.game-pick { display: block; margin-bottom: 10px; }

@media (max-width: 820px) {
  /*
   * iOS Safari zooms the whole page when a focused input has a font smaller than
   * 16px, and it does not zoom back out. Mid-game that means tapping the radius
   * field leaves you on a magnified map you have to pinch your way out of. The
   * fix is the font size, not user-scalable=no — disabling zoom breaks the map
   * for anyone who needs to enlarge it.
   */
  input, select, textarea { font-size: 16px; }

  /* One per row on a narrow phone: two 46px buttons side by side end up with
     wrapped labels, and a wrapped label on an answer button is a mis-tap. */
  .answer-card__btns button { flex: 1 1 100%; }

  .round__clock { font-size: 34px; }
}

/* A link that cannot be recovered deserves to look like one. */
.invite-fresh {
  margin: 10px 0;
  padding: 11px 12px;
  border-radius: 10px;
  background: rgba(78,163,214,.1);
  border: 1px solid rgba(78,163,214,.4);
  font-size: 12.5px;
  line-height: 1.5;
}
.invite-fresh code {
  display: block;
  margin-top: 7px;
  padding: 8px 9px;
  border-radius: 7px;
  background: #0b0f12;
  font-size: 11.5px;
  word-break: break-all;
  /* One tap selects the whole link, for when the clipboard API is unavailable —
     which it is in a plain WebView and over http. */
  user-select: all;
}
.invite-fresh__btns { display: flex; gap: 8px; margin-top: 10px; }
.invite-fresh__btns button { flex: 1; min-height: 44px; }

/* ------------------------------------------------------- the scoring clock */

.round__label { margin-bottom: -2px; }
/* The two phases must not look alike: one is time draining away from the hiders,
   the other is their score accumulating. Same digits, opposite meaning. */
.round__clock.is-hiding span { color: var(--warn); }
.round__clock.is-scoring span { color: var(--live); }
.round__clock.is-paused span { color: var(--muted); }

.standing {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  grid-template-areas: "rank name best" ". meta meta";
  align-items: baseline;
  gap: 2px 8px;
  padding: 9px 10px;
  margin-bottom: 6px;
  border-radius: 9px;
  background: var(--panel-2);
  border-left: 3px solid var(--team, var(--accent));
}
.standing__rank { grid-area: rank; color: var(--muted); font-size: 12px; }
.standing__name { grid-area: name; font-weight: 600; font-size: 13.5px; }
.standing__best {
  grid-area: best;
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  font-weight: 650;
}
.standing__meta { grid-area: meta; font-size: 11.5px; }
.standing.is-leader .standing__best { color: var(--live); }
