/* required styles */

.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
	position: absolute;
	left: 0;
	top: 0;
	}
.leaflet-container {
	overflow: hidden;
	}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
	-webkit-user-select: none;
	   -moz-user-select: none;
	        user-select: none;
	  -webkit-user-drag: none;
	}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
	background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
	image-rendering: -webkit-optimize-contrast;
	}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
	width: 1600px;
	height: 1600px;
	-webkit-transform-origin: 0 0;
	}
.leaflet-marker-icon,
.leaflet-marker-shadow {
	display: block;
	}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg {
	max-width: none !important;
	max-height: none !important;
	}
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
	max-width: none !important;
	max-height: none !important;
	width: auto;
	padding: 0;
	}

.leaflet-container img.leaflet-tile {
	/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
	mix-blend-mode: plus-lighter;
}

.leaflet-container.leaflet-touch-zoom {
	-ms-touch-action: pan-x pan-y;
	touch-action: pan-x pan-y;
	}
.leaflet-container.leaflet-touch-drag {
	-ms-touch-action: pinch-zoom;
	/* Fallback for FF which doesn't support pinch-zoom */
	touch-action: none;
	touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
	-ms-touch-action: none;
	touch-action: none;
}
.leaflet-container {
	-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
	-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
	filter: inherit;
	visibility: hidden;
	}
.leaflet-tile-loaded {
	visibility: inherit;
	}
.leaflet-zoom-box {
	width: 0;
	height: 0;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	z-index: 800;
	}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
	-moz-user-select: none;
	}

.leaflet-pane         { z-index: 400; }

.leaflet-tile-pane    { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane  { z-index: 500; }
.leaflet-marker-pane  { z-index: 600; }
.leaflet-tooltip-pane   { z-index: 650; }
.leaflet-popup-pane   { z-index: 700; }

.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg    { z-index: 200; }

.leaflet-vml-shape {
	width: 1px;
	height: 1px;
	}
.lvml {
	behavior: url(#default#VML);
	display: inline-block;
	position: absolute;
	}


/* control positioning */

.leaflet-control {
	position: relative;
	z-index: 800;
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}
.leaflet-top,
.leaflet-bottom {
	position: absolute;
	z-index: 1000;
	pointer-events: none;
	}
.leaflet-top {
	top: 0;
	}
.leaflet-right {
	right: 0;
	}
.leaflet-bottom {
	bottom: 0;
	}
.leaflet-left {
	left: 0;
	}
.leaflet-control {
	float: left;
	clear: both;
	}
.leaflet-right .leaflet-control {
	float: right;
	}
.leaflet-top .leaflet-control {
	margin-top: 10px;
	}
.leaflet-bottom .leaflet-control {
	margin-bottom: 10px;
	}
.leaflet-left .leaflet-control {
	margin-left: 10px;
	}
.leaflet-right .leaflet-control {
	margin-right: 10px;
	}


/* zoom and fade animations */

.leaflet-fade-anim .leaflet-popup {
	opacity: 0;
	-webkit-transition: opacity 0.2s linear;
	   -moz-transition: opacity 0.2s linear;
	        transition: opacity 0.2s linear;
	}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
	opacity: 1;
	}
.leaflet-zoom-animated {
	-webkit-transform-origin: 0 0;
	    -ms-transform-origin: 0 0;
	        transform-origin: 0 0;
	}
svg.leaflet-zoom-animated {
	will-change: transform;
}

.leaflet-zoom-anim .leaflet-zoom-animated {
	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
	}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
	-webkit-transition: none;
	   -moz-transition: none;
	        transition: none;
	}

.leaflet-zoom-anim .leaflet-zoom-hide {
	visibility: hidden;
	}


/* cursors */

.leaflet-interactive {
	cursor: pointer;
	}
.leaflet-grab {
	cursor: -webkit-grab;
	cursor:    -moz-grab;
	cursor:         grab;
	}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
	cursor: crosshair;
	}
.leaflet-popup-pane,
.leaflet-control {
	cursor: auto;
	}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
	cursor: move;
	cursor: -webkit-grabbing;
	cursor:    -moz-grabbing;
	cursor:         grabbing;
	}

/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
	pointer-events: none;
	}

.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}

/* visual tweaks */

