/* Discover — the iPhone app's design system, transcribed for the web.
 *
 * Every colour, size and radius here is named in Sources/DiscoverUI/
 * DesignSystem.swift; the two surfaces are meant to look like one product.
 * Instrument Sans for UI, JetBrains Mono for meta, near-black ground,
 * one purple accent. */

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

:root {
  /* Colour */
  --bg: #0A0A0C;              /* page background — near-black, slightly cool */
  --surface: #101014;         /* raised surfaces: the map sheet */
  --surface-raised: #131317;
  --ink: #F5F4F1;             /* warm off-white; never pure white */
  --accent: #7C5CFF;
  --accent-pressed: #6A48EC;
  --accent-soft: #B49BFF;     /* accent on dark, where full purple is illegible */
  --accent-tint: rgba(124, 92, 255, .16);
  --accent-edge: rgba(124, 92, 255, .42);
  --hairline: rgba(245, 244, 241, .09);
  --border: rgba(245, 244, 241, .12);
  --border-strong: rgba(245, 244, 241, .16);

  /* Ink opacity ramp */
  --em-body: rgba(245, 244, 241, .62);
  --em-secondary: rgba(245, 244, 241, .55);
  --em-muted: rgba(245, 244, 241, .45);
  --em-faint: rgba(245, 244, 241, .32);
  --em-ghost: rgba(245, 244, 241, .24);

  /* Metrics */
  --r-sheet: 32px;
  --r-sheet-low: 28px;
  --r-card: 20px;
  --r-tile: 16px;
  --gutter: 28px;
  --gutter-wide: 32px;

  --sans: "Instrument Sans", -apple-system, system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, monospace;
}

html, body { height: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  overscroll-behavior: none;
}

button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
.hidden { display: none !important; }

/* ================================================================= type === */

.heading {            /* 30pt — sheet and screen headings */
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.84px;
  line-height: 1.1;
}
.lead { font-size: 17px; font-weight: 600; }
.meta {               /* 11pt mono — timestamps, speed, elapsed */
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
}
.faint { color: var(--em-faint); }
.mono-label {         /* 10pt mono, uppercase, widely tracked */
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--em-faint);
}
.mono-label.accent { color: var(--accent); }

/* =============================================================== layout === */

#content { position: relative; flex: 1 1 auto; min-height: 0; }

.screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
}

/* ========================================================= start button === */

.start-btn {
  margin: 0 var(--gutter) var(--gutter);
  height: 52px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  transition: transform .1s, background .15s;
}
.start-btn:active { background: var(--accent-pressed); transform: scale(.975); }
.start-btn:disabled { opacity: .7; }
/* Inside the map sheet the row owns the spacing, not the button. */
.start-btn.sheet-start { margin: 0; flex: 1; }

/* ======================================================= status & voice === */

.status-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
.status-line .mono-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.status-dot {
  flex: none;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
/* The purple dot blinks while the guide is live. */
body.live .status-dot { animation: blink .8s ease-in-out infinite alternate; }
@keyframes blink { from { opacity: 1 } to { opacity: .25 } }

.mic-glyph { width: 26px; height: 26px; }
.mic-glyph.small { width: 19px; height: 19px; }

/* The expanding ring while the microphone is open. */
.halo {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid rgba(124, 92, 255, .45);
  opacity: 0;
  pointer-events: none;
}
.listening .halo { animation: halo 1.4s ease-out infinite; }
@keyframes halo {
  from { transform: scale(1); opacity: 1 }
  to   { transform: scale(1.28); opacity: 0 }
}

/* ================================================================== map === */

#screen-map { overflow: hidden; }

#map {
  position: absolute;
  inset: 0;
  background: var(--bg);
}
.leaflet-container { background: var(--bg); font-family: var(--sans); }

#map-attrib {
  position: absolute;
  left: 8px;
  top: calc(env(safe-area-inset-top) + 40px);
  z-index: 500;
  padding: 3px 6px;
  color: rgba(245, 244, 241, .3);
  background: rgba(10, 10, 12, .72);
  pointer-events: none;
}

