/* ==========================================================================
   Legacy Aviation Group — components & layout
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--white);
  color: var(--black);
  font-family: var(--font-body);
  font-size: var(--text-rg);
  font-weight: var(--w-light);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

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

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }

h1, h2, h3, h4, h5, h6 { margin: 0; font-family: var(--font-heading); font-weight: var(--w-display); }

/* The UA stylesheet gives blockquote a 40px side margin, which knocks the pull
   quote out of alignment with everything above it. */
blockquote, figure, dl, dd { margin: 0; }

::selection { background: var(--brand-light); color: var(--white); }

:focus-visible {
  outline: 1px solid var(--brand-light);
  outline-offset: 4px;
}

/* --- Layout -------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow { max-width: var(--container-narrow); }

.section { position: relative; }
.section--lg { padding-block: var(--section-lg); }
.section--md { padding-block: var(--section-md); }
.section--sm { padding-block: var(--section-sm); }

.section--dark { background: var(--neutral-dark); color: var(--white); }
.section--bone { background: var(--neutral-lightest); }
.section--brand { background: var(--brand-dark); color: var(--white); }

/* --- Type ---------------------------------------------------------------- */
.h1, .h2, .h3, .h4, .h5 {
  font-family: var(--font-heading);
  font-weight: var(--w-display);
}

.h1 {
  font-size: var(--h1);
  line-height: var(--leading-display);
  letter-spacing: var(--track-display);
}

.h2 {
  font-size: var(--h2);
  line-height: var(--leading-heading);
  letter-spacing: var(--track-h2);
}

.h3 {
  font-size: var(--h3);
  line-height: 1.18;
  letter-spacing: var(--track-h2);
}

.h4 {
  font-size: var(--h4);
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.h5 {
  font-size: var(--h5);
  font-weight: var(--w-light);
  line-height: 1.35;
  letter-spacing: -0.012em;
}

/* LUX — the italic serif accent. On the live site it only appears on aircraft
   names; here it also carries one word per headline, which is the single
   biggest lift in perceived luxury and stays inside the brand's own type. */
.accent {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 300;
  letter-spacing: -0.01em;
}

.accent--brand { color: var(--brand-light); }

.eyebrow {
  font-size: var(--text-rg);
  font-weight: var(--w-regular);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--dark-70);
}

.eyebrow--light { color: var(--white-50); }
/* --brand-light on white measures 3.08:1 at this size — below the 4.5:1
   floor for text this small. --brand-medium clears 5.8:1 and reads as the
   same brand blue, just deep enough to stay legible. */
.eyebrow--brand { color: var(--brand-medium); }
.eyebrow--sm { font-size: var(--text-sm); }

.lead {
  font-size: var(--text-lg);
  font-weight: var(--w-light);
  line-height: 1.45;
}

.body-md { font-size: var(--text-md); font-weight: var(--w-light); }
.text-white { color: var(--white); }
.text-muted { color: var(--dark-70); }
.text-muted-light { color: var(--white-70); }
.max-w-lead { max-width: 44rem; }
.max-w-xl { max-width: 60rem; }
.center { text-align: center; margin-inline: auto; }

/* --- Rules --------------------------------------------------------------- */
/* LUX — hairline dividers instead of hard borders. */
.rule {
  height: var(--hairline);
  background: var(--dark-10);
  border: 0;
  margin: 0;
}

.rule--light { background: var(--white-10); }

/* --- Buttons ------------------------------------------------------------- */
.btn {
  --btn-fill: var(--brand-light);
  --btn-ink: var(--white);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: 1rem 2.25rem;
  border: var(--hairline) solid var(--btn-fill);
  border-radius: var(--radius-pill);
  background: var(--btn-fill);
  color: var(--btn-ink);
  font-size: var(--text-md);
  font-weight: var(--w-light);
  line-height: 1.2;
  text-align: center;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--dur-md) var(--ease-lux),
              border-color var(--dur-md) var(--ease-lux);
}

/* LUX — a fill that sweeps up from the baseline, replacing the live site's
   transform: scale(1.05) hover. Scaling reads cheap; a wipe reads tailored. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--brand-medium);
  transform: translateY(101%);
  transition: transform var(--dur-md) var(--ease-lux);
}

.btn:hover::after,
.btn:focus-visible::after { transform: translateY(0); }
.btn:hover { border-color: var(--brand-medium); }

.btn--secondary {
  --btn-fill: transparent;
  --btn-ink: var(--black);
  border-color: var(--dark-30);
}

.btn--secondary:hover { --btn-ink: var(--white); border-color: var(--brand-medium); }

.btn--alt {
  --btn-fill: transparent;
  --btn-ink: var(--white);
  border-color: var(--white-40);
}

.btn--alt:hover { border-color: var(--white); }
.btn--alt::after { background: var(--white); }
.btn--alt:hover { --btn-ink: var(--black); }

.btn--sm { padding: 0.75rem 1.625rem; font-size: var(--text-rg); }

.btn-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-lg) var(--space-2xl);
}

.btn-group--center { justify-content: center; }

/* Text link with a rule that draws in on hover. */
.link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding-block: var(--space-3xs);
  font-size: var(--text-rg);
  letter-spacing: 0.02em;
}

.link::after {
  content: "";
  width: 0;
  height: var(--hairline);
  background: currentColor;
  transition: width var(--dur-md) var(--ease-lux);
}

.link:hover::after { width: 1.5rem; }

.link-arrow {
  display: inline-block;
  transition: transform var(--dur-md) var(--ease-lux);
}

.link:hover .link-arrow,
.list-link:hover .link-arrow { transform: translateX(0.375rem); }

/* NAV COLLAPSE POINT — 1150px, not 991px.
   Six links plus a button and a phone number do not fit comfortably below this:
   at 1024px only 16px separated "Client Experience" from the logo. Everything
   tied to the desktop bar collapsing has to move together — the menu, the
   toggle, the drawer, the mega panels and the mobile action bar — or the site
   ends up in a state with no navigation at all. */

/* --- Nav ----------------------------------------------------------------- */
.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: var(--z-nav);
  min-height: var(--nav-h);
  display: flex;
  align-items: center;
  background: var(--neutral-dark);
  color: var(--white);
  /* LUX — the bar is transparent over the hero and only solidifies on scroll,
     so the first impression is the film, not a chrome band. */
  background: transparent;
  transition: background var(--dur-md) var(--ease-lux),
              min-height var(--dur-md) var(--ease-lux),
              backdrop-filter var(--dur-md) var(--ease-lux);
}

