/* ==========================================================================
   Wasatch Mountain Express — Highway Marker
   Reads like a road sign. Condensed display type, hairline rules instead of
   cards, square corners, no shadow anywhere, and a single red that only ever
   means "act".
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Metric-matched fallback
   Archivo Narrow is condensed; Arial is not. While the webfont downloads the
   header renders ~20% wider, which is enough to wrap the nav to two rows and
   then snap it back once the font lands. Scaling the fallback to Archivo
   Narrow's measured width ratio removes that shift. Loading state only — it
   changes nothing once the real font arrives.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Archivo Narrow Fallback';
  src: local('Arial'), local('Helvetica'), local('Liberation Sans');
  size-adjust: 82%;
  ascent-override: 100%;
  descent-override: 26%;
  line-gap-override: 0%;
}

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Colour */
  --snowfield: #F4F6F7;   /* Page background */
  --white:     #FFFFFF;   /* Panels, alternate bands */
  --asphalt:   #101418;   /* Type, bars, footer */
  --slate:     #5A646E;   /* Secondary text, labels */
  --rule:      #C9D1D6;   /* Every hairline border */
  --red:       #D5202B;   /* Actions and the phone only */
  --red-hover: #A81820;
  --red-disabled: #E4C4C6;
  --body-ink:  #2A3138;   /* Body copy, dark rules */
  --on-asphalt:#9AA5AE;   /* Text on asphalt */
  --divider:   #E6EAEC;   /* Inner list divider */
  --map-sky:   #EAF0F3;
  --map-ridge: #C6D3DB;

  /* Dark-surface variants. Slate and signal red are both below WCAG AA on
     asphalt (3.07:1 and 3.59:1) at the small mono sizes they are used at, so
     each is lifted just far enough to clear 4.5:1. Same hues, and both stay
     dimmer than --on-asphalt so the type hierarchy is unchanged.
     These apply to text on asphalt only — never to a red fill. */
  --slate-on-dark: #74818E;  /* 4.64:1 on asphalt */
  --red-on-dark:   #E8434D;  /* 4.70:1 on asphalt, hue 356 as --red */

  /* Type */
  --display: 'Archivo Narrow', 'Archivo Narrow Fallback', Arial, sans-serif;
  --body: Archivo, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;

  /* 4px base scale */
  --s4: 4px;    --s8: 8px;    --s12: 12px;  --s16: 16px;
  --s20: 20px;  --s24: 24px;  --s32: 32px;  --s40: 40px;
  --s48: 48px;  --s56: 56px;  --s64: 64px;

  /* Structure */
  --content: 1320px;
  --gutter: var(--s24);
  --measure: 66ch;      /* Body copy */
  --measure-small: 70ch; /* Small print */
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--snowfield);
  color: var(--asphalt);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* Corners: 0px. Everywhere. No exceptions, including images, buttons and
   inputs. Shadow: none — depth comes from tone changes and rules. */
img, button, input, select, textarea, a, div, span, section, table {
  border-radius: 0;
  box-shadow: none;
}

img { max-width: 100%; display: block; }

a { color: var(--asphalt); text-decoration: none; }
a:hover { color: var(--red); }

::selection { background: var(--red); color: #fff; }

h1, h2, h3, p { margin: 0; }

table { border-collapse: collapse; width: 100%; }

/* Focus is always a 2px outline offset from the shape, never a colour change
   alone. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--asphalt);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--asphalt);
  color: var(--white);
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: var(--s12) var(--s20);
  z-index: 100;
}
.skip-link:focus {
  left: var(--s8);
  top: var(--s8);
  color: var(--white);
}

/* Available to screen readers, off-screen for everyone else */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   3. Layout
   -------------------------------------------------------------------------- */

.wrap {
  max-width: var(--content);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* Two backgrounds only — snowfield and white — alternating band to band,
   with asphalt for the utility bar, calls to action and the footer. */
.band          { border-bottom: 1px solid var(--rule); }
.band--white   { background: var(--white); }
.band--asphalt { background: var(--asphalt); color: var(--snowfield); }
.band--map     { background: var(--map-sky); }

.band__inner   { padding-top: var(--s56); padding-bottom: var(--s56); }
.band__inner--tight { padding-top: var(--s48); padding-bottom: var(--s48); }

/* Page header block under the site header */
.page-head { padding-top: var(--s40); padding-bottom: var(--s40); }

.split {
  display: grid;
  grid-template-columns: 1fr;
}
.cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s32);
}

.measure       { max-width: var(--measure); }
.measure-small { max-width: var(--measure-small); }

/* --------------------------------------------------------------------------
   4. Type
   -------------------------------------------------------------------------- */

.display-xl, .display-l, .display-m, .display-s, .heading {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
}