.leaflet-container {
	background: #ddd;
	outline-offset: 1px;
	}
.leaflet-container a {
	color: #0078A8;
	}
.leaflet-zoom-box {
	border: 2px dotted #38f;
	background: rgba(255,255,255,0.5);
	}


/* general typography */
.leaflet-container {
	font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
	font-size: 12px;
	font-size: 0.75rem;
	line-height: 1.5;
	}


/* general toolbar styles */

.leaflet-bar {
	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
	border-radius: 4px;
	}
.leaflet-bar a {
	background-color: #fff;
	border-bottom: 1px solid #ccc;
	width: 26px;
	height: 26px;
	line-height: 26px;
	display: block;
	text-align: center;
	text-decoration: none;
	color: black;
	}
.leaflet-bar a,
.leaflet-control-layers-toggle {
	background-position: 50% 50%;
	background-repeat: no-repeat;
	display: block;
	}
.leaflet-bar a:hover,
.leaflet-bar a:focus {
	background-color: #f4f4f4;
	}
.leaflet-bar a:first-child {
	border-top-left-radius: 4px;
	border-top-right-radius: 4px;
	}
.leaflet-bar a:last-child {
	border-bottom-left-radius: 4px;
	border-bottom-right-radius: 4px;
	border-bottom: none;
	}
.leaflet-bar a.leaflet-disabled {
	cursor: default;
	background-color: #f4f4f4;
	color: #bbb;
	}

.leaflet-touch .leaflet-bar a {
	width: 30px;
	height: 30px;
	line-height: 30px;
	}
.leaflet-touch .leaflet-bar a:first-child {
	border-top-left-radius: 2px;
	border-top-right-radius: 2px;
	}
.leaflet-touch .leaflet-bar a:last-child {
	border-bottom-left-radius: 2px;
	border-bottom-right-radius: 2px;
	}

/* zoom control */

.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
	font: bold 18px 'Lucida Console', Monaco, monospace;
	text-indent: 1px;
	}

.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out  {
	font-size: 22px;
	}


/* layers control */

.leaflet-control-layers {
	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
	background: #fff;
	border-radius: 5px;
	}
.leaflet-control-layers-toggle {
	background-image: url(/assets/layers.416d91365b44e4b4f477.png);
	width: 36px;
	height: 36px;
	}
.leaflet-retina .leaflet-control-layers-toggle {
	background-image: url(/assets/layers-2x.8f2c4d11474275fbc161.png);
	background-size: 26px 26px;
	}
.leaflet-touch .leaflet-control-layers-toggle {
	width: 44px;
	height: 44px;
	}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
	display: none;
	}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
	display: block;
	position: relative;
	}
.leaflet-control-layers-expanded {
	padding: 6px 10px 6px 6px;
	color: #333;
	background: #fff;
	}
.leaflet-control-layers-scrollbar {
	overflow-y: scroll;
	overflow-x: hidden;
	padding-right: 5px;
	}
.leaflet-control-layers-selector {
	margin-top: 2px;
	position: relative;
	top: 1px;
	}
.leaflet-control-layers label {
	display: block;
	font-size: 13px;
	font-size: 1.08333em;
	}
.leaflet-control-layers-separator {
	height: 0;
	border-top: 1px solid #ddd;
	margin: 5px -10px 5px -6px;
	}

/* Default icon URLs */
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
	background-image: url(/assets/marker-icon.2b3e1faf89f94a483539.png);
	}


/* attribution and scale controls */

.leaflet-container .leaflet-control-attribution {
	background: #fff;
	background: rgba(255, 255, 255, 0.8);
	margin: 0;
	}
.leaflet-control-attribution,
.leaflet-control-scale-line {
	padding: 0 5px;
	color: #333;
	line-height: 1.4;
	}
.leaflet-control-attribution a {
	text-decoration: none;
	}
.leaflet-control-attribution a:hover,
.leaflet-control-attribution a:focus {
	text-decoration: underline;
	}
.leaflet-attribution-flag {
	display: inline !important;
	vertical-align: baseline !important;
	width: 1em;
	height: 0.6669em;
	}
.leaflet-left .leaflet-control-scale {
	margin-left: 5px;
	}
.leaflet-bottom .leaflet-control-scale {
	margin-bottom: 5px;
	}
