@import url('https://fonts.googleapis.com/css2?family=Onest:wght@400;500;600;700;800&family=IBM+Plex+Mono:wght@500;600&display=swap');
/* Pinch- and double-tap-zoom off, so the app behaves like an app rather than
   a web page. The viewport meta carries maximum-scale=1, user-scalable=no --
   but Safari IGNORES user-scalable in a normal tab (it is honoured only once
   the app is installed to the Home Screen) and neither setting stops
   double-tap zoom. touch-action: manipulation is the half that does: it keeps
   scrolling and panning, and drops the double-tap-to-zoom gesture.
   Nothing else belongs in this rule. viewport-fit=cover and
   -webkit-text-size-adjust were added here on 2026-09-13 and immediately
   broke the layout on the owner's phone: viewport-fit=cover pushes content
   under the notch and home indicator, and text-size-adjust changes how iOS
   sizes text. Neither has anything to do with zoom. Disable zoom only. */
html { touch-action: manipulation; }


/* Accessibility pass (2026-09-05): --primary-btn, --amber-btn (both themes)
   only ever paired with white 15px/700 text — measured under 4.5:1 (WCAG
   1.4.3), so each was darkened along its own hue just enough to clear it.
   --bad-btn stays as-is (it doubles as Decline/Reject/Delete TEXT color on
   var(--surface), where it already passes) — a new --bad-solid token below
   covers the one place that color is used as a solid white-text button fill
   ("Cancel trip anyway"), which needed a different, darker shade than the
   text role does. */
