/* JerryJerry app styles. Colors, sizes and timings come from design/tokens.css
 * (var(--jj-*) only, no hex values here). Mobile first: a bottom sheet for
 * planning; from 900 px wide the sheet becomes a side panel. */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; margin: 0; overflow: hidden; overscroll-behavior: none; }
body {
  background: var(--jj-bg);
  color: var(--jj-text);
  font: var(--jj-fw-regular) var(--jj-fs-body)/var(--jj-lh-body) var(--jj-font);
  -webkit-font-smoothing: antialiased;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}
button { font: inherit; color: inherit; border: 0; background: none; padding: 0; cursor: pointer; }
input { font: inherit; color: inherit; }
a { color: var(--jj-accent); text-decoration: none; }
[hidden] { display: none !important; }
svg { width: 24px; height: 24px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* Sprite icons set their own strokes; fill-only shapes (the arrive flag's
 * chequers) must not inherit the outline style above. */
svg.jj-icon { stroke: none; }
.num, .stat b, .man-dist, .speed b, .sum-time, .sum-meta { font-variant-numeric: var(--jj-num); }

#map { position: fixed; inset: 0; z-index: var(--jj-z-map); background: var(--jj-bg); }
.maplibregl-ctrl-bottom-right, .maplibregl-ctrl-bottom-left { z-index: var(--jj-z-map-ui); }
.maplibregl-ctrl-attrib { display: none; }

/* ---------- Surfaces ---------- */
.card {
  background: linear-gradient(180deg, var(--jj-glass-highlight), transparent 40%), var(--jj-surface-glass);
  -webkit-backdrop-filter: var(--jj-backdrop);
  backdrop-filter: var(--jj-backdrop);
  box-shadow: inset 0 0 0 1px var(--jj-glass-edge), var(--jj-shadow-2);
  border-radius: var(--jj-radius-lg);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--jj-space-2);
  min-height: var(--jj-hit-lg); padding: 0 var(--jj-space-5);
  border-radius: var(--jj-radius-pill);
  background: var(--jj-surface-2); color: var(--jj-text);
  font-size: var(--jj-fs-body-lg); font-weight: var(--jj-fw-bold); white-space: nowrap;
  transition: transform var(--jj-dur-instant) var(--jj-ease-standard), background var(--jj-dur-fast) var(--jj-ease-standard), opacity var(--jj-dur-fast);
}
.btn:active { transform: scale(0.97); }
.btn.primary { background: var(--jj-accent-strong); color: var(--jj-text-on-accent); box-shadow: var(--jj-shadow-1); }
.btn.primary:active { background: var(--jj-accent-press); }
.btn.danger { background: var(--jj-danger-strong); color: var(--jj-text-on-accent); }
.btn:disabled { opacity: 0.4; pointer-events: none; }
.btn svg { width: 22px; height: 22px; }
.btn.primary svg, .recenter svg { fill: currentColor; stroke: none; }

.icon-btn {
  display: grid; place-items: center; width: var(--jj-hit); height: var(--jj-hit);
  border-radius: var(--jj-radius-pill); color: var(--jj-text-2);
  transition: background var(--jj-dur-fast), color var(--jj-dur-fast);
}
.icon-btn:active { background: var(--jj-surface-3); }

.pill {
  display: inline-flex; align-items: center; gap: var(--jj-space-1);
  min-height: var(--jj-hit-min); padding: 0 var(--jj-space-3);
  border-radius: var(--jj-radius-pill); color: var(--jj-accent);
  font-size: var(--jj-fs-label); font-weight: var(--jj-fw-medium);
}
.pill svg { width: 18px; height: 18px; }
.pill:active { background: var(--jj-accent-soft); }

.fab {
  display: grid; place-items: center; width: var(--jj-hit-lg); height: var(--jj-hit-lg);
  border-radius: var(--jj-radius-pill); color: var(--jj-text);
  background: var(--jj-surface-glass-strong);
  -webkit-backdrop-filter: var(--jj-backdrop); backdrop-filter: var(--jj-backdrop);
  box-shadow: inset 0 0 0 1px var(--jj-glass-edge), var(--jj-shadow-2);
  transition: transform var(--jj-dur-instant) var(--jj-ease-standard);
}
.fab:active { transform: scale(0.94); }
.fab.on { color: var(--jj-accent); }

/* ---------- Planning sheet ---------- */
.sheet {
  position: fixed; z-index: var(--jj-z-sheet);
  left: 0; right: 0; bottom: 0;
  max-height: calc(100% - var(--jj-safe-top) - var(--jj-space-8));
  display: flex; flex-direction: column;
  padding: 0 var(--jj-space-4) calc(var(--jj-space-3) + var(--jj-safe-bottom));
  border-radius: var(--jj-radius-sheet) var(--jj-radius-sheet) 0 0;
  overflow-y: auto; overscroll-behavior: contain;
  transition: transform var(--jj-dur-slow) var(--jj-ease-decel);
}
.sheet.collapsed { transform: translateY(calc(100% - var(--jj-sheet-peek) - var(--jj-safe-bottom))); }
/* A scrolling flex column shrinks its children (the avoid chips went to 0 px
 * on short screens, SPEC §6.1). */
.sheet > * { flex-shrink: 0; }
.grip { flex: none; height: 22px; width: 100%; display: grid; place-items: center; cursor: grab; }
.grip::before { content: ""; width: 40px; height: 5px; border-radius: var(--jj-radius-pill); background: var(--jj-border); }

.sheet-head { display: flex; align-items: center; gap: var(--jj-space-1); margin-bottom: var(--jj-space-2); }
.brand { flex: 1; padding-left: var(--jj-space-1); }   /* mark + wordmark: design/brand/brand.css */

