/* ==========================================================================
   Golden Bear International — design system
   Two faces. Cormorant Garamond carries the display voice — high contrast,
   set in caps, matching the wordmark. Montserrat carries everything else:
   body, navigation, and the tracked small-caps labels. Brand gold-on-black
   preserved per SPEC §4.1.
   ========================================================================== */

/* --- tokens ------------------------------------------------------------- */
:root {
  /* surfaces — tonal, never a light/dark flip */
  --ink:        #0b0b0c;
  --ink-2:      #131315;
  --ink-3:      #1a1a1d;
  --ink-4:      #232327;

  /* brand */
  --gold:       #c9a961;
  --gold-lift:  #e0c57f;
  --gold-deep:  #9d8449;   /* 5.4:1 on --ink, 5.1:1 on --ink-2 — WCAG AA */

  /* text — warm off-white, not pure white (clears contrast failures) */
  --bone:       #ede8e0;
  --bone-dim:   #a8a199;
  --bone-faint: #8f8a80;   /* 5.7:1 on --ink, 5.4:1 on --ink-2 — WCAG AA */

  --line:       color-mix(in srgb, var(--gold) 22%, transparent);
  --line-soft:  color-mix(in srgb, var(--bone) 10%, transparent);

  /* type — Cormorant for display, Montserrat for everything else */
  --font-display: "Cormorant Garamond", ui-serif, Didot, Georgia, serif;
  --font-body:    "Montserrat", ui-sans-serif, system-ui, sans-serif;

  /* Scale is anchored to the hero: step-4 is the largest type on the site and
     nothing exceeds it. Section headings sit a clear step below it, and body
     copy sits just above the nav. */
  --step--1: clamp(0.72rem, 0.70rem + 0.10vw, 0.78rem);
  --step-0:  clamp(0.95rem, 0.92rem + 0.16vw, 1.05rem);
  --step-1:  clamp(1.15rem, 1.05rem + 0.42vw, 1.45rem);
  --step-2:  clamp(1.50rem, 1.28rem + 0.95vw, 2.10rem);
  --step-3:  clamp(1.90rem, 1.55rem + 1.50vw, 2.75rem);
  --step-4:  clamp(2.20rem, 1.70rem + 2.20vw, 3.60rem);

  /* caps tracking — tightens as the type gets larger */
  --track-lg: 0.045em;
  --track-md: 0.085em;
  --track-sm: 0.16em;

  /* space */
  --s-1: 0.5rem;  --s-2: 0.875rem; --s-3: 1.25rem; --s-4: 2rem;
  --s-5: 3rem;    --s-6: 4.5rem;   --s-7: 7rem;
  --section-y: clamp(4.5rem, 8vw, 9rem);

  --measure: 58ch;
  --wrap: 1280px;
  --gutter: clamp(1.25rem, 5vw, 4rem);

  /* fixed so the hero can subtract it and land exactly one viewport tall */
  --header-h: clamp(68px, 5.6vw, 88px);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- reset / base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, video, svg { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

/* Headlines are set in caps, as the original site did — it is what carried the
   "handled with ceremony" register. Tracking opens up as the size comes down. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.02;
  margin: 0;
  text-transform: uppercase;
  text-wrap: balance;
}
h1 { font-size: var(--step-4); letter-spacing: var(--track-lg); line-height: 0.98; }
h2 { font-size: var(--step-3); letter-spacing: var(--track-lg); }
h3 { font-size: var(--step-1); letter-spacing: var(--track-md); }
h4 { font-size: var(--step-1); letter-spacing: var(--track-md); }

/* Running prose keeps sentence case — caps belong to the display voice only. */
.faq summary,
.teaser h2,
.article h2,
.article h3 { text-transform: none; letter-spacing: 0; }

p { margin: 0 0 var(--s-3); max-width: var(--measure); text-wrap: pretty; }
.lede, .hero__lede { text-wrap: pretty; }

/* accessibility floor */
:focus-visible {
  outline: 2px solid var(--gold-lift);
  outline-offset: 3px;
  border-radius: 2px;
}
.skip-link {
  position: absolute; left: var(--s-3); top: -100%;
  background: var(--gold); color: var(--ink);
  padding: var(--s-2) var(--s-3); z-index: 100;
  font-family: var(--font-body); font-size: var(--step--1);
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: var(--s-3); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* --- layout ------------------------------------------------------------- */
.wrap { width: min(var(--wrap), 100% - var(--gutter) * 2); margin-inline: auto; }
.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * 0.62); }
.section--raised { background: var(--ink-2); }

/* --- SIGNATURE: the manifest line --------------------------------------
   Tracked small caps carrying metadata in the company's own vernacular.
   Justified because this firm literally catalogues and numbers every item
   it moves.
   ----------------------------------------------------------------------- */
.manifest {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0 0 var(--s-3);
}
/* no leading rule — the eyebrow stands on its own */
.manifest--plain { /* retained as a no-op alias */ }
.manifest__sep { color: var(--gold-deep); }
.manifest__code { color: var(--bone-dim); letter-spacing: 0.12em; }

/* --- buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-body); font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 1rem 1.75rem;
  text-decoration: none;
  border: 1px solid var(--gold);
  background: transparent; color: var(--gold);
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease),
              border-color 0.25s var(--ease);
  min-height: 48px;                 /* touch-target floor */
}
.btn:hover, .btn:focus-visible { background: var(--gold); color: var(--ink); }
.btn--solid { background: var(--gold); color: var(--ink); }
.btn--solid:hover, .btn--solid:focus-visible {
  background: var(--gold-lift); border-color: var(--gold-lift);
}