:root {
  --bg: #f7f2e8;
  --surface: #ffffff;
  --ink: #1e2420;
  --ink-soft: #6b6a5e;
  --line: #a18a52;
  --primary: #2b4a3a;
  --primary-soft: #dce7de;
  --primary-btn: #3d6350;
  --amber: #c1622d;
  --amber-soft: #f3e1cc;
  --amber-btn: #ba5c27;
  --bad: #c15b6b;
  --bad-soft: #f5e0e3;
  --bad-btn: #c67c89;
  --bad-solid: #b7596a;
  --ok: #2f7d5c;
  --ok-soft: #dcece5;
  --font-display: 'Onest', system-ui, sans-serif;
  --font-body: 'Onest', -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1c231f;
    --surface: #242c26;
    --ink: #f3eee2;
    --ink-soft: #a9a499;
    --line: #667767;
    --primary: #7fae93;
    --primary-soft: #24352c;
    --primary-btn: #448262;
    --amber: #dd9463;
    --amber-soft: #3a2a1e;
    --amber-btn: #ad6432;
    --bad: #d98b98;
    --bad-soft: #362328;
    --bad-btn: #e0a3ac;
    --bad-solid: #c44f61;
    --ok: #6fbd9b;
    --ok-soft: #17302a;
  }
}
:root[data-theme="dark"] {
  --bg: #1c231f;
  --surface: #242c26;
  --ink: #f3eee2;
  --ink-soft: #a9a499;
  --line: #667767;
  --primary: #7fae93;
  --primary-soft: #24352c;
  --primary-btn: #448262;
  --amber: #dd9463;
  --amber-soft: #3a2a1e;
  --amber-btn: #ad6432;
  --bad: #d98b98;
  --bad-soft: #362328;
  --bad-btn: #e0a3ac;
  --bad-solid: #c44f61;
  /* Missing from this explicit block (present in the @media dark block
     above) — a light-OS user who taps "Тъмен режим" got these two tokens
     falling all the way back to the light theme's mint green, colliding
     with every other dark-themed token around it (e.g. the "Confirmed"
     trip pill). Match the media-query block so both paths to dark mode
     agree. */
  --ok: #6fbd9b;
  --ok-soft: #17302a;
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; width: 390px; height: 844px;
  background: var(--bg); color: var(--ink); font-family: var(--font-body);
  overflow: hidden; -webkit-font-smoothing: antialiased;
}
a { color: var(--primary); text-decoration: none; }
a:hover { color: #0a5747; }

.screen { width: 390px; height: 844px; display: flex; flex-direction: column; position: relative; }
.content { flex: 1; overflow-y: auto; padding: 24px 20px 12px; }
.content::-webkit-scrollbar { display: none; }

.topbar { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px 8px; }
.topbar h1 { font-family: var(--font-display); font-size: 20px; font-weight: 700; margin: 0; }
.back { width: 44px; height: 44px; border-radius: 50%; background: var(--surface); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; }

.icon { width: 20px; height: 20px; }
.icon-btn { width: 44px; height: 44px; border-radius: 12px; background: var(--surface); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; }

h2.display { font-family: var(--font-display); font-size: 26px; font-weight: 700; margin: 0 0 6px; letter-spacing: -0.01em; }
p.sub { color: var(--ink-soft); font-size: 14px; margin: 0 0 20px; line-height: 1.5; }

.btn { display: flex; align-items: center; justify-content: center; gap: 8px; font-family: var(--font-body); font-weight: 700; font-size: 15px; border-radius: 14px; padding: 15px 20px; border: none; cursor: pointer; width: 100%; }
/* Same pass as .card above: the main call-to-action button had no shadow at
   all, so it never stood out from a flat card the way the most important
   control on a screen should. A soft colored glow (using the button's own
   color via color-mix, so it stays correct in both themes automatically)
   is the standard "this is the one to tap" premium cue. */
.btn-primary { background: var(--primary-btn); color: #fff; box-shadow: 0 6px 18px color-mix(in srgb, var(--primary-btn) 40%, transparent); }
.btn-secondary { background: var(--surface); color: var(--ink); border: 1.5px solid var(--line); }
.btn-amber { background: var(--amber-btn); color: #fff; }
/* First solid destructive button in the app -- every cancel/remove action
   before this one was a secondary button recolored with --bad-btn, never a
   filled button. Reuses the same --bad-btn/--bad-solid tokens already live
   for the other --bad-* buttons, just wired to a class instead of inline
   border/color overrides. */
.btn-bad { background: var(--bad-btn); color: #fff; }

/* Buttons are sometimes <a> tags (leave-a-request, no-matches popup, etc.),
   which put them in the path of the global `a:hover { color: #0a5747 }`
   rule above. That rule's (element + pseudo-class) specificity beats a
   plain `.btn-primary` class, so hovering a primary/amber button — or just
   having the cursor land on one after a layout shift, e.g. after picking a
   date closes the calendar and the search button slides up under the
   pointer — silently swapped its white label for near-illegible dark teal
   on the green/amber fill. Re-assert the intended color at matching
   specificity so hover never touches it.*/
a.btn-primary:hover, a.btn-primary:focus { color: #fff; }
a.btn-amber:hover, a.btn-amber:focus { color: #fff; }
a.btn-bad:hover, a.btn-bad:focus { color: #fff; }
a.btn-secondary:hover, a.btn-secondary:focus { color: var(--ink); }

/* Owner, 2026-09-16 ("make it look more premium," after watching a video on
   what makes apps feel premium): every .card sitewide was completely flat --
   a border and nothing else, no sense of it sitting above the page. One
   shared rule here gives every card (search card, trip cards, profile,
   notifications, messages, everything using .card) a soft ambient shadow --
   subtle enough to read as depth, not a heavy skeuomorphic drop-shadow. */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 16px; box-shadow: 0 3px 14px rgba(0,0,0,0.14); }

.pill { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 11px; font-weight: 600; padding: 4px 10px; border-radius: 20px; background: var(--primary-soft); color: var(--primary); }
.pill.amber { background: var(--amber-soft); color: var(--amber); }
.pill.ok  { background: var(--ok-soft); color: var(--ok); }
.pill.bad { background: var(--bad-soft); color: var(--bad); }

/* Tab bar sized like a native app's (owner, 2026-09-14: "too small, make it
   like Instagram"). Instagram's is ~49pt tall with ~26px glyphs; this lands in
   the same range while keeping the text labels this design uses. The icon size
   is set HERE rather than in each screen's markup: the <svg> tags carry
   width="20" height="20" attributes in all 60 files, and a CSS dimension
   overrides an SVG's presentation attribute, so one rule resizes every screen
   and nothing can drift out of step. */
.navbar { display: flex; border-top: 1px solid var(--line); background: var(--surface); padding: 13px 8px calc(13px + env(safe-area-inset-bottom, 10px)); }
.nav-item { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 5px; }
.nav-item span { font-size: 11.5px; font-weight: 600; color: var(--ink-soft); }
.nav-item.active span { color: var(--primary); }
.nav-item.active svg { stroke: var(--primary); }
.nav-item svg { stroke: var(--ink-soft); width: 26px; height: 26px; }

.avatar { width: 44px; height: 44px; border-radius: 50%; background: var(--primary-soft); display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 700; color: var(--primary); font-size: 15px; flex-shrink: 0; }

.stars { display: flex; align-items: center; gap: 3px; font-size: 12.5px; color: var(--ink-soft); font-weight: 600; }

.divider { height: 1px; background: var(--line); margin: 16px 0; }

.segment { display: flex; background: var(--bg); border-radius: 12px; padding: 4px; gap: 4px; }
.segment-item { flex: 1; text-align: center; padding: 9px 4px; border-radius: 9px; font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.segment-item.active { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(20,32,31,0.08); }

.op-badge { width: 38px; height: 38px; border-radius: 10px; background: var(--primary-soft); color: var(--primary); display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 700; font-size: 13px; flex-shrink: 0; }

.toggle-switch { width: 44px; height: 26px; border-radius: 20px; background: var(--line); position: relative; cursor: pointer; transition: background .2s; flex-shrink: 0; }
.toggle-switch .knob { width: 20px; height: 20px; border-radius: 50%; background: #fff; position: absolute; top: 3px; left: 3px; transition: left .2s; }
.toggle-switch[data-on="true"] { background: var(--primary); }
.toggle-switch[data-on="true"] .knob { left: 21px; }

a.card-link, a.row-link, a.tap { display: block; text-decoration: none; color: inherit; cursor: pointer; }
a.nav-item, a.back, a.icon-btn, a.segment-item { text-decoration: none; color: inherit; cursor: pointer; }
a.btn { text-decoration: none; box-sizing: border-box; }

.btn, .icon-btn, .back, a.card-link, a.row-link, a.tap, .nav-item, .segment-item, .dest-option, .city-dropdown > div, .lang-row, .toggle-switch, button {
  -webkit-tap-highlight-color: transparent;
  transition: transform .1s ease, opacity .1s ease, filter .1s ease;
}
.btn:active, .icon-btn:active, .back:active, a.card-link:active, a.row-link:active, a.tap:active,
.nav-item:active, .segment-item:active, .dest-option:active, .city-dropdown > div:active, .lang-row:active, button:active {
  transform: scale(0.96);
  opacity: 0.8;
}
.toggle-switch:active { transform: scale(0.94); }

/* Accessibility: a visible keyboard-focus ring on every interactive
   component in this list. Almost none of them are native <button>/<a>
   elements styled by the browser's default focus ring — most are <div>s
   with onclick — so without this, Tabbing through the app (WCAG 2.4.7)
   showed literally nothing: no way to tell which control has focus.
   :focus-visible only fires for keyboard focus, so mouse/touch users see
   no change. row-dots (the kebab menu) and toggle-switch (see the
   role="switch" enhancement in app.js) are included here too. */
.btn:focus-visible, .icon-btn:focus-visible, .back:focus-visible, a.card-link:focus-visible,
a.row-link:focus-visible, a.tap:focus-visible, .nav-item:focus-visible, .segment-item:focus-visible,
.dest-option:focus-visible, .city-dropdown > div:focus-visible, .lang-row:focus-visible,
.toggle-switch:focus-visible, .row-dots:focus-visible, button:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.btn-primary:active, .btn-amber:active, .btn-bad:active { filter: brightness(0.92); }

/* iOS Safari (and some Android browsers) zoom the whole page in the moment
   you focus a text field whose computed font-size is under 16px, then never
   zoom back out on their own — "when you press to enter something it zooms
   and doesn't return to normal screen". Every page here sets its own inline
   font-size on inputs (as low as 12-15px in places), so the only way to
   guarantee no field can ever trigger it — without hunting down and editing
   every inline style on every page — is one rule here, high specificity, that
   wins over inline styles. Doesn't affect layout: inputs size by padding and
   an explicit height, not by font-size. */
input:not(#cr-price), select, textarea {
  font-size: 16px !important;
}

input[type="date"] { color-scheme: light dark; }
input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 1;
  cursor: pointer;
  width: 21px;
  height: 21px;
  padding: 0;
  margin-left: 6px;
  background-size: 21px 21px;
  background-repeat: no-repeat;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237a8580' stroke-width='2'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E");
}

.time-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.time-cell { display: flex; align-items: center; justify-content: center; font-size: 12.5px; font-weight: 600; border-radius: 8px; padding: 10px 4px; cursor: pointer; color: var(--ink); background: var(--surface); border: 1px solid var(--line); text-align: center; }
.time-cell.selected { background: var(--primary); color: #fff; border-color: var(--primary); }

/* Language picker sheet (app.js openLanguageSheet) — replaces what used to be
   a dedicated full-screen "page" (15-select-language.html) that faked the
   screen behind it with a hardcoded copy of the home screen. Any real change
   to that background screen made the fake copy visibly stale (exactly what
   happened here), and picking a language always dropped you back on Home
   even if you opened the picker from Profile. A real row list, reusable
   wherever the picker opens from. */
.lang-row { display: flex; align-items: center; justify-content: space-between; padding: 13px 4px; text-decoration: none; color: inherit; border-bottom: 1px solid var(--line); }
.lang-row:last-child { border-bottom: none; }
.lang-row.active { color: var(--primary); font-weight: 700; }

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; font-size: 12.5px; font-weight: 600; border-radius: 8px; color: var(--ink); text-decoration: none; cursor: pointer; }
.cal-day.muted { color: var(--ink-soft); font-weight: 500; font-size: 10px; cursor: default; }
.cal-day.today { border: 1.5px solid var(--primary); }
.cal-day.selected { background: var(--primary); color: #fff; }
.cal-day.empty { visibility: hidden; cursor: default; }
.cal-day.past { color: var(--ink-soft); opacity: .35; cursor: default; pointer-events: none; }
.cal-nav-btn { width: 26px; height: 26px; border-radius: 8px; background: var(--surface); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; }

/* ---- Dark-mode input fixes (added 2026-09-03) ----
   Two separate bugs, both showing up as "the field goes white when you type".

   1. Chrome/Safari force their OWN background on an autofilled field
      (-webkit-autofill), overriding any background we set. In dark mode that
      lands as a white/pale-yellow box with dark text — unreadable. There is no
      way to set background-color on it; the documented workaround is an inset
      box-shadow large enough to cover the field, plus -webkit-text-fill-color
      for the text itself.
   2. A checkbox with only `accent-color` still paints its UNCHECKED box white
      in dark mode, because the box itself is the browser's default surface. */

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--surface) inset !important;
  box-shadow: 0 0 0 1000px var(--surface) inset !important;
  -webkit-text-fill-color: var(--ink) !important;
  caret-color: var(--ink);
  transition: background-color 9999s ease-in-out 0s;   /* stops the flash */
}

/* Inputs sitting inside a .card already show the card's surface; keep autofill
   matching that rather than punching a differently-coloured block into it. */
.card input:-webkit-autofill,
.card input:-webkit-autofill:hover,
.card input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--surface) inset !important;
  box-shadow: 0 0 0 1000px var(--surface) inset !important;
}

input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--line);
  border-radius: 5px;
  background: var(--bg);
  cursor: pointer;
  display: inline-grid;
  place-content: center;
  flex-shrink: 0;
}
input[type="checkbox"]:checked {
  background: var(--primary);
  border-color: var(--primary);
}
input[type="checkbox"]:checked::after {
  content: "";
  width: 10px;
  height: 6px;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(-45deg) translate(1px, -1px);
}
input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* ---- House banner carousel (2026-09-03) ----
   Horizontal swipe, not a vertical fade. Uses native CSS scroll-snap so a real
   finger swipe on a phone works with zero JS — the script only auto-advances
   and paints the dots. */
.hb-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;              /* Firefox */
  -ms-overflow-style: none;
  gap: 0;
  margin-bottom: 10px;
}
.hb-track::-webkit-scrollbar { display: none; }

.hb-slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;           /* one card per swipe, never skips two */
  box-sizing: border-box;
}

