/* ============================================================================
   LocalLights — night drive. Deep navy ground, warm white text, amber for
   anything that is on tonight. Dark by default and dark when the OS asks for
   light, on purpose: this app is used in a dark car, and a bright page is a
   flashlight in the passenger's face.

   One stylesheet of tokens and shared components for index.html and
   admin.html. Each module adds its own small file after this one and uses the
   tokens; nothing below hardcodes a colour that has a token.
   ========================================================================= */

:root {
  color-scheme: dark;

  /* palette: the contract in docs/build-plan.md */
  --night:   #0B1026;   /* page ground, the map's own dark */
  --night-2: #141A3A;   /* surfaces: cards, sheets, bars, the dock */
  --night-3: #1E2650;   /* raised: quiet buttons, tiles, toasts, rows */
  --line:    #2A3466;   /* borders and dividers */
  --text:    #FFF4E0;   /* warm white */
  --text-2:  #C9C2B3;   /* secondary */
  --text-3:  #8E8A9E;   /* muted: captions, placeholders, attribution */
  --amber:   #FFB347;   /* on tonight; the one primary action colour */
  --amber-2: #FF8C42;   /* amber, pressed */
  --glow:    rgba(255, 179, 71, .55);
  --bulb-red:   #FF4D4D;   /* bulb colours: small accents only, never a surface */
  --bulb-green: #3DDC84;
  --bulb-blue:  #4DA3FF;
  --bulb-gold:  #FFD166;
  --ok:     #3DDC84;
  --danger: #FF4D4D;

  /* derived from the palette; use these rather than re-deriving them */
  --amber-ink:  var(--night);                /* text on an amber fill */
  --amber-soft: rgba(255, 179, 71, .14);     /* selected tint */
  --amber-line: rgba(255, 179, 71, .45);     /* selected border */
  --scrim:      rgba(11, 16, 38, .72);       /* behind a modal sheet */
  --glass:      rgba(20, 26, 58, .84);       /* bars that float over the map */
  --shadow:     0 1px 2px rgba(0, 0, 0, .35), 0 10px 30px rgba(0, 0, 0, .45);
  --shadow-up:  0 -10px 36px rgba(0, 0, 0, .5);
  --glow-ring:  0 0 0 6px rgba(255, 179, 71, .18), 0 6px 24px var(--glow);

  --appbar-h:    64px;
  --dock-h:      62px;
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --radius:      16px;
  --radius-sm:   10px;
  --pin-radius:  14px;

  --display: 'Fredoka', system-ui, sans-serif;
  --body:    -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

/* The tokens live on :root with no light-mode counterpart. If the OS asks for
   light it gets the same navy; the only thing we restate is the colour-scheme,
   so native controls and scrollbars stay dark too. */
@media (prefers-color-scheme: light) {
  :root { color-scheme: dark; }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body { margin: 0; padding: 0; background: var(--night); }
html { scrollbar-color: var(--line) transparent; }

body {
  color: var(--text);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.45;
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
}

img, video { max-width: 100%; display: block; }
button, input, textarea, select { font: inherit; color: inherit; }
a { color: var(--amber); }
svg { display: block; }
[hidden] { display: none !important; }
::selection { background: rgba(255, 179, 71, .35); color: var(--text); }
:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text);
}

/* Sheetposting's beer rings and the "Add a Sheet!" scrawl. The names stay so
   stray markup is harmless; the decorations do not come along. */
.ring, .nudge { display: none; }

/* --------------------------------------------------------------- appbar --- */

.appbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: calc(var(--appbar-h) + var(--safe-top));
  padding: var(--safe-top) 14px 0;
  background: var(--glass);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.brand { position: relative; display: flex; align-items: center; min-width: 0; }

/* The lockup is one piece of art, bulb and wordmark together. Height drives
   it so the bar never depends on how wide the word is. */
.wordmark { margin: 0; line-height: 0; display: block; min-width: 0; }
.logo { display: block; height: 44px; width: auto; max-width: 100%; }

@media (min-width: 768px) {
  :root { --appbar-h: 72px; }
  .logo { height: 52px; }
  .appbar { padding-left: 20px; padding-right: 20px; }
}

.appbar-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

.icon-btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--amber);
  border: 0;
  color: var(--amber-ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: 0 0 auto;
  transition: transform .08s ease, background .12s ease;
}
.icon-btn svg { width: 24px; height: 24px; }
.icon-btn:active { transform: scale(.94); background: var(--amber-2); }
@media (hover: hover) { .icon-btn:hover { background: var(--bulb-gold); } }
.icon-btn:focus-visible { outline: 3px solid var(--amber); outline-offset: 3px; }
.icon-btn.quiet { background: var(--night-3); color: var(--text); border: 1px solid var(--line); }
.icon-btn.quiet:active { background: var(--line); }
@media (hover: hover) { .icon-btn.quiet:hover { background: var(--line); } }

/* micro-caps line under the bar; app.js may rewrite its text */
.subline, .topbits { position: relative; }
.subline {
  margin: 0;
  padding: 10px 16px 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--text-3);
  text-align: center;
}

/* -------------------------------------------------------------- layout ---- */

main {
  position: relative;
  padding-bottom: calc(var(--dock-h) + var(--safe-bottom) + 28px);
}

.view { display: none; position: relative; }
.view.active { display: block; }

/* ------------------------------------------------------------ map home ---- */
/* The map is a fixed layer between the app bar and the bottom of the screen.
   The dock floats over its lower edge; the attribution and the report button
   are lifted clear of it. Everything in here sits above Leaflet's own panes
   (z 400) and controls (z 1000), and the layer itself sits under the bar and
   the dock. */

#view-map {
  position: fixed;
  top: calc(var(--appbar-h) + var(--safe-top));
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  background: var(--night-2);
}
#mapHost { position: absolute; inset: 0; background: var(--night-2); }
#mapHost .leaflet-container { width: 100%; height: 100%; }

#mapOverlay {
  position: absolute;
  left: 12px; right: 12px; top: 12px;
  z-index: 1100;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
#mapOverlay > * { pointer-events: auto; }
.overlay-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }

/* "Halloween 2026 · 41 displays" and "14 sleighs out tonight": one glass pill
   each, display face, the number in amber. */
.season-line {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  max-width: 100%;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--glass);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  font-family: var(--display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.2;
  color: var(--text);
  flex-wrap: wrap;          /* a long season line wraps; it never truncates in a car */
}
.season-line b { font-weight: 600; color: var(--amber); }

#mapFab {
  position: absolute;
  right: 16px;
  bottom: calc(var(--dock-h) + var(--safe-bottom) + 26px);
  z-index: 1100;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
}