.leaflet-control-scale-line {
	border: 2px solid #777;
	border-top: none;
	line-height: 1.1;
	padding: 2px 5px 1px;
	white-space: nowrap;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	background: rgba(255, 255, 255, 0.8);
	text-shadow: 1px 1px #fff;
	}
.leaflet-control-scale-line:not(:first-child) {
	border-top: 2px solid #777;
	border-bottom: none;
	margin-top: -2px;
	}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
	border-bottom: 2px solid #777;
	}

.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	box-shadow: none;
	}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	border: 2px solid rgba(0,0,0,0.2);
	background-clip: padding-box;
	}


/* popup */

.leaflet-popup {
	position: absolute;
	text-align: center;
	margin-bottom: 20px;
	}
.leaflet-popup-content-wrapper {
	padding: 1px;
	text-align: left;
	border-radius: 12px;
	}
.leaflet-popup-content {
	margin: 13px 24px 13px 20px;
	line-height: 1.3;
	font-size: 13px;
	font-size: 1.08333em;
	min-height: 1px;
	}
.leaflet-popup-content p {
	margin: 17px 0;
	margin: 1.3em 0;
	}
.leaflet-popup-tip-container {
	width: 40px;
	height: 20px;
	position: absolute;
	left: 50%;
	margin-top: -1px;
	margin-left: -20px;
	overflow: hidden;
	pointer-events: none;
	}
.leaflet-popup-tip {
	width: 17px;
	height: 17px;
	padding: 1px;

	margin: -10px auto 0;
	pointer-events: auto;

	-webkit-transform: rotate(45deg);
	   -moz-transform: rotate(45deg);
	    -ms-transform: rotate(45deg);
	        transform: rotate(45deg);
	}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
	background: white;
	color: #333;
	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
	}
.leaflet-container a.leaflet-popup-close-button {
	position: absolute;
	top: 0;
	right: 0;
	border: none;
	text-align: center;
	width: 24px;
	height: 24px;
	font: 16px/24px Tahoma, Verdana, sans-serif;
	color: #757575;
	text-decoration: none;
	background: transparent;
	}
.leaflet-container a.leaflet-popup-close-button:hover,
.leaflet-container a.leaflet-popup-close-button:focus {
	color: #585858;
	}
.leaflet-popup-scrolled {
	overflow: auto;
	}

.leaflet-oldie .leaflet-popup-content-wrapper {
	-ms-zoom: 1;
	}
.leaflet-oldie .leaflet-popup-tip {
	width: 24px;
	margin: 0 auto;

	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
	}

.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
	border: 1px solid #999;
	}


/* div icon */

.leaflet-div-icon {
	background: #fff;
	border: 1px solid #666;
	}


/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
	position: absolute;
	padding: 6px;
	background-color: #fff;
	border: 1px solid #fff;
	border-radius: 3px;
	color: #222;
	white-space: nowrap;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	pointer-events: none;
	box-shadow: 0 1px 3px rgba(0,0,0,0.4);
	}
.leaflet-tooltip.leaflet-interactive {
	cursor: pointer;
	pointer-events: auto;
	}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	position: absolute;
	pointer-events: none;
	border: 6px solid transparent;
	background: transparent;
	content: "";
	}

/* Directions */

.leaflet-tooltip-bottom {
	margin-top: 6px;
}
.leaflet-tooltip-top {
	margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
	left: 50%;
	margin-left: -6px;
	}
.leaflet-tooltip-top:before {
	bottom: 0;
	margin-bottom: -12px;
	border-top-color: #fff;
	}
.leaflet-tooltip-bottom:before {
	top: 0;
	margin-top: -12px;
	margin-left: -6px;
	border-bottom-color: #fff;
	}
.leaflet-tooltip-left {
	margin-left: -6px;
}
.leaflet-tooltip-right {
	margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	top: 50%;
	margin-top: -6px;
	}
.leaflet-tooltip-left:before {
	right: 0;
	margin-right: -12px;
	border-left-color: #fff;
	}
.leaflet-tooltip-right:before {
	left: 0;
	margin-left: -12px;
	border-right-color: #fff;
	}

/* Printing */

@media print {
	/* Prevent printers from removing background-images of controls. */
	.leaflet-control {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
		}
	}