.display-xl {
  font-size: clamp(38px, 8vw, 60px);
  line-height: 1.0;
  letter-spacing: -0.005em;
  text-wrap: balance;
}
.display-l { font-size: clamp(34px, 7vw, 52px); line-height: 1.0; }
.display-m { font-size: clamp(26px, 4.6vw, 34px); line-height: 1.0; }
.display-s { font-size: clamp(22px, 3.4vw, 26px); line-height: 1.05; }
.heading   { font-size: 20px; line-height: 1.15; }
.heading--sm { font-size: 19px; }

.body-l { font-size: 18px; line-height: 1.55; color: var(--body-ink); text-wrap: pretty; }
.body   { font-size: 17px; line-height: 1.55; color: var(--body-ink); text-wrap: pretty; }
.body-s { font-size: 15px; line-height: 1.5;  color: var(--slate); }

.micro {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate);
}
.micro-xs {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate);
}
.micro--red, .micro-xs--red { color: var(--red); }

.muted { color: var(--slate); }
.tabular { font-variant-numeric: tabular-nums; }

/* Section heading with its rule. 2px asphalt normally, 2px red when this is
   the heading to read. */
.rule-head {
  border-bottom: 2px solid var(--asphalt);
  padding-bottom: var(--s8);
  margin-bottom: var(--s20);
}
.rule-head--red { border-bottom-color: var(--red); }

.rule-head--flex {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--s24);
  flex-wrap: wrap;
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   5. Buttons and links
   -------------------------------------------------------------------------- */

.btn {
  display: inline-block;
  font-family: var(--display);
  font-weight: 700;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 16px 28px;
  border: none;
  cursor: pointer;
  text-align: center;
}

.btn--primary { background: var(--red); color: var(--white); }
.btn--primary:hover { background: var(--red-hover); color: var(--white); }
.btn--primary:disabled { background: var(--red-disabled); cursor: default; }

.btn--secondary {
  background: transparent;
  border: 2px solid var(--asphalt);
  color: var(--asphalt);
  padding: 14px 28px;
}
.btn--secondary:hover { background: var(--asphalt); color: var(--white); }
.btn--secondary:focus-visible { outline-color: var(--red); }

/* Primary sits at 14px in the header and 16px in a call-to-action band. */
.btn--sm { font-size: 14px; padding: 13px 20px; }
.btn--sm.btn--secondary { padding: 11px 20px; }

/* Text link — condensed caps over a red rule */
.tlink {
  display: inline-block;
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 2px solid var(--red);
  padding-bottom: 2px;
}
.tlink:hover { color: var(--red); }
.tlink:focus-visible { outline-offset: 3px; }
.tlink--on-dark { color: var(--snowfield); }
.tlink--on-dark:hover { color: var(--red); }
/* Inside a sentence. Takes the surrounding size, weight and case, and keeps
   only the red rule — thinned to a hairline so it does not shout mid-prose. */
.tlink--inline {
  display: inline;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  text-transform: none;
  border-bottom-width: 1px;
  padding-bottom: 1px;
}

/* The phone number is red because it is an action, never decoration. */
.phone {
  font-family: var(--display);
  font-weight: 700;
  color: var(--red);
  letter-spacing: -0.01em;
  line-height: 1;
}
.phone--lg { font-size: 32px; }
.phone--header { font-size: 23px; }
.phone--on-dark { color: var(--snowfield); }
.phone--on-dark:hover { color: var(--red); }

/* --------------------------------------------------------------------------
   6. Utility bar and header
   -------------------------------------------------------------------------- */

.utility {
  background: var(--asphalt);
  color: var(--snowfield);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.utility__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s24);
  padding-top: 9px;
  padding-bottom: 9px;
  flex-wrap: wrap;
}
.utility__flag { color: var(--red); font-weight: 700; }

.site-header {
  background: var(--white);
  border-bottom: 2px solid var(--asphalt);
  position: sticky;
  top: 0;
  z-index: 50;
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s16) var(--s24);
  flex-wrap: wrap;
  padding-top: var(--s12);
  padding-bottom: var(--s12);
  min-height: 54px;
}

.brand { display: flex; align-items: center; gap: var(--s12); flex-shrink: 0; }

