/*
 * PitStop -- base.css
 * Design tokens (the PitStop palette, light + dark safe), the centered mobile
 * frame, the map/list layout (map band on top, list sheet below), shared resets,
 * the quality color tiers, and the designed boot screens (locating/denied/error).
 */

/* ---------- tokens ---------- */
:root {
  /* surfaces */
  --bg: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #f0f2f5;
  --frame-bg: #e7eaef;

  /* text */
  --text: #15181d;
  --text-dim: #5b6470;
  --text-faint: #656f7c; /* darkened from #8a93a0 -- 5.10:1 on --surface, 4.55:1 on --surface-2 */

  /* lines */
  --border: #e2e6ec;
  --border-strong: #cdd3dc;

  /* brand */
  --brand: #2f6df0;
  --brand-ink: #ffffff;
  --tier-ink: #ffffff; /* foreground for anything whose BACKGROUND is a tier color */

  /* quality tiers (used IDENTICALLY on map markers, list badges, detail, rating) */
  --tier-great: #197d46; /* green */
  --tier-ok: #94640b; /* amber -- darkened from #d99a16: as TEXT on --tier-ok-soft it was ~2.6:1, now 4.53:1 */
  --tier-poor: #c63127; /* red */
  --tier-none: #636e7d; /* gray -- unrated */
  --tier-great-soft: #e4f4ea;
  --tier-ok-soft: #faf0d8;
  --tier-poor-soft: #fbe5e3;
  --tier-none-soft: #eef0f3;

  /* shape */
  --radius: 14px;
  --radius-sm: 10px;
  --radius-pill: 999px;
  --shadow-1: 0 1px 2px rgba(20, 24, 29, 0.06), 0 2px 8px rgba(20, 24, 29, 0.06);
  --shadow-2: 0 8px 30px rgba(20, 24, 29, 0.18);

  /* spacing */
  --gap: 12px;
  --pad: 16px;
  --tap: 48px; /* minimum touch target */

  /* type */
  --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial,
    sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1115;
    --surface: #171a21;
    --surface-2: #1f242d;
    --frame-bg: #0a0c10;

    --text: #eef1f5;
    --text-dim: #a7b0bd;
    --text-faint: #8b95a3; /* lightened to hold contrast on dark surfaces */

    --border: #262c36;
    --border-strong: #333b47;

    --brand: #4f8bff;
    --brand-ink: #0b0e13;
    --tier-ink: #0b0e13; /* foreground for anything whose BACKGROUND is a tier color */

    --tier-great: #34c97a;
    --tier-ok: #e7b13c;
    --tier-poor: #f0635a;
    --tier-none: #7f8894;
    --tier-great-soft: #16291f;
    --tier-ok-soft: #2a2415;
    --tier-poor-soft: #2c1917;
    --tier-none-soft: #1c212a;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 10px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 10px 36px rgba(0, 0, 0, 0.6);
  }
}

/* ---------- compatibility aliases ----------
 * Component sheets (topbar/list/detail/rating/trip/prefs/break) reference
 * token names base.css never defined, so their hardcoded fallbacks won --
 * which is where four different blues, three tier-green systems, and most
 * dark-mode drift came from. Defining the names HERE, as aliases of the real
 * tokens above, makes base.css the single source of truth in both themes.
 * Aliases that are a plain var() of a real token re-theme themselves, because
 * the dark block redefines what they point at. Aliases that are a blend do
 * NOT: they are written out per theme, light here and dark below. The blends
 * are literal rgba rather than color-mix() because a custom property is SET
 * even when its value is unparseable, so on an engine without color-mix() the
 * consumer's declaration dies at computed-value time and its own hardcoded
 * fallback never gets a chance. Component files stay untouched. */
