/* ============================================================
   MSGO — design tokens
   --route/--route-dark/--route-tint follow the real logo's palette
   (internalized 24.08.2026 — see frontend/assets/brand/SOURCE.txt):
   cobalt-ultramarine, a deliberate reference to Samarkand's majolica
   domes (Registan, Shah-i-Zinda), replacing the earlier placeholder
   green. --fare (warm amber/ochre, echoing gold embroidery) is
   unchanged — the logo's own palette kept it as-is too. This is the
   app's one base accent; the separate passenger/driver dual-accent
   idea from earlier in the project is intentionally NOT part of this
   — see memory role-color-redesign-deferred (parked until after
   launch + 3-4 months of real usage).
   Contrast checked by the numbers (WCAG relative luminance), not by
   eye: #1A4B8C + white button text ≈8.6:1, as text on the light
   --paper below ≈7.4:1 — both comfortably pass AA (4.5:1).
   Logic/behavior is untouched — this file is presentation only.
   ============================================================ */
:root{
  /* Declares the ACTIVE scheme, synced to data-theme — more specific
     than the static <meta name="color-scheme"> in index.html, which
     only hints before CSS loads. Added 06.09.2026: the meta alone
     wasn't enough to stop Telegram's Android WebView from
     algorithmically force-darkening the page (it saw "supports both"
     and applied its own darkening on top of our real light colors,
     washing out .chip-accept etc.) — reproduced only inside Telegram,
     not a normal mobile browser, confirming it's WebView-side, not a
     CSS bug. */
  color-scheme:light;
  --ink:#101519;
  --paper:#EEF1F5;
  --surface:#FFFFFF;
  /* Deliberately constant across themes (never redefined under
     [data-theme="dark"]) — unlike --ink (primary text color, inverts
     with theme), this is the "always-dark-backdrop-for-white-text"
     color used by solid pills/avatars/toasts/active chips. Those
     assume a dark bg + white content regardless of theme; if they used
     --ink directly, dark mode would flip them to a light bg with
     white text on top and make them unreadable. */
  --ink-solid:#101519;

  --route:#1A4B8C;         /* logo's cobalt-ultramarine — was #0C8368 (green) */
  --route-dark:#0F3268;
  --route-tint:#E7EEF9;

  --fare:#B3701F;         /* redesign 04.09.2026 (Claude Design canvas) — was #DB9138, same warm amber/ochre tone, deepened to actually pass AA (4.5:1) as a TEXT color (price labels), not just as a tinted-background fill */
  --fare-tint:#FBF0DE;

  --line:#E2E7EE;
  --muted:#68757F;
  --muted-2:#96A2AB;

  --danger:#B84A34;
  --danger-tint:#F9E9E4;

  /* Cabin-seat-picker only (added 01.09.2026) — a taken seat needs its
     own filled neutral, distinct from both --surface (available) and
     --route (selected by me); --line/--muted alone read too close to
     "available" once seats are actually side by side on screen. */
  --seat-taken:#C7CFCA;

  /* --control-fill — the fill for a small inset control (stepper
     button, neutral status chip, the seat-picker's cabin outline) that
     sits INSIDE a --surface card or a --paper sheet. Redesign
     04.09.2026: promoted off `var(--paper)` to its own dedicated
     "elevated backing" shade, visually distinct from both --paper (page
     canvas) and --surface (card) instead of borrowing --paper's value.
     Never reference --paper directly for a small inset control going
     forward — use this instead. */
  --control-fill:#F6F8FA;
  /* --field-bg (new 04.09.2026) — inputs/selects/textareas get their
     own filled background, distinct from --surface (card) and
     --control-fill (small inset control), so a field reads as a
     recessed input area sitting on a card. */
  --field-bg:#F6F8FA;

  --font-display:'Space Grotesk', sans-serif;
  --font-body:'Inter', sans-serif;
  --font-mono:'IBM Plex Mono', monospace;

  --radius-sm:13px;        /* redesign 04.09.2026, was 9px — fields */
  --radius-md:18px;        /* redesign 04.09.2026, was 14px — cards */
  --radius-lg:20px;
  --radius-pill:999px;

  --shadow-sheet:0 24px 60px -28px rgba(16,21,25,.45);
  --shadow-toast:0 20px 50px -24px rgba(16,21,25,.5);
  --shadow-highlight:0 0 0 3px var(--route-tint);
  /* --lift-card (new 04.09.2026) — a soft two-layer elevation (a tight
     1px contact shadow + a broader ambient one) for cards/panels/stat
     tiles that sit flush on the page, distinct from --shadow-sheet/
     --shadow-toast (those float ABOVE the page, not flush with it). */
  --lift-card:0 1px 2px rgba(16,21,25,.05), 0 10px 28px -20px rgba(16,21,25,.35);

  --sidebar-w:88px;
  --sidebar-w-desktop:240px;

  --text-scale:1;

  /* --- redesign tokens (26.08.2026, handoff/msgo.css) — additive,
     nothing above renamed/removed. --r-*/--s* are the new component
     library's own naming; --radius-*/--shadow-* aliases above stay so
     every existing var(--radius-md) etc. reference keeps working.
     --r-card/--r-sheet/--r-field bumped 04.09.2026 alongside the
     --radius-* redesign above; --r-pill/--r-chip untouched. */
  --on-route:#FFFFFF; --on-ink:#EEF2F0; --scrim:rgba(18,22,28,.42);
  --lift:0 1px 2px rgba(18,22,28,.05);
  --r-pill:999px; --r-card:18px; --r-sheet:26px; --r-field:13px; --r-chip:999px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:28px; --s7:40px;
}

/* Dark theme — same tokens, dark-adapted values. Explicit user choice
   (data-theme attribute), not prefers-color-scheme — same pattern as
   language/text-size below: opt-in via the settings sheet, persisted
   in localStorage, applied before first paint (see js/i18n.js). Kept
   as a straight token swap, not a separate stylesheet, so every
   existing var(--x) reference in this file picks it up automatically —
   nothing below this block needed to change for dark mode to work.
   Redesign 04.09.2026 (Claude Design canvas) rebuilt this whole block
   from scratch rather than inverting the light values — a deep
   blue-black base, not a desaturated grey. */
:root[data-theme="dark"]{
  color-scheme:dark;
  --ink:#E6EDF3;
  --paper:#0A0E13;          /* deep blue-black base */
  --surface:#131A21;        /* card */

  --route:#3470CE;          /* button fill — white text on it passes AA */
  --route-dark:#8FB6F2;     /* text, links, icons on the dark background */
  --route-tint:#15253E;

  --fare:#E8A85C;
  --fare-tint:#2C2213;

  --line:#27323C;
  --muted:#8B98A5;
  --muted-2:#66727D;

  --danger:#E8806A;
  --danger-tint:#32201C;

  --seat-taken:#333B37;
  --control-fill:#1A2129;   /* elevated surface = lighter than the card, same "elevation adds lightness in the dark" principle as before */
  --field-bg:#0F151B;       /* field = recessed, darker than the card */

  /* Shadows don't read in a dark theme — a thin light-on-dark outline
     stands in for one instead. */
  --shadow-sheet:0 34px 80px -34px #000, 0 0 0 1px rgba(255,255,255,.03);
  --shadow-toast:0 20px 50px -26px #000;
  --lift-card:0 0 0 1px rgba(255,255,255,.02), 0 14px 34px -24px #000;

  --on-route:#FFFFFF; --on-ink:#E6EDF3; --scrim:rgba(4,7,10,.6);
  --lift:0 1px 2px rgba(0,0,0,.35);
}