/* The mark alone, sized to fill the header row exactly.
   ------------------------------------------------------------------------
   logo.png has "Wasatch Mountain Express" set underneath the mark, and
   .brand__name says the same thing in real type right beside it. At any header
   size the baked-in wordmark was an illegible smudge repeating the name next to
   itself, and it got worse as the logo got bigger. logo-mark.png is the same
   artwork with the wordmark cropped off, so the mark itself renders about twice
   as large in the same height.

   60px is not a taste call, it is the measured ceiling. .brand__name wraps to
   three lines at 9ch — WASATCH / MOUNTAIN / EXPRESS — which is 60px tall, and
   that is what sets the height of the header row. A logo up to 60px fits inside
   it for free; at 64px the brand box starts driving the row and the whole site's
   header grows from 86px to 90px. So 60px is every pixel available without
   moving anything else. Measured at 1400px with the webfonts confirmed loaded:
   nav still one row, 50px of headroom, header height unchanged at 86px.

   Phones are limited by width, not height, so they cannot have it. The mark is
   2.17:1, so 60px tall is 130px wide, and the brand then needs 220px of content
   width. Below about 385px the row cannot give that — brand and Menu button wrap
   onto separate lines and the header jumps from 150px to 208px. 360px Android
   and the 375px iPhone SE both fall inside that, and 390px clears it by only
   5px, which is not slack. So it steps down at the 620px boundary this file
   already uses: 44px needs 185px against the 195px available at 360px. */
.brand img { height: 60px; width: auto; }

/* Phone-size header. Two rows: brand and Menu, then phone and Reserve now. */
@media (max-width: 619px) {
  .brand img { height: 44px; }

  /* Anchor the second row to both gutters, the way the first row already is.
     .header__actions is flex: 1 1 100% below 1320px, so it spans the full
     content width — but its two children were packed to the left, leaving the
     Reserve button's right edge 37px short of the Menu button's directly above
     it (299 against 336 at 360px). The left edge was never wrong: the phone
     number already sat on the 24px gutter with everything else. It was the
     right edge that was ragged, and against a Menu button one row up it read
     as a misalignment rather than as grouping.

     This is the same logic the header uses everywhere else — brand hard left,
     actions hard right — so it is consistent rather than a special case. Held
     to 619px deliberately: between 620 and 1319 the row is wide enough that
     the pair reads as a group rather than as a broken edge, and pushing them
     apart there would open a gap wide enough to look like a mistake. */
  .header__actions { justify-content: space-between; }
}

.brand__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  max-width: 9ch;
}

.header__actions { display: flex; align-items: center; gap: var(--s16); flex-shrink: 0; }

/* Mobile menu toggle — hidden once the full nav fits */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s8);
  background: transparent;
  border: 2px solid var(--asphalt);
  color: var(--asphalt);
  font-family: var(--display);
  font-weight: 700;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 10px 14px;
  cursor: pointer;
}
.nav-toggle__bars { display: block; width: 16px; height: 2px; background: currentColor; position: relative; }
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: ""; position: absolute; left: 0; width: 16px; height: 2px; background: currentColor;
}
.nav-toggle__bars::before { top: -5px; }
.nav-toggle__bars::after  { top: 5px; }

/* --------------------------------------------------------------------------
   7. Navigation
   -------------------------------------------------------------------------- */

.nav {
  font-family: var(--display);
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.nav a, .nav__trigger { display: block; padding: 10px 12px; }
.nav a:hover, .nav__trigger:hover { color: var(--red); }

/* Current page */
.nav a[aria-current="page"] { border-bottom: 2px solid var(--red); }

.nav__group { position: relative; }
.nav__trigger {
  background: none;
  border: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  text-align: left;
}
.nav__caret { font-size: 9px; }

.nav__menu {
  background: var(--white);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--red);
  min-width: 250px;
  display: flex;
  flex-direction: column;
}
.nav__menu a {
  padding: 13px 16px;
  border-bottom: 1px solid var(--divider);
}
.nav__menu a:last-child { border-bottom: none; }
.nav__menu a:hover { background: var(--snowfield); color: var(--red); }

/* --- Mobile-first: nav is a panel toggled open ---------------------------- */
/* The full eleven-item nav needs a 1320px viewport to sit on one row beside the
   brand, the phone and the Reserve button. Below that it becomes a panel behind
   the Menu button rather than wrapping to two lines. */
@media (max-width: 1319px) {
  /* Row 1: brand and the menu button. Row 2: phone and Reserve now.
     Row 3: the navigation panel, once opened. */
  .brand { flex: 1 1 auto; }
  .nav-toggle { flex: 0 0 auto; }
  .header__actions { flex: 1 1 100%; }

  .nav {
    display: none;
    width: 100%;
    border-top: 1px solid var(--rule);
    padding-top: var(--s8);
    padding-bottom: var(--s8);
  }
  .nav.is-open { display: block; }
  .nav a, .nav__trigger { padding: 12px 0; }
  .nav__caret { display: none; }
  .nav__trigger { cursor: default; color: var(--slate); font-size: 11px; letter-spacing: 0.12em; }
  .nav__trigger:hover { color: var(--slate); }
  .nav__menu {
    border: none;
    border-left: 2px solid var(--red);
    padding-left: var(--s16);
    margin-bottom: var(--s8);
    min-width: 0;
  }
  .nav__menu a { padding: 10px 0; border-bottom: none; }
  .nav a[aria-current="page"] { color: var(--red); border-bottom: none; }
}

