/* css/style.css */
/* NYC HUD design system: quiet graphite glass in the corners of the screen, taxi yellow for whatever is active,
   NYC DOT green for street names, so that the city itself stays the star */

:root {
  /* Surfaces */
  --glass: rgba(18, 19, 22, 0.62);
  --glass-strong: rgba(16, 17, 20, 0.88);
  --glass-border: rgba(255, 255, 255, 0.09);
  --glass-highlight: rgba(255, 255, 255, 0.08);
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.045 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --hover: rgba(255, 255, 255, 0.08);
  --divider: rgba(255, 255, 255, 0.1);

  /* Text */
  --text: #f6f5f2;
  --text-2: rgba(246, 245, 242, 0.68);
  --text-3: rgba(246, 245, 242, 0.44);

  /* Accents */
  --taxi: #ffc21a;
  --taxi-ink: #17140a;
  --sign-green: #0b6a46;
  --highway: #c08a3e;
  --ok: #5ee08f;
  --warn: #ffc857;
  --bad: #ff7a6b;

  /* Shape & motion */
  --edge: 20px;
  --bar-h: 50px;
  --r-panel: 16px;
  --r-ctl: 10px;
  --shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.7), 0 2px 8px rgba(0, 0, 0, 0.2);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
  --font-sign: 'Overpass', 'Inter', 'Helvetica Neue', Arial, sans-serif;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #0a0b0d;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  user-select: none;
  overscroll-behavior: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.85);
  outline-offset: 2px;
}

.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.icon {
  width: 18px;
  height: 18px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon-sm {
  width: 14px;
  height: 14px;
}

kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  border-radius: 5px;
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 650;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07), inset 0 -1px 0 rgba(0, 0, 0, 0.3);
}

#canvas-container {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 1;
  cursor: grab;
}

#canvas-container:active {
  cursor: grabbing;
}

/* Soft scrims behind the HUD: keep small type legible over a bright midday street */
body::before,
body::after {
  content: '';
  position: fixed;
  left: 0;
  right: 0;
  z-index: 5;
  pointer-events: none;
  transition: opacity 0.35s ease;
}

body::before {
  top: 0;
  height: 120px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.22), rgba(0, 0, 0, 0));
}

body::after {
  bottom: 0;
  height: 210px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.36), rgba(0, 0, 0, 0));
}

/* ------------------------------------------------------------------------------------------------------------------
   Glass panel
   ------------------------------------------------------------------------------------------------------------------ */
.panel {
  background: var(--grain), var(--glass);
  -webkit-backdrop-filter: blur(22px) saturate(170%);
  backdrop-filter: blur(22px) saturate(170%);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-panel);
  box-shadow: inset 0 1px 0 var(--glass-highlight), var(--shadow);
}

/* ------------------------------------------------------------------------------------------------------------------
   Loading screen
   ------------------------------------------------------------------------------------------------------------------ */
#loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  background: radial-gradient(120% 90% at 50% 38%, #1b1e24 0%, #0c0d10 55%, #060607 100%);
  transition: opacity 0.6s ease, visibility 0.6s ease;
}

#loading-overlay.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.loader {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  animation: rise-in 0.8s var(--ease-out) both;
}

.brand-badge.loader-badge {
  width: 56px;
  height: 56px;
  margin-bottom: 22px;
}

.brand-badge.loader-badge .icon {
  width: 34px;
  height: 34px;
}

.loader-title {
  font-size: 34px;
  font-weight: 650;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.loader-track {
  position: relative;
  width: 240px;
  height: 3px;
  margin: 26px 0 14px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}

.loader-fill {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--taxi);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 0.3s ease;
}

/* While the city is being built (main thread busy) the bar sweeps on the compositor; it fills once shaders compile */
.loader-track.is-indeterminate .loader-fill {
  width: 35%;
  transform: translateX(-100%);
  transition: none;
  animation: loader-sweep 1.5s cubic-bezier(0.45, 0, 0.25, 1) infinite;
  will-change: transform;
}

#loading-status {
  font-size: 12.5px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

@keyframes loader-sweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(290%); }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------------------------------------------------------
   Title screen (js/title-screen.js): over the live city, which circles the rider. Name at the top, rider and Ride at
   the bottom, the rider in the clear middle. Scrims top and bottom keep the text readable over any view.
   ------------------------------------------------------------------------------------------------------------------ */
.title-overlay {
  position: fixed;
  inset: 0;
  z-index: 95; /* under the loading screen (100), which fades off it */
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  text-align: center;
  padding: max(28px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right))
    max(18px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left));
  background:
    linear-gradient(to bottom, rgba(6, 6, 7, 0.72) 0%, rgba(6, 6, 7, 0.18) 32%, rgba(6, 6, 7, 0) 48%),
    linear-gradient(to top, rgba(6, 6, 7, 0.86) 0%, rgba(6, 6, 7, 0.3) 34%, rgba(6, 6, 7, 0) 52%);
  opacity: 0;
  transition: opacity 0.5s ease;
}
.title-overlay[hidden] { display: none; }
.title-overlay.is-shown { opacity: 1; }

.title-head,
.title-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: translateY(6px);
  transition: transform 0.7s var(--ease-out);
}
.title-overlay.is-shown .title-head,
.title-overlay.is-shown .title-foot { transform: none; }

.brand-badge.title-badge { width: 46px; height: 46px; border-radius: 13px; margin-bottom: 14px; }
.brand-badge.title-badge .icon { width: 30px; height: 30px; }

.title-kicker {
  font-family: var(--font-sign);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--taxi);
}

