/* ============================================================================
   Serveo — design system extensions
   Loaded after design.css, which is the token set and primitives ported
   verbatim from the supplied Customer and Driver PWA packages.

   This file adds only what the supplied packages did not cover, and which the
   specification requires:
     * Full RTL mirroring using logical properties (spec 314)
     * The Branch portal and HQ console, built on the same tokens (spec 322)
     * Login, address book, cancellation and offline states, which the design
       handoff explicitly flagged as not yet designed
   Nothing here introduces a second visual language. Every value resolves to a
   token already defined in design.css.
============================================================================ */

/* ------------------------------------------------------------ RTL mirroring
   Logical properties mean the entire interface flips — navigation, icons,
   progress indicators, timelines — rather than merely translating text inside
   a left-to-right layout. */
[dir="rtl"] { direction: rtl; }
[dir="rtl"] .appbar__back svg,
[dir="rtl"] .chev,
[dir="rtl"] .arrow { transform: scaleX(-1); }
[dir="rtl"] .step__rail { inset-inline-start: 5px; inset-inline-end: auto; }
[dir="rtl"] .progress > i { inset-inline-start: 0; }
[dir="rtl"] .switch { transform: scaleX(-1); }

/* Eastern Arabic numerals, selectable per user (spec 316). */
.numerals-eastern { font-feature-settings: "numr"; }
[lang="ar"].numerals-eastern .num { font-variant-numeric: ordinal; }

/* ------------------------------------------------------------ app scaffold */
html, body { height: 100%; }
body.app {
  background: var(--bg);
  margin: 0;
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
}
.app-shell {
  max-width: 480px;
  margin-inline: auto;
  min-height: 100dvh;
  background: var(--bg);
  position: relative;
  padding-bottom: env(safe-area-inset-bottom);
}
.screen { display: none; }
.screen.is-active { display: block; }
.pad { padding-inline: 20px; }
.spacer { height: 96px; }

/* --------------------------------------------------------------- app bar */
.appbar {
  padding: calc(14px + env(safe-area-inset-top)) 20px 14px;
  background: var(--surface);
  display: flex; align-items: center; gap: 12px;
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 40;
}
.appbar--dark { background: var(--ink); color: #fff; border-bottom-color: transparent; }
.appbar__logo { width: 47px; height: 15px; align-self: flex-start; object-fit: contain; }
.appbar__title { font-family: var(--font-display); font-size: 20px; line-height: 1.15; }
.appbar__sub { font-size: 10.5px; color: var(--ink-55); }
.appbar--dark .appbar__sub { color: rgba(255,255,255,.6); }
.appbar__back {
  width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--line);
  display: grid; place-items: center; background: var(--surface); cursor: pointer;
}