/* --- header ------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--ink) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line-soft);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); min-block-size: var(--header-h);
}
/* --- brand lockup -------------------------------------------------------
   The bear-and-stars mark, with the wordmark set live in the display face
   rather than baked into a raster logo. Scales, recolours, stays crisp.
   ----------------------------------------------------------------------- */
.brand {
  display: inline-flex; align-items: center; gap: clamp(0.7rem, 1.4vw, 1.1rem);
  text-decoration: none; color: var(--gold);
}
.brand__mark { width: clamp(38px, 4.4vw, 54px); height: auto; flex: none; }
.brand__type { display: grid; gap: 0.55em; }
.brand__name {
  font-family: var(--font-display);
  font-size: clamp(1.16rem, 0.96rem + 0.78vw, 1.72rem);   /* ~1pt smaller */
  font-weight: 400; line-height: 0.9;
  letter-spacing: 0.07em; text-transform: none;
  color: var(--gold);
  white-space: nowrap;            /* the wordmark never breaks */
}
.brand__sub {
  font-family: var(--font-body); font-weight: 600;
  font-size: clamp(0.48rem, 0.42rem + 0.18vw, 0.58rem);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-deep); line-height: 1;
  white-space: nowrap;
}
.brand:hover .brand__name,
.brand:focus-visible .brand__name { color: var(--gold-lift); }

/* stacked variant for the footer */
.brand--stack { flex-direction: column; align-items: flex-start; gap: var(--s-3); }
.brand--stack .brand__mark { width: clamp(54px, 6vw, 68px); }
.nav { display: flex; align-items: center; gap: clamp(0.7rem, 1.5vw, 1.5rem); }
/* navigation is utility, so it stays quiet: sentence case, tight tracking.
   Emphatic caps are reserved for content CTAs. */
.nav a {
  font-family: var(--font-body); font-size: 0.85rem; font-weight: 400;
  letter-spacing: 0.01em; text-transform: none;
  text-decoration: none; color: var(--bone);
  padding: 0.5rem 0; position: relative;
  white-space: nowrap;            /* nav items never break mid-label */
  transition: color 0.2s var(--ease);
}
.nav .btn {
  font-family: var(--font-body); font-weight: 600;
  padding: 0.7rem 1.1rem; font-size: 0.85rem;
  letter-spacing: 0.01em; text-transform: none;
}
.nav a:hover, .nav a:focus-visible, .nav a[aria-current="page"] { color: var(--gold); }
.nav .btn:hover, .nav .btn:focus-visible { color: var(--ink); }
.nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: var(--gold);
}
.nav__toggle { display: none; }

/* --- hero --------------------------------------------------------------- */
/* The media is taken out of flow and stretched to cover, so the section can
   grow with its content without a portrait source dictating the height —
   and without tall display type overflowing a fixed box. */
/* exactly one viewport, less the header — svh so mobile browser chrome
   collapsing doesn't leave a gap or force a scroll */
.hero {
  position: relative; display: flex; overflow: hidden;
  min-block-size: calc(100svh - var(--header-h));
}
/* isolate: the crossfade rotates z-index on the slides, and without a stacking
   context of their own those values compete with the scrim and the hero copy */
.hero__media { position: absolute; inset: 0; overflow: hidden; isolation: isolate; }
/* The first slide's image is also painted as a background. Slide 1 animates
   from opacity 0 and slides 2–3 have not started yet, so for the first ~1.3s
   of every load nothing was painted and the hero showed as empty — measured at
   76 consecutive frames of zero coverage. The background fills that window
   with the identical image, so the fade-in is invisible. */
.hero__media {
  background: url("/img/gb2.jpg") 50% center / cover no-repeat;
}
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% center; }