.title-name {
  margin-top: 2px;
  font-size: clamp(40px, 9vw, 76px);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}

.title-tagline {
  margin-top: 10px;
  font-size: 15px;
  color: var(--text-2);
}

.title-riders {
  display: flex;
  gap: 6px;
  padding: 5px;
  border-radius: 14px;
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid var(--glass-border);
}

.title-rider {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px; /* a comfortable thumb target */
  padding: 0 16px;
  border: 0;
  border-radius: 10px;
  font: 600 15px var(--font-sans);
  color: var(--text-2);
  background: transparent;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.title-rider:hover { background: var(--hover); color: var(--text); }
.title-rider.active { background: rgba(255, 255, 255, 0.14); color: var(--text); box-shadow: inset 0 0 0 1px rgba(255, 194, 26, 0.55); }

.title-ride {
  margin-top: 14px;
  min-width: 220px;
  min-height: 54px;
  padding: 0 34px;
  border: 0;
  border-radius: 16px;
  font: 800 20px var(--font-sans);
  letter-spacing: 0.02em;
  color: var(--taxi-ink);
  background: var(--taxi);
  box-shadow: 0 10px 30px -10px rgba(255, 194, 26, 0.6), inset 0 -2px 0 rgba(0, 0, 0, 0.18);
  cursor: pointer;
  transition: transform 0.15s ease, filter 0.15s ease;
}
.title-ride:hover { filter: brightness(1.06); }
.title-ride:active { transform: scale(0.97); }
.title-ride:focus-visible,
.title-rider:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }

.title-hint {
  margin-top: 10px;
  font-size: 12.5px;
  color: var(--text-3);
}
.title-hint kbd { vertical-align: 1px; }
/* The hint names the device in use (main.js sets body[data-input]); touch has the button and nothing else */
.title-hint--gamepad,
body[data-input='gamepad'] .title-hint--keyboard,
body.touch-enabled .title-hint { display: none; }
body[data-input='gamepad'] .title-hint--gamepad { display: block; }

.title-credits {
  max-width: 560px;
  margin-top: 16px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-3);
}

/* While the title is up, the game's HUD and touch controls are out of the way */
body.title-open .hud,
body.title-open #touch-controls,
body.title-open .getup-prompt { visibility: hidden; }

/* Short screens (a phone in landscape): tighter, with the rider and Ride side by side so the rider stays in view */
@media (max-height: 500px) {
  .title-overlay { padding-top: max(14px, env(safe-area-inset-top)); padding-bottom: max(10px, env(safe-area-inset-bottom)); }
  .brand-badge.title-badge { display: none; }
  .title-kicker { font-size: 11px; }
  .title-name { font-size: 36px; }
  .title-tagline { margin-top: 4px; font-size: 13px; }
  .title-foot { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px 12px; }
  .title-ride { margin-top: 0; min-width: 170px; min-height: 48px; }
  .title-hint { display: none; }
  .title-credits { flex-basis: 100%; margin-top: 0; font-size: 10.5px; }
}

/* ------------------------------------------------------------------------------------------------------------------
   HUD layout: four corners plus the bottom centre, the middle of the screen stays clear
   ------------------------------------------------------------------------------------------------------------------ */
.hud {
  position: fixed;
  z-index: 10;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.4s var(--ease-out);
}

.hud > * {
  pointer-events: auto;
}

.hud-top-left {
  top: max(var(--edge), env(safe-area-inset-top));
  left: max(var(--edge), env(safe-area-inset-left));
}

.hud-top-right {
  top: var(--edge);
  right: var(--edge);
}