.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgb(0 0 0 / 0.55), transparent);
  opacity: 1;
  transition: opacity var(--dur-md) var(--ease-lux);
  pointer-events: none;
}

.nav.is-solid {
  background: rgb(61 60 68 / 0.92);
  backdrop-filter: blur(14px) saturate(140%);
  min-height: 4.75rem;
}

.nav.is-solid::before { opacity: 0; }

/* With the drawer open the bar has to seat against it, or the hero film shows
   through the gap between the two. No backdrop-filter here — that property
   (like filter/transform/contain) makes its element a containing block for
   fixed-position descendants, and .nav__drawer is fixed + inset:0 expecting
   the viewport as that block. With it here, `bottom:0` resolved against the
   bar's own ~76px box instead, collapsing the drawer to the bar's height. */
.nav.is-open {
  background: rgb(61 60 68 / 0.98);
}

.nav.is-open::before { opacity: 0; }

.nav__inner {
  position: relative;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  /* Hamburger-only at every breakpoint — no left/right link menus. The two
     outer tracks stay equal-width so the logo centres on the bar regardless
     of how wide the toggle or the phone/CTA group happens to be. */
  grid-template-columns: 1fr max-content 1fr;
  align-items: center;
  gap: var(--space-sm);
}

.nav__toggle { justify-self: start; }

.nav__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-md);
  justify-self: end;
}

.nav__logo img { height: 3rem; width: auto; }

.nav__toggle {
  display: grid;
  width: 2.5rem;
  height: 2.5rem;
  place-items: center;
}

.nav__toggle span,
.nav__toggle span::before,
.nav__toggle span::after {
  display: block;
  width: 1.375rem;
  height: 1px;
  background: var(--white);
  transition: transform var(--dur-md) var(--ease-lux),
              opacity var(--dur-fast) linear;
}

.nav__toggle span { position: relative; }
.nav__toggle span::before,
.nav__toggle span::after { content: ""; position: absolute; left: 0; }
.nav__toggle span::before { top: -6px; }
.nav__toggle span::after { top: 6px; }

.nav.is-open .nav__toggle span { background: transparent; }
.nav.is-open .nav__toggle span::before { transform: translateY(6px) rotate(45deg); }
.nav.is-open .nav__toggle span::after { transform: translateY(-6px) rotate(-45deg); }

/* --- Hero ---------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  background: var(--neutral-dark);
  color: var(--white);
  overflow: hidden;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__media video,
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* LUX — a very slow push-in. Motionless footage reads like a screenshot. */
  animation: kenburns 32s var(--ease-inout) infinite alternate;
}

@keyframes kenburns {
  from { transform: scale(1.02); }
  to { transform: scale(1.12); }
}

/* LUX — cinematic grade over the footage. The hero film cuts between dark
   hangar frames and bright cabin frames, so the scrim has to hold contrast for
   ultralight white type on the worst frame, not the average one: a flat base
   darkening, a heavy left column where the copy sits, and a bottom lift. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to right, rgb(0 0 0 / 0.85) 0%, rgb(0 0 0 / 0.6) 38%, rgb(0 0 0 / 0.15) 72%, transparent 100%),
    linear-gradient(to top, rgb(0 0 0 / 0.65) 0%, transparent 60%),
    rgb(0 0 0 / 0.28);
}

.hero__vignette {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: radial-gradient(120% 90% at 50% 45%, transparent 45%, rgb(0 0 0 / 0.45) 100%);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 3;
  width: 100%;
  padding-block: calc(var(--nav-h) + var(--space-2xl)) var(--section-md);
}

.hero__content {
  max-width: 60rem;
  transition: opacity var(--dur-md) var(--ease-lux);
}

/* The drawer sits over the hero's left edge — same side the headline reads
   from. Rather than shifting or resizing the headline to dodge it (both
   read as the page reacting oddly to a menu opening), the headline itself
   recedes, so there is nothing left half-covered to look like a mistake. */
body.nav-open .hero__content { opacity: 0.12; }

@media (prefers-reduced-motion: reduce) {
  .hero__content { transition: none; }
}

/* Wherever the caption rail is present, the headline has to stop short of it.
   A breakpoint cannot do this reliably — the headline rewraps at every width, so
   it cleared the caption at 1440 and collided again at 1200. Reserving the rail's
   width is viewport-independent: the headline simply never reaches it. */
@media (min-width: 1151px) {
  .hero__content { max-width: min(60rem, calc(100% - 18rem)); }
}

.hero .h1 { margin-bottom: var(--space-xl); }

.hero__lead {
  max-width: 34rem;
  margin-bottom: var(--space-2xl);
  color: var(--white-70);
}

/* Vertical slide indicators pinned to the right edge, as on the live site. */
.hero__dots {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.hero__dot {
  width: 1px;
  height: 2.5rem;
  background: var(--white-30);
  transition: background var(--dur-md) var(--ease-lux),
              height var(--dur-md) var(--ease-lux);
}

.hero__dot.is-active { background: var(--brand-light); height: 4rem; }

/* LUX — a hairline scroll cue anchored to the baseline of the hero. */
.hero__cue {
  position: absolute;
  bottom: var(--space-xl);
  left: 50%;
  z-index: 4;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--white-50);
}

.hero__cue-line {
  width: 1px;
  height: 3.5rem;
  background: linear-gradient(to bottom, var(--white-40), transparent);
}

.hero__cue-line::after {
  content: "";
  display: block;
  width: 1px;
  height: 1rem;
  background: var(--white);
  animation: cue 2.8s var(--ease-inout) infinite;
}

@keyframes cue {
  0%   { transform: translateY(-1rem); opacity: 0; }
  40%  { opacity: 1; }
  100% { transform: translateY(3.5rem); opacity: 0; }
}

/* --- Logo strip ---------------------------------------------------------- */
.logo-strip { text-align: center; }
.logo-strip .eyebrow { margin-bottom: var(--space-xl); }

/* --- Logo marquee ------------------------------------------------------- */
/* The press and partner marks used to sit in a static centred grid. They now
   drift continuously, which reads current and lets the eight press marks share
   one line instead of wrapping to two. */
