/* Nydus — neon cyberpunk theme. Dark, always. Severity is the design language:
   every wait state glows its own neon; closed lanes go flat gray. */

:root {
  --bg: #06060d;
  --bg2: #0b0b14;
  --card: #101019;
  --line: #242431;
  --text: #edeaf7;
  --dim: #a09cb8;
  --faint: #615e78;
  --accent: #2f9df7;                 /* neon blue — brand, actions */
  --accent-hi: #7cc4ff;
  --accent-lo: #1668c8;
  --accent-ink: #200c02;
  --accent-soft: rgba(255, 92, 28, .13);
  --neon: #00e5ff;                   /* cyan — interactive, data */
  --mag: #ff3df2;                     /* magenta — utility, distinct from everything */
  --mag-soft: rgba(255, 61, 242, .12);
  --neon-ink: #00262c;
  --neon-soft: rgba(0, 229, 255, .10);
  --green: #00ff9d;  --green-bg: rgba(0, 255, 157, .10);
  --amber: #ffb020;  --amber-bg: rgba(255, 176, 32, .10);
  --red: #ff3b5c;    --red-bg: rgba(255, 59, 92, .12);
  --gray: #6f6e88;   --gray-bg: rgba(111, 110, 136, .14);
  --radius: 14px;
  --shadow: 0 10px 28px rgba(0, 0, 0, .55);
  --font-d: 'Chakra Petch', -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', sans-serif;
}

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

body {
  margin: 0;
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Inter, Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.45;
  background:
    radial-gradient(1100px 480px at 50% -8%, rgba(255, 45, 120, .055), transparent 62%),
    linear-gradient(rgba(0, 229, 255, .030) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 229, 255, .030) 1px, transparent 1px),
    var(--bg);
  background-size: auto, 34px 34px, 34px 34px, auto;
  min-height: 100vh;
}
::selection { background: rgba(0, 229, 255, .28); }

.wrap { max-width: 640px; margin: 0 auto; padding: 0 16px calc(96px + env(safe-area-inset-bottom));
  position: relative; z-index: 1; }

/* ---------- header ---------- */
header.top {
  padding: 30px 0 10px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}
.brand h1 {
  margin: 0;
  font-family: var(--font-d);
  font-size: 32px;
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
}
.brand h1 .dot { color: var(--accent); text-shadow: 0 0 14px var(--accent); }
.brand p { margin: 4px 0 0; color: var(--dim); font-size: 13.5px; }
.updated { font-size: 12px; color: var(--faint); text-align: right; white-space: nowrap; padding-bottom: 4px; }
.topright { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.updated::before {
  content: ''; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--green); box-shadow: 0 0 8px var(--green); margin-right: 7px;
  animation: pulse 2.2s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: .35; } }

.stale-banner {
  display: none;
  background: var(--amber-bg);
  border: 1px solid var(--amber);
  box-shadow: 0 0 16px rgba(255, 176, 32, .18);
  color: var(--amber);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin: 8px 0 4px;
}
.stale-banner.show { display: block; }

/* ---------- controls ---------- */
.controls {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  padding: 10px 0 12px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: space-between;
}
.seg {
  display: flex;
  background: rgba(0, 0, 0, .45);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 3px;
  gap: 2px;
}
.seg button {
  border: 0;
  background: transparent;
  color: var(--dim);
  font-family: var(--font-d);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 8px 15px;
  border-radius: 7px;
  cursor: pointer;
}
.seg button.on {
  background: var(--neon-soft);
  color: var(--neon);
  box-shadow: inset 0 0 0 1px var(--neon), 0 0 14px rgba(0, 229, 255, .28);
}
.seg button:focus-visible { outline: 2px solid var(--neon); outline-offset: 1px; }

/* ---------- crossing rows: color-coded boxes ----------
   Each card carries sev-light|moderate|heavy|unknown|closed.
   A neon edge bar + glowing wait pill encode busyness at a glance. */