/* --------------------------------------------------------------- controls */
.btn {
  height: 48px; border-radius: 13px; border: 0; width: 100%;
  font-family: var(--font-ui); font-size: 14px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer; transition: transform .12s ease, opacity .12s ease;
}
.btn:active { transform: scale(.985); }
.btn--primary { background: var(--brand); color: #fff; box-shadow: var(--sh-brand); }
.btn--dark { background: var(--ink); color: #fff; }
.btn--ghost { background: transparent; color: var(--ink); border: 1px solid var(--line-strong); }
.btn--quiet { background: var(--page); color: var(--ink); }
.btn[disabled], .btn.is-disabled {
  background: rgba(21,21,21,.14); color: #fff; box-shadow: none; cursor: not-allowed;
}
.btn-row { display: flex; gap: 10px; }

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-xl); padding: 14px; box-shadow: var(--sh-card);
}
.card--dark { background: var(--ink); color: #fff; border-color: transparent; }
.card--tint { background: var(--brand-tint); border-color: rgba(192,39,45,.18); }
.card--dashed { background: transparent; border: 1.5px dashed var(--line-strong); box-shadow: none; }
.card + .card { margin-top: 12px; }

.eyebrow {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-42);
}
.eyebrow--light { color: rgba(255,255,255,.55); }
.display { font-family: var(--font-display); font-size: 24px; line-height: 1.15; }
.display--lg { font-size: 30px; }
.small { font-size: 11.5px; color: var(--ink-55); }
.badge {
  display: inline-flex; align-items: center; gap: 4px; height: 20px;
  padding-inline: 8px; border-radius: var(--r-pill); background: var(--brand-tint);
  color: var(--brand); font-size: 9.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
}
.badge--dark { background: var(--ink); color: #fff; }
.badge--gold { background: var(--gold-tint); color: var(--gold); }

.chip-row { display: flex; gap: 8px; overflow-x: auto; padding-block: 4px; scrollbar-width: none; }
.chip-row::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto; height: 34px; padding-inline: 14px; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--surface);
  font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center;
}
.chip.is-active { background: var(--ink); color: #fff; border-color: var(--ink); }

/* Selected state is identical everywhere: 1.5px brand border, tint fill. */
.opt {
  border: 1.5px solid var(--line); border-radius: var(--r-md); padding: 12px;
  background: var(--surface); cursor: pointer; display: flex; align-items: center;
  gap: 10px; transition: none;
}
.opt.is-on { border-color: var(--brand); background: var(--brand-tint); }
.opt__t { font-size: 13px; font-weight: 700; }
.opt__d { font-size: 11.5px; color: var(--ink-55); }
.opt__radio, .opt__check {
  width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid var(--line-strong);
  flex: 0 0 auto; display: grid; place-items: center;
}
.opt__check { border-radius: 6px; }
.opt.is-on .opt__radio, .opt.is-on .opt__check { border-color: var(--brand); background: var(--brand); }
.opt.is-on .opt__radio::after { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #fff; }
.opt.is-on .opt__check::after { content: "✓"; color: #fff; font-size: 12px; line-height: 1; }
.opt-stack { display: grid; gap: 8px; }
.opt-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.opt-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.opt--pill { justify-content: center; text-align: center; padding: 10px 6px; }

.stepper { display: inline-flex; align-items: center; gap: 12px; }
.stepper button {
  width: 30px; height: 30px; border-radius: 9px; border: 0; background: var(--page);
  font-size: 16px; cursor: pointer; display: grid; place-items: center;
}
.stepper__v { min-width: 20px; text-align: center; font-weight: 700; font-size: 14px; }

.row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.row + .row { margin-top: 9px; }
.row__k { font-size: 12.5px; color: var(--ink-55); }
.row__v { font-size: 12.5px; font-weight: 600; }
.rule { height: 1px; background: var(--line); margin-block: 11px; }
.grow { flex: 1; min-width: 0; }

/* Placeholder photography. Every tile names the shot it needs, so the gap is
   explicit rather than discovered late. */
.thumb {
  border-radius: 13px; background:
    repeating-linear-gradient(135deg, var(--page) 0 8px, #EDE8E1 8px 16px);
  display: grid; place-items: center; text-align: center; overflow: hidden;
  font-family: var(--font-mono); font-size: 8px; color: var(--ink-35);
  padding: 4px; flex: 0 0 auto;
}
.thumb--44 { width: 44px; height: 44px; }
.thumb--52 { width: 52px; height: 52px; }
.thumb--78 { width: 78px; height: 78px; }
.thumb--hero { width: 100%; height: 250px; border-radius: 0; font-size: 10px; }

.dish { display: flex; gap: 12px; align-items: center; padding-block: 12px; cursor: pointer; }
.dish + .dish { border-top: 1px solid var(--line); }
.dish__name { font-size: 14px; font-weight: 700; }
.dish__desc {
  font-size: 11.5px; color: var(--ink-55); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.dish__foot { display: flex; align-items: center; justify-content: space-between; margin-top: 6px; }
.dish__price { font-size: 13.5px; font-weight: 800; }
.dish__add {
  height: 28px; padding-inline: 12px; border-radius: var(--r-sm); border: 0;
  background: var(--brand-tint); color: var(--brand); font-weight: 800;
  font-size: 10.5px; letter-spacing: .06em; cursor: pointer;
}
.dish.is-out { opacity: .45; }
.dish.is-out .dish__add { background: var(--page); color: var(--ink-42); }

/* ------------------------------------------------------------ tab bar */
.tabbar {
  position: sticky; bottom: 0; z-index: 40; background: var(--surface);
  border-top: 1px solid var(--line); display: grid;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
}
.tabbar--4 { grid-template-columns: repeat(4, 1fr); }
.tabbar--3 { grid-template-columns: repeat(3, 1fr); }
/* Five columns, for the custom-order tab. Same rule as the others; the label
   wraps rather than truncating, which is why the tab keeps its own line. */
.tabbar--5 { grid-template-columns: repeat(5, 1fr); }
.tab {
  min-height: 44px; display: grid; place-items: center; gap: 3px;
  font-size: 9.5px; font-weight: 600; color: var(--ink-42); cursor: pointer;
  background: none; border: 0;
}
.tab.is-active { color: var(--brand); }

.floating-cart {
  position: sticky; bottom: 74px; margin: 0 20px 12px; z-index: 45;
  background: var(--ink); color: #fff; border-radius: 13px; padding: 12px 16px;
  display: flex; align-items: center; justify-content: space-between;
  box-shadow: var(--sh-float); cursor: pointer;
}

/* -------------------------------------------------------------- timeline */
.steps { position: relative; padding-inline-start: 26px; }
.step { position: relative; padding-block: 9px; }
.step__dot {
  position: absolute; inset-inline-start: -26px; top: 12px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--line-strong);
}
.step.is-done .step__dot { background: var(--brand); border-color: var(--brand); }
.step__rail {
  position: absolute; inset-inline-start: -21px; top: 22px; bottom: -9px;
  width: 2px; background: var(--line);
}
.step.is-done .step__rail { background: var(--brand); }
.step:last-child .step__rail { display: none; }
.step__t { font-size: 12.5px; font-weight: 600; color: var(--ink-42); }
.step.is-done .step__t { color: var(--ink); }
.step__d { font-size: 10.5px; color: var(--ink-42); }

.pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--brand); animation: royPulse 1.7s infinite; }
.pulse--ok { background: var(--ok); }
@keyframes royPulse {
  0%   { box-shadow: 0 0 0 0 rgba(192,39,45,.45); }
  70%  { box-shadow: 0 0 0 9px rgba(192,39,45,0); }
  100% { box-shadow: 0 0 0 0 rgba(192,39,45,0); }
}

.progress { height: 6px; border-radius: 999px; background: rgba(255,255,255,.18); position: relative; overflow: hidden; }
.progress > i { position: absolute; inset-block: 0; inset-inline-start: 0; background: var(--gold); border-radius: 999px; }

/* ------------------------------------------------------------------ map
   Real map tiles when a Maps key is configured; otherwise this CSS map
   stands in, keeping the styling intent from the design package: muted olive
   land, white roads, brand-red route, red rider marker, black kitchen pin. */
.map {
  position: relative; overflow: hidden; background: var(--map-land);
  border-radius: var(--r-lg);
}
.map--tracking { height: 290px; border-radius: 0; }
.map--nav { height: 340px; }
.map--inset { height: 104px; }
.map__block { position: absolute; background: var(--map-block); border-radius: 3px; }
.map__block--warm { background: var(--map-block-warm); }
.map__park { position: absolute; background: var(--map-park); border-radius: 6px; }
.map__water { position: absolute; background: var(--map-water); }
.map__road { position: absolute; background: var(--map-road); }
.map__road-mid { position: absolute; background: var(--map-road-mid); }
.map__route {
  position: absolute; inset: 0; pointer-events: none;
}
.map__route path { fill: none; stroke: var(--brand); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.map__route path.trail { stroke: rgba(192,39,45,.28); }
.map__pin {
  position: absolute; width: 30px; height: 30px; border-radius: 50% 50% 50% 4px;
  transform: translate(-50%, -100%) rotate(-45deg); display: grid; place-items: center;
  box-shadow: var(--sh-float);
}
.map__pin > * { transform: rotate(45deg); }
.map__pin--kitchen { background: var(--ink); color: #fff; }
.map__pin--drop { background: var(--surface); color: var(--ink); border: 1.5px solid var(--ink); }
/* The marker glides across each interval rather than teleporting between
   updates. Without this the vehicle hops and the screen reads as fake. */
.map__rider {
  position: absolute; width: 32px; height: 32px; border-radius: 50%;
  background: var(--brand); color: #fff; display: grid; place-items: center;
  transform: translate(-50%, -50%); box-shadow: var(--sh-float);
  transition: inset-inline-start .9s linear, top .9s linear;
  will-change: inset-inline-start, top;
}
.map__rider > svg { transition: transform .5s ease; }
.map__controls { position: absolute; inset-block-start: 10px; inset-inline-end: 10px; display: grid; gap: 6px; }
.map__ctrl {
  width: 32px; height: 32px; border-radius: 9px; background: var(--surface);
  display: grid; place-items: center; box-shadow: var(--sh-float); cursor: pointer; border: 0;
}
.map__card {
  position: absolute; inset-block-end: 12px; inset-inline: 12px;
  background: var(--surface); border-radius: var(--r-lg); padding: 12px;
  box-shadow: var(--sh-float);
}
.map__scale {
  position: absolute; inset-block-end: 8px; inset-inline-start: 12px;
  font-family: var(--font-mono); font-size: 9px; color: var(--ink-42);
}
#leafletMap { height: 100%; width: 100%; }

/* ---------------------------------------------------------------- OTP pad */
.otp { display: flex; gap: 10px; justify-content: center; }
.otp__box {
  width: 54px; height: 64px; border-radius: var(--r-md); border: 1.5px solid var(--line);
  display: grid; place-items: center; font-size: 24px; font-weight: 700; background: var(--surface);
}
.otp__box.is-next { border-color: var(--brand); }
.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.keypad button {
  height: 54px; border-radius: var(--r-md); border: 0; background: var(--page);
  font-size: 20px; font-weight: 600; cursor: pointer;
}

.switch {
  width: 44px; height: 26px; border-radius: 999px; background: var(--line-strong);
  position: relative; cursor: pointer; flex: 0 0 auto; border: 0;
}
.switch::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
  border-radius: 50%; background: #fff; transition: left .18s ease;
}
.switch.is-on { background: var(--ink); }
.switch.is-on--brand { background: var(--brand); }
.switch.is-on::after { left: 21px; }

/* ========================================================== BRANCH PORTAL
   Designed for a screen mounted in a kitchen: large type, high contrast,
   readable from a metre away, minimal navigation depth. */
body.portal { background: var(--page); font-size: 15px; }
.portal-shell { display: grid; grid-template-rows: auto 1fr; min-height: 100dvh; }
.portal-bar {
  background: var(--ink); color: #fff; padding: 14px 22px;
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
}
.portal-bar__logo { width: 82px; height: 26px; object-fit: contain; }
.portal-bar__title { font-family: var(--font-display); font-size: 22px; }
.portal-body { padding: 20px; }

.queue { display: grid; grid-template-columns: repeat(5, minmax(230px, 1fr)); gap: 14px; }
.queue__col { background: var(--surface); border-radius: var(--r-lg); border: 1px solid var(--line); min-height: 260px; }
.queue__head {
  padding: 12px 14px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
}
.queue__title { font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.queue__count { background: var(--page); border-radius: 999px; padding: 2px 9px; font-size: 12px; font-weight: 700; }
.queue__list { padding: 10px; display: grid; gap: 10px; }

/* Kitchen ticket: one order per card, large type, allergens impossible to miss. */
.ticket { border: 1px solid var(--line); border-radius: var(--r-md); padding: 12px; background: var(--surface); }
.ticket.is-late { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-tint); }
.ticket__ref { font-family: var(--font-mono); font-size: 12px; color: var(--ink-55); }
.ticket__mode { font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.ticket__line { font-size: 16px; font-weight: 700; line-height: 1.35; }
.ticket__mods { font-size: 13px; color: var(--ink-70); }
.ticket__allergen { color: var(--brand); font-weight: 800; font-size: 12px; text-transform: uppercase; }
.ticket__age { font-size: 12px; color: var(--ink-42); }
.ticket__actions { display: flex; gap: 8px; margin-top: 10px; }
.ticket__actions .btn { height: 38px; font-size: 12.5px; }

/* ============================================================= HQ CONSOLE
   Dense, table-and-form heavy, built for people who live in it all day. */
body.console { background: var(--page); }
.console-shell { display: grid; grid-template-columns: 210px 1fr; min-height: 100dvh; }
.console-nav { background: var(--ink); color: #fff; padding: 18px 0; }
.console-nav__logo { width: 82px; height: 26px; margin: 0 18px 18px; object-fit: contain; }
.console-nav a {
  display: block; padding: 10px 18px; color: rgba(255,255,255,.68);
  text-decoration: none; font-size: 13px; font-weight: 600; cursor: pointer;
}
.console-nav a:hover { color: #fff; background: rgba(255,255,255,.06); }
.console-nav a.is-active { color: #fff; border-inline-start: 3px solid var(--brand); background: rgba(255,255,255,.08); }
.console-main { padding: 22px 26px; overflow: auto; }
.console-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; gap: 16px; flex-wrap: wrap; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 14px; }
.stat__v { font-family: var(--font-display); font-size: 27px; line-height: 1.1; }

table.grid { width: 100%; border-collapse: collapse; background: var(--surface); border-radius: var(--r-lg); overflow: hidden; }
table.grid th, table.grid td { padding: 10px 12px; text-align: start; font-size: 12.5px; border-bottom: 1px solid var(--line); }
table.grid th { background: var(--page); font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-55); }
table.grid tr:hover td { background: rgba(21,21,21,.02); }
table.grid tr.is-late td { background: var(--brand-tint); }
.bars { display: flex; align-items: flex-end; gap: 6px; height: 120px; }
.bars > i { flex: 1; background: var(--line-strong); border-radius: 4px 4px 0 0; min-height: 3px; }
.bars > i.peak { background: var(--brand); }

.input, select.input, textarea.input {
  height: 40px; border-radius: 10px; border: 1px solid var(--line-strong);
  padding-inline: 12px; font-family: var(--font-ui); font-size: 13px;
  background: var(--surface); width: 100%;
}
textarea.input { height: auto; padding-block: 10px; }
.field { display: grid; gap: 5px; }
.field label { font-size: 11px; font-weight: 700; color: var(--ink-55); text-transform: uppercase; letter-spacing: .05em; }

/* --------------------------------------------------- states that build trust
   Empty, loading, error and offline are designed, not skipped as edge cases.
   They are where trust is actually lost. */
.state { padding: 40px 20px; text-align: center; color: var(--ink-55); }
.state__title { font-family: var(--font-display); font-size: 19px; color: var(--ink); margin-bottom: 6px; }
.skeleton {
  background: linear-gradient(90deg, var(--page) 25%, #EFEAE4 37%, var(--page) 63%);
  background-size: 400% 100%; animation: shimmer 1.3s ease infinite; border-radius: 10px;
}
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
.toast {
  position: fixed; inset-block-end: 90px; inset-inline: 20px; z-index: 90;
  background: var(--ink); color: #fff; border-radius: 12px; padding: 12px 16px;
  font-size: 13px; box-shadow: var(--sh-float); opacity: 0; transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease; pointer-events: none;
}
.toast.is-on { opacity: 1; transform: translateY(0); }
.offline-bar {
  background: var(--ink); color: #fff; text-align: center;
  font-size: 11.5px; padding: 6px; display: none;
}
body.is-offline .offline-bar { display: block; }

/* Accessibility: minimum tap target and visible focus in both directions. */
button:focus-visible, a:focus-visible, .opt:focus-visible, input:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
@media print {
  .tabbar, .appbar, .btn, .console-nav { display: none !important; }
}

/* ============================================================================
   CUSTOMER APP — components matched to the approved screens
   Everything below resolves to tokens already declared in design.css. These
   rules exist because the screens specify states and compositions the base
   primitives do not cover on their own.
   ============================================================================ */

/* Screen titles sit on a white bar with a hairline, and the body sits on the
   warm background. Two background colours per screen, never three. */
.topbar {
  background: var(--surface);
  padding: calc(10px + env(safe-area-inset-top)) 20px 14px;
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 14px;
}
.topbar__title { font-family: var(--font-display); font-size: 27px; line-height: 1.15; }
.topbar__sub { font-size: 12.5px; color: var(--ink-55); line-height: 1.45; margin-top: 3px; }
.back {
  width: 26px; height: 26px; border: 0; background: none; cursor: pointer;
  display: grid; place-items: center; color: var(--ink); flex: 0 0 auto; padding: 0;
}

/* Home ------------------------------------------------------------------- */
.addr__label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-42);
}
.addr__value {
  font-size: 19px; font-weight: 700; display: flex; align-items: center; gap: 7px;
  line-height: 1.25;
}
.greet { font-size: 13.5px; color: var(--ink-55); }
.hook {
  font-family: var(--font-display); font-size: 30px; line-height: 1.18;
  margin: 4px 0 18px; letter-spacing: -.01em;
}

.search {
  display: flex; align-items: center; gap: 10px; height: 52px;
  border: 1px solid var(--line); border-radius: 13px; background: var(--surface);
  padding-inline: 16px; color: var(--ink-42);
}
.search input {
  border: 0; outline: 0; background: none; flex: 1; min-width: 0;
  font-family: var(--font-ui); font-size: 13.5px; color: var(--ink);
}
.search input::placeholder { color: var(--ink-42); }

/* Offer rail. Cards are 224px and the rail scrolls horizontally with the
   scrollbar hidden — a visible track reads as a desktop artefact on a phone. */
.rail {
  display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
  margin-inline: -20px; padding: 0 20px;
}
.rail::-webkit-scrollbar { display: none; }
.offer {
  flex: 0 0 224px; scroll-snap-align: start;
  border-radius: var(--r-lg); padding: 16px; border: 1px solid var(--line);
  background: var(--surface); min-height: 118px;
}
.offer--tint { background: var(--brand-tint); border-color: rgba(192,39,45,.16); }
.offer__code {
  font-size: 11.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  color: var(--brand);
}
.offer__code--gold { color: var(--gold); }
.offer__title { font-family: var(--font-display); font-size: 20px; line-height: 1.2; margin: 6px 0 6px; }
.offer__note { font-size: 11.5px; color: var(--ink-55); line-height: 1.4; }

.h2 { font-size: 19px; font-weight: 800; letter-spacing: -.01em; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.see-all {
  font-size: 12.5px; font-weight: 700; color: var(--brand);
  white-space: nowrap; cursor: pointer; background: none; border: 0; padding: 0;
}

.cats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.cat { cursor: pointer; }
.cat .thumb { width: 100%; aspect-ratio: 1; }
.cat__label { font-size: 12.5px; font-weight: 600; text-align: center; margin-top: 7px; }

/* Dish card. Each dish is its own white card, not a row with a divider —
   the screens are explicit about this and it changes the whole rhythm. */
.dishcard {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 12px; display: flex; gap: 14px;
  align-items: center; cursor: pointer;
}
.dishcard + .dishcard { margin-top: 10px; }
.dishcard__body { flex: 1; min-width: 0; }
.dishcard__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dishcard__name { font-size: 16px; font-weight: 700; line-height: 1.3; }
.dishcard__desc { font-size: 13px; color: var(--ink-55); line-height: 1.4; margin-top: 3px; }
.dishcard__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 9px;
}
/* The price must never wrap between the currency and the figure. */
.price { font-size: 16px; font-weight: 800; white-space: nowrap; }
.rating { font-size: 13px; color: var(--ink-55); white-space: nowrap; }
.addbtn {
  height: 34px; min-width: 74px; padding-inline: 18px; border: 0; border-radius: var(--r-sm);
  background: var(--brand-tint); color: var(--brand);
  font-family: var(--font-ui); font-size: 12px; font-weight: 800; letter-spacing: .07em;
  cursor: pointer; flex: 0 0 auto;
}
.dishcard.is-out { opacity: .5; }
.dishcard.is-out .addbtn { background: var(--page); color: var(--ink-42); }

.tag {
  display: inline-flex; align-items: center; height: 22px; padding-inline: 9px;
  border-radius: var(--r-sm); background: var(--brand-tint); color: var(--brand);
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.tag--gold { background: var(--gold-tint); color: var(--gold); }

/* Sticky cart bar, 74px above the tab bar as specified. */
.cartbar {
  position: sticky; bottom: 74px; z-index: 45; margin: 12px 20px;
  background: var(--brand); color: #fff; border-radius: 13px;
  padding: 16px 20px; display: flex; align-items: center; justify-content: space-between;
  box-shadow: var(--sh-brand); cursor: pointer; font-size: 15px; font-weight: 700;
}

/* Menu ------------------------------------------------------------------- */
.outlet__name { font-size: 20px; font-weight: 700; line-height: 1.25; }
.outlet__meta { font-size: 13px; color: var(--ink-55); margin-top: 3px; }
.catbar {
  background: var(--surface); border-bottom: 1px solid var(--line);
  padding: 14px 20px; position: sticky; z-index: 39;
}
.serif-title { font-family: var(--font-display); font-size: 30px; line-height: 1.15; }

/* Item customiser -------------------------------------------------------- */
.hero { position: relative; }
.hero .thumb { border-radius: 0; }
.hero__back {
  position: absolute; top: calc(14px + env(safe-area-inset-top)); inset-inline-start: 16px;
  width: 40px; height: 40px; border-radius: 50%; background: var(--surface);
  border: 0; display: grid; place-items: center; cursor: pointer; box-shadow: var(--sh-float);
}
.sheet {
  background: var(--bg); border-radius: 20px 20px 0 0; margin-top: -20px;
  position: relative; padding: 22px 20px 20px;
}
.item__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.item__name { font-family: var(--font-display); font-size: 27px; line-height: 1.15; flex: 1; }
.item__price { font-size: 19px; font-weight: 800; white-space: nowrap; padding-top: 4px; }
.item__desc { font-size: 14px; color: var(--ink-55); line-height: 1.5; margin: 10px 0 14px; }

.metachips { display: flex; gap: 10px; flex-wrap: wrap; }
/* Auto height, so "★ 4.9 · 840 reviews" cannot collide with its own second line. */
.metachip {
  border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--surface);
  padding: 8px 15px; font-size: 13px; color: var(--ink-70); line-height: 1.35;
  white-space: nowrap;
}

.group-head {
  display: flex; align-items: baseline; gap: 9px; margin: 22px 0 10px;
}
.group-head__t { font-size: 16px; font-weight: 700; }
.group-head__n { font-size: 13px; color: var(--ink-42); }

.pillrow { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.pill {
  height: 52px; border: 1.5px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); font-family: var(--font-ui); font-size: 14px; font-weight: 600;
  cursor: pointer; display: grid; place-items: center; color: var(--ink);
}
.pill.is-on { border-color: var(--brand); background: var(--brand-tint); }

.choice {
  display: flex; align-items: center; gap: 14px; width: 100%;
  border: 1.5px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  padding: 15px 16px; cursor: pointer; text-align: start;
}
.choice + .choice { margin-top: 10px; }
.choice.is-on { border-color: var(--brand); background: var(--brand-tint); }
.choice__t { font-size: 15px; font-weight: 700; line-height: 1.3; }
.choice__d { font-size: 12.5px; color: var(--ink-55); margin-top: 2px; }
/* Deltas are nowrap so "+AED 34" never breaks across two lines. */
.choice__x { font-size: 13.5px; color: var(--ink-55); white-space: nowrap; flex: 0 0 auto; }
.choice.is-on .choice__x { color: var(--brand); font-weight: 700; }
.mark {
  width: 22px; height: 22px; border-radius: 50%; border: 1.5px solid var(--line-strong);
  flex: 0 0 auto; display: grid; place-items: center; background: var(--surface);
}
.mark--box { border-radius: 6px; }
.choice.is-on .mark { border-color: var(--brand); background: var(--brand); }
.choice.is-on .mark::after {
  content: ""; width: 8px; height: 8px; border-radius: 50%; background: #fff;
}
.choice.is-on .mark--box::after {
  content: "✓"; width: auto; height: auto; background: none; color: #fff;
  font-size: 13px; font-weight: 700; line-height: 1;
}

/* Sticky footer: configuration summary and live line total on the left, the
   action on the right. */
.itembar {
  position: sticky; bottom: 0; z-index: 45; background: var(--surface);
  border-top: 1px solid var(--line);
  padding: 14px 20px calc(14px + env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.itembar__conf { font-size: 12.5px; color: var(--ink-55); line-height: 1.4; }
.itembar__total { font-size: 22px; font-weight: 800; margin-top: 2px; white-space: nowrap; }
.itembar .btn { width: auto; min-width: 168px; padding-inline: 26px; }

/* Cart ------------------------------------------------------------------- */
.line {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 12px; display: flex; align-items: center; gap: 14px;
}
.line + .line { margin-top: 10px; }
.line__body { flex: 1; min-width: 0; }
.line__name { font-size: 15px; font-weight: 700; line-height: 1.3; }
.line__conf { font-size: 12.5px; color: var(--ink-55); line-height: 1.4; margin-top: 2px; }
.line__price { font-size: 15px; font-weight: 800; margin-top: 6px; }

/* The stepper pair from the screens: light minus, black plus. */
.qty { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; }
.qty button {
  width: 40px; height: 40px; border-radius: 11px; border: 0; cursor: pointer;
  font-size: 20px; line-height: 1; display: grid; place-items: center;
  font-family: var(--font-ui);
}
.qty__minus { background: var(--page); color: var(--ink); }
.qty__plus { background: var(--ink); color: #fff; }
.qty__v { font-size: 16px; font-weight: 700; min-width: 14px; text-align: center; }

.upsell {
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-lg);
  padding: 16px; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 12px; cursor: pointer;
}
.upsell__t { font-size: 14px; font-weight: 700; line-height: 1.35; }
.upsell__a { font-size: 14px; font-weight: 700; color: var(--brand); white-space: nowrap; }

.bill { background: var(--surface); border: 1px solid var(--line);
        border-radius: var(--r-lg); box-shadow: var(--sh-card); padding: 16px; margin-top: 12px; }
.bill__t { font-size: 15px; font-weight: 700; margin-bottom: 12px; }
/* Each charge line is its own row, nothing bundled into an unexplained total. */
.bill__r { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.bill__r + .bill__r { margin-top: 10px; }
.bill__k { font-size: 13.5px; color: var(--ink-55); line-height: 1.4; }
.bill__v { font-size: 13.5px; white-space: nowrap; }
.bill__r--total { padding-top: 12px; margin-top: 12px; border-top: 1px solid var(--line); }
.bill__r--total .bill__k { font-size: 17px; font-weight: 700; color: var(--ink); }
.bill__r--total .bill__v { font-size: 19px; font-weight: 800; }
.bill__v--off { color: var(--brand); }

.stickybar {
  position: sticky; bottom: 0; z-index: 45; background: var(--bg);
  border-top: 1px solid var(--line);
  padding: 14px 20px calc(14px + env(safe-area-inset-bottom));
}
.btn--tall { height: 56px; font-size: 16px; }

/* Checkout --------------------------------------------------------------- */
.pinmap {
  height: 150px; background: var(--map-land); position: relative; overflow: hidden;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.pinmap__road {
  position: absolute; inset-inline: -10%; top: 46%; height: 22px;
  background: var(--map-road); transform: rotate(-4deg);
}
.pinmap__pin {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 26px; height: 26px; border-radius: 50%; background: var(--brand);
  border: 5px solid #fff; box-shadow: 0 0 0 6px rgba(192,39,45,.18);
}
.pinmap__label {
  position: absolute; inset-block-end: 8px; inset-inline-end: 12px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-42);
}
.addrcard {
  background: var(--surface); border: 1px solid var(--line); border-top: 0;
  border-radius: 0 0 var(--r-lg) var(--r-lg); padding: 16px;
}
.linkbtn {
  background: none; border: 0; padding: 0; cursor: pointer; white-space: nowrap;
  font-family: var(--font-ui); font-size: 12.5px; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase; color: var(--brand);
}
.chipmini {
  height: 28px; padding-inline: 12px; border-radius: var(--r-sm); border: 0;
  background: var(--brand-tint); color: var(--brand);
  font-size: 11.5px; font-weight: 800; letter-spacing: .06em;
  display: inline-flex; align-items: center; flex: 0 0 auto;
}
.promo-applied {
  border: 1.5px dashed rgba(192,39,45,.35); background: var(--brand-tint);
  border-radius: var(--r-lg); padding: 16px; margin-top: 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}

/* Live tracking ---------------------------------------------------------- */
.trackmap { height: 300px; position: relative; background: var(--map-land); overflow: hidden; }
.tracksheet {
  background: var(--bg); border-radius: 20px 20px 0 0; margin-top: -20px;
  position: relative; padding: 22px 20px 20px; z-index: 2;
}
.track__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.track__ref {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-42);
}
.track__title { font-family: var(--font-display); font-size: 28px; line-height: 1.15; margin-top: 8px; }
.track__eta-k {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-42); text-align: end;
}
.track__eta-v {
  font-family: var(--font-display); font-size: 24px; color: var(--brand);
  text-align: end; line-height: 1.2; white-space: nowrap;
}

/* Timeline with sub-captions. Done steps carry a filled dot, a solid rail and
   a black label; pending steps stay hollow and grey. */
.tl { margin-top: 20px; padding-inline-start: 30px; position: relative; }
.tl__s { position: relative; padding-bottom: 18px; }
.tl__s:last-child { padding-bottom: 0; }
.tl__dot {
  position: absolute; inset-inline-start: -30px; top: 3px;
  width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid var(--line-strong); background: var(--surface);
}
.tl__s.is-done .tl__dot { background: var(--brand); border-color: var(--brand); }
.tl__rail {
  position: absolute; inset-inline-start: -23.5px; top: 20px; bottom: -2px;
  width: 2px; background: var(--line);
}
.tl__s.is-done .tl__rail { background: rgba(192,39,45,.35); }
.tl__s:last-child .tl__rail { display: none; }
.tl__t { font-size: 16px; font-weight: 700; color: var(--ink-42); line-height: 1.3; }
.tl__s.is-done .tl__t { color: var(--ink); }
/* Captions wrap onto their own lines with real leading, so nothing overlaps. */
.tl__d { font-size: 13px; color: var(--ink-42); line-height: 1.45; margin-top: 3px; }

.ridercard {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 14px; margin-top: 18px;
  display: flex; align-items: center; gap: 14px;
}
.ridercard__body { flex: 1; min-width: 0; }
.ridercard__n { font-size: 16px; font-weight: 700; }
.ridercard__m { font-size: 13px; color: var(--ink-55); margin-top: 2px; }
.rbtn {
  height: 44px; padding-inline: 20px; border-radius: 11px; border: 0; cursor: pointer;
  font-family: var(--font-ui); font-size: 14px; font-weight: 700;
  display: inline-grid; place-items: center; text-decoration: none; flex: 0 0 auto;
}
.rbtn--quiet { background: var(--page); color: var(--ink); }
.rbtn--dark { background: var(--ink); color: #fff; }

.handover {
  background: var(--brand-tint); border-radius: var(--r-lg); padding: 16px; margin-top: 12px;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
}
.handover__k { font-size: 13.5px; color: var(--ink-70); }
.handover__v {
  font-family: var(--font-display); font-size: 34px; color: var(--brand);
  letter-spacing: .18em; line-height: 1.1; margin-top: 6px;
}
.handover__cash-k {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-42); text-align: end;
}
.handover__cash-v { font-size: 17px; font-weight: 800; text-align: end; white-space: nowrap; }

/* Rate ------------------------------------------------------------------- */
.tick {
  width: 72px; height: 72px; border-radius: 50%; background: var(--ink); color: #fff;
  display: grid; place-items: center; font-size: 32px; margin: 0 auto;
}
.rate__title { font-family: var(--font-display); font-size: 30px; text-align: center; margin-top: 16px; }
.rate__sub { font-size: 14px; color: var(--ink-55); text-align: center; line-height: 1.5; margin-top: 8px; }
.stars { display: flex; gap: 14px; justify-content: center; margin: 26px 0; }
.star {
  background: none; border: 0; cursor: pointer; padding: 0;
  font-size: 34px; line-height: 1; color: var(--line-strong);
}
.star.is-on { color: var(--gold); }
.tags { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.tagchip {
  height: 44px; padding-inline: 20px; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--surface);
  font-family: var(--font-ui); font-size: 14px; font-weight: 600; cursor: pointer;
}
.tagchip.is-on { background: var(--ink); color: #fff; border-color: var(--ink); }
.tipbox {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 16px; margin-top: 26px;
}
.tipgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 12px; }
.points {
  background: var(--brand-tint); border-radius: var(--r-lg); padding: 16px; margin-top: 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.points__t { font-size: 14px; font-weight: 600; }
.points__v { font-size: 15px; font-weight: 800; color: var(--brand); white-space: nowrap; }

/* Orders ----------------------------------------------------------------- */
.live {
  background: var(--ink); color: #fff; border-radius: var(--r-lg); padding: 18px;
  cursor: pointer;
}
.live__k {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.live__t { font-family: var(--font-display); font-size: 24px; line-height: 1.2; margin: 10px 0 8px; }
.live__foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.live__m { font-size: 13px; color: rgba(255,255,255,.62); line-height: 1.4; }
.live__a { font-size: 14px; font-weight: 700; white-space: nowrap; }

.past {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 12px; display: flex; align-items: center; gap: 14px;
}
.past + .past { margin-top: 10px; }
.past__body { flex: 1; min-width: 0; }
.past__t { font-size: 15px; font-weight: 700; line-height: 1.35; }
.past__m { font-size: 13px; color: var(--ink-55); margin-top: 4px; }

/* Rewards ---------------------------------------------------------------- */
.rewards-head {
  background: var(--ink); color: #fff;
  padding: calc(28px + env(safe-area-inset-top)) 20px 30px;
}
.rewards-head__k {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.55);
}
.rewards-head__v {
  font-size: 52px; font-weight: 800; line-height: 1; margin-top: 14px;
  display: flex; align-items: baseline; gap: 12px;
}
.rewards-head__u { font-size: 19px; font-weight: 500; color: rgba(255,255,255,.62); }
.rewards-head__n { font-size: 13.5px; color: rgba(255,255,255,.62); margin-top: 12px; line-height: 1.45; }
.statpair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.statcard {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 16px;
}
.statcard__k {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-42);
}
.statcard__v { font-size: 23px; font-weight: 800; margin-top: 8px; line-height: 1.15; }
.statcard__n { font-size: 13px; color: var(--ink-55); margin-top: 4px; }

.voucher {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 14px; display: flex; align-items: center; gap: 14px;
}
.voucher + .voucher { margin-top: 10px; }
.voucher__tile {
  width: 48px; height: 48px; border-radius: var(--r-md); background: var(--brand-tint);
  color: var(--brand); display: grid; place-items: center; flex: 0 0 auto;
  font-size: 15px; font-weight: 800;
}
.voucher__body { flex: 1; min-width: 0; }
.voucher__t { font-size: 15px; font-weight: 700; line-height: 1.3; }
.voucher__n { font-size: 13px; color: var(--ink-55); margin-top: 3px; }
.usebtn {
  height: 38px; padding-inline: 20px; border-radius: 10px; border: 0; background: var(--ink);
  color: #fff; font-family: var(--font-ui); font-size: 12.5px; font-weight: 800;
  letter-spacing: .06em; cursor: pointer; flex: 0 0 auto;
}

/* Dine-in ---------------------------------------------------------------- */
.daygrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.day {
  border: 1.5px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  padding: 14px 6px; cursor: pointer; text-align: center; font-family: var(--font-ui);
}
.day.is-on { border-color: var(--brand); background: var(--brand-tint); }
.day__d {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-42);
}
.day__n { font-size: 21px; font-weight: 700; margin-top: 5px; line-height: 1.1; }
.timegrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.slot {
  height: 52px; border: 1.5px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); font-family: var(--font-ui); font-size: 14.5px; font-weight: 600;
  cursor: pointer; display: grid; place-items: center;
}
.slot.is-on { border-color: var(--brand); background: var(--brand-tint); }
.guests {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 14px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.guests__v { font-size: 15px; font-weight: 600; line-height: 1.35; }
.requests {
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-lg); padding: 16px;
}
.requests__t { font-size: 15px; font-weight: 700; }
.requests textarea {
  border: 0; outline: 0; background: none; width: 100%; resize: none; margin-top: 8px;
  font-family: var(--font-ui); font-size: 14px; color: var(--ink); line-height: 1.5;
}
.requests textarea::placeholder { color: var(--ink-42); }

/* The room at the chosen sitting. Same tile language as the time slots above
   it, so the two read as one form rather than two widgets. A held table is
   dimmed and greyed rather than hidden — "T04 comes free at 9:15" is the
   useful answer, and removing the tile would throw it away. */
.roomgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 10px;
}
.roomtile {
  border: 1.5px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  padding: 10px 8px; text-align: center; font-family: var(--font-ui);
}
.roomtile__n { font-size: 16px; font-weight: 700; line-height: 1.2; }
.roomtile__s {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em;
  color: var(--ink-42); margin-top: 3px;
}
.roomtile__w { font-size: 11.5px; margin-top: 6px; line-height: 1.3; color: var(--brand); }
.roomtile.is-held { background: var(--brand-tint); border-color: var(--line); }
.roomtile.is-held .roomtile__w { color: var(--ink-42); }
.roomtile.is-small { opacity: .5; }

/* The bar appears on the first add rather than sitting there empty, so it
   slides up instead of popping into place. */
@keyframes cartIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.cartbar { animation: cartIn .22s ease-out; }
@media (prefers-reduced-motion: reduce) { .cartbar { animation: none; } }

/* ============================================================================
   DELIVERY AGENT APP — components matched to the approved driver screens
   One-handed use on a bike at a kerb: large targets, minimal reading, one
   primary action per screen.
   ============================================================================ */

.rider-bar {
  background: var(--surface);
  padding: calc(10px + env(safe-area-inset-top)) 20px 16px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 14px;
}
.avatar {
  width: 56px; height: 56px; border-radius: 50%; flex: 0 0 auto;
  background: repeating-linear-gradient(135deg, var(--page) 0 8px, #EDE8E1 8px 16px);
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 9px; color: var(--ink-35);
}
.avatar--sm { width: 44px; height: 44px; }
.rider-bar__n { font-size: 20px; font-weight: 700; line-height: 1.25; }
.rider-bar__m { font-size: 14px; color: var(--ink-55); margin-top: 2px; }

/* Offline ---------------------------------------------------------------- */
.offline-hero { text-align: center; padding: 34px 20px 6px; }
.offline-dot {
  width: 14px; height: 14px; border-radius: 50%; background: var(--ink-35); margin: 0 auto 16px;
}
.offline-hero__t { font-family: var(--font-display); font-size: 36px; line-height: 1.12; }
.offline-hero__s {
  font-size: 16px; color: var(--ink-55); line-height: 1.5; margin-top: 12px;
  max-width: 340px; margin-inline: auto;
}

.rstat {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 16px;
}
.rstat__k {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-42);
}
.rstat__v { font-size: 27px; font-weight: 800; margin-top: 8px; line-height: 1.1; }
.rstat__n { font-size: 14px; color: var(--ink-55); margin-top: 5px; }

/* Values in the shift card must never wrap — a broken time slot is unreadable
   at a glance, which is the entire point of this card. */
.shift__r { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.shift__r + .shift__r { margin-top: 12px; }
.shift__k { font-size: 15px; color: var(--ink-55); line-height: 1.35; }
.shift__v { font-size: 15px; font-weight: 600; white-space: nowrap; text-align: end; }

.surge {
  background: var(--brand-tint); border: 1px solid rgba(192,39,45,.16);
  border-radius: var(--r-lg); padding: 16px; margin-top: 12px;
}
.surge__t { font-size: 16px; font-weight: 700; line-height: 1.35; }
.surge__n { font-size: 14px; color: var(--ink-55); margin-top: 6px; line-height: 1.45; }

/* Online header ---------------------------------------------------------- */
.online-head {
  background: var(--ink); color: #fff;
  padding: calc(16px + env(safe-area-inset-top)) 20px 22px;
}
.online-head__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.online-head__zone {
  display: flex; align-items: center; gap: 9px;
  font-size: 17px; font-weight: 700; line-height: 1.3;
}
.offbtn {
  background: rgba(255,255,255,.14); color: #fff; border: 0; border-radius: var(--r-sm);
  padding: 10px 14px; font-family: var(--font-ui); font-size: 11.5px; font-weight: 800;
  letter-spacing: .07em; cursor: pointer; white-space: nowrap; flex: 0 0 auto;
}
.online-head__v {
  font-size: 46px; font-weight: 800; line-height: 1.05; margin-top: 16px;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.online-head__u { font-size: 17px; font-weight: 500; color: rgba(255,255,255,.6); }
.online-head__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 20px; }
.online-head__k {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: rgba(255,255,255,.5);
}
.online-head__n { font-size: 19px; font-weight: 700; margin-top: 6px; white-space: nowrap; }

/* Demand heatmap. Red blobs are order density, gold is surge pay. */
.heatmap { height: 250px; border-radius: var(--r-lg); }
.map__heat {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(192,39,45,.34) 0%, rgba(192,39,45,0) 70%);
}
.map__heat--gold {
  background: radial-gradient(circle, rgba(217,140,15,.30) 0%, rgba(217,140,15,0) 70%);
}
.map__overlay-pill {
  position: absolute; background: var(--surface); border-radius: var(--r-sm);
  padding: 8px 12px; font-size: 12.5px; font-weight: 700;
  box-shadow: var(--sh-float); white-space: nowrap;
}

.waiting {
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-lg);
  padding: 26px 20px; text-align: center; margin-top: 14px;
}
.waiting__t { font-size: 17px; font-weight: 700; line-height: 1.35; }
.waiting__n { font-size: 14px; color: var(--ink-55); margin-top: 8px; line-height: 1.45; }

.active-trip {
  background: var(--ink); color: #fff; border-radius: var(--r-lg); padding: 16px;
  display: flex; align-items: center; gap: 16px; margin-top: 12px;
}
.active-trip__t { font-size: 16px; font-weight: 700; line-height: 1.35; }
.active-trip__n { font-size: 13.5px; color: rgba(255,255,255,.6); margin-top: 4px; }
.resume {
  background: var(--brand); color: #fff; border: 0; border-radius: var(--r-sm);
  padding: 12px 18px; font-family: var(--font-ui); font-size: 12px; font-weight: 800;
  letter-spacing: .07em; cursor: pointer; flex: 0 0 auto;
}

.toggle-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 16px; margin-top: 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.toggle-card__t { font-size: 16px; font-weight: 700; line-height: 1.35; }
.toggle-card__n { font-size: 13.5px; color: var(--ink-55); margin-top: 5px; line-height: 1.45; }

/* Order request — dark screen ------------------------------------------- */
.request { background: var(--ink); color: #fff; min-height: 100dvh; padding-bottom: 190px; }
.request__k {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.5);
  text-align: center; padding-top: calc(22px + env(safe-area-inset-top));
}
/* The countdown is a conic gradient driven by --deg, so it sweeps rather than
   stepping — a stepping ring reads as a progress bar, not a deadline. */
.ring {
  width: 200px; height: 200px; border-radius: 50%; margin: 18px auto 0;
  background: conic-gradient(var(--brand) var(--deg, 360deg), rgba(255,255,255,.14) 0);
  display: grid; place-items: center;
}
.ring__in {
  width: 170px; height: 170px; border-radius: 50%; background: var(--ink);
  display: grid; place-items: center; text-align: center;
}
.ring__n { font-size: 44px; font-weight: 800; line-height: 1; }
.ring__u {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: rgba(255,255,255,.55); margin-top: 6px;
}
.request__pay { font-family: var(--font-display); font-size: 42px; text-align: center; margin-top: 24px; }
.request__meta {
  font-size: 15px; color: rgba(255,255,255,.6); text-align: center; margin-top: 8px; line-height: 1.45;
}

.leg { position: relative; padding-inline-start: 30px; padding-bottom: 22px; }
.leg:last-child { padding-bottom: 0; }
.leg__dot {
  position: absolute; inset-inline-start: 0; top: 4px;
  width: 16px; height: 16px; border-radius: 50%; background: #fff;
}
.leg__dot--drop { background: var(--brand); }
.leg__rail {
  position: absolute; inset-inline-start: 7px; top: 22px; bottom: 0;
  width: 2px; background: rgba(255,255,255,.22);
}
.leg:last-child .leg__rail { display: none; }
.leg__k {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: rgba(255,255,255,.5);
}
.leg__t { font-size: 19px; font-weight: 700; line-height: 1.3; margin-top: 5px; }
.leg__n { font-size: 14px; color: rgba(255,255,255,.58); margin-top: 5px; line-height: 1.45; }

.rchips { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 22px; }
.rchip {
  border-radius: var(--r-sm); padding: 11px 15px; font-size: 14px; font-weight: 700;
  background: rgba(255,255,255,.12); color: #fff; line-height: 1.3;
}
.rchip--brand { background: var(--brand); }
.rchip--gold { background: rgba(217,140,15,.24); color: var(--gold); }

.request__foot {
  position: fixed; inset-inline: 0; bottom: 0; padding: 0 20px calc(20px + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--ink) 72%, transparent);
}
.btn--dim { background: rgba(255,255,255,.10); color: rgba(255,255,255,.72); }

