/* ─────────────────────────────────────────────────────────────────────────────
   Doppi Taxi Mini App — design system (2026-09-22 redesign)

   Telegram-native iOS-style: grouped inset cards, 5-item bottom tab bar,
   dark + light palettes. Token names/values come straight from the design
   mockups (docs/web-app-redizayn.html) — do not rename them.

   Theme: dark by default; `html[data-theme="light"]` switches. init() picks the
   theme from Telegram's colorScheme and follows themeChanged.
   ──────────────────────────────────────────────────────────────────────────── */

:root {
  --bg: #0E1621;
  --sec: #17212B;
  --sep: #243140;
  --txt: #F5F7FA;
  --hint: #8596A8;
  --link: #6AB3F3;
  --btn: #2F74B5;
  --field: #242F3D;
  --seg: #1F2A36;
  --segOn: #3A4A5E;
  --segTxt: #B4C0CC;
  --segShadow: none;
  --red: #EF7A7A;
  --redBg: rgba(236, 107, 107, 0.15);
  --green: #63C872;
  --greenBg: rgba(92, 196, 106, 0.15);
  --warn: #E8B04A;
  --warnBg: rgba(232, 169, 58, 0.13);
  --blueBg: rgba(106, 179, 243, 0.13);
  --tab: #17212B;
  --tabBorder: #0A1118;
  --chev: #56687A;
  --off: #3A4756;
  --on: #4CAF63;
  --overlay: rgba(0, 0, 0, 0.55);
  --sheet: #0E1621;
}

html[data-theme="light"] {
  --bg: #EFEFF4;
  --sec: #FFFFFF;
  --sep: #E1E1E6;
  --txt: #101114;
  --hint: #6B6B72;
  --link: #1C72BF;
  --btn: #1F74C0;
  --field: #EDEDF1;
  --seg: #E3E3E8;
  --segOn: #FFFFFF;
  --segTxt: #4A4A52;
  --segShadow: 0 1px 3px rgba(0, 0, 0, 0.14);
  --red: #D23B3B;
  --redBg: rgba(210, 59, 59, 0.10);
  --green: #23873A;
  --greenBg: rgba(35, 135, 58, 0.11);
  --warn: #9A6208;
  --warnBg: rgba(245, 166, 35, 0.16);
  --blueBg: rgba(28, 114, 191, 0.09);
  --tab: #F8F8FA;
  --tabBorder: #D9D9DE;
  --chev: #BDBDC3;
  --off: #E3E3E8;
  --on: #34C759;
  --overlay: rgba(0, 0, 0, 0.35);
  --sheet: #EFEFF4;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body { height: 100%; }

body {
  background: var(--bg);
  color: var(--txt);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--link); }

/* ── App shell ────────────────────────────────────────────────────────────── */

.app { min-height: 100%; display: flex; flex-direction: column; }

.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 16px 10px;
}
.page-header h1 { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; }

/* sub-page header: back chevron + title */
.page-header.sub { align-items: center; padding-top: 14px; }
.page-header.sub h1 { font-size: 22px; }

.hdr-btn {
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: 50%; border: 0;
  background: var(--sec); color: var(--link);
  display: flex; align-items: center; justify-content: center;
}
.hdr-btn.plain { background: none; width: 36px; height: 44px; justify-content: flex-start; }
.hdr-btn:active { opacity: 0.6; }
.hdr-actions { display: flex; align-items: center; gap: 8px; }

.page-main {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 16px 16px calc(110px + env(safe-area-inset-bottom, 0px));
}

/* ── Section: uppercase caption + rounded card ────────────────────────────── */

.sec-cap {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px;
  padding: 0 16px 7px;
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--hint);
}
.sec-cap button {
  background: none; border: 0; color: var(--link);
  font-size: 13px; text-transform: none; letter-spacing: 0;
}
.card { background: var(--sec); border-radius: 12px; overflow: hidden; }
.card-pad { padding: 16px; }
.sec-note { padding: 7px 16px 0; font-size: 13px; line-height: 1.4; color: var(--hint); }

/* ── Inset list rows ──────────────────────────────────────────────────────── */

