/* ===========================================================================
 * site.css - page composition for Melbourne Airport Transfers.
 *
 * run.css owns the tokens and the primitives (colour, type, buttons, cards,
 * tables). This file owns page STRUCTURE: header, hero, grids, footer. If you
 * find yourself typing a hex value or a font name in here, it belongs in
 * run.css instead.
 * ======================================================================== */

*, *::before, *::after { box-sizing: border-box; }
img { max-width: 100%; height: auto; display: block; }

/* ── Header ────────────────────────────────────────────────────────────── */

.site-head {
  position: sticky; top: 0; z-index: 40;
  background: var(--run-ink);
  border-bottom: 1px solid var(--run-hairline-dk);
  /* Measured here so the film hero can subtract it rather than guess. */
  --head-h: 4.5625rem;
}
:root { --head-h: 4.5625rem; }
.site-head-in {
  max-width: var(--run-max); margin: 0 auto;
  padding: 0.85rem var(--run-gutter);
  display: flex; align-items: center; gap: 1.5rem;
}
/* The wordmark is set, not drawn: one heavy lowercase word, tightly tracked,
   with the accent carried by a dot rather than by a coloured second word. The
   dot is the mark. It is the only element that has to survive being shrunk to
   a favicon, and unlike the block device it cannot be misread as anything.
   Deliberately Archivo rather than Archivo Expanded: the expanded axis is for
   headlines, and a wordmark wants to be tight. */
.wordmark {
  display: inline-flex; flex-direction: column; gap: 0.22em;
  text-decoration: none; color: var(--run-paper);
  font-family: var(--run-font-body);
  line-height: 1; white-space: nowrap;
}
.wm-word {
  font-size: 1.3125rem; font-weight: 700;
  letter-spacing: -0.035em; text-transform: lowercase;
}
/* Drawn as a circle rather than typed as a full stop, because Archivo's period
   is a fraction of the size this needs and its shape drifts with the weight. */
.wm-dot {
  display: inline-block; width: 0.3em; height: 0.3em;
  margin-left: 0.1em; border-radius: 50%;
  background: var(--run-accent);
}
.wm-sub {
  font-size: 0.5rem; font-weight: 500;
  letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--run-muted-dark);
}
/* On a narrow screen the descriptor is unreadable anyway, so it goes rather
   than shrinking into a grey smear under the name. */
@media (max-width: 420px) { .wm-sub { display: none; } }


.site-nav { margin-left: auto; display: flex; align-items: center; gap: 1.5rem; }
.site-nav a {
  color: var(--run-paper); text-decoration: none;
  font-size: var(--run-small); letter-spacing: 0.04em;
}
.site-nav a:hover { color: var(--run-accent); }
.site-nav .run-btn { color: var(--run-accent-ink); }
@media (max-width: 720px) { .site-nav .hide-sm { display: none; } }

/* ── Hero ──────────────────────────────────────────────────────────────── */

.hero { background: var(--run-ink); color: var(--run-paper); padding: var(--run-band) var(--run-gutter) 0; }
.hero-in { max-width: var(--run-max); margin: 0 auto; }
.hero h1 { margin-bottom: 1.25rem; }
.hero-sub { color: var(--run-muted-dark); font-size: 1.0625rem; max-width: 52ch; margin: 0 0 2rem; }

/* The quote row. Addison Lee hides the fare behind a Book Now button because it
   sells on reputation; we are the cheaper option and new, so the price is the
   argument and it goes above the fold. */
.quote {
  background: var(--run-paper);
  border-radius: var(--run-radius);
  padding: 1.25rem;
  display: grid; gap: 0.85rem;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .quote { grid-template-columns: 1.4fr 1.4fr 1fr 0.6fr auto; align-items: end; }
}
.quote .f { min-width: 0; }
.quote .run-btn { width: 100%; justify-content: center; height: 3rem; }

.hero-trust { padding: 1.25rem 0 var(--run-band); }

/* ── Section heads ─────────────────────────────────────────────────────── */

.sec-head { margin-bottom: 2.5rem; }
.sec-head h2 { margin-bottom: 0.75rem; }
.eyebrow {
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--run-accent);
  margin: 0 0 0.75rem;
}

/* ── Grids ─────────────────────────────────────────────────────────────── */

.grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.grid-4 { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }

/* Terminal cards: the first thing an arriving passenger looks for. */
.term {
  display: flex; flex-direction: column; gap: 0.35rem;
  padding: 1.25rem; text-decoration: none; color: inherit;
  border: 1px solid var(--run-hairline-dk); border-radius: var(--run-radius);
  background: var(--run-ink-soft);
  transition: border-color var(--run-transition);
}
.term:hover { border-color: var(--run-accent); }
.term .code {
  font-family: var(--run-font-display); font-size: 1.5rem; font-weight: 600;
  letter-spacing: 0.02em; color: var(--run-accent);
}
.term .who { color: var(--run-paper); font-weight: 600; font-size: 0.9375rem; }
.term .note { color: var(--run-muted-dark); font-size: var(--run-small); }

/* Benefit cards. Every one carries a number or it does not ship. */
.benefit { padding: 1.5rem; border: 1px solid var(--run-hairline); border-radius: var(--run-radius); }
.benefit .ico { color: var(--run-accent); margin-bottom: 0.9rem; }
.benefit h3 { margin-bottom: 0.4rem; }
.benefit p { margin: 0; color: var(--run-muted); font-size: 0.9375rem; }