/* Navigation ------------------------------------------------------------- */
.navmap { height: 380px; position: relative; background: var(--map-land); overflow: hidden; }
.dest-card {
  position: absolute; inset-block-start: calc(14px + env(safe-area-inset-top));
  inset-inline-start: 14px; max-width: 78%;
  background: var(--surface); border-radius: var(--r-lg); padding: 14px 16px;
  box-shadow: var(--sh-float);
}
.dest-card__k {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-42);
}
.dest-card__t { font-size: 19px; font-weight: 700; line-height: 1.3; margin-top: 6px; }
.dest-card__n { font-size: 13.5px; color: var(--ink-55); margin-top: 5px; line-height: 1.4; }
.turn {
  position: absolute; inset-block-end: 16px; inset-inline-start: 14px; max-width: 74%;
  background: var(--ink); color: #fff; border-radius: var(--r-pill);
  padding: 13px 20px 13px 16px; display: flex; align-items: center; gap: 11px;
  font-size: 15px; font-weight: 700; line-height: 1.3; box-shadow: var(--sh-float);
}

.orow { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.orow + .orow { margin-top: 12px; }
.orow__k { font-size: 15px; color: var(--ink-55); line-height: 1.35; }
.orow__v { font-size: 15px; font-weight: 600; text-align: end; white-space: nowrap; }
.wbtn {
  height: 56px; border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--surface); font-family: var(--font-ui); font-size: 15px; font-weight: 700;
  cursor: pointer; display: grid; place-items: center; text-decoration: none; color: var(--ink);
}