/* crossfade: 3 slides stacked, each holding a 7s slot of a 21s cycle. Pure CSS
   — no JS, and no layout shift, since every slide fills the same absolutely
   positioned box.

   Each slide fades IN over the one before it and then STAYS opaque for the
   rest of the cycle. Two slides fading opposite directions at once would leave
   both semi-transparent at the midpoint and flash the layer underneath — so
   we only fade in, never out.

   Critical: the outgoing slide must keep its elevated z-index until the
   incoming fade has finished. Dropping it at the same instant the next slide
   starts (opacity 0) briefly reveals an older slide underneath — the
   double-swap glitch. Hold elevated through ~40% (incoming reaches opacity 1
   at 33%+7% ≈ 40%); later siblings at the same z-index still paint on top. */
.hero__slide { position: absolute; inset: 0; opacity: 0; animation: hero-fade 21s infinite; }
.hero__slide:nth-child(1) { animation-delay:  0s; }
.hero__slide:nth-child(2) { animation-delay:  7s; }
.hero__slide:nth-child(3) { animation-delay: 14s; }

@keyframes hero-fade {
       0% { opacity: 0; z-index: 2; }   /* arrives on top, transparent */
       7% { opacity: 1; z-index: 2; }   /* faded in over the previous slide */
      40% { opacity: 1; z-index: 2; }   /* hold until the NEXT slide has faded in */
  40.001% { opacity: 1; z-index: 1; }   /* safe to drop — fully covered now */
     100% { opacity: 1; z-index: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__slide { animation: none; opacity: 0; }
  .hero__slide:nth-child(1) { opacity: 1; }
}
/* scrim — the current site sets gold text on bare photography and it is
   close to illegible. This is the single biggest contrast fix. */
.hero__media::after {
  content: ""; position: absolute; inset: 0;
  z-index: 3;                       /* above the slides, which rotate 1 → 2 */
  /* The slides are bright — white rooms, white shrink-wrap — so the scrim has
     to carry more than it did against a dark image, or the lede washes out. */
  background:
    linear-gradient(to right,
      color-mix(in srgb, var(--ink) 90%, transparent) 0%,
      color-mix(in srgb, var(--ink) 74%, transparent) 40%,
      color-mix(in srgb, var(--ink) 34%, transparent) 72%,
      color-mix(in srgb, var(--ink) 14%, transparent) 100%),
    linear-gradient(to top,
      color-mix(in srgb, var(--ink) 80%, transparent) 0%,
      transparent 45%);
}
.hero__body {
  position: relative; z-index: 2;
  align-self: center; padding-block: clamp(2rem, 4vw, 3.25rem);
}
/* sized to fit the viewport: a wider measure cuts the line count, which saves
   more height than shrinking the type alone. Uses the scale's top step, so the
   hero and inner-page headings are the same size. */
.hero__title {
  max-width: 24ch;
  font-size: var(--step-4);
  line-height: 1.04;
}
.hero__title em { font-style: italic; color: var(--gold); text-transform: none; }
.hero__lede {
  font-size: clamp(1rem, 0.93rem + 0.3vw, 1.15rem);
  font-family: var(--font-body); font-weight: 300;
  color: var(--bone); max-width: 46ch; margin-top: var(--s-3);
  line-height: 1.6;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-4); }

/* --- stats ---------------------------------------------------------------
   Rebuilt from eight source SVGs whose copy was baked into outlined paths —
   every figure was invisible to search engines and screen readers. These are
   real text; only the Lucide marks are vector.
   ------------------------------------------------------------------------ */
/* Explicit column counts rather than auto-fit: the dividers are drawn with
   border-inline-start and reset per row, which needs a known column count.
   auto-fit can land on 3 columns at some widths and leave a stray leading
   border on the wrapped row. */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-5) 0;
}
/* two columns: the mark, then the figure with its label beneath. Grid rather
   than flex so the icon can sit in row 1 and centre against the figure itself,
   not against the whole text block. */
.stat {
  padding-inline: clamp(1rem, 2.5vw, 2rem);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: clamp(0.85rem, 1.4vw, 1.15rem);
  row-gap: var(--s-2);
  align-items: start;
  /* the parent grid stretches each .stat to the tallest in its row; without
     this the auto rows absorb that slack, inflating row 1 and dropping the
     vertically-centred icon out of line with its figure */
  align-content: start;
}
.stat + .stat { border-inline-start: 1px solid var(--line-soft); }
.stat:nth-child(4n + 1) { border-inline-start: 0; }   /* first in each row */

.stat__icon {
  color: var(--gold-deep); flex: none;
  grid-column: 1; grid-row: 1;
  align-self: start;                  /* top-aligned to the figure */
}
.stat__figure { grid-column: 2; grid-row: 1; }
.stat__label  { grid-column: 2; grid-row: 2; }
/* no figure to centre against here, so the glyph centres on the whole list */
.stat--rows .stat__list { grid-column: 2; grid-row: 1; }
.stat__figure {
  font-family: var(--font-display); font-size: var(--step-3);
  line-height: 1; color: var(--gold); margin: 0;
}
.stat__label {
  font-size: 0.85rem; line-height: 1.5; color: var(--bone-dim);
  margin: 0; max-width: 24ch;
}
/* the states figure has no single number — three lines rather than inventing a
   combined total the client never claimed */