.hb-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  text-decoration: none;
  color: inherit;
}
.hb-icon {
  width: 40px; height: 40px;
  border-radius: 11px;
  background: var(--primary-soft);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.hb-tag {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft);
}
.hb-title { margin: 2px 0 0; font-family: var(--font-display); font-size: 14px; font-weight: 700; }
.hb-body  { margin: 2px 0 0; font-size: 12px; color: var(--ink-soft); line-height: 1.42; }


/* Uniform slides: every card the same height regardless of how long its body
   text is, so the track doesn't jump as you swipe. The body clamps to two
   lines and the rest lives behind "See more". */
.hb-card { align-items: flex-start; min-height: 104px; }
.hb-body {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hb-more {
  display: inline-block;
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--primary);
  cursor: pointer;
}

/* Full explanation, as a sheet that rises from the bottom — keeps the person
   on the screen they were on rather than navigating away to read a paragraph. */
.hb-sheet-wrap {
  position: absolute; inset: 0; z-index: 60;
  background: rgba(20, 32, 31, .45);
  display: flex; align-items: flex-end; justify-content: center;
  opacity: 0; pointer-events: none; transition: opacity .22s ease;
}
.hb-sheet-wrap[data-open="true"] { opacity: 1; pointer-events: auto; }
.hb-sheet {
  width: 100%; max-width: 390px;
  background: var(--surface);
  border-radius: 22px 22px 0 0;
  padding: 10px 22px calc(30px + env(safe-area-inset-bottom, 0px));
  transform: translateY(14px);
  transition: transform .22s ease;
  max-height: 82%;
  overflow-y: auto;
}
.hb-sheet-wrap[data-open="true"] .hb-sheet { transform: translateY(0); }
.hb-grip {
  width: 38px; height: 4px; border-radius: 2px;
  background: var(--line); margin: 0 auto 18px;
}
.hb-sheet h3 {
  font-family: var(--font-display); font-size: 20px; font-weight: 700;
  margin: 0 0 12px; line-height: 1.22;
}
.hb-sheet p { margin: 0 0 22px; font-size: 14.5px; line-height: 1.62; color: var(--ink-soft); }
@media (prefers-reduced-motion: reduce) {
  .hb-sheet-wrap, .hb-sheet { transition: none; }
}