/* Vehicle cards */
.veh { padding: 1.5rem; border: 1px solid var(--run-hairline); border-radius: var(--run-radius); }
.veh .cap {
  display: flex; gap: 1rem; margin: 0.5rem 0 0.9rem;
  font-size: var(--run-small); color: var(--run-muted);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.veh .models { margin: 0 0 1rem; color: var(--run-muted); font-size: 0.875rem; }
.veh .from { display: flex; align-items: baseline; gap: 0.5rem; }
.veh .from .run-price { font-size: 1.75rem; }

/* Steps */
.step { padding-top: 1rem; border-top: 2px solid var(--run-accent); }
.step .n {
  font-family: var(--run-font-display); font-size: 2rem; font-weight: 600;
  color: var(--run-accent); line-height: 1; margin-bottom: 0.6rem;
}
.step h3 { margin-bottom: 0.4rem; }
.step p { margin: 0; color: var(--run-muted); font-size: 0.9375rem; }
.run-band-dark .step p { color: var(--run-muted-dark); }

/* ── Fare table ────────────────────────────────────────────────────────── */

.fare-note { margin: 1rem 0 0; font-size: var(--run-small); color: var(--run-muted); max-width: 70ch; }
.fare-more { margin-top: 1.5rem; }
td.suburb { font-weight: 500; }
td.suburb .km { color: var(--run-muted); font-size: var(--run-small); display: block; }
.run-table td.price { font-weight: 600; white-space: nowrap; }

/* ── FAQ ───────────────────────────────────────────────────────────────── */

.faq { border-top: 1px solid var(--run-hairline); }
.faq details { border-bottom: 1px solid var(--run-hairline); }
.faq summary {
  cursor: pointer; list-style: none; padding: 1.15rem 2rem 1.15rem 0;
  font-weight: 600; position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; position: absolute; right: 0; top: 1rem;
  font-size: 1.5rem; line-height: 1; color: var(--run-accent);
}
.faq details[open] summary::after { content: '\2212'; }
.faq .a { padding: 0 2rem 1.35rem 0; margin: 0; color: var(--run-muted); max-width: 72ch; }

/* ── Route index ───────────────────────────────────────────────────────── */

.routes { columns: 3 12rem; column-gap: 2rem; }
.routes a {
  display: block; padding: 0.4rem 0; text-decoration: none;
  color: inherit; font-size: 0.9375rem;
  break-inside: avoid;
}
.routes a:hover { color: var(--run-accent); text-decoration: underline; }
.routes a .p { color: var(--run-muted); }

/* ── Footer ────────────────────────────────────────────────────────────── */

.site-foot { background: var(--run-ink); color: var(--run-muted-dark); padding: var(--run-band) var(--run-gutter) 2rem; }
.site-foot-in { max-width: var(--run-max); margin: 0 auto; }
.foot-cols { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }
.foot-cols h3 {
  color: var(--run-paper); font-size: 0.6875rem; letter-spacing: 0.12em;
  text-transform: uppercase; margin-bottom: 0.9rem;
}
.foot-cols a, .foot-cols li { color: var(--run-muted-dark); font-size: 0.9375rem; }
.foot-cols ul { list-style: none; margin: 0; padding: 0; }
.foot-cols li { padding: 0.25rem 0; }
.foot-cols a { text-decoration: none; }
.foot-cols a:hover { color: var(--run-accent); }
.foot-legal {
  margin-top: 2.5rem; padding-top: 1.5rem;
  border-top: 1px solid var(--run-hairline-dk);
  font-size: var(--run-small); line-height: 1.7;
}

/* ── Service cards ─────────────────────────────────────────────────────── */
/* The primary navigation on the home page, following Addison Lee's pattern of
   letting the services do the wayfinding rather than a menu. */

.svc {
  display: flex; flex-direction: column; gap: 0.5rem;
  padding: 1.5rem; text-decoration: none; color: inherit;
  border: 1px solid var(--run-hairline); border-radius: var(--run-radius);
  transition: border-color var(--run-transition);
}
.svc:hover { border-color: var(--run-accent); }
.svc p { margin: 0; color: var(--run-muted); font-size: 0.9375rem; }
.svc .more {
  margin-top: auto; padding-top: 0.75rem;
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--run-accent-dim);
}
.run-band-dark .svc {
  background: var(--run-ink-soft); border-color: var(--run-hairline-dk);
}
.run-band-dark .svc h3 { color: var(--run-paper); }
.run-band-dark .svc p { color: var(--run-muted-dark); }
.run-band-dark .svc .more { color: var(--run-accent); }

/* Outline button, for the secondary action in a pair. */
.run-btn-line {
  background: transparent; color: var(--run-ink);
  border: 1px solid var(--run-ink);
}
.run-btn-line:hover { background: var(--run-ink); color: var(--run-paper); }
.run-band-dark .run-btn-line { color: var(--run-paper); border-color: var(--run-paper); }
.run-band-dark .run-btn-line:hover { background: var(--run-paper); color: var(--run-ink); }