/* Tune, top right — the only chrome above the map. */
.settings-btn {
  position: absolute;
  right: 16px;
  top: calc(env(safe-area-inset-top) + 10px);
  z-index: 650;
  padding: 10px 16px;
  border-radius: 999px;
  background: rgba(10, 10, 12, .72);
  border: 1px solid var(--border);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
}
.settings-btn:active { background: rgba(245, 244, 241, .08); }

#map-speed {
  position: absolute;
  right: 24px;
  top: calc(env(safe-area-inset-top) + 54px);
  z-index: 500;
  color: var(--em-secondary);
  pointer-events: none;
}

/* Pins: one colour rule, not a legend. The place being narrated is accent
   with its name in ink; every other place is grey — named if it may be
   spoken about, a small anonymous dot if it was passed over. Pins are
   scenery, not controls: nothing happens when one is tapped. */
.pin { display: flex; align-items: center; gap: 7px; }
.pin-dot {
  position: relative;
  flex: none;
  border-radius: 50%;
  border: 3px solid var(--bg);
  background: rgba(245, 244, 241, .22);
  width: 12px; height: 12px;
}
.pin.matched .pin-dot { width: 18px; height: 18px; background: rgba(245, 244, 241, .38); }
.pin.subject .pin-dot { background: var(--accent); }
.pin-label {
  display: none;
  padding: 3px 7px;
  border-radius: 6px;
  background: rgba(10, 10, 12, .78);
  font-size: 12px;
  font-weight: 600;
  color: rgba(245, 244, 241, .55);
  white-space: nowrap;
}
.pin.labelled .pin-label { display: block; }
.pin.subject .pin-label { color: var(--ink); }
.pin-car {
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--ink);
  border: 3px solid var(--bg);
}
/* The car with its heading: the whole glyph rotates so the chevron leads the
   dot; without a heading the chevron stays hidden and only the dot shows. */
.car-glyph { position: relative; width: 16px; height: 16px; }
.car-glyph .pin-car { position: absolute; inset: 0; }
.car-arrow {
  position: absolute;
  left: 50%; top: -8px;
  width: 0; height: 0;
  margin-left: -5px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 7px solid var(--ink);
  opacity: 0;
}
.car-glyph.headed .car-arrow { opacity: 1; }

/* The agent's event log: a console strip over the map, newest at the bottom,
   pinned to the tail unless the driver scrolls back. */
.log-panel {
  position: absolute;
  left: 10px;
  right: 10px;
  top: calc(env(safe-area-inset-top) + 96px);
  height: 40vh;
  z-index: 550;
  display: flex;
  flex-direction: column;
  background: rgba(10, 10, 12, .88);
  border: 1px solid var(--border);
  border-radius: 12px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-family: var(--mono);
  font-size: 10px;
}
.log-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px;
  color: var(--em-faint);
  letter-spacing: .1em;
  font-size: 9.5px;
}
.log-head button {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .1em;
  color: var(--em-body);
}
#log-lines {
  flex: 1;
  overflow-y: auto;
  padding: 0 10px 8px;
  overscroll-behavior: contain;
}
.log-line {
  padding: 3px 0;
  border-top: 1px solid rgba(245, 244, 241, .05);
  word-break: break-word;
}
.log-line .t { color: var(--em-ghost); margin-right: 6px; }
.log-line .dir { color: var(--accent-soft); margin-right: 5px; }
.log-line b { color: var(--ink); font-weight: 500; }
.log-line .detail {
  color: var(--em-muted);
  max-height: 2.7em;
  overflow: hidden;
  white-space: pre-wrap;
}
.log-line.open .detail { max-height: none; }

/* The bottom sheet repeats the drive controls so the map is not a dead end. */
#map-sheet {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 600;
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: var(--r-sheet-low) var(--r-sheet-low) 0 0;
  padding: 20px 24px calc(22px + env(safe-area-inset-bottom));
}

.sheet-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.sheet-done {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--em-body);
}

#sheet-title { margin-top: 12px; overflow-wrap: anywhere; }