.empty.map-empty {
  position: absolute;
  left: 16px; right: 16px; top: 38%;
  z-index: 1100;
  margin: 0;
  background: var(--glass);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* a small status dot: on, dim, or nothing */
.dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--text-3);
  flex: 0 0 auto;
}
.dot.is-on { background: var(--amber); box-shadow: 0 0 8px var(--glow); }

/* ------------------------------------------------------------------ fab --- */
/* Round floating buttons. The report button is the one thing on the map
   screen that glows: it is the thing under the passenger's thumb. */

.fab {
  width: 56px; height: 56px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--night-3);
  color: var(--text);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: transform .1s ease, background .12s ease, box-shadow .2s ease;
}
.fab svg { width: 26px; height: 26px; }
.fab:active { transform: scale(.94); background: var(--line); }
.fab:focus-visible { outline: 3px solid var(--amber); outline-offset: 3px; }
.fab.report {
  background: var(--amber);
  color: var(--amber-ink);
  border-color: transparent;
  box-shadow: var(--glow-ring), var(--shadow);
}
.fab.report:active { background: var(--amber-2); }
@media (hover: hover) { .fab.report:hover { background: var(--bulb-gold); } }
/* the tour screen's bigger one */
.fab.lg { width: 72px; height: 72px; }
.fab.lg svg { width: 32px; height: 32px; }

/* --------------------------------------------------------------- tally --- */
/* How many displays are up, right above the feed. The number is the point of
   the line, so it takes the display face and amber. */

.tally {
  position: relative;
  margin: 0;
  padding: 10px 16px 9px;
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--text-3);
}
.tally b {
  display: inline-block;
  margin-right: 5px;
  vertical-align: -2px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: .01em;
  color: var(--amber);
}
.tally.bump b { animation: tally-bump .42s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes tally-bump {
  0%   { transform: scale(1); }
  38%  { transform: scale(1.3) rotate(-4deg); }
  100% { transform: scale(1); }
}

/* ------------------------------------------------------------- masonry --- */
/* CSS multi-column gives the feed its collage fit: each pin keeps its own
   shape (app.js writes a deterministic aspect-ratio inline on .pin-img) and
   the columns fill to whatever height results. */

.masonry {
  columns: 2;
  column-gap: 10px;
  padding: 2px 10px 0;
}
@media (min-width: 640px)  { .masonry { columns: 3; column-gap: 14px; padding: 4px 14px 0; } }
@media (min-width: 960px)  { .masonry { columns: 4; } }
@media (min-width: 1320px) { .masonry { columns: 5; max-width: 1600px; margin: 0 auto; } }

.pin {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  display: block;
  width: 100%;
  margin: 0 0 14px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
@media (min-width: 640px) { .pin { margin-bottom: 18px; } }

.pin-img {
  position: relative;
  overflow: hidden;
  border-radius: var(--pin-radius);
  border: 1px solid var(--line);
  background: var(--night-3);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.pin-img img, .pin-img video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
}
.pin-img video { pointer-events: none; }   /* the pin is the button, not the clip */
.pin:active .pin-img { transform: scale(.985); }
@media (hover: hover) {
  .pin:hover .pin-img { transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--amber-line); }
}
.pin:focus-visible .pin-img { outline: 3px solid var(--amber); outline-offset: 3px; }
/* a display that is on tonight carries its glow into the feed */
.pin.is-on .pin-img { border-color: var(--amber); box-shadow: 0 0 0 1px var(--amber-line), 0 0 18px var(--glow); }

.pin-cap {
  font-size: 13px;
  line-height: 1.3;
  font-weight: 600;
  color: var(--text);
  margin: 9px 4px 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pin-cap.blank { font-weight: 400; font-style: italic; color: var(--text-3); }
.pin-loc {
  font-size: 12px;
  color: var(--text-3);
  margin: 3px 4px 0;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The small badge on anything that moves. Clips autoplay muted, so the badge
   is the only hint that it is not a photo until it starts. */
.clip-badge {
  position: absolute;
  left: 8px; bottom: 8px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px 3px 7px;
  border-radius: 999px;
  background: rgba(11, 16, 38, .78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--text);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.4;
  pointer-events: none;
}
.clip-badge::before {
  content: "";
  width: 0; height: 0;
  border-left: 7px solid var(--amber);
  border-top: 4.5px solid transparent;
  border-bottom: 4.5px solid transparent;
}

/* skeleton pins at assorted heights so the loading state looks like a feed */
.sk {
  break-inside: avoid;
  margin: 0 0 14px;
  border-radius: var(--pin-radius);
  border: 1px solid var(--line);
  background: linear-gradient(90deg, var(--night-2) 0%, var(--night-3) 50%, var(--night-2) 100%);
  background-size: 200% 100%;
  animation: shimmer 1.3s linear infinite;
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* ---------------------------------------------------------------- dock --- */

/* pull-to-refresh badge, parked above the app bar until dragged down */
.ptr {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, 0);
  margin-top: -48px;
  z-index: 45;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--night-3);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  display: grid;
  place-items: center;
  color: var(--text-3);
  font-size: 20px;
  line-height: 1;
  pointer-events: none;
}
.ptr.snap { transition: transform .2s ease; }
.ptr.ready { color: var(--amber); }
.ptr.spinning .ptr-spin { animation: ptrspin .8s linear infinite; }
@keyframes ptrspin { to { transform: rotate(360deg); } }

.dock {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(10px + var(--safe-bottom));
  z-index: 60;
  display: flex;
  gap: 2px;
  padding: 4px;
  background: var(--glass);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow);
}
.dock button {
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 18px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--display);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: .01em;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.dock button svg { width: 20px; height: 20px; }
.dock button[aria-selected="true"] { background: var(--amber-soft); color: var(--amber); }
.dock button:focus-visible { outline: 3px solid var(--amber); outline-offset: 3px; }
@media (max-width: 359px) { .dock button { padding: 0 12px; } }

/* -------------------------------------------------------- empty states --- */

.empty {
  text-align: center;
  padding: 36px 22px;
  margin: 10px 14px;
  color: var(--text-2);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: rgba(20, 26, 58, .5);
}
.empty .big { font-size: 34px; line-height: 1; margin-bottom: 10px; }
.empty h3 { font-size: 22px; margin: 0 0 7px; }
.empty p { margin: 0 auto; max-width: 32ch; font-size: 13.5px; line-height: 1.5; }
.empty .btn { margin-top: 16px; }
@media (min-width: 680px) { .empty { max-width: 560px; margin-left: auto; margin-right: auto; } }

.footer {
  position: relative;
  padding: 26px 22px 8px;
  text-align: center;
  color: var(--text-3);
  font-size: 11.5px;
  line-height: 1.6;
  max-width: 46ch;
  margin: 6px auto 0;
}
.footer a { color: var(--text-2); }

/* ------------------------------------------------------------ the door --- */
/* The way into the bouncer: seven taps in the bottom right, under the last of
   the feed. It has to read as empty ground, so it carries no ink of its own
   until a deliberate run is already three taps deep. */

.door-wrap {
  position: relative;
  display: flex;
  justify-content: flex-end;
  padding: 0 8px;
}
.door {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 80px; height: 64px;
  margin: 0; padding: 0;
  border: 0;
  background: none;
  position: relative;
  cursor: default;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
.door:focus { outline: none; }
.door-dots {
  position: absolute;
  right: 14px; bottom: 16px;
  display: flex;
  gap: 5px;
  opacity: 0;
  transition: opacity .2s ease;
}
.door.knocking .door-dots { opacity: 1; }
.door-dots i {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--text-3);
  opacity: .25;
  transform: scale(.78);
  transition: opacity .14s ease, transform .14s ease, background-color .14s ease;
}
.door-dots i.lit { background: var(--amber); opacity: 1; transform: scale(1); box-shadow: 0 0 6px var(--glow); }
.door.opening .door-dots i { background: var(--amber); opacity: 1; transform: scale(1.35); }

/* ------------------------------------------------------------- buttons --- */
/* Amber is the primary. There is no pressed shadow or outline: the surface
   steps down a shade and the button gives a little under the finger. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 10px 22px;
  background: var(--amber);
  color: var(--amber-ink);
  border: 0;
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: .01em;
  line-height: 1.15;
  cursor: pointer;
  text-decoration: none;
  -webkit-user-select: none;
  user-select: none;
  transition: transform .08s ease, background .12s ease, box-shadow .12s ease;
}
.btn:active { transform: scale(.98); background: var(--amber-2); }
@media (hover: hover) { .btn:hover { background: var(--bulb-gold); } }
.btn:focus-visible { outline: 3px solid var(--amber); outline-offset: 3px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.block { width: 100%; }
.btn svg { width: 20px; height: 20px; }

/* the one button on a screen that is "on": It's on!, Open in Maps */
.btn.glow { box-shadow: var(--glow-ring); }

.btn.quiet, .btn.ghost { background: var(--night-3); color: var(--text); border: 1px solid var(--line); }
.btn.quiet:active, .btn.ghost:active { background: var(--line); }
@media (hover: hover) { .btn.quiet:hover, .btn.ghost:hover { background: var(--line); } }
.btn.ghost { background: transparent; }

.btn.danger { background: transparent; color: var(--danger); border: 1px solid rgba(255, 77, 77, .55); }
.btn.danger:active { background: rgba(255, 77, 77, .12); }
@media (hover: hover) { .btn.danger:hover { background: rgba(255, 77, 77, .12); } }

.btn.sm { min-height: 40px; padding: 7px 16px; font-size: 14.5px; }
.btn.xs { min-height: 36px; padding: 4px 12px; font-size: 13px; font-family: var(--body); font-weight: 700; }
.btn.share-btn { padding: 9px 20px; }

.btn-row { display: flex; gap: 9px; flex-wrap: wrap; }
.btn-row .btn { flex: 1 1 auto; }

.round-btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--night-3);
  border: 1px solid var(--line);
  color: var(--text);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: 0 0 auto;
  transition: transform .08s ease, background .12s ease;
}
.round-btn svg { width: 22px; height: 22px; }
.round-btn:active { transform: scale(.94); background: var(--line); }
.round-btn:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }

/* --------------------------------------------------------------- chips --- */
/* Small labelled pills: the picks row on the map, filters, the nav provider.
   A static chip is a label; a button or link chip is a 44 px target. */

.chips {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  padding: 2px;
  margin: -2px;
}
.chips::-webkit-scrollbar { display: none; }
.chips > * { flex: 0 0 auto; scroll-snap-align: start; }
.chips.wrap { flex-wrap: wrap; overflow: visible; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 13px;
  border-radius: 999px;
  background: var(--night-3);
  border: 1px solid var(--line);
  color: var(--text-2);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
button.chip, a.chip { min-height: 44px; cursor: pointer; color: var(--text); }
button.chip:active, a.chip:active { background: var(--line); }
.chip svg { width: 16px; height: 16px; }
.chip b { font-family: var(--display); font-weight: 600; color: var(--amber); }
.chip.is-on, .chip[aria-pressed="true"], .chip[aria-selected="true"] {
  background: var(--amber-soft);
  border-color: var(--amber-line);
  color: var(--amber);
}
.chip.glass {
  background: var(--glass);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--shadow);
}
.chip:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }

/* ----------------------------------------------------- segmented control -- */
/* Two to five choices, one selected: Circle / Draw / A to B, the budget,
   Waze / Apple / Google. */

.seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--night);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.seg-btn {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-2);
  font-family: var(--display);
  font-weight: 600;
  font-size: 15px;
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.seg-btn[aria-pressed="true"], .seg-btn[aria-selected="true"], .seg-btn.is-on {
  background: var(--amber);
  color: var(--amber-ink);
}
.seg-btn:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }
.seg-btn:disabled { opacity: .4; cursor: not-allowed; }

/* --------------------------------------------------------------- tiles --- */
/* The report grid: five big one-tap tiles, two columns, icon over label. Also
   the Photo / Clip / Camera chooser. A tile is its own surface; inside the
   older .create-tiles pattern the surface is the .tile-box instead. */

.tiles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 104px;
  padding: 14px 10px;
  border-radius: 18px;
  background: var(--night-3);
  border: 1px solid var(--line);
  color: var(--text);
  font-family: var(--display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.15;
  text-align: center;
  cursor: pointer;
  transition: transform .08s ease, background .12s ease, border-color .12s ease;
}
.tile svg { width: 32px; height: 32px; color: var(--amber); }
.tile .tile-icon { font-size: 30px; line-height: 1; }
.tile small, .tile .sub { font-family: var(--body); font-weight: 500; font-size: 12px; color: var(--text-3); }
.tile:active { transform: scale(.97); background: var(--line); }
@media (hover: hover) { .tile:hover { border-color: var(--amber-line); } }
.tile:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }
.tile:disabled { opacity: .45; cursor: not-allowed; }
.tile.is-on, .tile[aria-pressed="true"] { background: var(--amber-soft); border-color: var(--amber); color: var(--amber); }
.tile.primary { background: var(--amber); color: var(--amber-ink); border-color: transparent; box-shadow: var(--glow-ring); }
.tile.primary svg { color: var(--amber-ink); }
.tile.primary small, .tile.primary .sub { color: rgba(11, 16, 38, .7); }
.tile.wide { grid-column: 1 / -1; }