.fare-more { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* Vehicle photography. Our own cars, so the tier a customer books is the car
   that turns up. Fixed aspect so a slow image never reflows the grid. */
.veh { padding: 0; overflow: hidden; }
.veh > :not(.veh-img) { margin-left: 1.5rem; margin-right: 1.5rem; }
.veh > h3 { margin-top: 1.25rem; }
.veh > .from { padding-bottom: 1.5rem; }
.veh-img {
  width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  border-bottom: 1px solid var(--run-hairline); background: var(--run-paper-warm);
}
.run-band-dark .veh-img { border-color: var(--run-hairline-dk); }

/* ── Narrow column ─────────────────────────────────────────────────────── */
/* Forms and legal text read badly at full width. Anything meant to be read
   line by line sits in here. */
.run-narrow { max-width: 46rem; }

/* ── Booking form ──────────────────────────────────────────────────────── */

.bookform fieldset {
  border: 0; padding: 0; margin: 0 0 2.5rem;
}
.bookform legend {
  font-family: var(--run-font-display);
  font-size: 1.125rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.02em; padding: 0 0 1rem;
  border-bottom: 2px solid var(--run-accent); width: 100%; margin-bottom: 1.25rem;
}
.bookform .opt { color: var(--run-muted); font-weight: 400; text-transform: none; letter-spacing: 0; }
.fieldrow { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px) { .fieldrow { grid-template-columns: 1fr 1fr; } }
/* Passengers, suitcases and carry-ons belong on one line: they are one thought,
   and splitting them makes the third look like an afterthought nobody fills in. */
@media (min-width: 640px) { .fieldrow.three { grid-template-columns: 1fr 1fr 1fr; } }
.bookform .f { margin-bottom: 1rem; }
.bookform .hint { margin: -0.25rem 0 1.25rem; font-size: var(--run-small); color: var(--run-muted); }
.bookform textarea.run-field { resize: vertical; font-family: inherit; }

/* Vehicle tier radios, styled as selectable cards. */
.tiers { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); }
.tier {
  display: block; padding: 1rem; cursor: pointer;
  border: 1px solid var(--run-hairline); border-radius: var(--run-radius);
  transition: border-color var(--run-transition);
}
.tier:hover { border-color: var(--run-accent); }
.tier input { margin-bottom: 0.5rem; accent-color: var(--run-accent); }
.tier:has(input:checked) { border-color: var(--run-ink); box-shadow: inset 0 0 0 1px var(--run-ink); }
.tier .t-name { display: block; font-weight: 600; }
.tier .t-cap { display: block; font-size: var(--run-small); color: var(--run-muted); }
/* What the car actually is. Directly under the tile name, because it is the
   line that answers "what am I getting". Deliberately NOT in the accent:
   the fare below it already owns that colour, and two accent lines on one
   tile means neither is read. */
/* INHERIT, never a fixed colour. These tiles sit on the black band on the
   booking page and on white elsewhere, and a hard-coded near-black ink made
   the line invisible on the one page it was written for: present in the
   markup, absent from the screen. */
.tier .t-model { display: block; font-size: var(--run-small); font-weight: 500;
                 color: inherit; opacity: .78; margin: 1px 0 2px; }

.check { display: flex; gap: 0.75rem; align-items: flex-start; margin-bottom: 1rem; font-size: 0.9375rem; }
.check input { margin-top: 0.25rem; accent-color: var(--run-accent); flex: 0 0 auto; }

.formnote { font-size: var(--run-small); color: var(--run-muted); margin-bottom: 1.25rem; }
.formstatus { margin-top: 1rem; font-size: 0.9375rem; min-height: 1.5em; }
.formstatus.ok  { color: var(--run-ok); font-weight: 600; }
.formstatus.err { color: var(--run-warn); font-weight: 600; }

/* ── Legal pages ───────────────────────────────────────────────────────── */

.legal-sec { margin-bottom: 2.5rem; }
.legal-sec h2 {
  font-size: 1.25rem; letter-spacing: 0.01em;
  padding-bottom: 0.6rem; margin-bottom: 1rem;
  border-bottom: 1px solid var(--run-hairline);
}
.legal-sec p { margin: 0 0 1rem; }
.legal-foot {
  margin-top: 3rem; padding-top: 1.5rem;
  border-top: 1px solid var(--run-hairline);
  font-size: var(--run-small); color: var(--run-muted);
}
.legal h2 + p { margin-top: 0; }

/* FAQ page section headings, between accordion groups. */
.run-narrow > h2 { margin: 2.5rem 0 0.5rem; font-size: 1.5rem; }
.run-narrow > h2:first-child { margin-top: 0; }

/* ── Photography ───────────────────────────────────────────────────────── */
/* Addison Lee leads with a photograph of a person or a car in context and sets
   type over it; the studio cutout only appears in the vehicle picker. We follow
   that, with one difference: every photograph here is our own fleet or a city
   we actually serve, so nothing on the page promises a car we cannot send. */

.hero-photo { position: relative; isolation: isolate; overflow: hidden; }
.hero-bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 40%;
  z-index: -2;
}
/* The quote form sits on this photograph, so the scrim is doing legibility
   work, not decoration. Darkest at the top where the h1 and the labels are. */
.hero-photo::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    rgb(0 0 0 / 0.82) 0%, rgb(0 0 0 / 0.72) 45%, rgb(0 0 0 / 0.88) 100%);
}
.hero-photo .hero-in { position: relative; }

/* Shared card photograph: same 4:3 crop for cities and services, so a row of
   mixed cards keeps one baseline. */
.card-img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block;
  background: var(--run-ink-soft);
}

.term-photo { padding: 0; overflow: hidden; }
.term-photo .term-txt {
  display: flex; flex-direction: column; gap: 0.35rem; padding: 1.25rem;
}
.term-photo .card-img { border-bottom: 1px solid var(--run-hairline-dk); }

.svc-photo { padding: 0; overflow: hidden; }
.svc-photo .svc-txt { padding: 1.5rem; }
.svc-photo .card-img { border-bottom: 1px solid var(--run-hairline); }
.run-band-dark .svc-photo .card-img { border-bottom-color: var(--run-hairline-dk); }
/* A text-only service card keeps the same inner structure so the two kinds sit
   level in one grid. */
