/* ==========================================================================
   Sayless Logistics — customer app.
   A standalone SPA shell. On a phone it is full-bleed and IS the app; on a
   desktop it renders inside a device frame so the demo reads as a product,
   not a web page. Shares the site's palette so the two feel like one brand.
   ========================================================================== */

:root{
  --navy:#071a3d;
  --navy-2:#0c2555;
  --navy-3:#12336f;
  --blue:#1e5ae8;
  --blue-dark:#1543b8;
  --blue-soft:#eaf0fe;
  --gold:#e4b93f;
  --gold-deep:#c9a227;
  --gold-text:#7a600a;  /* 5.5:1 on gold-soft */
  --gold-soft:#fdf6e3;
  --white:#fff;
  --surface:#f4f7fb;
  --surface-2:#e9eff7;
  --line:#e2e8f0;
  --line-strong:#cbd5e1;
  --ink:#0a1b33;
  --ink-2:#3d4a5c;
  --ink-3:#5a6a7f;      /* 5.2:1 on surface — #6b7a90 was 4.36 and failed AA */
  --good:#0a7a42;       /* 4.8:1 on good-soft — #0f9d58 was 3.1 and failed AA */
  --good-soft:#e7f6ee;
  --warn:#b45309;
  --warn-soft:#fef3c7;
  --bad:#dc2626;
  --bad-soft:#fef2f2;
  /* Body and label text never renders below 14px. Micro-labels (tab bar,
     calendar day names, chips) are the documented exception at 12px, which is
     platform convention for those specific controls. */
  --fs-min:.875rem;
  --fs-micro:12px;
  --r:12px;
  --r-lg:18px;
  --r-sm:8px;
  --tab-h:64px;
  --top-h:56px;
  --ease:cubic-bezier(.22,.61,.36,1);
  /* Safe-area insets go through variables so a test can set them to a real
     device value — env() itself is always 0 in a headless browser, so a rule
     written directly against env() can never be proven to work. */
  --sat:env(safe-area-inset-top,0px);
  --sab:env(safe-area-inset-bottom,0px);
  --sal:env(safe-area-inset-left,0px);
  --sar:env(safe-area-inset-right,0px);
  --sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --display:'Sora',var(--sans);
  --shadow:0 8px 28px rgba(7,26,61,.10);
  --shadow-lg:0 20px 50px rgba(7,26,61,.18);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;font:400 16px/1.55 var(--sans);color:var(--ink-2);
  -webkit-tap-highlight-color:transparent;
  background:var(--surface);-webkit-font-smoothing:antialiased;
  overscroll-behavior-y:none;
}
img,svg{display:block;max-width:100%}
h1,h2,h3,h4{margin:0;font-family:var(--display);font-weight:800;color:var(--ink);letter-spacing:-.02em;line-height:1.2}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
button,input,select,textarea{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer}
a{color:var(--blue);text-decoration:none}
:focus-visible{outline:3px solid var(--gold);outline-offset:2px;border-radius:6px}
[hidden]{display:none!important}

/* ---------------------------------------------------------- device frame */
/* The height chain must be unbroken from the viewport down to .app, or a
   percentage height resolves against an auto-height ancestor, silently falls
   back to CONTENT height, and the app bursts out of the phone frame:
     mobile   .stage -> #tpApp(100dvh) -> #tpAppRoot(100%) -> .app(100%)
     desktop  .device(fixed) -> #tpApp(100%) -> #tpAppRoot(100%) -> .app(100%)
   #tpAppRoot was added later (to keep the toast outside the swapped region) and
   was the link that had no height. */
.stage{min-height:100dvh;display:block;background:var(--surface)}
#tpApp{position:relative;display:block;height:100dvh;overflow:hidden}
#tpAppRoot{height:100%}