.marquee {
  overflow: hidden;
  /* Fade both ends so marks enter and leave rather than being chopped off. */
  mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}

.logo-strip__row {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-2xl) var(--space-3xl);
  width: max-content;
  /* Shift by exactly one copy of the set, so the wrap is seamless. Duration is
     set per strip so every marquee drifts at an identical speed regardless of
     how many marks it holds. */
  animation: marquee var(--marquee-dur, 80s) linear infinite;
}

@keyframes marquee {
  to { transform: translateX(calc(-100% / var(--copies))); }
}

/* Hold still so a mark can be read, and never run it for anyone who asked for
   less motion — there it falls back to the original centred, wrapping row. */
.marquee:hover .logo-strip__row { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .marquee { mask-image: none; -webkit-mask-image: none; }
  .logo-strip__row {
    animation: none;
    flex-wrap: wrap;
    justify-content: center;
    width: auto;
    padding-inline: var(--gutter);
  }
  /* The duplicate copies are decoration; without motion they are just repeats. */
  .logo-strip__row img[aria-hidden="true"] { display: none; }
}

/* The four partner marks range from 1:1 to 6.6:1, so a fixed height makes the
   wide ones dwarf the square ones. Constrain both axes and let each mark find
   its own size inside a shared optical box. */
.logo-strip__row img {
  width: auto;
  height: auto;
  max-height: 3rem;
  max-width: 8.5rem;
  object-fit: contain;
  /* LUX — desaturated at rest, colour on hover: the editorial convention for
     a press / partner row. */
  filter: grayscale(1);
  opacity: 0.55;
  transition: opacity var(--dur-md) var(--ease-lux),
              filter var(--dur-md) var(--ease-lux);
}

.logo-strip__row img:hover { opacity: 1; filter: grayscale(0); }

/* --- Split content (The Legacy Aviation Difference) --------------------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: var(--space-4xl);
}

.split__copy > * + * { margin-top: var(--space-md); }
.split__copy .eyebrow + .h2 { margin-top: var(--space-md); }
.split__copy .btn-group { margin-top: var(--space-xl); }

/* Two overlapping frames, matching the live site's staggered photo pair. */
.frames {
  position: relative;
  padding-bottom: 22%;
  padding-right: 12%;
}

.frames__lg {
  position: relative;
  z-index: 1;
  width: 88%;
  aspect-ratio: 627 / 485;
  object-fit: cover;
}

.frames__sm {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  width: 52%;
  aspect-ratio: 1;
  object-fit: cover;
  /* LUX — a hairline mat around the overlapping frame so the two photos read
     as deliberately layered rather than accidentally colliding. */
  border: 8px solid var(--white);
}

.section--bone .frames__sm { border-color: var(--neutral-lightest); }

/* --- Journey tiles ------------------------------------------------------- */
.journey__head {
  max-width: 52rem;
  margin-bottom: var(--section-sm);
}

.journey__head .h2 { margin-bottom: var(--space-md); }

.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2xs);
}

.tile {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 420px;
  padding: var(--space-xl);
  background: var(--neutral-dark);
  color: var(--white);
  overflow: hidden;
}

.tile__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.4;
  transition: opacity var(--dur-slow) var(--ease-lux),
              transform var(--dur-slow) var(--ease-lux);
}

.tile:hover .tile__img { opacity: 0.55; transform: scale(1.06); }

/* LUX — a bottom-weighted scrim under the label. The culinary and golf frames
   are bright enough to swallow white type on their own. */
.tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgb(0 0 0 / 0.75) 0%, rgb(0 0 0 / 0.25) 42%, transparent 70%);
  pointer-events: none;
}

.tile__body {
  position: relative;
  z-index: 2;
  width: 100%;
}

.tile__title { margin-bottom: var(--space-sm); }

/* LUX — the label sits low and a hairline + link reveal on hover, so the
   tile has a resting state and an invited state. */
.tile__reveal {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  font-size: var(--text-sm);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--white-70);
  opacity: 0;
  transform: translateY(0.5rem);
  transition: opacity var(--dur-md) var(--ease-lux),
              transform var(--dur-md) var(--ease-lux);
}

.tile:hover .tile__reveal,
.tile:focus-visible .tile__reveal { opacity: 1; transform: translateY(0); }

/* --- Programs ------------------------------------------------------------ */
.programs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: var(--space-4xl);
}

.programs__copy .eyebrow { margin-bottom: var(--space-md); }
.programs__copy .h2 { margin-bottom: var(--space-md); }
.programs__copy .lead { margin-bottom: var(--space-xl); }

.program-list { border-top: var(--hairline) solid var(--white-10); }

.list-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block: var(--space-md);
  border-bottom: var(--hairline) solid var(--white-10);
  font-size: var(--text-md);
  font-weight: var(--w-light);
  transition: padding-left var(--dur-md) var(--ease-lux),
              color var(--dur-md) var(--ease-lux);
}

.list-link:hover { padding-left: var(--space-sm); color: var(--brand-light); }

.programs__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* --- Aircraft slider ---------------------------------------------------- */
.fleet__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-lg);
  margin-bottom: var(--section-sm);
}

.fleet__head .eyebrow { margin-bottom: var(--space-md); }

.fleet {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--space-4xl);
}

.fleet__stage {
  position: relative;
  min-height: 22rem;
  display: grid;
  place-items: center;
}

.fleet__slide {
  grid-area: 1 / 1;
  width: 100%;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transform: translateX(3rem);
  transition: opacity var(--dur-slow) var(--ease-lux),
              transform var(--dur-slow) var(--ease-lux),
              visibility var(--dur-slow) step-end;
}

.fleet__slide.is-active {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
  transition: opacity var(--dur-slow) var(--ease-lux),
              transform var(--dur-slow) var(--ease-lux),
              visibility 0s step-start;
}

.fleet__slide img {
  width: 100%;
  max-width: 42rem;
  margin-inline: auto;
  /* LUX — the cutouts are on transparent ground; a soft contact shadow keeps
     them from looking pasted onto the page. */
  filter: drop-shadow(0 24px 40px rgb(0 0 0 / 0.16));
}

.fleet__cat { margin-bottom: var(--space-2xs); }

.fleet__name {
  font-size: var(--accent-size);
  line-height: 1.1;
  margin-bottom: var(--space-lg);
}