/*
 * Colors follow digitaldoc-ui: its navy brand scale (src/config/brandColors.ts) as the
 * primary, on Mantine's default light/dark neutrals. Comments name the source shade.
 */
:root {
  --phone-width: 430px; /* the UI column; see .phone */
  --bg: #f1f3f5; /* gray-1, app background */
  --surface: #ffffff; /* body */
  --field: #ffffff; /* input background */
  --text: #000000; /* black */
  --muted: #868e96; /* gray-6, dimmed */
  --border: #ced4da; /* gray-4, default border */
  --accent: #002b7f; /* brand blue-6, primary */
  --banner: #002b7f; /* brand blue-6 */
  --route: #2449af; /* brand blue-5 */
  --route-casing: #001a51; /* brand blue-8 */
  --route-alt: #adb5bd; /* gray-5 */
  --report: #fd7e14; /* orange-6 */
  --danger: #fa5252; /* red-6 */
  --toast: #212529; /* gray-9 */
  --backdrop: rgb(0 0 0 / 0.35);
  --shadow: 0 1px 3px rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.05) 0 20px 25px -5px, rgb(0 0 0 / 0.04) 0 10px 10px -5px;
  --radius: 14px;
  color-scheme: light;
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

/*
 * <html data-theme> is always "light" or "dark": public/theme-init.js sets it before first paint from
 * the user's choice in the menu (light, dark, or following the system), and src/js/theme.js keeps it current.
 */
:root[data-theme='dark'] {
  --bg: #1f1f1f; /* dark-8 */
  --surface: #242424; /* dark-7, body */
  --field: #2e2e2e; /* dark-6 */
  --text: #c9c9c9; /* dark-0 */
  --muted: #828282; /* dark-2 */
  --border: #424242; /* dark-4 */
  --accent: #506ebf; /* brand blue-4, the dark-scheme primary shade */
  --route: #506ebf; /* brand blue-4 */
  --route-casing: #002268; /* brand blue-7 */
  --route-alt: #696969; /* dark-3 */
  --danger: #e03131; /* red-8 */
  --toast: #3b3b3b; /* dark-5 */
  --backdrop: rgb(0 0 0 / 0.55);
  --shadow: 0 1px 3px rgb(0 0 0 / 0.3), rgb(0 0 0 / 0.35) 0 10px 20px -5px;
  color-scheme: dark;
}

/* Night map: invert the OSM tiles and mute them towards Mantine's neutral dark grays. */
:root[data-theme='dark'] .leaflet-tile-pane {
  filter: invert(1) hue-rotate(180deg) brightness(0.85) contrast(0.9) saturate(0.3);
}

.leaflet-container {
  background: var(--bg);
}

* {
  box-sizing: border-box;
}

/* Hidden means hidden, whatever display a class gives the element. */
[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
  margin: 0;
}