.stat__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-1); }
.stat__list li { font-size: 0.85rem; color: var(--bone-dim); line-height: 1.4; }
.stat__n {
  font-family: var(--font-display); font-size: var(--step-1);
  color: var(--gold); line-height: 1; margin-inline-end: 0.15em;
}

.stats-band {
  background: var(--ink-2);
  border-block: 1px solid var(--line);
  padding-block: clamp(2.5rem, 5vw, 3.75rem);
}

/* 4 across → 2 → 1, dividers reset at the start of each row.
   Resets use `.stat + .stat` to match the base rule's specificity — a bare
   `.stat` selector loses to it and would need !important. */
@media (max-width: 1080px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat + .stat:nth-child(odd) { border-inline-start: 0; }
}
@media (max-width: 620px) {
  .stats { grid-template-columns: 1fr; gap: var(--s-5); }
  .stat, .stat + .stat { border-inline-start: 0; padding-inline: 0; }
}

/* --- editorial two-column ---------------------------------------------- */
.duo {
  display: grid; gap: clamp(2rem, 5vw, var(--s-6));
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  align-items: center;
}
.duo--reverse .duo__media { order: 2; }
.duo__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.duo__media--square img { aspect-ratio: 1; }
.duo__body p:last-child { margin-bottom: 0; }
/* headings inside a half-width column step down — at full display size they
   wrap to four lines and stop reading as a headline */
.duo__body h2 { font-size: var(--step-2); }
.duo__body h2 + p { margin-top: var(--s-3); }
.duo__pull {
  font-family: var(--font-display); font-size: var(--step-2);
  font-style: italic; color: var(--gold); line-height: 1.25;
  margin: var(--s-4) 0; max-width: 42ch;
}

/* --- services ----------------------------------------------------------- */
.cards {
  display: grid; gap: var(--s-3); margin-top: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
.card {
  display: flex; flex-direction: column;
  background: var(--ink-3);
  border: 1px solid transparent;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.card:hover { border-color: var(--line); transform: translateY(-3px); }
.card__media { overflow: hidden; }
.card__media img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  transition: transform 0.6s var(--ease);
}
.card:hover .card__media img { transform: scale(1.04); }
.card__body { padding: var(--s-4); display: flex; flex-direction: column; flex: 1; }
.card__body .manifest {
  font-size: clamp(0.58rem, 0.55rem + 0.08vw, 0.64rem);
  letter-spacing: 0.18em;
}
.card__body h3 { margin-bottom: var(--s-2); }
.card__body p { color: var(--bone-dim); font-size: 0.98rem; line-height: 1.6; }
.card__link {
  font-family: var(--font-body); font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold); text-decoration: none;
  margin-top: auto; padding-top: var(--s-3); display: inline-flex; gap: var(--s-2);
  min-height: 44px; align-items: center;
}
.card__link:hover, .card__link:focus-visible { color: var(--gold-lift); }
.card__link::after { content: "→"; transition: transform 0.25s var(--ease); }
.card__link:hover::after { transform: translateX(4px); }

/* --- testimonials — all three visible, no carousel ---------------------- */
.quotes {
  display: grid; gap: var(--s-4); margin-top: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}
.quote {
  border-top: 1px solid var(--line); padding-top: var(--s-4);
  display: flex; flex-direction: column;      /* captions bottom-align across columns */
}
.quote blockquote {
  margin: 0 0 var(--s-4);
  font-family: var(--font-display); font-size: var(--step-1);
  line-height: 1.45; color: var(--bone);
}
.quote figcaption { font-family: var(--font-body); font-size: var(--step--1); margin-top: auto; }
.quote__name { color: var(--gold); letter-spacing: 0.12em; text-transform: uppercase; }
.quote__route { color: var(--bone-faint); display: block; margin-top: 0.35rem; }