/* ---- Carousel height fix (2026-09-03) ----
   Every slide was sizing to its own content, so a longer Bulgarian title made
   one card taller than the next and the whole track jumped as you swiped —
   text appeared to slide down the screen. Stretch the slides so every card
   takes the height of the tallest, and clamp the title so one long string
   can't blow that height out. */
.hb-track { align-items: stretch; }

.hb-slide { display: flex; }

.hb-card {
  flex: 1;
  min-height: 0;                 /* replaces the fixed 104px floor */
  align-items: flex-start;
  overflow: hidden;              /* nothing can spill past the rounded corner */
}

/* Text column must be allowed to shrink, or a long unbroken word pushes the
   card wider than the slide and the layout drifts sideways. */
.hb-card > div:last-child { min-width: 0; }

.hb-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}
.hb-body { overflow-wrap: anywhere; }

/* The "see more" is pinned to the bottom of the card so it sits on the same
   line across every slide, however long the text above it is. */
.hb-card > div:last-child { display: flex; flex-direction: column; height: 100%; }
.hb-more { margin-top: auto; padding-top: 6px; }

/* Sheet header: title left, close X top-right. One affordance instead of two
   stacked footer buttons — the sheet only has to be readable and dismissible. */
.hb-sheet-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 12px;
}
.hb-sheet-head h3 { margin: 0; flex: 1; min-width: 0; }
.hb-x {
  flex-shrink: 0;
  width: 32px; height: 32px;
  border-radius: 50%;
  border: none;
  background: var(--bg);
  color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
}
.hb-x:hover { color: var(--ink); }
.hb-x:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.hb-sheet p:last-child { margin-bottom: 6px; }