.create-tiles {
  display: flex;
  justify-content: center;
  gap: 14px;
  padding: 18px 16px 4px;
  flex-wrap: wrap;
}
.create-tiles .tile { background: none; border: 0; min-height: 0; padding: 0; gap: 10px; font-size: 14px; }
.tile-box {
  width: 104px; height: 104px;
  border-radius: 18px;
  background: var(--night-3);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  transition: background .12s ease, transform .08s ease, border-color .12s ease;
}
.tile-box svg { width: 36px; height: 36px; color: var(--amber); }
.create-tiles .tile:active .tile-box { transform: scale(.97); background: var(--line); }
@media (hover: hover) { .create-tiles .tile:hover .tile-box { border-color: var(--amber-line); } }
.create-tiles .tile:focus-visible { outline: none; }
.create-tiles .tile:focus-visible .tile-box { outline: 3px solid var(--amber); outline-offset: 3px; }

/* --------------------------------------------------------------- forms --- */

.field { margin-bottom: 14px; }
.field label {
  display: block;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--text);
  margin-bottom: 6px;
}
.field .sub { display: block; font-size: 12px; color: var(--text-3); font-weight: 400; margin-top: 1px; }

.input, textarea.input, select.input {
  width: 100%;
  min-height: 48px;
  background: var(--night);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  color: var(--text);
  font-size: 16px;   /* 16px keeps iOS from zooming on focus */
  outline: none;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.input::placeholder { color: var(--text-3); opacity: 1; }
.input:focus { border-color: var(--amber); box-shadow: 0 0 0 3px rgba(255, 179, 71, .22); }
.input:disabled { opacity: .5; }
textarea.input { min-height: 84px; resize: vertical; line-height: 1.4; }
select.input {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%23C9C2B3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}
.charcount { text-align: right; font-size: 11px; color: var(--text-3); margin-top: 4px; }

.checkline {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: 14.5px;
  color: var(--text-2);
  font-weight: 600;
  cursor: pointer;
}
.checkline input { width: 20px; height: 20px; margin: 0; accent-color: var(--amber); flex: 0 0 auto; }
input[type="range"] { width: 100%; accent-color: var(--amber); }
input[type="checkbox"], input[type="radio"] { accent-color: var(--amber); }

.note {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-2);
  background: var(--night-3);
  border-left: 3px solid var(--amber);
  border-radius: 0 12px 12px 0;
  padding: 10px 13px;
  margin: 0 0 14px;
}

/* ------------------------------------------------------------ progress --- */

.progress { height: 6px; background: var(--night-3); border-radius: 3px; overflow: hidden; margin-top: 12px; }
.progress i { display: block; height: 100%; width: 0; background: var(--amber); box-shadow: 0 0 8px var(--glow); transition: width .3s ease; }

/* -------------------------------------------------------- modal sheets --- */
/* The post flow, the report grid, the display card: a panel that slides up
   over a scrim. On a wide screen it floats in the middle instead. */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--scrim);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: none;
  overscroll-behavior: contain;
}
.sheet.open { display: block; }

.sheet-inner {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-height: 94dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--night-2);
  border-top: 1px solid var(--line);
  border-radius: 22px 22px 0 0;
  box-shadow: var(--shadow-up);
  padding: 0 0 calc(24px + var(--safe-bottom));
  animation: slideUp .24s cubic-bezier(.2, .8, .3, 1);
}
@keyframes slideUp { from { transform: translateY(16%); opacity: .4; } to { transform: none; opacity: 1; } }

@media (min-width: 760px) {
  .sheet-inner {
    left: 50%;
    transform: translateX(-50%);
    max-width: 640px;
    border: 1px solid var(--line);
    border-radius: 22px;
    bottom: 4vh;
    max-height: 92vh;
  }
  @keyframes slideUp { from { transform: translateX(-50%) translateY(10%); opacity: .4; } to { transform: translateX(-50%); opacity: 1; } }
}

.sheet-head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--glass);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.sheet-head h3 { font-size: 21px; }
.sheet-body { padding: 16px; }

.x {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--night-3);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 18px;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: 0 0 auto;
}
.x:active { background: var(--line); }
.grab { width: 40px; height: 5px; background: var(--text-3); border-radius: 3px; margin: 10px auto 0; opacity: .6; }

/* full-screen variant, used by the display card on a phone */
.sheet.full .sheet-inner {
  top: 0; bottom: 0; left: 0; right: 0;
  max-width: none;
  max-height: none;
  border-radius: 0;
  border: 0;
  transform: none;
  padding-bottom: calc(28px + var(--safe-bottom));
  animation: fadeUp .2s ease;
}
@keyframes fadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (min-width: 760px) {
  .sheet.full .sheet-inner {
    top: 3vh; bottom: 3vh; left: 50%; right: auto;
    transform: translateX(-50%);
    width: min(680px, 94vw);
    border-radius: 22px;
    border: 1px solid var(--line);
  }
}

.detail-bar {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: calc(10px + var(--safe-top)) 12px 14px;
  background: linear-gradient(180deg, var(--night-2) 0%, var(--night-2) 64%, rgba(20, 26, 58, 0) 100%);
}
.detail-bar-actions { display: flex; align-items: center; gap: 8px; }

/* ------------------------------------------------------- bottom sheet ---- */
/* A panel that lives over the map rather than in front of it: the Now card
   on the tour, the display card peeking under the map. It has three places to
   be, driven by a class: open (default), .is-peek (just the handle and the
   first row showing; set --bsheet-peek to the height you want visible) and
   .is-hidden. Dragging is the module's job; it sets --bsheet-y in px while the
   finger is down with .is-dragging on, then drops into one of the classes. */

.bsheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 70;
  max-height: min(72dvh, 640px);
  display: flex;
  flex-direction: column;
  background: var(--night-2);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 22px 22px 0 0;
  box-shadow: var(--shadow-up);
  padding-bottom: var(--safe-bottom);
  transform: translateY(var(--bsheet-y, 0px));
  transition: transform .28s cubic-bezier(.2, .8, .3, 1);
  will-change: transform;
}
.bsheet.is-dragging { transition: none; }
.bsheet.is-peek { --bsheet-y: calc(100% - var(--bsheet-peek, 132px) - var(--safe-bottom)); }
.bsheet.is-hidden { --bsheet-y: calc(100% + 40px); pointer-events: none; }

.bsheet-handle {
  flex: 0 0 auto;
  height: 40px;
  display: grid;
  place-items: center;
  cursor: grab;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.bsheet-handle::before {
  content: "";
  width: 40px; height: 5px;
  border-radius: 3px;
  background: var(--text-3);
  opacity: .6;
}
.bsheet.is-dragging .bsheet-handle { cursor: grabbing; }

.bsheet-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0 16px 10px;
}
.bsheet-head h3 { font-size: 20px; line-height: 1.2; }

.bsheet-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 0 16px 16px;
}

@media (min-width: 760px) {
  .bsheet {
    left: 50%; right: auto;
    width: 560px;
    transform: translateX(-50%) translateY(var(--bsheet-y, 0px));
  }
}

/* ---------------------------------------------------------------- card --- */
/* The display card's bones: media on top, then the address and the status
   line, then a row of actions. The same shell works inside a sheet, a bottom
   sheet, or on its own in a list. */