/* --- qubo — dark section, stark left/right card ------------------------- */
.qubo { background: var(--ink); }
.qubo__card {
  display: grid;
  grid-template-columns: minmax(16rem, 0.85fr) minmax(0, 1.15fr);
  background: var(--ink-2);
  border: 1px solid var(--line);
  overflow: hidden;
}
.qubo__body {
  display: flex; flex-direction: column; justify-content: center;
  gap: 0;
  padding: clamp(2rem, 4.5vw, 3.5rem);
  background: var(--ink);
}
.qubo__mark {
  width: clamp(72px, 8vw, 104px); height: auto;
  align-self: center;             /* centered in the left column */
}
.qubo__rule {
  border: 0; border-block-start: 1px solid var(--gold);
  width: 2.75rem; margin: var(--s-4) 0;
}
.qubo__sub {
  font-family: var(--font-display);
  font-size: var(--step-1);
  letter-spacing: var(--track-md);
  text-transform: uppercase;
  color: var(--bone);
  margin: 0 0 var(--s-3);
  max-width: 28ch;
}
.qubo__body > p:not(.qubo__sub):not(.qubo__action) {
  color: var(--bone-dim);
  font-size: 0.98rem;
  line-height: 1.65;
  max-width: 36ch;
  margin: 0;
}
.qubo__action { margin: var(--s-4) 0 0; }
.qubo__media {
  position: relative;
  align-self: stretch;
  min-block-size: 100%;
  background: var(--ink);
}
.qubo__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  max-width: none;              /* override global img { max-width:100%; height:auto } */
  object-fit: cover;
  object-position: center;
  display: block;
}
@media (max-width: 820px) {
  .qubo__card { grid-template-columns: 1fr; }
  .qubo__media { order: -1; min-block-size: 14rem; aspect-ratio: 16 / 10; }
}

/* --- newsletter --------------------------------------------------------- */
.signup__grid {
  display: grid; gap: clamp(2rem, 5vw, var(--s-6)); align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
}
.field { display: flex; flex-direction: column; gap: var(--s-1); margin-bottom: var(--s-3); }
.field label {
  font-family: var(--font-body); font-size: var(--step--1);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--bone-dim);
}
.field input, .field textarea, .field select {
  font-family: var(--font-body); font-size: var(--step-0);
  color: var(--bone); background: var(--ink-3);
  border: 1px solid var(--line-soft);
  padding: 0.85rem 1rem; min-height: 48px;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
}
.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--gold); background: var(--ink-4); outline: none;
}
.field textarea { min-height: 8rem; resize: vertical; }
.hp { position: absolute; left: -9999px; }   /* honeypot */

/* --- footer ------------------------------------------------------------- */
.site-footer { background: var(--ink-2); border-top: 1px solid var(--line); }
.site-footer__grid {
  display: grid; gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  padding-block: var(--s-6) var(--s-5);
}
.site-footer h2 {
  font-size: 0.82rem; font-family: var(--font-body); font-weight: 500;
  letter-spacing: 0.18em; color: var(--gold);
  margin-bottom: var(--s-3);
}
.site-footer p { font-size: 0.88rem; line-height: 1.65; color: var(--bone-dim); }
.site-footer a { color: var(--bone-dim); text-decoration: none; font-size: 0.88rem; }
.site-footer a:hover, .site-footer a:focus-visible { color: var(--gold); }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; }
/* keep the 44px touch target without the visual gap it used to create */
.site-footer li a { display: flex; align-items: center; min-height: 40px; line-height: 1.4; }
.social { display: flex; gap: var(--s-3); }
.social a {
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 1px solid var(--line-soft);
}
.social a:hover { border-color: var(--gold); }
.colophon {
  border-top: 1px solid var(--line-soft);
  padding-block: var(--s-4);
  display: flex; flex-wrap: wrap; gap: var(--s-3); justify-content: space-between;
  font-family: var(--font-body); font-size: var(--step--1);
  color: var(--bone-faint); letter-spacing: 0.08em;
}

/* --- centered block — CTA, 404, the VIP commitment ----------------------
   One component instead of the same four inline styles repeated per page.
   ----------------------------------------------------------------------- */
.center { text-align: center; }
.center .manifest { justify-content: center; }
.center h1, .center h2 { margin-inline: auto; max-width: 32ch; }
.center p { margin-inline: auto; }
.center__lede { max-width: 52ch; margin-top: var(--s-4); }
.center__action { margin-top: var(--s-5); max-width: none; }

/* --- inner-page hero ---------------------------------------------------- */
.page-hero { position: relative; min-block-size: clamp(400px, 58vh, 600px); display: flex; }
.page-hero__media { position: absolute; inset: 0; overflow: hidden; }
.page-hero__media img { width: 100%; height: 100%; object-fit: cover; }
.page-hero__media--top img { object-position: top; }
.page-hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right, color-mix(in srgb, var(--ink) 70%, transparent) 6%, color-mix(in srgb, var(--ink) 42%, transparent) 52%, transparent 84%);
}
.page-hero__body { position: relative; z-index: 2; align-self: end; padding-block: clamp(3rem, 7vw, 5.5rem); }
.page-hero__body h1 { max-width: 24ch; }
.page-hero__body p:last-child { margin-bottom: 0; }
.page-hero--plain {
  block-size: auto; min-block-size: 0;
  background: var(--ink-2); border-bottom: 1px solid var(--line);
}
.page-hero--plain .page-hero__body { padding-block: clamp(3rem, 7vw, 5.5rem); }
.page-hero--compact { min-block-size: clamp(260px, 38vh, 400px); }
.page-hero--compact .page-hero__body { padding-block: clamp(1.25rem, 3vw, 2rem); }
/* intro copy is one size everywhere — matches .hero__lede */
.lede {
  font-size: clamp(1rem, 0.93rem + 0.3vw, 1.15rem);
  font-weight: 300; line-height: 1.6;
  max-width: 46ch; color: var(--bone);
}

