/* ==========================================================================
   ANTEAMBULO — hero
   One full-viewport section over a full-bleed plate. The architecture is the
   glass/bottom-anchored layout; the palette, type and voice are the brand kit.

   Palette is the NEW kit sampled from the supplied artboards, not the previous
   site's tokens: gold moved #C6A04A -> #C8A05F and the black moved
   #131210 -> #231F20. The logo art is authored in the new values, so keeping
   the old ones would have put two different golds on the same screen.
   ========================================================================== */

@font-face {
  font-family: 'Montserrat';
  src: url('assets/fonts/montserrat.woff2') format('woff2');
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('assets/fonts/montserrat-italic.woff2') format('woff2');
  font-weight: 300 600;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'Roboto Mono';
  src: url('assets/fonts/roboto-mono.woff2') format('woff2');
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
}

:root {
  /* --- Brand (sampled from the supplied artwork) --- */
  --ink-900:   #231F20;
  --gold-600:  #C8A05F;
  --gold-300:  #D9BE90;   /* R6 gold hover. #DCBC8A was invented here and disagreed with the kit. */
  --ivory-100: #FDFBF6;
  --ivory-200: #F7F3EA;   /* the inverted surface */
  --ink-500:   #55524A;   /* 7.04:1 on ivory-200 — the only ink that may set text there */

  /* --- Glass ---------------------------------------------------------
     Kept at the source design's opacities so the cards read as one system
     with the nav pill. --glass-line is the top edge that stops a panel
     dissolving where it meets a bright patch of the plate. */
  /* Ivory-based, not pure white: a cool white inside a warm palette read as a
     second, colder white sitting next to Ivory 100. Same alphas. */
  --glass:      rgba(253, 251, 246, 0.10);
  --glass-line: rgba(253, 251, 246, 0.14);

  /* --- Surfaces below the hero ----------------------------------------
     Glass only makes sense over the plate. Past the hero there is nothing
     behind it to sample, so the sections use the main site's R6 ladder —
     the same tokens, re-solved against this same #231F20 canvas, so the two
     properties agree rather than each inventing a dark grey.
     Steps: canvas->band 1.17:1, band->tile 1.29:1. */
  --band-750:  #322B26;
  --tile-700:  #473C2E;
  --tile-600:  #4C4030;   /* hover */
  --sand-300:  #BFB7A8;   /* body — 8.19:1 canvas · 6.99:1 band · 5.40:1 tile */
  /* One muted tier, legal on every surface this site uses. --sand-500 was
     canvas-only (4.66 there) and fell to 3.98 on the band and 3.07 on a tile —
     both below AA. The inner pages put step labels on a band and card meta on a
     tile, so a canvas-only token could not survive the new routes.
     #ABA89C: canvas 6.84 · band 5.84 · tile 4.51. */
  --sand-400:  #ABA89C;
  --sand-500:  #8E8979;   /* DEPRECATED — canvas only. Do not use on band or tile. */
  --hairline:  rgba(253, 251, 246, 0.12);   /* ivory ramp; the sand-based value was the only one of its kind */

  --font-display: 'Montserrat', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'Roboto Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-accent: Georgia, 'Times New Roman', serif;   /* the one pull quote */

  --ease-panel: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-state: 0.2s ease;   /* the documented state curve */
}

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

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

body {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  color: var(--ivory-100);
  background: var(--ink-900);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.is-locked { overflow: hidden; }

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

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
  color: var(--ivory-100);   /* the UA link blue is off-palette even while clipped */
}
.sr-only:focus {
  position: fixed; top: 12px; left: 12px;
  width: auto; height: auto; margin: 0; padding: 10px 16px;
  clip-path: none; z-index: 60;
  background: var(--ivory-100); color: var(--ink-900); border-radius: 999px;
}

:where(a, button, input):focus-visible {
  outline: 2px solid var(--gold-600);
  outline-offset: 3px;
}

/* ============================================================ STRUCTURE */

