/* ─────────────────────────────────────────────────────────────────────────────
   native.css — safe areas + native-shell chrome.

   SAFE AREAS
   Android 15 (API 35) made edge-to-edge mandatory and Android 16 removed the opt-out, so the
   WebView now always spans the full screen with the status and navigation bars floating OVER it.
   `Window.setStatusBarColor` / `StatusBar.setOverlaysWebView` are gone — the ONLY correct way to
   keep content clear of the system bars is to pad by the insets.

   Two sources give us those insets and neither covers everything:
     • `env(safe-area-inset-*)` — the standard. Reliable on iOS; on Android WebView it is either
       zero or stale on a long tail of versions.
     • `--safe-area-inset-*`    — real px values pushed onto <html> by Capacitor's own SystemBars
       plugin on every inset change (Capacitor ≥ 8.3). Native only; absent on the web.

   So every consumer reads ONE var that layers them, native value first — i.e. `--sai-top` means
   "the Capacitor-injected value, else env(), else 0px":

       padding-top: var(--sai-top);

   Use `--sai-*` everywhere instead of bare `env()` — on the web it IS `env()`, so nothing changes
   there, and on device it stops being a guess.
   ───────────────────────────────────────────────────────────────────────────── */

:root {
  --sai-top:    var(--safe-area-inset-top,    env(safe-area-inset-top,    0px));
  --sai-right:  var(--safe-area-inset-right,  env(safe-area-inset-right,  0px));
  --sai-bottom: var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
  --sai-left:   var(--safe-area-inset-left,   env(safe-area-inset-left,   0px));

  /* Live software-keyboard height, published by scripts/native/keyboard.js. 0 whenever the
     keyboard is down, and on the web (where the visual viewport handles it). A sheet that must
     stay above the keyboard reads this rather than guessing at a fixed offset. */
  --kb-height: 0px;
}

/* ── Status-bar scrim ─────────────────────────────────────────────────────────
   Under edge-to-edge the map/globe would run underneath the clock and battery icons. Before
   Android 15 we asked the OS for a solid bar coloured `--surface-app`; that API is dead, so we
   paint the same band ourselves. It is EXACTLY the old look: one app-surface strip the height of
   the top inset, with the app's own topbar continuing beneath it.

   Native only (`.is-native`), and only while the shell reports a non-zero top inset — a device
   with no cutout and a translucent bar gets nothing. `pointer-events: none` so a tap in the strip
   still reaches whatever is under it (the map pans normally right up to the screen edge). */
.is-native .native-statusbar-scrim {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--sai-top);
  background: var(--surface-app, #202020);
  /* Above every piece of app chrome, but BELOW the boot cover (99999) and the intro animation
     (100000) — those two are meant to own the whole screen, and a band across the top of them
     would be visible. So the ordering alone handles boot; no extra state class needed. */
  z-index: 99000;
  pointer-events: none;
}

/* ── Native shell feel ────────────────────────────────────────────────────────
   A WebView that behaves like a browser reads as a website. These are the differences a user
   actually notices, all scoped to `.is-native` so the web app is untouched. */
.is-native {
  /* No blue flash on tap — native controls don't do that. */
  -webkit-tap-highlight-color: transparent;
  /* No rubber-band past the app's own scrollers; sheets and the map own their overscroll. */
  overscroll-behavior: none;
}
.is-native body {
  /* Long-press should open OUR context UI (add-a-stop, action menu), never the OS text-selection
     magnifier / "Copy · Look Up" callout. Re-enabled per element below. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}
/* Anything the user is meant to read, select or type in opts back IN. */
.is-native input,
.is-native textarea,
.is-native [contenteditable],
.is-native .selectable {
  -webkit-touch-callout: default;
  -webkit-user-select: text;
  user-select: text;
}

/* iOS momentum scrolling inside the app's own panes. */
.is-native-ios .scroll-y,
.is-native-ios [data-scroll] { -webkit-overflow-scrolling: touch; }

/* ── Keyboard ─────────────────────────────────────────────────────────────────
   With the WebView in `resize: none` mode (which is what keeps the map from being squashed every
   time a search field is focused), the layout does NOT move when the keyboard opens — so anything
   that must stay visible lifts itself by --kb-height. */
.is-native.kb-open .lifts-for-keyboard { transform: translateY(calc(-1 * var(--kb-height))); }
.is-native.kb-open .pads-for-keyboard  { padding-bottom: max(var(--kb-height), var(--sai-bottom, 0px)); }

/* `max()`, not the sum this used to be — for the reason spelled out below, which the rule itself
   was contradicting. An open keyboard already covers the home-indicator strip, so adding the two
   left a visible gap above the keyboard. Nothing had ever used the class, so nothing showed it.

   A transition so the bar RIDES up with the keyboard instead of teleporting. The keyboard animates
   over ~250ms on both platforms; without this the bar arrives first and reads as a glitch. */
.is-native .lifts-for-keyboard { transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1); }
@media (prefers-reduced-motion: reduce) {
  .is-native .lifts-for-keyboard { transition: none; }
}