.svc .svc-txt {
  display: flex; flex-direction: column; gap: 0.5rem; flex: 1;
}
.svc .svc-txt h3 { margin: 0; }
.svc .svc-txt p { margin: 0; }

@media (prefers-reduced-motion: no-preference) {
  .card-img { transition: transform var(--run-transition); }
  .svc-photo:hover .card-img, .term-photo:hover .card-img { transform: scale(1.02); }
}

/* ── Page hero photography ─────────────────────────────────────────────── */
/* Addison Lee opens every page on a photograph, not just the home page. The
   band keeps its dark ground so the type contract is unchanged; the picture
   sits behind it and the scrim carries the legibility. */
.band-photo { position: relative; isolation: isolate; overflow: hidden; }
.band-bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 45%;
  z-index: -2;
}
.band-photo::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    rgb(10 10 10 / 0.88) 0%, rgb(10 10 10 / 0.74) 55%, rgb(10 10 10 / 0.92) 100%);
}
.band-photo > .run-inner { position: relative; }

/* ── Full-bleed break band ─────────────────────────────────────────────── */
/* Their "travel seamlessly" panel: one photograph across the full width with a
   single sentence on it, used to break a long page rather than to say anything
   the page has not already said. One per page, never two. */
.break-band {
  position: relative; isolation: isolate; overflow: clip;
  min-height: 100svh; display: grid;
  padding: 0 var(--run-gutter);
}
.break-band img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: -2;
}
.break-band::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgb(10 10 10 / 0.72) 0%, rgb(10 10 10 / 0.30) 55%, rgb(10 10 10 / 0.15) 100%),
    linear-gradient(90deg,  rgb(10 10 10 / 0.62) 0%, rgb(10 10 10 / 0.28) 60%, rgb(10 10 10 / 0.10) 100%);
}
.break-in {
  max-width: var(--run-max); margin: 0 auto; width: 100%;
  padding-top: 7.5rem;
}
.break-stick { position: sticky; top: 7.5rem; padding-bottom: 2rem; }
.break-cta { margin: 1.75rem 0 0; }
/* Someone who has asked their system to stop moving things gets a plain band
   rather than a pinned one. */
@media (prefers-reduced-motion: reduce) {
  .break-band { min-height: 60svh; display: grid; align-items: center; }
  .break-stick { position: static; }
}
.break-in h2 { color: var(--run-paper); max-width: 16ch; margin: 0 0 0.9rem; }
.break-in p { color: var(--run-muted-dark); max-width: 42ch; margin: 0; font-size: 1.0625rem; }

/* ── Icon row ──────────────────────────────────────────────────────────── */
/* Their benefit blocks lead with a 56px line icon in the accent colour. Drawn
   inline rather than fetched: six glyphs are not worth a network request, and
   an icon that fails to load leaves a benefit block looking broken. */
.ico {
  display: block; width: 2.75rem; height: 2.75rem;
  stroke: var(--run-accent); stroke-width: 1.5; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}
.benefit .ico { margin-bottom: 0.9rem; }

/* Available to a screen reader and to a crawler, absent from the page. Used
   for the home h1: the client did not want the headline, but a page with no
   h1 at all announces nothing about itself. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* The hero says four words. Nobody reads a paragraph sitting on top of a form
   they came to fill in, so the sentence is gone and what is left is the shape
   of the trip. The full stops are the wordmark's dot again, in the accent
   colour, which is the whole reason the line is punctuated rather than
   phrased. */
.hero-line {
  color: var(--run-paper);
  font-family: var(--run-font-display);
  font-size: clamp(2.25rem, 8vw, 4.5rem);
  line-height: 0.98; letter-spacing: -0.02em;
  font-weight: 700; text-transform: uppercase;
  margin: 0 0 2rem; max-width: 15ch; text-wrap: balance;
}
.hero-line b { color: var(--run-accent); font-weight: inherit; }

/* Honeypot. Off-screen rather than display:none, because some bots skip fields
   that are display:none and fill the ones that are merely positioned away. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ── City chooser on the prices page ───────────────────────────────────── */
/* The reader picks a city before they see a fare table, so these are the first
   real decision on the page and are sized like it. Same shape as the city
   cards elsewhere, minus the photograph: this is a control, not a link. */
.citypick { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); }
.citybtn {
  display: flex; flex-direction: column; gap: 0.3rem; text-align: left;
  padding: 1.15rem 1.25rem; cursor: pointer;
  font: inherit; color: inherit;
  background: var(--run-paper); border: 1px solid var(--run-hairline);
  border-radius: var(--run-radius);
  transition: border-color var(--run-transition), background var(--run-transition);
}
.citybtn:hover { border-color: var(--run-accent); }
.citybtn .code {
  font-family: var(--run-font-display); font-size: 1.375rem; font-weight: 700;
  letter-spacing: 0.01em; color: var(--run-accent-dim);
}
.citybtn .who { font-weight: 600; }
.citybtn .note { font-size: 0.8125rem; color: var(--run-muted); }
/* aria-pressed carries the state, so the styling hangs off it rather than a
   class: the two can never drift apart. */
.citybtn[aria-pressed="true"] {
  background: var(--run-ink); border-color: var(--run-ink); color: var(--run-paper);
}
.citybtn[aria-pressed="true"] .code { color: var(--run-accent); }
.citybtn[aria-pressed="true"] .note { color: var(--run-muted-dark); }