*{ box-sizing:border-box; }
html,body{ margin:0; padding:0; }

/* ============================================================
   Text size (accessibility, requested 24.08.2026 — for users with
   poor eyesight). font-size scaling via calc(Npx * var(--text-scale))
   — NOT `zoom`: three live-tested zoom attempts (root <html>, then
   .content-area/.sheet, then their direct children) all overflowed
   the visible width, because zoom paints an element's box bigger
   without shrinking what "100% width" resolves to, so text scrolls
   past the edge instead of wrapping. calc()-scaled font-size leaves
   every element's WIDTH untouched — bigger text just wraps to more
   lines within the same box, same as real browser text zoom.
   Icon/glyph-only spans (avatar initials, seat-stepper +/-, nav
   icons, nav-fab) are deliberately left in plain px, not scaled —
   those aren't reading text, and letting them grow risks overflowing
   their fixed circular/square boxes.
   See js/i18n.js's getTextSize/setTextSize/applyTextSize (persisted
   in localStorage, applied to <html> before first paint) and the
   settings sheet (profile screen's ⚙ icon) for the UI. */
/* HANDOFF's own boolean large-text switch (data-textsize="lg", for any
   NEW rem-based markup added below) — additive, does not replace the
   existing 3-level data-text-size system above, which every current
   screen is already built against and stays the primary mechanism. */
html[data-textsize="lg"]{ font-size:18.5px; }
:focus-visible{ outline:2px solid var(--route); outline-offset:2px; }
html[data-text-size="2"]{ --text-scale:1.15; }
html[data-text-size="3"]{ --text-scale:1.3; }
html[data-text-size="4"]{ --text-scale:1.5; }
body{
  min-height:100dvh;
  font-family:var(--font-body);
  color:var(--ink);
  background:var(--paper);
}
button{ font-family:inherit; }
input,select,textarea{ font-family:inherit; }

/* Scrollbar track/thumb hidden everywhere inside the app — scrolling
   itself is untouched (touch/wheel/keyboard all still work), this only
   removes the visible bar. */
.app-shell, .app-shell *{
  scrollbar-width:none;      /* Firefox */
  -ms-overflow-style:none;   /* legacy Edge/IE */
}
.app-shell::-webkit-scrollbar, .app-shell *::-webkit-scrollbar{
  display:none;               /* Chrome/Safari/Chromium Edge */
}

@keyframes rt-pulse{ 0%{opacity:.9;transform:scale(1)} 70%,100%{opacity:0;transform:scale(2.6)} }
@keyframes rt-blink{ 0%,100%{opacity:1} 50%{opacity:.3} }
/* Водителю на карточке заказа — «пассажир хочет отменить, подтвердите»
   (requested 02.09.2026). rt-blink уже был в файле, просто не
   применялся нигде — переиспользую вместо новой анимации. */
.needs-cancel-blink{ animation:rt-blink 1.1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce){ .needs-cancel-blink{ animation:none; } }
@keyframes fade-in{ from{opacity:0; transform:translateY(4px)} to{opacity:1; transform:translateY(0)} }
@keyframes sheet-up{ from{transform:translateY(24px); opacity:.6} to{transform:translateY(0); opacity:1} }

/* ============================================================
   App shell — adaptive: phone frame on mobile, centered card on
   tablet/desktop with a real side/tab navigation instead of the
   fixed-mobile-only frame from the original prototype.
   ============================================================ */
.app-shell{
  min-height:100dvh;
  display:flex;
  align-items:center;
  justify-content:center;
  background:var(--paper);
  padding:0;
  container-type:inline-size;
  container-name:msgo;
}
/* Dev-only viewport/role switcher — testing aid, not part of the product UI.
   Forces .app-shell's inline size so the @container breakpoints above
   respond to a chosen width instead of the real browser window. */
.app-shell.dev-mobile{ max-width:390px; margin:0 auto; }
.app-shell.dev-tablet{ max-width:820px; margin:0 auto; }
.app-shell.dev-desktop{ max-width:1280px; margin:0 auto; }