/* "No rides found" pop-up. The request option used to be a card at the BOTTOM
   of the results list, below the fold — owner: "it is down and it is hard to
   see". Centred and modal so it cannot be missed. A bottom sheet was the wrong
   fix here: it lands in the same place the person already wasn't looking. */
.nm-wrap {
  position: absolute; inset: 0; z-index: 70;
  background: rgba(20, 32, 31, .55);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.nm-wrap[data-open="true"] { opacity: 1; pointer-events: auto; }
.nm-card {
  width: 100%; max-width: 330px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 20px; padding: 24px 22px 20px; text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .32);
  transform: scale(.96); transition: transform .2s ease;
}
.nm-wrap[data-open="true"] .nm-card { transform: scale(1); }
.nm-card h3 {
  font-family: var(--font-display); font-size: 18px; font-weight: 700;
  margin: 0 0 18px; line-height: 1.28;
}
.nm-card p.nm-body { margin: 16px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink-soft); }
.nm-card p.nm-note { margin: 8px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--ink-soft); }
.nm-card .btn { margin: 0; }
.nm-dismiss {
  display: block; width: 100%; margin-top: 10px; padding: 11px;
  background: none; border: 0; font-family: inherit; font-size: 13.5px;
  font-weight: 600; color: var(--ink-soft); cursor: pointer;
}
.nm-dismiss:hover { color: var(--ink); }
.nm-dismiss:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 8px; }
@media (prefers-reduced-motion: reduce) { .nm-wrap, .nm-card { transition: none; } }

