/* Onway — premium polish layer. Loaded last on every surface.
   Motion, press states, type rendering, focus, selection, richer fallback maps. */

html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }
body { font-variant-numeric: tabular-nums; }

/* ── Micro-interactions: every control answers the hand ── */
button {
  transition: transform .13s cubic-bezier(.2,.7,.3,1), background-color .16s ease,
              color .16s ease, box-shadow .2s ease, border-color .16s ease, opacity .16s ease;
}
button:not(:disabled):active { transform: scale(.965); }
a { transition: color .15s ease, opacity .15s ease; }
input, textarea, select { transition: border-color .16s ease, box-shadow .2s ease, background-color .16s ease; }

::selection { background: rgba(139,255,90,.28); }
button:focus-visible, a:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid #55c936; outline-offset: 2px;
}

/* ── Device frame: deeper, softer presence ── */
.phone {
  box-shadow: 0 60px 120px -24px rgba(5,5,5,.5), 0 24px 48px -24px rgba(5,5,5,.4),
              0 0 0 1px rgba(255,255,255,.06);
}

/* ── Fallback map: reads like a street map, not graph paper ── */
.map {
  background-color: #edece7;
  background-image:
    radial-gradient(ellipse 340px 240px at 28% 30%, rgba(148,196,138,.20), transparent 70%),
    radial-gradient(ellipse 300px 220px at 78% 74%, rgba(120,170,215,.16), transparent 70%),
    linear-gradient(90deg, rgba(28,28,34,.075) 2px, transparent 2px),
    linear-gradient(0deg, rgba(28,28,34,.075) 2px, transparent 2px),
    linear-gradient(90deg, rgba(28,28,34,.035) 1px, transparent 1px),
    linear-gradient(0deg, rgba(28,28,34,.035) 1px, transparent 1px);
  background-size: 100% 100%, 100% 100%, 220px 220px, 220px 220px, 44px 44px, 44px 44px;
}