/* ── Booking steps ─────────────────────────────────────────────────────── */
.steps {
  display: flex; gap: 0; list-style: none; margin: 0 0 2rem; padding: 0;
  counter-reset: step;
}
.steps li {
  flex: 1; counter-increment: step; position: relative;
  padding: 0.85rem 0 0; border-top: 3px solid var(--run-hairline);
  font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase;
  font-weight: 600; color: var(--run-muted);
}
.steps li::before { content: counter(step) ". "; }
.steps li[data-state="now"]  { border-top-color: var(--run-accent); color: var(--run-ink); }
.steps li[data-state="done"] { border-top-color: var(--run-accent); color: var(--run-muted); }

/* Back sits left, forward right, so the pair reads the way the flow moves. */
.steprow { display: flex; gap: 0.75rem; align-items: center; margin-top: 1.75rem; }
.steprow .run-btn-line { margin-right: auto; }
@media (max-width: 520px) {
  .steps li { font-size: 0; padding-top: 0.6rem; }     /* the bar alone on a phone */
  .steps li::before { font-size: 0.75rem; }
  .steprow { flex-wrap: wrap; }
}

/* Three seat counts side by side: they are one question, not three. */
.seatrow {
  display: grid; gap: 0.75rem; grid-template-columns: 1fr;
  margin-bottom: 0.5rem; align-items: end;
}
@media (min-width: 640px) { .seatrow { grid-template-columns: repeat(3, 1fr); } }
.seatrow .run-label { font-weight: 600; }

/* A contradiction the customer can still fix, not an error: they are told what
   is wrong and why, and the form does not block them over it. */
.fare-note.warn { color: var(--run-ink); font-weight: 600; }
.fare-note.warn::before { content: "⚠ "; color: var(--run-accent-dim); }

/* ── Services rail ─────────────────────────────────────────────────────── */
/* Six tiles and a seventh to the rest, swiped rather than stacked. Eight cards
   down a phone is most of a screen spent on a menu. */
.rail {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: min(88vw, 26rem);
  gap: 0.85rem; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* bleed to both edges so the last tile is visibly cut off: that overflow is
     the only thing telling a thumb there is more to the right */
  margin-inline: calc(var(--run-gutter) * -1);
  padding-inline: var(--run-gutter); padding-bottom: 0.5rem;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
@media (min-width: 720px) { .rail { grid-auto-columns: 24rem; } }

.tile {
  scroll-snap-align: start; display: flex; flex-direction: column;
  text-decoration: none; color: var(--run-ink); overflow: hidden;
  border: 1px solid var(--run-hairline); border-radius: var(--run-radius);
  background: var(--run-paper);
  transition: border-color var(--run-transition);
}
.tile:hover { border-color: var(--run-accent); }
.tile-img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; }
.tile-txt { display: flex; flex-direction: column; gap: 0.4rem; padding: 1.5rem 1.5rem 1.85rem; }
.tile-h {
  font-family: var(--run-font-display); font-weight: 700;
  font-size: 1.5rem; line-height: 1.1; letter-spacing: -0.01em;
}
.tile-p { color: var(--run-muted); font-size: 0.9375rem; }
.tile-all { background: var(--run-ink); color: var(--run-paper); border-color: var(--run-ink); justify-content: center; }
.tile-all .tile-p { color: var(--run-muted-dark); }
.tile-all .more { margin-top: 0.75rem; }

/* ── What sets us apart ────────────────────────────────────────────────── */
/* One word, and the sentences behind it. Nobody reads six paragraphs stacked;
   everybody reads one. */
.apart-list { border-top: 1px solid var(--run-hairline); }
.apart { border-bottom: 1px solid var(--run-hairline); }
.apart summary {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 1.15rem 0; cursor: pointer; list-style: none;
}
.apart summary::-webkit-details-marker { display: none; }
.apart summary .ico { width: 1.75rem; height: 1.75rem; margin: 0; flex: none; }
.apart-h {
  font-family: var(--run-font-display); font-weight: 700;
  font-size: 1.125rem; letter-spacing: 0.02em; text-transform: uppercase;
}
/* The chevron is drawn from two borders so it costs nothing and turns. */
.apart-x {
  margin-left: auto; width: 0.6rem; height: 0.6rem;
  border-right: 2px solid var(--run-accent); border-bottom: 2px solid var(--run-accent);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--run-transition);
}
.apart[open] .apart-x { transform: rotate(-135deg) translate(-2px, -2px); }
.apart p {
  margin: 0 0 1.35rem; padding-left: calc(1.75rem + 0.9rem);
  color: var(--run-muted); max-width: 60ch;
}

/* ── Film hero ─────────────────────────────────────────────────────────── */
/* The screen is the film and the words sit at the foot of it, which is what
   Addison Lee does and why their mobile page reads: one idea, one button, and
   nothing competing with either. */
.hero-film {
  position: relative; isolation: isolate; overflow: clip;
  min-height: calc(100svh - var(--head-h)); display: grid; align-content: end;
  /* Bottom padding is deliberately small: the button is the last thing on the
     screen and belongs where the thumb already is. */
  padding: var(--run-band) var(--run-gutter) 2.5rem;
}
.hero-film .hero-bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: -2;
  /* the film is atmosphere, not information: it must never out-shout the type */
  filter: saturate(0.85);
}
/* Weighted to the foot, where the words are. */
.hero-film::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    rgb(10 10 10 / 0.55) 0%, rgb(10 10 10 / 0.30) 34%,
    rgb(10 10 10 / 0.78) 72%, rgb(10 10 10 / 0.94) 100%);
}
.hero-film .hero-in { position: relative; max-width: var(--run-max); margin: 0 auto; width: 100%; }
.hero-film .hero-sub { margin: 0 0 1.75rem; max-width: 34ch; }
.hero-cta { margin: 0; }
.run-btn-lg { padding: 1.05rem 1.9rem; font-size: 0.9375rem; }