/* min-height, not height. At one viewport the section is exactly full-screen
   and the content sits on the bottom edge, which is the whole idea. But a
   squat window — a 731x698 restored browser, landscape phones, large text
   settings — needs more room than that, and with a fixed height plus
   overflow:hidden the cards were simply cut off with no way to scroll to
   them. Growing costs nothing when the content already fits. */
.hero {
  position: relative;
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;   /* the mobile URL bar must not crop the cards */
  overflow: hidden;     /* clips the plate's bleed, not the copy */
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Weighted to the bottom-left, where the lede sits. A flat wash would have
   dulled the whole plate to lift type that only occupies one corner. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(35, 31, 32, 0.94) 0%, rgba(35, 31, 32, 0.70) 38%, rgba(35, 31, 32, 0) 72%),
    linear-gradient(to right, rgba(35, 31, 32, 0.78) 0%, rgba(35, 31, 32, 0.32) 50%, rgba(35, 31, 32, 0) 80%),
    linear-gradient(to bottom, rgba(35, 31, 32, 0.55) 0%, rgba(35, 31, 32, 0) 26%);
}

.hero__stack {
  position: relative;
  z-index: 10;
  display: flex;
  flex-direction: column;
  /* Matches the section's floor so `margin-top:auto` on the content still
     drops it to the bottom edge of a full viewport. `height:100%` would
     resolve against an auto-height parent and collapse. */
  min-height: 100vh;
  min-height: 100svh;
}

/* ================================================================== NAV */

/* Fixed, not in the hero's flow: with sections below it now has to survive the
   scroll. z-index sits BELOW .scrim on purpose — when the drawer opens the bar
   should be dimmed with everything else, leaving only the burger above it. */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px;
  transition: background-color 220ms ease;
}

/* Earns a surface once it is no longer sitting on the video. */
.nav.is-scrolled {
  background: rgba(35, 31, 32, 0.78);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
}

.logo { display: block; flex: none; }
.logo img { width: auto; height: 20px; }

.nav__desktop { display: none; }

.nav__pill {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  border-radius: 999px;
  background: var(--glass);
  border: 1px solid var(--glass-line);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.nav__link {
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  color: rgba(253, 251, 246, 0.80);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--ease-state), color var(--ease-state);
}
.nav__link:hover { background: var(--glass); color: var(--ivory-100); }

/* ============================================================== BUTTONS */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--font-display);
  /* 500, not 600 — the main site's note holds here too: on a page whose
     thesis is whisper-weight the CTA should not be the loudest thing on it. */
  font-weight: 500;
  font-size: 14px;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  /* One treatment, one padding. The same button was rendering at four heights
     (47 / 44 / 44 / 38px) from four different paddings; M5 asks for exactly one. */
  padding: 12px 18px;
  transition: background-color var(--ease-state), color var(--ease-state);
}

/* Brand primary is solid gold on obsidian. The source design's dark vertical
   gradient is not in this kit and would have read as a dead panel against the
   plate, so the kit's button wins. */
.btn--primary { background: var(--gold-600); color: var(--ink-900); }
.btn--primary:hover { background: var(--gold-300); }

/* No align-self:stretch — it was the last thing making one button treatment
   render at two heights (47px in the nav, 40px everywhere else). */

/* ========================================================= MOBILE MENU */

.burger {
  position: fixed;
  top: 20px; right: 20px;
  z-index: 50;
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  flex: none;
  padding: 0;
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  background: var(--glass);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  color: var(--ivory-100);
  cursor: pointer;
}

.burger svg { grid-area: 1 / 1; width: 18px; height: 18px; transition: all 300ms ease; }
.burger__close { transform: rotate(-90deg) scale(0); opacity: 0; }
.burger[aria-expanded="true"] .burger__menu  { transform: rotate(90deg) scale(0); opacity: 0; }
.burger[aria-expanded="true"] .burger__close { transform: none; opacity: 1; }

.scrim {
  position: fixed;
  inset: 0;
  z-index: 40;   /* above .nav (30), below .burger (50) */
  background: rgba(35, 31, 32, 0.86);   /* was #141112 — neither the old ink nor the new */
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  transition: opacity 300ms ease;
}
.scrim.is-open { opacity: 1; }
.scrim[hidden] { display: none; }