/* Pickup verification ---------------------------------------------------- */
.verify {
  display: flex; align-items: center; gap: 14px; width: 100%;
  border: 1.5px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  padding: 18px 16px; cursor: pointer; text-align: start;
}
.verify + .verify { margin-top: 10px; }
.verify.is-on { border-color: var(--brand); background: var(--brand-tint); }
.verify__t { font-size: 16px; font-weight: 600; line-height: 1.35; }
.box {
  width: 26px; height: 26px; border-radius: 7px; border: 1.5px solid var(--line-strong);
  flex: 0 0 auto; display: grid; place-items: center; background: var(--surface);
}
.verify.is-on .box { border-color: var(--brand); background: var(--brand); }
.verify.is-on .box::after { content: "✓"; color: #fff; font-size: 15px; font-weight: 700; line-height: 1; }

/* Proof of delivery ------------------------------------------------------ */
.otpgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.otpbox {
  aspect-ratio: 1 / 1.12; border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--surface); display: grid; place-items: center;
  font-size: 34px; font-weight: 700; box-shadow: var(--sh-card);
}
.otpbox.is-next { border-color: var(--brand); border-width: 1.5px; }
.pad3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.key {
  height: 76px; border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--surface); font-family: var(--font-ui); font-size: 26px; font-weight: 600;
  cursor: pointer; box-shadow: var(--sh-card);
}
.key--blank { background: none; border: 0; box-shadow: none; cursor: default; }
.photo-row {
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-lg); padding: 14px;
  display: flex; align-items: center; gap: 14px; cursor: pointer;
}
.photo-row__t { font-size: 15px; font-weight: 600; flex: 1; min-width: 0; line-height: 1.35; }