.dev-bar{
  position:fixed; top:10px; left:50%; transform:translateX(-50%);
  z-index:200; display:flex; gap:6px; align-items:center;
  background:rgba(18,22,28,.92); border-radius:var(--radius-pill);
  padding:5px; box-shadow:var(--shadow-toast); backdrop-filter:blur(6px);
}
.dev-bar button{
  border:none; background:transparent; color:#B8C2BD; font-size:calc(11.5px * var(--text-scale)); font-weight:600;
  padding:6px 10px; border-radius:var(--radius-pill); cursor:pointer; white-space:nowrap;
}
.dev-bar button.active{ background:#fff; color:var(--ink); }
.dev-bar .dev-sep{ width:1px; align-self:stretch; background:rgba(255,255,255,.18); margin:2px 2px; }
@container msgo (min-width:641px){
  .app-shell{ background:#D9DFDB; padding:32px 16px; }
}

.app-frame{
  width:100%;
  max-width:100%;
  height:100dvh;
  background:var(--paper);
  overflow:hidden;
  display:flex;
  flex-direction:column;
  position:relative;
}
@container msgo (min-width:641px) and (max-width:1023px){
  .app-frame{ max-width:760px; height:min(920px,92vh); border-radius:24px; border:1px solid var(--line); box-shadow:var(--shadow-sheet); }
}
@container msgo (min-width:1024px){
  .app-frame{ max-width:1240px; height:min(880px,92vh); border-radius:24px; border:1px solid var(--line); box-shadow:var(--shadow-sheet); }
}

/* toasts */
.toast-stack{ position:absolute; top:14px; left:14px; right:14px; z-index:90; display:flex; flex-direction:column; gap:8px; }
@container msgo (min-width:641px){ .toast-stack{ left:auto; width:340px; right:20px; top:20px; } }
.toast{ background:var(--ink-solid); color:#fff; padding:12px 14px; border-radius:13px; font-size:calc(13px * var(--text-scale)); display:flex; gap:10px; align-items:flex-start; box-shadow:var(--shadow-toast); animation:fade-in .18s ease-out; }

/* ============================================================
   Layout: content area shifts right of the sidebar on wide
   screens; bottom nav becomes a left sidebar.
   ============================================================ */
.content-area{ flex:1; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.content-pad-bottom{ padding-bottom:90px; }
@container msgo (min-width:1024px){
  .app-frame.has-nav .content-area{ margin-left:var(--sidebar-w-desktop); }
  .app-frame.has-nav .content-pad-bottom{ padding-bottom:24px; }
}
@container msgo (min-width:641px) and (max-width:1023px){
  .app-frame.has-nav .content-area{ margin-left:var(--sidebar-w); }
  .app-frame.has-nav .content-pad-bottom{ padding-bottom:24px; }
}

/* ============================================================
   Typography helpers
   ============================================================ */
.h-display{ font-family:var(--font-display); font-weight:700; }
.text-muted{ color:var(--muted); }
.text-muted-2{ color:var(--muted-2); }
.mono{ font-family:var(--font-mono); }
.eyebrow{ font-size:calc(11px * var(--text-scale)); text-transform:uppercase; letter-spacing:.06em; font-family:var(--font-mono); color:var(--muted-2); }

/* ============================================================
   Buttons
   ============================================================ */
.btn{ border:none; border-radius:14px; font-weight:600; cursor:pointer; transition:opacity .15s ease, transform .1s ease, box-shadow .15s ease; }
.btn:active{ transform:scale(.98); }
.btn:disabled{ cursor:not-allowed; }
.btn-block{ width:100%; padding:16px 20px; font-size:calc(15px * var(--text-scale)); }
.btn-primary{ background:var(--route); color:#fff; box-shadow:0 12px 26px -16px var(--route); }
.btn-dark{ background:var(--ink); color:var(--paper); }
.btn-danger{ background:var(--danger-tint); color:var(--danger); border:1px solid var(--danger-tint); }
.btn-danger-solid{ background:var(--danger); color:#fff; }
.btn-outline{ background:var(--control-fill); border:1px solid var(--line); color:var(--route-dark); }
.btn-ghost{ background:none; border:none; color:var(--route-dark); font-weight:600; cursor:pointer; }
.btn-social{ flex:1; display:flex; align-items:center; justify-content:center; gap:8px; border:1px solid var(--line); background:var(--surface); color:var(--ink); padding:12px 0; border-radius:14px; font-weight:600; font-size:calc(13.5px * var(--text-scale)); cursor:pointer; }
.btn-social.dark{ border:none; background:var(--ink-solid); color:#fff; }

.segmented{ display:flex; gap:4px; background:var(--control-fill); border:1px solid var(--line); border-radius:14px; padding:4px; }
.segmented button{ flex:1; border:none; padding:11px 0; border-radius:11px; font-weight:600; font-size:calc(13.5px * var(--text-scale)); cursor:pointer; background:transparent; color:var(--muted); transition:background .15s ease,color .15s ease; }
.segmented button.active{ background:var(--surface); color:var(--ink); box-shadow:var(--lift-card); }

.field{ margin-bottom:14px; }
.field label{ display:block; font-family:var(--font-mono); font-weight:600; font-size:calc(10.5px * var(--text-scale)); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-bottom:7px; }
.field input, .field select, .field textarea{
  width:100%; border:1px solid var(--line); background:var(--field-bg); border-radius:var(--radius-sm);
  padding:14px 15px; font-size:calc(15px * var(--text-scale)); color:var(--ink); outline:none; box-sizing:border-box;
}
.field input:focus, .field select:focus, .field textarea:focus{ border-color:var(--route); box-shadow:0 0 0 3px var(--route-tint); }
.field textarea{ resize:none; }
/* Required-field-missing highlight — project-wide convention (requested
   10.09.2026, "если важное не заполнено или не выбрано, тогда визуально
   показываем чего не хватает... правило для всего проекта"): red
   border only, no inline error text — whatever toast/message already
   exists for that validation stays the explanation, this is just WHICH
   field. Wrap any field needing this in `.field.invalid` (or, for a
   custom-styled wrapper that sets its own inline border like the auth
   screen's phone field, drive the border color from state directly —
   see renderAuth). Higher specificity than the plain rule above (extra
   class), so no !important needed. */
.field.invalid input, .field.invalid select, .field.invalid textarea{ border-color:var(--danger); }
.field.invalid input:focus, .field.invalid select:focus, .field.invalid textarea:focus{ border-color:var(--danger); box-shadow:0 0 0 3px var(--danger-tint); }

/* Show/hide password toggle (requested 26.08.2026, "везде где есть
   пароль") — the icon sits INSIDE the input's own border, never
   outside it, so it never widens/pushes the field. Extra specificity
   (.field .pwd-field input) over .field input above is what lets this
   win without !important. */
.pwd-field{ position:relative; }
.field .pwd-field input{ padding-right:42px; }
.pwd-toggle{
  position:absolute; top:50%; right:3px; transform:translateY(-50%);
  width:32px; height:32px; display:flex; align-items:center; justify-content:center;
  background:none; border:none; padding:0; margin:0; cursor:pointer; color:var(--muted); border-radius:8px;
}
.pwd-toggle:hover{ color:var(--ink); }
.pwd-toggle svg{ width:19px; height:19px; }

/* ============================================================
   Auth screen
   ============================================================ */
.auth-wrap{ padding:0 22px; }
@container msgo (min-width:641px){ .auth-wrap{ max-width:420px; margin:0 auto; padding:0 24px; } }
/* flex-wrap:wrap is a no-op at normal size (everything already fits on
   one line) — it only engages when a zoomed .content-area (see the
   text-size rules above) makes the RU/Aa switcher buttons too wide to
   share the row with the zoomed brand text; they drop to their own
   line instead of forcing a horizontal scroll to reach them. */
.brand-row{ display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin:22px 0 26px; }
.brand-mark{ width:38px; height:38px; border-radius:11px; background:var(--ink-solid); display:flex; align-items:center; justify-content:center; flex:none; }
.brand-name{ font-family:var(--font-display); font-weight:700; font-size:calc(19px * var(--text-scale)); }
.brand-tag{ font-size:calc(11.5px * var(--text-scale)); color:var(--muted); font-family:var(--font-mono); letter-spacing:.04em; }

/* Compact language switcher — auth screen only (top-right of brand row,
   a small flyout list instead of the full-width segmented control used
   elsewhere, see renderAuth). */
/* Wraps lang-compact + text-size-compact as one flex item of
   .brand-row (which has flex-wrap:wrap for the zoomed case above) —
   as a single item they either both fit on line 1 or both wrap to
   line 2 together; two separate auto-margin items could otherwise
   split across lines with one landing flush against the zoomed edge. */
.brand-switchers{ display:flex; align-items:center; gap:6px; margin-left:auto; flex:none; }
.lang-compact{ position:relative; flex:none; }
.text-size-compact{ position:relative; flex:none; }
.lang-compact-btn{
  display:flex; align-items:center; gap:4px; border:1px solid var(--line); background:var(--surface);
  border-radius:var(--radius-pill); padding:7px 11px; font-weight:600; font-size:calc(12.5px * var(--text-scale)); color:var(--ink);
  cursor:pointer;
}
.lang-compact-menu{
  position:absolute; top:calc(100% + 6px); right:0; min-width:96px; background:var(--surface);
  border:1px solid var(--line); border-radius:12px; box-shadow:var(--shadow-sheet); z-index:70;
  max-height:220px; overflow-y:auto;
}
.lang-compact-menu button{
  display:block; width:100%; text-align:left; border:none; background:transparent; padding:10px 13px;
  font-size:calc(13px * var(--text-scale)); font-weight:600; color:var(--ink); cursor:pointer;
}
.lang-compact-menu button.active{ background:var(--ink-solid); color:#fff; }
.lang-compact-menu button:hover:not(.active){ background:var(--paper); }

.progress-dots{ display:flex; gap:6px; margin:6px 0 20px; }
.progress-dots span{ height:4px; flex:1; border-radius:4px; background:var(--line); }
.progress-dots span.done{ background:var(--route); }

.auth-divider{ display:flex; align-items:center; gap:10px; margin:18px 0; }
.auth-divider .line{ flex:1; height:1px; background:var(--line); }
.auth-legal{ margin-top:18px; padding-bottom:26px; text-align:center; font-size:calc(13px * var(--text-scale)); color:var(--muted); line-height:1.5; }
.auth-legal span{ color:var(--route-dark); font-weight:600; cursor:pointer; }

/* Telegram-delivered OTP (added 09.09.2026) — guide screen + animated
   code boxes, see app.js's authStep 'tg-guide'/'tg-code'. */
.otp-guide-steps{ margin-bottom:24px; display:flex; flex-direction:column; gap:12px; }
.otp-guide-step{
  background:var(--field-bg); border-radius:var(--radius-sm); padding:12px 14px;
  font-size:calc(14px * var(--text-scale)); line-height:1.4; color:var(--ink);
}
/* Boxes fill in one at a time (animateTgCode drives revealCount via
   setState) purely so this still looks/feels like a normal app's OTP
   screen — there's no real typing behind it, the code is already fully
   known the moment this screen renders (see otpBoxesHtml's own doc
   comment for why that's a deliberate, requested UX choice). */
.otp-boxes{ display:flex; gap:8px; justify-content:center; margin:14px 0; }
.otp-box{
  width:42px; height:52px; border:1.5px solid var(--line); border-radius:var(--radius-sm);
  background:var(--surface); display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-weight:600; font-size:calc(20px * var(--text-scale)); color:var(--ink);
  transition:border-color .15s, transform .15s, background .15s;
}
.otp-box.filled{
  border-color:var(--route); background:var(--route-tint);
  animation:otp-box-pop .18s ease-out;
}
@keyframes otp-box-pop{ from{ transform:scale(.8); } to{ transform:scale(1); } }

/* ============================================================
   Home header + toggles
   ============================================================ */
.home-header{ display:flex; align-items:center; justify-content:space-between; padding:12px 20px 6px; }
@container msgo (min-width:1024px){ .home-header{ padding:24px 28px 6px; } }
.avatar{ width:44px; height:44px; border-radius:13px; background:var(--ink-solid); color:#fff; display:flex; align-items:center; justify-content:center; font-family:var(--font-display); font-weight:600; font-size:15px; flex:none; }
.avatar.lg{ width:74px; height:74px; border-radius:20px; font-size:24px; margin:0 auto 12px; }
.avatar.sm{ width:32px; height:32px; border-radius:9px; font-size:12px; }
.bell-btn{ width:40px; height:40px; border-radius:12px; background:var(--surface); border:1px solid var(--line); display:flex; align-items:center; justify-content:center; position:relative; cursor:pointer; }
.bell-dot{ position:absolute; top:6px; right:7px; width:8px; height:8px; border-radius:50%; background:var(--fare); border:2px solid var(--paper); }

.mode-row{ display:flex; gap:8px; padding:10px 20px 0; }
@container msgo (min-width:1024px){ .mode-row{ padding:10px 28px 0; } }
.mode-row button{ flex:1; border:1.5px solid var(--line); background:var(--surface); color:var(--muted-2); padding:9px 0; border-radius:var(--radius-pill); font-weight:600; font-size:calc(13px * var(--text-scale)); cursor:not-allowed; opacity:.5; }
.mode-row button.active{ border-color:var(--ink-solid); background:var(--ink-solid); color:#fff; cursor:pointer; opacity:1; }

.balance-card{ margin:12px 20px 4px; background:var(--route); border-radius:var(--radius-lg); padding:16px; color:#fff; display:flex; align-items:center; justify-content:space-between; gap:12px; box-shadow:0 16px 34px -22px var(--route); }
@container msgo (min-width:1024px){ .balance-card{ margin:12px 28px 4px; } }
.balance-card .label{ font-size:calc(11px * var(--text-scale)); font-family:var(--font-mono); letter-spacing:.06em; color:rgba(255,255,255,.72); text-transform:uppercase; }
.balance-card .value{ font-size:calc(20px * var(--text-scale)); font-weight:600; margin-top:3px; font-family:var(--font-display); }

.route-card{ margin:12px 20px 4px; background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:14px; display:flex; flex-direction:column; gap:10px; position:relative; }
@container msgo (min-width:1024px){ .route-card{ margin:12px 28px 4px; } }
.route-select-row{ display:flex; gap:8px; }
/* text-overflow/white-space (requested 27.08.2026) — a long region
   name (e.g. "Qashqadaryo viloyati") was clipping mid-word with no "…"
   in the closed <select> box. Most engines that matter here (Chromium/
   WebKit — Telegram's in-app WebView included) already honor these on
   a closed native select; browsers that don't just keep today's plain
   clip, no regression either way. */
.route-select-row select{ flex:1; width:auto; min-width:0; border:1px solid var(--line); background:var(--field-bg); border-radius:12px; padding:12px 10px; font-size:calc(12.5px * var(--text-scale)); color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.route-select-row select:disabled{ opacity:.5; cursor:not-allowed; }
/* "Откуда"/"Куда" above each select row, top-left (requested 26.08.2026,
   switched from top-right the same day — was there before a redesign
   pass dropped it from the home search card; the create-ride sheet's
   own from/to still uses a plain top-left .field label and is
   untouched). A column flex group (not absolute positioning) so it can
   never overlap the selects regardless of text scale or a select row
   wrapping on a narrow screen. */
.route-select-group{ display:flex; flex-direction:column; gap:4px; }
.route-select-label{ align-self:flex-start; font-size:calc(11.5px * var(--text-scale)); font-weight:600; color:var(--muted); }
/* Пульсирующая оранжевая рамка (requested 02.09.2026) — жмут «Поиск»
   без заполненного Откуда/Куда, читается без единой буквы (та же идея,
   что iOS-тряска неверного пароля, просто кольцом вместо тряски).
   Цвет — фирменный оранжевый Claude, не завязан на тему/токены
   намеренно: это сигнал "внимание сюда", должен быть одинаково заметен
   и в светлой, и в тёмной теме. */
@keyframes route-pulse-orange{
  0%{ box-shadow:0 0 0 0 rgba(218,119,86,.6); border-color:#DA7756; }
  70%{ box-shadow:0 0 0 9px rgba(218,119,86,0); border-color:#DA7756; }
  100%{ box-shadow:0 0 0 0 rgba(218,119,86,0); border-color:var(--line); }
}
.route-select-group.pulse-missing .route-select-row select{
  animation:route-pulse-orange .5s ease-out 2; /* 2×0.5s = 1s, matches the JS timeout that removes this class */
}
.route-summary{ display:flex; flex-direction:column; gap:6px; padding-top:2px; }
.route-summary-row{ display:flex; align-items:center; gap:8px; font-size:calc(13px * var(--text-scale)); font-weight:500; color:var(--ink); }
.route-input-row{ display:flex; align-items:center; gap:10px; position:relative; }
.route-input-row input{ flex:1; border:none; background:transparent; font-size:calc(14px * var(--text-scale)); color:var(--ink); outline:none; font-weight:500; }
.route-dot{ width:8px; height:8px; border-radius:50%; background:var(--muted-2); flex:none; }
.route-dot.to{ border-radius:2px; background:var(--route); }
.route-sep{ height:1px; background:var(--line); margin-left:2px; }
.suggest-list{ position:absolute; top:26px; left:0; right:0; background:var(--surface); border:1px solid var(--line); border-radius:12px; box-shadow:var(--shadow-sheet); max-height:180px; overflow-y:auto; z-index:70; }
.suggest-list button{ display:block; width:100%; text-align:left; border:none; background:transparent; padding:10px 14px; font-size:calc(13.5px * var(--text-scale)); color:var(--ink); cursor:pointer; border-bottom:1px solid var(--line); }
.suggest-list button:hover{ background:var(--paper); }

.orders-heading{ display:flex; align-items:center; justify-content:space-between; padding:14px 20px 0; }
@container msgo (min-width:1024px){ .orders-heading{ padding:22px 28px 0; } }
.sort-btn{ border:1.5px solid var(--line); background:var(--surface); color:var(--muted); padding:7px 12px; border-radius:var(--radius-pill); font-weight:600; font-size:calc(12px * var(--text-scale)); cursor:pointer; }

.tabs-row{
  display:flex; gap:6px; padding:18px 20px 6px; overflow-x:auto;
  /* Fade the right edge instead of hard-clipping a chip when the row
     doesn't fully fit — scrolling still works (see the hidden-scrollbar
     rule near the top of this file), this just signals there's more. */
  -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 18px), transparent 100%);
  mask-image:linear-gradient(to right, #000 calc(100% - 18px), transparent 100%);
}
@container msgo (min-width:1024px){ .tabs-row{ padding:18px 28px 6px; } }
.tab-chip{ flex:none; border:1.5px solid var(--line); background:var(--surface); color:var(--muted); padding:8px 13px; border-radius:var(--radius-pill); font-weight:600; font-size:calc(12.5px * var(--text-scale)); white-space:nowrap; display:flex; align-items:center; gap:5px; cursor:pointer; }
.tab-chip.active{ border-color:var(--ink-solid); background:var(--ink-solid); color:#fff; }
.tab-chip .count{ font-family:var(--font-mono); font-size:calc(11px * var(--text-scale)); opacity:.75; }

/* ============================================================
   Ride ticket cards + grid (real responsive grid, replaces the
   original's disabled desktop columns)
   ============================================================ */
.tickets-area{ display:flex; flex-direction:column; gap:10px; padding:14px 20px 24px; }
@container msgo (min-width:641px){
  .tickets-area{ display:grid; grid-template-columns:repeat(2,1fr); gap:12px; padding:14px 28px 28px; }
}
@container msgo (min-width:1024px){
  .tickets-area{ grid-template-columns:repeat(3,1fr); }
}
.tickets-heading{ grid-column:1/-1; font-family:var(--font-mono); font-size:calc(11px * var(--text-scale)); text-transform:uppercase; letter-spacing:.06em; color:var(--muted-2); padding:0 4px; }

.ticket{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-md); box-shadow:var(--lift-card); position:relative; overflow:hidden; }
.ticket.highlight{ border-color:var(--line); border-width:1px; background:var(--surface); box-shadow:var(--lift-card); }
.ticket.highlight::before{ content:''; position:absolute; top:0; left:0; bottom:0; right:auto; width:4px; height:auto; background:var(--route); }
.ticket-body{ padding:16px 16px 14px; }
/* flex-wrap (found 01.09.2026, text-scale audit): at larger text sizes
   the status chip alone can eat most of the row's width, and without
   wrap the order-no/date span on the right doesn't drop to its own
   line — it re-wraps WORD BY WORD inside its own cramped remaining
   space instead ("OP60 · Aug 29," / "09:00"), which reads far worse
   than the two halves just stacking. gap covers the vertical spacing
   wrap introduces (margin-bottom below still separates the row from
   whatever comes next). */
.ticket-top{ display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:4px 10px; margin-bottom:12px; }
/* nowrap on the right-hand span specifically (found alongside the
   above) — combined with flex-wrap on the parent, this is what makes
   it drop to a clean second line as one unit instead of breaking
   mid-string; every .ticket-top usage in app.js carries this same
   inline font-size style, this rule covers all of them by tag. */
.ticket-top > span:last-child{ white-space:nowrap; }
.chip{ font-family:'Inter',sans-serif; font-weight:600; letter-spacing:0; text-transform:none; font-size:calc(11.5px * var(--text-scale)); padding:5px 10px; border-radius:var(--radius-pill); }
.route-line{ display:flex; align-items:center; gap:0; margin-bottom:12px; }
.route-line .pt{ flex:1; }
.route-line .pt.right{ text-align:right; }
.route-line .dash{ flex:none; width:46px; height:1px; margin:14px 8px 0; border-top:2px dashed var(--line); }
/* align-items:flex-start (found 01.09.2026, text-scale audit): was
   `center` — fine while .name/.meta stayed one line each, but at
   larger text sizes .meta can wrap to two lines (e.g. "📦 Посылка/
   Почта" splitting at the slash) and centering against that taller
   sibling floats .price into the gap between the two meta lines
   instead of staying level with .name. flex-start keeps price pinned
   to the top regardless of how many lines the middle column wraps to. */
.driver-row{ display:flex; align-items:flex-start; gap:9px; }
.driver-row .name{ font-size:calc(13px * var(--text-scale)); font-weight:600; }
.driver-row .meta{ font-size:calc(11px * var(--text-scale)); color:var(--muted); }
.price{ font-family:var(--font-mono); font-weight:600; font-size:calc(17px * var(--text-scale)); color:var(--ink); }
.ticket-actions{ padding:0 16px 16px; display:flex; gap:8px; }
.cancel-banner{ margin-top:12px; padding:10px 12px; border-radius:10px; background:var(--danger-tint); display:flex; flex-direction:column; gap:8px; }
.offer-divider{ border:none; height:1px; margin:0; background:repeating-linear-gradient(90deg,var(--line) 0 6px,transparent 6px 12px); }

.empty-state{ grid-column:1/-1; text-align:center; padding:60px 24px; color:var(--muted); }
.empty-state .title{ font-family:var(--font-display); font-size:calc(16px * var(--text-scale)); color:var(--ink); margin-bottom:6px; }
.empty-state p{ font-size:calc(13.5px * var(--text-scale)); line-height:1.5; margin:0; }

/* ============================================================
   Profile
   ============================================================ */
.profile-head{ padding:20px; text-align:center; }
.profile-name{ font-size:calc(20px * var(--text-scale)); font-weight:700; }
.profile-contact{ font-size:calc(13px * var(--text-scale)); color:var(--muted); margin-top:2px; }
.role-badge{ display:inline-flex; align-items:center; gap:4px; background:var(--route-tint); color:var(--route-dark); font-size:calc(11px * var(--text-scale)); font-weight:700; padding:3px 8px; border-radius:var(--radius-pill); font-family:var(--font-mono); margin-top:8px; }
.stat-row{ display:flex; gap:10px; padding:4px 20px 20px; }
.stat-card{ flex:1; background:var(--surface); border:1px solid var(--line); border-radius:16px; padding:14px; text-align:center; box-shadow:var(--lift-card); }
.stat-card .val{ font-family:var(--font-mono); font-size:calc(20px * var(--text-scale)); font-weight:600; color:var(--ink); }
.stat-card .lbl{ font-size:calc(11px * var(--text-scale)); color:var(--muted); margin-top:2px; }
.panel{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-md); padding:15px; margin-bottom:8px; box-shadow:var(--lift-card); }
.panel-section{ padding:0 20px 8px; }
@container msgo (min-width:641px){ .panel-section{ max-width:640px; } }
.panel-section .section-label{ font-size:calc(10.5px * var(--text-scale)); color:var(--muted); text-transform:uppercase; letter-spacing:.1em; margin:18px 0 8px 2px; font-family:var(--font-mono); }
.route-history-card{ background:var(--surface); border:1px solid var(--line); border-radius:12px; padding:12px 14px; }

/* ============================================================
   Bottom nav — becomes a left sidebar from tablet width up
   ============================================================ */
.bottom-nav{
  position:absolute; left:16px; right:16px; bottom:14px; top:auto; width:auto;
  background:var(--surface); border:1px solid var(--line); border-top:1px solid var(--line);
  border-radius:24px;
  display:flex; flex-direction:row; align-items:center; justify-content:space-around;
  gap:8px; padding:7px; z-index:40; box-sizing:border-box; box-shadow:var(--shadow-sheet);
}
.bottom-nav .nav-item{ background:none; border:none; display:flex; flex-direction:column; align-items:center; gap:4px; flex:1; padding:10px 0; cursor:pointer; opacity:1; border-radius:18px; color:var(--muted); }
.bottom-nav .nav-item.active{ background:var(--route-tint); }
.bottom-nav .nav-item span{ font-size:calc(10.5px * var(--text-scale)); font-weight:600; color:var(--muted-2); }
.bottom-nav .nav-item.active span{ color:var(--route-dark); }
.nav-fab{ width:44px; height:44px; border-radius:14px; background:var(--route); display:flex; align-items:center; justify-content:center; box-shadow:0 12px 22px -12px var(--route); border:none; margin-top:0; }

@container msgo (min-width:641px){
  .bottom-nav{
    left:0; right:auto; top:0; bottom:0; width:var(--sidebar-w);
    border-radius:0; box-shadow:none;
    flex-direction:column; justify-content:flex-start; gap:28px;
    padding:28px 0 0; border-top:none; border-right:1px solid var(--line);
  }
  .bottom-nav .nav-item{ flex:none; }
  .nav-fab{ margin-top:0; }
}
@container msgo (min-width:1024px){
  .bottom-nav{ width:var(--sidebar-w-desktop); align-items:flex-start; padding-left:28px; }
  .bottom-nav .nav-item{ flex-direction:row; gap:10px; }
}

/* ============================================================
   Bottom sheet
   ============================================================ */
.sheet-overlay{ position:absolute; inset:0; background:rgba(18,22,28,.5); z-index:60; display:flex; align-items:flex-end; }
@container msgo (min-width:641px){ .sheet-overlay{ align-items:center; justify-content:center; } }
.sheet{ background:var(--paper); width:100%; border-radius:var(--r-sheet) var(--r-sheet) 0 0; max-height:88%; overflow-y:auto; padding-bottom:26px; box-sizing:border-box; animation:sheet-up .18s ease-out; }
.sheet.no-anim{ animation:none; } /* re-renders while typing shouldn't replay the entrance animation */
/* Driver's passenger-detail screen (requested 02.09.2026) — genuinely
   full height, not the usual 88% bottom sheet, per "полным экраном". */
.sheet.full{ max-height:100%; height:100%; border-radius:0; }
@container msgo (min-width:641px){ .sheet.full{ max-height:85vh; height:auto; border-radius:24px; } }
@container msgo (min-width:641px){ .sheet{ width:480px; max-width:92vw; border-radius:24px; max-height:85vh; } }
.sheet-grip{ width:36px; height:4px; border-radius:4px; background:var(--line); margin:10px auto 4px; }
.sheet-header{ display:flex; align-items:center; justify-content:space-between; padding:12px 20px; border-bottom:1px solid var(--line); }
.sheet-header h3{ font-size:calc(18px * var(--text-scale)); margin:0; font-family:var(--font-display); }
.sheet-close{ width:34px; height:34px; border-radius:12px; background:var(--control-fill); border:1px solid var(--line); display:flex; align-items:center; justify-content:center; cursor:pointer; }
.sheet-content{ padding:14px 20px 4px; }

/* First-run coach-mark tour (requested 27.08.2026) — positioned via JS
   (positionTour(), app.js) against the real target element, this only
   supplies the box models. Deliberately blocks interaction with the
   rest of the page (no data-onclick on the overlay itself — a tap
   outside the tooltip's own buttons just does nothing) rather than
   trying to detect the real action and auto-advance. Every size here
   uses calc(px * var(--text-scale)) like the rest of the app, so a
   larger text-size setting grows the tooltip's height, never pushes it
   off-screen — the JS side clamps width/left to the viewport. */
.tour-overlay{ position:fixed; inset:0; z-index:200; }
.tour-spotlight{ position:fixed; border-radius:14px; box-shadow:0 0 0 9999px rgba(15,18,22,.72); transition:all .2s ease; pointer-events:none; }
.tour-tooltip{ position:fixed; background:var(--surface); color:var(--ink); border-radius:16px; padding:16px; box-shadow:0 12px 32px rgba(0,0,0,.35); z-index:201; box-sizing:border-box; }
.tour-dots{ display:flex; gap:5px; margin-bottom:10px; }
.tour-dots span{ width:6px; height:6px; border-radius:50%; background:var(--line); flex:none; }
.tour-dots span.active{ background:var(--route); }
.tour-title{ font-weight:700; font-size:calc(15px * var(--text-scale)); margin-bottom:6px; }
.tour-text{ font-size:calc(13px * var(--text-scale)); color:var(--muted); line-height:1.45; margin-bottom:14px; }
.tour-actions{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.tour-skip{ font-size:calc(12.5px * var(--text-scale)); color:var(--muted); padding:0; flex:none; }
.tour-next{ padding:8px 18px; font-size:calc(13px * var(--text-scale)); flex:none; }

.fee-note{ background:var(--control-fill); border:1px solid var(--line); border-radius:14px; padding:14px 16px; margin:2px 0 16px; }
.fee-note .row{ display:flex; justify-content:space-between; font-size:calc(13px * var(--text-scale)); color:var(--muted); }
.total-note{ background:var(--control-fill); border:1px solid var(--line); border-radius:14px; padding:14px 16px; margin-bottom:16px; }
.total-note .row{ display:flex; justify-content:space-between; font-size:calc(15.5px * var(--text-scale)); font-weight:700; }

.seat-stepper{ display:flex; align-items:center; justify-content:space-between; background:var(--field-bg); border:1px solid var(--line); border-radius:13px; padding:5px; }
.seat-stepper button{ width:34px; height:34px; border-radius:50%; border:1.5px solid var(--line); background:var(--control-fill); font-size:18px; font-weight:700; color:var(--ink); cursor:pointer; }

/* Cabin-seat-picker (requested 01.09.2026) — replaces the seat-stepper
   above in the passenger's own request sheet specifically (the driver
   still uses seat-stepper for total-seats-when-publishing, unrelated).
   Visual language matches the standalone mockup discussed the same day
   (https://claude.ai/code/artifact/14935568-7a68-46d9-b2c9-6c65fd9921cd),
   built from this app's own tokens directly rather than copied values. */
.cabin-wrap{ display:flex; justify-content:center; margin:6px 0 16px; }
.cabin{ position:relative; width:230px; background:var(--control-fill); border:1.5px solid var(--line); border-radius:26px 26px 34px 34px; padding:20px 16px 22px; }
.cabin .windshield{ position:absolute; top:-1.5px; left:50%; transform:translateX(-50%); width:120px; height:14px; background:var(--surface); border:1.5px solid var(--line); border-top:none; border-radius:0 0 40px 40px; }
.cabin .cabin-row{ display:flex; justify-content:center; gap:14px; }
.cabin .cabin-row + .cabin-row{ margin-top:16px; }
.cabin .cabin-row.front{ justify-content:space-between; padding:0 6px; }
.cabin-seat{
  width:54px; height:54px; border-radius:14px 14px 8px 8px; display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-weight:600; font-size:calc(13px * var(--text-scale)); cursor:pointer; user-select:none;
  border:1.5px solid var(--line); background:var(--surface); color:var(--muted); position:relative;
  transition:transform .12s ease, background .12s ease, border-color .12s ease, color .12s ease;
}
.cabin-seat:hover:not(.taken){ transform:translateY(-2px); border-color:var(--route); }
/* Same fixed-white reasoning as .cabin-seat.selected::after below —
   the seat NUMBER on a selected (blue) seat has the identical
   near-unreadable dark-on-blue problem in the dark theme via
   --on-route, fixed here too for the same "понятной белой" ask. */
.cabin-seat.selected{ background:var(--route); border-color:var(--route); color:#fff; }
/* Значок «забронировано» на выбранном месте (requested 02.09.2026) —
   чуть крупнее/жирнее прежнего, и цвет самой галочки зафиксирован белым
   намеренно, не через --on-route: в тёмной теме --on-route почти чёрный
   (подобран для .chip-accept на своём фоне), на синем кружке значка это
   читалось почти нечитаемо — здесь нужен гарантированно белый цвет в
   обеих темах, не то же значение, что у --on-route. */
.cabin-seat.selected::after{ content:'✓'; position:absolute; top:-7px; right:-7px; width:20px; height:20px; border-radius:50%; background:var(--route); color:#fff; font-size:11px; font-weight:800; display:flex; align-items:center; justify-content:center; border:2.5px solid var(--surface); }
.cabin-seat.taken{ background:var(--seat-taken); border-color:var(--seat-taken); color:var(--muted); cursor:not-allowed; }
.cabin-seat.taken::after{ content:''; position:absolute; inset:0; background:repeating-linear-gradient(135deg, transparent, transparent 4px, rgba(0,0,0,.06) 4px, rgba(0,0,0,.06) 5px); border-radius:inherit; }
.cabin-seat.driver{ background:transparent; border-style:dashed; color:var(--muted-2); cursor:default; font-size:17px; }
.cabin-legend{ display:flex; justify-content:center; gap:16px; margin-top:14px; flex-wrap:wrap; }
.cabin-legend .item{ display:flex; align-items:center; gap:6px; font-size:calc(11.5px * var(--text-scale)); color:var(--muted); }
.cabin-legend .dot{ width:12px; height:12px; border-radius:4px; border:1.5px solid var(--line); background:var(--surface); flex:none; }
.cabin-legend .dot.selected{ background:var(--route); border-color:var(--route); }
.cabin-legend .dot.taken{ background:var(--seat-taken); border-color:var(--seat-taken); }
.whole-cabin-btn{
  font-family:var(--font-body); font-weight:600; font-size:calc(12.5px * var(--text-scale)); color:var(--route-dark);
  background:var(--route-tint); border:none; border-radius:var(--radius-pill);
  padding:7px 13px; cursor:pointer; display:flex; align-items:center; gap:5px;
}
.whole-cabin-btn.on{ background:var(--ink-solid); color:#fff; }
@media (prefers-reduced-motion: reduce){ .cabin-seat{ transition:none; } .cabin-seat:hover{ transform:none; } }

.request-row{ border:1px solid var(--line); border-radius:12px; padding:12px; display:flex; flex-direction:column; gap:8px; }

.card-option{ text-align:left; border:1.5px solid var(--line); background:var(--surface); border-radius:12px; padding:12px 14px; font-family:var(--font-mono); font-size:calc(13.5px * var(--text-scale)); cursor:pointer; }
.card-option.selected{ border-color:var(--route); background:var(--route-tint); }
.progress-bar{ height:6px; border-radius:4px; background:var(--line); margin-bottom:16px; overflow:hidden; }
.progress-bar .fill{ height:100%; background:var(--route); }

.notif-item{ background:var(--control-fill); border-left:3px solid var(--line); border-radius:0 14px 14px 0; padding:12px 14px; }
.notif-item .time{ font-size:calc(11px * var(--text-scale)); color:var(--muted); margin-top:4px; font-family:var(--font-mono); }

/* ============================================================
   Redesign component library (26.08.2026, handoff/msgo.css) —
   additive: new semantic classes for new/updated markup. Existing
   classes above (.ticket, .segmented, .field, .sheet-header etc.) are
   NOT removed — still load-bearing for markup not yet migrated.
   Where a name collides with an existing one (.sheet, .toast), the
   rule below wins by source order and only tightens color/radius/
   shadow to the new tokens — it does not change structure.
   ============================================================ */
.t-display{ font-family:var(--font-display); font-size:1.75rem; line-height:1.15; font-weight:600; letter-spacing:-.02em; }
.t-title{ font-family:var(--font-display); font-size:1.25rem; line-height:1.25; font-weight:600; letter-spacing:-.01em; }
.t-head{ font-family:var(--font-display); font-size:1rem; line-height:1.3; font-weight:600; }
.t-body{ font-size:.94rem; line-height:1.45; }
.t-sub{ font-size:.81rem; line-height:1.4; color:var(--muted); }
.t-cap{ font-size:.69rem; line-height:1.3; color:var(--muted-2); font-family:var(--font-mono); letter-spacing:.06em; text-transform:uppercase; }
.t-num{ font-family:var(--font-mono); font-feature-settings:"tnum" 1; letter-spacing:-.01em; }

.btn-secondary{ border:1px solid var(--line); color:var(--ink); background:var(--surface); }
.btn-secondary:hover{ border-color:var(--route); color:var(--route); }
.btn-sm{ min-height:38px; font-size:calc(.84rem * var(--text-scale)); padding:0 var(--s4); }
.btn-icon{ min-height:44px; width:44px; padding:0; border-radius:var(--r-pill); color:var(--ink); background:none; border:none; display:inline-flex; align-items:center; justify-content:center; cursor:pointer; }
.btn-icon:hover{ background:var(--paper); }

.chip-wait{ background:var(--fare-tint); color:var(--fare); }
.chip-accept{ background:var(--route); color:var(--on-route); }
.chip-done{ background:var(--control-fill); color:var(--muted); border:1px solid var(--line); }
.chip-cancel{ background:transparent; color:var(--muted-2); border:1px solid var(--line); }
.chip-verified{ background:var(--route-tint); color:var(--route); font-family:var(--font-body); font-size:.72rem; letter-spacing:0; text-transform:none; font-weight:600; padding:4px 9px 4px 7px; border-radius:var(--r-pill); display:inline-flex; align-items:center; gap:4px; }
.chip-toggle{ border:1px solid var(--line); background:var(--surface); color:var(--muted); font-family:var(--font-body); font-size:.78rem; font-weight:600; padding:0 12px; min-height:34px; border-radius:var(--r-pill); display:inline-flex; align-items:center; gap:7px; cursor:pointer; }
.chip-toggle.on{ border-color:var(--route); background:var(--route-tint); color:var(--route); }
.chip-toggle .dot{ width:7px; height:7px; border-radius:50%; background:var(--muted-2); flex:none; }
.chip-toggle.on .dot{ background:var(--route); }

.card{ background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); padding:var(--s4); }
.card-active{ border-color:var(--route); background:linear-gradient(180deg,var(--route-tint),var(--surface) 62%); overflow:hidden; position:relative; padding-top:calc(var(--s4) + 3px); }
.card-active::before{ content:''; position:absolute; top:0; left:0; right:0; height:3px; background:var(--route); }

/* Route rail: two-level from → to (district, region below) — for
   markup migrated off the flat .route-line string pattern. */
.route{ display:grid; grid-template-columns:14px 1fr; column-gap:10px; align-items:start; }
.rail{ display:flex; flex-direction:column; align-items:center; padding-top:6px; }
.rail i{ width:8px; height:8px; border-radius:50%; background:var(--route); display:block; }
.rail i.end{ background:transparent; border:2px solid var(--route); width:9px; height:9px; }
.rail span{ flex:1; width:1px; background:var(--line); min-height:18px; margin:3px 0; }
.route-city{ font-family:var(--font-display); font-size:1.06rem; font-weight:600; line-height:1.28; }
.route-reg{ font-size:.81rem; line-height:1.35; color:var(--muted); }

.input{ width:100%; min-height:50px; border-radius:var(--r-field); border:1px solid var(--line); background:var(--surface); color:var(--ink); padding:0 var(--s4); font-family:var(--font-body); font-size:.94rem; }
.input.mono{ font-family:var(--font-mono); letter-spacing:.02em; }
.input:focus{ outline:none; border-color:var(--route); box-shadow:0 0 0 3px var(--route-tint); }
.seg{ display:flex; background:var(--paper); border:1px solid var(--line); border-radius:var(--r-pill); padding:3px; gap:2px; }
.seg-opt{ flex:1; min-height:38px; border:0; background:none; border-radius:var(--r-pill); font-family:var(--font-body); font-size:.84rem; font-weight:600; color:var(--muted); cursor:pointer; display:flex; align-items:center; justify-content:center; gap:6px; }
.seg-opt[aria-selected="true"]{ background:var(--surface); color:var(--ink); box-shadow:var(--lift-card); }
/* .role-opt (added 04.09.2026) — the Пассажир/Водитель role picker on
   the auth screen is a .seg-opt too, but the redesign handoff
   explicitly keeps it solid-filled rather than the floating-tab style
   every other .seg uses (see msgo-redesign-handoff.md step 2.2's
   exception). Same specificity as the rule above (one class + one
   attribute selector each) — wins by coming later in source order,
   no !important needed. */
.role-opt[aria-selected="true"]{ background:var(--route); color:#fff; box-shadow:none; }

.choice{ display:flex; gap:var(--s3); align-items:center; width:100%; text-align:left; background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); padding:14px var(--s4); cursor:pointer; color:var(--ink); font-family:var(--font-body); font-size:.9rem; min-height:56px; }
.choice:hover{ border-color:var(--route); }
.choice[aria-checked="true"]{ border-color:var(--route); background:var(--route-tint); }
.radio{ width:20px; height:20px; border-radius:50%; border:1.5px solid var(--muted-2); flex:none; display:grid; place-items:center; }
.choice[aria-checked="true"] .radio{ border-color:var(--route); }
.choice[aria-checked="true"] .radio::after{ content:''; width:10px; height:10px; border-radius:50%; background:var(--route); }

.notice{ border:1px solid var(--line); background:var(--fare-tint); border-radius:var(--r-card); padding:var(--s3) var(--s4); }
.stat{ background:var(--surface); border:1px solid var(--line); border-radius:var(--r-card); padding:var(--s3) var(--s4); flex:1; }
.balance{ background:var(--ink-solid); color:var(--on-ink); border-radius:var(--r-card); padding:var(--s5); }

/* Value-only overrides of existing structural classes — same
   selectors as above in this file, later in source order so these
   tighten color/radius/shadow without touching markup structure
   (.sheet-header/.sheet-content/.sheet-grip stay as-is). */
.sheet{ background:var(--surface); }
.toast{ color:var(--on-ink); border-radius:14px; }

/* SMS-code 4-cell input (redesign 26.08.2026, handoff/HANDOFF.md item 2) */
.code-cells{ display:flex; gap:10px; margin-bottom:20px; }
.code-cell{ width:58px; height:58px; border-radius:var(--r-field); border:1.5px solid var(--line); background:var(--surface); color:var(--ink); font-family:var(--font-mono); font-size:24px; font-weight:600; text-align:center; padding:0; }
.code-cell:focus{ outline:none; border-color:var(--route); box-shadow:0 0 0 3px var(--route-tint); }