/* Native date/time inputs on the request-edit panel, dressed to match the
   app's other fields. Native is deliberate: it gives the phone's own picker,
   which beats anything hand-rolled here. */
.ro-field {
  width: 100%; box-sizing: border-box; height: 46px;
  background: var(--bg); border: none; border-radius: 10px; padding: 0 12px;
  font-family: inherit; font-size: 15px; font-weight: 600; color: var(--ink);
}
.ro-field:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* Row menu — the three dots on a trip card. Anchored to the card, not the
   viewport, so it opens where you tapped. */
.row-menu-wrap { position: relative; flex-shrink: 0; }
.row-dots {
  width: 44px; height: 44px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--ink-soft);
}
.row-dots:hover { background: var(--bg); color: var(--ink); }
.row-menu {
  position: absolute; top: 34px; right: 0; z-index: 40; min-width: 196px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 13px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .28); overflow: hidden;
}
.row-menu[hidden] { display: none; }
.row-menu button {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: 12px 14px; font-family: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--ink); cursor: pointer; border-bottom: 1px solid var(--line);
}
.row-menu button:last-child { border-bottom: 0; }
.row-menu button:hover { background: var(--bg); }
.row-menu button.danger { color: var(--bad); }

/* In-app confirm. window.confirm() draws a browser dialog at the top of the
   window — outside the phone frame entirely — and it blocks the page while
   open. This lives inside the screen, like everything else. */