/* Cash ------------------------------------------------------------------- */
.due { background: var(--ink); color: #fff; border-radius: var(--r-lg); padding: 20px; }
.due__k {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: rgba(255,255,255,.5);
}
.due__v { font-size: 42px; font-weight: 800; line-height: 1.05; margin-top: 10px; }
.due__n { font-size: 14px; color: rgba(255,255,255,.6); margin-top: 8px; }

/* Trip summary ----------------------------------------------------------- */
.tick--brand { background: var(--brand); }
.rated { display: flex; align-items: center; gap: 16px; }
.rated__t { font-size: 16px; font-weight: 700; line-height: 1.35; }
.rated__n { font-size: 14px; color: var(--ink-55); margin-top: 5px; line-height: 1.45; }
.nextdrop {
  background: var(--ink); color: #fff; border-radius: var(--r-lg); padding: 16px;
  display: flex; align-items: center; gap: 16px; margin-top: 12px; cursor: pointer;
}
.nextdrop__t { font-size: 16px; font-weight: 700; line-height: 1.35; }
.nextdrop__n { font-size: 13.5px; color: rgba(255,255,255,.6); margin-top: 4px; }
.nextdrop__a { font-size: 13px; font-weight: 800; letter-spacing: .07em; flex: 0 0 auto; }

/* Earnings --------------------------------------------------------------- */
.earn-head {
  background: var(--ink); color: #fff;
  padding: calc(20px + env(safe-area-inset-top)) 20px 24px;
}
.earn-head__k {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.5);
}
.earn-head__v {
  font-size: 46px; font-weight: 800; line-height: 1.05; margin-top: 12px;
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
}
.earn-head__u { font-size: 16px; font-weight: 500; color: rgba(255,255,255,.6); }
.weekbars { display: flex; align-items: flex-end; gap: 10px; height: 190px; margin-top: 22px; }
.weekbar { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 10px; height: 100%; }
.weekbar__b {
  width: 100%; background: rgba(255,255,255,.22); border-radius: 8px 8px 0 0; min-height: 6px;
  margin-top: auto;
}
.weekbar__b.peak { background: var(--brand); }
.weekbar__l {
  font-family: var(--font-mono); font-size: 12px; color: rgba(255,255,255,.5);
  text-transform: uppercase;
}

.payrow { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.payrow + .payrow { margin-top: 12px; }
.payrow__k { font-size: 15px; color: var(--ink-55); line-height: 1.4; }
.payrow__v { font-size: 15px; font-weight: 600; white-space: nowrap; text-align: end; }
.payrow--net { border-top: 1px solid var(--line); padding-top: 14px; margin-top: 14px; }
.payrow--net .payrow__k { font-size: 17px; font-weight: 700; color: var(--ink); }
.payrow--net .payrow__v { font-size: 19px; font-weight: 800; color: var(--brand); }

/* Ratings ---------------------------------------------------------------- */
.dist { display: flex; align-items: center; gap: 14px; }
.dist + .dist { margin-top: 14px; }
.dist__k { font-size: 15px; color: var(--ink-55); width: 74px; flex: 0 0 auto; }
.dist__track {
  flex: 1; height: 10px; border-radius: 999px; background: var(--page);
  overflow: hidden; display: block;
}
.dist__fill { display: block; height: 100%; border-radius: 999px; background: var(--brand); }
.dist__v { font-size: 15px; font-weight: 700; width: 48px; text-align: end; flex: 0 0 auto; }
.note { font-size: 15px; line-height: 1.5; color: var(--ink-70); }
.note + .note { border-top: 1px solid var(--line); margin-top: 14px; padding-top: 14px; }

/* Chat ------------------------------------------------------------------- */
.bubble {
  max-width: 78%; border-radius: 14px; padding: 12px 15px;
  font-size: 15px; line-height: 1.45;
}
.bubble--in { background: var(--page); color: var(--ink); }
.bubble--out { background: var(--ink); color: #fff; margin-inline-start: auto; }
.bubble + .bubble { margin-top: 10px; }
.quick { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.quickchip {
  border: 0; background: var(--page); border-radius: var(--r-pill);
  padding: 11px 16px; font-family: var(--font-ui); font-size: 14px; cursor: pointer;
  color: var(--ink-70);
}
.stop-queued {
  border: 1.5px solid rgba(217,140,15,.5); border-radius: var(--r-lg); padding: 16px;
  margin-top: 12px; display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
}
.stop-queued__t { font-size: 15px; font-weight: 700; line-height: 1.35; }
.stop-queued__n { font-size: 13.5px; color: var(--ink-55); margin-top: 5px; line-height: 1.45; }
.stop-queued__b {
  font-size: 12px; font-weight: 800; letter-spacing: .07em; color: var(--gold);
  white-space: nowrap; flex: 0 0 auto;
}

/* ============================================================================
   HQ CONSOLE — charts, fleet map and editing
   ============================================================================ */

.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 1180px) {
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .console-shell { grid-template-columns: 1fr; }
  .console-nav { display: flex; overflow-x: auto; padding: 10px; gap: 4px; }
  .console-nav__logo, .console-nav__meta { display: none; }
  .console-nav a { white-space: nowrap; border-radius: 8px; }
}

.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-card); padding: 18px;
}
.panel__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 16px;
}
.panel__t { font-size: 15px; font-weight: 700; }
.panel__n { font-size: 12.5px; color: var(--ink-42); }

/* Charts are hand-drawn SVG rather than a charting library: the whole console
   is one 40 KB file with no build step, and these five shapes are all it needs. */
.chart { width: 100%; display: block; overflow: visible; }
.chart .grid-line { stroke: var(--line); stroke-width: 1; }
.chart .axis-label { font-size: 10px; fill: var(--ink-42); font-family: var(--font-ui); }
.chart .area { fill: url(#revFill); }
.chart .line { fill: none; stroke: var(--brand); stroke-width: 2.5;
               stroke-linejoin: round; stroke-linecap: round; }
.chart .dot { fill: var(--brand); }
.chart .bar { fill: var(--line-strong); }
.chart .bar.peak { fill: var(--brand); }
.chart .bar:hover { fill: var(--brand-dark); }
.chart .slice { stroke: var(--surface); stroke-width: 2; }

.legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }
.legend__i { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink-70); }
.legend__s { width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto; }