/* Round outline arrows, 5.25rem, as on the live build. The pair is split to the
   top and bottom of the stage so it frames the aircraft rather than landing on
   top of the tail. */
.fleet__nav {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  pointer-events: none;
}

.fleet__nav .fleet__arrow { pointer-events: auto; }

.fleet__arrow {
  display: grid;
  place-items: center;
  width: 5.25rem;
  height: 5.25rem;
  border: var(--hairline) solid var(--dark-30);
  border-radius: 50%;
  background: var(--white-70);
  backdrop-filter: blur(6px);
  color: var(--black);
  transition: background var(--dur-md) var(--ease-lux),
              border-color var(--dur-md) var(--ease-lux),
              color var(--dur-md) var(--ease-lux);
}

/* LUX — hover shifts the arrow to brand fill rather than scaling it. */
.fleet__arrow:hover {
  background: var(--brand-light);
  border-color: var(--brand-light);
  color: var(--white);
}

.fleet__arrow svg { width: 1.25rem; height: 1.25rem; }

.specs { border-top: var(--hairline) solid var(--dark-15); }

.spec {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block: var(--space-md);
  border-bottom: var(--hairline) solid var(--dark-15);
}

.spec__label {
  font-size: var(--text-sm);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--dark-70);
}

.spec__value {
  font-size: var(--text-md);
  font-weight: var(--w-light);
  text-align: right;
  /* LUX — tabular figures so the numbers hold a column as slides change. */
  font-variant-numeric: tabular-nums;
}

.specs__cta { margin-top: var(--space-xl); }

.fleet__counter {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-lg);
  font-size: var(--text-sm);
  letter-spacing: var(--track-eyebrow);
  color: var(--dark-70);
  font-variant-numeric: tabular-nums;
}

.fleet__counter-rule {
  flex: 1;
  height: var(--hairline);
  background: var(--dark-15);
  position: relative;
  overflow: hidden;
}

.fleet__counter-rule::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--progress, 20%);
  background: var(--brand-light);
  transition: width var(--dur-slow) var(--ease-lux);
}

/* --- Testimonial -------------------------------------------------------- */
.quote { max-width: 62rem; }

/* Ethic New draws its quote glyph small inside the em box, so the mark is
   oversized and its line box collapsed to sit tight above the quote. */
.quote__mark {
  font-family: var(--font-accent);
  font-style: italic;
  font-size: 11rem;
  line-height: 0.42;
  height: 2.5rem;
  color: var(--brand-light);
  margin: 0 0 var(--space-sm);
}

.quote__text { margin-bottom: var(--space-xl); font-weight: var(--w-display); }

.quote__author {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.quote__avatar {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  border: var(--hairline) solid var(--dark-30);
  border-radius: 50%;
  font-size: var(--text-sm);
  letter-spacing: 0.08em;
  color: var(--dark-70);
}

.quote__name { font-weight: var(--w-medium); }
.quote__role { font-size: var(--text-sm); color: var(--dark-70); }

/* --- CTA ---------------------------------------------------------------- */
.cta {
  position: relative;
  overflow: hidden;
  text-align: center;
}

/* A screen blend at 0.25 lifted the whole panel off #00445a into a flat mid
   teal. Keep the cloud motion as a faint light source only, then re-seat the
   depth with a vignette so the panel reads deep rather than washed. */
.cta__clouds {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.14;
  mix-blend-mode: screen;
}

.cta::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 100% at 50% 40%, transparent 30%, rgb(0 24 34 / 0.55) 100%);
  pointer-events: none;
}

.cta__inner { position: relative; z-index: 1; }
.cta .h2 { margin-bottom: var(--space-md); }
.cta .lead { margin-bottom: var(--space-xl); }

/* --- FAQ ---------------------------------------------------------------- */
.faq {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: var(--space-4xl);
  align-items: start;
}

.faq__head .h2 { margin-bottom: var(--space-md); }

.faq__list { border-top: var(--hairline) solid var(--dark-15); }

.faq__item { border-bottom: var(--hairline) solid var(--dark-15); }

.faq__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  padding-block: var(--space-lg);
  text-align: left;
  transition: color var(--dur-md) var(--ease-lux);
}

.faq__trigger:hover { color: var(--brand-medium); }

/* LUX — a thin plus that rotates to a minus; no chunky chevron. */
.faq__icon {
  position: relative;
  flex: none;
  width: 1rem;
  height: 1rem;
}

.faq__icon::before,
.faq__icon::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto;
  height: 1px;
  background: currentColor;
  transition: transform var(--dur-md) var(--ease-lux),
              opacity var(--dur-md) var(--ease-lux);
}

.faq__icon::after { transform: rotate(90deg); }

.faq__item.is-open .faq__icon::after { transform: rotate(0deg); opacity: 0; }

.faq__panel {
  overflow: hidden;
  height: 0;
  transition: height var(--dur-md) var(--ease-lux);
}

.faq__panel-inner {
  padding-bottom: var(--space-lg);
  padding-right: var(--space-2xl);
  color: var(--dark-70);
  opacity: 0;
  transform: translateY(-0.5rem);
  transition: opacity var(--dur-md) var(--ease-lux),
              transform var(--dur-md) var(--ease-lux);
}

.faq__item.is-open .faq__panel-inner { opacity: 1; transform: translateY(0); }

.faq__still { margin-top: var(--section-sm); }
.faq__still .h3 { margin-bottom: var(--space-2xs); }
.faq__still .lead { margin-bottom: var(--space-md); }

/* --- Footer ------------------------------------------------------------- */
.footer {
  background: var(--neutral-dark);
  color: var(--white);
  padding-block: var(--section-md) var(--space-lg);
}

.footer__newsletter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-lg);
  padding-bottom: var(--section-sm);
  margin-bottom: var(--section-sm);
  border-bottom: var(--hairline) solid var(--white-10);
}

.footer__newsletter .h4 { margin-bottom: var(--space-2xs); }
.footer__newsletter p { margin: 0; font-size: var(--text-sm); color: var(--white-50); max-width: 30rem; }

.subscribe {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-width: min(100%, 28rem);
}

.subscribe input {
  flex: 1;
  height: 3rem;
  padding-inline: var(--space-md);
  background: transparent;
  border: var(--hairline) solid var(--white-30);
  border-radius: var(--radius-pill);
  color: var(--white);
  font: inherit;
  transition: border-color var(--dur-md) var(--ease-lux);
}