.drawer {
  position: fixed;
  top: 0; right: 0;
  z-index: 41;   /* above .scrim, below .burger */
  display: flex;
  flex-direction: column;
  width: 288px;
  max-width: 86vw;
  height: 100%;
  background: rgba(35, 31, 32, 0.92);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  transform: translateX(100%);
  transition: transform 500ms var(--ease-panel);
}
.drawer.is-open { transform: none; }
.drawer[hidden] { display: none; }

.drawer__links { display: flex; flex-direction: column; gap: 8px; padding: 96px 24px 0; }

.drawer__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 16px;
  font-weight: 400;
  color: rgba(253, 251, 246, 0.80);
  text-decoration: none;
  /* Closed state. The open state adds the stagger; on close every item
     travels back together, which reads as the panel leaving rather than the
     links leaving one at a time. */
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 400ms ease, transform 400ms ease,
              background-color var(--ease-state), color var(--ease-state);
}
.drawer__link:hover { background: var(--glass); color: var(--ivory-100); }

.drawer.is-open .drawer__link { opacity: 1; transform: none; }
.drawer.is-open .drawer__link:nth-child(1) { transition-delay: 60ms; }
.drawer.is-open .drawer__link:nth-child(2) { transition-delay: 120ms; }
.drawer.is-open .drawer__link:nth-child(3) { transition-delay: 180ms; }

.drawer__foot { margin-top: auto; padding: 0 24px 40px; }

.drawer__cta {
  width: 100%;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 400ms ease 300ms, transform 400ms ease 300ms,
              background-color var(--ease-state);
}
.drawer.is-open .drawer__cta { opacity: 1; transform: none; }

/* ============================================================== CONTENT */

.hero__content {
  margin-top: auto;         /* the whole point: content hangs off the bottom */
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 0 20px 32px;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 20px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-600);
}
.eyebrow::before { content: ""; width: 24px; height: 1px; background: var(--gold-600); flex: none; }

/* R2 — M1/M2. Was clamped at 56px and never rose: 60px at 1440 AND at 1920,
   3.75x body against the bar's 5-6x, with 1.02 leading against 0.90. The bar's
   hard floor is 72px on desktop and its target is 96px. The headline occupied
   42% of the frame where the reference's holds 66%.
   8.2vw is the reference's own coefficient: 96px lands at 1170px viewport, so
   the full display size is reached before the common laptop widths, not after. */
.display {
  margin: 0 0 20px;
  font-size: clamp(38px, 8.2vw, 96px);
  font-weight: 300;
  line-height: 0.9;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.display .line { display: block; }
.accent { font-style: italic; font-weight: 300; }

.subhead {
  margin: 0 0 22px;
  max-width: 46ch;
  font-size: 14.5px;
  font-weight: 300;
  line-height: 1.5;
  color: rgba(253, 251, 246, 0.72);
}

/* The main site's line-by-line rise, kept at the same timing so the two pages
   open the same way. */
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.display .line, .subhead, .eyebrow {
  opacity: 0;
  animation: rise 2.5s cubic-bezier(0.455, 0.03, 0.515, 0.955) forwards;
}
.eyebrow                 { animation-delay: .04s; }
.display .line:nth-child(1) { animation-delay: .12s; }
.display .line:nth-child(2) { animation-delay: .24s; }
.subhead                 { animation-delay: .40s; }

/* -------------------------------------------------------------- capture */

.hero__actions { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }

/* The main site's second hero CTA, restored — and it doubles as the scroll
   affordance. A locked full-viewport hero with no visible bottom edge reads as
   the whole page otherwise. */
.ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  /* At 1200px this shrank to 74x70 — a three-line stack beside the CTA. It is a
     flex item with a long label and had no floor of its own. */
  flex: none;
  white-space: nowrap;
  font-size: 14px;
  font-weight: 400;
  color: rgba(253, 251, 246, 0.75);
  text-decoration: none;
  transition: color var(--ease-state);
}
.ghost:hover { color: var(--ivory-100); }




.meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}
.mono-micro {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(253, 251, 246, 0.55);
}


/* ============================================================= SECTIONS */