.hbar { display: flex; align-items: center; gap: 12px; }
.hbar + .hbar { margin-top: 11px; }
.hbar__k { font-size: 12.5px; width: 150px; flex: 0 0 auto;
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbar__t {
  flex: 1; height: 9px; border-radius: 999px; background: var(--page);
  overflow: hidden; display: block;
}
/* display:block matters: this is a span inside a span, and height has no
   effect on an inline box — without it the bar renders at zero height. */
.hbar__f { display: block; height: 100%; border-radius: 999px; background: var(--brand); }
.hbar__v { font-size: 12.5px; font-weight: 700; min-width: 96px; text-align: end;
           flex: 0 0 auto; white-space: nowrap; }

.funnel { display: grid; gap: 8px; }
.funnel__i {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px; border-radius: var(--r-sm); background: var(--page); font-size: 13px;
}
.funnel__n { font-weight: 800; font-size: 15px; }

/* Fleet map. OpenStreetMap tiles through Leaflet — no key, no billing. */
#fleetMap { height: calc(100dvh - 210px); min-height: 460px; border-radius: var(--r-lg); z-index: 1; }
.leaflet-container { font-family: var(--font-ui); background: var(--map-land); }
.fleet-pin {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  box-shadow: var(--sh-float); border: 2px solid #fff;
}
.fleet-pin--online { background: var(--brand); color: #fff; }
.fleet-pin--break { background: var(--gold); color: #fff; }
.fleet-pin--offline { background: var(--ink-35); color: #fff; }
.fleet-pin--kitchen { background: var(--ink); color: #fff; border-radius: 50% 50% 50% 4px; }
.fleet-side { display: grid; gap: 10px; max-height: calc(100dvh - 210px); overflow: auto; }
.fleet-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px 14px; cursor: pointer;
}
.fleet-card:hover { border-color: var(--line-strong); }
.fleet-card.is-sel { border-color: var(--brand); background: var(--brand-tint); }

/* Modal used for every create and edit form in the console. */
.modal {
  position: fixed; inset: 0; z-index: 200; display: grid; place-items: center;
  background: rgba(21,21,21,.45); padding: 24px;
}
.modal__box {
  background: var(--surface); border-radius: var(--r-2xl); width: min(680px, 100%);
  max-height: 88vh; overflow: auto; box-shadow: 0 24px 60px rgba(0,0,0,.24);
}
.modal__head {
  padding: 20px 24px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  position: sticky; top: 0; background: var(--surface); z-index: 2;
}
.modal__t { font-family: var(--font-display); font-size: 22px; }
.modal__body { padding: 22px 24px; }
.modal__foot {
  padding: 16px 24px; border-top: 1px solid var(--line);
  display: flex; gap: 10px; justify-content: flex-end;
  position: sticky; bottom: 0; background: var(--surface);
}
.modal__foot .btn { width: auto; padding-inline: 22px; height: 42px; }
.x { background: none; border: 0; font-size: 24px; cursor: pointer; color: var(--ink-55); line-height: 1; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-grid .span-2 { grid-column: 1 / -1; }
.check { display: flex; align-items: center; gap: 9px; font-size: 13px; cursor: pointer; }

.rowbtns { display: flex; gap: 6px; justify-content: flex-end; }
.tinybtn {
  border: 1px solid var(--line-strong); background: var(--surface); border-radius: 7px;
  padding: 6px 11px; font-family: var(--font-ui); font-size: 11.5px; font-weight: 700;
  cursor: pointer; white-space: nowrap; color: var(--ink);
}
.tinybtn:hover { background: var(--page); }
.tinybtn--danger { color: var(--brand); border-color: rgba(192,39,45,.35); }
.tinybtn--danger:hover { background: var(--brand-tint); }

/* Vehicle markers -----------------------------------------------------------
   The marker glides between position updates; the silhouette inside it turns
   independently, so a corner looks like a turn rather than a slide. */
.map__rider { overflow: visible; }
.map__rider--online { background: var(--brand); }
.map__rider--break  { background: var(--gold); }
.map__rider--offline{ background: var(--ink-35); }
.map__rider-name {
  position: absolute; top: 36px; left: 50%; transform: translateX(-50%);
  font-size: 10px; font-weight: 700; color: var(--ink); white-space: nowrap;
  background: var(--surface); border-radius: 999px; padding: 2px 7px;
  box-shadow: var(--sh-card);
}
/* A soft halo so a moving vehicle is findable on a busy map. */
.map__rider--online::before,
.fleet-pin--online::before {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  background: rgba(192,39,45,.18); z-index: -1;
}
.fleet-pin { position: relative; overflow: visible; }
.fleet-pin svg { display: block; }

/* ============================================================================
   ORDERS — list / Kanban toggle, filter panel, board
   ============================================================================ */

.seg {
  display: inline-flex; background: var(--page); border-radius: 10px; padding: 3px;
  border: 1px solid var(--line);
}
.seg button {
  border: 0; background: none; border-radius: 8px; cursor: pointer;
  padding: 8px 16px; font-family: var(--font-ui); font-size: 12.5px; font-weight: 700;
  color: var(--ink-55); display: inline-flex; align-items: center; gap: 7px;
}
.seg button.is-on { background: var(--surface); color: var(--ink); box-shadow: var(--sh-card); }

.filters {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 16px; margin-bottom: 16px;
}
.filters__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px;
}
.filters__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 14px; flex-wrap: wrap;
}
.activefilter {
  display: inline-flex; align-items: center; gap: 7px; background: var(--brand-tint);
  color: var(--brand); border-radius: var(--r-pill); padding: 6px 12px;
  font-size: 12px; font-weight: 700;
}
.activefilter button { border: 0; background: none; cursor: pointer; color: inherit; font-size: 14px; line-height: 1; padding: 0; }

/* Board. Columns scroll horizontally rather than compressing — six squeezed
   columns are unreadable, and a dispatcher scrolls without thinking. */
.board {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(268px, 1fr);
  gap: 14px; overflow-x: auto; padding-bottom: 10px; align-items: start;
}
.board__col {
  background: var(--page); border: 1px solid var(--line); border-radius: var(--r-lg);
  min-height: 220px; display: flex; flex-direction: column;
}
.board__col.is-over { border-color: var(--brand); background: var(--brand-tint); }
.board__head {
  padding: 13px 14px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  position: sticky; top: 0; background: var(--page); border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.board__t { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.board__n {
  background: var(--surface); border-radius: 999px; padding: 2px 9px;
  font-size: 12px; font-weight: 700; border: 1px solid var(--line);
}
.board__list { padding: 10px; display: grid; gap: 10px; max-height: 62vh; overflow-y: auto; }

.ocard {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px; cursor: grab; box-shadow: var(--sh-card);
}
.ocard:active { cursor: grabbing; }
.ocard.is-dragging { opacity: .45; }
.ocard.is-late { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-tint); }
.ocard__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ocard__ref { font-family: var(--font-mono); font-size: 12px; color: var(--ink-55); }
.ocard__total { font-size: 14px; font-weight: 800; white-space: nowrap; }
.ocard__who { font-size: 14px; font-weight: 700; margin-top: 7px; line-height: 1.3; }
.ocard__sum {
  font-size: 12.5px; color: var(--ink-55); margin-top: 4px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ocard__meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 9px; font-size: 11.5px; color: var(--ink-42);
}
.ocard__tags { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 8px; }
.minitag {
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  border-radius: 5px; padding: 3px 7px; background: var(--page); color: var(--ink-55);
}
.minitag--brand { background: var(--brand-tint); color: var(--brand); }
.minitag--gold { background: var(--gold-tint); color: var(--gold); }
.minitag--dark { background: var(--ink); color: #fff; }

/* ============================================================================
   HQ CONSOLE — light theme
   The console is a working tool used all day under office lighting. Warm
   beige and a black sidebar look handsome in a screenshot and tire the eye
   over an eight-hour shift. White ground, near-black text, red reserved for
   the things that need acting on: late, over threshold, destructive.
   Tokens are overridden rather than rules rewritten, so every component
   already built inherits the new palette.
   ============================================================================ */
body.console {
  --bg:          #FFFFFF;
  --page:        #F6F7F9;
  --surface:     #FFFFFF;
  --line:        #E8EAED;
  --line-strong: #D3D7DD;
  --ink:         #14161A;
  --ink-70:      #3C4149;
  --ink-55:      #656C77;
  --ink-42:      #8A929D;
  --ink-35:      #A7AEB8;
  background: var(--page);
}

/* Sidebar: white with a hairline, red only on the active item. */
body.console .console-nav {
  background: var(--surface);
  border-inline-end: 1px solid var(--line);
  color: var(--ink);
  padding-top: 20px;
}
body.console .console-nav a {
  color: var(--ink-55);
  border-inline-start: 3px solid transparent;
  margin-inline: 8px;
  border-radius: 8px;
  padding: 9px 14px;
}
body.console .console-nav a:hover { background: var(--page); color: var(--ink); }
body.console .console-nav a.is-active {
  background: var(--brand-tint);
  color: var(--brand);
  border-inline-start-color: var(--brand);
  font-weight: 700;
}
.console-nav__group {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-35);
  padding: 16px 22px 7px;
}
body.console .console-nav__meta { color: var(--ink-42); }

body.console table.grid { border: 1px solid var(--line); }
body.console table.grid th { background: var(--page); color: var(--ink-55); }
body.console .board__col, body.console .board__head { background: var(--page); }
body.console .ocard, body.console .panel, body.console .stat { background: var(--surface); }

/* Help ---------------------------------------------------------------------
   A console this dense needs to explain itself. Every page carries one line
   saying what it is for, and anything non-obvious carries a hint rather than
   assuming the reader already knows. */
.page-help {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--brand);
  border-radius: var(--r-md); padding: 14px 16px; margin-bottom: 18px;
}
.page-help__i {
  width: 20px; height: 20px; border-radius: 50%; background: var(--brand-tint);
  color: var(--brand); display: grid; place-items: center; flex: 0 0 auto;
  font-size: 12px; font-weight: 800; margin-top: 1px;
}
.page-help__t { font-size: 13.5px; line-height: 1.55; color: var(--ink-70); }
.page-help__t strong { color: var(--ink); }

.hint {
  font-size: 12px; color: var(--ink-42); line-height: 1.5; margin-top: 5px;
  display: flex; gap: 6px; align-items: flex-start;
}
.hint::before { content: "?"; font-weight: 800; color: var(--ink-35); flex: 0 0 auto; }

.kpi-help { font-size: 11.5px; color: var(--ink-42); margin-top: 6px; line-height: 1.45; }

.empty {
  text-align: center; padding: 46px 24px;
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-lg);
}
.empty__t { font-family: var(--font-display); font-size: 20px; margin-bottom: 8px; }
.empty__n { font-size: 13.5px; color: var(--ink-55); line-height: 1.55; max-width: 420px; margin-inline: auto; }
.empty__a { margin-top: 16px; }

/* Call centre --------------------------------------------------------------
   Built for someone typing while a customer talks: three panes on one screen,
   no navigation, nothing hidden behind a tab. */
.call { display: grid; grid-template-columns: 320px 1fr 340px; gap: 16px; align-items: start; }
@media (max-width: 1400px) { .call { grid-template-columns: 300px 1fr; } .call__bill { grid-column: 1 / -1; } }
@media (max-width: 1000px) { .call { grid-template-columns: 1fr; } }

.call__pane {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 16px; box-shadow: var(--sh-card);
}
.call__step {
  display: flex; align-items: center; gap: 9px; margin-bottom: 14px;
}
.call__num {
  width: 22px; height: 22px; border-radius: 50%; background: var(--ink); color: #fff;
  display: grid; place-items: center; font-size: 11.5px; font-weight: 800; flex: 0 0 auto;
}
.call__num.is-done { background: var(--ok); }
.call__t { font-size: 14px; font-weight: 700; }

.phone-input {
  width: 100%; height: 54px; border: 1.5px solid var(--line-strong); border-radius: var(--r-md);
  padding-inline: 14px; font-family: var(--font-mono); font-size: 19px; letter-spacing: .04em;
  background: var(--surface); color: var(--ink);
}
.phone-input:focus { border-color: var(--brand); outline: none; }

.caller {
  border: 1.5px solid var(--line); border-radius: var(--r-md); padding: 12px;
  cursor: pointer; margin-top: 8px; background: var(--surface);
}
.caller:hover { border-color: var(--line-strong); }
.caller.is-on { border-color: var(--brand); background: var(--brand-tint); }
.caller__n { font-size: 14px; font-weight: 700; }
.caller__p { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-55); margin-top: 2px; }
.caller__m { font-size: 12px; color: var(--ink-42); margin-top: 6px; line-height: 1.45; }

.pickitem {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border-radius: 9px; cursor: pointer; border: 1px solid transparent;
}
.pickitem:hover, .pickitem.is-cursor { background: var(--page); border-color: var(--line); }
.pickitem__n { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; }
.pickitem__p { font-size: 13px; font-weight: 700; white-space: nowrap; }
.pickitem.is-out { opacity: .45; cursor: not-allowed; }
.picklist { max-height: 460px; overflow-y: auto; margin-top: 10px; }

.callline {
  display: flex; align-items: center; gap: 10px; padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.callline__n { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; line-height: 1.35; }
.callline__q { display: flex; align-items: center; gap: 8px; }
.callline__q button {
  width: 28px; height: 28px; border-radius: 7px; border: 1px solid var(--line-strong);
  background: var(--surface); cursor: pointer; font-size: 15px; line-height: 1;
}
.callline__t { font-size: 13.5px; font-weight: 700; width: 74px; text-align: end; white-space: nowrap; }

kbd {
  font-family: var(--font-mono); font-size: 11px; background: var(--page);
  border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 5px;
  padding: 1px 5px; color: var(--ink-70);
}

/* Tabs on detail pages ------------------------------------------------------
   A rider or branch record carries more than fits on one screen. Tabs keep
   each view scannable without hiding anything behind a menu. */
.tabs {
  display: flex; gap: 4px; border-bottom: 1px solid var(--line);
  margin-bottom: 18px; overflow-x: auto;
}
.tab-btn {
  border: 0; background: none; cursor: pointer; white-space: nowrap;
  padding: 11px 16px; font-family: var(--font-ui); font-size: 13.5px; font-weight: 600;
  color: var(--ink-55); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab-btn:hover { color: var(--ink); }
.tab-btn.is-on { color: var(--brand); border-bottom-color: var(--brand); font-weight: 700; }

/* Media library ------------------------------------------------------------
   The crop frame is the app's display shape, so what an operator sees inside
   the frame is exactly what a customer sees on the phone. */
.cropwrap {
  position: relative; background: #1A1A1A; border-radius: var(--r-md);
  overflow: hidden; touch-action: none; user-select: none;
}
.cropwrap canvas { display: block; width: 100%; height: auto; }
.cropbox {
  position: absolute; inset: 0; pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(20,22,26,.62);
  border: 2px solid rgba(255,255,255,.95); border-radius: 2px;
}
.cropbox::before, .cropbox::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-color: rgba(255,255,255,.28); border-style: solid;
}
.cropbox::before { border-width: 0 1px; left: 33.33%; right: 33.33%; }
.cropbox::after  { border-width: 1px 0; top: 33.33%; bottom: 33.33%; }

.range {
  width: 100%; accent-color: var(--brand); height: 30px; background: none; border: 0;
}

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.shot {
  margin: 0; border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; background: var(--surface);
}
.shot.is-primary { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-tint); }
.shot img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; }
.shot figcaption { padding: 12px; }

/* A photograph fills the same box the placeholder occupied, so a menu with
   some images and some briefs still lines up. */
.thumb--photo { object-fit: cover; background: var(--page); }

/* A vehicle carrying an order stands out from one heading back empty. */
.fleet-card.is-busy { border-inline-start: 3px solid var(--brand); }
.fleet-pin span { display: block; transition: transform .45s ease; }
.leaflet-tooltip { font-family: var(--font-ui); font-size: 12.5px; line-height: 1.45; }

/* ============================================================================
   SIDE MENU — everything that is not "order food"
   Keeping the wallet, past orders and support here leaves the home screen
   about the menu, and gives each of them a permanent place rather than being
   buried inside a tab.
   ============================================================================ */
.drawer {
  position: fixed; inset: 0; z-index: 120;
  background: rgba(21,21,21,.42);
  animation: fade .18s ease-out;
}
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }

.drawer__panel {
  position: absolute; inset-block: 0; inset-inline-start: 0;
  width: min(340px, 86vw); background: var(--bg);
  display: flex; flex-direction: column; overflow-y: auto;
  padding: calc(14px + env(safe-area-inset-top)) 18px calc(18px + env(safe-area-inset-bottom));
  animation: slideIn .22s ease-out;
}
/* Logical properties, so the panel comes from the right in Arabic without a
   second rule — which is the whole reason the layout uses them. */
@keyframes slideIn { from { transform: translateX(-100%) } to { transform: none } }
[dir="rtl"] .drawer__panel { animation-name: slideInRtl; }
@keyframes slideInRtl { from { transform: translateX(100%) } to { transform: none } }
@media (prefers-reduced-motion: reduce) {
  .drawer, .drawer__panel { animation: none; }
}

.drawer__head { display: flex; align-items: flex-start; gap: 12px; }
.drawer__name { font-size: 19px; font-weight: 700; line-height: 1.25; }
.drawer__meta { font-size: 13.5px; color: var(--ink-55); margin-top: 3px; }

.drawer__wallet {
  display: flex; justify-content: space-between; gap: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 14px 16px; margin-top: 16px;
  box-shadow: var(--sh-card);
}
.drawer__balance { font-size: 21px; font-weight: 800; margin-top: 5px; }

.drawer__live {
  display: flex; align-items: center; gap: 12px; width: 100%;
  background: var(--ink); color: #fff; border: 0; border-radius: var(--r-lg);
  padding: 14px 16px; margin-top: 12px; cursor: pointer; text-align: start;
}
.drawer__live .drawer__n { color: rgba(255,255,255,.7); }

.drawer__list { margin-top: 14px; display: grid; gap: 2px; }
.drawer__row {
  display: flex; align-items: center; gap: 14px; width: 100%;
  background: none; border: 0; cursor: pointer; text-align: start;
  padding: 14px 4px; border-bottom: 1px solid var(--line);
  font-family: var(--font-ui); color: var(--ink);
}
.drawer__row:last-child { border-bottom: 0; }
.drawer__i { color: var(--ink-55); display: grid; place-items: center; flex: 0 0 auto; }
.drawer__t { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.3; }
.drawer__n { display: block; font-size: 12.5px; color: var(--ink-55); margin-top: 3px; line-height: 1.4; }
.drawer__chev { color: var(--ink-35); flex: 0 0 auto; }
[dir="rtl"] .drawer__chev { transform: scaleX(-1); }

.drawer__lang {
  margin-top: 16px; width: 100%; height: 44px; border-radius: var(--r-md);
  border: 1px solid var(--line-strong); background: var(--surface);
  font-family: var(--font-ui); font-size: 15px; font-weight: 600; cursor: pointer;
}
.drawer__foot { margin-top: auto; padding-top: 18px; }

/* Support conversation ---------------------------------------------------- */
.chat { display: grid; gap: 10px; padding-bottom: 12px; }
.bubble__at { font-size: 10.5px; opacity: .62; margin-top: 5px; }
.composer { display: flex; gap: 10px; align-items: center; }
.composer .input { flex: 1; height: 48px; }

/* The rider's number, tappable. On a phone this dials; on a laptop it is
   still the number, which is what someone reads out to a colleague. */
.ridercard__phone {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 6px; font-size: 13.5px; font-weight: 600;
  color: var(--brand); text-decoration: none;
  font-variant-numeric: tabular-nums;
}

/* The menu button in the app bar. It has to be a real 44px target: the header
   sits under the notch on a phone and a small icon there is genuinely hard to
   hit with a thumb. */
.iconbtn {
  width: 44px; height: 44px; flex: 0 0 auto; margin-inline-start: -10px;
  display: grid; place-items: center; border: 0; background: none;
  color: var(--ink); cursor: pointer; border-radius: 50%;
}
.iconbtn:active { background: var(--page); }