.cf-wrap {
  position: absolute; inset: 0; z-index: 90;
  background: rgba(20, 32, 31, .55);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  opacity: 0; pointer-events: none; transition: opacity .18s ease;
}
.cf-wrap[data-open="true"] { opacity: 1; pointer-events: auto; }
.cf-card {
  width: 100%; max-width: 320px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 18px; padding: 22px 20px 16px;
  box-shadow: 0 22px 50px rgba(0, 0, 0, .34);
  transform: scale(.97); transition: transform .18s ease;
}
.cf-wrap[data-open="true"] .cf-card { transform: scale(1); }
.cf-card p { margin: 0 0 18px; font-size: 14px; line-height: 1.5; color: var(--ink); text-align: center; }
.cf-card .btn { margin: 0; }
.cf-no {
  display: block; width: 100%; margin-top: 8px; padding: 11px; background: none;
  border: 0; font-family: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--ink-soft); cursor: pointer;
}
.cf-no:hover { color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .cf-wrap, .cf-card { transition: none; } }


/* ---------------------------------------------------------------------------
   Popups (2026-09-22): first-booking congrats (P1), arrival safety check
   (P4) + driver/passenger rating (P2/P3), docked location-sharing bar (P5),
   and live toasts for accepted requests / new bookings / new messages
   (P6/P7/P8). Built on top of the existing .hb-sheet-wrap / .hb-sheet bottom
   sheet (already used for the feature-info sheet) rather than a new modal
   system -- generic #popup-sheet-wrap reuses those classes with fresh
   content per popup. See app.js's "Popups" section for the JS.
--------------------------------------------------------------------------- */

/* Rating stars as real 44x44 buttons (P2/P3), separate from 10-rate-trip.html's
   existing bare-SVG .rate-star, which keeps working unchanged. */
.rate-star-btn {
  border: none; background: transparent; padding: 4px;
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.rate-star-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 8px; }

/* Tag pills sized as a deliberate touch-target upsize over the shared .pill --
   a NEW variant class so this never changes any other pill on the site. */
.pill-tag {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 36px; padding: 0 14px; border-radius: 20px; border: none;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 600;
  background: var(--primary-soft); color: var(--primary);
  opacity: .5; cursor: pointer;
}
.pill-tag.on { opacity: 1; }
.pill-tag:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Popup sheet: driver/passenger avatar row, price line, etc. */
.popup-avatar-row { display: flex; align-items: center; gap: 12px; justify-content: center; flex-direction: column; margin-bottom: 4px; }
.popup-eyebrow { display: block; text-align: center; font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 1.3px; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 10px; }
.popup-title { margin: 0 0 6px; text-align: center; font-family: var(--font-display); font-size: 22px; font-weight: 700; letter-spacing: -.3px; line-height: 1.2; color: var(--ink); }
.popup-sub { margin: 0 0 14px; text-align: center; font-size: 14.5px; line-height: 1.5; color: var(--ink-soft); }
.popup-trip-card {
  box-sizing: border-box; background: var(--bg); border: 1px solid var(--line); border-radius: 16px;
  padding: 16px; display: flex; align-items: center; gap: 12px; margin-bottom: 4px;
}
.popup-trip-price { font-family: var(--font-mono); font-size: 15px; font-weight: 600; color: var(--ink); }
.popup-star-row { display: flex; justify-content: center; gap: 2px; margin-bottom: 4px; }
.popup-progress { display: flex; justify-content: center; gap: 6px; margin-bottom: 10px; }
.popup-progress span { width: 22px; height: 5px; border-radius: 3px; background: var(--line); }
.popup-progress span.done { background: var(--ok); }
.popup-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 4px 0 6px; }
.popup-safety-icon { width: 64px; height: 64px; border-radius: 50%; background: var(--primary-soft); display: flex; align-items: center; justify-content: center; margin: 0 auto 4px; }