.subscribe input::placeholder { color: var(--white-40); }
.subscribe input:focus { outline: none; border-color: var(--brand-light); }

.footer__cols {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-lg);
  align-items: start;
  padding-bottom: var(--section-sm);
}

.footer__col-title {
  display: block;
  margin-bottom: var(--space-md);
  font-size: var(--text-sm);
  font-weight: var(--w-regular);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  /* --brand-light on the footer's --neutral-dark only measures 3.54:1 — below
     WCAG AA's 4.5:1 floor for text this size. This tint (30% white mixed in)
     clears 4.9:1 while still reading as the brand blue. */
  color: #4cbbe0;
  transition: padding-left var(--dur-md) var(--ease-lux);
}

.footer__col-title:hover { padding-left: var(--space-2xs); }

.footer__link {
  display: block;
  padding-block: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--white-70);
  transition: color var(--dur-md) var(--ease-lux),
              padding-left var(--dur-md) var(--ease-lux);
}

.footer__link:hover { color: var(--white); padding-left: var(--space-2xs); }

.footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-md);
  padding-top: var(--space-lg);
  border-top: var(--hairline) solid var(--white-10);
}

.footer__credit { font-size: var(--text-sm); color: var(--white-50); }

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.footer__legal a { font-size: var(--text-sm); color: var(--white-70); }
.footer__legal a:hover { color: var(--white); }

.footer__logo img { height: 2.5rem; width: auto; }

/* --- Scroll reveal ------------------------------------------------------ */
/* LUX — content rises into place on a long curve. Headlines reveal line by
   line via [data-reveal="lines"], which JS splits and staggers.
   Every rule here is scoped to `.js`, which main.js adds to <html> and removes
   again if it throws. Without working JS nothing is ever hidden, so the page
   can never render blank. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity var(--dur-reveal) var(--ease-lux),
              transform var(--dur-reveal) var(--ease-lux);
}

.js [data-reveal].is-in { opacity: 1; transform: none; }

.reveal-line { display: block; overflow: hidden; }

.js .reveal-line > span {
  display: block;
  transform: translateY(110%);
  transition: transform var(--dur-reveal) var(--ease-lux);
}

.js [data-reveal="lines"] { opacity: 1; transform: none; }
.js [data-reveal="lines"].is-in .reveal-line > span { transform: translateY(0); }

/* --- Nav drawer ----------------------------------------------------------
   The single primary-nav surface at every breakpoint — there is no separate
   desktop menu to fall back to above 1150px anymore. Full viewport height
   (not just below the bar), the flat item list pinned to the top under the
   bar, and a glassy blur instead of a near-opaque card. */
.nav__drawer {
  position: fixed;
  /* All four sides pinned — `bottom: auto` here would shrink-wrap the panel
     to its content height instead of spanning the viewport, leaving the
     bottom of the screen uncovered. */
  inset: 0;
  /* Below the bar's z-index (900) so its own controls stay on top and
     clickable once the panel is open. */
  z-index: 800;
  display: grid;
  align-content: center;
  text-align: right;
  /* Headroom for a tall flyout on a short viewport, or Contact Us running
     off-screen with no way to reach it. */
  overflow-y: auto;
  /* Full-bleed below 640px — near-opaque, or the hero's own headline shows
     straight through the empty left two-thirds of the panel and collides
     with the menu text sitting on top of it. */
  background: rgb(61 60 68 / 0.94);
  backdrop-filter: blur(16px) saturate(140%);
  padding: var(--nav-h) var(--gutter) var(--space-2xl);
  gap: var(--space-2xs);
  /* A slide, not a clip-path reveal — clip-path animates the mask but the
     content underneath sits still, which read as flatter and gave the
     stagger nothing to play against. Translating the whole panel gives the
     motion an actual direction, and transform is compositor-only work, so
     it stays smooth regardless of what else is going on in the page. */
  transform: translateX(-100%);
  transition: transform var(--dur-slide) var(--ease-slide),
              background var(--dur-md) var(--ease-lux);
}

.nav__drawer.is-open { transform: translateX(0); }

/* Top-level rows only — a plain link or a Programs/Fleet/Lifestyle group's
   row. Sub-items (further down) are excluded on purpose: they're hidden
   until their group expands, independent of the drawer's own open state. */
.nav__drawer > a,
.nav__drawer-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-sm);
  padding-block: var(--space-sm);
  border-bottom: var(--hairline) solid var(--white-10);
  font-size: var(--text-lg);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--white-70);
}

.nav__drawer-link { color: inherit; }

.nav__drawer > a,
.nav__drawer > .nav__drawer-group {
  opacity: 0;
  transform: translateX(0.75rem);
  transition: opacity var(--dur-md) var(--ease-lux),
              transform var(--dur-md) var(--ease-lux);
}

.nav__drawer.is-open > a,
.nav__drawer.is-open > .nav__drawer-group {
  opacity: 1;
  transform: none;
}

/* Staggered across the back half of the panel's own 820ms slide, so items
   are still settling in as the panel arrives rather than popping in early
   and sitting idle while the panel finishes. */
.nav__drawer > *:nth-child(1) { transition-delay: 220ms; }
.nav__drawer > *:nth-child(2) { transition-delay: 270ms; }
.nav__drawer > *:nth-child(3) { transition-delay: 320ms; }
.nav__drawer > *:nth-child(4) { transition-delay: 370ms; }
.nav__drawer > *:nth-child(5) { transition-delay: 420ms; }
.nav__drawer > *:nth-child(6) { transition-delay: 470ms; }
.nav__drawer > *:nth-child(7) { transition-delay: 520ms; }

/* --- Drawer sub-menus: Programs, Fleet, Lifestyle -------------------------
   Expand in place below the trigger row. The caret is a separate control
   from the label on purpose — the label still navigates straight to that
   section's landing page, so a plain click isn't hijacked into "expand" the
   way it would be if the whole row were one combined control. */
.nav__drawer-caret {
  display: inline-flex;
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
}

.nav__drawer-caret span {
  width: 0.5rem;
  height: 0.5rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  /* Matched to .nav__drawer-sub below. Slower still, and switched off
     ease-glide (a fast-out curve — most of its motion happens in the first
     third) to a true ease-in-out: a gradual start reads as deliberate,
     where a fast start reads as a snap no matter how long the tail is. */
  transition: transform 1400ms var(--ease-inout);
}