.hud-bottom-left {
  left: var(--edge);
  bottom: var(--edge);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.hud-bottom-center {
  left: 50%;
  bottom: var(--edge);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.hud-bottom-right {
  right: var(--edge);
  bottom: var(--edge);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

/* Clean view [H]: everything but the toggle itself steps out of the way */
body.hud-minimized::before,
body.hud-minimized::after {
  opacity: 0;
}

body.hud-minimized .hud:not(.hud-top-right) {
  opacity: 0;
}

body.hud-minimized .hud:not(.hud-top-right),
body.hud-minimized .hud:not(.hud-top-right) > * {
  pointer-events: none;
}

body.hud-minimized .hud-top-left { transform: translateY(-10px); }
body.hud-minimized .hud-bottom-left,
body.hud-minimized .hud-bottom-right { transform: translateY(12px); }
body.hud-minimized .hud-bottom-center { transform: translate(-50%, 12px); }

body.hud-minimized .toolbar > :not(#btn-toggle-hud) {
  display: none;
}

/* ------------------------------------------------------------------------------------------------------------------
   Top left: brand
   ------------------------------------------------------------------------------------------------------------------ */
.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  height: var(--bar-h);
  padding: 0 18px 0 9px;
}

/* The game's badge: the EUC rider glyph on a taxi-yellow rounded square (no transit-line bullet) */
.brand-badge {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--taxi);
  color: var(--taxi-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.18);
}

.brand-badge .icon {
  width: 20px;
  height: 20px;
  stroke-width: 2;
}

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

.brand-titles h1 {
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.repo-link {
  flex: none;
  padding: 3px 0;
  color: var(--text-2);
  font-size: 11px;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}

.repo-link:hover,
.repo-link:focus-visible {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.brand-subtitle {
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

#hud-fps {
  font-weight: 650;
  color: var(--text-2);
}

#hud-fps.fps-ok { color: var(--ok); }
#hud-fps.fps-warn { color: var(--warn); }
#hud-fps.fps-bad { color: var(--bad); }

/* ------------------------------------------------------------------------------------------------------------------
   Top right: toolbar (time of day, teleport, map, clean view)
   ------------------------------------------------------------------------------------------------------------------ */
.toolbar {
  display: flex;
  align-items: center;
  gap: 2px;
  height: var(--bar-h);
  padding: 0 5px;
}

.toolbar-divider {
  flex: none;
  width: 1px;
  height: 20px;
  margin: 0 5px;
  background: var(--divider);
}

.time-switch {
  display: flex;
  gap: 2px;
}

.time-btn {
  height: 36px;
  padding: 0 9px;
  border-radius: var(--r-ctl);
  display: inline-flex;
  align-items: center;
  gap: 0;
  color: var(--text-2);
  transition: background-color 0.2s ease, color 0.2s ease, gap 0.35s var(--ease-out), padding 0.35s var(--ease-out);
}

.time-btn:hover {
  color: var(--text);
  background: var(--hover);
}

/* The active time of day spells out its name */
.time-btn .seg-label {
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 600;
  transition: max-width 0.4s var(--ease-out), opacity 0.25s ease;
}

.time-btn.active,
.time-btn.active:hover {
  gap: 7px;
  padding: 0 12px 0 10px;
  background: var(--text);
  color: #121314;
}

.time-btn.active .seg-label {
  max-width: 120px;
  opacity: 1;
}

.tool-btn {
  height: 36px;
  padding: 0 11px;
  border-radius: var(--r-ctl);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--text);
  transition: background-color 0.2s ease;
}

.tool-btn:hover,
.tool-btn.is-open {
  background: var(--hover);
}

.tool-btn .icon-sm {
  margin-left: -2px;
  color: var(--text-3);
  transition: transform 0.3s var(--ease-out);
}

.tool-btn.is-open .icon-sm {
  transform: rotate(180deg);
}

.tool-btn.icon-only {
  width: 36px;
  padding: 0;
  justify-content: center;
}

.icon-show {
  display: none;
}

body.hud-minimized .icon-hide {
  display: none;
}

body.hud-minimized .icon-show {
  display: block;
}

.tool-btn:active,
.time-btn:active,
.icon-btn:active,
.mode-btn:active,
.camera-current:active,
.pop-item:active {
  transform: scale(0.97);
}

/* ------------------------------------------------------------------------------------------------------------------
   Popovers (teleport destinations, cameras)
   ------------------------------------------------------------------------------------------------------------------ */
.popover {
  position: fixed;
  inset: auto;
  margin: 0;
  padding: 6px;
  min-width: 264px;
  max-height: calc(100vh - 2 * var(--edge) - 64px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  color: var(--text);
  background: var(--grain), var(--glass-strong);
  -webkit-backdrop-filter: blur(26px) saturate(170%);
  backdrop-filter: blur(26px) saturate(170%);
  border: 1px solid var(--glass-border);
  border-radius: 14px;
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 28px 60px -22px rgba(0, 0, 0, 0.8), 0 4px 14px rgba(0, 0, 0, 0.3);
  transform-origin: top right;
  transition: opacity 0.18s ease, transform 0.26s var(--ease-out), overlay 0.26s allow-discrete, display 0.26s allow-discrete;
}

.popover[data-side='above'] {
  transform-origin: bottom right;
}

.popover:not(:popover-open) {
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
}

.popover[data-side='above']:not(:popover-open) {
  transform: translateY(4px) scale(0.98);
}

@starting-style {
  .popover:popover-open {
    opacity: 0;
    transform: translateY(-4px) scale(0.98);
  }

  .popover[data-side='above']:popover-open {
    transform: translateY(4px) scale(0.98);
  }
}

.pop-title {
  padding: 9px 10px 6px;
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

.pop-title:not(:first-child) {
  margin-top: 5px;
  padding-top: 12px;
  border-top: 1px solid var(--divider);
}

.pop-item {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 10px;
  border-radius: 9px;
  text-align: left;
  font-size: 13px;
  font-weight: 550;
  color: var(--text);
  transition: background-color 0.15s ease;
}

.pop-item:hover {
  background: var(--hover);
}

.pop-item.active,
.pop-item.active:hover {
  background: var(--text);
  color: #121314;
}

.pop-item.active kbd {
  color: rgba(0, 0, 0, 0.55);
  background: rgba(0, 0, 0, 0.08);
  box-shadow: none;
}

.tp-btn {
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
}

.pop-sub {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-3);
}

/* ------------------------------------------------------------------------------------------------------------------
   Bottom left: NYC street-name signs over the GPS radar
   ------------------------------------------------------------------------------------------------------------------ */
.location {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  pointer-events: none;
}

.location-place {
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7), 0 0 14px rgba(0, 0, 0, 0.4);
  animation: rise-in 0.4s var(--ease-out) both;
}

.location-signs {
  display: flex;
  align-items: center;
  gap: 6px;
  animation: rise-in 0.4s var(--ease-out) both;
}

.location-near {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}

/* Green blade, white inset border, Highway Gothic lettering: the sign on every Manhattan corner */
.street-sign {
  max-width: 210px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 9px 13px 7px;
  font-family: var(--font-sign);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: 0.01em;
  color: #ffffff;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 55%), var(--sign-green);
  border-radius: 6px;
  outline: 1.5px solid rgba(255, 255, 255, 0.92);
  outline-offset: -4px;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.35), 0 10px 22px -10px rgba(0, 0, 0, 0.75);
}

.radar {
  position: relative;
  width: 288px;
  height: 184px;
  overflow: hidden;
  border-radius: 18px;
  background: #0a1118;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  cursor: pointer;
  transition: transform 0.35s var(--ease-out);
}

.radar:hover {
  transform: translateY(-2px);
}

/* Inner rim: a soft vignette so the map sinks into the frame */
.radar::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06), inset 0 0 30px rgba(0, 0, 0, 0.55);
}