.stops { list-style: none; margin: 0; padding: 0; position: relative; }
/* Compact sheet (ROU-60 D5, app.js foldSheet): one "A → B +2" row instead of the stop editor. */
.trip-row {
  display: none; align-items: center; gap: var(--jj-space-2); width: 100%; min-height: var(--jj-hit-lg);
  margin: var(--jj-space-1) 0 var(--jj-space-2); padding: 0 var(--jj-space-2) 0 var(--jj-space-3);
  border-radius: var(--jj-radius-md); background: var(--jj-surface-2); text-align: left; font-weight: var(--jj-fw-medium);
}
.trip-row .name { min-width: 0; flex: 0 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trip-row .dot { flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--jj-stop-start); }
.trip-row .dot.end { background: var(--jj-stop-end); }
.trip-row .arrow { flex: none; color: var(--jj-text-3); }
.trip-row .more { flex: none; padding: 0 var(--jj-space-2); border-radius: var(--jj-radius-pill); background: var(--jj-surface-3); color: var(--jj-text-2); font-size: var(--jj-fs-label); }
.trip-row .jj-icon { flex: none; margin-left: auto; width: 20px; height: 20px; color: var(--jj-text-3); }
.sheet.compact > .trip-row { display: flex; }
.sheet.compact > :is(.sheet-head, .stops, .stop-actions, .avoid, .foot) { display: none; }
.stop {
  position: relative; display: flex; align-items: center; gap: var(--jj-space-2);
  min-height: var(--jj-hit-lg); margin-bottom: var(--jj-space-1);
  padding-left: var(--jj-space-1);
  border-radius: var(--jj-radius-md);
  background: var(--jj-surface-2);
  transition: transform var(--jj-dur-base) var(--jj-ease-spring), box-shadow var(--jj-dur-fast);
}
.stop.dragging { z-index: var(--jj-z-drag); transition: none; box-shadow: var(--jj-shadow-3); background: var(--jj-surface-3); }
.stop .dot {
  flex: none; display: grid; place-items: center; width: 24px; height: 24px; margin-left: var(--jj-space-2);
  border-radius: var(--jj-radius-pill); border: 3px solid var(--jj-stop-via); background: var(--jj-surface);
  font-size: 11px; font-weight: var(--jj-fw-heavy); color: var(--jj-text);
}
.stop.start .dot { border-color: var(--jj-stop-start); background: var(--jj-stop-start); }
.stop.end .dot { border-color: var(--jj-stop-end); background: var(--jj-stop-end); color: var(--jj-text-on-accent); }
.stop .field {
  flex: 1; min-width: 0; min-height: var(--jj-hit-lg); text-align: left;
  display: flex; flex-direction: column; justify-content: center; padding: var(--jj-space-1) 0;
}
.stop .name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: var(--jj-fw-medium); }
.stop .sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--jj-text-3); font-size: var(--jj-fs-caption); line-height: var(--jj-lh-caption); }
.stop .placeholder { color: var(--jj-text-3); font-weight: var(--jj-fw-regular); }
.stop .handle, .stop .remove { flex: none; display: grid; place-items: center; width: var(--jj-hit-min); height: var(--jj-hit-lg); color: var(--jj-text-3); }
.stop .handle { cursor: grab; touch-action: none; }
.stop .handle svg, .stop .remove svg { width: 20px; height: 20px; }
/* Planned charging / fuel stops (ROU-57): between the user's stops, not draggable. */
.stop.plan { background: transparent; box-shadow: inset 0 0 0 1px var(--jj-divider); }
.stop.plan .dot { border-color: var(--jj-success); background: var(--jj-success-soft); color: var(--jj-success); }
.stop.plan.fuel .dot { border-color: var(--jj-accent); background: var(--jj-accent-soft); color: var(--jj-accent); }
.stop.plan .dot .jj-icon { width: 14px; height: 14px; }
.stop.plan { min-height: var(--jj-hit-min); }
.stop.plan .field { min-height: var(--jj-hit-min); padding-right: var(--jj-space-3); }
.stop.plan .name { font-size: var(--jj-fs-label); }
.stop.plan .sub { color: var(--jj-text-2); }
.stops.reorder .stop.plan { display: none; }

/* Add stop, Reverse (icon only, so the row fits German) and the vehicle chip.
 * At 360 px in German the row is full; should it ever overflow, the chip
 * moves to its own line (right-aligned) instead of being cut. */
.stop-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--jj-space-1) 2px; margin: 0 0 var(--jj-space-2); }
.stop-actions .pill { flex: none; white-space: nowrap; }
.stop-actions > .pill:first-child { padding-left: var(--jj-space-1); }
.pill.icon { width: var(--jj-hit); justify-content: center; padding: 0; }
.pill.icon svg { width: 22px; height: 22px; }

/* Active vehicle (SPEC §10.2): right end of the stop actions, opens Settings.
 * The label never wraps or ellipsizes (§10.3). */
.vchip {
  margin-left: auto; height: 36px; padding: 0 var(--jj-space-2) 0 var(--jj-space-3); border-radius: var(--jj-radius-pill);
  display: inline-flex; align-items: center; gap: 5px; position: relative; flex: none;
  background: var(--jj-surface-2); color: var(--jj-text);
  font-size: var(--jj-fs-label); font-weight: var(--jj-fw-bold); white-space: nowrap;
}
.vchip::after { content: ""; position: absolute; inset: -4px 0; }
.vchip .jj-icon { width: 22px; height: 22px; color: var(--jj-accent); }
.vchip .jj-icon:last-child { width: 16px; height: 16px; color: var(--jj-text-3); margin-left: -2px; }
.vchip .soc { color: var(--jj-success); font-variant-numeric: var(--jj-num); }
.vchip .soc.warn { color: var(--jj-warning); }
.vchip .soc.low { color: var(--jj-danger); }
.vchip:active { transform: scale(0.97); }

/* A horizontal scroller (SPEC §6.1), edge to edge, so long German chip
 * labels never add a second row. */
.avoid {
  display: flex; align-items: center; gap: var(--jj-space-2); overflow-x: auto; scrollbar-width: none;
  margin: 0 calc(-1 * var(--jj-space-4)) var(--jj-space-3); padding: var(--jj-space-1) var(--jj-space-4);
}
.avoid::-webkit-scrollbar { display: none; }
/* A 32 px fade at the right edge: a clipped last chip reads as "more". */
.avoid { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent); }
.avoid > * { flex: none; }
.avoid-label { color: var(--jj-text-3); font-size: var(--jj-fs-label); text-transform: uppercase; letter-spacing: var(--jj-tracking-caps); margin-right: var(--jj-space-1); }
.chip {
  display: inline-flex; align-items: center; gap: var(--jj-space-1);
  min-height: 40px; padding: 0 var(--jj-space-3);
  border-radius: var(--jj-radius-pill);
  background: var(--jj-surface-2); color: var(--jj-text-2);
  box-shadow: inset 0 0 0 1px var(--jj-border);
  font-size: var(--jj-fs-label); font-weight: var(--jj-fw-medium);
  transition: background var(--jj-dur-fast), color var(--jj-dur-fast), box-shadow var(--jj-dur-fast), transform var(--jj-dur-base) var(--jj-ease-spring);
  position: relative;
}
.chip::after { content: ""; position: absolute; inset: -4px 0; } /* 48 px hit area */
.chip svg { width: 18px; height: 18px; }
.chip[aria-pressed="true"] { background: var(--jj-accent-soft); color: var(--jj-accent); box-shadow: inset 0 0 0 1.5px var(--jj-accent); }
.chip[aria-pressed="true"]:active, .chip:active { transform: scale(0.96); }

.summary { min-height: 0; }
.summary:not(:empty) { display: flex; align-items: center; gap: var(--jj-space-3); padding: var(--jj-space-2) 0 var(--jj-space-3); }
.sum-main { flex: 1; min-width: 0; }
.sum-time { font: var(--jj-fw-heavy) var(--jj-fs-headline)/var(--jj-lh-headline) var(--jj-font-display); letter-spacing: var(--jj-tracking-tight); color: var(--jj-success); }
.sum-meta { color: var(--jj-text-2); }
.sum-note { color: var(--jj-text-3); font-size: var(--jj-fs-caption); line-height: var(--jj-lh-caption); }
.sum-err { color: var(--jj-danger); }
.sum-warn { color: var(--jj-warning); font-weight: var(--jj-fw-medium); }
/* EV charge on arrival (SPEC §10.2): icon colour by level. */
.sum-soc { display: flex; align-items: center; gap: var(--jj-space-1); color: var(--jj-text-2); font-variant-numeric: var(--jj-num); white-space: nowrap; }
.sum-soc .jj-icon { width: 16px; height: 16px; color: var(--jj-success); }
.sum-soc.warn .jj-icon { color: var(--jj-warning); }
.sum-soc.low, .sum-soc.low .jj-icon { color: var(--jj-danger); }
.sum-soc.busy, .sum-soc.busy .jj-icon { color: var(--jj-text-3); }
.sum-soc.wrap { white-space: normal; align-items: baseline; }
.sum-soc.wrap .jj-icon { flex: none; align-self: center; }
.sum-plan { color: var(--jj-text-2); }
.sum-fuel { display: flex; align-items: baseline; gap: var(--jj-space-1); color: var(--jj-text-2); }
/* The icon stays on the first line when the text wraps; prices and the source never break (ROU-60 D10). */
.sum-fuel .jj-icon { flex: none; align-self: flex-start; margin-top: 2px; }
.sum-fuel .nw, .sum-plan .nw { white-space: nowrap; }
.sum-fuel small { color: var(--jj-text-3); font-size: var(--jj-fs-caption); white-space: nowrap; }
.sum-fuel a { color: inherit; }
.sum-fuel .jj-icon { flex: none; width: 16px; height: 16px; color: var(--jj-success); }
.sum-note a { color: inherit; }