/* --- Desktop: horizontal bar with hover/focus dropdowns ------------------- */
@media (min-width: 1320px) {
  .nav {
    display: flex !important;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px 4px;
    /* basis 0 so the nav never forces the phone and Reserve button onto a
       second header row — it takes the space that is left and wraps inside
       itself if it ever runs out */
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
  }
  /* 11px rather than 12px: the full nav is 10px too wide for the 1320px
     content width at 12px, and would break the single-row header. */
  .nav a, .nav__trigger { padding: 10px 11px; }

  /* Reserve the current-page underline on every top-level item. Without this
     only the current item carries the 2px border, making it 2px taller, and
     align-items:center then drops every other item by 1px — the labels stop
     sharing a baseline. The red is applied by the .nav a[aria-current] rule,
     which is more specific and still wins here. */
  .nav > a,
  .nav__trigger { border-bottom: 2px solid transparent; }

  .nav-toggle { display: none; }
  .nav__menu {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 60;
    display: none;
  }
  .nav__group:hover .nav__menu,
  .nav__group:focus-within .nav__menu { display: flex; }
  .nav__trigger { cursor: pointer; }
}

/* --------------------------------------------------------------------------
   8. Hero
   -------------------------------------------------------------------------- */

.hero { display: grid; grid-template-columns: 1fr; }
.hero__copy { padding: var(--s48) var(--gutter) var(--s40); }
.hero__media { position: relative; min-height: 320px; background: var(--asphalt); }
.hero__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.btn-row { display: flex; gap: 10px; flex-wrap: wrap; }

/* Photo caption tag */
.caption-tag {
  position: absolute;
  left: var(--s16);
  bottom: var(--s16);
  background: var(--asphalt);
  color: var(--white);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 7px 10px;
}
.caption-tag--red { background: var(--red); }

/* Full-bleed image band */
.image-band { position: relative; min-height: 260px; background: var(--asphalt); }
.image-band img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Image that fills its half of a split */
.media-fill { position: relative; min-height: 300px; background: var(--asphalt); }
.media-fill img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* --------------------------------------------------------------------------
   9. Components
   -------------------------------------------------------------------------- */

/* Stat cell row
   The 1px gaps over a --rule background are what draw the dividers between
   cells, which is why there is one between every pair and none on the outer
   edges. That matches the design system, where each cell carries border-right
   and the last one does not.

   No border of its own, deliberately. The horizontal rules above and below this
   row are the two bands' own border-bottom, which run the full width of the
   viewport. This element is capped at 1320px, so giving it a border-top and
   border-bottom drew a second, shorter line 1px away from each of them — at
   1400px the stray one ran x33 to x1353 while the band's ran edge to edge, and
   you could see exactly where it stopped. Shad caught it on the home page.

   .stats--boxed is the other usage — ski-season.php and design-system.php —
   where the row sits inside a normal padded wrap rather than spanning the band.
   There a closed box is right, and it sets all four borders itself. */
.stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--rule);
}
.stats__cell { background: var(--white); padding: 22px var(--gutter); }
.stats--boxed { border: 1px solid var(--rule); }
.stats--boxed .stats__cell { padding: 20px; }
.stat__value {
  font-family: var(--display);
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
}
.stat__value--sm { font-size: 28px; }
.stat__label { font-size: 14px; color: var(--slate); margin-top: 5px; }

/* Rate row */
.rates td { padding: 15px 0; font-size: 17px; }
.rates tr { border-bottom: 1px solid var(--rule); }
.rates tr:last-child { border-bottom: none; }
.rates__price {
  text-align: right;
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rates__price--quoted { font-size: 17px; color: var(--slate); font-weight: 700; }
.rates__note { color: var(--slate); font-size: 15px; }

/* Included / extra list */
.deflist { display: flex; flex-direction: column; }
.deflist__row {
  display: flex;
  justify-content: space-between;
  gap: var(--s16);
  padding: 13px 0;
  border-bottom: 1px solid var(--divider);
  font-size: 16px;
}
.deflist__row:last-child { border-bottom: none; }
.deflist__value--strong { font-weight: 700; font-variant-numeric: tabular-nums; }

/* Plain bordered list */
.plainlist { display: flex; flex-direction: column; }
.plainlist__row {
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 17px;
}
.plainlist__row:last-child { border-bottom: none; }

/* Chips */
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  border: 1px solid var(--asphalt);
  padding: 6px 11px;
  font-family: var(--display);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.chip--lg { padding: 7px 12px; font-size: 14px; }
.chip--active { border-color: var(--red); background: var(--red); color: var(--white); }
.chip--off { border-color: var(--divider); color: var(--rule); }

/* Point list — heading plus paragraph, repeated */
.points { display: flex; flex-direction: column; gap: 22px; }
.point__title {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 6px;
}
.point__body { font-size: 16px; line-height: 1.55; color: var(--slate); }

/* Service cards */
.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}
.card { background: var(--white); display: flex; flex-direction: column; }
/* The card is an <a>, so its parts are spans — blockify them. */
.card__media, .card__body, .card__title, .card__text { display: block; }
.card__media { height: 170px; overflow: hidden; }
.card__media img { width: 100%; height: 100%; object-fit: cover; }
.card__body { padding: var(--s20); }
.card__title {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 7px;
}
.card__text { font-size: 15px; line-height: 1.5; color: var(--slate); }