#minimap-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.radar-north {
  position: absolute;
  top: 7px;
  left: 50%;
  transform: translateX(-50%);
  width: 17px;
  height: 17px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 9px;
  font-weight: 800;
  line-height: 1;
  color: #ffffff;
  background: rgba(10, 12, 15, 0.72);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
  pointer-events: none;
}

.radar-key {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 1;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(10, 12, 15, 0.6);
  transition: background-color 0.2s ease, color 0.2s ease;
}

.radar:hover .radar-key {
  color: var(--taxi-ink);
  background: var(--taxi);
  box-shadow: none;
}

/* ------------------------------------------------------------------------------------------------------------------
   Bottom centre: travel mode switcher & keyboard guide
   ------------------------------------------------------------------------------------------------------------------ */
.controls-hint {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 16px;
  max-width: 600px;
  font-size: 12px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.88);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.75);
  pointer-events: none;
}

.hint {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  white-space: nowrap;
  animation: rise-in 0.35s var(--ease-out) both;
}

.hint kbd {
  color: #ffffff;
  background: rgba(12, 13, 15, 0.55);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  text-shadow: none;
}

/* Gamepad prompts (shown after any pad input, main.js setPromptDevice): face buttons are round and coloured in the
   Xbox layout; triggers, bumpers and sticks keep the key shape */
.hint kbd[data-pad='A'],
.hint kbd[data-pad='B'],
.hint kbd[data-pad='X'],
.hint kbd[data-pad='Y'] {
  width: 19px;
  padding: 0;
  border-radius: 50%;
  font-weight: 800;
}
.hint kbd[data-pad='A'] { color: #7ee07e; }
.hint kbd[data-pad='B'] { color: #ff7a6e; }
.hint kbd[data-pad='X'] { color: #6eb5ff; }
.hint kbd[data-pad='Y'] { color: #ffd34d; }

.hint-label {
  margin-left: 4px;
}

.mode-switch {
  position: relative;
  display: flex;
  gap: 2px;
  padding: 5px;
}

/* The taxi-yellow pill glides to the selected mode (positioned by main.js) */
.mode-indicator {
  position: absolute;
  z-index: 0;
  top: 5px;
  bottom: 5px;
  left: 0;
  width: var(--ind-w, 0px);
  transform: translateX(var(--ind-x, 0px));
  border-radius: 12px;
  background: var(--taxi);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), inset 0 -1px 0 rgba(0, 0, 0, 0.12), 0 4px 12px -4px rgba(0, 0, 0, 0.5);
  transition: transform 0.45s var(--ease-out), width 0.45s var(--ease-out);
}

.mode-switch.no-anim .mode-indicator {
  transition: none;
}

.mode-btn {
  position: relative;
  z-index: 1;
  height: 42px;
  padding: 0 12px 0 11px;
  border-radius: 12px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--text-2);
  transition: color 0.25s ease, background-color 0.2s ease;
}

.mode-btn:hover {
  color: var(--text);
  background: var(--hover);
}

.mode-btn.active,
.mode-btn.active:hover {
  color: var(--taxi-ink);
  background: transparent;
}

.mode-btn .icon {
  width: 20px;
  height: 20px;
  stroke-width: 1.7;
}

.mode-btn kbd {
  margin-left: 2px;
  transition: color 0.25s ease, background-color 0.25s ease;
}

.mode-btn.active kbd {
  color: rgba(23, 20, 10, 0.62);
  background: rgba(23, 20, 10, 0.1);
  box-shadow: none;
}

/* ------------------------------------------------------------------------------------------------------------------
   Bottom right: speed cluster & camera switcher
   ------------------------------------------------------------------------------------------------------------------ */
.cluster {
  width: 272px;
  overflow: hidden;
}

.gauge {
  padding: 13px 16px 15px;
}

.gauge-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.gauge-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

.gauge-speed {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 5px;
}

#hud-speed {
  font-size: 42px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums;
}

.gauge-unit {
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

.gauge-meter {
  position: relative;
  height: 4px;
  margin-top: 12px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}

/* Speed as a share of the wheel's top speed; it turns taxi yellow while the overspeed beeps sound */
#hud-speed-meter {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--text);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 0.25s linear, background-color 0.2s ease;
}

body.is-overspeed #hud-speed-meter {
  background: var(--taxi);
}

/* km/h rides along at the right of the gauge, small and dim, so neither unit has to be chosen */
.gauge-alt {
  margin-left: auto;
  align-self: baseline;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-3);
}

#hud-speed-kmh {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
}

/* Wheel cues (euc-hud.js, EUC Thrills' hudModel): the power ladder and tilt-back, and the over-speed warning, whose
   blink shares the beeps' period. Pills above the gauge; nothing shows while all is well. */
.wheel-cues {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  pointer-events: none;
}

.wheel-cues:not(:has(.wheel-cue:not([hidden]))) {
  display: none;
}

.wheel-cue {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--glass-strong);
  box-shadow: var(--shadow);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
  animation: rise-in 0.25s var(--ease-out) both;
}

.wheel-cue[hidden] {
  display: none;
}

.power-cue::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 8px currentColor;
}