/* Map markers: planned stops and fuel price pins. */
.mk-stop {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: var(--jj-radius-pill);
  background: var(--jj-success-strong); color: #fff; box-shadow: 0 0 0 3px var(--jj-surface), var(--jj-shadow-2);
}
.mk-stop.fuel { background: var(--jj-accent-strong); }
/* Stops over price pins (ROU-60 D4). */
.maplibregl-marker.mk-stop { z-index: 2; }
.mk-stop .jj-icon { width: 18px; height: 18px; }
.mk-fuel {
  padding: 2px 6px; border-radius: var(--jj-radius-sm); white-space: nowrap;
  background: var(--jj-surface); color: var(--jj-text); box-shadow: inset 0 0 0 1px var(--jj-divider), var(--jj-shadow-1);
  font-size: 12px; font-variant-numeric: var(--jj-num); cursor: default; margin-bottom: 6px;
}
.mk-fuel::after { content: ""; position: absolute; left: 50%; bottom: -5px; margin-left: -5px; border: 5px solid transparent; border-bottom: 0; border-top-color: var(--jj-surface); }
.mk-fuel b { font-weight: var(--jj-fw-bold); }
.mk-fuel sup { font-size: 9px; }
.mk-fuel.cheap { background: var(--jj-success-strong); color: #fff; z-index: 1; box-shadow: var(--jj-shadow-2); }
.mk-fuel.cheap::after { border-top-color: var(--jj-success-strong); }
.mk-fuel.closed { opacity: 0.55; text-decoration: line-through; }
/* A pin that would cover another pin, a stop, an incident or a camera (app.js placeFuel). */
.mk-fuel.nofit { visibility: hidden; pointer-events: none; }
body.mode-nav .mk-fuel { display: none; }
.spinner { width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--jj-accent-soft); border-top-color: var(--jj-accent); animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
/* Re-routing: the old summary stays, dimmed, with a small spinner. */
.sum-main { transition: opacity var(--jj-dur-fast); }
.summary.busy .sum-main { opacity: 0.5; }
.summary.busy .spinner { width: 18px; height: 18px; border-width: 2px; }

/* Sticky so Drive never scrolls away on a landscape phone. */
.go-row {
  position: sticky; bottom: 0; z-index: 1;
  display: flex; gap: var(--jj-space-2);
  margin: 0 calc(-1 * var(--jj-space-4)); padding: var(--jj-space-2) var(--jj-space-4);
  background: var(--jj-surface-glass-strong);
}
.go-row .btn { flex: 1; padding: 0 var(--jj-space-3); }
.go-row .btn.primary { flex: 1.4; }

.foot { margin: var(--jj-space-3) 0 0; color: var(--jj-text-3); font-size: 11px; line-height: var(--jj-lh-caption); text-align: center; }
.foot a { color: var(--jj-text-2); }

.fabs { position: fixed; z-index: var(--jj-z-fab); right: calc(var(--jj-edge) + var(--jj-safe-right)); top: calc(var(--jj-edge) + var(--jj-safe-top)); display: flex; flex-direction: column; gap: var(--jj-space-2); }

/* ---------- Search ---------- */
.search {
  position: fixed; inset: 0; z-index: var(--jj-z-dialog);
  display: flex; flex-direction: column;
  background: var(--jj-surface);
  padding: var(--jj-safe-top) var(--jj-safe-right) var(--jj-safe-bottom) var(--jj-safe-left);
  animation: rise var(--jj-dur-base) var(--jj-ease-decel);
}
@keyframes rise { from { opacity: 0; transform: translateY(16px); } }
@keyframes slidein { from { opacity: 0; transform: translateX(-16px); } }
.search-bar { display: flex; align-items: center; gap: var(--jj-space-1); padding: var(--jj-space-2) var(--jj-space-3); border-bottom: 1px solid var(--jj-divider); }
.search-bar input {
  flex: 1; min-width: 0; height: var(--jj-hit); padding: 0 var(--jj-space-4);
  border: 0; outline: 0; border-radius: var(--jj-radius-pill);
  background: var(--jj-surface-2); font-size: var(--jj-fs-body-lg);
  user-select: text; -webkit-user-select: text;
}
.search-bar input:focus { box-shadow: inset 0 0 0 2px var(--jj-focus); }
.results { list-style: none; margin: 0; padding: var(--jj-space-1) 0; overflow-y: auto; flex: 1; }
.results li > button {
  width: 100%; display: flex; align-items: center; gap: var(--jj-space-3);
  min-height: var(--jj-hit-lg); padding: var(--jj-space-2) var(--jj-space-4); text-align: left;
}
.results li > button:active, .results li > button.sel { background: var(--jj-surface-2); }
.results .ic { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--jj-radius-pill); background: var(--jj-surface-2); color: var(--jj-text-2); }
.results .ic svg { width: 20px; height: 20px; }
.results .t { min-width: 0; flex: 1; }
.results .t b { display: block; font-weight: var(--jj-fw-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.results .t small { display: block; color: var(--jj-text-3); font-size: var(--jj-fs-caption); line-height: var(--jj-lh-caption); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.results .t mark { background: none; color: var(--jj-accent); font-weight: var(--jj-fw-bold); }
.results .d { flex: none; color: var(--jj-text-3); font-size: var(--jj-fs-label); font-variant-numeric: var(--jj-num); }
.results .hint { padding: var(--jj-space-6) var(--jj-space-4); color: var(--jj-text-3); text-align: center; }

/* ---------- Settings (SPEC §6.6 / §10) ---------- */
.scrim { position: fixed; inset: 0; z-index: var(--jj-z-scrim); background: var(--jj-scrim); animation: fadein var(--jj-dur-base) var(--jj-ease-decel); }
.settings {
  position: fixed; z-index: var(--jj-z-dialog); left: 0; right: 0; bottom: 0; top: calc(var(--jj-safe-top) + 56px);
  display: flex; flex-direction: column;
  background: var(--jj-surface); border-radius: var(--jj-radius-sheet) var(--jj-radius-sheet) 0 0;
  box-shadow: var(--jj-shadow-3);
  animation: rise var(--jj-dur-slow) var(--jj-ease-decel);
  max-width: 640px; margin-inline: auto; /* centred on tablet portrait */
}
.dlg-head { flex: none; display: grid; grid-template-columns: 1fr auto; align-items: center; padding: 0 var(--jj-space-4) var(--jj-space-2); border-bottom: 1px solid var(--jj-divider); }
.dlg-head .grip { grid-column: 1 / -1; }
.dlg-head h2 { margin: 0 var(--jj-space-1); font: var(--jj-fw-heavy) var(--jj-fs-title)/var(--jj-lh-title) var(--jj-font-display); letter-spacing: var(--jj-tracking-tight); }
.dlg-head .fab { width: var(--jj-hit); height: var(--jj-hit); background: var(--jj-surface-2); box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.dlg-body {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 0 var(--jj-space-4) calc(var(--jj-space-6) + var(--jj-safe-bottom));
}
.section-label {
  margin: var(--jj-space-5) var(--jj-space-1) var(--jj-space-2);
  color: var(--jj-text-3); font-size: var(--jj-fs-caption); line-height: var(--jj-lh-caption); font-weight: var(--jj-fw-bold);
  text-transform: uppercase; letter-spacing: var(--jj-tracking-caps);
}
.note { margin: var(--jj-space-2) var(--jj-space-1) 0; color: var(--jj-text-3); font-size: var(--jj-fs-label); line-height: var(--jj-lh-label); }
/* German: row titles, hints and notes may wrap, hyphenated (SPEC §10.3). */
:lang(de) .item .grow, :lang(de) .note { hyphens: auto; }
.note.warn { color: var(--jj-warning); margin-bottom: var(--jj-space-2); }
.group { background: var(--jj-surface-2); border-radius: var(--jj-radius-lg); padding: 0 var(--jj-space-4); }
.item { width: 100%; display: flex; align-items: center; gap: var(--jj-space-3); min-height: 56px; padding: var(--jj-space-2) 0; text-align: left; }
.item + .item { border-top: 1px solid var(--jj-divider); }
.item > .jj-icon { width: 22px; height: 22px; color: var(--jj-text-2); }
.item .grow { flex: 1; min-width: 0; }
.item .s { font-size: var(--jj-fs-label); line-height: var(--jj-lh-label); color: var(--jj-text-2); }
.item.col { flex-direction: column; align-items: stretch; gap: var(--jj-space-2); padding: var(--jj-space-3) 0; }
.item .pill { margin-right: calc(-1 * var(--jj-space-2)); }
.item .line { display: flex; justify-content: space-between; align-items: baseline; }
.item output { font-variant-numeric: var(--jj-num); white-space: nowrap; color: var(--jj-text-2); }
.item output b { color: var(--jj-text); font-weight: var(--jj-fw-heavy); }
.item output.big { font-weight: var(--jj-fw-bold); }
.item output.big b { font: var(--jj-fw-heavy) var(--jj-fs-headline)/1 var(--jj-font-display); letter-spacing: var(--jj-tracking-tight); }
.item.danger-text { color: var(--jj-danger); font-weight: var(--jj-fw-medium); justify-content: center; }

/* Vehicle cards: 5 across on a phone, icon over label. */
/* Bleeds 8 px into the sheet padding so "Transporter" fits at 360 px. */
.vehicles { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin: 0 calc(-1 * var(--jj-space-2)); }
.vehicles button {
  min-width: 0; min-height: 76px; padding: var(--jj-space-2) 0; white-space: nowrap; letter-spacing: -0.1px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--jj-space-1);
  border-radius: var(--jj-radius-md); background: var(--jj-surface-2); color: var(--jj-text-2);
  font-size: var(--jj-fs-caption); line-height: var(--jj-lh-caption); font-weight: var(--jj-fw-medium);
  transition: background var(--jj-dur-fast), color var(--jj-dur-fast), box-shadow var(--jj-dur-fast);
}
.vehicles button .jj-icon { width: 30px; height: 30px; }
.vehicles button:active { transform: scale(0.96); }
.vehicles button[aria-checked="true"] { background: var(--jj-accent-soft); color: var(--jj-accent); box-shadow: inset 0 0 0 1.5px var(--jj-accent); font-weight: var(--jj-fw-bold); }
.group.ev { margin-top: var(--jj-space-2); animation: rise var(--jj-dur-base) var(--jj-ease-decel); }

.stepper { display: flex; align-items: center; gap: var(--jj-space-1); }
.stepper button { width: 40px; height: 40px; display: grid; place-items: center; border-radius: var(--jj-radius-pill); background: var(--jj-surface-3); color: var(--jj-text); position: relative; }
.stepper button::after { content: ""; position: absolute; inset: -2px; } /* 44 px hit */
.stepper button:disabled { opacity: 0.4; }
/* Number and text fields in Settings (tariff, operator prices). */
.item input.text {
  min-height: var(--jj-hit-min); padding: 0 var(--jj-space-2); border-radius: var(--jj-radius-md);
  background: var(--jj-surface-3); border: 0; min-width: 0;
}
.item input.text:focus { outline: none; box-shadow: inset 0 0 0 2px var(--jj-focus); }
.item input.price { width: 5.5em; flex: none; text-align: right; font-variant-numeric: var(--jj-num); }
.item .unit { color: var(--jj-text-2); font-size: var(--jj-fs-label); white-space: nowrap; }
.item.op-add { gap: var(--jj-space-2); }
.item.op-add .pill { margin-right: 0; }
.group.gap { margin-top: var(--jj-space-2); }
.stepper button .jj-icon { width: 20px; height: 20px; }
.stepper output { min-width: 68px; text-align: center; font-size: var(--jj-fs-label); }
.stepper output b { font-size: var(--jj-fs-body-lg); }

/* Range slider: the filled part is --v (set by app.js). */
.slider { -webkit-appearance: none; appearance: none; width: 100%; height: var(--jj-hit-min); margin: 0; background: transparent; min-width: 0; }
.slider::-webkit-slider-runnable-track { height: 6px; border-radius: var(--jj-radius-pill); background: linear-gradient(90deg, var(--jj-accent-strong) var(--v, 50%), var(--jj-surface-3) var(--v, 50%)); }
.slider::-moz-range-track { height: 6px; border-radius: var(--jj-radius-pill); background: var(--jj-surface-3); }
.slider::-moz-range-progress { height: 6px; border-radius: var(--jj-radius-pill); background: var(--jj-accent-strong); }
.slider::-webkit-slider-thumb { -webkit-appearance: none; width: 28px; height: 28px; margin-top: -11px; border-radius: 50%; background: var(--jj-text-on-accent); box-shadow: var(--jj-shadow-2), 0 0 0 1px var(--jj-border); }
.slider::-moz-range-thumb { width: 28px; height: 28px; border: 0; border-radius: 50%; background: var(--jj-text-on-accent); box-shadow: var(--jj-shadow-2); }
.slider:focus-visible { outline: 2px solid var(--jj-focus); outline-offset: 2px; border-radius: var(--jj-radius-sm); }

/* Segmented control (theme, language, units, voice). */
.segs { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 2px; padding: 3px; background: var(--jj-surface-3); border-radius: var(--jj-radius-md); }
.segs button {
  min-width: 0; min-height: 40px; padding: 0 var(--jj-space-2); border-radius: var(--jj-radius-sm);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-size: var(--jj-fs-label); font-weight: var(--jj-fw-medium); color: var(--jj-text-2);
}
.segs button span { white-space: nowrap; }
.segs button small { color: var(--jj-text-3); font-weight: var(--jj-fw-regular); margin-left: 2px; }
.segs button .jj-icon { width: 18px; height: 18px; }
.segs button[aria-checked="true"] { background: var(--jj-surface); color: var(--jj-text); box-shadow: var(--jj-shadow-1); font-weight: var(--jj-fw-bold); }
.item.col .segs { margin-bottom: var(--jj-space-1); }

.switch { width: 52px; height: 32px; border-radius: var(--jj-radius-pill); background: var(--jj-surface-3); position: relative; flex: none; box-shadow: inset 0 0 0 1px var(--jj-border); transition: background var(--jj-dur-fast) var(--jj-ease-standard); }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 50%; background: var(--jj-text-on-accent); box-shadow: var(--jj-shadow-1); transition: transform var(--jj-dur-fast) var(--jj-ease-standard); }
.switch[aria-checked="true"] { background: var(--jj-accent-strong); box-shadow: none; }
.switch[aria-checked="true"]::after { transform: translateX(20px); }
.settings :focus-visible { outline: 2px solid var(--jj-focus); outline-offset: 2px; }

/* ---------- Navigation ---------- */
.nav { position: fixed; inset: 0; z-index: var(--jj-z-banner); pointer-events: none; }
.nav > * { pointer-events: auto; }
/* Banner with the "Then" strip hanging below it. */
.nav > .banner-wrap {
  position: absolute; left: calc(var(--jj-edge) + var(--jj-safe-left)); right: calc(var(--jj-edge) + var(--jj-safe-right));
  top: calc(var(--jj-edge) + var(--jj-safe-top));
  display: flex; flex-direction: column; align-items: flex-start;
  pointer-events: none;
}
.banner-wrap > * { pointer-events: auto; }
.banner {
  align-self: stretch;
  display: flex; align-items: center; gap: var(--jj-space-3);
  min-height: 96px; padding: var(--jj-space-3) var(--jj-space-4);
  background: var(--jj-banner); color: var(--jj-banner-text);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: var(--jj-shadow-3);
}
.banner.arrive { background: var(--jj-success-strong); }
.man-icon { flex: none; width: 64px; height: 64px; display: grid; place-items: center; }
.man-icon svg { width: 64px; height: 64px; stroke-width: 2.4; }
.man-text { min-width: 0; flex: 1; }
.man-dist { font: var(--jj-fw-heavy) var(--jj-fs-display)/var(--jj-lh-display) var(--jj-font-display); letter-spacing: var(--jj-tracking-tight); }
.man-dist.text { font-size: var(--jj-fs-headline); line-height: var(--jj-lh-headline); }
.man-dist small { font-size: var(--jj-fs-title); font-weight: var(--jj-fw-bold); margin-left: var(--jj-space-1); }
.man-road { font: var(--jj-fw-bold) var(--jj-fs-title)/var(--jj-lh-title) var(--jj-font); color: var(--jj-banner-text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.banner .swap { animation: fadein var(--jj-dur-base) var(--jj-ease-decel); }
@keyframes fadein { from { opacity: 0; transform: translateY(-4px); } }
/* "Then [icon] street" (SPEC §6.3), never wider than the banner. */
.then {
  margin-left: var(--jj-space-4); max-width: calc(100% - 2 * var(--jj-space-4)); min-width: 0;
  display: flex; align-items: center; gap: var(--jj-space-2);
  padding: var(--jj-space-1) var(--jj-space-3); border-radius: 0 0 var(--jj-radius-md) var(--jj-radius-md);
  background: var(--jj-banner-2); color: var(--jj-banner-text-2); box-shadow: var(--jj-shadow-1);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  font-size: var(--jj-fs-label); font-weight: var(--jj-fw-bold);
}
.then > span { flex: none; }
.then-icon { display: grid; }
.then-icon svg { width: 20px; height: 20px; }
.then > .then-road { flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--jj-banner-text); }
.banner.dim { opacity: 0.6; }
.toast { display: flex; align-items: center; gap: var(--jj-space-2); }
.toast .jj-icon { width: 20px; height: 20px; color: var(--jj-accent); }
.toast.spin .jj-icon { animation: spin 0.9s linear infinite; }
.toast.warn .jj-icon { color: var(--jj-warning); }
.toast b { color: var(--jj-success); }
/* "New route · +1 min" is a loss: amber, not green; the same time is plain (ROU-60 D10). */
.toast.loss b { color: var(--jj-warning); }
.toast.same b { color: inherit; }
@media (prefers-reduced-motion: reduce) { .toast.spin .jj-icon { animation-duration: 2.4s; } }
/* In demo, toasts stack below the demo pill (SPEC §6.8). */
.nav:has(#demo-ctl:not([hidden])) .toast { top: calc(var(--jj-safe-top) + var(--jj-edge) + 204px); }
.arrived .flag .jj-icon { width: 34px; height: 34px; }

.speed {
  position: absolute; left: calc(var(--jj-edge) + var(--jj-safe-left)); bottom: calc(var(--jj-safe-bottom) + 112px);
  width: 72px; height: 72px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--jj-surface-glass-strong); -webkit-backdrop-filter: var(--jj-backdrop); backdrop-filter: var(--jj-backdrop);
  box-shadow: inset 0 0 0 1px var(--jj-glass-edge), var(--jj-shadow-2);
}
.speed b { font: var(--jj-fw-heavy) var(--jj-fs-headline)/1 var(--jj-font-display); letter-spacing: var(--jj-tracking-tight); }
.speed small { font-size: 11px; line-height: 14px; color: var(--jj-text-2); }

.nav-fabs { position: absolute; right: calc(var(--jj-edge) + var(--jj-safe-right)); bottom: calc(var(--jj-safe-bottom) + 112px); display: flex; flex-direction: column; gap: var(--jj-space-2); }
.recenter {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(var(--jj-safe-bottom) + 112px);
  display: flex; align-items: center; gap: var(--jj-space-2);
  min-height: var(--jj-hit); padding: 0 var(--jj-space-5); border-radius: var(--jj-radius-pill);
  color: var(--jj-accent); font-weight: var(--jj-fw-bold);
}
.recenter svg { width: 20px; height: 20px; }
/* Centred with margins, not a transform, so the fade-in can move it. */
.toast {
  position: absolute; left: 0; right: 0; margin: 0 auto; width: max-content; top: calc(var(--jj-safe-top) + 140px);
  z-index: var(--jj-z-toast); max-width: calc(100% - 2 * var(--jj-edge));
  padding: var(--jj-space-2) var(--jj-space-4); border-radius: var(--jj-radius-pill);
  font-weight: var(--jj-fw-medium); white-space: nowrap;
  animation: fadein var(--jj-dur-base) var(--jj-ease-decel);
}
.demo-ctl {
  position: absolute; right: calc(var(--jj-edge) + var(--jj-safe-right)); top: calc(var(--jj-safe-top) + var(--jj-edge) + 144px);
  display: flex; align-items: center; gap: var(--jj-space-1); padding: var(--jj-space-1); border-radius: var(--jj-radius-pill);
  font-size: var(--jj-fs-label); color: var(--jj-text-2);
}
.demo-ctl > span { padding: 0 var(--jj-space-2); text-transform: uppercase; letter-spacing: var(--jj-tracking-caps); font-size: var(--jj-fs-caption); }
.seg { min-width: 40px; height: 36px; padding: 0 var(--jj-space-2); border-radius: var(--jj-radius-pill); font-weight: var(--jj-fw-bold); position: relative; }
.seg::after { content: ""; position: absolute; inset: -6px 0; }
.seg.on { background: var(--jj-accent-strong); color: var(--jj-text-on-accent); }

.navbar {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: var(--jj-space-2);
  padding: var(--jj-space-3) calc(var(--jj-space-4) + var(--jj-safe-right)) calc(var(--jj-space-3) + var(--jj-safe-bottom)) calc(var(--jj-space-4) + var(--jj-safe-left));
  border-radius: var(--jj-radius-sheet) var(--jj-radius-sheet) 0 0;
  background: var(--jj-surface-glass-strong);
}
.stat { flex: 1; display: flex; flex-direction: column; align-items: center; min-width: 0; }
.stat b { white-space: nowrap; font: var(--jj-fw-heavy) var(--jj-fs-headline)/var(--jj-lh-headline) var(--jj-font-display); letter-spacing: var(--jj-tracking-tight); }
.stat:first-child b { color: var(--jj-success); }
.stat b .ampm { margin-left: 0.2em; font-size: 0.55em; letter-spacing: 0; }
.stat small { color: var(--jj-text-3); font-size: var(--jj-fs-caption); line-height: var(--jj-lh-caption); text-transform: uppercase; letter-spacing: var(--jj-tracking-caps); white-space: nowrap; }
.navbar .btn { min-height: var(--jj-hit); padding: 0 var(--jj-space-5); }

.arrived {
  position: absolute; left: 0; right: 0; margin: 0 auto; bottom: calc(var(--jj-safe-bottom) + var(--jj-space-4));
  z-index: var(--jj-z-dialog); width: min(420px, calc(100% - 2 * var(--jj-edge)));
  padding: var(--jj-space-6); text-align: center;
  background: var(--jj-surface); animation: rise var(--jj-dur-slow) var(--jj-ease-decel);
}
.arrived .flag { width: 56px; height: 56px; margin: 0 auto var(--jj-space-3); border-radius: 50%; display: grid; place-items: center; background: var(--jj-success-strong); color: var(--jj-text-on-accent); }
.arrived h2 { margin: 0; font: var(--jj-fw-heavy) var(--jj-fs-title)/var(--jj-lh-title) var(--jj-font-display); }
.arrived p { margin: var(--jj-space-1) 0 0; color: var(--jj-text-2); }
.arrived .trip { margin-bottom: var(--jj-space-4); color: var(--jj-text-3); font-size: var(--jj-fs-label); font-variant-numeric: var(--jj-num); }
.arrived .btn { width: 100%; }
/* Arrival (SPEC §6.5): the card replaces the banner and the bottom bar. */
.nav.done :is(.banner, .then, .navbar, .speed, .nav-fabs) {
  opacity: 0; pointer-events: none;
  transition: opacity var(--jj-dur-slow) var(--jj-ease-accel);
}

/* ---------- Live features (ROU-56) ---------- */
/* Signpost under the street: road numbers as chips, destinations, exit number. */
.man-sign { display: flex; align-items: center; gap: var(--jj-space-1) var(--jj-space-2); flex-wrap: wrap; margin-top: var(--jj-space-1); font-size: var(--jj-fs-label); line-height: var(--jj-lh-label); font-weight: var(--jj-fw-bold); color: var(--jj-banner-text); min-width: 0; }
.man-sign .ref { padding: 0 var(--jj-space-1); border-radius: var(--jj-radius-xs); background: var(--jj-banner-text); color: var(--jj-banner); white-space: nowrap; }
.man-sign .exit { padding: 0 var(--jj-space-1); border-radius: var(--jj-radius-xs); box-shadow: inset 0 0 0 1.5px var(--jj-banner-text); white-space: nowrap; }
.man-sign .dest { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--jj-banner-text-2); }
/* Lane strip under the banner: one box per lane, recommended lanes bright. */
.lanes {
  align-self: stretch; display: flex; justify-content: center; gap: var(--jj-space-1);
  margin: 0 var(--jj-space-4); padding: var(--jj-space-1) var(--jj-space-3);
  border-radius: 0 0 var(--jj-radius-md) var(--jj-radius-md);
  background: var(--jj-banner-2); color: var(--jj-banner-text); box-shadow: var(--jj-shadow-1);
}
.lane { position: relative; width: 34px; height: 38px; display: grid; place-items: center; border-radius: var(--jj-radius-xs); opacity: 0.38; }
.lane + .lane::before { content: ""; position: absolute; left: -3px; top: 6px; bottom: 6px; border-left: 2px dashed currentColor; opacity: 0.5; }
.lane.on { opacity: 1; background: rgba(255, 255, 255, 0.16); }
.lane svg { grid-area: 1 / 1; width: 30px; height: 30px; stroke-width: 2.6; }
.lane svg + svg { opacity: 0.55; }
.then { margin-top: 0; }
/* Hazard / camera card under the banner. */
.alert {
  align-self: stretch; margin-top: var(--jj-space-2);
  display: flex; align-items: center; gap: var(--jj-space-3);
  padding: var(--jj-space-2) var(--jj-space-3); border-radius: var(--jj-radius-md);
  background: var(--jj-surface-glass-strong); box-shadow: inset 0 0 0 1px var(--jj-glass-edge), var(--jj-shadow-2);
  animation: fadein var(--jj-dur-base) var(--jj-ease-decel);
}
.alert-ico { flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; background: var(--jj-severe); color: var(--jj-severe-ink); font: var(--jj-fw-heavy) 22px/1 var(--jj-font-display); }
.alert-ico .jj-icon { width: 24px; height: 24px; }
.alert.warn .alert-ico { background: var(--jj-hazard); color: var(--jj-hazard-ink); }
/* SPEC §11.2: wrong-way driver / closure is the one solid red card; its text wraps, never ellipsized. */
.alert.severe { background: var(--jj-severe); color: var(--jj-severe-ink); box-shadow: var(--jj-shadow-2); }
.alert.severe .alert-ico { background: var(--jj-severe-ink); color: var(--jj-severe); }
.alert.severe .alert-text b, .alert.severe .alert-text span { white-space: normal; color: inherit; }
.alert.cam .alert-ico { background: #FFFFFF; color: #0E1420; box-shadow: inset 0 0 0 4px #D12F2F; font-size: 15px; }
.alert-text { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.alert-text b { font-size: var(--jj-fs-body-lg); line-height: var(--jj-lh-body-lg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.alert-text span { color: var(--jj-text-2); font-size: var(--jj-fs-label); line-height: var(--jj-lh-label); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.alert-dist { flex: none; font: var(--jj-fw-heavy) var(--jj-fs-title)/1 var(--jj-font-display); font-variant-numeric: var(--jj-num); }
/* "Faster route found" offer. */
.offer {
  align-self: stretch; margin-top: var(--jj-space-2);
  display: flex; align-items: center; gap: var(--jj-space-2); flex-wrap: wrap;
  padding: var(--jj-space-3); border-radius: var(--jj-radius-md);
  background: var(--jj-surface); box-shadow: inset 0 0 0 1px var(--jj-glass-edge), var(--jj-shadow-3);
  animation: fadein var(--jj-dur-base) var(--jj-ease-decel);
}
.offer-text { flex: 1 1 100%; min-width: 0; display: flex; flex-direction: column; }
.offer-text span { color: var(--jj-success); font-weight: var(--jj-fw-bold); }
.offer .btn { flex: 1; min-height: var(--jj-hit); padding: 0 var(--jj-space-4); }
/* SPEC §11.5: the 10 s countdown on "Switch", a lighter fill growing left to right. */
.offer #offer-take { position: relative; overflow: hidden; isolation: isolate; }
.offer.counting #offer-take::before {
  content: ''; position: absolute; inset: 0; z-index: -1; background: rgba(255, 255, 255, 0.24);
  transform-origin: left; animation: offer-count var(--offer-ms, 10s) linear forwards;
}
@keyframes offer-count { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) { .offer.counting #offer-take::before { animation: none; transform: scaleX(1); opacity: 0.5; } }
/* German speed-limit sign above the speedometer. */
.limit {
  position: absolute; left: calc(var(--jj-edge) + var(--jj-safe-left) + 4px); bottom: calc(var(--jj-safe-bottom) + 112px + 80px);
  width: 64px; height: 64px; border-radius: 50%; display: grid; place-items: center;
  background: #FFFFFF; color: #0E1420; box-shadow: inset 0 0 0 7px #D12F2F, var(--jj-shadow-2);
  font: var(--jj-fw-heavy) 26px/1 var(--jj-font-display); letter-spacing: var(--jj-tracking-tight); font-variant-numeric: var(--jj-num);
}
.limit.small { font-size: 18px; }
/* "End of all limits": white disc, black ring, grey diagonal stripes. */
.limit.none { box-shadow: inset 0 0 0 2px #0E1420, var(--jj-shadow-2); background: repeating-linear-gradient(135deg, #FFFFFF 0 7px, #6B7280 7px 9px); color: transparent; }
.limit.walk { font-size: 11px; font-weight: var(--jj-fw-bold); text-align: center; }
.limit.over { animation: limit-pulse 1s var(--jj-ease-standard) infinite alternate; }
@keyframes limit-pulse { to { transform: scale(1.1); } }
.speed.over { background: var(--jj-danger-strong); color: #FFFFFF; }
.speed.over small { color: rgba(255, 255, 255, 0.85); }
.navbar .delay { color: var(--jj-warning); font-size: var(--jj-fs-caption); line-height: var(--jj-lh-caption); font-weight: var(--jj-fw-bold); white-space: nowrap; }
.nav.done :is(.limit, .lanes, .alert, .offer) { opacity: 0; pointer-events: none; transition: opacity var(--jj-dur-slow) var(--jj-ease-accel); }
@media (prefers-reduced-motion: reduce) { .limit.over { animation: none; } }
/* Planning summary: traffic delay and incidents on the route. */
.sum-traffic { display: flex; align-items: center; gap: var(--jj-space-1); color: var(--jj-warning); font-weight: var(--jj-fw-bold); }
.sum-traffic .jj-icon { width: 18px; height: 18px; flex: none; }
.sum-traffic.danger { color: var(--jj-danger); }
.sum-traffic.ok { color: var(--jj-success); font-weight: var(--jj-fw-medium); }
/* Bottom bar: arrival time by the size of the delay (SPEC §11.1). */
#eta.warn { color: var(--jj-warning); }
#eta.danger { color: var(--jj-danger); }
/* Incident card: over the map at the top (planning) or above the bottom bar (driving). */
.inc-pop {
  position: fixed; z-index: var(--jj-z-toast); left: calc(var(--jj-edge) + var(--jj-safe-left)); right: calc(var(--jj-edge) + var(--jj-safe-right));
  top: calc(var(--jj-safe-top) + var(--jj-edge)); max-height: 45vh; overflow: auto;
  padding: var(--jj-space-3) var(--jj-space-4); border-radius: var(--jj-radius-lg);
  background: var(--jj-surface); box-shadow: inset 0 0 0 1px var(--jj-glass-edge), var(--jj-shadow-3);
  font-size: var(--jj-fs-label); line-height: var(--jj-lh-label);
  animation: fadein var(--jj-dur-base) var(--jj-ease-decel);
}
.inc-pop .icon-btn { position: absolute; top: var(--jj-space-1); right: var(--jj-space-1); }
body.mode-nav .inc-pop { top: auto; bottom: calc(var(--jj-safe-bottom) + 112px); }
.inc-badge { float: left; width: 48px; height: 48px; margin: 0 var(--jj-space-3) var(--jj-space-1) 0; border-radius: 50%; display: grid; place-items: center; background: var(--jj-hazard); color: var(--jj-hazard-ink); }
.inc-badge.severe { background: var(--jj-severe); color: var(--jj-severe-ink); }
.inc-badge .jj-icon { width: 28px; height: 28px; }
.inc-card h3 { margin: 0 40px var(--jj-space-1) 0; font: var(--jj-fw-bold) var(--jj-fs-body-lg)/var(--jj-lh-body-lg) var(--jj-font); }
.inc-card .meta { color: var(--jj-text-2); }
.inc-card p { margin: var(--jj-space-1) 0 0; white-space: pre-line; color: var(--jj-text-2); }
/* ROU-60 D6: at most 4 lines, ending in "…"; a tap shows the rest. */
.inc-card .inc-text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; line-clamp: 4; overflow: hidden; cursor: pointer; }
.inc-card .inc-text.open { display: block; -webkit-line-clamp: unset; line-clamp: none; }
.inc-card .src { color: var(--jj-text-3); font-size: var(--jj-fs-caption); }
.settings .note.legal { color: var(--jj-warning); }
/* Desktop first, then landscape phones (a 932 px wide phone matches both). */
@media (min-width: 900px), (orientation: landscape) and (max-height: 540px) {
  .inc-pop { left: calc(var(--jj-safe-left) + 2 * var(--jj-edge) + var(--jj-col)); right: auto; width: min(380px, calc(100% - var(--jj-col) - 4 * var(--jj-edge))); }
  body.mode-nav .inc-pop { top: calc(var(--jj-safe-top) + var(--jj-edge)); bottom: auto; }
}
@media (min-width: 900px) {
  .limit { bottom: calc(var(--jj-edge) + var(--jj-space-4) + 80px); }
}
@media (orientation: landscape) and (max-height: 540px) {
  .limit { left: auto; right: calc(var(--jj-edge) + var(--jj-safe-right) + 4px); bottom: calc(var(--jj-safe-bottom) + var(--jj-edge) + 80px); width: 56px; height: 56px; font-size: 22px; }
  .lane { width: 28px; height: 30px; }
  .lane svg { width: 24px; height: 24px; }
}

/* Modes */
body.mode-nav .sheet, body.mode-nav .plan-only { display: none; }
/* The scale bar would sit under the nav FABs. */
body.mode-nav .maplibregl-ctrl-scale { display: none; }

/* Reduced motion (SPEC §7): fades only, nothing slides. */
@media (prefers-reduced-motion: reduce) {
  @keyframes rise { from { opacity: 0; } }
  @keyframes fadein { from { opacity: 0; } }
  @keyframes slidein { from { opacity: 0; } }
}

/* ---------- Map markers ---------- */
.puck { width: 64px; height: 64px; pointer-events: none; }
.puck svg { width: 64px; height: 64px; stroke: none; }
.puck.dot .jj-puck-cone { display: none; }
.stop-pin { width: 30px; height: 30px; cursor: grab; }

/* ---------- Desktop and landscape phones: left column (SPEC §6 Layouts) ----------
 * app.js wide() uses the same query. */
:root { --jj-col: min(var(--jj-panel-w), 46vw); }
@media (min-width: 900px), (orientation: landscape) and (max-height: 540px) {
  .sheet {
    left: calc(var(--jj-edge) + var(--jj-safe-left)); right: auto; top: calc(var(--jj-safe-top) + var(--jj-edge)); bottom: auto;
    width: var(--jj-col); max-height: calc(100% - var(--jj-safe-top) - var(--jj-safe-bottom) - 2 * var(--jj-edge));
    border-radius: var(--jj-radius-lg); padding-bottom: var(--jj-space-4);
  }
  .sheet.collapsed { transform: none; }
  .grip { display: none; }
  .sheet-head { margin-top: var(--jj-space-3); }
  .search {
    inset: calc(var(--jj-safe-top) + var(--jj-edge)) auto auto calc(var(--jj-edge) + var(--jj-safe-left));
    width: var(--jj-col); max-height: calc(100% - var(--jj-safe-top) - var(--jj-safe-bottom) - 2 * var(--jj-edge));
    padding: 0; border-radius: var(--jj-radius-lg); box-shadow: var(--jj-shadow-3);
  }
  /* Settings: a full-height side panel over the planner; no scrim, so the
   * map stays live and shows re-routes (SPEC §10.1). */
  .scrim { display: none; }
  .settings {
    left: calc(var(--jj-edge) + var(--jj-safe-left)); right: auto;
    top: calc(var(--jj-safe-top) + var(--jj-edge)); bottom: calc(var(--jj-safe-bottom) + var(--jj-edge));
    width: var(--jj-col); border-radius: var(--jj-radius-lg);
    animation-name: slidein;
  }
  .settings .dlg-head { padding-top: var(--jj-space-3); }
  .settings .dlg-head .grip { display: none; }
  .settings .dlg-body { padding-bottom: var(--jj-space-4); }
  .nav > .banner-wrap { right: auto; width: var(--jj-col); }
  .arrived { left: calc(var(--jj-edge) + var(--jj-safe-left)); right: auto; margin: 0; width: var(--jj-col); bottom: calc(var(--jj-safe-bottom) + var(--jj-edge)); }
}
@media (min-width: 900px) {
  .navbar { left: 50%; right: auto; transform: translateX(-50%); width: 560px; bottom: var(--jj-edge); border-radius: var(--jj-radius-lg); padding-bottom: var(--jj-space-3); }
  .speed { bottom: calc(var(--jj-edge) + var(--jj-space-4)); }
  .demo-ctl { top: calc(var(--jj-edge) + 112px); }
  .nav-fabs { bottom: calc(var(--jj-edge) + var(--jj-space-4)); }
  .recenter { bottom: calc(var(--jj-edge) + 100px); }
  .toast { top: calc(var(--jj-edge) + 40px); }
}
/* Tablets in portrait: banner, hazard and offer cards stay card-sized, left-aligned as on desktop. */
@media (min-width: 600px) and (max-width: 899px) and (orientation: portrait) {
  .nav > .banner-wrap { right: auto; width: min(560px, calc(100% - 2 * var(--jj-edge) - var(--jj-safe-left) - var(--jj-safe-right))); }
}
/* Landscape phones: everything in or beside the column, a slimmer banner.
 * After the desktop block, which a 932 px wide phone also matches. */
@media (orientation: landscape) and (max-height: 540px) {
  /* ROU-60 D1: the column is too short for banner, lanes, "Then", hazard and
   * offer above the trip bar. While the offer shows it takes their place, so
   * Keep / Switch stay reachable (no offer comes within 300 m of a turn). */
  .banner-wrap:has(#offer:not([hidden])) > :is(.lanes, .then, .alert) { display: none; }
  /* The sheet scrolls here: the trip time sticks right above Drive, and both
   * are opaque so the stops don't show through them. */
  .sheet > .stop-actions, .sheet > .avoid { order: 1; }
  .sheet { padding-bottom: 0; }
  .sheet > .summary:not(:empty) {
    order: 2; position: sticky; z-index: 1; bottom: calc(var(--jj-hit-lg) + var(--jj-space-2) + var(--jj-space-4));
    margin: 0 calc(-1 * var(--jj-space-4)); padding: var(--jj-space-2) var(--jj-space-4) 0;
    background: var(--jj-surface);
  }
  .sheet > .go-row { order: 2; padding-bottom: var(--jj-space-4); background: var(--jj-surface); }
  .sheet > .foot { order: 3; margin-bottom: var(--jj-space-3); }
  .banner { min-height: 0; padding: var(--jj-space-2) var(--jj-space-3); }
  .man-icon, .man-icon svg { width: 48px; height: 48px; }
  .man-dist { font-size: var(--jj-fs-headline); line-height: var(--jj-lh-headline); }
  .man-dist small { font-size: var(--jj-fs-body-lg); }
  .man-dist.text { font-size: var(--jj-fs-title); line-height: var(--jj-lh-title); }
  .man-road { font-size: var(--jj-fs-body-lg); line-height: var(--jj-lh-body-lg); }
  .navbar {
    left: calc(var(--jj-edge) + var(--jj-safe-left)); right: auto; transform: none; width: var(--jj-col);
    bottom: calc(var(--jj-safe-bottom) + var(--jj-edge)); border-radius: var(--jj-radius-lg);
    padding: var(--jj-space-2) var(--jj-space-3);
  }
  .stat b { font-size: var(--jj-fs-title); line-height: var(--jj-lh-title); }
  .speed { left: auto; right: calc(var(--jj-edge) + var(--jj-safe-right)); bottom: calc(var(--jj-safe-bottom) + var(--jj-edge)); }
  .nav-fabs { bottom: auto; top: calc(var(--jj-safe-top) + var(--jj-edge)); }
  /* The demo pill in the column right above the trip bar: the FAB stack on the
   * right ends with the Report button (ROU-77 R4). */
  .demo-ctl {
    top: auto; right: auto; left: calc(var(--jj-edge) + var(--jj-safe-left)); bottom: calc(var(--jj-safe-bottom) + var(--jj-edge) + 84px);
    max-width: var(--jj-col); flex-wrap: wrap;
  }
  /* Centred in the map right of the column. */
  .recenter {
    left: calc(var(--jj-safe-left) + var(--jj-edge) + var(--jj-col) + (100% - var(--jj-safe-left) - var(--jj-edge) - var(--jj-col)) / 2);
    bottom: calc(var(--jj-safe-bottom) + var(--jj-edge));
  }
  /* Toasts sit in the column under the banner, clear of the demo pill. */
  .nav .toast, .nav:has(#demo-ctl:not([hidden])) .toast {
    top: calc(var(--jj-safe-top) + var(--jj-edge) + 108px);
    left: calc(var(--jj-edge) + var(--jj-safe-left)); right: calc(100% - var(--jj-edge) - var(--jj-safe-left) - var(--jj-col));
    max-width: var(--jj-col);
  }
  .arrived { padding: var(--jj-space-4); }
  .arrived .flag { width: 48px; height: 48px; margin-bottom: var(--jj-space-2); }
}
@media (hover: hover) {
  .icon-btn:hover, .pill:hover { background: var(--jj-surface-3); }
  .chip:hover { color: var(--jj-text); }
  .results li > button:hover { background: var(--jj-surface-2); }
  .stop .remove:hover { color: var(--jj-danger); }
}