body {
  height: 100dvh;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  -webkit-tap-highlight-color: transparent;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.muted {
  color: var(--muted);
}

.card {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* ---------- Layout and modes (body[data-mode] = browse | route | nav) ---------- */

/* The map fills the window; everything else lives in .phone, a phone-width column over its
   middle. On a phone that's the whole screen; on a desktop it looks like a phone in the middle
   of the screen with the map carrying on around it. The column itself lets touches through to
   the map; only its controls catch them. */
#map {
  position: fixed;
  inset: 0;
}

.phone {
  position: relative;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  width: min(100%, var(--phone-width));
  height: 100dvh;
  margin: 0 auto;
  pointer-events: none;
}

/* The part of the column above the bottom panel: the phone's window onto the map. */
.stage {
  position: relative;
  flex: 1;
  min-height: 0;
}

/* Everything at the bottom of the view, stacked differently per mode:
     browsing       buttons on the right, then the search bar
     route preview  the route card across the width (no buttons), then the search bar
     driving        speed on the left and buttons on the right, then the turn banner (no search)
   Hidden pieces take no space, so the stack fits whatever is showing. */
.dock {
  position: absolute;
  z-index: 1000;
  left: 12px;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    '. fabs'
    'search search';
  align-items: end;
  gap: 12px;
}

/* While choosing a route the card takes the full width and the locate/report buttons step aside;
   they come back once the trip starts (or the route is cancelled). */
[data-mode='route'] .dock {
  grid-template-areas:
    'card card'
    'search search';
}

[data-mode='route'] .fabs {
  display: none;
}

[data-mode='nav'] .dock {
  /* The panel below already keeps clear of the iPhone home bar. */
  bottom: 12px;
  grid-template-areas:
    'speed fabs'
    'banner banner';
}

/* Once a trip has started the search goes away; ending the trip brings it back. */
[data-mode='nav'] .search {
  display: none;
}

/* Alerts and toasts, just below the top row (map credit left, user button right: 52px + 12px),
   and left of the compass under the user button. */
.top {
  position: absolute;
  z-index: 1000;
  top: calc(max(12px, env(safe-area-inset-top)) + 64px);
  left: 12px;
  right: 76px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.top > *,
.user,
.dock > *,
.toast,
.sheet {
  pointer-events: auto;
}

/* Under the user button, centred on it: the needle points north however the map is turned; tapping
   switches between following the direction of travel and north up (see app.js). */
.compass {
  position: absolute;
  z-index: 1000;
  top: calc(max(12px, env(safe-area-inset-top)) + 64px);
  right: 18px;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow);
  color: var(--text);
  padding: 0;
  border: 0;
  pointer-events: auto;
}

.compass svg {
  width: 26px;
  height: 26px;
}

.compass-north {
  fill: var(--danger);
}

.compass text {
  fill: currentColor;
  font-size: 10px;
  font-weight: 700;
}

/* The user menu button, top right, in every mode. */
.user {
  position: absolute;
  z-index: 1001;
  top: max(12px, env(safe-area-inset-top));
  right: 12px;
}

.fab.user-fab {
  color: var(--accent);
}

/* Signed in: the user's initial on the brand color instead of the person. */
.fab.user-fab.signed-in {
  background: var(--accent);
  color: #fff;
}

.user-initial {
  display: none;
  font-size: 21px;
  font-weight: 700;
  line-height: 1;
}

.user-fab.signed-in svg {
  display: none;
}

.user-fab.signed-in .user-initial {
  display: block;
}

.banner,
.speed,
.sheet,
.route-card {
  display: none;
}

[data-mode='route'] .route-card,
[data-mode='nav'] .sheet {
  display: block;
}

[data-mode='nav'] .banner,
[data-mode='nav'] .speed {
  display: flex;
}

/* ---------- Search ---------- */

/* Docked at the bottom of the map while browsing and previewing a route, within thumb reach, like
   Waze. On Android the page shrinks above the on-screen keyboard (interactive-widget in the
   viewport meta), so it stays visible. */
.search {
  grid-area: search;
  position: relative;
  /* Above the rest of the dock, so its results list opens over it. */
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
}

.search-icon {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--muted);
}