.nav__drawer-group.is-expanded .nav__drawer-caret span { transform: rotate(225deg); }

.nav__drawer-sub {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  text-align: right;
  transition: max-height 1400ms var(--ease-inout),
              opacity 1400ms var(--ease-inout);
}

.nav__drawer-group.is-expanded .nav__drawer-sub {
  /* Generous on purpose — Fleet has 7 categories, some (e.g. "Premium Long
     Range Heavy Jet") wrapping to two lines in the narrower panel, and
     20rem was clipping the bottom of that list with overflow:hidden. This
     needs to clear the tallest real group, not look proportional to it. */
  max-height: 32rem;
  opacity: 1;
}

.nav__drawer-sub a {
  display: block;
  padding-block: var(--space-xs);
  font-size: var(--text-sm);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--white-50);
  transition: color var(--dur-fast) var(--ease-lux);
}

.nav__drawer-sub a:hover { color: var(--white); }

/* Above 640px a single edge-to-edge column of links looks sparse rather than
   editorial, so the panel narrows to a fixed-width sidebar like Flexjet's
   rather than stretching the full viewport width. Right-aligned text against
   the panel's own right edge — that inner edge, not the screen edge — is
   Flexjet's actual layout, not an accident of a full-bleed drawer. */
@media (min-width: 640px) {
  .nav__drawer {
    /* "Client Experience" needs ~225px and was landing right on a subpixel
       rounding boundary against the available width at both 20rem and
       21rem — scrollWidth rounds up, getBoundingClientRect doesn't, and the
       two kept disagreeing by a fraction of a pixel right at the edge.
       22rem clears it with real margin instead of chasing that boundary. */
    width: min(22rem, 85vw);
    inset: 0 auto 0 0;
    /* Contained to a strip rather than spanning the screen, so it can afford
       to be genuinely glassy without the see-through gap reading as a bug.
       Fading to fully transparent over the last 10% — rather than ending in
       a hard vertical edge — means whatever hero text happens to sit behind
       that edge blends off instead of looking sliced. Masking the element
       (not just its background-color) fades the blur along with the tint,
       so the effect reads as depth, not a layered cutout. */
    background: rgb(61 60 68 / 0.82);
    backdrop-filter: blur(24px) saturate(140%);
    box-shadow: 30px 0 60px -20px rgb(0 0 0 / 0.35);
    -webkit-mask-image: linear-gradient(to right, black 0%, black 90%, transparent 100%);
            mask-image: linear-gradient(to right, black 0%, black 90%, transparent 100%);
    /* The fade zone above eats into the last ~10% of the panel — extra
       right padding keeps the right-aligned text's own edge clear of it, or
       the panel's real menu labels would fade out along with the hero text
       behind them. */
    padding-right: 3rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav__drawer > a,
  .nav__drawer > .nav__drawer-group {
    transition-delay: 0ms !important;
    transform: none;
  }
}

/* --- Responsive -------------------------------------------------------- */
@media (max-width: 1150px) {
  .split,
  .programs,
  .fleet,
  .faq { grid-template-columns: 1fr; gap: var(--space-2xl); }

  .fleet__head { flex-direction: column; align-items: flex-start; }
  .fleet__stage { min-height: 20rem; }

  .fleet__nav {
    position: static;
    transform: none;
    flex-direction: row;
    justify-content: center;
    margin-top: var(--space-md);
  }

  .fleet__arrow { width: 4rem; height: 4rem; }

  .tiles { grid-template-columns: 1fr; }
  .tile { min-height: 300px; }

  .footer__cols { grid-template-columns: repeat(2, 1fr); gap: var(--space-xl) var(--space-lg); }
}

@media (max-width: 767px) {
  .frames { padding-right: 0; padding-bottom: 28%; }
  .frames__lg { width: 82%; }
  .frames__sm { width: 58%; border-width: 6px; }

  .btn-group { gap: var(--space-sm); }
  .btn { width: 100%; }
  .hero__dots { display: none; }
  /* Full-width buttons reach the centre line, so the cue would draw straight
     through them. */
  .hero__cue { display: none; }
  .footer__cols { grid-template-columns: 1fr; }
  .quote__text { font-size: var(--h4); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .js [data-reveal] { opacity: 1; transform: none; }
  .js .reveal-line > span { transform: none; }
}

/* build.mjs wraps images in <picture> to serve AVIF. `display: contents` keeps
   the wrapper out of layout entirely, so the <img> stays the flex/grid item and
   every existing selector and layout rule continues to apply unchanged. */
picture { display: contents; }

/* The poster is a real <img> so it is a discoverable, high-priority preload
   target (a <video poster> is not). It cross-fades out once the film is playing. */
.hero__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  animation: kenburns 32s var(--ease-inout) infinite alternate;
}

.hero__media.is-playing .hero__poster {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-lux);
}

.hero__media video { position: relative; z-index: 1; }
.hero__media.is-playing video { z-index: 2; }

/* The hero finale swap (main.js) dips this to near-black and back around the
   `src` change, so the cut between the reel and the finale clip (and back)
   reads as a quick dip-to-dark rather than an abrupt jump. Driven as an
   inline style, same as the swap itself. */
.hero__media video[data-finale-src] { transition: filter var(--dur-fast) var(--ease-lux); }

@media (prefers-reduced-motion: reduce) {
  .hero__media video[data-finale-src] { transition: none; }
}

/* ========================================================================== */
/* Polish pass                                                                */
/* Site-wide interaction consistency. The individual components already had    */
/* their own hovers; what was missing was a shared vocabulary — everything     */
/* liftable lifts by the same amount, on the same curve, and every focus ring  */
/* looks the same. That evenness is most of what reads as "finished".          */
/* ========================================================================== */

/* A 1px ring is easy to miss against photography; 2px stays visible on both the
   bone and dark sections. No border-radius here — this rule has the same
   specificity as .btn and would square off every pill button on focus. Outlines
   follow the element's own radius anyway. */
:focus-visible {
  outline: 2px solid var(--brand-light);
  outline-offset: 3px;
}

/* Buttons gain a small physical lift. Paired with the existing fill sweep this
   is the difference between a button that changes colour and one that responds. */
.btn {
  transition: color var(--dur-md) var(--ease-lux),
              border-color var(--dur-md) var(--ease-lux),
              transform var(--dur-fast) var(--ease-spring),
              box-shadow var(--dur-md) var(--ease-lux);
}