/* Fleet card — taller media, roomier body */
.card--fleet .card__media { height: 240px; }
.card--fleet .card__body { padding: var(--s24); }
.card--fleet .card__title { font-size: 22px; margin-bottom: 10px; }
.card--fleet .card__text { font-size: 16px; line-height: 1.6; }

/* Review card */
.reviews-grid { display: grid; grid-template-columns: 1fr; gap: var(--s20); }
.review {
  background: var(--white);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--red);
  padding: 22px;
}
.review__quote { font-size: 16px; line-height: 1.55; margin-bottom: 12px; color: var(--slate); }
.review__by { font-size: 14px; color: var(--slate); }

/* Numbered steps */
.steps { display: flex; flex-direction: column; }
.step {
  display: flex;
  gap: var(--s20);
  padding: var(--s24) 0;
  border-bottom: 1px solid var(--rule);
}
.step:first-child { padding-top: 0; }
.step:last-child { border-bottom: none; padding-bottom: 0; }
.step__n {
  font-family: var(--display);
  font-size: 32px;
  font-weight: 700;
  color: var(--red);
  line-height: 1;
  min-width: 36px;
}
.step__title {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 7px;
}
/* Body ink rather than slate. These steps get read one-handed, in a bright
   terminal, by someone who has just got off a plane — 12:1 not 5.9:1. */
.step__body { font-size: 16px; line-height: 1.55; color: var(--body-ink); }
.step__body strong { font-weight: 700; color: var(--asphalt); }
.step__title em { font-style: normal; color: var(--red); }

/* Photo drop inside a step. Native <details> like the FAQ, so it works with
   JavaScript off, and closed by default so photographs cost no scroll length —
   this page is followed while walking. No `name`, so several can be open at
   once: someone comparing the escalator and the curb should not have one shut
   the other. The image is only fetched when the panel is opened. */
.step__photo { margin-top: 12px; }
.step__photo summary {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--red);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  list-style: none;
}
.step__photo summary::-webkit-details-marker { display: none; }
.step__photo summary::after { content: "+"; font-size: 14px; line-height: 1; }
.step__photo[open] summary::after { content: "\2212"; }
.step__photo summary:hover { color: var(--red-hover); }
.step__photo img {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 10px;
  border: 1px solid var(--rule);
}

/* The #steps anchor is what a landed customer is sent. It is on the page head
   now, so it resolves to the top of the page; the scroll-margin is kept so a
   browser restoring that hash still clears the sticky header rather than
   tucking the eyebrow under the logo. */
#steps { scroll-margin-top: 160px; }
@media (min-width: 900px) { #steps { scroll-margin-top: 120px; } }

/* On a phone the split stacks, so the curb photograph lands after all seven
   steps — roughly 1,100px of scroll for something step 7's photo drop now
   offers on tap. Hidden below 900px; on desktop it still sits beside the steps,
   where it costs nothing. */
@media (max-width: 899px) { .steps-band .media-fill { display: none; } }

@media (max-width: 899px) {
  /* Bigger tap-free reading targets on the page people follow while walking */
  .step { padding: var(--s20) 0; gap: var(--s16); }
  .step__n { font-size: 28px; min-width: 30px; }
  .step__title { font-size: 19px; }
  .step__body { font-size: 17px; line-height: 1.5; }
}

/* Fact tiles */
.facts {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}
.fact { background: var(--white); padding: var(--s24); }
.fact__value {
  font-family: var(--display);
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
}
.fact__note { font-size: 15px; color: var(--slate); margin-top: 6px; }

/* Accordion. Native <details> so it works with JavaScript switched off;
   the name attribute keeps one open at a time where the browser supports it. */
.accordion { border-top: 2px solid var(--asphalt); }
.accordion details { border-bottom: 1px solid var(--rule); }
.accordion summary {
  padding: 20px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s20);
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-size: 21px;
  font-weight: 700;
  text-transform: uppercase;
}
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary::after {
  content: "+";
  font-family: var(--mono);
  font-size: 18px;
  color: var(--red);
  flex-shrink: 0;
}
.accordion summary:hover { color: var(--red); }
.accordion details[open] summary { color: var(--red); }
.accordion details[open] summary::after { content: "\2212"; }
/* The gap above the hairline belongs to the <details>, not to the answer
   paragraph, so anything may come last inside an answer — a second paragraph
   or a .tlink, whose red rule would otherwise sit on the border. */