.row {
  display: flex; align-items: center; gap: 14px;
  padding-left: 16px;
  text-decoration: none; color: var(--txt); text-align: left;
  background: none; border: 0; width: 100%;
}
.row:active { background: var(--field); }
.row-ic {
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: 8px; color: #FFFFFF;
  display: flex; align-items: center; justify-content: center;
}
.row-body {
  flex-grow: 1; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  min-height: 48px;
  padding: 8px 14px 8px 0;
  box-sizing: border-box;
}
.row + .row > .row-body,
.row-sep > .row-body { border-top: 1px solid var(--sep); }
/* …but never on the first row of a card, whatever `sep` the caller passed. */
.card > .row:first-child > .row-body { border-top: 0; }
.row-txt { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.row-title { font-size: 16px; font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-sub { font-size: 13px; color: var(--hint); overflow: hidden; text-overflow: ellipsis; }
.row-sub.wrap { white-space: normal; }
.row-val {
  font-size: 16px; color: var(--hint);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.chev { color: var(--chev); display: flex; flex-shrink: 0; }
.row-act { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
/* A row whose body stacks text above its own action buttons (e.g. a pending-transfer row with
   three actions that would not fit beside the title) — a MODIFIER on .row-body, never a
   replacement for it, so the separator/first-row rules above still apply. */
.row-body.row-stack { flex-direction: column; align-items: stretch; gap: 8px; padding: 12px 16px 12px 0; }

/* ── Picker result (a search-result row that opens as a plain, unstyled button) ───────────────── */
.pick-card { width: 100%; border: 0; text-align: left; }
/* A display name is whatever the person typed into their Telegram profile, so it can be one
   unbreakable run with nowhere to wrap (a long emoji or cuneiform string). Measured before this
   rule: such a name spilled 1551px past the card, straight across the screen. Clip it to the
   card — the same thing .p-name/.p-sub already do for the list this picker is opened from. */
.pick-card > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Stat grid ────────────────────────────────────────────────────────────── */

.stats {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  row-gap: 18px; column-gap: 12px;
}
.stat { display: flex; flex-direction: column; gap: 2px; text-align: left; background: none; border: 0; }
.stat-num { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--txt); }
.stat-lbl { font-size: 13px; color: var(--hint); }
.stat.tap:active { opacity: 0.55; }
/* Three figures in one row (the Daromad page) — smaller numbers so 9-digit sums still fit a phone. */
.stats.three { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 8px; }
.stats.three .stat-num { font-size: 18px; }

/* ── Segmented control ────────────────────────────────────────────────────── */

.seg {
  display: flex; gap: 2px;
  background: var(--seg); border-radius: 9px; padding: 2px;
}
.seg button {
  flex: 1 1 0; min-width: 0;
  border: 0; border-radius: 7px; background: none;
  padding: 7px 4px;
  font-size: 13px; font-weight: 500; color: var(--segTxt);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.seg button.on { background: var(--segOn); color: var(--txt); font-weight: 600; box-shadow: var(--segShadow); }
.seg-wrap { padding: 0 0 4px; }

/* ── Switch ───────────────────────────────────────────────────────────────── */

.sw {
  position: relative; width: 51px; height: 31px; flex-shrink: 0;
  border-radius: 16px; border: 0; padding: 0; background: var(--off);
  transition: background 0.18s ease;
}
.sw .knob {
  position: absolute; top: 2px; left: 2px;
  width: 27px; height: 27px; border-radius: 50%;
  background: #FFFFFF; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: left 0.18s ease;
}
.sw.on { background: var(--on); }
.sw.on .knob { left: 22px; }
.sw[disabled] { opacity: 0.5; }

/* ── Fields ───────────────────────────────────────────────────────────────── */

.field {
  width: 100%;
  background: var(--field); color: var(--txt);
  border: 0; border-radius: 10px;
  padding: 12px 14px;
  font-size: 16px;
  outline: none;
}
.field::placeholder { color: var(--hint); }
.field:focus { box-shadow: inset 0 0 0 1.5px var(--link); }
textarea.field { min-height: 92px; resize: vertical; line-height: 1.4; }
select.field { appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, var(--hint) 50%), linear-gradient(135deg, var(--hint) 50%, transparent 50%);
  background-position: calc(100% - 18px) 21px, calc(100% - 13px) 21px;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.field-lbl { font-size: 13px; color: var(--hint); padding: 0 2px 6px; display: block; }
.form { display: flex; flex-direction: column; gap: 12px; }
.form-row { display: flex; gap: 10px; }
.form-row > * { flex: 1 1 0; min-width: 0; }

.search {
  display: flex; align-items: center; gap: 8px;
  background: var(--field); border-radius: 10px;
  padding: 0 12px;
}
.search svg { color: var(--hint); flex-shrink: 0; }
.search input { flex-grow: 1; min-width: 0; background: none; border: 0; outline: none; padding: 11px 0; font-size: 16px; }
.search input::placeholder { color: var(--hint); }

/* ── Buttons ──────────────────────────────────────────────────────────────── */

.btn {
  width: 100%;
  border: 0; border-radius: 10px;
  background: var(--btn); color: #FFFFFF;
  padding: 13px 16px;
  font-size: 16px; font-weight: 600;
  display: flex; align-items: center; justify-content: center; gap: 8px;
}
.btn:active { opacity: 0.75; }
.btn[disabled] { opacity: 0.55; }
.btn.sec { background: var(--sec); color: var(--link); }
.btn.danger { background: var(--redBg); color: var(--red); }
.btn.ghost { background: none; color: var(--link); padding: 10px 0; }

.mini {
  border: 0; border-radius: 8px;
  background: var(--field); color: var(--link);
  padding: 7px 12px; font-size: 14px; font-weight: 500;
  white-space: nowrap;
}
.mini.danger { color: var(--red); background: var(--redBg); }
.mini.primary { background: var(--btn); color: #fff; }
.mini:active { opacity: 0.7; }

/* ── Badges / chips ───────────────────────────────────────────────────────── */

.badge {
  display: inline-flex; align-items: center; gap: 4px;
  border-radius: 6px; padding: 3px 8px;
  font-size: 12px; font-weight: 600; white-space: nowrap;
  background: var(--field); color: var(--hint);
}
.badge.green { background: var(--greenBg); color: var(--green); }
.badge.red { background: var(--redBg); color: var(--red); }
.badge.warn { background: var(--warnBg); color: var(--warn); }
.badge.blue { background: var(--blueBg); color: var(--link); }
.badges { display: flex; flex-wrap: wrap; gap: 6px; }

/* ── Avatar ───────────────────────────────────────────────────────────────── */

.ava {
  width: 38px; height: 38px; flex-shrink: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 600; color: #fff;
}

/* ── Empty / loading / error ──────────────────────────────────────────────── */

.empty {
  padding: 36px 20px; text-align: center;
  color: var(--hint); font-size: 15px; line-height: 1.45;
}
.empty .big { display: block; font-size: 30px; margin-bottom: 10px; opacity: 0.7; }

.spinner {
  width: 26px; height: 26px; margin: 40px auto;
  border: 2.5px solid var(--sep); border-top-color: var(--link);
  border-radius: 50%; animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.err-box {
  background: var(--redBg); color: var(--red);
  border-radius: 10px; padding: 12px 14px; font-size: 14px; line-height: 1.4;
}

/* ── Bottom tab bar ───────────────────────────────────────────────────────── */

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  height: calc(82px + env(safe-area-inset-bottom, 0px));
  box-sizing: border-box;
  padding: 6px 4px calc(22px + env(safe-area-inset-bottom, 0px));
  background: var(--tab); border-top: 1px solid var(--tabBorder);
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
}
.tabbar button {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: none; border: 0;
  font-size: 11px; font-weight: 500; color: var(--hint);
  overflow: hidden;
}
.tabbar button span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tabbar button.on { color: var(--link); font-weight: 600; }

/* ── Modal / bottom sheet ─────────────────────────────────────────────────── */

.overlay {
  position: fixed; inset: 0; z-index: 60;
  background: var(--overlay);
  display: flex; align-items: flex-end; justify-content: center;
}
.overlay.hidden { display: none; }
.sheet {
  width: 100%; max-height: 88vh; overflow-y: auto;
  background: var(--sheet);
  border-radius: 16px 16px 0 0;
  padding: 10px 16px calc(24px + env(safe-area-inset-bottom, 0px));
  animation: sheet-up 0.22s ease;
}
@keyframes sheet-up { from { transform: translateY(24px); opacity: 0.6; } to { transform: none; opacity: 1; } }
.sheet-grip { width: 36px; height: 5px; border-radius: 3px; background: var(--sep); margin: 0 auto 12px; }
.sheet-hdr {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-bottom: 12px;
}
.sheet-hdr h2 { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; }
.sheet-x { background: none; border: 0; color: var(--hint); font-size: 22px; line-height: 1; padding: 2px 4px; }
.sheet-body { display: flex; flex-direction: column; gap: 18px; }

/* ── Toast ────────────────────────────────────────────────────────────────── */

.toast {
  position: fixed; left: 16px; right: 16px; z-index: 80;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  background: var(--sec); color: var(--txt);
  border-radius: 12px; padding: 12px 16px;
  font-size: 14px; line-height: 1.4;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
  animation: sheet-up 0.2s ease;
}
.toast.err { color: var(--red); }

/* ── Pagination ───────────────────────────────────────────────────────────── */

.pager {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 4px 0;
  font-size: 14px; color: var(--hint);
}
.pager button {
  background: var(--field); border: 0; border-radius: 8px;
  color: var(--link); padding: 7px 12px; font-size: 14px;
}
.pager button[disabled] { opacity: 0.4; color: var(--hint); }

/* ── Misc helpers ─────────────────────────────────────────────────────────── */

.mono { font-variant-numeric: tabular-nums; }
.muted { color: var(--hint); }
.small { font-size: 13px; line-height: 1.4; }
.hidden { display: none !important; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.grow { flex-grow: 1; min-width: 0; }
.warn-banner {
  background: var(--warnBg); color: var(--warn);
  border-radius: 10px; padding: 11px 14px; font-size: 13px; line-height: 1.45;
}
.kv { display: flex; justify-content: space-between; gap: 12px; font-size: 15px; padding: 7px 0; }
.kv + .kv { border-top: 1px solid var(--sep); }
.kv .k { color: var(--hint); }
.kv .v { text-align: right; word-break: break-word; }
pre.trace {
  background: var(--field); border-radius: 10px; padding: 12px;
  font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre-wrap; word-break: break-word; max-height: 320px; overflow: auto;
  color: var(--txt);
}

/* ── List primitives extracted from per-row inline styles (2026-09-23) ──────
   Rendering hundreds of rows with ~600 bytes of inline style each cost ~8× the
   HTML; these carry the same look as classes. */

.ok-box {
  background: var(--greenBg); color: var(--green);
  border-radius: 10px; padding: 12px 14px; font-size: 14px; line-height: 1.4;
}

/* keyword chip */
.kw-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--field); border-radius: 8px;
  padding: 7px 8px 7px 11px; font-size: 14px; max-width: 100%;
}
.kw-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kw-chip button {
  border: 0; background: none; color: var(--chev);
  display: flex; align-items: center; padding: 2px; flex-shrink: 0;
}
.kw-chip button:active { color: var(--red); }
.kw-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 16px; }

/* person row (drivers list, VIP people) */
.p-row { display: flex; align-items: center; gap: 12px; padding: 0 12px 0 16px; }
.p-row + .p-row { border-top: 1px solid var(--sep); }
.p-row > .p-main {
  flex-grow: 1; min-width: 0; display: flex; align-items: center; gap: 12px;
  min-height: 64px; padding: 9px 0; background: none; border: 0; text-align: left; color: var(--txt);
}
.p-row .ava.lg { width: 44px; height: 44px; font-size: 16px; }
.p-txt { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.p-name { font-size: 16px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.p-sub { font-size: 13px; color: var(--hint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.p-tg {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 50%;
  background: var(--blueBg); color: var(--link);
  display: flex; align-items: center; justify-content: center;
}
.p-tg:active { opacity: 0.6; }
/* name + inline badge line, and the @username accent used in person rows */
.p-nameline { display: flex; align-items: center; gap: 6px; min-width: 0; }
.p-at { color: var(--link); }

/* Fast ping page (page_fastping.js) */
.fp-nums { display: flex; gap: 8px; margin-top: 12px; }
.fp-n { flex: 1; min-width: 0; background: var(--bg); border-radius: 10px; padding: 8px 9px;
        display: flex; flex-direction: column; gap: 1px; font-size: 11px; }
.fp-n b { font-size: 17px; font-weight: 700; }
.fp-up { color: var(--green); }
.fp-down { color: var(--red); }
.fp-vd { margin-top: 10px; padding: 8px 10px; border-radius: 10px; font-size: 13px; line-height: 1.35;
         background: var(--bg); color: var(--hint); }
.fp-vd.green { background: var(--greenBg); color: var(--green); }
.fp-vd.warn { background: var(--warnBg); color: var(--warn); }
.fp-vd.red { background: var(--redBg); color: var(--red); }

/* ── Browser (outside Telegram): login + a phone-width column on desktop ───── */

.login { max-width: 380px; margin: 0 auto; padding: 72px 16px 32px; text-align: center; }
.login h1 { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; margin-top: 14px; }
.login-sub { color: var(--hint); font-size: 15px; margin: 4px 0 24px; }
.login-logo {
  width: 64px; height: 64px; margin: 0 auto; border-radius: 18px;
  background: var(--btn); color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.login .form { text-align: left; }

html.web .app { max-width: 560px; margin: 0 auto; width: 100%; }
html.web .tabbar { max-width: 560px; margin: 0 auto; }
html.web .sheet { max-width: 560px; margin-left: auto; margin-right: auto; }