.card {
  background: var(--night-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.card + .card { margin-top: 12px; }
.card.is-on { border-color: var(--amber-line); box-shadow: 0 0 20px rgba(255, 179, 71, .18); }

.card-media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--night-3);
  overflow: hidden;
}
.card-media.tall { aspect-ratio: 3 / 4; }
.card-media.auto { aspect-ratio: auto; }
.card-media img, .card-media video { width: 100%; height: 100%; object-fit: cover; }

.card-body { padding: 14px 16px; }
.card-title { font-family: var(--display); font-weight: 600; font-size: 20px; line-height: 1.2; color: var(--text); }
.card-sub { font-size: 13.5px; color: var(--text-3); margin-top: 2px; }
.card-note { font-size: 14.5px; color: var(--text-2); margin-top: 8px; line-height: 1.45; }
.card-actions { display: flex; gap: 8px; flex-wrap: wrap; padding: 0 16px 16px; }
.card-actions .btn { flex: 1 1 auto; }

/* "On tonight, seen by 3" / "Owner says it's off tonight" / nothing yet */
.status-line {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 8px 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-2);
}
.status-line::before {
  content: "";
  flex: 0 0 auto;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--text-3);
  opacity: .7;
}
.status-line.is-on { color: var(--amber); }
.status-line.is-on::before {
  background: var(--amber);
  opacity: 1;
  box-shadow: 0 0 10px var(--glow), 0 0 0 3px rgba(255, 179, 71, .18);
}
.status-line.is-off { color: var(--text-3); }
.status-line.is-off::before {
  background: linear-gradient(135deg, transparent 40%, var(--text-3) 40% 60%, transparent 60%);
  border: 2px solid var(--text-3);
  opacity: .8;
}
.status-line.is-dim { color: var(--text-3); }

/* -------------------------------------------------------- glow markers --- */
/* A display on the map. Build it as a Leaflet divIcon with className
   'glow-marker is-on' (or is-off / is-dim) and iconSize [22, 22]; the sizes
   are pinned here as well so the hit box is the same whatever the icon
   options say. On tonight is a lit amber dot with a ring that breathes out;
   off tonight is a crossed-out bulb; dim is a quiet dot nobody has
   confirmed. */

.glow-marker {
  width: 22px !important;
  height: 22px !important;
  margin-left: -11px !important;
  margin-top: -11px !important;
  background: none;
  border: 0;
}
.glow-marker::before, .glow-marker::after {
  content: "";
  position: absolute;
  border-radius: 50%;
}
.glow-marker.is-on::after {
  inset: 4px;
  background: var(--amber);
  box-shadow: 0 0 0 2px rgba(11, 16, 38, .6), 0 0 12px 2px var(--glow);
}
.glow-marker.is-on::before {
  inset: 0;
  border: 2px solid var(--amber);
  opacity: .8;
  animation: glow-pulse 2.4s ease-out infinite;
}
.glow-marker.is-dim::after {
  inset: 6px;
  background: var(--text-3);
  opacity: .75;
  box-shadow: 0 0 0 2px rgba(11, 16, 38, .6);
}
.glow-marker.is-off::after {
  inset: 5px;
  background: var(--night-3);
  border: 2px solid var(--text-3);
  opacity: .9;
}
.glow-marker.is-off::before {
  inset: 10px -1px auto;
  height: 2px;
  border-radius: 1px;
  background: var(--text-2);
  transform: rotate(-45deg);
  z-index: 1;
}
@keyframes glow-pulse {
  0%   { transform: scale(.55); opacity: .9; }
  100% { transform: scale(2.1); opacity: 0; }
}

/* neighbourhood counts past zoom 13 */
.cluster {
  width: 40px !important;
  height: 40px !important;
  margin-left: -20px !important;
  margin-top: -20px !important;
  display: grid !important;
  place-items: center;
  border-radius: 50%;
  background: rgba(20, 26, 58, .92);
  border: 2px solid var(--amber);
  color: var(--amber);
  font-family: var(--display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
  box-shadow: 0 0 14px var(--glow);
}
/* if Leaflet.markercluster is used instead, its defaults get the same look */
.marker-cluster, .marker-cluster div { background: transparent !important; }
.marker-cluster div {
  width: 40px !important; height: 40px !important; margin: 0 !important;
  border-radius: 50%;
  background: rgba(20, 26, 58, .92) !important;
  border: 2px solid var(--amber);
  color: var(--amber) !important;
  font-family: var(--display); font-weight: 600; font-size: 15px;
  box-shadow: 0 0 14px var(--glow);
}
.marker-cluster span { line-height: 36px !important; }

/* a street with four or more live displays: className on the polyline */
.lit-street {
  stroke: var(--amber);
  stroke-opacity: .85;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 6px var(--glow));
}

/* --------------------------------------------------------------- leaflet -- */

.leaflet-container { font-family: var(--body); background: var(--night-2); }
.leaflet-container a { color: var(--amber); }
.leaflet-div-icon { background: none; border: 0; }

/* Dark basemaps are neutral grey-black; this pushes them toward --night so the
   map and the chrome read as one surface. Tuned on CARTO Dark Matter; if the
   tile provider changes, retune or drop it. */
.leaflet-tile-pane .osm-dark {
  /* OpenStreetMap's daytime tiles turned into a night map: invert, swing the
     hue so water lands on blue rather than brown, then pull the whole thing
     down toward the navy ground. No key, no vendor, full house-level zoom. */
  filter: invert(1) hue-rotate(195deg) saturate(.55) brightness(.72) contrast(1.08);
}

.leaflet-control-attribution {
  background: rgba(11, 16, 38, .72) !important;
  color: var(--text-3) !important;
  font-size: 9.5px !important;
  padding: 2px 6px !important;
  border-radius: 8px 0 0 0;
}
.leaflet-control-attribution a { color: var(--text-2) !important; }

.leaflet-bar { border: 1px solid var(--line) !important; border-radius: 12px !important; box-shadow: var(--shadow) !important; overflow: hidden; }
.leaflet-bar a {
  background: var(--night-2) !important;
  color: var(--text) !important;
  border-bottom-color: var(--line) !important;
  width: 40px !important; height: 40px !important; line-height: 40px !important;
}
.leaflet-bar a:hover { background: var(--night-3) !important; }
.leaflet-bar a.leaflet-disabled { color: var(--text-3) !important; }
.locate-btn { font-size: 15px !important; text-align: center; }
/* pinch does the zooming on a phone; the buttons only cover the map */
@media (pointer: coarse) { .leaflet-control-zoom { display: none; } }

/* the bottom corners clear the dock */
#mapHost .leaflet-bottom { bottom: calc(var(--dock-h) + var(--safe-bottom) + 10px); }