.accordion details[open] { padding-bottom: 22px; }
.accordion__body {
  font-size: 17px;
  line-height: 1.6;
  color: var(--slate);
  max-width: var(--measure-small);
}
.accordion__link { margin-top: 14px; }

/* Notice — carries the [CHECK] marker */
.notice {
  border: 1px solid var(--red);
  background: var(--white);
  padding: 20px 24px;
}
.notice__label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 8px;
}
.notice__body { font-size: 16px; line-height: 1.6; color: var(--body-ink); }

/* Inline callout panel */
.callout {
  background: var(--snowfield);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--red);
  padding: 22px var(--s24);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s24);
  flex-wrap: wrap;
}
.callout__title {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 4px;
}

/* Call-to-action band */
.cta__inner {
  padding-top: var(--s40);
  padding-bottom: var(--s40);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s32);
  flex-wrap: wrap;
}
.cta__title {
  font-family: var(--display);
  font-size: clamp(28px, 5vw, 36px);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1;
}
.cta__note { font-size: 15px; color: var(--on-asphalt); margin-top: 8px; }
.cta__actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.cta__phone { font-size: clamp(24px, 4vw, 30px); }

/* Map legend */
.map-legend {
  display: flex;
  justify-content: space-between;
  gap: var(--s24);
  flex-wrap: wrap;
  padding: 4px 0 var(--s20);
}
img.map { width: 100%; height: auto; display: block; }

/* A photographic map is capped rather than run to the full 1320px wrap. The
   ski map is 1233x848, so at wrap width it stands 837px tall and fills a
   laptop screen on its own — it stopped reading as a figure on the page and
   started reading as the page. 820px puts it at 564px, in scale with the
   440px photograph above it, and the labels still read at 15px. */
.map-figure { max-width: 820px; margin: 0 auto; }

/* --------------------------------------------------------------------------
   10. Forms
   -------------------------------------------------------------------------- */

.form { display: grid; grid-template-columns: 1fr; gap: 18px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field--full { grid-column: 1 / -1; }
.field__label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
}
.field input,
.field select,
.field textarea {
  font-family: var(--body);
  font-size: 16px;
  padding: 13px 14px;
  border: 1px solid var(--rule);
  background: var(--white);
  color: var(--asphalt);
  width: 100%;
}
.field textarea { resize: vertical; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--red);
  outline: none;
}
/* Keyboard users still get the offset outline */
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--asphalt);
  outline-offset: 2px;
}
.field input:disabled,
.field select:disabled,
.field textarea:disabled {
  border-color: var(--divider);
  background: var(--snowfield);
  color: var(--on-asphalt);
}
.field--error input,
.field--error select,
.field--error textarea { border: 2px solid var(--red); }
.field--error .field__label { color: var(--red); }
.field__error { font-size: 13px; color: var(--red); }