/* Takes the magnifier's place while a search is running, so nothing shifts. */
.search-spinner {
  display: none;
  flex: none;
  width: 20px;
  height: 20px;
  border: 2.5px solid color-mix(in srgb, var(--accent) 20%, transparent);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.search.searching .search-icon {
  display: none;
}

.search.searching .search-spinner {
  display: block;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .search-spinner {
    animation-duration: 2s;
  }
}

.search input {
  flex: 1;
  min-width: 0;
  padding: 15px 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font-size: 17px;
}

/* Runs the search, like Enter: 6px from the bar's right edge, as from its top and bottom. */
.search-submit {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  margin-right: -8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  cursor: pointer;
}

.search-submit svg {
  width: 20px;
  height: 20px;
}

/* Searching as you type (js/search.js): no button needed. */
.search.as-you-type .search-submit {
  display: none;
}

/* Drops down from the user button. */
.menu {
  position: absolute;
  z-index: 1;
  top: calc(100% + 6px);
  right: 0;
  min-width: 200px;
  padding: 6px;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.menu-label {
  padding: 6px 10px 4px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.menu-label:not(:first-child) {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.menu [role='menuitemradio'] {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 10px;
  border: 0;
  border-radius: 10px;
  background: none;
  font-size: 16px;
  text-align: left;
}

.menu [role='menuitemradio']:hover,
.menu [role='menuitemradio']:focus-visible {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  outline: none;
}

.menu [aria-checked='true'] {
  color: var(--accent);
  font-weight: 600;
}

.menu [aria-checked='true']::after {
  content: '✓';
}

/* Who's signed in, above "Sign out". */
.menu-user {
  display: flex;
  flex-direction: column;
  padding: 6px 10px;
}

.menu-user b {
  font-size: 16px;
}

.menu-user small {
  font-size: 13px;
}

.menu-action {
  display: block;
  width: 100%;
  padding: 10px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--accent);
  font-size: 16px;
  font-weight: 600;
  text-align: left;
}

.menu-action:hover,
.menu-action:focus-visible {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  outline: none;
}

/* Opens upwards, out of the docked search bar. */
.results {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 50vh;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.results li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 10px;
  cursor: pointer;
}

.results li:hover,
.results li.active {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.results small {
  color: var(--muted);
}

.results li.results-empty {
  color: var(--muted);
  cursor: default;
  background: none;
}

/* ---------- Turn banner and hazard alert ---------- */

/* While driving, the next turn sits at the bottom of the view, under speed and the buttons. */
.banner {
  grid-area: banner;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  background: var(--banner);
  color: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.maneuver {
  flex: none;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  font-size: 38px;
  line-height: 1;
}

.maneuver svg {
  width: 48px;
  height: 48px;
  fill: currentColor;
}

.banner-body {
  min-width: 0;
}

.step-dist {
  font-size: 28px;
  font-weight: 700;
}

.step-text {
  font-size: 17px;
  opacity: 0.92;
}

/* "Reported ahead" while driving. */
.alert {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
}

.alert[hidden] {
  display: none;
}

.alert-icon {
  font-size: 30px;
}

.alert-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.vote-row {
  display: flex;
  gap: 8px;
}

.vote-row button {
  flex: 1;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
}

.vote-row button.chosen {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--surface));
}

.vote-row.compact button {
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0;
  font-size: 20px;
}

/* ---------- Floating controls ---------- */

.speed {
  grid-area: speed;
  justify-self: start;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.speed b {
  font-size: 24px;
  line-height: 1;
}

.speed small {
  font-size: 11px;
  color: var(--muted);
}

.fabs {
  grid-area: fabs;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.fab {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow);
}

.fab svg {
  width: 26px;
  height: 26px;
}

.fab.attention {
  color: #fff;
  background: var(--accent);
}

.fab-report {
  width: 62px;
  height: 62px;
  background: var(--report);
  color: #fff;
}

.fab-report svg {
  width: 30px;
  height: 30px;
}

/* Under the "reported ahead" alert when there is one (both sit in .top). */
.toast {
  align-self: center;
  max-width: 100%;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--toast);
  color: #fff;
  box-shadow: var(--shadow);
  font-size: 15px;
  text-align: center;
}

.toast[hidden] {
  display: none;
}

/* ---------- Route card and driving panel ---------- */

/* Route preview: destination, route options and Go, above the search bar and left of the
   locate and report buttons, so the search stays usable for a new destination. */
.route-card {
  grid-area: card;
  max-height: 45dvh;
  overflow-y: auto;
  padding: 12px;
}

.route-card .sheet-head {
  align-items: center;
  margin-bottom: 8px;
}

.route-card .dest b {
  font-size: 16px;
}

.route-card .dest small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-card .icon-btn {
  width: 34px;
  height: 34px;
  font-size: 15px;
}

.route-card .route-options {
  gap: 6px;
  margin-bottom: 10px;
}

.route-card .route-option {
  grid-template-columns: auto minmax(0, 1fr);
  padding: 8px 10px;
}

.route-card .route-time {
  font-size: 17px;
}

.route-card .route-meta {
  overflow: hidden;
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-card .primary {
  padding: 11px 14px;
  font-size: 16px;
}

/* Driving: ETA and controls at the bottom of the phone column, over the map (which carries on underneath). */
.sheet {
  position: relative;
  z-index: 1001;
  padding: 16px 16px calc(14px + env(safe-area-inset-bottom));
  border-radius: 18px 18px 0 0;
  background: var(--surface);
  box-shadow: 0 -4px 20px rgb(0 0 0 / 0.15);
}

.sheet-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 12px;
}

.dest {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.dest b {
  font-size: 18px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.icon-btn {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 8%, transparent);
  font-size: 18px;
}

.route-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
}

.route-option {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: 'time reports' 'meta meta';
  gap: 2px 12px;
  width: 100%;
  padding: 12px 14px;
  border: 2px solid var(--border);
  border-radius: 12px;
  background: transparent;
  text-align: left;
}

.route-option.selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.route-time {
  grid-area: time;
  font-size: 20px;
  font-weight: 700;
}

.route-reports {
  grid-area: reports;
  justify-self: end;
  align-self: center;
}

.route-meta {
  grid-area: meta;
  font-size: 14px;
}

.route-message {
  padding: 14px;
  color: var(--muted);
  text-align: center;
}

.primary,
.danger,
.ghost {
  padding: 14px 18px;
  border: 0;
  border-radius: 12px;
  font-size: 17px;
  font-weight: 600;
}

.primary {
  background: var(--accent);
  color: #fff;
}

.primary:disabled {
  opacity: 0.5;
  cursor: default;
}

.primary.small,
.ghost.small {
  padding: 8px 14px;
  font-size: 15px;
}

.link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font-size: inherit;
}

.link:disabled {
  color: var(--muted);
  cursor: default;
}

.danger {
  background: var(--danger);
  color: #fff;
}

.ghost {
  background: color-mix(in srgb, var(--text) 8%, transparent);
}

.wide {
  width: 100%;
}

.nav-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-bottom: 12px;
  text-align: center;
}

.nav-stats div {
  display: flex;
  flex-direction: column;
}

.nav-stats b {
  font-size: 22px;
}

.nav-stats small {
  color: var(--muted);
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nav-actions .ghost,
.nav-actions .danger {
  flex: 1;
}

/* ---------- Map markers and popups ---------- */

/* The map's panes turn inside .map-rotor (js/rotate.js). Markers and popups turn back by the same
   angle about the point they mark, so they stay upright; each sets that point as its origin. */
.map-rotor {
  position: absolute;
  top: 0;
  left: 0;
}

.leaflet-marker-icon > *,
.leaflet-popup-content-wrapper,
.leaflet-popup-tip-container {
  rotate: calc(-1 * var(--map-bearing, 0deg));
}

/* A popup points 13px below its box: Leaflet's 20px bottom margin minus its 7px offset. */
.leaflet-popup-content-wrapper {
  position: relative; /* for the close button, which rotate.js moves in here */
  transform-origin: 50% calc(100% + 13px);
}

.leaflet-popup-tip-container {
  transform-origin: 50% 14px; /* it starts 1px above the box's bottom */
}

.me-dot {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 3px solid #fff;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 1px 6px rgb(0 0 0 / 0.4);
}

.me-arrow {
  display: none;
  width: 16px;
  height: 16px;
  fill: #fff;
}

.me.has-heading .me-arrow {
  display: block;
}

/* Leaflet writes stroke colors as SVG attributes; these rules win and follow the theme. */
.route-line {
  stroke: var(--route);
}

.route-casing {
  stroke: var(--route-casing);
}

.route-alt {
  stroke: var(--route-alt);
}

.accuracy {
  stroke: var(--accent);
  fill: var(--accent);
}

/* The destination: drag it to adjust before the trip starts. */
.dest-pin {
  cursor: grab;
  font-size: 30px;
  line-height: 32px;
  text-align: center;
}

.dest-pin span {
  display: block;
  transform-origin: 16px 30px; /* the icon anchor */
}

.report-pin span,
.comment-pin span {
  transform-origin: 18px 42px; /* the icon anchor, below the tip */
  position: relative;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 3px solid var(--pin);
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.35);
  font-size: 18px;
}

/* Comments are speech bubbles, so they read differently from round road reports. */
.comment-pin span {
  --pin: var(--accent);
  border-radius: 12px;
}

.comment-pin b {
  position: absolute;
  top: -8px;
  right: -8px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  line-height: 18px;
  text-align: center;
}

.report-pin span::after,
.comment-pin span::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -9px;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top: 7px solid var(--pin);
  border-bottom: 0;
}