.sheet-body {
  margin-top: 8px;
  min-height: 44px;
  font-size: 14.5px;
  color: var(--em-secondary);
  animation: rise .45s ease-out both;
}
.sheet-body:empty { min-height: 0; margin-top: 0; }
@keyframes rise { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: none } }

.sheet-actions {
  margin-top: 18px;
  display: flex;
  gap: 12px;
}

/* The hold-to-ask control in its wide form: a flexible purple pill beside a
   fixed ghost. */
/* Quiet by default so Start the guide is the one call to action; it takes
   the accent only while it is actually listening. */
.ask-pill {
  position: relative;
  flex: 1;
  height: 52px;
  border-radius: 999px;
  background: none;
  border: 1px solid var(--border-strong);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  font-size: 14px;
  font-weight: 600;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  touch-action: none;
  transition: transform .22s cubic-bezier(.3, 1.4, .5, 1), background .12s;
}
.ask-pill.down,
.ask-pill.listening {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.ask-pill.down { transform: scale(.975); }
.ask-pill:disabled { opacity: .45; }
.ask-pill .halo { border-radius: 999px; }

.skip-btn {
  flex: none;
  height: 52px;
  padding: 0 18px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
}
.skip-btn:active { background: rgba(245, 244, 241, .06); }

.sheet-meta {
  margin-top: 10px;
  margin-bottom: 2px;
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  color: rgba(245, 244, 241, .3);
}

/* ================================================================= tune === */

/* The key card, in its three states. */
.key-add { width: 100%; text-align: left; }
.row-chevron { flex: none; color: rgba(245, 244, 241, .4); font-size: 18px; }
.key-check { flex: none; color: var(--accent-soft); font-size: 16px; font-weight: 700; }
.card-action.muted { color: rgba(245, 244, 241, .42); }

/* The how-to behind the key card: numbered steps with schematic sketches of
   the pages, closed until the driver asks for it. */
#key-guide {
  margin-top: 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-tile);
}
#key-guide summary {
  list-style: none;
  cursor: pointer;
  padding: 14px 16px;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
#key-guide summary::-webkit-details-marker { display: none; }
#key-guide summary::after { content: "+"; color: var(--em-faint); font-size: 15px; }
#key-guide[open] summary::after { content: "–"; }
.guide-body {
  padding: 2px 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.guide-step { display: flex; gap: 12px; }
.guide-num {
  flex: none;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--accent-tint);
  color: var(--accent-soft);
  font-size: 12px;
  font-weight: 600;
  display: grid;
  place-items: center;
}
.guide-text { min-width: 0; }
.guide-text h3 { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.guide-text p { margin-top: 4px; font-size: 12.5px; line-height: 1.5; color: var(--em-muted); }
.mono-inline { font-family: var(--mono); font-size: 11.5px; color: var(--accent-soft); }
.guide-link {
  display: inline-block;
  margin-top: 9px;
  padding: 8px 13px;
  border-radius: 999px;
  border: 1px solid var(--accent-edge);
  background: var(--accent-tint);
  color: var(--accent-soft);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
}
.guide-art {
  display: block;
  margin-top: 12px;
  width: 100%;
  max-width: 280px;
  border-radius: 10px;
}

/* Seven days of estimated spend — thin purple columns, today rightmost. */
.spend-card { display: block; }
.spend-stats { display: flex; flex-direction: column; gap: 6px; }
.spend-stat { display: flex; align-items: baseline; gap: 7px; white-space: nowrap; }
.spend-bars {
  display: flex;
  gap: 6px;
  align-items: flex-end;
  margin-top: 14px;
}
.spend-bar {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}
.spend-bar i {
  width: 100%;
  max-width: 34px;
  border-radius: 3px;
  background: rgba(124, 92, 255, .3);
}
.spend-bar.today i { background: rgba(124, 92, 255, .85); }
.spend-bar span {
  font-family: "JetBrains Mono", monospace;
  font-size: 9.5px;
  letter-spacing: .08em;
  color: var(--em-faint);
}

/* The no-key prompt: over the map, above the sheet, under Settings. */
.key-prompt {
  position: absolute;
  inset: 0;
  z-index: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(10, 10, 12, .72);
  backdrop-filter: blur(6px);
}
.key-prompt-card {
  width: 100%;
  max-width: 380px;
  padding: 24px;
  border: 1px solid rgba(245, 244, 241, .1);
  border-radius: var(--r-card);
  background: var(--bg);
}
.key-prompt-card .sheet-body { margin-top: 10px; }
.key-prompt-actions { display: flex; align-items: center; gap: 12px; margin-top: 20px; }
.key-prompt-actions .start-btn { margin: 0; flex: 1; }

/* An overlay above the map rather than a tab beside it. */
#screen-tune {
  overflow: hidden;
  z-index: 900;
  background: var(--bg);
}