.xcard {
  position: relative;
  background: linear-gradient(180deg, #13131d, #0e0e16);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin: 8px 0;
  overflow: hidden;
  box-shadow: var(--shadow);
  cursor: pointer;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
.xcard::before {
  content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px;
  border-radius: 3px; background: var(--gray);
}
.xcard.sev-light::before   { background: var(--green); box-shadow: 0 0 10px var(--green); }
.xcard.sev-moderate::before{ background: var(--amber); box-shadow: 0 0 10px var(--amber); }
.xcard.sev-heavy::before   { background: var(--red);   box-shadow: 0 0 14px var(--red); }
.xcard.sev-heavy { box-shadow: var(--shadow), 0 0 26px rgba(255, 59, 92, .10); }
.xcard.sev-unknown::before { background: var(--gray); }
.xcard.sev-closed::before  { background: var(--gray); box-shadow: none; }
.xcard:active { transform: scale(.997); }
.xcard.open { border-color: var(--neon); box-shadow: var(--shadow), 0 0 22px rgba(0, 229, 255, .14); }
.xcard.open::before { top: 12px; bottom: 12px; }
.xrow {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px 8px 8px 18px;
  min-height: 62px;
}
.xrow-name {
  flex: 1; min-width: 0;
  font-family: var(--font-d); font-size: 16.5px; font-weight: 600; letter-spacing: .4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sev-closed .xrow-name { color: var(--dim); }

/* neon wait pills — the busyness signal */
.xwait {
  font-family: var(--font-d); font-size: 14px; font-weight: 700;
  letter-spacing: .8px; text-transform: uppercase; white-space: nowrap;
  padding: 7px 13px; border-radius: 8px; border: 1px solid transparent;
}
.xwait.light {
  color: var(--green); border-color: var(--green); background: var(--green-bg);
  box-shadow: 0 0 14px rgba(0, 255, 157, .28), inset 0 0 10px rgba(0, 255, 157, .08);
}
.xwait.moderate {
  color: var(--amber); border-color: var(--amber); background: var(--amber-bg);
  box-shadow: 0 0 14px rgba(255, 176, 32, .28), inset 0 0 10px rgba(255, 176, 32, .08);
}
.xwait.heavy {
  color: var(--red); border-color: var(--red); background: var(--red-bg);
  box-shadow: 0 0 16px rgba(255, 59, 92, .38), inset 0 0 10px rgba(255, 59, 92, .10);
}
.xwait.unknown {
  color: var(--gray); border-color: var(--line); background: var(--gray-bg);
}
.xwait.closed {
  color: var(--gray); border-color: var(--gray); background: transparent;
  box-shadow: none;
}



.xdetail {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .32s ease;
}
.xcard.open .xdetail { grid-template-rows: 1fr; }
.xdetail-in { overflow: hidden; min-height: 0; }
.xdetail-in .dir { padding: 12px 16px 16px; }
.xplaces {
  color: var(--dim); font-size: 13px;
  padding: 10px 16px 0;
  border-top: 1px solid var(--line);
}
.xnote {
  color: var(--faint); font-size: 12.5px; font-style: italic;
  padding: 6px 16px 0;
}

.listhint {
  font-size: 12.5px; color: var(--faint);
  padding: 2px 4px 0;
}

/* ---------- desktop: master-detail ---------- */
#panel { display: none; }
@media (min-width: 900px) {
  /* Master-detail: list left, live detail right. The panel stretches to the
     list column's full height and its camera fills the slack, so the four
     rows and the panel end on the same line. */
  .wrap { max-width: 1080px; }
  .layout {
    display: grid;
    grid-template-columns: minmax(320px, 400px) 1fr;
    gap: 24px;
  }
  /* the cards own row 1; the Point Roberts toggle gets row 2 to itself,
     so the panel's bottom edge lines up with the last card, not the toggle */
  #cards { grid-column: 1; grid-row: 1; }
  #panel { grid-column: 2; grid-row: 1; }
  .layout > .prtoggle { grid-column: 1; grid-row: 2; }
  .stale-banner { grid-column: 1 / -1; }
  .xcard .xdetail { display: none; } /* detail lives in the panel */
  .xcard { cursor: pointer; }
  /* rich rows: the info lives here now, so the list column balances the panel */
  #cards .xcard { padding: 14px 16px; margin: 0 0 16px; }
  /* the wrapper is always #cards' last child, so the last card is nth-last-child(2);
     it stays flush with the panel's bottom edge, the open gap comes from the wrapper */
  #cards .xcard:nth-last-child(2) { margin-bottom: 0; }
  #cards .prwrap { margin-top: 0; }
  #cards .prwrap.open { margin-top: 16px; }
  #cards .prwrap > .xcard { margin: 0; }
  .xmeta { margin-top: 10px; display: grid; gap: 3px; }
  .xm-places { font-size: 13px; color: var(--dim); }
  /* bottom line: hours left, source right — wraps instead of colliding */
  .xm-bot { display: flex; justify-content: space-between; align-items: baseline; gap: 4px 16px; flex-wrap: wrap; }
  .xm-hours { font-size: 12px; color: var(--faint); }
  .xm-src { font-size: 12px; color: var(--faint); margin-left: auto; white-space: nowrap; }
  .xm-src .note { color: var(--amber); }
  .xm-closed { font-size: 12.5px; color: var(--dim); margin-top: 2px; }
  .xm-closed strong { color: var(--text); }
  #panel {
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 16px;
    background: linear-gradient(180deg, #14141e, #0d0d15);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow), 0 0 44px rgba(0, 229, 255, .05);
    padding: 20px;
  }
  /* weather sits under the header as quiet metadata */
  .pwx { margin-top: 6px; font-size: 13px; color: var(--dim); }
  .phead { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 2px; }
  .pname {
    font-family: var(--font-d); font-size: 21px; font-weight: 700;
    letter-spacing: 1px; text-transform: uppercase;
  }
  .pwait {
    font-family: var(--font-d); font-size: 17px; font-weight: 700;
    letter-spacing: .8px; text-transform: uppercase; white-space: nowrap;
    padding: 9px 16px; border-radius: 8px; border: 1px solid transparent;
  }
  .pwait.light {
    color: var(--green); border-color: var(--green); background: var(--green-bg);
    box-shadow: 0 0 16px rgba(0, 255, 157, .30);
  }
  .pwait.moderate {
    color: var(--amber); border-color: var(--amber); background: var(--amber-bg);
    box-shadow: 0 0 16px rgba(255, 176, 32, .30);
  }
  .pwait.heavy {
    color: var(--red); border-color: var(--red); background: var(--red-bg);
    box-shadow: 0 0 18px rgba(255, 59, 92, .40);
  }
  .pwait.unknown { color: var(--gray); border-color: var(--line); background: var(--gray-bg); }
  .pwait.closed { color: var(--gray); border-color: var(--gray); background: transparent; }
  #panel .hero { margin: 12px -20px 0; border-radius: 0; flex: 1 1 auto; min-height: 0; }
  /* the detail wrapper nests the cam — it has to be the flex column, not the panel itself */
  #panel .xdetail-in { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
  #panel .hero .shot { min-height: 260px; }
  #panel .hero.single img { aspect-ratio: auto; }
  #panel .hero .nocam { min-height: 260px; display: flex; align-items: center; justify-content: center; }
  #panel .xnote { padding: 6px 0 0; }
  /* slim direction label: the rows already carry source, hours, and status */
  .pdir {
    margin-top: 14px;
    font-family: var(--font-d); font-size: 12.5px; font-weight: 700;
    letter-spacing: 1.5px; text-transform: uppercase; color: var(--neon);
    text-shadow: 0 0 12px rgba(0, 229, 255, .35);
  }
}
.navbtn {
  position: relative; overflow: hidden;
  display: block; width: 100%;
  margin-top: 4px; padding: 15px;
  background: rgba(0, 229, 255, .05);
  color: var(--neon);
  border: 2px solid var(--neon);
  /* chamfered cyberpunk corners */
  clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px);
  font-family: var(--font-d); font-size: 16px; font-weight: 700;
  letter-spacing: 3px; text-transform: uppercase;
  text-shadow: 0 0 10px rgba(0, 229, 255, .8);
  /* drop-shadow follows the clipped shape - box-shadow would be cut off */
  filter: drop-shadow(0 0 10px rgba(0, 229, 255, .45));
  animation: navpulse 2.8s ease-in-out infinite;
  cursor: pointer;
}
.navbtn:hover { background: rgba(0, 229, 255, .12); }
.navbtn:active { transform: scale(.99); }
@keyframes navpulse {
  0%, 100% { filter: drop-shadow(0 0 8px rgba(0, 229, 255, .35)); }
  50% { filter: drop-shadow(0 0 20px rgba(0, 229, 255, .7)); }
}
/* closed crossing: dead terminal - flat gray, no neon */
.navbtn.closed {
  background: rgba(255, 255, 255, .05);
  color: var(--faint);
  border-color: var(--faint);
  text-shadow: none;
  filter: none;
  animation: none;
  cursor: default;
}
.navbtn.closed:active { transform: none; }
/* hold-to-share discoverability: a neon fill tracks the 550ms hold, so the
   gesture reveals itself the moment anyone presses and lingers */
.navbtn .navfill {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(0, 229, 255, .48), rgba(0, 229, 255, .16));
  transform: scaleX(0); transform-origin: left center;
  transition: transform 450ms cubic-bezier(.22, 1, .36, 1);
  pointer-events: none;
}
.navbtn.holding .navfill { transform: scaleX(1); transition: transform 550ms linear; }
.navbtn .navlabel { position: relative; }
/* one-time self-demo: the button presses itself to teach the hold gesture */
.navbtn.demo { animation: demopress 1.9s ease-in-out 1; }
.navbtn.demo .navfill { animation: demofill 1.9s ease-in-out 1; }
@keyframes demopress { 0%, 100% { transform: scale(1); } 30%, 70% { transform: scale(.97); } }
@keyframes demofill { 0% { transform: scaleX(0); } 40%, 70% { transform: scaleX(1); } 100% { transform: scaleX(0); } }

/* mobile: the navigate action caps the expanded row detail — full-width,
   thumb-sized, the last thing in the card. (Desktop hides .xcard .xdetail,
   so this placement only ever shows below 900px.) */
.xcard .xdetail .navbtn {
  margin: 14px 0 2px;
  padding: 17px 15px;
}

.prtoggle {
  display: block;
  margin: 14px auto 4px;
  background: none; border: 1px dashed var(--line);
  color: var(--dim); font-family: var(--font-d); font-size: 13px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase;
  padding: 9px 18px; border-radius: 999px; cursor: pointer;
}
.prtoggle:active { background: var(--bg2); }
/* Point Roberts: the card lives above the toggle and unfolds smoothly */
.prwrap {
  display: grid; grid-template-rows: 0fr;
  margin-top: 0;
  transition: grid-template-rows .38s cubic-bezier(.4, 0, .2, 1),
              margin-top .38s cubic-bezier(.4, 0, .2, 1);
}
.prwrap.open { grid-template-rows: 1fr; margin-top: 8px; }
.prwrap > .xcard { min-height: 0; margin: 0; }

/* ---------- detail: cams, directions ---------- */
.hero { display: flex; gap: 2px; background: #000; border-top: 1px solid var(--line); }
.hero .shot { position: relative; flex: 1; min-height: 150px; background: #0a0d13; }
.hero.single .shot { min-height: 190px; }
.hero img { width: 100%; height: 100%; object-fit: cover; display: block; aspect-ratio: 16/9; }
.hero.single img { aspect-ratio: 16/8; }
/* camera sits as a slim strip until tapped */
.hero.cam-mini { cursor: pointer; }
.hero.cam-mini .shot { min-height: 54px; }
.hero.cam-mini img { aspect-ratio: 21/4; }
.hero.cam-mini .nocam { min-height: 54px; font-size: 12px; }
.hero.cam-mini .tag::after { content: ' \2922'; }
.hero .tag {
  position: absolute; left: 8px; bottom: 8px;
  background: rgba(0, 229, 255, .12); color: var(--neon);
  border: 1px solid rgba(0, 229, 255, .45);
  font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  padding: 4px 8px; border-radius: 6px;
  backdrop-filter: blur(4px);
}
.hero .nocam {
  display: flex; align-items: center; justify-content: center;
  min-height: 120px; color: var(--faint); font-size: 13px;
  background: linear-gradient(135deg, #0a0a12, #12121c);
}

.dir { padding: 14px 16px; border-top: 1px solid var(--line); }
.dir-label {
  font-family: var(--font-d);
  font-size: 12px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--neon); margin-bottom: 8px;
  display: flex; justify-content: space-between; align-items: center;
  text-shadow: 0 0 12px rgba(0, 229, 255, .35);
}
.wx { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--faint); text-shadow: none; }

.src { font-size: 12.5px; color: var(--faint); margin-top: 6px; }
.src .note { color: var(--amber); }

/* closed lane: flat gray, no glow — the absence of neon is the signal */
.closedline { margin-top: 12px; font-size: 13px; color: var(--dim); }
.closedline strong { color: var(--text); }

/* desktop has no long-press; don't promise the gesture */
@media (min-width: 900px) { .hint-touch { display: none; } }

/* navigate */

/* ---------- footer / about ---------- */
footer { margin-top: 26px; text-align: center; }
footer .row { display: flex; gap: 10px; justify-content: center; margin-bottom: 14px; }
footer button.linklike {
  background: none; border: 0; color: var(--dim); font: inherit; font-size: 14px; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
footer .fine { font-size: 12.5px; color: #c9c6e2; max-width: 520px; margin: 0 auto; background: rgba(8,8,18,.72); padding: 8px 16px; border-radius: 10px; border: 1px solid rgba(0,229,255,.12); }
/* the fixed snapshot pill would sit on the footer toggles — clear it */
/* snapshot: a utility, not an action — sharp magenta ghost tag. Nothing else
   in the app uses sharp corners or magenta, so it can't be mistaken for a
   toggle, a wait pill, or the navigate button. Lives in the header, never
   floating over content. */
.snapchip {
  background: transparent;
  border: 1px solid rgba(255, 61, 242, .38);
  color: rgba(255, 61, 242, .72);
  border-radius: 3px;
  padding: 6px 10px;
  font-family: var(--font-d); font-size: 10px; font-weight: 700;
  letter-spacing: 2px; text-transform: uppercase;
  white-space: nowrap; cursor: pointer;
  text-shadow: 0 0 6px rgba(255, 61, 242, .22);
  box-shadow: 0 0 8px rgba(255, 61, 242, .07);
}
.snapchip:active {
  transform: scale(.96);
  background: var(--mag-soft);
  border-color: var(--mag); color: var(--mag);
}

dialog {
  background: #12121b; color: var(--text);
  border: 1px solid var(--neon); border-radius: 12px;
  box-shadow: 0 0 34px rgba(0, 229, 255, .18);
  max-width: 560px; width: calc(100vw - 40px);
  padding: 22px; margin: auto;
}
dialog::backdrop { background: rgba(2, 2, 8, .72); backdrop-filter: blur(3px); }
dialog h2 { margin: 0 0 8px; font-size: 20px; font-family: var(--font-d); letter-spacing: 1px; text-transform: uppercase; }
dialog p, dialog li { font-size: 14px; color: var(--dim); }
dialog ul, dialog ol { padding-left: 20px; }
dialog .close {
  margin-top: 14px; width: 100%;
  background: var(--neon-soft); border: 1px solid var(--neon); color: var(--neon);
  border-radius: 8px; padding: 11px;
  font-family: var(--font-d); font-size: 15px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase; cursor: pointer;
  box-shadow: 0 0 14px rgba(0, 229, 255, .25);
}

.toast {
  position: fixed; left: 50%; bottom: 76px; transform: translateX(-50%) translateY(20px);
  background: #12121b; color: var(--neon); border: 1px solid var(--neon);
  padding: 10px 18px; border-radius: 999px; font-size: 14px; font-weight: 600;
  box-shadow: 0 0 18px rgba(0, 229, 255, .30);
  opacity: 0; pointer-events: none; transition: all .25s; z-index: 40;
  max-width: calc(100vw - 48px); text-align: center;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

.loading {
  text-align: center; color: var(--dim); padding: 60px 20px; font-size: 15px;
  font-family: var(--font-d); letter-spacing: 2px; text-transform: uppercase;
}
.err {
  background: var(--red-bg); border: 1px solid var(--red); color: var(--red);
  border-radius: 10px; padding: 14px; margin: 14px 0; font-size: 14px;
  box-shadow: 0 0 16px rgba(255, 59, 92, .20);
}

/* ---------- backdrop: full-bleed neon panorama, wide screens only ----------
   Seattle left, Vancouver right, a border-gate portal in the middle,
   traffic crawling the highway across the bottom. Still air: the whole
   thing hides in driving mode and under prefers-reduced-motion.
   Pure atmosphere: pointer-events none, dim, twinkling windows. */
.bg {
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none; opacity: .5; display: none;
}
.bg svg {
  width: 100%; height: 100%; display: block;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 30%);
  mask-image: linear-gradient(180deg, transparent 0, #000 30%);
}
@media (min-width: 1420px) { .bg { display: block; } }
.bg .win { animation: twinkle 4.5s ease-in-out infinite; }
@keyframes twinkle { 0%, 100% { opacity: .95; } 50% { opacity: .12; } }
/* gate beacons: alternating amber blink */
.bg .beacon { animation: beacon 1.6s ease-in-out infinite; }
.bg .beacon.b2 { animation-delay: .8s; }
@keyframes beacon { 0%, 100% { opacity: 1; } 50% { opacity: .2; } }
/* barrier arm: rests down while cars wait, rises to let them through, lowers again */
.bg .arm { transform-box: fill-box; transform-origin: 100% 50%; animation: armrise 12s ease-in-out infinite; }
@keyframes armrise {
  0%, 30% { transform: rotate(0); }
  42%, 62% { transform: rotate(80deg); }
  74%, 100% { transform: rotate(0); }
}
/* traffic: cars cruise both lanes, queued cars breathe their brake lights */
.bg .mcar { animation: drivR 36s linear infinite; }
.bg .mcar.flip { animation-name: drivL; }
.bg .mcar.gate-r { animation-name: drivRgate; }
.bg .mcar.gate-l { animation-name: drivLgate; }
@keyframes drivRgate {
  0% { transform: translateX(950px); opacity: 0; }
  6% { opacity: 1; }
  92% { opacity: 1; }
  100% { transform: translateX(1750px); opacity: 0; }
}
@keyframes drivLgate {
  0% { transform: translateX(640px); opacity: 0; }
  6% { opacity: 1; }
  92% { opacity: 1; }
  100% { transform: translateX(-160px); opacity: 0; }
}
@keyframes drivR { from { transform: translateX(-240px); } to { transform: translateX(1840px); } }
@keyframes drivL { from { transform: translateX(1840px); } to { transform: translateX(-240px); } }
.bg .brake { animation: brake 2.4s ease-in-out infinite; }
.bg .brake.b2 { animation-delay: 1.2s; }
@keyframes brake { 0%, 100% { opacity: .95; } 50% { opacity: .4; } }
/* gate signs (roadside) */
.bgsign-t {
  font-family: var(--font-d); font-size: 13px; font-weight: 700;
  letter-spacing: 1px; fill: #00e5ff;
}
.bgsign-s {
  font-family: var(--font-d); font-size: 10px; font-weight: 600;
  letter-spacing: 1.5px; fill: #9a97b5;
}
/* static background for now: all panorama motion off (delete to re-enable) */
.bg .win, .bg .beacon, .bg .arm, .bg .mcar, .bg .brake { animation: none; }
.bg .mcar.flip, .bg .mcar.gate-r, .bg .mcar.gate-l { animation-name: none; }
@media (prefers-reduced-motion: reduce) {
  .bg .win, .bg .beacon, .bg .arm, .bg .mcar, .bg .brake,
  .updated::before { animation: none; }
  .prwrap, .prwrap > .xcard { transition: none; }
  .xdetail { transition: none; }
  .navbtn { animation: none; }
}

@media (max-width: 899px) {
  /* driving mode is a desktop thing: the phone UI is already minimal, and the
     toggle just adds clutter next to About */
  footer .drivetoggle { display: none; }
  /* both switches on one line, pinned to the sides */
  .controls { flex-wrap: nowrap; gap: 8px; padding: 8px 0 10px; margin-top: 12px; }
  .seg { padding: 2px; gap: 1px; }
  .seg button { font-size: 11px; letter-spacing: .5px; padding: 7px 9px; white-space: nowrap; }
  /* thumb reach: switches and rows sit lower, with more air between rows */
  .layout { padding-top: 14px; }
  .xcard { margin: 12px 0; }
}

/* ---------- driving mode: dim + declutter for night driving ----------
   Toggle lives in the footer, persisted in localStorage.
   Kills glare, motion, and the camera feeds; severity colors stay,
   pills get bigger — the list becomes glanceable in the dark. */
.drivetoggle {
  background: none; border: 1px solid var(--line); color: var(--dim);
  font-family: var(--font-d); font-size: 12px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase;
  padding: 8px 16px; border-radius: 999px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px;
}
.drivetoggle::before {
  content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--faint);
}
.drivetoggle.on { color: var(--neon); border-color: var(--neon); }
.drivetoggle.on::before { background: var(--neon); box-shadow: 0 0 8px var(--neon); }

/* install: same pill language as the driving toggle, neon edge so it's
   findable — hidden until the browser says install is possible (or iOS,
   where the how-to is shown instead of a real prompt). */
.installbtn {
  background: none; border: 1px solid var(--neon); color: var(--neon);
  font-family: var(--font-d); font-size: 12px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase;
  padding: 8px 16px; border-radius: 999px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px;
  box-shadow: 0 0 10px rgba(0, 229, 255, .18);
}
.installbtn::before { content: '\2193'; font-size: 14px; line-height: 1; }
.installbtn[hidden] { display: none; }

body.driving { background: var(--bg); }
body.driving .bg,
body.driving .hero { display: none; }
body.driving .updated::before { animation: none; }
body.driving .brand h1 .dot,
body.driving .dir-label { text-shadow: none; }
/* glows off — the colors stay, the glare goes */
body.driving .xwait,
body.driving .pwait,
body.driving .navbtn,
body.driving .snapchip,
body.driving .seg button.on,
body.driving .toast,
body.driving dialog,
body.driving .xcard.sev-heavy,
body.driving .xcard.open,
body.driving .xcard::before,
body.driving .stale-banner,
body.driving .err { box-shadow: none; }
/* the navigate button glows via filter/text-shadow, not box-shadow */
body.driving .navbtn { filter: none; text-shadow: none; animation: none; }
/* glanceable: bigger pills, quieter everything else */
body.driving .xwait { font-size: 16px; padding: 9px 15px; }
body.driving .xplaces,
body.driving .xnote,
body.driving .src,
body.driving .listhint,
body.driving footer .fine { color: var(--faint); }