.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
  background: var(--surface);
  color: var(--text);
}

.leaflet-container {
  font: inherit;
}

/* The map credit OSM requires (small, but still legible), at the top left of the phone column:
   the same 12px from the edges as the user button on the right, and styled like it. */
.leaflet-top.leaflet-left {
  left: max(0px, calc((100% - var(--phone-width)) / 2));
}

.leaflet-container .leaflet-control-attribution {
  margin: max(12px, env(safe-area-inset-top)) 0 0 12px;
  padding: 4px 10px;
  border-radius: 12px;
  background: var(--surface);
  box-shadow: var(--shadow);
  color: var(--muted);
  font-size: 10px;
  line-height: 1.5;
}


.leaflet-control-attribution a {
  color: var(--accent);
}

.report-card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 17px;
}

.report-card-title span {
  font-size: 24px;
}

.report-card-meta {
  margin: 4px 0 10px;
}


/* ---------- Comment threads (inside map popups) ---------- */

.thread-body {
  max-height: 260px;
  overflow-y: auto;
}

.thread-body > p {
  margin: 0 0 8px;
}

.comment + .comment {
  margin-top: 10px;
}

.comment.reply {
  margin-left: 6px;
  padding-left: 10px;
  border-left: 2px solid var(--border);
}

.comment-text {
  margin: 0;
  font-size: 15px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.comment > .comment-text {
  font-size: 16px;
}

.comment.reply > .comment-text {
  font-size: 14px;
}

.comment-meta {
  margin-top: 2px;
  font-size: 12px;
}

.reply-form {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}

.reply-form input {
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--field);
  color: var(--text);
  font: inherit;
  font-size: 15px;
}