/* ── Sheets & overlays: one shared entrance curve ── */
@media (prefers-reduced-motion: no-preference) {
  .offer-sheet { animation: onway-sheetup .34s cubic-bezier(.16,1,.3,1); }
  @keyframes onway-sheetup { from { transform: translateY(24px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* Shared spinner rotation. The blanket reduced-motion rule above would run this
   at .01ms forever — a strobe, which is the opposite of what it asks for — so
   the spin is stopped outright there. The label beside it still says the app is
   working, so nothing is lost. */
@keyframes onway-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  [style*="onway-spin"] { animation: none !important; }
}

/* ══ Onway motion system — movement is the brand ══════════════════════
   Shared by every surface (marketing, rider, driver, ops). Restraint:
   one or two moving things per screen; everything answers the hand. */
@media (prefers-reduced-motion: no-preference) {

  /* Driver "Go online": a live pulse ring + breathing glow — signals "ready". */
  .onway-golive { position: relative; animation: onway-golive-breathe 2.2s ease-in-out infinite; }
  .onway-golive::after {
    content: ""; position: absolute; inset: 0; border-radius: 9999px;
    box-shadow: 0 0 0 0 rgba(139,255,90,.55); pointer-events: none;
    animation: onway-golive-ring 2.2s ease-out infinite;
  }
  @keyframes onway-golive-ring {
    0% { box-shadow: 0 0 0 0 rgba(139,255,90,.5); }
    70% { box-shadow: 0 0 0 16px rgba(139,255,90,0); }
    100% { box-shadow: 0 0 0 0 rgba(139,255,90,0); }
  }
  @keyframes onway-golive-breathe {
    0%, 100% { transform: translateY(0) scale(1); }
    50% { transform: translateY(-1px) scale(1.014); }
  }

  /* Rider home tiles: a quick staggered rise as the sheet settles. */
  .onway-tilegrid > button { animation: onway-tile-in .42s cubic-bezier(.16,1,.3,1) both; }
  .onway-tilegrid > button:nth-child(1){ animation-delay:.02s; }
  .onway-tilegrid > button:nth-child(2){ animation-delay:.06s; }
  .onway-tilegrid > button:nth-child(3){ animation-delay:.10s; }
  .onway-tilegrid > button:nth-child(4){ animation-delay:.14s; }
  .onway-tilegrid > button:nth-child(5){ animation-delay:.18s; }
  .onway-tilegrid > button:nth-child(6){ animation-delay:.22s; }
  .onway-tilegrid > button:nth-child(7){ animation-delay:.26s; }
  .onway-tilegrid > button:nth-child(8){ animation-delay:.30s; }
  .onway-tilegrid > button:hover img { transform: translateY(-3px) scale(1.06); transition: transform .18s cubic-bezier(.2,.7,.3,1); }
  @keyframes onway-tile-in { from { opacity:0; transform: translateY(10px); } to { opacity:1; transform: translateY(0); } }
  @keyframes onwayBlink { 0%,50%{ opacity:1; } 50.01%,100%{ opacity:.15; } }

  /* Buttons feel alive: lift toward the cursor, keep the press-in. */
  button:not(:disabled):hover { transform: translateY(-1.5px); box-shadow: 0 8px 20px -8px rgba(5,5,5,.30); }
  /* …but nav pills and icon chips stay flat (they have their own hover). */
  .navlink:hover, .navlink:not(:disabled):hover { transform: none; box-shadow: none; }

  /* Primary CTA catches a slow band of light — draws the eye without nagging. */
  .onway-cta { position: relative; overflow: hidden; }
  .onway-cta::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.38), transparent);
    transform: skewX(-18deg); pointer-events: none;
    animation: onway-cta-shine 6s ease-in-out 2s infinite;
  }
  @keyframes onway-cta-shine {
    0%, 72% { left: -60%; } 86% { left: 130%; } 100% { left: 130%; }
  }

  /* Animated wordmark: the route-dot slowly loses steam, drifts off the end and
     the mark slumps — "despair" — then springs back to life on hover/focus/click. */
  .onway-logo-dot { animation: onway-dot-leave 6.5s ease-in 1.2s forwards; }
  .onway-logo-track { transform-origin: left center; animation: onway-track-despair 6.5s ease-in 1.2s forwards; }
  .onway-logo > span:first-child { display: inline-block; transform-origin: left center; animation: onway-word-despair 6.5s ease-in 1.2s forwards; }
  @keyframes onway-dot-leave { 0% { left: 0; opacity: 1; } 68% { left: 100%; opacity: 1; } 100% { left: 122%; opacity: 0; } }
  @keyframes onway-track-despair { 0% { opacity: 1; transform: rotate(0) scaleX(1); } 100% { opacity: .45; transform: rotate(3deg) scaleX(.8); } }
  @keyframes onway-word-despair { 0% { opacity: 1; transform: none; } 100% { opacity: .5; transform: translateY(1.5px) skewX(-4deg); } }

  .onway-logo:hover .onway-logo-dot, .onway-logo:focus-visible .onway-logo-dot, .onway-logo:active .onway-logo-dot {
    animation: onway-dot-return 1s cubic-bezier(.2,.9,.3,1) forwards; }
  .onway-logo:hover .onway-logo-track, .onway-logo:focus-visible .onway-logo-track, .onway-logo:active .onway-logo-track {
    animation: onway-revive .5s ease forwards; }
  .onway-logo:hover > span:first-child, .onway-logo:focus-visible > span:first-child, .onway-logo:active > span:first-child {
    animation: onway-revive .5s ease forwards; }
  @keyframes onway-dot-return { 0% { left: 122%; opacity: 0; } 100% { left: 0; opacity: 1; } }
  @keyframes onway-revive { to { opacity: 1; transform: none; } }

  /* Service icons pop up to meet a tap. No drop-shadow — flat per brand rule. */
  .svc { transition: transform .2s cubic-bezier(.2,.7,.3,1); }
  .svc:hover { transform: translateY(-5px); }

  /* Hero packshot breathes — the page is never quite still. */
  .onway-float { animation: onway-float 7s ease-in-out infinite; }
  @keyframes onway-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }

  /* Sticky footer CTA: a slow, faint lime band drifts across — a quiet "go" signal.
     On hover it sweeps through quickly (catches, then clears) to reward intent. */
  .onway-sticky-cta::before {
    content: ""; position: absolute; top: 0; bottom: 0; left: -40%; width: 24%;
    background: linear-gradient(100deg, transparent, rgba(139,255,90,.28), transparent);
    transform: skewX(-16deg); pointer-events: none; z-index: 0;
    animation: onway-sticky-sweep 22s linear infinite;
  }
  .onway-sticky-cta:hover::before { animation-duration: 4s; }
  @keyframes onway-sticky-sweep {
    0% { left: -40%; } 40% { left: 140%; } 100% { left: 140%; }
  }
}