.form__submit {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

.checkline { display: flex; align-items: center; gap: 10px; font-size: 15px; }
.checkline input { width: 18px; height: 18px; accent-color: var(--red); }

/* --------------------------------------------------------------------------
   11. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--asphalt);
  border-top: 1px solid var(--body-ink);
  color: var(--on-asphalt);
}
.site-footer a { color: var(--on-asphalt); }
.site-footer a:hover { color: var(--snowfield); }
.site-footer a:focus-visible { outline-color: var(--snowfield); }

.footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s32);
  padding-top: var(--s48);
  padding-bottom: var(--s20);
}
.footer__brand {
  font-family: var(--display);
  font-weight: 700;
  font-size: 18px;
  text-transform: uppercase;
  color: var(--snowfield);
  letter-spacing: 0.02em;
  margin-bottom: 12px;
}
.footer__blurb { font-size: 15px; line-height: 1.55; margin-bottom: var(--s16); max-width: 36ch; }
.footer__label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 14px;
}
.footer__links { display: flex; flex-direction: column; gap: 9px; font-size: 15px; }
.footer__phone {
  color: var(--snowfield);
  font-family: var(--display);
  font-size: 22px;
  font-weight: 700;
}
.footer__phone:hover { color: var(--red); }
/* The address is too long for its column and has to wrap somewhere. It must
   NOT be break-all or overflow-wrap:anywhere — both let the line fill greedily
   to the last character that fits, which splits it mid-word ("…expre / ss.com").
   Leaving it as normal means the <wbr> after the @ in the markup is the only
   break opportunity, so it always breaks there. */
.footer__email { overflow-wrap: normal; }

/* Square icon buttons. The marks are inline SVG because the site makes no
   external requests — an icon font or a CDN is not an option. The link text is
   an aria-label, so the border is the only visible target: keep it. */
.social { display: flex; gap: 10px; flex-wrap: wrap; }
.social a {
  border: 1px solid var(--body-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  color: var(--on-asphalt);
}
.social a svg { display: block; width: 18px; height: 18px; fill: currentColor; }
.social a:hover { border-color: var(--red); color: var(--red-on-dark); }

/* Social buttons on a light band (Contact page) */
.social--light a { border-color: var(--asphalt); color: var(--asphalt); }
.social--light a:hover { background: var(--asphalt); color: var(--white); }

.footer__base {
  border-top: 1px solid var(--body-ink);
  padding-top: var(--s16);
  padding-bottom: var(--s40);
  display: flex;
  justify-content: space-between;
  gap: var(--s16);
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.footer__legal { display: flex; gap: 18px; flex-wrap: wrap; }
.footer__base a, .footer__copy { color: var(--slate); }
.footer__base a:hover { color: var(--snowfield); }

/* --------------------------------------------------------------------------
   11b. Text on dark surfaces
   Recessive and red text sitting on asphalt, lifted to clear WCAG AA. Scoped
   to text only: --red still fills the primary button inside these bands, and
   white-on-red must keep its own 5.16:1.
   -------------------------------------------------------------------------- */

.band--asphalt .micro,
.band--asphalt .micro-xs,
.site-footer .footer__label,
.site-footer .footer__base a,
.site-footer .footer__copy {
  color: var(--slate-on-dark);
}
.site-footer .footer__base a:hover { color: var(--snowfield); }

.utility__flag,
.band--asphalt .micro--red,
.band--asphalt .micro-xs--red {
  color: var(--red-on-dark);
}

/* The [CHECK] note is the only red text on the tinted map band, where the
   signal red lands at 4.48:1 — a hair under AA. It takes the deep red already
   in the palette as the primary-button hover, which gives 6.48:1 there. */
.band--map .micro-xs--red { color: var(--red-hover); }

/* --------------------------------------------------------------------------
   12. Design-system reference page only
   -------------------------------------------------------------------------- */

.swatches {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}
.swatches--secondary { border-top: none; }
.swatch { background: var(--white); }
.swatch__chip { height: 88px; }
.swatch__chip--sm { height: 56px; }
.swatch__body { padding: 14px; }
.swatch__name {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 700;
  text-transform: uppercase;
}
.swatch__hex { font-family: var(--mono); font-size: 11px; color: var(--slate); margin-top: 3px; }
.swatch__use { font-size: 13px; color: var(--slate); margin-top: 6px; }

.spec-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s12);
  padding: var(--s20) 0;
  border-bottom: 1px solid var(--rule);
}
.spec-row:last-child { border-bottom: none; }
.spec-row__key { font-family: var(--mono); font-size: 11px; color: var(--slate); }

.scale-row { display: flex; align-items: center; gap: 14px; }
.scale-row__n { font-family: var(--mono); font-size: 11px; color: var(--slate); width: 38px; }
.scale-row__bar { height: 12px; background: var(--asphalt); display: block; }

.states { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.states__head { background: var(--snowfield); padding: 12px 14px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--slate); }
.states__cell { background: var(--white); padding: 18px 14px; }
.states__rowlabel { background: var(--white); padding: 18px 14px; font-family: var(--display); font-size: 14px; font-weight: 700; text-transform: uppercase; display: flex; align-items: center; }

.state-demo { display: inline-block; font-family: var(--display); font-weight: 700; font-size: 15px; text-transform: uppercase; letter-spacing: 0.05em; padding: 14px 22px; }
.state-demo--primary { background: var(--red); color: var(--white); }
.state-demo--primary-hover { background: var(--red-hover); color: var(--white); }
.state-demo--primary-focus { background: var(--red); color: var(--white); outline: 2px solid var(--asphalt); outline-offset: 2px; }
.state-demo--primary-disabled { background: var(--red-disabled); color: var(--white); }
.state-demo--secondary { border: 2px solid var(--asphalt); color: var(--asphalt); padding: 12px 22px; }
.state-demo--secondary-hover { border: 2px solid var(--asphalt); background: var(--asphalt); color: var(--white); padding: 12px 22px; }
.state-demo--secondary-focus { border: 2px solid var(--asphalt); color: var(--asphalt); padding: 12px 22px; outline: 2px solid var(--red); outline-offset: 2px; }
.state-demo--secondary-disabled { border: 2px solid var(--rule); color: var(--rule); padding: 12px 22px; }
.state-demo--tlink { border-bottom: 2px solid var(--red); padding: 0 0 2px; }
.state-demo--tlink-hover { color: var(--red); border-bottom: 2px solid var(--red); padding: 0 0 2px; }
.state-demo--tlink-focus { border-bottom: 2px solid var(--red); padding: 0 0 2px; outline: 2px solid var(--asphalt); outline-offset: 3px; }
.state-demo--tlink-disabled { color: var(--rule); border-bottom: 2px solid var(--divider); padding: 0 0 2px; }

.navdemo {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  border: 1px solid var(--rule);
  background: var(--white);
  padding: 8px;
  font-family: var(--display);
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.navdemo span { padding: 10px 12px; }
.navdemo .is-hover { color: var(--red); }
.navdemo .is-current { border-bottom: 2px solid var(--red); }

.voice { display: flex; flex-direction: column; }
.voice__row { padding: 13px 0; border-bottom: 1px solid var(--rule); font-size: 16px; }
.voice__row:last-child { border-bottom: none; }
.voice__row--never { color: var(--slate); }

/* --------------------------------------------------------------------------
   13. Responsive
   -------------------------------------------------------------------------- */

@media (min-width: 620px) {
  .cards         { grid-template-columns: repeat(2, 1fr); }
  .reviews-grid  { grid-template-columns: repeat(2, 1fr); }
  /* auto-fit, not repeat(3): the strip had three tiles and now has two, and a
     fixed count leaves an empty cell showing the grid's --rule background. */
  .facts         { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
  .form          { grid-template-columns: 1fr 1fr; }
  .footer__grid  { grid-template-columns: 1fr 1fr; }
  .swatches      { grid-template-columns: repeat(3, 1fr); }
  .states        { grid-template-columns: repeat(5, 1fr); }
  .spec-row      { grid-template-columns: 200px 1fr; gap: var(--s24); align-items: baseline; }
}

@media (min-width: 900px) {
  .hero          { grid-template-columns: 1.02fr 0.98fr; }
  .hero__copy    { padding: var(--s64) var(--gutter) var(--s56); border-right: 1px solid var(--rule); }
  .hero__media   { min-height: 460px; }
  .split         { grid-template-columns: 1fr 1fr; }
  .split--wide-left  { grid-template-columns: 1.05fr 0.95fr; }
  .split--wide-right { grid-template-columns: 0.85fr 1.15fr; }
  .split--photo-left { grid-template-columns: 0.9fr 1.1fr; }
  /* Mirror of --photo-left. The photo stays first in the markup so every
     profile stacks photo-then-text on a phone; order swaps it only here. */
  .split--photo-right { grid-template-columns: 1.1fr 0.9fr; }
  .split--photo-right > .media-fill   { order: 2; }
  .split--photo-right > .split__panel { order: 1; }
  /* A driver profile is short next to a 480px photo. Centre the copy against
     it; the panel still stretches, so its hairline runs the full height. */
  .split--photo-left  > .split__panel,
  .split--photo-right > .split__panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .cols          { grid-template-columns: 1fr 1fr; gap: var(--s56); }
  .stats         { grid-template-columns: repeat(4, 1fr); }
  .cards         { grid-template-columns: repeat(4, 1fr); }
  .reviews-grid  { grid-template-columns: repeat(3, 1fr); }
  .footer__grid  { grid-template-columns: 1.3fr 1fr 1fr 1.2fr; gap: var(--s40); }
  .swatches      { grid-template-columns: repeat(6, 1fr); }
  .media-fill    { min-height: 420px; }
  .image-band    { min-height: 400px; }

  /* Panel that sits beside a filled image inside a split */
  .split__panel        { padding: var(--s48) var(--gutter); border-left: 1px solid var(--rule); }
  .split__panel--left  { border-left: none; border-right: 1px solid var(--rule); }
}

/* Sections whose inner padding differs from the 56px default */
@media (max-width: 899px) {
  /* The wraps holding a split zero their own gutters so the photo can bleed to
     the screen edge, so the panel has to supply the gutter itself. Without it
     the copy runs edge to edge on a phone while the rest of the page is
     inset. */
  .split__panel { padding: var(--s40) var(--gutter); }
  .cta__inner { align-items: flex-start; }
}

/* Two-up card grid (the fleet on About). Declared after the wider breakpoints
   so it wins over the four-column default at equal specificity. */
.cards--two { grid-template-columns: 1fr; }
@media (min-width: 620px) {
  .cards--two { grid-template-columns: repeat(2, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