.shell { max-width: 1200px; margin-inline: auto; padding-inline: 20px; }

.section { padding-block: 72px; }
.section--band { background: var(--band-750); }

/* Was canvas, directly under a canvas Process and above a canvas footer —
   1,322px of one flat value with only 1px rules between, which M3 names as
   forbidden. The ladder now alternates on every seam:
   hero(plate) -> services(band) -> process(canvas) -> contact(band) -> footer(canvas). */
.section--contact { background: var(--band-750); }

.section__head { margin-bottom: 40px; }

/* Section display. Was 34px — smaller than what the bar calls a sub-section.
   M2 sets the 80px row to leading 1.0. */
.h2 {
  margin: 0;
  font-size: clamp(32px, 6.6vw, 80px);
  font-weight: 300;
  line-height: 1.0;
  letter-spacing: -0.02em;
  color: var(--ivory-100);
  text-wrap: balance;
}

.section__note {
  margin: 16px 0 0;
  max-width: 52ch;
  font-size: 15px;
  font-weight: 300;
  line-height: 1.55;
  color: var(--sand-300);
}

.grid { display: grid; gap: 16px; grid-template-columns: 1fr; }

/* ---------------------------------------------------------------- tiles */

.tile {
  display: flex;
  flex-direction: column;
  border-radius: 16px;
  background: var(--tile-700);
  padding: 24px;
  transition: background-color var(--ease-state);
}
.tile:hover { background: var(--tile-600); }

.tile__icon { display: block; width: 34px; height: 34px; color: var(--gold-600); }
.tile__icon svg { width: 100%; height: 100%; display: block; }

.tile__index {
  margin: 18px 0 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--sand-300);
}

.tile__title {
  margin: 10px 0 0;
  font-size: 22px;          /* heading-sm; M2 puts the 22-38px band at 0.9 */
  font-weight: 300;
  line-height: 0.9;
  letter-spacing: -0.01em;
  color: var(--ivory-100);
}

.tile__body {
  margin: 14px 0 0;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.6;
  color: var(--sand-300);
}

/* ---------------------------------------------------------------- steps */

.steps { list-style: none; margin: 0; padding: 0; }

.step__rule { height: 1px; background: var(--hairline); margin-bottom: 18px; }
.step:first-child .step__rule { background: var(--gold-600); }

/* The mono tag now carries a literal noun. Skimming the headings alone used to
   yield "someone walks ahead on a path" and nothing about the actual work. */
.step__n {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sand-400);
}

.step__title {
  margin: 12px 0 0;
  font-size: 22px;
  font-weight: 300;
  line-height: 0.9;
  color: var(--ivory-100);
}

.step__body {
  margin: 12px 0 0;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.6;
  color: var(--sand-300);
}

/* ----------------------------------------------------------------- band */

/* Full-bleed and carries no text, so it needs no scrim of its own. */
.band { margin: 56px 0 0; }
.band img { width: 100%; height: clamp(200px, 24vw, 360px); object-fit: cover; }

/* ------------------------------------------------------------- inverted */

/* M3 wants four visible surface levels in one scroll. Canvas, band and tile
   existed; this is the fourth, and the only light surface on the page. */
.inverted {
  margin: 56px 0 0;
  padding: 40px 28px;
  border-radius: 16px;
  background: var(--ivory-200);
  color: var(--ink-900);
}

/* The single Georgia instance on the page — the accent voice M6 reserves for
   exactly one pull quote, and the role this page previously had nothing in. */
.inverted__quote {
  margin: 0;
  max-width: 34ch;
  font-family: var(--font-accent);
  font-size: clamp(22px, 3.4vw, 32px);
  font-style: italic;
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.inverted__attrib {
  margin: 24px 0 0;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-500);   /* 7.04:1 on ivory-200; gold-700 would give 3.11:1 */
}

/* -------------------------------------------------------------- contact */

.contact { display: flex; flex-direction: column; gap: 28px; }
.contact__note { margin-top: 18px; }
.contact__act { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }

.contact__alt { margin: 0; font-size: 14px; font-weight: 300; color: var(--sand-300); }
.contact__alt a { color: var(--ivory-100); text-decoration: none; border-bottom: 1px solid var(--hairline); }
.contact__alt a:hover { border-bottom-color: var(--gold-600); }

/* --------------------------------------------------------------- footer */

.footer { border-top: 1px solid var(--hairline); padding-block: 36px; }

.footer__inner { display: flex; flex-direction: column; gap: 20px; }
.footer .logo img { height: 18px; }

.footer__contact { display: flex; flex-wrap: wrap; gap: 8px 24px; font-size: 14px; font-weight: 300; }
.footer__contact a { color: var(--sand-300); text-decoration: none; }
.footer__contact a:hover { color: var(--ivory-100); }

.footer__legal { margin: 0; color: var(--sand-400); }

/* =========================================================== BREAKPOINTS */

@media (min-width: 640px) {
  .nav { padding: 24px 32px; }
  .logo img { height: 22px; }

  .hero__content { gap: 32px; padding: 0 32px 48px; }

  .display { margin-bottom: 22px; }   /* size comes from the clamp, not from here */
  .subhead { font-size: 16px; }

  .hero__actions { flex-direction: row; align-items: center; gap: 20px; }

  .section { padding-block: 88px; }
  .grid { gap: 20px; grid-template-columns: repeat(2, 1fr); }
  .section__head { margin-bottom: 48px; }

}

@media (min-width: 768px) {
  .nav__desktop { display: flex; align-items: center; gap: 12px; }
  .burger { display: none; }
  /* Belt and braces: if the viewport is widened while the menu is open, the
     panels must not be left hanging over the desktop layout. */
  .drawer, .scrim { display: none; }
  body.is-locked { overflow: auto; }
}

@media (min-width: 1024px) {
  .nav { padding: 24px 48px; }
  .logo img { height: 24px; }

  /* Single column now the cards are gone — a row with one child and
     space-between was doing nothing. */
  .hero__content { padding: 0 48px 64px; }

  /* No fixed .display size here any more. THIS is what pinned the headline at
     56/60px and made the clamp above dead code — it resolved 96px and was then
     overridden at every desktop width. The measure widens instead, because at
     96px "You move forward." needs the room. */
  .hero__lede { max-width: 62rem; }
  .subhead { margin-bottom: 28px; max-width: 42ch; }

  .section { padding-block: 112px; }
  .grid { grid-template-columns: repeat(4, 1fr); gap: 24px; }

  /* Head splits: title left, note right, sharing the baseline. */
  .section__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 48px;
    margin-bottom: 56px;
  }
  .section__note { margin-top: 0; max-width: 42ch; text-align: right; }
  .contact__note { text-align: left; margin-top: 18px; }

  .contact { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: 64px; }
  .contact__act { align-items: flex-end; }

  .footer__inner { flex-direction: row; align-items: center; justify-content: space-between; gap: 32px; }
}

/* 1440 no longer needs a display rule: clamp(38px, 8.2vw, 96px) reaches its
   96px ceiling at 1171px, so every desktop width above that is already there. */

/* Squat windows below the two-column breakpoint — a restored 731x698 browser
   is the common one. The stacked layout ran 29px long there; this trims the
   vertical padding rather than dropping anything, so it lands inside one
   screen. The min-height rule above is still the backstop if it does not. */
@media (max-height: 780px) and (max-width: 1023px) {
  .hero__content { gap: 20px; padding-bottom: 24px; }
  .meta { margin-top: 16px; }
  .subhead { margin-bottom: 18px; }
}

/* Short landscape phones: the plate is only ~380px tall, so the meta row and
   the cards are the first things that would push the CTA off screen. */
@media (max-height: 560px) and (max-width: 1023px) {
  .meta { display: none; }
  .hero__content { padding-bottom: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  .display .line, .subhead, .eyebrow { animation: none; opacity: 1; }
  .drawer, .scrim, .drawer__link, .drawer__cta, .burger svg { transition-duration: 1ms; }
  .hero__video { display: none; }   /* the plate falls back to its poster */
  .hero { background: url('assets/media/poster-2560.webp') center / cover no-repeat, var(--ink-900); }
}