/* Logo track/dot geometry (works even with motion off — dot just rests at start). */
.onway-logo { position: relative; display: inline-flex; flex-direction: column; gap: 4px; text-decoration: none; }
.onway-logo-track { position: relative; height: 2px; width: 100%; border-radius: 2px; background: rgba(255,255,255,.22); }
.onway-logo-dot { position: absolute; top: 50%; left: 0; width: 6px; height: 6px; border-radius: 50%;
  background: #8bff5a; box-shadow: 0 0 8px rgba(139,255,90,.9); transform: translate(-50%, -50%); }

/* ── Install banner: reserve its space, never float over the CTA ──
   #onway-install-banner is fixed to the bottom at z-index 99999, which is where
   both apps dock their primary action (rider "Choose <tier>", driver accept /
   go-online). It used to overlap that button: on Android it covered the lower
   ~14px so a low thumb tap hit the banner instead, and on iOS — where the
   Add-to-Home-Screen hint wraps taller and the home-indicator inset lifts the
   banner further — it covered the button outright. Either way the tap landed on
   the banner: nothing happened, no error shown, no request sent, so the failure
   left no trace in the logs (shipped in the Jul 25 PWA pass, #22).
   onway-pwa.js publishes the occupied height as --onway-install-h; adding it to
   the shell's bottom padding lifts the CTA clear of the banner. Inert when no
   banner is up (--onway-install-h is 0 and the class is absent). The keyboard
   rule still wins while it is open — that inset is the larger of the two. */
html.onway-install-open:not(.onway-kb-open) .screen {
  padding-bottom: calc(var(--safe-b, env(safe-area-inset-bottom, 0px)) + var(--onway-install-h, 0px));
}

/* ── Rider app: text contrast in the booking flow ────────────────────────────
   Measured on a 414px viewport against the backdrop actually painted behind
   each run. Everything below failed WCAG AA for its size, and none of it is
   decoration — it is the labels, links and price disclosure a rider reads while
   deciding to book. Scoped to .screen so only the rider app is touched, and
   applied to the inline declarations because these colours are set per element.

   The dark appearance is a whole-screen invert() filter, so darkening these for
   light mode lightens them for dark by the same step — one fix covers both. */

/* Accent green used as TEXT: #55c936 measured 2.1:1 and #3f9e1e / #3d9e1f 3.4:1
   on white. "Adjust" and "Change" on the Choose sheet are links, not accents.
   Fills, toggles and icons keep the bright brand green — only text moves. */
.screen [style*="color: rgb(85, 201, 54)"],
.screen [style*="color: rgb(63, 158, 30)"],
.screen [style*="color: rgb(61, 158, 31)"] { color: #2b7d12 !important; }

/* Secondary and tertiary greys, all under 4.5:1 at the sizes they are set in:
   #a3a3a3 (2.5:1) on "optional, shared with your driver", #a0a0a0 (2.6:1) on the
   recent-places empty state, #909090 (3.2:1) on the booking-fee disclosure under
   the CTA, #7a7a7a (4.0:1) on the service subtitles, #767676 (4.1:1) on the
   per-tier "Est. fare" caption. #6f6f6f clears 5:1 on white and 4.7:1 on the
   #f3f3f3 rows these sit on. */
.screen [style*="color: rgb(163, 163, 163)"],
.screen [style*="color: rgb(160, 160, 160)"],
.screen [style*="color: rgb(144, 144, 144)"],
.screen [style*="color: rgb(122, 122, 122)"],
.screen [style*="color: rgb(118, 118, 118)"],
.screen [style*="color: rgb(189, 189, 189)"],   /* inbox gesture hint, 1.9:1  */
.screen [style*="color: rgb(175, 175, 175)"]    /* "More options coming soon", 2.2:1 */
  { color: #6a6a6a !important; }

/* One more accent green used as text, on the support screen's live-chat line.
   #2c8a00 measures 4.4:1 — a hair under, same fix as the others. */
.screen [style*="color: rgb(44, 138, 0)"] { color: #2b7d12 !important; }

/* The unselected rating stars were #e2e2e0 — 1.3:1, effectively invisible, on
   the one control the Rate screen exists for. WCAG puts UI components at 3:1,
   which #949492 clears while staying obviously unfilled next to a rated star. */
.screen [style*="color: rgb(226, 226, 224)"] { color: #949492 !important; }