.btn:hover,
.btn:focus-visible { transform: translateY(-2px); }
.btn:active { transform: translateY(0); transition-duration: 80ms; }

/* Only the filled variant gets a shadow — a shadow under a transparent outline
   button reads as a rendering mistake. */
.btn:not(.btn--secondary):not(.btn--alt):hover { box-shadow: 0 10px 24px -8px rgb(0 158 210 / 0.5); }

/* The two cards that were missing the lift every other card has. */
.prog-card,
.article--link {
  transition: transform var(--dur-md) var(--ease-lux),
              border-color var(--dur-md) var(--ease-lux);
}

.prog-card:hover,
.article--link:hover { transform: translateY(-4px); }

/* --- Scroll progress ---------------------------------------------------- */
.nav__progress {
  position: absolute;
  inset: auto 0 0;
  height: 2px;
  opacity: 0;
  transition: opacity var(--dur-md) var(--ease-lux);
  pointer-events: none;
}

/* Hidden over the hero, where there is no bar for it to sit on. */
.nav.is-solid .nav__progress { opacity: 1; }

.nav__progress > span {
  display: block;
  height: 100%;
  width: 100%;
  background: linear-gradient(to right, var(--brand-medium), var(--brand-light));
  transform: scaleX(var(--p, 0));
  transform-origin: 0 50%;
  /* No transition: this tracks the scrollbar, and easing it would make it lag
     behind the content it is reporting on. */
}

@media (prefers-reduced-motion: reduce) {
  .btn:hover,
  .btn:focus-visible,
  .btn:active,
  .prog-card:hover,
  .article--link:hover { transform: none; }
}

/* --- Footer charter desk ------------------------------------------------- */
.footer__desk {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  padding-block: var(--space-xl);
  border-bottom: var(--hairline) solid var(--white-15);
}

.footer__desk .eyebrow { margin-bottom: var(--space-2xs); }

.footer__phone {
  display: inline-block;
  font-size: clamp(1.75rem, 3.4vw, 2.75rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--white);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-inout);
}

.footer__phone:hover { color: var(--brand-light); }

.footer__phone-alt {
  margin: var(--space-2xs) 0 0;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--white-50);
}

/* --- Hero slides -------------------------------------------------------- */
/* Photographs stack above the film (video sits at z-index 2 once playing) and
   cross-fade in. Only opacity animates, so switching slides costs nothing. */
.hero__alt {
  position: absolute;
  inset: 0;
  z-index: 3;
  opacity: 0;
  transition: opacity 1100ms var(--ease-lux);
  pointer-events: none;
}

.hero__alt.is-on { opacity: 1; }

/* Caption and indicators share the right-hand rail, vertically centred. The
   caption cannot live at the bottom of the hero: the quote bar floats ~96px up
   over it and swallowed it entirely. */
.hero__rail {
  position: absolute;
  top: 50%;
  right: var(--gutter);
  z-index: 4;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}

.hero__caps { display: grid; }

.hero__cap {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  gap: var(--space-3xs);
  opacity: 0;
  transform: translateY(0.5rem);
  transition: opacity var(--dur-md) var(--ease-lux), transform var(--dur-md) var(--ease-lux);
  pointer-events: none;
  text-decoration: none;
}

.hero__cap.is-on { opacity: 1; transform: none; pointer-events: auto; }

.hero__cap-name {
  font-size: var(--text-sm);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--white);
}

.hero__cap-cue {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--white-50);
  transition: color var(--dur-fast) var(--ease-inout);
}

.hero__cap:hover .hero__cap-cue { color: var(--brand-light); }
.hero__cap:hover .link-arrow { transform: translateX(0.35rem); }

/* The indicators are real buttons now. Padding gives a usable hit area around
   the 1px mark without changing how it looks. */
.hero__dots button.hero__dot {
  padding: 0;
  border: 0;
  cursor: pointer;
  background: var(--white-30);
}

.hero__dots button.hero__dot.is-active { background: var(--brand-light); }
.hero__dots button.hero__dot:hover { background: var(--white-70); }

/* The caption sits on the right rail, vertically centred — exactly where the
   headline is widest. Below 1150px the headline wraps far enough right to run
   into it (measured: caption at x738, headline glyphs to x983 at 1024px), so it
   is dropped for the whole tablet band. The indicators still work and the
   aircraft is one tap away. Same breakpoint as the nav collapse, deliberately. */
@media (max-width: 1150px) {
  .hero__caps { display: none; }
}

/* --- Credibility band --------------------------------------------------- */
.stats__row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-lg);
  margin: 0;
  padding-block: var(--space-md);
  border-top: var(--hairline) solid var(--dark-15);
  border-bottom: var(--hairline) solid var(--dark-15);
}

.stat { text-align: center; }

.stat__num {
  font-family: var(--font-heading);
  font-weight: var(--w-display);
  font-size: clamp(2rem, 3.4vw, 3rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--black);
  font-variant-numeric: tabular-nums;
}

.stat__label {
  margin: var(--space-2xs) 0 0;
  font-size: var(--text-sm);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--dark-70);
}

@media (max-width: 640px) {
  .stats__row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl) var(--space-lg); }
}

/* Caption is capped so it can never grow back into the headline. */
.hero__cap { max-width: 14rem; }

.hero__cap-class {
  font-size: var(--text-xs);
  line-height: 1.35;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--white-50);
}

.hero__cap-cue { margin-top: var(--space-2xs); }

/* --- Film grain ---------------------------------------------------------- */
/* A fine noise layer over the dark sections. Large flat fields of #3D3C44 look
   like a filled rectangle; a little grain reads as printed matter and stops the
   photography above and below from feeling pasted on. The texture is an inline
   SVG turbulence, so it costs no request. */
.section--dark::before,
.hero__vignette::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* The grain must sit under the content, not over it. */
.section--dark > * { position: relative; z-index: 1; }

/* Slightly stronger over the hero film, where the gradient is smoothest. */
.hero__vignette::after { opacity: 0.07; }


/* --- Marquee layout overrides ------------------------------------------- */
/* .logo-strip__row-partners sets display:grid for the static/reduced-motion
   fallback. Inside a moving marquee everything is one row regardless, so
   that grid is both unnecessary and wrong there. These selectors carry two
   classes so they win outright. */