@media (min-width:900px){
  /* height, not min-height, and the device sizes off the PADDED content box.
     Subtracting a guessed 2rem while the padding was clamp(1rem,3vh,2.5rem) per
     side left the page scrollable by the difference — 16px at 1280x800. */
  .stage{
    --pad:clamp(.75rem,3vh,2.5rem);
    height:100dvh;overflow:hidden;
    display:flex;align-items:center;justify-content:center;
    padding:var(--pad);
    background:
      radial-gradient(90% 70% at 80% 6%,rgba(228,185,63,.16),transparent 62%),
      radial-gradient(80% 60% at 12% 96%,rgba(30,90,232,.07),transparent 60%),
      linear-gradient(180deg,#ffffff 0%,#f6f8fc 100%);
  }

  /* ------------------------------------------------------ the phone frame
     Natural geometry in fixed CSS px, then the WHOLE frame is scaled by one
     transform. This is the New Leaf deck's approach and it is the reason that
     frame never drifts: every relationship is written once, as a literal, so it
     cannot be re-derived wrongly at some other zoom level.

       screen  392 x 844   (the app's own layout size — never scaled separately)
       bezel   11 a side
       outer   414 x 866
       radii   inner 51, outer 62 — concentric BY CONSTRUCTION, 62 = 51 + 11

     The previous version multiplied a variable by six different fractions and
     recomputed the radii from it. It looked correct at exactly one viewport and
     wrong at every other, because a fraction of a fraction cannot hold
     `outer = inner + bezel` across rounding. Literals can. */
  /* Every dimension is a fixed literal MULTIPLIED BY --k, which fitDevice()
     sets. That keeps New Leaf's guarantee — `62 = 51 + 11` scales to
     `62k = 51k + 11k`, so the radii stay concentric at every size exactly — while
     keeping the frame OUT of its own compositing layer.

     Why that matters: a `transform` (like a `filter`) promotes the element to a
     GPU layer, and a composited layer sitting directly on the stage's gradient
     shows a faint rectangular seam at its bounds, with the corners poking out
     past the rounded silhouette. That is the grey box. It does not reproduce in
     a headless software renderer, so the rule is: nothing that sits on the
     gradient may be composited. The app inside still needs a transform — it is
     laid out at its own 392x844 — but that one sits over flat white, inside an
     overflow:hidden rounded screen, where a seam has no gradient to band against.

       screen  392k x 844k     bezel 11k       outer 414k x 866k
       radii   inner 51k, outer 62k */
  .device{
    --bez:calc(11px * var(--k,1));
    --r-in:calc(51px * var(--k,1));
    --r-out:calc(62px * var(--k,1));
    position:relative;flex:none;
    /* OUTER dimensions: box-sizing is border-box globally, so the padding is
       inside these and the content box lands on exactly 392k x 844k. Writing the
       screen size here instead left #tpApp overflowing by two bezels. */
    width:calc(414px * var(--k,1));
    height:calc(866px * var(--k,1));
    padding:var(--bez);
    border-radius:var(--r-out);
    box-shadow:0 34px 70px rgba(7,26,61,.26),0 8px 20px rgba(7,26,61,.13);
  }
  /* The rail is its own layer so the metal gradient can run under the screen
     without tinting it, and so the frame keeps a hairline highlight the way a
     machined edge does. A flat fill reads as a rounded rectangle, not a phone. */
  .device__rail{
    position:absolute;inset:0;border-radius:var(--r-out);z-index:0;
    background:linear-gradient(146deg,
      #3d4a63 0%,#1b2740 16%,#0e1830 34%,#35415c 52%,
      #14203a 72%,#33405a 88%,#111c33 100%);
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.10),
               inset 0 1px 0 rgba(255,255,255,.16);
  }
  .device__btn{
    position:absolute;width:calc(3.5px * var(--k,1));z-index:0;
    border-radius:calc(2px * var(--k,1));
    background:linear-gradient(180deg,#48566f,#1a2540);
    left:calc(-3px * var(--k,1));
  }
  .device__btn--act{top:calc(133px * var(--k,1));height:calc(30px * var(--k,1))}
  .device__btn--vup{top:calc(186px * var(--k,1));height:calc(55px * var(--k,1))}
  .device__btn--vdn{top:calc(251px * var(--k,1));height:calc(55px * var(--k,1))}
  .device__btn--pwr{
    left:auto;right:calc(-3px * var(--k,1));
    top:calc(196px * var(--k,1));height:calc(90px * var(--k,1));
  }
  /* Dynamic Island, proportioned off the 392 screen the way New Leaf's is off
     its 440: 112 x 33 with a 16.5 radius, sitting 12px below the bezel. */
  .device__island{
    position:absolute;left:50%;transform:translateX(-50%);
    top:calc(var(--bez) + 12px * var(--k,1));
    width:calc(112px * var(--k,1));
    height:calc(33px * var(--k,1));
    border-radius:calc(16.5px * var(--k,1));
    background:#0a1424;z-index:60;pointer-events:none;
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.12);
  }
  /* Kept very light so it never fights the UI underneath. */
  .device__sheen{
    position:absolute;inset:var(--bez);border-radius:var(--r-in);
    z-index:55;pointer-events:none;
    background:linear-gradient(122deg,rgba(255,255,255,.10) 0%,rgba(255,255,255,0) 34%);
  }
  /* The screen. Laid out at the phone's own 392x844 and scaled by transform —
     the ONE transform in the frame, and it sits over flat white. */
  #tpApp{
    position:relative;z-index:10;
    width:392px;height:844px;border-radius:51px;
    transform:scale(var(--k,1));transform-origin:top left;
  }
}