/* --- spec list — the "what's included" manifest ------------------------- */
.specs { display: grid; gap: 0; margin-top: var(--s-5); border-top: 1px solid var(--line-soft); }
.spec {
  display: grid; gap: var(--s-2) var(--s-5);
  grid-template-columns: minmax(min(100%, 15rem), 22rem) 1fr;
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--line-soft);
  align-items: baseline;
}
.spec dt {
  font-family: var(--font-body); font-size: var(--step--1);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold);
}
.spec dd { margin: 0; color: var(--bone-dim); font-size: 1rem; line-height: 1.65; }

/* --- feature bullets ---------------------------------------------------- */
.ticks { list-style: none; margin: 0 0 var(--s-4); padding: 0; display: grid; gap: var(--s-2); }
.ticks li { display: grid; grid-template-columns: 1.25rem 1fr; gap: var(--s-2); color: var(--bone-dim); }
.ticks li::before { content: "★"; color: var(--gold); font-size: 0.8em; line-height: 1.9; }

/* --- split card — large left/right editorial panel ---------------------- */
.split {
  display: grid;
  grid-template-columns: minmax(16rem, 1fr) minmax(16rem, 1fr);
  border: 1px solid var(--line);
  background: var(--ink-2);
  overflow: hidden;
}
.split__main, .split__aside {
  padding: clamp(2rem, 5vw, 3.75rem);
  display: flex; flex-direction: column; justify-content: center;
}
.split__main { background: var(--ink); }
.split__main h2 { max-width: 18ch; }
.split__sub {
  margin: var(--s-4) 0 0;
  max-width: 36ch;
  color: var(--bone-dim);
  font-size: 0.98rem;
  line-height: 1.65;
}
.split__aside { border-inline-start: 1px solid var(--line-soft); }
.split__aside .manifest { margin-bottom: var(--s-4); }
.split__aside .ticks { margin: 0; gap: var(--s-4); }
.split__aside .ticks li {
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--bone);
}
@media (max-width: 820px) {
  .split { grid-template-columns: 1fr; }
  .split__aside { border-inline-start: 0; border-block-start: 1px solid var(--line-soft); }
}

/* --- cities ------------------------------------------------------------- */
.cities {
  display: grid; gap: var(--s-3); margin-top: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}
.city { position: relative; overflow: hidden; }
.city img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; transition: transform 0.6s var(--ease); }
.city:hover img { transform: scale(1.05); }
.city h3 {
  position: absolute; inset-inline: 0; bottom: 0; margin: 0;
  padding: var(--s-4) var(--s-3) var(--s-3);
  font-size: var(--step-1);
  background: linear-gradient(to top, var(--ink) 12%, transparent);
}

/* --- coverage map -------------------------------------------------------
   Replaces a 3.5 MB MP4 whose only payload was a map animation plus one line
   of typeset-into-the-pixels copy. The plate is a bare map; the pins, the
   corridors and the headline are all live.
   ----------------------------------------------------------------------- */
.cmap__title { max-width: 28ch; }
.cmap__lede { margin-top: var(--s-3); max-width: 52ch; color: var(--bone-dim); }
.cmap { position: relative; margin: var(--s-5) 0 0; }
.cmap__plate { width: 100%; }
.cmap__lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

.cmap__route {
  fill: none;
  stroke: var(--gold);
  stroke-width: 2.5;
  stroke-dasharray: 7 10;
  stroke-linecap: round;
  opacity: 0.85;
  stroke-dashoffset: 620;
  animation: cmap-draw 2.2s var(--ease) forwards;
  animation-delay: calc(var(--i) * 0.16s + 0.2s);
}
.cmap__pin {
  fill: var(--gold-lift);
  opacity: 0;
  animation: cmap-pin 0.5s var(--ease) forwards;
  animation-delay: calc(var(--i) * 0.07s);
}
@keyframes cmap-draw { to { stroke-dashoffset: 0; } }
@keyframes cmap-pin  { to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .cmap__route { stroke-dashoffset: 0; animation: none; }
  .cmap__pin { opacity: 1; animation: none; }
}