.leaflet-popup-content-wrapper {
  background: var(--night-2);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
}
.leaflet-popup-tip { background: var(--night-2); box-shadow: none; }
.leaflet-popup-content { margin: 10px 12px; font-size: 13px; line-height: 1.4; }
.leaflet-popup-content img { border-radius: 8px; margin-bottom: 7px; width: 100%; height: 96px; object-fit: cover; }
.leaflet-popup-content .pc {
  font-weight: 600; line-height: 1.3; margin-bottom: 8px;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.leaflet-container a.leaflet-popup-close-button { color: var(--text-3); }
.leaflet-container a.leaflet-popup-close-button:hover { color: var(--text); }

/* the small map inside a form, and Sheetposting's #map id for anything that
   still uses it */
#map, .minimap {
  width: 100%;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--night-2);
  overflow: hidden;
  z-index: 1;
}
#map { height: calc(100dvh - 196px); min-height: 320px; margin: 0 12px; width: calc(100% - 24px); }
.minimap { height: 190px; }

.pin-marker {
  width: 26px; height: 26px;
  background: var(--amber);
  border: 2px solid var(--night);
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  box-shadow: 0 0 12px var(--glow);
}

/* -------------------------------------------------------------- upload --- */

.drop {
  border: 1px dashed var(--text-3);
  border-radius: var(--radius);
  padding: 26px 16px;
  text-align: center;
  color: var(--text-3);
  background: rgba(20, 26, 58, .5);
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.drop.over, .drop:hover { border-color: var(--amber); background: var(--night-3); }
.drop .big { font-size: 30px; margin-bottom: 8px; }
.drop b { color: var(--text); display: block; margin-bottom: 3px; font-size: 15px; }
.drop span { font-size: 12.5px; }

.preview-wrap { position: relative; margin-bottom: 14px; }
.preview-wrap img, .preview-wrap video {
  width: 100%;
  max-height: 42vh;
  object-fit: contain;
  background: var(--night);
  border-radius: 12px;
  border: 1px solid var(--line);
}

.locbox {
  background: var(--night-3);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 11px 12px;
  margin-bottom: 12px;
  font-size: 13px;
}
.locbox .row { display: flex; align-items: center; gap: 8px; }
.locbox .status { flex: 1 1 auto; }
.locbox .status b { display: block; font-size: 13px; color: var(--text); }
.locbox .status.found b { color: var(--ok); }
.locbox .status.missing b { color: var(--danger); }
.locbox .status span { font-size: 11.5px; color: var(--text-3); }
.locbox .actions { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 10px; }

/* the photo detail (Sheetposting's names; the display card reuses them) */
.detail-img { transition: filter .3s ease; }
.detail-img.loading { filter: blur(7px); }
.detail-img {
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--night-3);
}
.detail-cap { font-family: var(--display); font-weight: 600; font-size: 22px; line-height: 1.3; color: var(--text); margin: 18px 2px 10px; }
.detail-cap.blank { font-family: var(--body); font-weight: 400; font-style: italic; color: var(--text-3); font-size: 15px; }
.detail-meta { font-size: 13px; color: var(--text-3); margin: 0 2px 5px; }
.detail-meta a { color: var(--amber); font-weight: 600; }
.detail-meta .approx { font-size: .85em; font-style: italic; color: var(--text-3); }

.create-inner { background: var(--night-2); }
.create-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 14px 4px;
}
.create-head h3 { font-size: 21px; }
.create-head .spacer { width: 40px; flex: 0 0 auto; }
.create-note { text-align: center; color: var(--text-2); font-size: 13px; line-height: 1.5; padding: 18px 28px 4px; margin: 0; }

/* ----------------------------------------------------------- typeahead --- */
/* The address list under the one field. It floats over the form so the sheet
   does not jump as suggestions come and go. Rows are a thumb, not a mouse. */