:root {
  /* accent family (was #2563eb in topbar/list/detail, #2f6fed in rating) */
  --accent: var(--brand);
  --accent-text: var(--brand-ink);
  --color-accent: var(--brand);
  --accent-soft: rgba(47, 109, 240, 0.12);
  --accent-border: rgba(47, 109, 240, 0.25);
  --accent-bg: rgba(47, 109, 240, 0.06);

  /* text + surfaces */
  --text-muted: var(--text-dim);
  --muted: var(--text-dim);
  --bg-subtle: var(--surface-2);
  --color-surface: var(--surface);
  --color-surface-2: var(--surface-2);
  --color-text: var(--text);
  --scrim: rgba(0, 0, 0, 0.5);
  /* the track keeps the OLD lighter grey -- a subtle meter rail, not text */
  --track: rgba(154, 163, 175, 0.28);
  --color-track: rgba(154, 163, 175, 0.28);

  /* shape + layout */
  --radius-lg: 18px;
  --radius-md: var(--radius);
  --app-max-width: 480px;

  /* tier aliases: list/detail chain through --color-*, rating uses bare names */
  --color-great: var(--tier-great);
  --color-ok: var(--tier-ok);
  --color-poor: var(--tier-poor);
  --color-muted: var(--tier-none);
  --color-great-bg: var(--tier-great-soft);
  --color-ok-bg: var(--tier-ok-soft);
  --color-poor-bg: var(--tier-poor-soft);
  --color-muted-bg: var(--tier-none-soft);
  --great: var(--tier-great);
  --ok: var(--tier-ok);
  --poor: var(--tier-poor);
  --neutral: var(--tier-none);
  --great-bg: var(--tier-great-soft);
  --ok-bg: var(--tier-ok-soft);
  --poor-bg: var(--tier-poor-soft);
  --tier-unrated: var(--tier-none);

  /* map user puck / recenter (was Google-blue #1a73e8) */
  --user-puck: var(--brand);

  /* semantic danger (topbar's denied/error accents) */
  --danger: var(--tier-poor);
  --danger-soft: var(--tier-poor-soft);
  --danger-border: rgba(216, 69, 59, 0.25);
}

@media (prefers-color-scheme: dark) {
  :root {
    --scrim: rgba(0, 0, 0, 0.62);

    /* the blended aliases -- restated against the dark brand/tier values */
    --accent-soft: rgba(79, 139, 255, 0.12);
    --accent-border: rgba(79, 139, 255, 0.25);
    --accent-bg: rgba(79, 139, 255, 0.06);
    --track: rgba(108, 118, 130, 0.28);
    --color-track: rgba(108, 118, 130, 0.28);
    --danger-border: rgba(240, 99, 90, 0.25);
  }
}

/* ---------- resets ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: var(--font);
  color: var(--text);
  background: var(--frame-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior: none;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: none;
  background: none;
}

h1,
h2,
h3,
p {
  margin: 0;
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* ---------- mobile frame ---------- */
.app-frame {
  position: relative;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  height: 100%;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}

.app-main {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* map band on top */
.map-root {
  position: relative;
  flex: 0 0 42%;
  min-height: 220px;
  background: var(--surface-2);
}

/* list sheet below, overlapping the map slightly for a 'sheet' feel */
.list-root {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  margin-top: -16px;
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
  background: var(--bg);
  box-shadow: 0 -6px 20px rgba(20, 24, 29, 0.12);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  z-index: 2;
}

/* ---------- overlays ---------- */
.overlay-root {
  position: absolute;
  inset: 0;
  z-index: 50;
  pointer-events: none; /* empty overlay does not block the app */
}
.overlay-root:not(:empty) {
  pointer-events: auto;
}

/* ---------- quality tier helpers (shared vocabulary) ---------- */
.tier-great {
  --tier: var(--tier-great);
  --tier-soft: var(--tier-great-soft);
}
.tier-ok {
  --tier: var(--tier-ok);
  --tier-soft: var(--tier-ok-soft);
}
.tier-poor {
  --tier: var(--tier-poor);
  --tier-soft: var(--tier-poor-soft);
}
.tier-none {
  --tier: var(--tier-none);
  --tier-soft: var(--tier-none-soft);
}

/* ---------- shared button ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 0 18px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--text);
  font-weight: 600;
  line-height: 1;
  transition: filter 0.12s ease, transform 0.05s ease;
}
.btn:active {
  transform: translateY(1px);
}
.btn-primary {
  background: var(--brand);
  color: var(--brand-ink);
}
.btn-block {
  width: 100%;
}

/* ---------- boot / status screens (app.js drives status) ---------- */
/* These render inside the list-root by the list module, but the chrome here
   keeps locating/denied/error visually consistent and clearly designed. */
.status-screen {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  padding: 32px 26px;
}
.status-screen .status-icon {
  font-size: 44px;
  line-height: 1;
  color: var(--brand);
}
.status-screen.status-denied .status-icon,
.status-screen.status-error .status-icon {
  color: var(--tier-ok);
}
.status-screen h2 {
  font-size: 19px;
  font-weight: 700;
}
.status-screen p {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.45;
  max-width: 30ch;
}
.status-screen .btn {
  margin-top: 6px;
}

/* spinner for 'locating' / 'loading' */
.spinner {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid var(--border-strong);
  border-top-color: var(--brand);
  animation: pitstop-spin 0.8s linear infinite;
}
@keyframes pitstop-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 2s;
  }
}

/* visually-hidden utility for a11y labels */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Leaflet sits inside the frame; keep its panes under our overlays. */
.leaflet-container {
  background: var(--surface-2);
  font: inherit;
}
.leaflet-pane {
  z-index: 1;
}