/* --- FAQ ---------------------------------------------------------------- */
.faq { margin-top: var(--s-5); border-top: 1px solid var(--line-soft); }
.faq details { border-bottom: 1px solid var(--line-soft); }
.faq summary {
  cursor: pointer; list-style: none; padding-block: var(--s-4);
  font-family: var(--font-display); font-size: var(--step-1);
  display: flex; justify-content: space-between; gap: var(--s-3); align-items: center;
  min-height: 48px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--gold); font-family: var(--font-body); flex: none; }
.faq details[open] summary::after { content: "–"; }
.faq details > div { padding-bottom: var(--s-4); }
.faq details > div p { color: var(--bone-dim); margin-bottom: 0; }

/* --- gallery ------------------------------------------------------------ */
.grid-gallery {
  display: grid; gap: var(--s-2); margin-top: var(--s-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
}
.grid-gallery img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }

/* JS wraps each tile in a button; without JS the grid stays plain images */
.gg__btn {
  padding: 0; border: 0; background: none; cursor: zoom-in; display: block;
  overflow: hidden; position: relative;
}
.gg__btn img { transition: transform 0.5s var(--ease), opacity 0.3s var(--ease); }
.gg__btn:hover img, .gg__btn:focus-visible img { transform: scale(1.04); opacity: 0.86; }

/* --- lightbox ----------------------------------------------------------- */
.lb {
  border: 0; padding: 0; max-width: 100%; max-height: 100%;
  width: 100%; height: 100%; background: transparent; color: var(--bone);
  overflow: hidden;
}
.lb::backdrop { background: rgba(6, 6, 7, 0.94); }
.lb__inner {
  display: grid; grid-template-rows: 1fr auto;
  width: 100%; height: 100%; padding: clamp(0.75rem, 2.5vw, 2rem);
  gap: var(--s-3);
}
.lb__stage { min-height: 0; position: relative; }
/* pinned to the stage rather than centred with a percentage max-height —
   that does not reliably constrain an image inside a 1fr grid track, and the
   image overflowed onto the caption */
.lb__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  animation: lb-in 0.28s var(--ease);
}
@keyframes lb-in { from { opacity: 0; transform: scale(0.985); } to { opacity: 1; transform: none; } }

.lb__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3);
}
.lb__count {
  font-size: var(--step--1); letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--bone-faint);
}
.lb__caption {
  font-size: 0.9rem; color: var(--bone-dim); margin: 0;
  max-width: 60ch; text-align: center; flex: 1;
}
.lb__nav { display: flex; gap: var(--s-2); }
.lb__btn {
  width: 48px; height: 48px; display: grid; place-items: center;
  background: transparent; color: var(--bone);
  border: 1px solid var(--line-soft); cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.lb__btn:hover, .lb__btn:focus-visible { border-color: var(--gold); color: var(--gold); }
.lb__close { position: absolute; top: 0; right: 0; z-index: 2; }

@media (max-width: 620px) {
  .lb__caption { display: none; }
  .lb__bar { justify-content: center; }
}

/* --- article ------------------------------------------------------------ */
.article { max-width: 68ch; margin-inline: auto; }
.article h2 { font-size: var(--step-2); margin-top: var(--s-5); }
.article h3 {
  font-size: var(--step-1); margin-top: var(--s-5); color: var(--gold);
  font-family: var(--font-display);
}
.article p { max-width: none; }
.article figure { margin: var(--s-5) 0; }
.article__meta {
  font-family: var(--font-body); font-size: var(--step--1);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--bone-faint);
}

/* --- post teaser -------------------------------------------------------- */
.teaser { border-top: 1px solid var(--line); padding-top: var(--s-4); max-width: 58ch; }
.teaser h2 { font-size: var(--step-2); margin-bottom: var(--s-3); }
.teaser h2 a { text-decoration: none; }
.teaser h2 a:hover { color: var(--gold); }

/* --- fieldset / checkbox groups ---------------------------------------- */
.group { border: 0; padding: 0; margin: 0 0 var(--s-4); }
.group legend {
  font-family: var(--font-body); font-size: var(--step--1);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--bone-dim);
  padding: 0; margin-bottom: var(--s-2);
}
.choice { display: flex; align-items: center; gap: var(--s-2); min-height: 44px; }
.choice input { width: 1.1rem; height: 1.1rem; accent-color: var(--gold); flex: none; }
.choice label { font-family: var(--font-body); text-transform: none; letter-spacing: 0; color: var(--bone); }
.form-note { color: var(--bone-faint); font-size: 0.85rem; margin-top: var(--s-4); }