/* ---- Live toasts (P6/P7/P8) ---- */
.live-toast {
  position: fixed; left: 12px; right: 12px; top: 70px; z-index: 9500;
  box-sizing: border-box; max-width: 390px; margin: 0 auto;
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  padding: 12px 34px 12px 14px; display: flex; align-items: center; gap: 12px;
  box-shadow: 0 14px 36px rgba(0,0,0,0.28);
  text-align: left; font-family: var(--font-body); cursor: pointer;
  opacity: 0; transform: translateY(-14px); transition: opacity .2s ease, transform .2s ease;
  min-height: 68px;
}
.live-toast.show { opacity: 1; transform: translateY(0); }
.live-toast-avatar {
  width: 44px; height: 44px; border-radius: 50%; background: var(--primary-soft); color: var(--primary);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  font-family: var(--font-display); font-weight: 700; font-size: 15px;
}
.live-toast-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.live-toast-title { font-size: 14.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-toast-sub { font-size: 13px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-toast-action { font-size: 14px; font-weight: 700; color: var(--primary); flex-shrink: 0; }
/* Dismiss reuses the .hb-x 32px circle pattern, pinned top-right so it never
   competes with the tap target the rest of the toast provides. */
.live-toast { position: fixed; }
.live-toast-dismiss.hb-x { position: absolute; top: 8px; right: 8px; width: 26px; height: 26px; }
@media (prefers-reduced-motion: reduce) { .live-toast { transition: none; } }

/* ---- Top-anchored booking success banner ---- */
/* Positioned absolute within .screen (not fixed to the viewport) so it stays
   confined to the phone mockup on desktop and spans the real device width on
   mobile, matching how the rest of this page's chrome is scoped. */
.booking-success-banner {
  position: absolute; left: 0; right: 0; z-index: 40;
  background: var(--ok); color: #fff;
  padding: 12px 20px; display: flex; align-items: center; gap: 10px;
  font-size: 13.5px; font-weight: 700; font-family: var(--font-body);
  opacity: 0; transform: translateY(-8px); pointer-events: none;
  transition: opacity .25s ease, transform .25s ease;
}
.booking-success-banner.show { opacity: 1; transform: translateY(0); }
.booking-success-banner svg { flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) { .booking-success-banner { transition: none; } }

/* ---- Docked location-sharing bar (P5) ----
   Plain document flow, prepended before everything else -- pushes the rest
   of the screen down by design while it's visible; when not inserted, the
   layout is byte-identical to before (no reserved space). */
.loc-bar {
  box-sizing: border-box; width: 100%; background: var(--ok-soft); border-bottom: 1px solid var(--line);
  padding: 10px 14px; display: flex; align-items: center; gap: 12px;
}
.loc-bar-dotwrap { position: relative; width: 30px; height: 30px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.loc-bar-ring { position: absolute; width: 30px; height: 30px; border-radius: 50%; background: color-mix(in srgb, var(--ok) 25%, transparent); }
.loc-bar-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--ok); border: 2px solid var(--ok-soft); }
.loc-bar-dot.pulse { animation: locBarPulse 1.6s ease-in-out infinite; }
@keyframes locBarPulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.8); } }
.loc-bar-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.loc-bar-title { font-size: 14px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loc-bar-sub { font-size: 12.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loc-bar-btn {
  min-height: 44px; border: none; border-radius: 14px; background: var(--primary-btn); padding: 0 14px;
  font-family: var(--font-body); font-size: 14px; font-weight: 700; color: #fff; cursor: pointer; flex-shrink: 0;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--primary-btn) 40%, transparent);
}

/* Publish locked until the cost-sharing box is ticked (06-post-trip-driver).
   A class, not `disabled`, so the tap still reaches publishTrip() and can
   explain why; inline busy-state styles there still win over it. */
.btn-primary.is-locked { opacity: .45; box-shadow: none; cursor: not-allowed; transition: opacity .15s; }
.card.has-error { border: 1.5px solid var(--bad); background: var(--bad-soft); }

/* Vehicle body-type cards: a long label ("Микроавтобус") must wrap inside its
   card instead of spilling over the neighbour at ~386px. Mirrored from website/style.css. */
[id$="body-type-grid"] > .card { min-width: 0; overflow-wrap: anywhere; }
[id$="body-type-grid"] > .card p { line-height: 1.2; }
@media (max-width: 480px) {
  [id$="body-type-grid"] { gap: 6px !important; }
  [id$="body-type-grid"] > .card { padding-left: 0 !important; padding-right: 0 !important; }
  [id$="body-type-grid"] > .card p { font-size: 9.5px !important; letter-spacing: -.02em; }
}