/* Add to home screen ------------------------------------------------------
   Shown only where it can be completed, and dismissible for good — an install
   bar that returns on every visit is an advert, not an offer. */
.install {
  display: flex; align-items: center; gap: 12px;
  margin: 12px 20px 0; padding: 12px 14px;
  background: var(--ink); color: #fff; border-radius: var(--r-lg);
}
.install__i {
  width: 36px; height: 36px; border-radius: 10px; flex: 0 0 auto;
  background: rgba(255,255,255,.14); display: grid; place-items: center;
}
.install__t { font-size: 14px; font-weight: 700; line-height: 1.3; }
.install__n { font-size: 12px; color: rgba(255,255,255,.7); margin-top: 3px; line-height: 1.4; }
.install__go {
  flex: 0 0 auto; border: 0; border-radius: var(--r-sm); cursor: pointer;
  background: var(--brand); color: #fff; padding: 10px 16px;
  font-family: var(--font-ui); font-size: 13px; font-weight: 700;
}
.install__x {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  color: rgba(255,255,255,.6); display: grid; place-items: center;
  width: 32px; height: 32px;
}

/* Update prompt. Offered, never applied silently — reloading under someone
   mid-order would lose their basket. */
.updatebar {
  position: fixed; z-index: 300;
  inset-inline: 12px; bottom: calc(12px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 10px;
  background: var(--ink); color: #fff;
  border-radius: var(--r-lg); padding: 12px 12px 12px 16px;
  font-size: 14px; box-shadow: var(--sh-float);
}
.updatebar__go {
  border: 0; border-radius: var(--r-sm); cursor: pointer;
  background: var(--brand); color: #fff; padding: 9px 15px;
  font-family: var(--font-ui); font-size: 13px; font-weight: 700;
}
.updatebar__x {
  border: 0; background: none; color: rgba(255,255,255,.6);
  font-size: 20px; cursor: pointer; line-height: 1; padding: 0 4px;
}

/* ============================================================================
   VERTICAL RHYTHM
   The app had two spacing systems fighting each other: `.pad` is a flex column
   with `gap: 12px`, and individual elements also carried their own margins.
   So `hook → search` got 12 + 18 = 30px while `search → rail` got only the
   12px gap, and `dishcard + dishcard` got 12 + 10 = 22px. Measured across the
   home screen the gaps came out 12, 16, 22, 28, 30 — no rhythm at all, which
   is what reads as "too much here, none there".

   One system now. The gap is removed and spacing comes from sibling rules, so
   every pair is predictable and a heading can hug its own content while
   sections stay apart.
   ============================================================================ */
/* Browsers give h1–h6 and p a margin of their own — 0.83em on an h2, which is
   nearly 16px. Every heading in the app was therefore adding an invisible
   step on top of the layout's own spacing, which is most of why gaps looked
   arbitrary. The layout owns vertical space; the elements do not. */
:where(.app, .screen, .console-main) :where(h1, h2, h3, h4, p) { margin: 0; }

:root {
  --gap-tight:   10px;   /* heading to the thing it labels */
  --gap-block:   16px;   /* between blocks inside a section */
  --gap-section: 28px;   /* between sections */
}

.pad { gap: 0; }

/* Default step between any two blocks. */
.pad > * + * { margin-top: var(--gap-block); }

/* A heading belongs to what follows it, so it sits closer to it. */
.pad > .h2 + *,
.pad > .row:has(.h2) + * { margin-top: var(--gap-tight); }

/* …and further from whatever came before. */
.pad > * + .h2,
.pad > * + .row:has(.h2) { margin-top: var(--gap-section); }

/* The hook is the loudest thing on the screen and needs air after it, but its
   own margins were doubling with the gap. */
/* The hook carried margin of its own from design.css, which added to the
   section step and produced a 46px hole. The layout owns vertical space. */
.pad > .hook { margin-block: 0; }

/* The greeting is a lead-in to the hook, so they belong together. */
.pad > .greet + .hook { margin-top: 6px; }
.pad > .hook + * { margin-top: var(--gap-section); }

/* Cards in a list are siblings of equal weight; one step, not two. */
.dishcard + .dishcard,
.card + .card { margin-top: var(--gap-block); }

/* :has() is well supported now, but a browser without it must not collapse
   sections into each other. This keeps a sane fallback. */
@supports not (selector(:has(*))) {
  .pad > * + * { margin-top: var(--gap-block); }
}

/* The offer rail breaks out of the page padding to bleed off the edge, then
   re-inserts it so the first card still lines up with everything above. The
   scroll padding is what keeps that alignment when it snaps back. */
.rail {
  margin-inline: -20px;
  padding-inline: 20px;
  scroll-padding-inline: 20px;
}
/* Safari has historically dropped the trailing padding on a scroll container,
   which leaves the last card flush against the edge. This is immune to that. */
.rail::after { content: ""; flex: 0 0 4px; }

/* Category tiles: the label was 7px from its image and 10px from its
   neighbour, so the columns read as vertical pairs rather than a row. */
.cats { gap: 12px; }
.cat__label { margin-top: 8px; }

/* ============================================================================
   HOME BANNERS
   A scroll-snap strip rather than a JavaScript slider: swiping is the browser's
   own scrolling, so it is smooth on any phone, works with a trackpad, and
   still behaves if the script fails.
   ============================================================================ */
.banners { margin-top: 14px; }

.banners__strip {
  display: flex; overflow-x: auto;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  scrollbar-width: none; -ms-overflow-style: none;
  gap: 12px; padding-inline: 20px; scroll-padding-inline: 20px;
}
.banners__strip::-webkit-scrollbar { display: none; }

.banner {
  position: relative; flex: 0 0 100%; scroll-snap-align: center;
  border-radius: var(--r-lg); overflow: hidden; cursor: pointer;
  background: var(--page);
}
/* Fixed ratio, so the page never jumps as images load. */
.banner__img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }

/* Text is drawn over the image rather than baked into it, so it translates,
   stays sharp at any size, and can be read by a screen reader. The scrim is
   what keeps it legible over a photograph nobody has vetted. */
.banner__text {
  position: absolute; inset-inline: 0; bottom: 0; padding: 16px 18px;
  background: linear-gradient(to top, rgba(15,15,15,.82), rgba(15,15,15,.35) 55%, transparent);
  color: #fff;
}
.banner__title { font-size: 19px; font-weight: 800; line-height: 1.2; }
.banner__sub { font-size: 13px; line-height: 1.4; margin-top: 4px; opacity: .88; }

.banners__dots { display: flex; justify-content: center; gap: 6px; margin-top: 10px; }
.dot {
  width: 6px; height: 6px; border-radius: 50%; border: 0; padding: 0;
  background: var(--line-strong); cursor: pointer; transition: width .2s, background .2s;
}
.dot.is-on { width: 18px; border-radius: 3px; background: var(--brand); }

@media (prefers-reduced-motion: reduce) {
  .banners__strip { scroll-behavior: auto; }
}

/* ============================================================================
   HERO — one fixed panel, image and text set from the console.
   Not a carousel: it is the first thing on the screen and it should not move
   while someone is reading it.
   ============================================================================ */
.hero {
  position: relative; overflow: hidden;
  background: var(--ink);
  min-height: 208px; display: flex; align-items: flex-end;
}
.hero__img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0;
}
/* The client will upload photographs nobody has seen. Without a scrim, white
   text lands on a pale plate sooner or later and becomes unreadable — so the
   gradient is not decoration, it is what makes the text safe on any image. */
.hero--photo::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg,
              rgba(12,12,12,.10) 0%,
              rgba(12,12,12,.52) 55%,
              rgba(12,12,12,.82) 100%);
}
.hero__body { position: relative; z-index: 2; padding: 20px; color: #fff; }
.hero__greet { font-size: 13.5px; color: rgba(255,255,255,.82); }
.hero__line {
  margin: 6px 0 0; font-size: 27px; line-height: 1.18;
  font-weight: 700; letter-spacing: -.01em; text-wrap: balance;
}
.hero__sub { margin: 8px 0 0; font-size: 13.5px; color: rgba(255,255,255,.78); }
.hero[data-hero] { cursor: pointer; }

/* ============================================================================
   OFFERS — many, each on its own photograph, swiped with dots.
   This is where movement belongs: someone scanning offers expects to move
   through them.
   ============================================================================ */
.offers { margin-top: 16px; }
.poffer {
  position: relative; flex: 0 0 84%; scroll-snap-align: start;
  min-height: 168px; border-radius: var(--r-lg); overflow: hidden;
  background: var(--brand); display: flex; align-items: flex-end;
  cursor: pointer;
}
.poffer__img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0;
}
.poffer::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg,
              rgba(120,18,22,.20) 0%,
              rgba(120,18,22,.58) 50%,
              rgba(96,14,18,.88) 100%);
}
.poffer__body { position: relative; z-index: 2; padding: 16px; color: #fff; }
.poffer__eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--gold);
}
.poffer__title { margin-top: 6px; font-size: 19px; font-weight: 700; line-height: 1.22; }
.poffer__note { margin-top: 6px; font-size: 12.5px; color: rgba(255,255,255,.8); line-height: 1.4; }

.offers__dots { display: flex; gap: 6px; justify-content: center; margin-top: 12px; }
.dot {
  width: 6px; height: 6px; padding: 0; border: 0; border-radius: 999px;
  background: var(--line-strong); cursor: pointer;
  transition: width .18s ease, background .18s ease;
}
.dot.is-on { width: 20px; background: var(--brand); }

/* ============================================================================
   OPTION ROWS
   The portion and add-on lists were built at card scale — 15px of padding and
   a 10px gap on every row. On a dish with three sizes and six add-ons that is
   most of a screen of empty space, and the customer has to scroll past it to
   reach Add to cart.

   Tightened to list scale. The rows are still a comfortable 48px target, well
   above the 44px minimum, so nothing has become harder to tap.
   ============================================================================ */
.choice { padding: 11px 14px; gap: 12px; }
.choice + .choice { margin-top: 7px; }
.choice__t { font-size: 14.5px; }
.choice__d { font-size: 12px; }

/* A group heading belongs to the rows under it, so it sits close to them and
   further from the group above. */
.group-head { margin: 20px 0 8px; }
.pad > .group-head + * { margin-top: 0; }
.pad > .choice + .choice { margin-top: 7px; }

/* More air at the page edge. Text starting 20px from the edge of a phone reads
   as cramped once the rows themselves are tight — the two work together. */
.pad { padding-inline: 24px; }
.appbar { padding-inline: 24px; }

/* `scrollbar-gutter: both-edges` reserves space inside the SHELL as well when
   the shell is the scroll container, which pushed its content 30px right and
   9px left — the asymmetry visible in the item screen. The centred shell does
   not need it; reserving the gutter on the page is enough and leaves the app
   itself untouched. */
/* Reserve the scrollbar's width on BOTH sides of the page, so a centred shell
   stays centred whether or not the page is scrollable. Reserving it on one
   side only — which is the default — moves the shell left by half the
   scrollbar width the moment content grows past the viewport, which is the
   uneven margin visible on the item screen. */
/* Only above the shell's own width. A phone has an overlay scrollbar that
   takes no space, so reserving a gutter there just eats 30px of a 390px
   screen — which it did, until this was measured. */
@media (min-width: 481px) {
  html { scrollbar-gutter: stable both-edges; }
}
/* The shell must never reserve it again inside itself. */
.app-shell { scrollbar-gutter: auto; }

/* ============================================================================
   OPTION ROWS — final tightening
   A 23px gap was still showing in the app. That figure is what you get from
   the flex gap on `.pad` (12px) plus the row's own margin (10px), which means
   the earlier rhythm rules were not winning where it mattered.

   Rather than add another rule to the argument, this states the outcome once,
   at a specificity nothing else in the file reaches, and switches off the
   competing flex gap at the same time.
   ============================================================================ */
.app .pad,
.screen .pad { row-gap: 0; }

.app .pad > .choice + .choice,
.screen .pad > .choice + .choice,
.app .choice + .choice { margin-top: 6px; }

/* The name and its "Serves 3-4" sit in the same line, so they need their own
   space — the row gap does not reach inside them. Without this they run
   together as "Family packServes 3-4". */
.app .choice, .screen .choice { padding: 10px 14px; gap: 12px; }
.app .choice__t, .screen .choice__t { margin-inline-end: 7px; }

/* Heading sits close to the rows it labels, further from the group above. */
.app .pad > .group-head, .screen .pad > .group-head { margin: 18px 0 7px; }
.app .pad > .group-head + .choice { margin-top: 0; }

/* Marker: if this line is not in the app.css your server is serving, the file
   is stale and none of the spacing work above is live. */
:root { --serveo-css: "options-tightened-2"; }

/* ============================================================================
   DELIVERY LOCATIONS
   ============================================================================ */
.loccard {
  border: 1.5px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); padding: 14px; cursor: pointer;
}
.loccard + .loccard { margin-top: 8px; }
.loccard.is-on { border-color: var(--brand); background: var(--brand-tint); }
.addrcard__label { font-size: 14.5px; font-weight: 700; }
.addrcard__line { font-size: 13.5px; margin-top: 4px; line-height: 1.4; }
.addrcard__sub { font-size: 12.5px; color: var(--ink-55); margin-top: 3px; line-height: 1.4; }