.power-cue[data-level='notice'],
.overspeed-cue[data-level='notice'] { color: #ffd23f; }
.power-cue[data-level='warn'],
.overspeed-cue[data-level='warn'] { color: #ff8a1f; }
.power-cue[data-level='tiltBack'],
.overspeed-cue[data-level='critical'] { color: #ff4a3d; }
.power-cue[data-level='tiltBack'] { animation: rise-in 0.25s var(--ease-out) both, cue-pulse 1.1s ease-in-out infinite; }

.overspeed-cue {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  animation: beep-blink var(--beep-period, 1s) steps(1, end) infinite;
}

@keyframes beep-blink {
  0%, 74% { opacity: 1; }
  75%, 100% { opacity: 0.34; }
}

@keyframes cue-pulse {
  50% { opacity: 0.58; }
}

/* Get-up prompt (euc-hud.js): above the fallen rider, in taxi yellow, until they are back on the wheel */
.getup-prompt {
  position: fixed;
  left: 50%;
  top: 38%;
  z-index: 13;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 20px 10px 16px;
  border: 1px solid rgba(255, 194, 26, 0.55);
  border-radius: 999px;
  background: var(--glass-strong);
  box-shadow: var(--shadow);
  font-size: 17px;
  font-weight: 650;
  white-space: nowrap;
  pointer-events: none;
  animation: getup-in 0.35s var(--ease-out) both;
}

.getup-prompt[hidden] {
  display: none;
}

.getup-prompt kbd,
body.touch-enabled .getup-prompt kbd {
  display: inline-flex;
  min-width: 34px;
  height: 30px;
  padding: 0 10px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--taxi-ink);
  background: var(--taxi);
  box-shadow: none;
  animation: getup-pulse 1.1s ease-in-out infinite;
}

.getup-prompt kbd[data-pad='B'] {
  width: 32px;
  min-width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 50%;
  color: #2a0b07;
  background: #ff7a6e;
}

@keyframes getup-in {
  from { opacity: 0; transform: translate(-50%, -30%); }
  to { opacity: 1; transform: translate(-50%, -50%); }
}

@keyframes getup-pulse {
  50% { box-shadow: 0 0 0 5px rgba(255, 194, 26, 0.25); }
}

/* Officer Dorkins (nemesis-chase.js): a cue among the wheel cues while he is on your tail, with his light bar's red
   and blue and a meter that fills as you shake him off; a short banner when he ambushes and when you lose him */
.chase-cue {
  color: #f2f4f8;
}

.chase-light {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  animation: chase-flash 0.9s steps(1, end) infinite;
}

.chase-meter {
  display: none;
  width: 54px;
  height: 5px;
  border-radius: 3px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.16);
}

.chase-meter > span {
  display: block;
  width: 0;
  height: 100%;
  background: #7bf0a0;
}

.chase-cue[data-state='unseen'] .chase-meter,
.chase-cue[data-state='far'] .chase-meter {
  display: block;
}

.chase-cue[data-state='unseen'],
.chase-cue[data-state='far'] {
  color: #b9f5cc;
}

.chase-banner {
  position: fixed;
  left: 50%;
  top: 20%;
  z-index: 12;
  transform: translate(-50%, -50%);
  padding: 10px 22px;
  border: 2px solid #ff3b3b;
  border-radius: 999px;
  background: var(--glass-strong);
  box-shadow: var(--shadow);
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  animation: getup-in 0.35s var(--ease-out) both;
}

.chase-banner[data-kind='ambush'] {
  animation: getup-in 0.35s var(--ease-out) both, chase-border 0.9s steps(1, end) infinite;
}

.chase-banner[data-kind='escaped'] {
  border-color: #7bf0a0;
  color: #b9f5cc;
}

/* His wind-up: taxi yellow, as the get-up prompt, pulsing fast; the hit: red */
.chase-banner[data-kind='paddle'] {
  border-color: #ffd23f;
  color: #ffe27a;
  animation: getup-in 0.2s var(--ease-out) both, cue-pulse 0.35s ease-in-out infinite;
}

.chase-banner[data-kind='busted'] {
  border-color: #ff3b3b;
  color: #ff8a80;
}

.chase-banner[hidden] {
  display: none;
}

body.title-open .chase-banner { visibility: hidden; }

@media (max-width: 520px) {
  .chase-banner { font-size: 14px; padding: 8px 16px; }
}

@keyframes chase-flash {
  0%, 49% { background: #ff3b3b; box-shadow: 0 0 9px #ff3b3b; }
  50%, 100% { background: #3b6bff; box-shadow: 0 0 9px #3b6bff; }
}

@keyframes chase-border {
  0%, 49% { border-color: #ff3b3b; }
  50%, 100% { border-color: #3b6bff; }
}

.camera-switch {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-top: 1px solid var(--divider);
}

.icon-btn {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: var(--r-ctl);
  display: inline-grid;
  place-items: center;
  color: var(--text-2);
  transition: background-color 0.15s ease, color 0.15s ease;
}

.icon-btn:hover {
  color: var(--text);
  background: var(--hover);
}

.camera-current {
  flex: 1;
  min-width: 0;
  height: 36px;
  padding: 0 8px;
  border-radius: var(--r-ctl);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  transition: background-color 0.15s ease;
}

.camera-current:hover,
.camera-current.is-open {
  background: var(--hover);
}

.camera-current .icon {
  color: var(--text-3);
}

#hud-active-camera {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ------------------------------------------------------------------------------------------------------------------
   Full-screen interactive street map ([M])
   ------------------------------------------------------------------------------------------------------------------ */
.fullmap-modal {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: #0a1118;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}

.fullmap-modal.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.fullmap-canvas-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  cursor: crosshair;
}

.fullmap-canvas-wrap.is-panning {
  cursor: grabbing;
}

#fullmap-canvas {
  touch-action: none;
  display: block;
  width: 100%;
  height: 100%;
}

.fullmap-header {
  position: absolute;
  top: var(--edge);
  left: var(--edge);
  right: var(--edge);
  display: flex;
  align-items: stretch;
  gap: 10px;
  pointer-events: none;
}

.fullmap-header > * {
  pointer-events: auto;
}

.fullmap-modal:not(.hidden) .fullmap-header,
.fullmap-modal:not(.hidden) .map-controls,
.fullmap-modal:not(.hidden) .fullmap-footer,
.fullmap-modal:not(.hidden) .fullmap-credits {
  animation: rise-in 0.45s var(--ease-out) both;
}

.fullmap-title {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 9px 20px 9px 11px;
}

.fullmap-title h2 {
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.2;
  white-space: nowrap;
}

.fullmap-subtitle {
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fullmap-search-wrap {
  flex: 0 1 440px;
  min-width: 180px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  color: var(--text-3);
  cursor: text;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.fullmap-search-wrap:focus-within {
  color: var(--text-2);
  border-color: rgba(255, 255, 255, 0.24);
  background: var(--grain), var(--glass-strong);
}

.fullmap-search {
  flex: 1;
  min-width: 0;
  height: 100%;
  background: none;
  border: 0;
  outline: none;
  color: var(--text);
  font: inherit;
  font-size: 13.5px;
  user-select: text;
}

.fullmap-search::placeholder {
  color: var(--text-3);
}

.fullmap-close {
  margin-left: auto;
  height: auto;
  padding: 0 14px 0 12px;
  border-radius: var(--r-panel);
}

.fullmap-close:hover {
  background: var(--grain), var(--glass-strong);
}

/* (centred with `translate`, which the rise-in entrance animation on `transform` leaves alone) */
.map-controls {
  position: absolute;
  top: 50%;
  right: var(--edge);
  translate: 0 -50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.map-compass {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: grid;
  place-items: center;
}

.map-compass svg {
  width: 44px;
  height: 44px;
}

.map-compass text {
  font: 800 7.5px var(--font-sans);
  fill: #ffffff;
}

.map-zoom {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px;
  border-radius: 14px;
}

.fullmap-footer {
  position: absolute;
  left: 50%;
  bottom: var(--edge);
  translate: -50% 0;
  display: flex;
  max-width: min(560px, calc(100% - 2 * var(--edge) - 2 * 200px));
}

.fullmap-status {
  min-width: 0;
  padding: 10px 16px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fullmap-legend {
  position: absolute;
  right: var(--edge);
  bottom: var(--edge);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-2);
  white-space: nowrap;
}

.fullmap-modal:not(.hidden) .fullmap-legend {
  animation: rise-in 0.45s var(--ease-out) both;
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.legend-swatch {
  flex: none;
  display: inline-block;
}

.player-swatch {
  width: 10px;
  height: 11px;
  background: #ffffff;
  clip-path: polygon(50% 0, 100% 100%, 50% 78%, 0 100%);
}

.landmark-swatch {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0 0 2px #0b0f14, 0 0 0 3px rgba(255, 255, 255, 0.35);
}

.gps-swatch,
.bridge-swatch {
  width: 16px;
  height: 4px;
  border-radius: 2px;
}

.gps-swatch { background: var(--taxi); }
.bridge-swatch { background: var(--highway); }

.legend-counts {
  padding-left: 14px;
  border-left: 1px solid var(--divider);
  color: var(--text-3);
}

/* Licence credits on the full map (OpenStreetMap's ODbL asks for them where the map is shown) */
.fullmap-credits {
  position: absolute;
  left: var(--edge);
  bottom: var(--edge);
  margin: 0;
  max-width: min(440px, calc(50% - var(--edge) - 300px));
  padding: 8px 12px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--text-2);
}

.fullmap-credits a {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--divider);
  text-underline-offset: 2px;
}

.fullmap-credits a:hover,
.fullmap-credits a:focus-visible {
  text-decoration-color: currentColor;
}

/* ------------------------------------------------------------------------------------------------------------------
   Responsive
   ------------------------------------------------------------------------------------------------------------------ */
@media (max-width: 1800px) {
  .legend-counts { display: none; }
}

@media (max-width: 1360px) {
  .fullmap-legend { display: none; }
}

@media (max-width: 1240px) {
  .controls-hint { display: none; }
  .mode-btn kbd { display: none; }
}

@media (max-width: 1080px) {
  .mode-label,
  .tool-label,
  .tool-btn kbd { display: none; }
  .mode-btn { padding: 0 12px; }
  .rider-switch .mode-label { display: inline; } /* both riders share the icon: keep their names */
  .tool-btn:not(.icon-only):not(.fullmap-close) { gap: 4px; padding: 0 9px; }
}

@media (max-width: 820px) {
  :root { --edge: 12px; }
  .hud-top-left { top: calc(max(var(--edge), env(safe-area-inset-top)) + 62px); }
  .brand > .brand-badge,
  .brand-heading h1,
  .brand-subtitle { display: none; }
  .brand { height: 44px; padding: 0 12px; }
  .repo-link { display: flex; align-items: center; gap: 4px; min-height: 44px; font-size: 12px; }
  .radar { width: 220px; height: 148px; }
  .cluster { width: 220px; }
  #hud-speed { font-size: 34px; }
  .fullmap-title > div { display: none; }
  .fullmap-title { padding: 9px; }
  .fullmap-footer { max-width: calc(100% - 2 * var(--edge)); bottom: calc(var(--edge) + 52px); }
  .map-controls { top: auto; bottom: calc(var(--edge) + 114px); translate: none; }
  .fullmap-credits { max-width: calc(100% - 2 * var(--edge)); bottom: var(--edge); padding: 6px 10px; font-size: 10px; }
}

@media (max-width: 620px) {
  .time-btn.active .seg-label { display: none; }
  .time-btn.active { padding: 0 9px; gap: 0; }
  .radar { display: none; }
  .hud-bottom-right { bottom: calc(var(--edge) + 64px); }
  .gauge { display: none; }
  .camera-switch { border-top: 0; }
}

/* ------------------------------------------------------------------------------------------------------------------
   Touch controls (touch-controls.js), EUC Thrills' layout (src/ui/game.css .euc-touch @5f45fff): an invisible stick
   zone over the bottom-left where a floating stick appears under the thumb, HOP / CHARGE under the right thumb, GET UP
   beside them while the rider is down. One anatomy in portrait and landscape; only size and lift change. The layer
   sits just under the HUD (z 9 < 10), so the rider chooser stays tappable where the two meet.
   ------------------------------------------------------------------------------------------------------------------ */
.euc-touch {
  position: fixed;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;

  --touch-scale: 1;
  --touch-fit: 1;
  --touch-unit: calc(16px * var(--touch-scale) * var(--touch-fit));
  --touch-stick: calc(6.6 * var(--touch-unit));
  --touch-knob: calc(2.6 * var(--touch-unit));
  --touch-throw: calc((var(--touch-stick) - var(--touch-knob)) / 2 - 0.28 * var(--touch-unit));
  --touch-primary: calc(4.05 * var(--touch-unit));
  --touch-button: calc(3.6 * var(--touch-unit));
  --touch-actions-rise: calc(0.95 * var(--touch-unit));
  --touch-rise: 0px;
  --lane-x: max(18px, env(safe-area-inset-left));
  --lane-x-right: max(18px, env(safe-area-inset-right));
  --lane-bottom: max(16px, env(safe-area-inset-bottom));
  --touch-bottom: calc(var(--lane-bottom) + var(--touch-rise));
  --touch-throttle: 0;
  --touch-steer: 0;
  --touch-x: 0;
  --touch-y: 0;
}

.euc-touch[hidden] { display: none; }

.touch-zone {
  position: absolute;
  left: 0;
  bottom: 0;
  width: min(48%, 384px);
  height: min(52%, 272px);
  pointer-events: auto;
  touch-action: none;
}

/* At rest the stick waits, half-faded, in the bottom-left corner; on touch it jumps under the thumb */
.touch-stick {
  position: absolute;
  left: calc(var(--lane-x) + var(--touch-stick) / 2 + 6px);
  bottom: calc(var(--touch-bottom) + var(--touch-stick) / 2);
  width: var(--touch-stick);
  height: var(--touch-stick);
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 50%;
  background: rgba(13, 16, 20, 0.34);
  opacity: 0.5;
  transform: translate(-50%, 50%);
  transition: opacity 160ms ease;
  pointer-events: none;
}

.touch-stick[data-active='true'] {
  left: calc(var(--touch-x) * 1px);
  top: calc(var(--touch-y) * 1px);
  bottom: auto;
  opacity: 0.92;
  transform: translate(-50%, -50%);
}

.touch-knob {
  width: var(--touch-knob);
  height: var(--touch-knob);
  border-radius: 50%;
  background: rgba(246, 245, 242, 0.9);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  transform: translate(calc(var(--touch-steer) * var(--touch-throw)), calc(var(--touch-throttle) * var(--touch-throw) * -1));
}

.stick-hint {
  position: absolute;
  top: 50%;
  width: calc(0.62 * var(--touch-unit));
  height: calc(0.62 * var(--touch-unit));
  border-top: 2px solid rgba(255, 255, 255, 0.55);
  border-left: 2px solid rgba(255, 255, 255, 0.55);
}
.stick-hint--left { left: calc(0.55 * var(--touch-unit)); transform: translateY(-50%) rotate(-45deg); }
.stick-hint--right { right: calc(0.55 * var(--touch-unit)); transform: translateY(-50%) rotate(135deg); }
.stick-hint--up { top: calc(0.55 * var(--touch-unit)); left: 50%; transform: translateX(-50%) rotate(45deg); }
.stick-hint--down { top: auto; bottom: calc(0.55 * var(--touch-unit)); left: 50%; transform: translateX(-50%) rotate(225deg); }

.touch-actions {
  position: absolute;
  right: var(--lane-x-right);
  bottom: calc(var(--touch-bottom) + var(--touch-actions-rise));
  display: grid;
  grid-template-areas: 'hop    .' 'getup  charge';
  gap: calc(0.42 * var(--touch-unit));
  align-items: end;
  justify-items: center;
}

.touch-btn {
  width: var(--touch-button);
  height: var(--touch-button);
  min-width: 44px;
  min-height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.38);
  border-radius: calc(1.05 * var(--touch-unit));
  background: rgba(13, 16, 20, 0.58);
  color: var(--text);
  font-size: max(10px, calc(0.62 * var(--touch-unit)));
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1;
  pointer-events: auto;
  touch-action: none;
  box-shadow: 0 2px 7px rgba(0, 0, 0, 0.18);
  opacity: 0.82;
}

.touch-btn--hop { grid-area: hop; border-color: rgba(230, 90, 85, 0.82); background: rgba(91, 31, 31, 0.6); }
.touch-btn--charge {
  grid-area: charge;
  width: var(--touch-primary);
  height: var(--touch-primary);
  border-color: rgba(95, 149, 223, 0.78);
  background: rgba(25, 53, 91, 0.58);
  font-size: max(9px, calc(0.5 * var(--touch-unit)));
}
/* GET UP: only while the rider is down, in taxi yellow, pulsing (the prompt above names it) */
.touch-btn--getup {
  grid-area: getup;
  display: none;
  border-color: var(--taxi);
  background: rgba(255, 194, 26, 0.9);
  color: var(--taxi-ink);
  font-size: max(9px, calc(0.5 * var(--touch-unit)));
  opacity: 1;
  animation: getup-pulse 1.1s ease-in-out infinite;
}
.euc-touch[data-down='true'] .touch-btn--getup { display: grid; }

.touch-btn[data-pressed='true'] {
  opacity: 1;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.72), 0 2px 7px rgba(0, 0, 0, 0.18);
  transform: translateY(1px);
}
.touch-btn--hop[data-pressed='true'] { background: rgba(133, 39, 37, 0.8); }
.touch-btn--charge[data-pressed='true'] { background: rgba(35, 83, 145, 0.78); }

/* A first-run hint that steps aside after a few seconds */
.touch-look-hint {
  position: absolute;
  top: calc(max(var(--edge), env(safe-area-inset-top)) + 120px);
  left: var(--lane-x);
  max-width: 45%;
  color: var(--text-2);
  font-size: 11px;
  font-weight: 550;
  text-shadow: 0 1px 5px #000;
  animation: touch-hint-out 0.6s ease 9s forwards;
}

@keyframes touch-hint-out { to { opacity: 0; visibility: hidden; } }

/* Portrait: lift both clusters clear of the rider chooser at the bottom centre */
@media (orientation: portrait) {
  .euc-touch { --touch-rise: 54px; }
}
/* Short landscape (phones on their side): smaller controls, a shorter stick zone */
@media (orientation: landscape) and (max-height: 480px) {
  .euc-touch { --touch-fit: 0.82; }
  .touch-zone { height: min(62%, 192px); }
}
@media (max-height: 352px) {
  .euc-touch { --touch-fit: 0.7; }
}

/* ------------------------------------------------------------------------------------------------------------------
   The HUD on a touch screen: no key caps, no guide row, the speed and camera at the top right
   ------------------------------------------------------------------------------------------------------------------ */
body.touch-enabled .controls-hint,
body.touch-enabled .radar,
body.touch-enabled .gauge-top,
body.touch-enabled kbd,
body.touch-enabled .toolbar-divider,
body.touch-enabled .seg-label { display: none; }

body.touch-enabled .hud-top-right { top: max(var(--edge), env(safe-area-inset-top)); right: max(var(--edge), env(safe-area-inset-right)); }
body.touch-enabled .toolbar { gap: 2px; padding: 4px; }
body.touch-enabled .time-btn,
body.touch-enabled .time-btn.active { height: 44px; min-width: 44px; padding: 0 8px; gap: 0; }
body.touch-enabled .tool-btn { min-width: 44px; min-height: 44px; }
body.touch-enabled .tool-label { display: none; }
body.touch-enabled .hud-bottom-center { bottom: max(var(--edge), env(safe-area-inset-bottom)); }
body.touch-enabled .mode-label { display: block; font-size: 10px; }
body.touch-enabled .mode-btn { width: 62px; height: 48px; padding: 0; flex-direction: column; justify-content: center; gap: 3px; }
body.touch-enabled .hud-bottom-right { top: calc(max(var(--edge), env(safe-area-inset-top)) + 62px); right: max(var(--edge), env(safe-area-inset-right)); bottom: auto; }
body.touch-enabled .wheel-cues { order: 2; }
body.touch-enabled .cluster { width: 230px; }
/* Speed stays on screen on every phone and tablet, compact: mph large, km/h beside it */
body.touch-enabled .gauge { display: block; padding: 8px 12px 9px; }
body.touch-enabled .gauge-speed { margin-top: 0; }
body.touch-enabled #hud-speed { font-size: 28px; }
body.touch-enabled .gauge-meter { margin-top: 7px; height: 3px; }
body.touch-enabled .camera-switch { border-top: 1px solid var(--divider); }
body.touch-enabled .camera-switch .icon-btn { width: 44px; height: 44px; }
body.touch-enabled .hud-bottom-left { left: max(var(--edge), env(safe-area-inset-left)); bottom: calc(max(var(--edge), env(safe-area-inset-bottom)) + 254px); max-width: calc(100% - 2 * var(--edge)); }
body.touch-enabled .hud-bottom-left > * { pointer-events: none; } /* street signs never block the stick zone */
body.touch-enabled .fullmap-header { top: max(var(--edge), env(safe-area-inset-top)); left: max(var(--edge), env(safe-area-inset-left)); right: max(var(--edge), env(safe-area-inset-right)); }
body.touch-enabled .map-controls .icon-btn { width: 44px; height: 44px; }
body.touch-enabled .pop-item { min-height: 44px; }

@media (max-width: 360px) {
  body.touch-enabled .toolbar { width: 194px; height: auto; flex-wrap: wrap; justify-content: center; }
  body.touch-enabled .hud-bottom-right { top: calc(max(var(--edge), env(safe-area-inset-top)) + 114px); }
  .touch-look-hint { top: calc(max(var(--edge), env(safe-area-inset-top)) + 172px); }
}

@media (max-height: 500px) {
  body.touch-enabled .hud-bottom-left { display: none; }
  body.touch-enabled .hud-bottom-right { top: calc(max(var(--edge), env(safe-area-inset-top)) + 58px); }
  body.touch-enabled .gauge-meter { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