/* ── Keyboard-aware surfaces ──────────────────────────────────────────────────
   The keyboard runs `resize: 'none'` (capacitor.config.json + scripts/native/keyboard.js): the
   layout NEVER moves when the keyboard opens, because resizing the web view would resize the WebGL
   drawing buffer and visibly re-project the globe on every focus. The cost of that decision is
   that anything anchored to the bottom of the screen is simply COVERED, and must opt in here.

   `--kb-height` and `.kb-open` have existed since the keyboard module was written and nothing had
   ever consumed them, so on a device every one of these surfaces sat under the keyboard.

   Consumers now: onboarding and #confirm-modal below, plus `.mui-bb-wrap`, which takes
   `.lifts-for-keyboard` in mobile-ui/bottombar.js — its centre button is Save in the add-a-stop
   flow, so a covered bottom bar meant a note you could type and not save (webpage#16).

   `max()`, not a sum: an open keyboard already covers the home-indicator strip, so adding
   --kb-height to --sai-bottom would double-count and leave a visible gap above the keyboard.

   `.kb-open` is only ever set by the native keyboard module, so these are implicitly native-only —
   a browser reflows its own viewport and needs none of it. */

/* First-run gate. `.onb-stage` is justify-content:flex-end, so the form sits exactly where the
   keyboard lands: without this, a new user types their username under the keyboard and the
   continue button is beneath that. The worst possible screen to get wrong. */
html.kb-open .onb-content {
  padding-bottom: calc(40px + max(var(--kb-height), var(--sai-bottom, 0px)));
}

/* Add-a-stop sheet. Its save action is the bottom bar's centre button (see mobile-add-stop.css),
   so the sheet AND the bar have to clear the keyboard or the stop cannot be saved while typing
   a note — which is the one field people actually type into. */
html.kb-open #confirm-modal {
  padding-bottom: calc(var(--cm-bb-reserve, 100px) + max(var(--kb-height), var(--sai-bottom, 0px)));
}
/* NOT DONE: lifting the bottom bar itself. It holds the add-a-stop save action, so it needs to
   clear the keyboard too — but nothing I could apply to `.mui-bb-wrap` moved it reproducibly.
   `bottom` is inert on it even inline with !important (computed stays 0px) despite the element
   resolving to `position: fixed`; a translateY moved it once and then stopped moving it across
   later measurements, which says the shell re-renders the node underneath a test rather than that
   any particular declaration wins. That needs someone watching a real keyboard on a real device,
   not more guessing in a desktop browser. → webpage#16 */

/* Follows the keyboard rather than jumping ahead of it. Both platforms animate the keyboard in
   over roughly this long, and a bar that teleports reads as a glitch.
   The positioning rules above all out-specify their component stylesheets, so they win whatever
   the load order. These do NOT — `transition` is a shorthand that replaces, and #confirm-modal
   owns a slide animation in mobile-add-stop.css which loads after this file and must keep it. So
   the sheet's padding snaps while the bar and the onboarding form ease; that is the right way
   round, since the sheet's own slide is the motion the eye is following anyway. */
.onb-content { transition: padding-bottom 220ms ease; }
@media (prefers-reduced-motion: reduce) {
  .onb-content { transition: none; }
}