/* --- contact aside ------------------------------------------------------ */
.aside { display: grid; gap: var(--s-6); align-content: start; }
.aside h2 { font-size: var(--step-2); margin-bottom: var(--s-3); }
.promo {
  border: 1px solid var(--line);
  background: var(--ink-3);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.promo p { color: var(--bone-dim); font-size: 0.95rem; }
.promo__action { margin: var(--s-4) 0 0; }
.contact-list { list-style: none; padding: 0; margin: var(--s-3) 0 0; display: grid; gap: var(--s-2); }
.contact-list a { color: var(--gold); text-decoration: none; }
.contact-list a:hover, .contact-list a:focus-visible { color: var(--gold-lift); }
.form-status { margin-top: var(--s-3); font-family: var(--font-body); font-size: var(--step--1); }
.form-status[data-state="ok"]   { color: var(--gold); }
.form-status[data-state="err"]  { color: #ff9d8a; }

/* --- responsive --------------------------------------------------------- */
/* collapse to the menu button early — eight items plus the lockup will not sit
   on one line below this, and a wrapping nav looks broken rather than dense */
@media (max-width: 1080px) {
  .nav { display: none; }
  .nav--open { display: flex; }
  .nav__toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 48px; height: 48px; background: none; border: 1px solid var(--line-soft);
    color: var(--bone); cursor: pointer;
  }
  .site-header__inner { position: relative; }
  .nav--open {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: flex-start;
    background: var(--ink-2); border: 1px solid var(--line-soft);
    padding: var(--s-3); gap: 0;
  }
  .nav--open a { padding: 0.9rem 0; width: 100%; }
  .duo--reverse .duo__media { order: 0; }

  /* narrow viewports sit the copy directly over the subject, so the horizontal
     scrim no longer separates them — go vertical and heavier */
  .hero__media::after {
    background: linear-gradient(to top,
      color-mix(in srgb, var(--ink) 96%, transparent) 4%,
      color-mix(in srgb, var(--ink) 88%, transparent) 48%,
      color-mix(in srgb, var(--ink) 72%, transparent) 100%);
  }
  .page-hero__media::after {
    background: linear-gradient(to top,
      color-mix(in srgb, var(--ink) 94%, transparent) 4%,
      color-mix(in srgb, var(--ink) 78%, transparent) 52%,
      color-mix(in srgb, var(--ink) 58%, transparent) 100%);
  }
  .spec { grid-template-columns: 1fr; gap: var(--s-1); }
}

@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;
  }
}

/* --- motion --------------------------------------------------------------
   Additive only. Two separate mechanisms, deliberately:

   1. Entrances (hero, header) are pure CSS animations with `both` fill. They
      need no JavaScript, so if site.js fails to load the content still ends
      visible. A JS-gated opacity:0 here would strand the hero permanently.
   2. Scroll reveals hide via [data-reveal], an attribute only JS ever adds —
      so no JS means no attribute means nothing hidden.

   Only opacity and transform are animated; both are compositor properties, so
   none of this can shift layout. Measured CLS: 0.
   ------------------------------------------------------------------------ */
@keyframes gb-rise  { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes gb-fade  { from { opacity: 0; } to { opacity: 1; } }
@keyframes gb-settle{ from { transform: scale(1.045); } to { transform: none; } }

@media (prefers-reduced-motion: no-preference) {

  /* entrances — no JS required */
  .js .hero__body > *,
  .js .page-hero__body > * { animation: gb-rise 0.8s var(--ease) both; }
  .js :is(.hero__body, .page-hero__body) > *:nth-child(1) { animation-delay: 0.10s; }
  .js :is(.hero__body, .page-hero__body) > *:nth-child(2) { animation-delay: 0.21s; }
  .js :is(.hero__body, .page-hero__body) > *:nth-child(3) { animation-delay: 0.32s; }
  .js :is(.hero__body, .page-hero__body) > *:nth-child(4) { animation-delay: 0.43s; }
  .js :is(.hero__body, .page-hero__body) > *:nth-child(5) { animation-delay: 0.54s; }

  .js .site-header { animation: gb-fade 0.6s var(--ease) 0.1s both; }
  .js .hero__media { animation: gb-settle 1.8s var(--ease) both; }

  /* scroll reveal — [data-reveal] is added by JS, so this only ever applies
     when the script is actually running */
  .js [data-reveal] { opacity: 0; transform: translateY(14px); }
  .js [data-reveal].is-in {
    opacity: 1; transform: none;
    transition: opacity 0.65s var(--ease), transform 0.65s var(--ease);
    transition-delay: calc(var(--i, 0) * 80ms);
  }
  .js [data-reveal="media"] { transform: translateY(20px) scale(1.012); }
  .js [data-reveal="media"].is-in { transition-duration: 0.9s; transform: none; }
}

/* Reduced motion: no entrance, no reveal, no count-up (the JS checks the same
   query). Everything simply present. */
@media (prefers-reduced-motion: reduce) {
  .js .hero__body > *,
  .js .page-hero__body > *,
  .js .site-header,
  .js .hero__media,
  .js [data-reveal] { animation: none; opacity: 1; transform: none; }
}