.app{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  height:100%;background:var(--surface);
}
@media (min-width:900px){.app{border-radius:51px}}

.app__top{
  flex:none;display:flex;align-items:center;gap:.75rem;
  min-height:calc(var(--top-h) + var(--sat));
  padding:calc(.5rem + var(--sat)) calc(1rem + var(--sar)) .5rem calc(1rem + var(--sal));
  background:var(--white);border-bottom:1px solid var(--line);z-index:20;
}
@media (min-width:900px){.app__top{padding-top:2.6rem;min-height:calc(var(--top-h) + 2rem)}}
.app__top h2{font-size:1.06rem;flex:1 1 auto;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app__top--navy{background:var(--navy);border-bottom-color:transparent}
.app__top--navy h2{color:#fff}
.iconbtn{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:44px;height:44px;border-radius:50%;color:var(--ink);position:relative;
  transition:background-color .18s;
}
.iconbtn:hover{background:var(--surface-2)}
.app__top--navy .iconbtn{color:#fff}
.app__top--navy .iconbtn:hover{background:rgba(255,255,255,.12)}
.iconbtn__dot{
  position:absolute;top:9px;right:9px;width:9px;height:9px;border-radius:50%;
  background:var(--gold);border:2px solid var(--white);
}
.app__top--navy .iconbtn__dot{border-color:var(--navy)}

.app__body{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch}
.app__body::-webkit-scrollbar{width:0}
/* Every scrollable surface in the app hides its scrollbar, not just the body —
   the auth screens scroll too and were showing a track inside the phone frame. */
#tpApp,#tpApp *{scrollbar-width:none;-ms-overflow-style:none}
#tpApp ::-webkit-scrollbar,#tpApp::-webkit-scrollbar{width:0;height:0;display:none}
/* In landscape the notch is on the LEFT or RIGHT, so scrollable content needs
   the horizontal insets as much as the chrome does. */
.pad{padding:1rem calc(1rem + var(--sar)) 1.5rem calc(1rem + var(--sal))}

/* An installed app WILL be rotated — iOS ignores the manifest's orientation
   lock — and portrait chrome eats a third of a 390px-tall landscape viewport. */
@media (max-height:520px) and (orientation:landscape){
  :root{--tab-h:52px;--top-h:48px}
  .pad{padding-top:.75rem;padding-bottom:1rem}
  .auth{padding-top:calc(.9rem + var(--sat));padding-bottom:calc(.9rem + var(--sab))}
  .auth h1{font-size:1.5rem;margin:1rem 0 .5rem}
  .auth__brand{margin-bottom:.5rem}
  .tab{font-size:11px;gap:1px}
  .tab__ico{height:22px}
}

/* A hidden scrollbar leaves no signal that there is more below, so a clipped
   last card reads as broken rather than scrollable. The mask sits on the scroll
   container's own box, so it stays at the bottom edge while the content moves,
   and [data-more] is set only while something is actually below the fold. */
.auth[data-more="true"],
.app__body[data-more="true"]{
  -webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 44px),transparent 100%);
          mask-image:linear-gradient(180deg,#000 calc(100% - 44px),transparent 100%);
}

/* ------------------------------------------------------------- tab bar */
.tabs{
  flex:none;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  background:var(--white);border-top:1px solid var(--line);
  padding-bottom:var(--sab);padding-left:var(--sal);padding-right:var(--sar);z-index:20;
}
.tab{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  min-height:var(--tab-h);padding:.35rem .2rem;color:var(--ink-3);
  font-size:var(--fs-micro);font-weight:600;letter-spacing:.01em;transition:color .18s;
}
.tab svg{flex:none}
.tab[aria-current="page"]{color:var(--blue)}
.tab[aria-current="page"] .tab__ico{background:var(--blue-soft)}
.tab__ico{
  display:flex;align-items:center;justify-content:center;
  width:40px;height:26px;border-radius:13px;transition:background-color .2s var(--ease);
}

/* --------------------------------------------------------------- cards */
.card{
  background:var(--white);border:1px solid var(--line);border-radius:var(--r);
  padding:1rem;margin-bottom:.75rem;
}
.card--flush{padding:0;overflow:hidden}
.card--navy{background:var(--navy);border-color:transparent;color:#c9d6ee}
.card--navy h3,.card--navy h4{color:#fff}
.card__hd{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-bottom:.6rem}
.card__hd h3{font-size:1rem}
.sec{margin:1.25rem 0 .6rem;font:800 var(--fs-min)/1 var(--sans);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3)}
.sec:first-child{margin-top:0}

/* ------------------------------------------------------- the trip card */
.trip{
  position:relative;overflow:hidden;border-radius:var(--r-lg);
  background:linear-gradient(150deg,var(--navy) 0%,var(--navy-2) 60%,var(--navy-3) 100%);
  color:#c9d6ee;padding:1.15rem;margin-bottom:.75rem;
}
.trip::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(90% 70% at 95% 0%,rgba(228,185,63,.20),transparent 62%);
}
.trip > *{position:relative;z-index:1}
.trip__row{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem}
.trip__when{font:800 1.55rem/1.1 var(--display);color:#fff;letter-spacing:-.02em}
.trip__date{font-size:var(--fs-min);color:#8fa6cd;margin-top:.15rem}
.trip__leg{
  display:inline-flex;align-items:center;gap:.4rem;margin-top:.85rem;
  font-size:.875rem;font-weight:700;color:var(--gold);
}
.trip__path{display:grid;grid-template-columns:18px minmax(0,1fr);gap:.55rem .7rem;margin-top:.9rem}
.trip__pin{display:flex;align-items:center;justify-content:center;padding-top:.2em}
.trip__dot{width:9px;height:9px;border-radius:50%;background:var(--gold)}
.trip__dot--hollow{background:transparent;border:2px solid rgba(255,255,255,.55)}
.trip__line{grid-column:1;width:2px;height:14px;background:rgba(255,255,255,.22);margin-inline:auto}
.trip__place{font-size:.9rem;color:#fff;min-width:0}
.trip__place small{display:block;color:#8fa6cd;font-size:var(--fs-min)}
.trip__foot{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1rem}

/* --------------------------------------------------------------- chips */
.chip{
  display:inline-flex;align-items:center;gap:.35rem;
  min-height:26px;padding:.2rem .6rem;border-radius:13px;
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.02em;white-space:nowrap;
}
.chip--live{background:rgba(15,157,88,.18);color:#7ee2b0}
.chip--soon{background:rgba(228,185,63,.18);color:var(--gold)}
.chip--muted{background:rgba(255,255,255,.10);color:#c9d6ee}
.chip--ok{background:var(--good-soft);color:var(--good)}
.chip--warnk{background:var(--warn-soft);color:var(--warn)}
.chip--badk{background:var(--bad-soft);color:#b91c1c}   /* --bad was 4.37 on bad-soft */
.chip--info{background:var(--blue-soft);color:var(--blue)}
.chip--gold{background:var(--gold-soft);color:var(--gold-text)}
.pulse{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none;
  animation:pulse 1.6s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.75)}}
@media (prefers-reduced-motion:reduce){.pulse{animation:none}}

/* -------------------------------------------------------------- buttons */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  min-height:48px;padding:.7rem 1.15rem;border-radius:var(--r-sm);
  font-weight:700;font-size:.95rem;border:2px solid transparent;
  transition:background-color .18s,border-color .18s,transform .15s var(--ease),opacity .18s;
}
.btn:active{transform:scale(.985)}
.btn[disabled]{opacity:.45;pointer-events:none}
.btn--primary{background:var(--blue);border-color:var(--blue);color:#fff}
.btn--primary:hover{background:var(--blue-dark);border-color:var(--blue-dark)}
.btn--gold{background:var(--gold);border-color:var(--gold);color:var(--navy)}
.btn--gold:hover{background:var(--gold-deep);border-color:var(--gold-deep)}
.btn--ghost{border-color:var(--line-strong);color:var(--ink)}
.btn--ghost:hover{background:var(--surface-2)}
.btn--light{background:rgba(255,255,255,.14);color:#fff;border-color:transparent}
.btn--light:hover{background:rgba(255,255,255,.24)}
.btn--danger{background:var(--bad);border-color:var(--bad);color:#fff}
.btn--sm{min-height:44px;padding:.45rem .85rem;font-size:var(--fs-min)}
.btn--wide{width:100%}
.btnrow{display:flex;gap:.5rem;flex-wrap:wrap}
.btnrow .btn{flex:1 1 auto;min-width:0}

/* ------------------------------------------------------------- listrows */
.row{
  display:grid;grid-template-columns:42px minmax(0,1fr) auto;gap:.85rem;align-items:center;
  width:100%;padding:.8rem 0;text-align:left;border-bottom:1px solid var(--line);
}
.row:last-child{border-bottom:0}
.row__ico{
  display:flex;align-items:center;justify-content:center;width:42px;height:42px;flex:none;
  border-radius:var(--r-sm);background:var(--blue-soft);color:var(--blue);
}
.row__ico--gold{background:var(--gold-soft);color:var(--gold-text)}
.row__ico--good{background:var(--good-soft);color:var(--good)}
.row__ico--bad{background:var(--bad-soft);color:var(--bad)}
.row__ico--grey{background:var(--surface-2);color:var(--ink-3)}
.row__b{min-width:0}
.row__b b{display:block;font-size:.95rem;color:var(--ink);font-weight:700}
.row__b span{display:block;font-size:var(--fs-min);color:var(--ink-3);line-height:1.45}
.row__end{flex:none;color:var(--ink-3);font-size:.875rem;font-weight:600;text-align:right}
.row__end strong{display:block;color:var(--ink);font-size:.95rem}
button.row,a.row{cursor:pointer;text-decoration:none;color:inherit}
button.row:hover,a.row:hover{background:var(--surface)}

/* ---------------------------------------------------------------- forms */
.field{margin-bottom:.9rem;min-width:0}
.field label{display:block;margin-bottom:.35rem;font-size:var(--fs-min);font-weight:700;color:var(--ink)}
.input{
  width:100%;min-width:0;min-height:50px;padding:.7rem .85rem;
  background:var(--white);border:1px solid var(--line-strong);border-radius:var(--r-sm);
  font-size:1rem;transition:border-color .18s,box-shadow .18s;
}
.input:focus{border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft);outline:none}
.input::placeholder{color:#9aa8bd}
textarea.input{min-height:96px;resize:vertical}
select.input{appearance:none;padding-right:2.4rem;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%236b7a90' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .9rem center}
.hint{margin-top:.35rem;font-size:var(--fs-min);color:var(--ink-3);line-height:1.5}
.err{margin-top:.35rem;font-size:var(--fs-min);font-weight:600;color:var(--bad);display:none}
.field.bad .input{border-color:var(--bad)}
.field.bad .err{display:block}
.switch{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.8rem 0;border-bottom:1px solid var(--line)}
.switch:last-child{border-bottom:0}
.switch__t{min-width:0}
.switch__t b{display:block;font-size:.94rem;color:var(--ink)}
.switch__t span{display:block;font-size:var(--fs-min);color:var(--ink-3)}
.toggle{flex:none;width:52px;height:31px;border-radius:16px;background:var(--line-strong);
  position:relative;transition:background-color .2s var(--ease)}
.toggle::before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  height:44px}
.toggle::after{content:"";position:absolute;top:3px;left:3px;width:25px;height:25px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.25);transition:transform .2s var(--ease)}
.toggle[aria-pressed="true"]{background:var(--blue)}
.toggle[aria-pressed="true"]::after{transform:translateX(21px)}

/* -------------------------------------------------------------- segment */
.seg{display:flex;gap:.35rem;padding:.28rem;background:var(--surface-2);border-radius:10px}
.seg button{
  flex:1 1 0;min-width:0;min-height:40px;border-radius:8px;
  font-size:var(--fs-min);font-weight:700;color:var(--ink-2);
  transition:background-color .18s,color .18s,box-shadow .18s;
}
.seg button[aria-pressed="true"]{background:var(--white);color:var(--blue);box-shadow:0 1px 3px rgba(7,26,61,.12)}

/* ----------------------------------------------------------- week strip */
.week{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:.3rem;margin-bottom:1rem}
.day{
  display:flex;flex-direction:column;align-items:center;gap:.15rem;
  min-height:64px;padding:.45rem .1rem;border-radius:10px;border:1px solid var(--line);
  background:var(--white);transition:all .18s var(--ease);
}
.day small{font-size:var(--fs-micro);font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.day b{font-size:1rem;color:var(--ink);font-family:var(--display)}
.day i{width:5px;height:5px;border-radius:50%;background:var(--line-strong);font-style:normal}
.day[aria-pressed="true"]{background:var(--navy);border-color:var(--navy)}
.day[aria-pressed="true"] small{color:#8fa6cd}
.day[aria-pressed="true"] b{color:#fff}
.day[data-booked="1"] i{background:var(--good)}
.day[aria-pressed="true"][data-booked="1"] i{background:var(--gold)}
.day[disabled]{opacity:.4}

/* ---------------------------------------------------------------- map */
.map{
  position:relative;border-radius:var(--r);overflow:hidden;
  background:linear-gradient(160deg,#0d1f42,#123063);aspect-ratio:1/1;margin-bottom:.75rem;
}
.map svg{width:100%;height:100%;display:block}
.map__road{fill:none;stroke:rgba(255,255,255,.08);stroke-width:6;stroke-linecap:round}
.map__route{fill:none;stroke:var(--gold);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.map__done{fill:none;stroke:#7ee2b0;stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}
.map__stop{fill:#0d1f42;stroke:var(--gold);stroke-width:2.4}
.map__stop--done{fill:#7ee2b0;stroke:#7ee2b0}
.map__stop--you{fill:var(--gold);stroke:#fff;stroke-width:2.5}
.map__veh{fill:#fff;stroke:var(--navy);stroke-width:1.5}
.map__label{fill:#8fa6cd;font:600 11px var(--sans)}
.map__badge{
  position:absolute;left:.75rem;top:.75rem;display:inline-flex;align-items:center;gap:.4rem;
  padding:.35rem .7rem;border-radius:14px;background:rgba(7,26,61,.82);
  color:#fff;font-size:var(--fs-min);font-weight:700;backdrop-filter:blur(6px);
}
.map__eta{
  position:absolute;right:.75rem;bottom:.75rem;padding:.5rem .8rem;border-radius:10px;
  background:rgba(255,255,255,.95);color:var(--ink);backdrop-filter:blur(6px);
}
.map__eta b{display:block;font-family:var(--display);font-size:1.1rem;line-height:1.1}
.map__eta span{display:block;font-size:var(--fs-min);color:var(--ink-3)}

/* --------------------------------------------------------- driver card */
.driver{display:grid;grid-template-columns:56px minmax(0,1fr) auto;gap:.85rem;align-items:center}
.avatar{
  width:56px;height:56px;border-radius:50%;flex:none;overflow:hidden;
  background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;
  font-family:var(--display);font-weight:800;font-size:1.15rem;
}
.avatar img{width:100%;height:100%;object-fit:cover}
.avatar--sm{width:40px;height:40px;font-size:.9rem}
.driver__b b{display:block;font-size:1rem;color:var(--ink)}
.driver__b span{display:block;font-size:var(--fs-min);color:var(--ink-3)}
/* Bright gold stars are 1.86:1 on white, and in the trips list the stars ARE the
   rating — no number beside them — so they must meet contrast, not just look
   decorative. Text-grade gold on light, bright gold where the ground is dark. */
.stars{color:var(--gold-text);font-size:var(--fs-min);letter-spacing:.06em}
.card--navy .stars,.trip .stars,.on-dark .stars{color:var(--gold)}
.driver__b .plate,
.plate{
  display:inline-block;margin-top:.25rem;padding:.1rem .45rem;border-radius:4px;
  background:var(--surface-2);border:1px solid var(--line-strong);
  font-family:var(--display);font-weight:700;font-size:var(--fs-min);color:var(--ink);letter-spacing:.06em;
}

/* ------------------------------------------------------------- progress */
.steps{margin-top:.5rem}
.step{display:grid;grid-template-columns:22px minmax(0,1fr);gap:.75rem;padding-bottom:.9rem;position:relative}
.step:last-child{padding-bottom:0}
.step::before{
  content:"";position:absolute;left:10px;top:20px;bottom:-2px;width:2px;background:var(--line);
}
.step:last-child::before{display:none}
.step__d{
  width:22px;height:22px;border-radius:50%;flex:none;z-index:1;
  background:var(--white);border:2px solid var(--line-strong);
  display:flex;align-items:center;justify-content:center;color:var(--white);
}
.step--done .step__d{background:var(--good);border-color:var(--good)}
.step--now .step__d{background:var(--gold);border-color:var(--gold)}
.step--done::before{background:var(--good)}
.step__t b{display:block;font-size:.93rem;color:var(--ink)}
.step__t span{display:block;font-size:var(--fs-min);color:var(--ink-3)}
.step--pending .step__t b{color:var(--ink-3);font-weight:600}

/* ----------------------------------------------------------------- SOS */
.sos{
  display:flex;align-items:center;justify-content:center;gap:.6rem;width:100%;
  min-height:56px;border-radius:var(--r);background:var(--bad-soft);
  border:1.5px solid #fecaca;color:var(--bad);font-weight:800;font-size:1rem;
}
.sos:hover{background:#fee2e2}

/* --------------------------------------------------------------- sheet */
.scrim{
  position:absolute;inset:0;z-index:70;background:rgba(7,26,61,.55);
  opacity:0;visibility:hidden;transition:opacity .22s var(--ease),visibility .22s;
  display:flex;align-items:flex-end;
}
.scrim[data-open="true"]{opacity:1;visibility:visible}
.sheet{
  width:100%;max-height:88%;overflow-y:auto;background:var(--white);
  border-radius:20px 20px 0 0;padding:1.25rem 1rem calc(1.25rem + var(--sab));
  transform:translateY(14px);transition:transform .26s var(--ease);
}
.scrim[data-open="true"] .sheet{transform:none}
.sheet__grab{width:38px;height:4px;border-radius:2px;background:var(--line-strong);margin:0 auto 1rem}
.sheet h3{font-size:1.15rem;margin-bottom:.35rem}
.sheet__p{font-size:.92rem;margin-bottom:1rem}

/* --------------------------------------------------------------- toast */
.toast{
  position:absolute;left:1rem;right:1rem;bottom:calc(var(--tab-h) + 1rem + var(--sab));z-index:80;
  display:flex;align-items:center;gap:.6rem;padding:.85rem 1rem;border-radius:var(--r);
  background:var(--navy);color:#fff;font-size:.9rem;font-weight:600;
  box-shadow:var(--shadow-lg);
  opacity:0;transform:translateY(10px);visibility:hidden;
  transition:opacity .22s var(--ease),transform .22s var(--ease),visibility .22s;
}
.toast[data-open="true"]{opacity:1;transform:none;visibility:visible}
.toast svg{flex:none;color:var(--gold)}

/* ---------------------------------------------------------------- auth */
/* Light and cheerful, matching every screen AFTER sign-in. These used to be a
   navy slab, which made the first thing anyone saw the gloomiest screen in the
   product. */
.auth{
  position:relative;display:flex;flex-direction:column;height:100%;overflow-y:auto;
  color:var(--ink-2);
  background:
    radial-gradient(78% 42% at 88% 0%,rgba(228,185,63,.20),transparent 64%),
    radial-gradient(70% 40% at 4% 100%,rgba(30,90,232,.10),transparent 62%),
    linear-gradient(180deg,#ffffff 0%,#f7faff 100%);
  padding:calc(1.5rem + var(--sat)) calc(1.25rem + var(--sar))
          calc(1.5rem + var(--sab)) calc(1.25rem + var(--sal));
}
@media (min-width:900px){.auth{padding-top:3.4rem}}
.auth > *{position:relative;z-index:1}

/* NOT margin-bottom:auto. In a flex column that swallows ALL the free space and
   dumps it in one place — 92px under the wordmark at 392x844 and 180px on a Pro
   Max, against 8-24px everywhere else. Content flows from the top and the slack
   falls at the end, where trailing whitespace reads as the end of a screen. */
.auth__brand{
  display:flex;align-items:center;gap:.6rem;color:var(--ink);
  font-family:var(--display);font-weight:800;font-size:1.15rem;margin-bottom:1.5rem;
}
.auth__brand em{font-style:normal;color:var(--gold-text)}

.auth h1{color:var(--ink);font-size:1.85rem;margin:0 0 .5rem}
.auth__sub{color:var(--ink-2);font-size:.95rem;margin-bottom:1.15rem;max-width:34ch}

.auth .field label{color:var(--ink)}
.auth .input{background:var(--white);border-color:var(--line-strong);color:var(--ink)}
.auth .input::placeholder{color:#9aa8bd}
.auth .input:focus{border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft)}
.auth .hint{color:var(--ink-3)}

.auth__demo{
  margin:1rem 0 1.25rem;padding:.85rem .95rem;border-radius:var(--r);
  background:var(--gold-soft);border:1px solid #f0dfa8;
}
.auth__demo b{
  display:block;color:var(--gold-text);font-size:var(--fs-min);font-weight:800;
  letter-spacing:.1em;text-transform:uppercase;margin-bottom:.35rem;
}
.auth__demo code{
  display:block;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:var(--fs-min);color:var(--ink);line-height:1.6;word-break:break-all;
}
.auth__swap{margin-top:1.25rem;text-align:center;font-size:.9rem;color:var(--ink-3)}
.auth__swap button{color:var(--blue);font-weight:700;min-height:44px;padding:0 .35rem}
.auth__legal{margin-top:.5rem;font-size:var(--fs-min);color:var(--ink-3);line-height:1.6}

/* ---------------------------------------------------- account-type picker */
.picks{display:grid;gap:.5rem;margin:.25rem 0 .75rem}
.pick{
  display:grid;grid-template-columns:44px minmax(0,1fr) 20px;gap:.85rem;align-items:center;
  width:100%;text-align:left;padding:.8rem;border-radius:var(--r);
  background:var(--white);border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(7,26,61,.05);
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease),transform .15s var(--ease);
}
.pick:hover{border-color:var(--blue);box-shadow:0 8px 22px rgba(7,26,61,.10);transform:translateY(-1px)}
.pick:active{transform:translateY(0)}
.pick__ico{
  display:flex;align-items:center;justify-content:center;width:44px;height:44px;flex:none;
  border-radius:var(--r-sm);background:var(--blue-soft);color:var(--blue);
}
/* A different accent per type so the choice reads as four things, not a list. */
.pick[data-type="group"] .pick__ico{background:var(--gold-soft);color:var(--gold-text)}
.pick[data-type="business"] .pick__ico{background:#e8f1ff;color:#12336f}
.pick[data-type="onceoff"] .pick__ico{background:var(--good-soft);color:var(--good)}

.pick__b{min-width:0}
.pick__b b{display:block;color:var(--ink);font-family:var(--display);font-size:1.02rem;line-height:1.25}
.pick__b em{display:block;font-style:normal;color:var(--gold-text);font-size:var(--fs-min);font-weight:700;margin-top:.1rem}
.pick[data-type="personal"] .pick__b em{color:var(--blue-dark)}
.pick[data-type="business"] .pick__b em{color:#12336f}
.pick[data-type="onceoff"] .pick__b em{color:var(--good)}
.pick__b span{display:block;color:var(--ink-2);font-size:var(--fs-min);line-height:1.5;margin-top:.3rem}
.pick__go{color:var(--ink-3);flex:none}

.auth__back{
  display:inline-flex;align-items:center;gap:.4rem;min-height:44px;
  color:var(--ink-3);font-size:var(--fs-min);font-weight:700;margin-bottom:.25rem;
}
.auth__back:hover{color:var(--blue)}
.authbadge{
  display:inline-flex;align-items:center;gap:.45rem;align-self:flex-start;
  padding:.3rem .7rem;border-radius:14px;margin-bottom:.5rem;
  background:var(--blue-soft);border:1px solid #c9dbfb;
  color:var(--blue-dark);font-size:var(--fs-min);font-weight:700;
}

/* --------------------------------------------------------------- misc */
.empty{text-align:center;padding:2.5rem 1rem;color:var(--ink-3)}
.empty svg{margin:0 auto .85rem;color:var(--line-strong)}
.empty b{display:block;color:var(--ink);font-family:var(--display);font-size:1.05rem;margin-bottom:.3rem}
.kv{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  padding:.6rem 0;border-bottom:1px solid var(--line);font-size:.92rem}
.kv:last-child{border-bottom:0}
.kv dt{color:var(--ink-3);min-width:0}
.kv dd{margin:0;font-weight:700;color:var(--ink);text-align:right;
  font-variant-numeric:tabular-nums;flex:none}
.big{font-family:var(--display);font-weight:800;letter-spacing:-.02em;
  font-size:2rem;color:var(--ink);line-height:1.1;font-variant-numeric:tabular-nums}
.card--navy .big{color:#fff}
.mut{color:var(--ink-3);font-size:var(--fs-min)}
.mt0{margin-top:0}.mt1{margin-top:.5rem}.mt2{margin-top:1rem}.mt3{margin-top:1.5rem}
.mb0{margin-bottom:0}
.center{text-align:center}
.vh{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* view transition */
.view{animation:viewIn .26s var(--ease) both}
@keyframes viewIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.view{animation:none}}

/* Taller screens have slack below the chooser. Spend some of it on roomier
   cards rather than leaving it all as trailing whitespace — bigger tap targets
   and a list that fills the screen. */
@media (min-height:800px){
  .pick{padding:1rem}
  .picks{gap:.65rem}
}

/* ------------------------------------------------------- group + business */
.facepile{display:flex;flex-wrap:wrap;gap:.4rem}
.avatar--off{background:var(--surface-2);color:var(--ink-3)}
.pillrow{display:flex;flex-wrap:wrap;gap:.4rem}
.statgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem;margin-bottom:.75rem}
.statbox{
  min-width:0;background:var(--white);border:1px solid var(--line);border-radius:var(--r);
  padding:.75rem .6rem;text-align:center;
}
.statbox b{
  display:block;font-family:var(--display);font-weight:800;letter-spacing:-.02em;
  color:var(--ink);font-size:1.1rem;line-height:1.15;font-variant-numeric:tabular-nums;
  overflow-wrap:anywhere;
}
.statbox span{display:block;margin-top:.2rem;font-size:var(--fs-min);color:var(--ink-3);line-height:1.35}

/* ------------------------------------------------------------- once-off */
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 .7rem}
.quote{
  margin-top:.5rem;padding:1rem;border-radius:var(--r);
  background:var(--navy);color:#c9d6ee;text-align:center;
}
.quote__l{display:block;font-size:var(--fs-min);font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:var(--gold)}
.quote__v{display:block;margin-top:.2rem;font-family:var(--display);font-weight:800;
  letter-spacing:-.03em;color:#fff;font-size:2.1rem;line-height:1.1;font-variant-numeric:tabular-nums}
.quote__n{display:block;margin-top:.35rem;font-size:var(--fs-min);color:#8fa6cd;line-height:1.5}

/* A driver card with the plate in its own column squeezes the name column and
   breaks names mid-word inside the phone frame. This variant stacks the plate
   under the vehicle instead. */
.driver--stack{grid-template-columns:40px minmax(0,1fr)}
.driver--stack .plate{margin-top:.35rem}