.marquee .logo-strip__row {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-start;
  width: max-content;
  /* Was 0, relying entirely on each logo's own leftover space inside its
     fixed 11rem box (from object-fit:contain) for spacing. A wide lockup
     like NBC Sports fills that box edge to edge and reads as crowding its
     neighbor, while a square mark like ABC has room to spare either side —
     the row looked unevenly spaced because it effectively was. A real gap
     guarantees the same minimum distance between every pair regardless of
     each logo's own aspect ratio; it's a fixed value like the box widths
     themselves, so the seamless-loop math above is unaffected. */
  gap: 2.5rem;
}

/* Each mark gets a fixed optical box. Without it the track width depends on
   which logos have finished loading, and the animation shifts by a percentage
   OF that width — so a half-loaded strip would loop to the wrong place. */
.marquee .logo-strip__row img {
  flex: 0 0 auto;
  width: 11rem;
  height: 2.25rem;
  max-width: none;
  max-height: none;
  object-fit: contain;
}

/* --- Header phone -------------------------------------------------------- */
.nav__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-size: var(--text-sm);
  letter-spacing: 0.06em;
  color: var(--white-70);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-inout);
}

.nav__phone:hover { color: var(--white); }

/* Handset drawn in CSS — one more request for a 12px glyph is not worth it. */
.nav__phone-icon {
  width: 0.5rem;
  height: 0.5rem;
  border: 1.5px solid currentColor;
  border-radius: 2px 2px 6px 2px;
  border-top-color: transparent;
  border-right-color: transparent;
  transform: rotate(-45deg);
}

/* With no left/right link menu left to crowd it, the phone number now only
   needs to give way once the hamburger + logo + phone + button genuinely
   can't fit — the mobile action bar carries the same two CTAs below this
   width anyway. */
@media (max-width: 480px) {
  .nav__phone { display: none; }
}

/* The button goes next — at 375px, logo + "Contact Us" alone already ran the
   bar past the viewport edge. Below 640px the sticky action bar (Call the
   desk / Request a Quote) is the CTA; the top bar only needs the hamburger
   and logo. */
@media (max-width: 640px) {
  .nav__actions .btn { display: none; }
}

/* --- Mobile action bar --------------------------------------------------- */
.actionbar { display: none; }

@media (max-width: 1150px) {
  .actionbar {
    position: fixed;
    inset: auto 0 0;
    z-index: var(--z-nav);
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: stretch;
    gap: var(--hairline);
    background: var(--neutral-dark);
    /* Clears the iOS home indicator. */
    padding-bottom: env(safe-area-inset-bottom, 0);
    transform: translateY(100%);
    transition: transform var(--dur-md) var(--ease-lux);
  }

  /* Held back until the hero is behind you — it should not cover the first
     impression, only follow it. */
  .actionbar.is-up { transform: translateY(0); }

  .actionbar__call,
  .actionbar__quote {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    /* Tight enough that both labels hold one line at 375px — "Request a Quote"
       was wrapping and making the bar two rows tall. */
    padding: 1.125rem var(--space-sm);
    font-size: var(--text-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
  }

  .actionbar__call { color: var(--white); }
  .actionbar__quote { background: var(--brand-light); color: var(--white); }

  /* So the footer's last row is never permanently sat on by the bar. The bar
     measures ~81px, so this clears it with a little room to spare. */
  .footer { padding-bottom: 6.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .actionbar { transition: none; }
}


/* --- Nav crowding ------------------------------------------------------- */
/* Nothing in the bar wraps. Without this the two labels containing a space were
   the first to give when the flex row ran short of room. */
.nav__actions .btn,
.nav__phone { white-space: nowrap; }

/* The button was sized for body copy; in a 76px bar it only needs to read as a
   button, and the extra padding was part of what overflowed the row. */
.nav__actions .btn--sm { padding: 0.625rem 1.25rem; font-size: var(--text-sm); }

/* The four partner marks run from 1.07:1 to 6.64:1. Constraining both axes
   leaves them with very different box widths (~8.5 / 8.5 / 6.7 / 3.2rem), so a
   constant flex gap still reads as uneven — the square mark ends up with far
   more apparent air around it than the wordmarks. Giving every mark an
   identical column makes the centres evenly spaced, which is what the eye
   actually reads as even.
   NOTE: one class, same specificity as .logo-strip__row — must stay after it. */
.logo-strip__row--partners {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 10rem;
  place-items: center;
  gap: 0;
}

/* With a shared column, the tall square mark no longer needs to be the widest
   thing on the row; trimming it evens the optical weight as well as the gaps. */
.logo-strip__row--partners img { max-height: 2.5rem; max-width: 7.25rem; }
.logo-strip__row--partners img[data-mark="simply"] { max-height: 2.75rem; max-width: 2.75rem; }

@media (prefers-reduced-motion: reduce) {
  /* The static fallback wraps, so the column flow has to go back to rows. */
  .logo-strip__row--partners {
    grid-auto-flow: row;
    grid-template-columns: repeat(auto-fit, 10rem);
    justify-content: center;
    gap: var(--space-xl) 0;
  }
}

/* Partner marks: even INK spacing, not even boxes.
   `.marquee .logo-strip__row img` pins every mark to a uniform 11rem box with
   object-fit: contain. That makes the centres evenly spaced but not the visible
   gaps — the wordmarks (up to 6.64:1) fill their box while the square Simply
   mark renders ~38px of ink inside 176px, leaving a hole either side of it.
   Letting each mark take its natural width under a shared height cap puts a
   constant gap between the marks themselves, which is what reads as even.
   Specificity 0,3,1 so it beats the 0,2,1 rule above regardless of order. */
.marquee .logo-strip__row.logo-strip__row--partners img {
  width: auto;
  height: auto;
  /* Wordmarks are width-limited and squat, the square mark is height-limited.
     A wider cap with a lower height cap brings the rendered heights within a
     few pixels of each other (~26-32px) instead of 22 vs 46. */
  max-height: 2rem;
  max-width: 11rem;
  object-fit: contain;
}

/* Simply is the only square lockup in the set; at a shared max-height it reads
   smaller than the wordmarks, so it is allowed to run a little taller — the
   same allowance the press row already makes for ABC. */
.marquee .logo-strip__row.logo-strip__row--partners img[data-mark="simply"] {
  max-height: 2.4rem;
}