.typeahead { position: relative; }
.ta-list {
  position: absolute;
  z-index: 20;
  left: 0; right: 0;
  top: 100%;
  margin: 5px 0 0;
  padding: 4px;
  list-style: none;
  max-height: 280px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--night-3);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
}
.ta-list li, .ta-item {
  min-height: 44px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-radius: 8px;
  font-size: 15px;
  color: var(--text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ta-list li + li { border-top: 1px solid rgba(42, 52, 102, .5); }
.ta-item b { font-family: var(--display); font-weight: 600; color: var(--amber); min-width: 3ch; }
.ta-item small { color: var(--text-3); font-size: 12.5px; margin-left: auto; white-space: nowrap; }
.ta-list li.on, .ta-item.on, .ta-list li:active { background: var(--amber); color: var(--amber-ink); border-top-color: transparent; }
.ta-list li.on b, .ta-item.on b, .ta-list li.on small, .ta-item.on small { color: var(--amber-ink); }
@media (hover: hover) { .ta-list li:hover { background: var(--line); } .ta-list li.on:hover { background: var(--amber); } }

/* -------------------------------------------------------------- toasts --- */

#toasts {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--dock-h) + var(--safe-bottom) + 34px);
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: min(93vw, 460px);
  pointer-events: none;
}
.toast {
  background: var(--night-3);
  color: var(--text);
  border: 1px solid var(--line);
  border-left: 4px solid var(--text-3);
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  box-shadow: var(--shadow);
  animation: toastIn .2s ease;
}
.toast.err { border-left-color: var(--danger); }
.toast.ok { border-left-color: var(--ok); }
/* "You're the first to light this one up tonight": the toast that glows */
.toast.glow { border-left-color: var(--amber); box-shadow: var(--shadow), 0 0 18px var(--glow); }
@keyframes toastIn { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ========================================================= admin page ==== */
/* The bouncer. css/admin.css adds the new tabs; these are the shared bones. */

.admin-body { padding: 0 0 40px; }
.admin-top {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 15px;
  border-bottom: 1px solid var(--line);
  background: var(--glass);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  flex-wrap: wrap;
}
.admin-top .logo { height: 36px; }
.admin-brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-badge {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  background: var(--amber);
  color: var(--amber-ink);
  border-radius: 999px;
  padding: 4px 9px;
  line-height: 1.4;
  flex: 0 0 auto;
}
.admin-wrap { max-width: 1100px; margin: 0 auto; padding: 15px; }

.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; margin-bottom: 16px; }
@media (min-width: 620px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--night-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 11px 13px;
  cursor: pointer;
  transition: transform .08s ease, background .12s ease, border-color .12s ease;
}
.stat b { font-family: var(--display); font-weight: 600; font-size: 27px; color: var(--amber); display: block; line-height: 1.1; }
.stat span { font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.stat.warn { border-color: rgba(255, 77, 77, .6); background: rgba(255, 77, 77, .08); }
.stat.warn b { color: var(--danger); }
.stat.on { border-color: var(--amber); background: var(--amber-soft); }
.stat.on span { color: var(--text); }
.stat:active { transform: scale(.98); }
@media (hover: hover) { .stat:hover { background: var(--night-3); } .stat.warn:hover { background: rgba(255, 77, 77, .14); } }
.stat:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }

.admin-tabs { display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none; padding: 2px 2px 10px; margin-bottom: 14px; }
.admin-tabs::-webkit-scrollbar { display: none; }
.admin-tabs button {
  flex: 0 0 auto;
  min-height: 40px;
  background: var(--night-2);
  border: 1px solid var(--line);
  color: var(--text-2);
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.admin-tabs button[aria-selected="true"] { background: var(--amber); color: var(--amber-ink); border-color: transparent; }
.admin-tabs button:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }

.arow { background: var(--night-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; margin-bottom: 12px; }
.arow.flagged { border-color: rgba(255, 77, 77, .6); }
/* the row a Slack link pointed at, so the eye lands on it after the scroll */
.arow.hit { animation: arow-hit 2.6s ease-out 1; }
@keyframes arow-hit {
  0%, 70% { box-shadow: 0 0 0 3px var(--amber); background: var(--night-3); }
  100%    { box-shadow: 0 0 0 3px transparent; background: var(--night-2); }
}
.arow-top { display: flex; gap: 12px; align-items: flex-start; }
.arow-top img.pv, .arow-top video.pv {
  width: 116px; height: 116px;
  object-fit: cover;
  border-radius: 9px;
  border: 1px solid var(--line);
  background: var(--night-3);
  flex: 0 0 auto;
  cursor: zoom-in;
}
.arow-top .pv.gone {
  width: 116px; height: 116px;
  border-radius: 9px;
  flex: 0 0 auto;
  border: 1px dashed var(--line);
  background: var(--night);
  display: grid;
  place-content: center;
  gap: 4px;
  text-align: center;
  color: var(--text-3);
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.arow-top .pv.gone span { font-size: 22px; line-height: 1; }
@media (max-width: 520px) {
  .arow-top { flex-direction: column; }
  .arow-top img.pv, .arow-top video.pv, .arow-top .pv.gone { width: 100%; height: 190px; }
}
.arow-top .fields { flex: 1 1 auto; min-width: 0; }
.arow .field { margin-bottom: 9px; }
.arow .input { padding: 9px 11px; min-height: 42px; }
.arow h3 { margin: 0 0 12px; font-size: 19px; }

.tagline { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 9px; }
.tag {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--night);
  color: var(--text-2);
}
.tag.gold { background: var(--amber); border-color: var(--amber); color: var(--amber-ink); }
.tag.bad { border-color: var(--danger); color: var(--danger); }
.tag.ok { border-color: var(--ok); color: var(--ok); }
.tag.on { border-color: var(--amber-line); color: var(--amber); }

.bulk-row {
  display: flex;
  align-items: center;
  gap: 11px;
  background: var(--night-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 9px;
  margin-bottom: 8px;
}
.bulk-row img, .bulk-row video { width: 54px; height: 54px; object-fit: cover; border-radius: 7px; border: 1px solid var(--line); background: var(--night-3); flex: 0 0 auto; }
.bulk-row .bmeta { flex: 1 1 auto; min-width: 0; }
.bulk-row .bmeta .nm { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bulk-row .bmeta .st { font-size: 11px; color: var(--text-3); margin-top: 3px; }
.bulk-row .bmeta .st.ok { color: var(--ok); }
.bulk-row .bmeta .st.err { color: var(--danger); }
.bulk-row .bmeta .st.warn { color: var(--amber); }
.bulk-row input.cap {
  width: 100%; margin-top: 5px;
  background: var(--night); border: 1px solid var(--line); border-radius: 7px;
  padding: 6px 9px; font-size: 16px; color: var(--text); outline: none;
}
.bulk-row input.cap:focus { border-color: var(--amber); }

/* standings: voting is not a LocalLights feature, but the list style is the
   shape of any ranked list in the bouncer (picks, busiest streets) */
.standing {
  display: flex;
  align-items: center;
  gap: 11px;
  background: var(--night-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px;
  margin-bottom: 9px;
  position: relative;
  overflow: hidden;
  width: 100%;
  text-align: left;
  color: inherit;
}
.standing .bar { position: absolute; left: 0; top: 0; bottom: 0; background: linear-gradient(90deg, rgba(255, 179, 71, .16), rgba(255, 179, 71, .03)); z-index: 0; }
.standing > * { position: relative; z-index: 1; }
.standing .rk { font-family: var(--display); font-weight: 600; font-size: 25px; color: var(--amber); width: 32px; text-align: center; flex: 0 0 auto; line-height: 1; }
.standing .pic { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; border: 1px solid var(--line); background: var(--night-3); flex: 0 0 auto; }
.standing .meta { flex: 1 1 auto; min-width: 0; }
.standing .meta .t { font-size: 13.5px; font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.standing .meta .t.blank { color: var(--text-3); font-style: italic; font-weight: 400; }
.standing .meta .s { font-size: 11px; color: var(--text-3); margin-top: 3px; }
.standing .pts { text-align: right; flex: 0 0 auto; }
.standing .pts b { font-family: var(--display); font-weight: 600; font-size: 21px; color: var(--text); display: block; line-height: 1.05; }
.standing .pts span { font-size: 9.5px; letter-spacing: .1em; color: var(--text-3); text-transform: uppercase; }

/* ---------------------------------------------------------- analytics -- */
/* Amber is the only accent in the charts. Green stays reserved for "that
   worked", and a busy Tuesday is not a success message. */

.an-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: space-between; margin-bottom: 14px; }
.an-ranges { display: flex; gap: 6px; flex-wrap: wrap; }
.an-ranges button {
  min-height: 36px;
  border: 1px solid var(--line); background: var(--night-2); color: var(--text-2);
  border-radius: 999px; padding: 7px 13px; font: 700 12.5px/1 var(--body);
  cursor: pointer; white-space: nowrap;
}
.an-ranges button[aria-selected="true"] { background: var(--amber); color: var(--amber-ink); border-color: transparent; }
.an-ranges button:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }
.an-tools { display: flex; align-items: center; gap: 9px; }
.an-stamp { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }

.an-tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; margin-bottom: 12px; }
@media (min-width: 620px) { .an-tiles { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px) { .an-tiles { grid-template-columns: repeat(6, 1fr); } }
.an-tile { background: var(--night-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 11px 12px; text-align: left; }
.an-tile b { font-family: var(--display); font-weight: 600; font-size: 25px; color: var(--amber); display: block; line-height: 1.1; }
.an-tile span { display: block; font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--text-3); font-weight: 700; margin-top: 2px; }
.an-tile em { display: block; margin-top: 6px; font-style: normal; }
.an-d { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; color: var(--text-3); }
.an-d.up { color: var(--text); }
.an-d.down { color: var(--amber-2); }

.an-card { background: var(--night-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 13px; margin-bottom: 12px; }
.an-card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: space-between; margin-bottom: 11px; }
.an-card h3 { margin: 0; font-size: 17px; }
.an-cols { display: grid; gap: 12px; }
@media (min-width: 760px) {
  .an-cols { grid-template-columns: 1fr 1fr; margin-bottom: 12px; }
  .an-cols .an-card { margin-bottom: 0; }
}

.an-pills { display: flex; gap: 5px; flex-wrap: wrap; }
.an-pill { min-height: 32px; border: 1px solid var(--line); background: var(--night); color: var(--text-2); border-radius: 999px; padding: 5px 10px; font: 700 11.5px/1 var(--body); cursor: pointer; }
.an-pill.on { background: var(--text); color: var(--night); border-color: var(--text); }
.an-pill:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }

/* the readout is a fixed line, not a floating tooltip: no hover on a phone */
.an-readout { min-height: 34px; margin-bottom: 9px; }
.an-readout b { display: block; font-size: 14px; color: var(--text); line-height: 1.25; }
.an-readout span { display: block; font-size: 11.5px; color: var(--text-3); margin-top: 2px; }

.an-bars { display: flex; align-items: flex-end; gap: 2px; height: 132px; }
.an-bar { flex: 1 1 0; min-width: 0; height: 100%; padding: 0; border: 0; background: none; display: flex; align-items: flex-end; cursor: pointer; border-radius: 3px; }
.an-bar i { display: block; width: 100%; background: var(--amber); border-radius: 3px 3px 0 0; min-height: 0; opacity: .85; transition: background .12s ease, opacity .12s ease; }
.an-bar.on i, .an-bar:focus-visible i { background: var(--text); opacity: 1; }
.an-bar.on { background: rgba(255, 244, 224, .06); }
.an-bar:focus-visible { outline: 2px solid var(--amber); outline-offset: 1px; }
@media (hover: hover) { .an-bar:hover i { background: var(--text); opacity: 1; } }
.an-axis { display: flex; gap: 2px; margin-top: 6px; }
.an-axis span { flex: 1 1 0; min-width: 0; text-align: center; font-size: 9.5px; color: var(--text-3); font-weight: 700; letter-spacing: .04em; overflow: visible; white-space: nowrap; }

.an-row { position: relative; display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: var(--radius-sm); overflow: hidden; margin-bottom: 3px; }
.an-fill { position: absolute; inset: 0 auto 0 0; background: var(--amber-soft); border-radius: var(--radius-sm); z-index: 0; }
.an-row > .an-lab, .an-row > .an-n { position: relative; z-index: 1; }
.an-lab { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.an-lab em { font-style: normal; font-weight: 400; color: var(--text-3); font-size: 11.5px; }
.an-n { flex: 0 0 auto; font-size: 13px; font-weight: 700; color: var(--text-2); }

.an-more { margin-top: 9px; }
.an-more summary { font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); cursor: pointer; padding: 4px 0; }
.an-more summary:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }
.an-list { list-style: none; margin: 6px 0 0; padding: 0; }
.an-list li { display: flex; justify-content: space-between; gap: 10px; padding: 5px 0; font-size: 12.5px; color: var(--text-2); border-top: 1px solid var(--line); }
.an-list li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.an-list li b { flex: 0 0 auto; color: var(--text); }
.an-hint { margin: 9px 2px 0; line-height: 1.45; }
.an-foot { margin: 4px 2px 0; line-height: 1.5; }
.an-foot a { color: var(--amber); font-weight: 700; }

.an-odds { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 11px; border-top: 1px solid var(--line); padding-top: 10px; }
.an-odds span { font-size: 11px; color: var(--text-3); font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.an-odds b { font-family: var(--display); font-weight: 600; font-size: 16px; color: var(--text); display: block; letter-spacing: 0; text-transform: none; }

.an-sheets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
@media (min-width: 620px) { .an-sheets { grid-template-columns: repeat(8, 1fr); } }
.an-sheet { padding: 0; border: 0; background: none; cursor: pointer; text-align: center; }
.an-sheet img, .an-gone {
  width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--pin-radius);
  border: 1px solid var(--line); background: var(--night-3); display: block;
}
.an-gone { display: grid; place-items: center; font-size: 19px; color: var(--text-3); }
.an-sheet span { display: block; margin-top: 5px; font-size: 10px; color: var(--text-3); font-weight: 700; letter-spacing: .04em; line-height: 1.3; }
.an-sheet span b { display: block; font-family: var(--display); font-weight: 600; font-size: 15px; color: var(--amber); letter-spacing: 0; }
.an-sheet:active img { transform: scale(.98); }
.an-sheet:focus-visible img, .an-sheet:focus-visible .an-gone { outline: 3px solid var(--amber); outline-offset: 2px; }

.an-note { background: var(--night-2); border: 1px solid var(--amber-line); border-radius: var(--radius); padding: 15px; }
.an-note h3 { margin: 0 0 7px; font-size: 19px; }
.an-note p { margin: 0 0 10px; font-size: 13.5px; color: var(--text-2); line-height: 1.5; }
.an-note a { color: var(--amber); font-weight: 700; }
.an-steps { margin: 0 0 10px; padding-left: 20px; font-size: 13.5px; color: var(--text-2); line-height: 1.6; }
.an-steps code { background: var(--night); border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; font-size: 12px; word-break: break-all; }

.login-card {
  max-width: 380px;
  margin: 10vh auto 0;
  padding: 24px 22px;
  background: var(--night-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.login-card h2 { margin: 0 0 4px; font-size: 28px; }
.login-card p { color: var(--text-2); font-size: 13.5px; margin: 0 0 16px; }
.login-card p.tiny { margin: 20px 0 0; }
.login-card p.tiny + p.tiny { margin-top: 11px; }

.hint { color: var(--text-2); font-size: 13.5px; margin: 0 2px 14px; line-height: 1.5; }
.hint strong { color: var(--text); font-weight: 700; }

/* ----------------------------------------------------------- utilities --- */

.muted { color: var(--text-3); }
.tiny { font-size: 11.5px; }
.center { text-align: center; }
.mt { margin-top: 14px; }
.mb { margin-bottom: 14px; }
.hidden { display: none !important; }
.warn-text { color: var(--danger); font-weight: 600; }
.ok-text { color: var(--ok); font-weight: 600; }
.amber-text { color: var(--amber); }
.display { font-family: var(--display); font-weight: 600; }

/* ------------------------------------------------------- reduced motion -- */
/* Nothing here is load-bearing: a marker that does not breathe is still a
   marker, a sheet that appears is still a sheet. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .glow-marker.is-on::before { animation: none; transform: scale(1.25); opacity: .45; }
  .sk { animation: none; background: var(--night-3); }
}