/* A viewport-tall video is a lot of data for something decorative, so anyone
   who has asked for less motion gets the poster frame instead. */
@media (prefers-reduced-motion: reduce) {
  .hero-film .hero-bg { display: none; }
  .hero-film { background: url("/assets/video/hero-poster.jpg") center / cover var(--run-ink); }
}

/* Four cities as a line of links rather than a grid of photographs. */
.citylinks { display: flex; flex-wrap: wrap; gap: 0.5rem 1.75rem; margin: 0 0 2rem; }
.citylinks a {
  color: var(--run-paper); text-decoration: none;
  font-family: var(--run-font-display); font-weight: 700;
  font-size: 1.25rem; letter-spacing: -0.01em;
  border-bottom: 2px solid var(--run-accent); padding-bottom: 0.15rem;
}
.citylinks a:hover { color: var(--run-accent); }

/* ══ DARK THROUGHOUT ═══════════════════════════════════════════════════════
 * The site is black end to end. This block is deliberately last and
 * deliberately in one place rather than edited through thirty rules above,
 * because the token names are older than the decision: --run-ink means both
 * "dark surface" and "text on a light surface", and --run-paper means both
 * "light surface" and "text on a dark one". Flipping the tokens themselves
 * would invert the things that were already correct. So the grounds change
 * here, and every component that assumed white underneath it is answered.
 */

body,
.run-band,
.run-band-warm { background: var(--run-ink); color: var(--run-paper); }
/* The alternate band lifts rather than lightens: one step up in black. */
.run-band-warm { background: var(--run-ink-soft); }

.run-band h3, .run-band-warm h3 { color: var(--run-paper); }
.run-sub, .fare-note, .formnote { color: var(--run-muted-dark); }
.eyebrow { color: var(--run-accent); }

/* Cards: raised black, hairlines in the dark tone. */
.svc, .veh, .benefit, .tile, .citybtn, .run-card {
  background: var(--run-ink-soft);
  border-color: var(--run-hairline-dk);
  color: var(--run-paper);
}
.svc p, .veh .models, .benefit p, .tile-p, .citybtn .note { color: var(--run-muted-dark); }
.tile-h, .svc h3, .veh h3, .benefit h3 { color: var(--run-paper); }
/* The "all services" tile inverted itself against a white rail; on black it
   has to invert the other way or it disappears into its neighbours. */
.tile-all { background: var(--run-accent); border-color: var(--run-accent); color: var(--run-accent-ink); }
.tile-all .tile-h, .tile-all .tile-p, .tile-all .more { color: var(--run-accent-ink); }
.citybtn[aria-pressed="true"] { background: var(--run-accent); border-color: var(--run-accent); color: var(--run-accent-ink); }
.citybtn[aria-pressed="true"] .code,
.citybtn[aria-pressed="true"] .note { color: var(--run-accent-ink); }

/* Fare tables. */
.run-table { color: var(--run-paper); }
.run-table th { background: var(--run-ink); color: var(--run-muted-dark); border-color: var(--run-hairline-dk); }
.run-table td, .run-table tr { border-color: var(--run-hairline-dk); }
.run-table tbody tr:nth-child(even) { background: var(--run-ink-soft); }
.run-table .km { color: var(--run-muted-dark); }

/* Expanders and steps. */
.apart-list, .apart { border-color: var(--run-hairline-dk); }
.apart-h { color: var(--run-paper); }
.apart p, .step p { color: var(--run-muted-dark); }
.step, .sec-head { border-color: var(--run-hairline-dk); }

/* Form fields stay light. A dark input on a dark page reads as disabled, and
   this is the one surface where being obviously fillable beats being on-theme. */
.run-field { background: var(--run-paper); color: var(--run-ink); border-color: var(--run-hairline); }
.quote { background: var(--run-ink-soft); }
.run-label { color: var(--run-muted-dark); }

.run-btn-line { color: var(--run-paper); border-color: var(--run-paper); }
.run-btn-line:hover { background: var(--run-paper); color: var(--run-ink); }
.card-img, .veh-img { border-color: var(--run-hairline-dk); }
.faq details, .faq summary { border-color: var(--run-hairline-dk); }
.faq summary { color: var(--run-paper); }
.faq .a { color: var(--run-muted-dark); }

/* ══ Footer, compact ══════════════════════════════════════════════════════
 * It was a full band of padding and a four-column grid with 2rem gaps, which
 * on a phone is most of a screen of links nobody scrolled for. Addison Lee's
 * is a tight block at the bottom, so this is too. */
.site-foot { padding: 2.5rem var(--run-gutter) 1.5rem; }
.foot-cols { gap: 1.25rem 1.5rem; grid-template-columns: repeat(auto-fit, minmax(min(45%, 9rem), 1fr)); }
.foot-cols h3 { font-size: 0.625rem; margin-bottom: 0.5rem; }
.foot-cols a, .foot-cols li { font-size: 0.8125rem; }
.foot-cols li { padding: 0.1rem 0; }
.foot-legal { margin-top: 1.75rem; padding-top: 1rem; font-size: 0.75rem; }

/* Two things the contrast audit caught after the flip, both of them rules that
   were correct while the page was white and became invisible when it was not. */
/* The from-price was ink, which had a .run-band-dark override. Every band is
   dark now, so the override is the rule. */