/* Pinned to the top of the scroll, so closing never requires scrolling back
   up. It bleeds over the scroll gutters and the safe area, and content
   slides underneath it. */
.tune-head {
  position: sticky;
  top: calc(-18px - env(safe-area-inset-top));
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: calc(-18px - env(safe-area-inset-top)) calc(-1 * var(--gutter)) 0;
  padding: calc(14px + env(safe-area-inset-top)) var(--gutter) 12px;
  background: rgba(10, 10, 12, .92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hairline);
}

/* The standard circular close, in the standard corner. */
.close-btn {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(245, 244, 241, .08);
  color: var(--em-body);
  font-size: 14px;
  line-height: 1;
  display: grid;
  place-items: center;
}
.close-btn:active { background: rgba(245, 244, 241, .16); }

.tune-scroll {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: calc(18px + env(safe-area-inset-top)) var(--gutter) 24px;
}
.tune-scroll::-webkit-scrollbar { width: 0; }

/* The narrator pick list: the full cast under the card, current one marked. */
.persona-list {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.persona-option {
  text-align: left;
  padding: 14px 16px;
  border-radius: var(--r-tile);
  border: 1px solid var(--border);
}
.persona-option.on {
  border-color: var(--accent-edge);
  background: var(--accent-tint);
}
.persona-option .hint { margin-top: 3px; }

.section-label { margin-top: var(--gutter); }

.input-card, .card {
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px;
  border: 1px solid rgba(245, 244, 241, .1);
  border-radius: var(--r-card);
}
#devmode-card.on { border-color: var(--accent-edge); }

.input-card input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
}
.input-card input::placeholder { color: rgba(245, 244, 241, .35); }

.card-action {
  flex: none;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accent-soft);
}
.card-action:disabled { color: rgba(245, 244, 241, .42); cursor: default; }

.card-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.control-title { font-size: 13px; font-weight: 600; }

.chip-btn {
  flex: none;
  padding: 11px 15px;
  border-radius: 999px;
  background: rgba(124, 92, 255, .16);
  color: var(--accent-soft);
  font-size: 12.5px;
  font-weight: 600;
}

.pill-flow {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.select-pill {
  padding: 11px 15px;
  border-radius: 999px;
  background: var(--accent-tint);
  border: 1px solid var(--accent-edge);
  color: var(--accent-soft);
  font-size: 13px;
  font-weight: 600;
}
/* An unchosen option in a pick-one row: same shape, no tint. */
.select-pill.off {
  background: none;
  border-color: rgba(245, 244, 241, .14);
  color: var(--em-body);
}

.hint {
  margin-top: 12px;
  font-size: 12.5px;
  font-weight: 400;
  color: rgba(245, 244, 241, .38);
  line-height: 1.45;
}
.hint.tight { margin-top: 0; }

/* Toggle, tinted with the soft accent like the SwiftUI one. */
.switch { flex: none; display: inline-block; }
.switch input { display: none; }
.switch-track {
  display: block;
  width: 46px; height: 28px;
  border-radius: 999px;
  background: rgba(245, 244, 241, .16);
  position: relative;
  transition: background .18s;
}
.switch-knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: #fff;
  transition: transform .18s;
}
.switch input:checked + .switch-track { background: var(--accent-soft); }
.switch input:checked + .switch-track .switch-knob { transform: translateX(18px); }