/* The pin sits fixed at the centre and the map moves underneath it. Dragging a
   marker means the thumb covers the exact spot being chosen; moving the map
   keeps the target visible the whole time. */
/* A fixed height rather than a viewport fraction. dvh changes as the address
   bar collapses on a phone, which resizes the map mid-gesture; a stable box
   keeps the pin where the thumb left it. */
.pinwrap { position: relative; height: 320px; }
@media (min-height: 780px) { .pinwrap { height: 380px; } }
.locmap { position: absolute; inset: 0; }
.pinmark {
  position: absolute; left: 50%; top: 50%; z-index: 500;
  transform: translate(-50%, -100%);
  color: var(--brand); pointer-events: none;
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.32));
}
.pinmark svg { width: 38px; height: 38px; }
/* A dot at the true centre, because the pin's point is above it. */
.pinmark::after {
  content: ""; position: absolute; left: 50%; bottom: -5px; width: 6px; height: 6px;
  transform: translateX(-50%); border-radius: 50%; background: var(--brand);
  box-shadow: 0 0 0 2px rgba(255,255,255,.9);
}
.pinme {
  position: absolute; z-index: 500; inset-inline-end: 14px; bottom: 14px;
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); cursor: pointer;
  display: grid; place-items: center; box-shadow: var(--sh-card);
}

.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  border: 1.5px solid var(--line); border-radius: 999px; background: var(--surface);
  padding: 9px 16px; font-family: var(--font-ui); font-size: 13.5px; font-weight: 600;
  cursor: pointer; color: var(--ink);
}
.chip.is-on { border-color: var(--brand); background: var(--brand-tint); color: var(--brand); }

/* The demo one-time code. Deliberately looks like a note pinned to the screen
   rather than part of the interface — nobody should mistake it for something
   that ships. Tapping it fills the box. */
.democode {
  display: grid; gap: 3px; width: 100%; margin-top: 18px; cursor: pointer;
  text-align: start; border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-md); background: var(--page); padding: 14px 16px;
  font-family: var(--font-ui); color: var(--ink);
}
.democode__k { font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-42); }
.democode__v { font-size: 30px; font-weight: 800; letter-spacing: .22em;
  font-variant-numeric: tabular-nums; }
.democode__n { font-size: 12px; color: var(--ink-55); }

.otpinput {
  font-size: 26px; font-weight: 700; letter-spacing: .5em;
  text-align: center; height: 62px;
}


/* The pin lifts while the map is dragged, so it reads as anchored to the
   centre rather than frozen. The interaction is the opposite of what most
   people try first, so it has to announce itself. */
.pinmark { transition: transform .16s ease; }
.pinmark.is-lifted { transform: translate(-50%, -108%) scale(1.06); }

.pinhint {
  position: absolute; z-index: 500; left: 50%; top: 12px;
  transform: translateX(-50%);
  background: rgba(21,21,21,.78); color: #fff;
  font-size: 12.5px; font-weight: 600; padding: 7px 13px; border-radius: 999px;
  pointer-events: none; white-space: nowrap;
  transition: opacity .25s ease;
}
.pinhint.is-hidden { opacity: 0; }

/* Who you are, at the foot of the menu. Quiet, but present — an app that
   cannot tell you which account you are in is an app you stop trusting with a
   saved card. */
.signedin {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--r-md);
  background: var(--page); border: 1px solid var(--line);
}
.signedin__i { color: var(--ink-55); display: grid; place-items: center; }
.signedin__k { display: block; font-size: 11px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-42); }
.signedin__v { display: block; font-size: 13.5px; font-weight: 600; margin-top: 2px;
  font-variant-numeric: tabular-nums; }

/* Back control on the tracking map.
   The map runs to the top edge by design — there is no app bar to put a back
   button in — so it floats over the map instead of pushing it down. Without
   it the tracking screen was a dead end: no header, no way home. */
.map__back {
  position: absolute; z-index: 30;
  inset-block-start: calc(14px + env(safe-area-inset-top));
  inset-inline-start: 14px;
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  display: grid; place-items: center; cursor: pointer; box-shadow: var(--sh-card);
}
/* Mirrors with the language: the arrow must point the way back, not left. */
[dir="rtl"] .map__back svg { transform: scaleX(-1); }

/* Menu button on a dark header.
   `.iconbtn` inherits the ink colour, which is nearly the same as the online
   header's background — the control was there but invisible. The earnings
   header is dark for the same reason. */
.iconbtn--light { color: #fff; }
.iconbtn--light:active { background: rgba(255,255,255,.14); }

/* ============================================================================
   KANBAN DRAG AND DROP
   The board was read-only — cards were plain links with no drag handling.
   These states make a drag legible: what is moving, where it may go, and
   where it will land.
   ============================================================================ */
.ocard[draggable="true"] { cursor: grab; }
.ocard.is-dragging { opacity: .45; cursor: grabbing; }
.ocard.is-saving { opacity: .5; pointer-events: none; }

/* Only the columns this order can legally reach light up, so an impossible
   move looks impossible instead of being silently refused by the server. */
.board__col.is-droppable { outline: 1.5px dashed var(--line-strong); outline-offset: -4px; }
.board__col.is-over {
  outline: 2px solid var(--brand); outline-offset: -4px;
  background: var(--brand-tint);
}
.board__col.is-droppable, .board__col.is-over { border-radius: var(--r-lg); }

/* Running orders on the home screen.
   The home screen never mentioned an order in progress — the only ways to
   reach tracking were the side menu and the Orders tab. One row per running
   order, because a customer can easily have two. */
.livebar {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: 1.5px solid var(--brand); border-radius: var(--r-md);
  background: var(--brand-tint); padding: 11px 14px; cursor: pointer;
  font-family: var(--font-ui); color: var(--ink); text-align: start;
}
.livebar + .livebar { margin-top: 8px; }
.livebar__t { display: block; font-size: 14px; font-weight: 700; }
.livebar__n { display: block; font-size: 12px; color: var(--ink-55); margin-top: 2px; }
.livebar__a { font-size: 13px; font-weight: 700; color: var(--brand); white-space: nowrap; }

/* ============================================================================
   HQ KITCHEN
   The branch kitchen view, in the console. Large type and high contrast: it is
   the same information a kitchen screen shows, and it should be readable at a
   glance rather than studied.
   ============================================================================ */
.kitchen {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  align-items: start;
}
.kt {
  border: 1.5px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); padding: 16px; display: flex; flex-direction: column; gap: 10px;
}
/* Late tickets announce themselves. A kitchen screen is glanced at, not read. */
.kt.is-late { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(192,39,45,.10); }
.kt.is-ready { border-color: #1E8E5A; background: rgba(30,142,90,.05); }
.kt.is-new { animation: ktIn .5s ease; }
@keyframes ktIn { from { transform: translateY(-6px); opacity: 0; } to { transform: none; opacity: 1; } }

.kt__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.kt__ref { font-family: var(--font-mono); font-size: 13px; font-weight: 700; letter-spacing: .06em; }
.kt__branch { font-size: 12px; color: var(--ink-55); margin-top: 2px; }
.kt__age {
  font-size: 26px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: 3px;
}
.kt__age span { font-size: 11px; font-weight: 600; color: var(--ink-42); }
.kt__age.is-late { color: var(--brand); }

.kt__tags { display: flex; flex-wrap: wrap; gap: 6px; }
.kt__lines { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.kt__lines li { display: flex; gap: 10px; align-items: baseline; }
.kt__qty { font-weight: 800; font-variant-numeric: tabular-nums; min-width: 26px; }
.kt__item { display: block; font-size: 15px; font-weight: 700; line-height: 1.25; }
.kt__mods { display: block; font-size: 12.5px; color: var(--ink-55); margin-top: 2px; }

.kt__allergen {
  font-size: 12.5px; font-weight: 700; color: var(--brand);
  background: var(--brand-tint); border-radius: 8px; padding: 8px 10px;
}
.kt__note { font-size: 12.5px; color: var(--ink-55); font-style: italic; }

.kt__foot { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 2px; }
.kt__total { font-weight: 700; font-variant-numeric: tabular-nums; }
.kt__go { width: auto; padding-inline: 18px; height: 40px; }
.kt__done { font-size: 12.5px; color: var(--ink-55); }

/* Demo account picker on the staff login page.
   Typing a username and password in front of a client is dead time, and
   mistyping one is worse. Two columns so all eight fit without scrolling. */
.logins { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 10px; }
.loginpick {
  display: grid; gap: 2px; text-align: start; cursor: pointer;
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
  padding: 8px 10px; font-family: var(--font-ui); color: var(--ink);
}
.loginpick:hover { border-color: var(--brand); background: var(--brand-tint); }
.loginpick__u { font-family: var(--font-mono); font-size: 11.5px; font-weight: 700; }
.loginpick__r { font-size: 10.5px; color: var(--ink-55); line-height: 1.3; }

/* The rider install bar stacks: "Add Serveo Fleet to your home screen" beside a
   button squeezed the title into three lines on a phone. */
.install--stack { display: block; }
.install--stack .row { display: flex; align-items: flex-start; gap: 10px; }
.install--stack .install__go { width: 100%; margin-top: 12px; }

/* ---------------------------------------------------------------- chat
   The bubble and the sheet it opens. Everything is scoped under #serveoChat
   so none of it can reach a screen the customer app already renders — the
   widget mounts into its own element and styles only what is inside it.

   Bottom sheet on a phone, floating panel from 560px up, which is the
   breakpoint the rest of the app already changes at. */
/* The app is a 480px column centred in the window, so a bubble fixed to the
   viewport lands far out to the right of it on a desktop — off the app
   entirely, which is why it looked missing. This pins it to the column's own
   right edge, and falls back to the viewport edge once the window is narrower
   than the column. */
#serveoChat .chatfab {
  position: fixed;
  inset-inline-end: max(16px, calc(50% - 240px + 16px));
  bottom: calc(76px + env(safe-area-inset-bottom));
  width: 52px; height: 52px; border-radius: 50%; border: 0;
  background: var(--brand); color: #fff; display: grid; place-items: center;
  box-shadow: 0 6px 20px rgba(0,0,0,.22); cursor: pointer; z-index: 60;
}
#serveoChat .chatsheet {
  position: fixed; inset-inline: 0; bottom: 0; top: 0;
  background: var(--surface); display: flex; flex-direction: column; z-index: 70;
}
#serveoChat .chatsheet__bar {
  display: flex; align-items: center; gap: 12px; padding: 16px;
  border-bottom: 1px solid var(--line);
}
#serveoChat .chatsheet__t { font-weight: 700; font-size: 16px; }
#serveoChat .chatsheet__n { font-size: 12px; color: var(--ink-42); margin-top: 2px; }
#serveoChat .chatsheet__x {
  margin-inline-start: auto; border: 0; background: none; font-size: 26px;
  line-height: 1; cursor: pointer; color: var(--ink-42); padding: 0 4px;
}
#serveoChat .chatlog {
  flex: 1; overflow-y: auto; padding: 16px;
  display: flex; flex-direction: column; gap: 10px;
}
#serveoChat .chatrow { max-width: 82%; align-self: flex-start; }
#serveoChat .chatrow--mine { align-self: flex-end; }
#serveoChat .chatrow__k { font-size: 11px; color: var(--ink-42); margin-bottom: 3px; }
#serveoChat .chatbubble {
  background: #f1ede8; border-radius: 14px;
  padding: 10px 13px; font-size: 14.5px; line-height: 1.45; white-space: pre-wrap;
}
#serveoChat .chatbubble--mine { background: var(--brand); color: #fff; }
#serveoChat .chatnote {
  align-self: center; font-size: 12px; color: var(--ink-42);
  text-align: center; padding: 2px 8px;
}
#serveoChat .chatsheet__foot {
  display: flex; gap: 8px; align-items: flex-end; padding: 12px 16px;
  border-top: 1px solid var(--line);
}
#serveoChat .chatinput {
  flex: 1; resize: none; border: 1px solid var(--line); border-radius: 12px;
  padding: 11px 13px; font: inherit; font-size: 15px; max-height: 110px;
  background: var(--surface);
}
#serveoChat .chatsend {
  width: 42px; height: 42px; border-radius: 12px; border: 0; flex: none;
  background: var(--brand); color: #fff; display: grid; place-items: center; cursor: pointer;
}
#serveoChat .chathuman {
  border: 0; background: none; color: var(--brand); font: inherit; font-size: 13px;
  font-weight: 600; padding: 0 16px calc(14px + env(safe-area-inset-bottom)); cursor: pointer;
  text-align: center;
}

@media (min-width: 560px) {
  /* Aligned to the same column edge as the bubble, so the panel opens over
     the app rather than against the browser frame. */
  #serveoChat .chatsheet {
    inset: auto; inset-inline-end: max(20px, calc(50% - 240px + 16px)); bottom: 20px;
    width: 380px; height: 560px; max-height: 80vh;
    border-radius: 18px; border: 1px solid var(--line);
    box-shadow: 0 18px 50px rgba(0,0,0,.20); overflow: hidden;
  }
  #serveoChat .chatfab { bottom: 20px; }
}