.run-price { color: var(--run-accent); }
/* The current step was ink on what is now a black band. */
.steps li[data-state="now"] { color: var(--run-paper); }

/* Inline links in prose. There was no rule for these at all, so they were
   rendering in the browser default blue, #0000EE, which was already wrong on
   white and is unreadable on black. Nav, footer, cards and buttons all style
   their own anchors, which is why this never showed until a contrast audit
   went looking for it. */
.run-inner p a:not(.run-btn):not(.more),
.faq .a a,
.run-narrow a:not(.run-btn) {
  color: var(--run-accent);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
.run-inner p a:not(.run-btn):not(.more):hover,
.faq .a a:hover { color: var(--run-paper); }

/* The quote page opens on the form, so it needs top room of its own now that
   there is no hero band above it. */
.bookband { padding-top: 2.5rem; }
.tier .t-from {
  display: block; margin-top: 0.4rem;
  color: var(--run-accent); font-weight: 700; font-size: 0.9375rem;
}
/* The header is sticky, so anything scrolled to must clear it. */
.steps { scroll-margin-top: 5.5rem; }

/* ---- The price step ------------------------------------------------------
   Only ever visible when the server has actually returned a price. The
   markup ships hidden and the script unhides it, so a page with no key, no
   route or no network simply never shows these and keeps its "from" prices. */

/* The route line above the cars: what was measured, and what the number
   covers. Quiet, because it is context for the prices rather than a claim. */
.quoteline {
  margin: 0 0 1rem; padding: 0.7rem 0.9rem;
  border: 1px solid var(--run-hairline); border-radius: var(--run-radius);
  font-size: var(--run-small); color: var(--run-muted);
}

/* A car the party will not fit into. Dimmed and unclickable rather than
   removed: seeing it go grey as the passenger count passes it explains the
   constraint, where a vanishing tile just looks like a bug. */
.tier.is-out { opacity: 0.4; cursor: not-allowed; }
.tier.is-out:hover { border-color: var(--run-hairline); }

/* The total, on the last panel, immediately above Send. This is the one number
   the customer is agreeing to, so it is the loudest thing on the panel. */
.quotesummary {
  margin: 0 0 1rem; padding: 0.9rem 1rem;
  border: 1px solid var(--run-accent); border-radius: var(--run-radius);
  font-size: 1rem; font-weight: 600; line-height: 1.5;
}

/* ---- Service tiles sit on the ground, not above it -----------------------
   The photograph already separates a tile from the page. The raised grey
   behind its caption only added a seam under the picture, so the caption takes
   the same black and the hairline is left to do the work of an edge. */
.tile:not(.tile-all) { background: var(--run-ink); }

/* ---- What sets us apart, given the page ---------------------------------
   It closes the homepage now that "how it works" has gone, so it gets the
   viewport rather than a slot. min-height, not height: six expanders opened at
   once on a phone must be allowed to grow past it. */
.apart-full { min-height: 100svh; display: grid; align-content: center; }

/* ---- Prices: city, then suburb, then the price ------------------------- */

/* Each step arrives rather than appears, so the eye follows the answer down
   the page instead of hunting for what changed. */
.farestep { margin-top: 2.5rem; }
.farestep[hidden] { display: none; }
.subfind { max-width: 26rem; }

/* The suburb list is a lot of small targets, so they wrap as chips rather than
   stacking into a column nobody scrolls to the end of. */
.subpick { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.subbtn {
  font: inherit; font-size: 0.9375rem; cursor: pointer;
  padding: 0.55rem 0.9rem; border-radius: 999px;
  border: 1px solid var(--run-hairline-dk);
  background: var(--run-ink-soft); color: var(--run-paper);
  transition: border-color var(--run-transition), background var(--run-transition);
}
.subbtn:hover { border-color: var(--run-accent); }
.subbtn[aria-pressed="true"] {
  background: var(--run-accent); border-color: var(--run-accent); color: var(--run-accent-ink);
}
/* Only shown when a search has crossed into another city, where the suburb
   name alone would be ambiguous. */
.sub-city { margin-left: 0.45rem; opacity: 0.6; font-size: 0.8125rem; }
.subbtn[aria-pressed="true"] .sub-city { opacity: 0.75; }

/* The answer. Three cars, because three is what anyone is actually choosing
   between; the full seven-column table is still on the page below. */
.fc-head {
  margin: 0 0 0.25rem; font-size: 1.125rem; color: var(--run-muted-dark);
}
.fc-head b { color: var(--run-paper); font-weight: 700; }
.fc-when { display: block; font-size: var(--run-small); color: var(--run-muted-dark); margin-top: 0.2rem; }

.fc-grid {
  display: grid; gap: 0.75rem; margin: 1.25rem 0 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}
.fc {
  display: flex; flex-direction: column; gap: 0.3rem;
  padding: 1.4rem 1.25rem;
  border: 1px solid var(--run-hairline-dk); border-radius: var(--run-radius);
  background: var(--run-ink-soft);
}
.fc-name { font-weight: 600; color: var(--run-paper); }
.fc-cap  { font-size: var(--run-small); color: var(--run-muted-dark); }
/* The number is the reason the page exists, so nothing on the card competes. */
.fc-price {
  margin-top: 0.5rem; color: var(--run-accent);
  font-family: var(--run-font-display); font-weight: 700;
  font-size: 2.25rem; line-height: 1; letter-spacing: -0.02em;
}
.fc-note { margin: 0; font-size: var(--run-small); color: var(--run-muted-dark); }
.fc-cta  { margin: 1.25rem 0 0; }

/* ---- What sets us apart, opened out --------------------------------------
   These now ship open, so the body copy is the section rather than something
   behind a click. Sized up to match: at the old 0.9375rem it read as a caption
   under a heading instead of the point of the band. */
.apart summary { padding: 1.5rem 0 1.1rem; }
.apart summary .ico { width: 2rem; height: 2rem; }
.apart-h { font-size: 1.375rem; }
.apart p {
  font-size: 1.0625rem; line-height: 1.65;
  margin-bottom: 1.75rem; max-width: 62ch;
}
@media (min-width: 720px) {
  .apart summary { padding: 1.75rem 0 1.25rem; }
  .apart-h { font-size: 1.625rem; }
  .apart p { font-size: 1.125rem; }
}

/* ── Card field ─────────────────────────────────────────────────────────────
   Stripe renders the inputs inside an iframe it owns, so the card number never
   enters this page's DOM and never reaches our servers. All we style is the box
   around it, which has to match the other fields or the most sensitive field on
   the form is the one that looks least like it belongs. */
.paybox { margin: 18px 0 6px; }
.cardfield {
  border: 1px solid var(--run-hairline, #d2d2d7);
  border-radius: 12px; padding: 13px 14px; background: #fff;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cardfield.is-focus { border-color: #0071e3; box-shadow: 0 0 0 3px rgba(0,113,227,.15); }
.cardfield.is-error { border-color: #d70015; }
.paybox .fare-note { margin-top: 8px; }

/* ── Price breakdown ────────────────────────────────────────────────────────
   A single sentence with every extra folded into it made the customer
   reverse-engineer the total. A total on its own always provokes "why is it
   that much"; itemising answers it before they ask, and on a payment screen
   that question going unanswered is where people leave. */
.quotesummary .bd {
  display: grid; grid-template-columns: 1fr auto;
  gap: 6px 16px; margin-bottom: 10px;
}
.quotesummary .bd-k { text-align: left; }
.quotesummary .bd-v { text-align: right; font-variant-numeric: tabular-nums; }
.quotesummary .bd-total {
  font-weight: 800; padding-top: 8px;
  border-top: 1px solid currentColor; margin-top: 2px;
}
.quotesummary .bd-note { display: block; font-size: .9em; opacity: .75; }

/* ── Wallet button ──────────────────────────────────────────────────────────
   Above the card field on purpose. On a phone the wallet is how most people
   will pay, and putting it below a card form asks them to read past the easy
   option to find it. Both stay visible: a wallet is not always set up, and a
   customer who wants to type a card should never have to hunt for the field. */
#walletEl { margin-bottom: 14px; }
.wallet-or {
  display: flex; align-items: center; gap: 12px;
  margin: 0 0 14px; color: var(--run-muted, #86868b); font-size: 13px;
}
.wallet-or::before, .wallet-or::after {
  content: ""; flex: 1; height: 1px; background: currentColor; opacity: .25;
}

/* A step that refuses to advance has to say why. The car radios are hidden
   inside their tiles, so the browser's own bubble never appears and the
   customer sees a dead Continue button instead of a missing answer. */
.steperr {
  margin: 14px 0 0;
  color: #d7263d;
  font-size: 14px;
  font-weight: 600;
}

/* Social links sit inline in the footer contact list rather than as icons.
   Two links do not need a row of glyphs, and words are readable by anyone
   using a screen reader without an aria-label doing the work. */
.foot-social { display: flex; gap: 1rem; }

/* ── The price gate ────────────────────────────────────────────────────────
   Shown after a route is priced and before the fares. Every colour is stated
   rather than inherited: this widget sits on pages with different backgrounds,
   and a panel that borrows its text colour is how you ship a form nobody can
   read. That has happened on this site once already. */
.leadgate {
  margin: 0 0 1.25rem;
  padding: 1.1rem 1.1rem 1rem;
  background: #FAFAF8;
  color: var(--run-ink, #0A0A0A);
  border: 1px solid var(--run-hairline, #E4E4E4);
  border-left: 3px solid var(--run-accent, #FFC800);
  border-radius: var(--run-radius, 2px);
}
.leadgate .lg-h {
  margin: 0 0 .35rem;
  font-size: 1.05rem; font-weight: 700; line-height: 1.3;
  color: var(--run-ink, #0A0A0A);
}
.leadgate .lg-s {
  margin: 0 0 .9rem;
  font-size: .875rem; line-height: 1.5;
  color: var(--run-muted, #6B6B6B);
}
.leadgate .f { margin: 0 0 .7rem; }
.leadgate .run-label { color: var(--run-ink, #0A0A0A); }
.leadgate .run-field { background: #FFFFFF; color: var(--run-ink, #0A0A0A); }
.leadgate .run-btn { width: 100%; margin-top: .2rem; }
.leadgate .lg-f {
  margin: .7rem 0 0;
  font-size: .8125rem; line-height: 1.45;
  color: var(--run-muted, #6B6B6B);
}

/* The gate's way out. Quiet on purpose: it should be findable by somebody
   looking for it and not compete with the button above it. Colours stated,
   not inherited, like the rest of this panel. */
.leadgate .lg-skip {
  appearance: none; -webkit-appearance: none;
  display: block; width: 100%;
  margin: .55rem 0 0; padding: .6rem;
  border: 0; background: none;
  font: inherit; font-size: .8125rem; font-weight: 600;
  color: var(--run-muted, #6B6B6B);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.leadgate .lg-skip:hover { color: var(--run-ink, #0A0A0A); }
.leadgate .lg-skip:focus-visible { outline: 2px solid var(--run-ink, #0A0A0A); outline-offset: 2px; }