/* ---------- Dialogs ---------- */

.dialog {
  width: min(420px, calc(100% - 32px));
  padding: 0;
  border: 0;
  border-radius: 20px;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow);
}

.dialog::backdrop {
  background: var(--backdrop);
}

.dialog form {
  padding: 20px;
}

.dialog h2 {
  margin: 0 0 2px;
  font-size: 20px;
}

.dialog p {
  margin: 0 0 16px;
}

.dialog-actions {
  display: flex;
  gap: 10px;
}

.dialog-actions > button {
  flex: 1;
}

.dialog textarea {
  display: block;
  width: 100%;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--field);
  color: var(--text);
  font: inherit;
  font-size: 16px;
  resize: vertical;
}

.comment-form-meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 6px 0 14px;
}

.comment-form-meta small:last-child {
  flex: none;
}

.dialog .form-error {
  margin: -4px 0 12px;
  color: var(--danger);
}

.report-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 14px;
}

.report-type {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 6px;
  border: 2px solid color-mix(in srgb, var(--pin) 40%, transparent);
  border-radius: 14px;
  background: color-mix(in srgb, var(--pin) 10%, transparent);
}

.report-type span {
  font-size: 30px;
}

.report-type small {
  font-size: 13px;
  font-weight: 600;
}

/* ---------- Account dialog ---------- */

.icon-btn.small {
  width: 34px;
  height: 34px;
  font-size: 15px;
}

.account-dialog .sheet-head {
  margin-bottom: 16px;
}

.account-dialog .sheet-head p {
  margin: 4px 0 0;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
}

.field > span:first-child {
  color: var(--muted);
  font-size: 13px;
}

.field > input,
.field-box {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--field);
  color: var(--text);
}

/* 16px text, so phones don't zoom in on the field. */
.field input {
  min-width: 0;
  padding: 12px;
  font: inherit;
  font-size: 16px;
}

.field > input:focus-visible,
.field-box:focus-within {
  border-color: var(--accent);
  outline: none;
}

/* A password with Show/Hide beside it. */
.field-box {
  display: flex;
  align-items: center;
}

.field-box input {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  color: inherit;
}

.field-box .link {
  padding: 12px;
  font-size: 14px;
  font-weight: 600;
}

.field small {
  font-size: 12px;
}

/* Google's button renders in an iframe of its own height; reserve it so nothing jumps. */
.google-button {
  display: flex;
  justify-content: center;
  min-height: 44px;
}

.google-button:empty {
  display: none;
}

.google-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  font-size: 16px;
  font-weight: 600;
}

.google-fallback svg {
  width: 20px;
  height: 20px;
}

/* ──── or ──── */
.or {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 0;
  color: var(--muted);
  font-size: 13px;
}

.or::before,
.or::after {
  content: '';
  flex: 1;
  border-top: 1px solid var(--border);
}

.dialog #account-notice {
  margin: -4px 0 12px;
}

.account-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 8px;
}

.account-links .link {
  padding: 8px 10px;
  font-size: 15px;
}

