/* ==========================================================================
   Indigo Editorial - coded landing template
   Tokens mirror the active Novamira design system "Indigo Editorial".
   ========================================================================== */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/archivo-roman-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/archivo-roman-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/archivo-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/archivo-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg:      #F2F2F0;
  --surface: #FFFFFF;
  --ink:     #0E1B33;
  --accent:  #24457F;
  --muted:   #5C6880;
  --line:    #D8D8D3;
  --wash:    #93AFD9;

  --ink-rgb: 14, 27, 51;

  --font: 'Archivo', 'Helvetica Neue', Arial, sans-serif;

  --sp-xs: 8px;
  --sp-sm: 16px;
  --sp-md: 32px;
  --sp-lg: 64px;
  --sp-xl: 120px;

  --r-sm: 2px;
  --r-md: 4px;

  --gutter: 40px;
  --maxw: 1440px;

  --section-y: clamp(84px, 10vw, 160px);
}

/* --------------------------------------------------------------------------
   Scoped reset. :where() keeps specificity at 0 so any component rule wins,
   while still neutralising UA defaults and anything the stack leaks in.
   -------------------------------------------------------------------------- */

:where(.ie-page *, .ie-page *::before, .ie-page *::after) {
  box-sizing: border-box;
}

:where(.ie-page h1, .ie-page h2, .ie-page h3, .ie-page h4, .ie-page h5, .ie-page h6,
       .ie-page p, .ie-page figure, .ie-page blockquote, .ie-page dl, .ie-page dd,
       .ie-page ul, .ie-page ol, .ie-page li) {
  margin: 0;
  padding: 0;
  border: 0;
  font: inherit;
  list-style: none;
}

:where(.ie-page img, .ie-page svg) {
  display: block;
  max-width: 100%;
  border: 0;
}

body.ie-page a {
  color: inherit;
  text-decoration: none;
}

:where(.ie-page button) {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

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

body.ie-page {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.6;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/*
 * The active kit sets h1-h6 to a display serif globally. That rule has real
 * specificity, so the :where() reset above cannot beat it and every heading
 * silently falls back to Fraunces. Declare the family explicitly, at a
 * specificity the leak cannot reach.
 */
body.ie-page,
body.ie-page h1, body.ie-page h2, body.ie-page h3,
body.ie-page h4, body.ie-page h5, body.ie-page h6,
body.ie-page p, body.ie-page a, body.ie-page span,
body.ie-page li, body.ie-page em, body.ie-page strong,
body.ie-page button, body.ie-page figcaption {
  font-family: var(--font);
}

/* --------------------------------------------------------------------------
   Shared container. Every section aligns to this left edge.
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--section-y);
}

/* --------------------------------------------------------------------------
   Type scale
   -------------------------------------------------------------------------- */

.d1, .d2, .d3 {
  font-family: var(--font);
  font-weight: 600;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.d1 {
  font-size: clamp(2.75rem, 7.2vw, 6.5rem);
  line-height: 0.98;
}

.d2 {
  font-size: clamp(2.1rem, 4.6vw, 4rem);
  line-height: 1.02;
}

.d3 {
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  line-height: 1.1;
  letter-spacing: -0.028em;
}

/* Italic emphasis is the same family. Descenders need room at display sizes. */
.d1 em, .d2 em, .d3 em {
  font-style: italic;
  font-weight: 500;
  line-height: 1.12;
  padding-bottom: 0.06em;
  display: inline-block;
}

.lede {
  font-size: clamp(1.0625rem, 1.35vw, 1.25rem);
  line-height: 1.55;
  max-width: 34ch;
  color: var(--muted);
}

.body-copy {
  max-width: 62ch;
  color: var(--muted);
}

.body-copy + .body-copy {
  margin-top: 1.1em;
}

.label {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   Buttons. One radius rule: interactive is full pill.
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 28px;
  border-radius: 999px;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transition: background-color .28s ease, color .28s ease, border-color .28s ease, transform .12s ease;
}

.btn:active { transform: translateY(1px); }

body.ie-page .btn--primary {
  background: var(--ink);
  color: var(--bg);
  border: 1px solid var(--ink);
}
body.ie-page .btn--primary:hover { background: var(--accent); border-color: var(--accent); }

body.ie-page .btn--ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid rgba(var(--ink-rgb), .35);
}
body.ie-page .btn--ghost:hover { border-color: var(--ink); background: rgba(var(--ink-rgb), .05); }

/* On the dark ground the pair inverts so both keep AA contrast. */
body.ie-page .on-ink .btn--primary {
  background: var(--bg);
  color: var(--ink);
  border-color: var(--bg);
}
body.ie-page .on-ink .btn--primary:hover { background: var(--wash); border-color: var(--wash); color: var(--ink); }

/* Over a photograph a hairline stroke alone is not enough: add a scrim so the
   label keeps its contrast when a bright part of the image sits behind it. */
body.ie-page .on-ink .btn--ghost {
  color: var(--bg);
  border-color: rgba(242, 242, 240, .58);
  background: rgba(14, 27, 51, .3);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
body.ie-page .on-ink .btn--ghost:hover { border-color: var(--bg); background: rgba(14, 27, 51, .5); }

/* The contact section is a flat dark ground, so it needs no scrim. */
body.ie-page .contact .btn--ghost { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
body.ie-page .contact .btn--ghost:hover { background: rgba(242, 242, 240, .1); }

.btn .arw {
  width: 15px;
  height: 15px;
  flex: none;
  transition: transform .28s ease;
}
.btn:hover .arw { transform: translateX(3px); }

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.hdr {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 60;
  padding-block: 28px;
  transition: background-color .35s ease, box-shadow .35s ease, padding .35s ease;
}

/* Sit below the WordPress toolbar when an editor is signed in. */
body.admin-bar .hdr { top: 32px; }
@media screen and (max-width: 782px) {
  body.admin-bar .hdr { top: 46px; }
}

.hdr__in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
}

/*
 * The supplied logo is navy artwork on an opaque light ground, so a CSS invert
 * turns it into a white slab. Two pre-built transparent variants are swapped
 * instead, one for the light ground and one for the hero photograph.
 */
.hdr__logo img {
  height: 68px;
  width: auto;
  transition: height .35s ease;
}

.hdr__logo-light { display: none; }
.hdr--over .hdr__logo-light { display: block; }
.hdr--over .hdr__logo-dark { display: none; }

body.menu-open .hdr .hdr__logo-light { display: none; }
body.menu-open .hdr .hdr__logo-dark { display: block; }
body.menu-open .hdr .burger span { background: var(--ink); }

/*
 * The open panel is a light ground, so the over-hero white link colour has to
 * be beaten back or the whole menu reads as blank.
 */
body.menu-open .hdr--over .nav a { color: var(--ink); }
body.menu-open .hdr--over .nav > .btn { color: var(--bg); background: var(--ink); border-color: var(--ink); }

/* Over the hero photograph the nav inverts to the light ground colour. */
.hdr--over .nav a { color: var(--bg); }
.hdr--over .nav a::after { background: var(--bg); }
body.ie-page .hdr--over .btn--ghost { color: var(--bg); border-color: rgba(242, 242, 240, .45); }
body.ie-page .hdr--over .btn--ghost:hover { border-color: var(--bg); background: rgba(242, 242, 240, .1); }
.hdr--over .burger span { background: var(--bg); }

.hdr--stuck {
  background: rgba(242, 242, 240, .92);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  box-shadow: 0 1px 0 var(--line);
  padding-block: 18px;
}
.hdr--stuck .hdr__logo img { height: 52px; }

.nav {
  display: flex;
  align-items: center;
  gap: 34px;
  margin-left: auto;
}

.nav a {
  position: relative;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
  padding-block: 4px;
}

/* The header sits over photography, so its labels carry more weight than the
   body scale would normally use. */
.hdr .btn { font-weight: 600; }

.nav a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .34s cubic-bezier(.2,.7,.3,1);
}
.nav a:hover::after { transform: scaleX(1); transform-origin: left; }

/* The in-nav call to action only appears once the nav becomes the mobile panel. */
.nav > .btn { display: none; }

.hdr__cta { margin-left: 26px; }
.hdr__cta .btn { padding: 12px 24px; }

.burger {
  display: none;
  width: 44px;
  height: 44px;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
  gap: 6px;
  margin-left: auto;
}
.burger span {
  display: block;
  width: 26px;
  height: 1.5px;
  background: var(--ink);
  transition: transform .3s ease, opacity .3s ease, width .3s ease;
}
.burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   Hero. Full bleed photograph, headline anchored bottom left,
   contact column offset right. Sized to sit inside the first viewport.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
}

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

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
  transform: scale(1.08);
  transition: transform 1.6s cubic-bezier(.16,.84,.28,1);
}
.js .hero--in .hero__media img { transform: scale(1); }

/*
 * Background video. The photograph stays underneath as an instant poster and
 * as the fallback whenever autoplay is refused: low power mode, data saver,
 * reduced motion, or no JavaScript at all.
 */
.hero__video {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  /* Lets the cover maths below measure the hero rather than the viewport. */
  container-type: size;

  /*
   * Asymmetric on purpose. Fading up is leisurely, but dropping back to the
   * photograph is near instant, because that drop is what hides YouTube's
   * control overlay whenever the player leaves the playing state.
   */
  transition: opacity .2s ease;
}

.hero__video.is-playing {
  opacity: 1;
  transition: opacity 1.1s ease;
}

/* A 16:9 iframe scaled to cover a container of any shape. */
.hero__video iframe {
  position: absolute;
  top: 50%;
  left: 50%;

  /* Viewport-unit fallback for engines without container query units. */
  width: 100vw;
  height: 56.25vw;
  min-width: 177.78vh;
  min-height: 100vh;

  /*
   * The hero is sized in svh, so viewport units drift from it on phones where
   * the browser chrome collapses. Measuring the container instead keeps the
   * footage covering edge to edge at every size.
   */
  width: 100cqw;
  height: 56.25cqw;
  min-width: 177.78cqh;
  min-height: 100cqh;

  border: 0;
  /*
   * Overscaled on purpose. YouTube paints its title bar along the top edge of
   * the player and a control strip along the bottom, so the frame is pushed
   * beyond the container and those bands are cropped away.
   */
  transform: translate(-50%, -50%) scale(1.3);
  pointer-events: none;
}

/* Directional scrim: heavy at the lower left where the headline sits. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, rgba(var(--ink-rgb), .88) 0%, rgba(var(--ink-rgb), .55) 34%, rgba(var(--ink-rgb), .12) 68%, rgba(var(--ink-rgb), .34) 100%),
    linear-gradient(to right, rgba(var(--ink-rgb), .6) 0%, rgba(var(--ink-rgb), 0) 62%);
}

/* Moving daylight footage is brighter and busier than the still, so the scrim
   is carried further once the video takes over. */
.hero--video .hero__scrim {
  background:
    linear-gradient(to top, rgba(var(--ink-rgb), .92) 0%, rgba(var(--ink-rgb), .64) 34%, rgba(var(--ink-rgb), .22) 68%, rgba(var(--ink-rgb), .42) 100%),
    linear-gradient(to right, rgba(var(--ink-rgb), .7) 0%, rgba(var(--ink-rgb), 0) 64%);
}

.hero__in {
  width: 100%;
  padding-bottom: clamp(48px, 6vw, 88px);
  padding-top: 140px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--sp-lg);
  color: var(--bg);
}

.hero__eyebrow {
  color: rgba(242, 242, 240, .78);
  margin-bottom: 22px;
}

.hero .d1 {
  color: var(--bg);
  max-width: 15ch;
  margin-bottom: 26px;
}

/*
 * Cycling headline. "Full service retail" holds while the noun crossfades
 * through four words on a twelve second loop. Pure CSS, so it still runs with
 * JavaScript off; the accessible name on the h1 stays a single fixed phrase.
 */
.hero .hero__h1 { max-width: none; }

/*
 * A two-tone headline. The fixed line goes to pure white so it reads as crisply
 * as possible against moving footage, and the cycling word takes the pale blue
 * already in the palette, lifted with a soft halo. The paired dark shadow is
 * doing the real work: it holds the type legible when a bright frame of video
 * passes behind it.
 */
.hero__lead {
  display: block;
  color: #FFFFFF;
  text-shadow: 0 2px 24px rgba(14, 27, 51, .5);
}

.hero__word {
  color: var(--wash);
  text-shadow:
    0 0 36px rgba(147, 175, 217, .5),
    0 0 12px rgba(147, 175, 217, .35),
    0 2px 20px rgba(14, 27, 51, .55);
}

.hero__cycle {
  display: block;
  position: relative;
  height: 1.18em;
}

.hero__word {
  position: absolute;
  left: 0;
  top: 0;
  display: inline-block;
  font-style: italic;
  font-weight: 500;
  line-height: 1.12;
  padding-bottom: 0.06em;
  white-space: nowrap;
  opacity: 0;
  animation: heroWord 12s cubic-bezier(.16, .84, .28, 1) infinite;
}

/*
 * Three words on a twelve second loop, so each holds for four seconds. The
 * hold ends at 30% and the fade completes at 34%, while the next word starts
 * its own fade at 33.3%: they overlap rather than leaving a blank beat.
 * These delays assume three words. Change $hero_words and change these too.
 */
.hero__word:nth-child(1) { animation-delay: 0s; }
.hero__word:nth-child(2) { animation-delay: 4s; }
.hero__word:nth-child(3) { animation-delay: 8s; }

@keyframes heroWord {
  0%   { opacity: 0; transform: translate3d(0, .16em, 0); }
  3%   { opacity: 1; transform: none; }
  30%  { opacity: 1; transform: none; }
  34%  { opacity: 0; transform: translate3d(0, -.12em, 0); }
  100% { opacity: 0; transform: translate3d(0, .16em, 0); }
}

/* Hold the cycle until the headline itself has revealed. */
.js .hero__h1.reveal:not(.is-in) .hero__word { animation-play-state: paused; }

.hero .lede {
  color: rgba(242, 242, 240, .82);
  max-width: 46ch;
  margin-bottom: 34px;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.hero__call {
  text-align: right;
  padding-bottom: 6px;
}
.hero__call .label { color: rgba(242, 242, 240, .7); }
.hero__call a {
  display: block;
  margin-top: 10px;
  font-size: clamp(1.25rem, 1.7vw, 1.6rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--bg);
}
.hero__call a:hover { color: var(--wash); }

/* --------------------------------------------------------------------------
   Statistics band. Real numbers set very large, hairlines instead of cards.
   -------------------------------------------------------------------------- */

.stats {
  border-bottom: 1px solid var(--line);
  padding-block: clamp(56px, 6vw, 92px);
}

.stats__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.stat {
  padding: 4px 28px 4px 0;
  border-left: 1px solid var(--line);
  padding-left: 28px;
}
.stat:first-child { border-left: 0; padding-left: 0; }

.stat__n {
  display: block;
  font-size: clamp(3rem, 5.6vw, 5.25rem);
  font-weight: 600;
  line-height: 0.94;
  letter-spacing: -0.05em;
  color: var(--ink);
}

.stat__l {
  display: block;
  margin-top: 16px;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--muted);
  max-width: 20ch;
}

/* --------------------------------------------------------------------------
   About. Copy left, image cluster right bleeding past the container.
   -------------------------------------------------------------------------- */

.about__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
}

.about__head .label { display: block; margin-bottom: 26px; }
.about__head .d2 { margin-bottom: 34px; max-width: 18ch; }

.tags {
  margin-top: 40px;
  padding-top: 30px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tag {
  display: inline-block;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.8125rem;
  color: var(--muted);
  transition: border-color .25s ease, color .25s ease;
}
.tag:hover { border-color: var(--accent); color: var(--accent); }

/* The cluster escapes the container to the right viewport edge. */
.about__media {
  position: relative;
  margin-right: calc(50% - 50vw);
  padding-bottom: 90px;
}

.about__media-main img {
  width: 100%;
  height: auto;
  border-radius: var(--r-md);
}

.about__media-inset {
  position: absolute;
  left: -46px;
  bottom: 0;
  width: 46%;
  box-shadow: 0 24px 60px -24px rgba(var(--ink-rgb), .38);
  border-radius: var(--r-md);
  overflow: hidden;
}
.about__media-inset img { width: 100%; height: auto; }

.about__media-cap {
  position: absolute;
  right: var(--gutter);
  bottom: 22px;
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   Ground-up development. A full-bleed massing study with the copy set into
   the drawing's own open left third, so nothing is laid over the subject.
   -------------------------------------------------------------------------- */

.gu {
  position: relative;
  padding-block: clamp(40px, 4vw, 76px) 0;
}

.gu__stage {
  position: relative;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

.gu__stage svg {
  display: block;
  width: 100%;
  height: auto;
}

.gu__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  pointer-events: none;
}

/* The open part of the drawing is roughly the left 40%, so the copy column is
   sized in px against that, and the heading steps down a notch to suit it. */
.gu__copy {
  pointer-events: auto;
  width: min(40%, 500px);
}

.gu__copy .d2 {
  font-size: clamp(1.75rem, 3.2vw, 3rem);
  line-height: 1.04;
  margin-bottom: 26px;
}

.gu__copy .body-copy { max-width: 42ch; }
.gu__copy .body-copy + .body-copy { margin-top: .9em; }

.gu__cap {
  display: block;
  margin-top: 30px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

/* The linework draws itself in, which is the one moment on the page where the
   animation is the content: a building being set out. */
.js .gu__stage.reveal,
.js .gu__stage.reveal.is-in {
  opacity: 1;
  transform: none;
  transition: none;
}

.js .gu .ms-edges path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.5s cubic-bezier(.16, .84, .28, 1);
}
.js .gu__stage.is-in .ms-edges path { stroke-dashoffset: 0; }

.js .gu .ms-edges[data-b="1"] path { transition-delay: .16s; }
.js .gu .ms-edges[data-b="2"] path { transition-delay: .32s; }
.js .gu .ms-edges[data-b="3"] path { transition-delay: .48s; }

.js .gu .ms-ground,
.js .gu .ms-ghost,
.js .gu .ms-fills,
.js .gu .ms-detail,
.js .gu .ms-trees {
  opacity: 0;
  transition: opacity 1.1s ease .35s;
}
.js .gu__stage.is-in .ms-ground,
.js .gu__stage.is-in .ms-ghost,
.js .gu__stage.is-in .ms-fills,
.js .gu__stage.is-in .ms-detail,
.js .gu__stage.is-in .ms-trees { opacity: 1; }

/* --------------------------------------------------------------------------
   Capability rows. Numbered index, hairline rules, no boxes.
   -------------------------------------------------------------------------- */

.caps { border-top: 1px solid var(--line); }

.caps__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-bottom: clamp(48px, 5vw, 78px);
}
.caps__head .d2 { max-width: 20ch; }

.cap {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--sp-md);
  align-items: baseline;
  padding-block: clamp(28px, 3vw, 42px);
  border-bottom: 1px solid var(--line);
  transition: background-color .3s ease;
}
.cap:first-child { border-top: 1px solid var(--line); }

.cap:hover { background: rgba(36, 69, 127, .045); }
.cap:hover .cap__t { color: var(--accent); }

.cap__n {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.cap__t {
  font-size: clamp(1.375rem, 2.1vw, 1.875rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.03em;
  transition: color .3s ease;
}

.cap__d {
  color: var(--muted);
  max-width: 52ch;
}

/* --------------------------------------------------------------------------
   What we build. Deliberately uneven tiles, image first, caption below.
   -------------------------------------------------------------------------- */

.build__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-lg);
  margin-bottom: clamp(44px, 4.5vw, 72px);
}
.build__head .d2 { max-width: 26ch; }

.tiles {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(20px, 2.4vw, 40px) clamp(20px, 2.4vw, 40px);
}

.tile--a { grid-column: 1 / span 7; }
.tile--b { grid-column: 8 / span 5; align-self: end; }
.tile--c { grid-column: 1 / -1; margin-top: clamp(12px, 2vw, 40px); }

.tile__fig {
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--line);
}

.tile__fig img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.1s cubic-bezier(.16,.84,.28,1);
}
.tile:hover .tile__fig img { transform: scale(1.045); }

.tile--a .tile__fig { aspect-ratio: 7 / 6; }
.tile--b .tile__fig { aspect-ratio: 5 / 5.4; }
.tile--c .tile__fig { aspect-ratio: 16 / 7; }

.tile__meta {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-md);
}

.tile__t {
  font-size: clamp(1.25rem, 1.65vw, 1.5rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.tile__d {
  margin-top: 10px;
  color: var(--muted);
  font-size: 0.9375rem;
  max-width: 46ch;
}

/* --------------------------------------------------------------------------
   Marquee strips
   -------------------------------------------------------------------------- */

.marq {
  background: var(--ink);
  color: var(--bg);
  padding-block: clamp(26px, 3vw, 42px);
  overflow: hidden;
}

.marq__track {
  display: flex;
  width: max-content;
  gap: 0;
  animation: marq 34s linear infinite;
}

.marq__item {
  display: inline-flex;
  align-items: center;
  gap: 44px;
  padding-right: 44px;
  font-size: clamp(1.5rem, 3.1vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  white-space: nowrap;
}

.marq__dot {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--wash);
  flex: none;
}

@keyframes marq {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* --------------------------------------------------------------------------
   Tenant wall. Real marks only, no labels beneath.
   -------------------------------------------------------------------------- */

.tenants { background: var(--surface); }

.tenants__head { margin-bottom: clamp(40px, 4vw, 64px); }
.tenants__head .label { display: block; margin-bottom: 22px; }
.tenants__head .d2 { max-width: 21ch; }

.wall { overflow: hidden; }

.wall__track {
  display: flex;
  width: max-content;
  align-items: center;
  animation: marq 46s linear infinite;
}

.wall__logo {
  flex: none;
  width: clamp(150px, 15vw, 210px);
  height: 96px;
  display: grid;
  place-items: center;
  padding: 0 26px;
}

/*
 * Several supplied marks are JPEGs on a white ground. Multiplying them into the
 * off-white section removes the visible plate without editing the source files.
 */
.wall__logo img {
  max-height: 62px;
  max-width: 100%;
  width: auto;
  object-fit: contain;
  mix-blend-mode: multiply;
  filter: grayscale(1);
  opacity: .6;
  transition: filter .35s ease, opacity .35s ease;
}
.wall__logo:hover img { filter: grayscale(0); opacity: 1; }

/* --------------------------------------------------------------------------
   Contact. Dark ground, split composition.
   -------------------------------------------------------------------------- */

.contact {
  background: var(--ink);
  color: var(--bg);
}

.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(48px, 6vw, 110px);
  align-items: start;
}

.contact .d2 { color: var(--bg); max-width: 14ch; margin-bottom: 28px; }
.contact .body-copy { color: rgba(242, 242, 240, .72); margin-bottom: 38px; }

.contact__actions { display: flex; flex-wrap: wrap; gap: 12px; }

.people {
  display: grid;
  gap: 0;
}

.person {
  padding-block: 26px;
  border-top: 1px solid rgba(242, 242, 240, .18);
}
.person:last-of-type { border-bottom: 1px solid rgba(242, 242, 240, .18); }

.person__n {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.025em;
}

.person__r {
  font-size: 0.8125rem;
  color: rgba(242, 242, 240, .55);
  margin-top: 4px;
}

.person__c {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 26px;
  font-size: 0.9375rem;
  color: rgba(242, 242, 240, .8);
}
.person__c a:hover { color: var(--wash); }

.contact__addr {
  margin-top: 30px;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: rgba(242, 242, 240, .6);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.foot {
  background: var(--ink);
  color: rgba(242, 242, 240, .72);
  border-top: 1px solid rgba(242, 242, 240, .16);
  padding-block: clamp(56px, 6vw, 86px) 34px;
}

.foot__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 80px);
  padding-bottom: 46px;
}

.foot__logo img {
  height: 52px;
  width: auto;
  opacity: .95;
}

.foot__tag {
  margin-top: 20px;
  max-width: 30ch;
  font-size: 0.9375rem;
  color: rgba(242, 242, 240, .6);
}

.foot h4 {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(242, 242, 240, .45);
  margin-bottom: 20px;
}

.foot li + li { margin-top: 11px; }
.foot a { font-size: 0.9375rem; }
.foot a:hover { color: var(--bg); }

.foot__bar {
  border-top: 1px solid rgba(242, 242, 240, .16);
  padding-top: 26px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-sm);
  font-size: 0.8125rem;
  color: rgba(242, 242, 240, .5);
}

/* --------------------------------------------------------------------------
   Scroll reveal. Hidden only once JS has confirmed it is running, so the
   page renders fully visible without JS, for crawlers and for print.
   -------------------------------------------------------------------------- */

.js .reveal {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity .8s cubic-bezier(.16,.84,.28,1), transform .8s cubic-bezier(.16,.84,.28,1);
}
.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

.js .reveal[data-d='1'] { transition-delay: .08s; }
.js .reveal[data-d='2'] { transition-delay: .16s; }
.js .reveal[data-d='3'] { transition-delay: .24s; }
.js .reveal[data-d='4'] { transition-delay: .32s; }

/* --------------------------------------------------------------------------
   Responsive. Every multi-column layout collapses explicitly.
   -------------------------------------------------------------------------- */

@media (max-width: 1180px) {
  .nav { gap: 24px; }
  .cap { grid-template-columns: 64px minmax(0, 1fr) minmax(0, 1fr); }
}

@media (max-width: 1024px) {
  :root { --gutter: 28px; }

  .nav, .hdr__cta { display: none; }
  .burger { display: flex; }

  .nav--open {
    display: flex;
    position: fixed;
    inset: 0;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 8px;
    padding: var(--gutter);
    background: var(--bg);
    z-index: 55;
  }
  .nav--open a {
    color: var(--ink);
    font-size: 2rem;
    font-weight: 600;
    letter-spacing: -0.035em;
    padding-block: 10px;
  }
  .nav--open a::after { display: none; }
  .nav--open > .btn {
    display: inline-flex;
    margin-top: 24px;
    font-size: 0.9375rem;
    color: var(--bg);
    background: var(--ink);
    border-color: var(--ink);
  }

  .hero__in { grid-template-columns: minmax(0, 1fr); gap: var(--sp-md); }
  .hero__call { text-align: left; }

  .stats__grid { grid-template-columns: repeat(2, 1fr); gap: 40px 0; }
  .stat:nth-child(3) { border-left: 0; padding-left: 0; }

  .about__grid { grid-template-columns: minmax(0, 1fr); }
  .about__media { margin-right: calc(50% - 50vw); padding-bottom: 70px; }
  .about__media-inset { left: 0; width: 42%; }

  .build__head { flex-direction: column; align-items: flex-start; gap: var(--sp-md); }

  /* Copy moves above the drawing, and the drawing zooms in on the massing so
     it still reads at phone width instead of shrinking to a smudge. */
  .gu {
    display: flex;
    flex-direction: column;
    padding-bottom: 0;
  }

  .gu__overlay {
    position: static;
    display: block;
    order: 1;
  }

  .gu__copy {
    width: auto;
    max-width: none;
  }
  .gu__copy .body-copy { max-width: 60ch; }

  .gu__stage {
    order: 2;
    overflow: hidden;
    margin-top: 36px;
  }
  /* max-width has to be released here, or the global svg reset caps the zoom. */
  .gu__stage svg { width: 200%; max-width: none; margin-left: -78%; }

  .tile--a, .tile--b, .tile--c { grid-column: 1 / -1; margin-top: 0; }
  .tile--a .tile__fig,
  .tile--b .tile__fig,
  .tile--c .tile__fig { aspect-ratio: 4 / 3; }

  .contact__grid { grid-template-columns: minmax(0, 1fr); }

  .foot__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foot__brand { grid-column: 1 / -1; }
}

@media (max-width: 720px) {
  :root { --gutter: 20px; }

  body.ie-page { font-size: 16px; }

  .hero { min-height: 92svh; }
  .hero__in { padding-top: 120px; }
  .hero .d1 { max-width: 100%; }
  .hero .lede { max-width: 100%; }
  .hero__actions .btn { flex: 1 1 auto; justify-content: center; }

  .stats__grid { grid-template-columns: minmax(0, 1fr); gap: 34px; }
  .stat { border-left: 0; padding-left: 0; padding-bottom: 30px; border-bottom: 1px solid var(--line); }
  .stat:last-child { border-bottom: 0; padding-bottom: 0; }

  .cap { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .cap__n { order: -1; }

  .about__media-inset { position: static; width: 60%; margin-top: 18px; }
  .about__media { padding-bottom: 0; }
  .about__media-cap { position: static; margin-top: 16px; padding-right: var(--gutter); }

  .tile__meta { flex-direction: column; gap: 10px; }

  .foot__grid { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Reduced motion. Everything collapses to the finished state.
   -------------------------------------------------------------------------- */

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

  .js .reveal,
  .js .reveal.is-in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  .marq__track,
  .wall__track { animation: none; }

  .hero__media img,
  .js .hero--in .hero__media img { transform: none; transition: none; }

  /* The headline settles on the first word and the video never loads. */
  .hero__word { animation: none !important; opacity: 0 !important; transform: none !important; }
  .hero__word:first-child { opacity: 1 !important; }
  .hero__video { display: none !important; }

  .tile:hover .tile__fig img { transform: none; }

  *, *::before, *::after { transition-duration: .01ms !important; }
}

/* Keyboard focus stays visible everywhere. */
.ie-page a:focus-visible,
.ie-page button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
.hdr--over a:focus-visible,
.contact a:focus-visible,
.foot a:focus-visible {
  outline-color: var(--wash);
}

/* ==========================================================================
   Five-section layout
   The page is five full-screen views that step one at a time. This block is
   last in the file on purpose: it settles every specificity tie in its favour.
   ========================================================================== */

/* One screen per section is the homepage's behaviour. Interior pages scroll
   normally, so the snap container is scoped to the landing body. */
html:has(body.ie-landing) {
  scroll-snap-type: y mandatory;
}

.snap {
  scroll-snap-align: start;
  /* Stops a single flick from skipping a whole view. */
  scroll-snap-stop: always;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* A view taller than the screen still scrolls normally inside itself, so
   nothing is ever cut off; it just starts flush with the top. */
.snap > * { flex: none; }

/* The footer trails the last view rather than claiming a screen of its own. */
.foot { scroll-snap-align: none; }

/* --------------------------------------------------------- 1. hero + stats */

.hero {
  justify-content: flex-end;
  min-height: 100svh;
}

/*
 * Each view is already a screen tall, so the old standing section padding is
 * redundant. The top value is a floor rather than a clamp, because a snapped
 * section aligns its top with the viewport top and the fixed header would
 * otherwise sit straight over the heading.
 */
.snap.section {
  padding-top: max(148px, 12svh);
  padding-bottom: clamp(40px, 6svh, 88px);
}

.close__tenants { padding-top: max(144px, 11svh); }

.hero__body {
  width: 100%;
  padding-top: clamp(132px, 17svh, 172px);
  padding-bottom: clamp(22px, 3svh, 42px);
}

.hero .d1 { margin-bottom: clamp(16px, 2.4svh, 26px); }
.hero .lede { margin-bottom: clamp(20px, 3.2svh, 34px); }

.hero__in {
  padding-top: 0;
  padding-bottom: 0;
}

.hero__stats {
  margin-top: clamp(22px, 4svh, 46px);
  padding-top: clamp(16px, 2.4svh, 28px);
  border-top: 1px solid rgba(242, 242, 240, .24);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-md);
}

.hero__stats .stat {
  padding: 0 0 0 26px;
  border-left: 1px solid rgba(242, 242, 240, .2);
  border-bottom: 0;
}
.hero__stats .stat:first-child { border-left: 0; padding-left: 0; }

.hero__stats .stat__n {
  font-size: clamp(1.5rem, 2.5vw, 2.5rem);
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--bg);
}

.hero__stats .stat__l {
  margin-top: 10px;
  font-size: 0.8125rem;
  line-height: 1.35;
  color: rgba(242, 242, 240, .64);
  max-width: 20ch;
}

/* ------------------------------------------------- 4. what we build */

.build__head {
  display: block;
  margin-bottom: clamp(30px, 3.4vw, 52px);
}
.build__head .d2 { max-width: 20ch; margin-bottom: 22px; }
.build__head .body-copy { max-width: 56ch; }

/*
 * The drawing carries its own open left third, so the heading and copy sit in
 * it rather than stacking above and costing the view another 300px of height.
 */
.build__stage {
  position: relative;
  margin-bottom: clamp(26px, 3.4svh, 48px);
}

.build .gu__stage { margin-bottom: 0; }
.build .gu__stage svg { height: clamp(230px, 40svh, 440px); width: 100%; }

.build .gu__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  pointer-events: none;
}
.build .gu__copy { pointer-events: auto; }

.build__lead {
  display: block;
  padding-bottom: 18px;
  margin-bottom: clamp(24px, 2.6vw, 36px);
  border-bottom: 1px solid var(--line);
}

/* Three in a row, image first, caption below. Still not card containers. */
.tiles {
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 2.4vw, 36px);
}

.tiles .tile { grid-column: auto; margin-top: 0; align-self: start; }
.tiles .tile__fig { aspect-ratio: 16 / 10; }

.tile__meta { margin-top: 18px; padding-top: 16px; }
.tile__t { font-size: clamp(1.125rem, 1.4vw, 1.375rem); }
.tile__d { margin-top: 10px; max-width: 38ch; }

/* The linework draw-in moved with the drawing into this section. */
.js .build .ms-edges path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.5s cubic-bezier(.16, .84, .28, 1);
}
.js .build .ms-edges[data-b="1"] path { transition-delay: .16s; }
.js .build .ms-edges[data-b="2"] path { transition-delay: .32s; }
.js .build .ms-edges[data-b="3"] path { transition-delay: .48s; }

.js .build .ms-ground,
.js .build .ms-ghost,
.js .build .ms-fills,
.js .build .ms-detail,
.js .build .ms-trees {
  opacity: 0;
  transition: opacity 1.1s ease .35s;
}

/* Trim the two heaviest views so each sits closer to a single screen without
   losing any copy: cap the map, and tighten the capability rows. */
.about .about__media-main img {
  max-height: 46svh;
  width: 100%;
  object-fit: cover;
}

.snap .cap { padding-block: clamp(18px, 2.6svh, 34px); }

/* ----------------------------------------- 5. tenants and contact, one view */

.close {
  padding: 0;
  justify-content: center;
}

.close__tenants {
  background: var(--surface);
  /* Floor, not a clamp: this is the snapped top edge, under the fixed header. */
  padding-top: max(104px, 8svh);
  padding-bottom: clamp(36px, 4.4svh, 64px);
}

.close__tenants .tenants__head { margin-bottom: clamp(26px, 3vw, 44px); }
.close__tenants .tenants__head .d3 { max-width: 26ch; }

.close__tenants .wall__logo { height: 78px; }
.close__tenants .wall__logo img { max-height: 50px; }

.close__contact {
  background: var(--ink);
  color: var(--bg);
  padding-block: clamp(48px, 5.4vw, 88px);
}

/* ---------------------------------------------------------------- mobile */

@media (max-width: 1024px) {
  .hero__stats { grid-template-columns: repeat(2, 1fr); gap: 22px var(--sp-md); }
  .hero__stats .stat:nth-child(3) { border-left: 0; padding-left: 0; }

  /*
   * Stacked, the three blocks cost well over a screen on their own. As a
   * swipe row they stay one row, keep all three, and the view stays short.
   */
  .tiles {
    display: flex;
    grid-template-columns: none;
    gap: 14px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    margin-inline: calc(50% - 50vw);
    padding-inline: var(--gutter);
  }
  .tiles::-webkit-scrollbar { display: none; }

  .tiles .tile {
    flex: 0 0 76%;
    scroll-snap-align: start;
  }
  .tiles .tile__fig { aspect-ratio: 4 / 3; }
  .tiles .tile__d { max-width: none; }

  /* The map cluster is the tallest thing in the About view. */
  .about .about__media { padding-bottom: 0; }
  .about .about__media-main img { max-height: 34svh; }
  .about .about__media-inset { width: 48%; }

  /* Copy above the drawing once the drawing's open side is too narrow to
     hold it, and the drawing zooms in on the massing. */
  .build__stage { display: flex; flex-direction: column; }
  .build .gu__overlay { position: static; display: block; order: 1; }
  .build .gu__copy { width: auto; max-width: none; }
  .build .gu__stage { order: 2; overflow: hidden; margin-top: 28px; }
  .build .gu__stage svg { width: 200%; max-width: none; height: auto; margin-left: -78%; }
}

@media (max-width: 720px) {
  .hero__body { padding-top: 112px; }

  .hero__stats {
    margin-top: 26px;
    padding-top: 18px;
    grid-template-columns: repeat(2, 1fr);
    gap: 18px 16px;
  }
  .hero__stats .stat {
    padding: 0;
    border-left: 0;
    border-bottom: 0;
  }
  .hero__stats .stat__n { font-size: 1.375rem; }
  .hero__stats .stat__l { font-size: 0.75rem; margin-top: 6px; }
}

/* ==========================================================================
   Revisions
   ========================================================================== */

/*
 * The footer was unreachable: it had no snap position, so mandatory snapping
 * pulled the page back to the last section every time. Aligning it to the end
 * of the scrollport makes it a real stop.
 */
.ie-landing .foot {
  scroll-snap-align: end;
  scroll-snap-stop: normal;
}

.build__title { margin-bottom: clamp(26px, 4svh, 48px); max-width: 26ch; }

@media (max-width: 900px) {
  /* The logo steps down on phones, so the clearance can be smaller than desktop
     but still has to clear a taller bar than before. */
  .hdr { padding-block: 18px; }
  .hdr--stuck { padding-block: 14px; }
  .hdr__logo img { height: 54px; }
  .hdr--stuck .hdr__logo img { height: 46px; }

  .snap.section { padding-top: max(116px, 9svh); }
  .close__tenants { padding-top: max(112px, 9svh); }
  .hero__body { padding-top: clamp(112px, 14svh, 140px); }

  /* 1. Hero: the number lives in the header call to action and the footer,
     so dropping it here buys the view its last 90px. */
  .hero__call { display: none; }

  /* 2. About: the two maps are the whole reason this view overflowed. */
  .about .about__media { display: none; }

  .about__head .d2 { font-size: clamp(1.5rem, 6.4vw, 2rem); margin-bottom: 18px; }
  .about .body-copy { font-size: 0.9375rem; line-height: 1.5; }
  .about .body-copy + .body-copy { margin-top: .7em; }
  .about .tags { margin-top: 20px; padding-top: 16px; gap: 6px; }
  .about .tag { padding: 6px 12px; font-size: 0.75rem; }

  /* 3. Capabilities: the index moves inline with the title so each row is two
     tight lines instead of three, which is what fits six of them on a phone. */
  .caps__head { margin-bottom: clamp(16px, 2.4svh, 28px); }
  .caps__head .d2 { font-size: clamp(1.5rem, 6.4vw, 2rem); }

  .snap .cap {
    grid-template-columns: 34px minmax(0, 1fr);
    gap: 3px 10px;
    padding-block: clamp(9px, 1.5svh, 16px);
    align-items: baseline;
  }
  .cap__n { order: 0; font-size: 0.6875rem; }
  .cap__t { grid-column: 2; font-size: 1.0625rem; line-height: 1.2; }
  .cap__d { grid-column: 2; font-size: 0.8125rem; line-height: 1.4; max-width: none; }
}

/* --------------------------------------------------------------- header type
 *
 * The bar lives in two states and they need opposite treatments. Over the hero
 * it sits on dark footage, so the links take the pale blue from the headline
 * and carry a halo. Once it sticks, the ground is off-white: a glow there would
 * read as a blur, so the links switch to the brand accent instead, which has
 * roughly 9:1 contrast on that ground.
 */
.nav a { font-weight: 700; }
.hdr .btn { font-weight: 700; }

/*
 * A dedicated scrim behind the bar. Without it the nav sits over whatever the
 * video happens to be showing, and a pale blue over a bright sky fails.
 *
 * It fades on the same curve as the stuck background rather than switching
 * instantly, otherwise the scrim disappears while the light background is still
 * fading in and the links spend a third of a second dark-on-dark.
 */
.hdr::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom, rgba(var(--ink-rgb), .62), rgba(var(--ink-rgb), 0));
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
}
.hdr--over::before { opacity: 1; }

/* Cross-fade the label colours on the same timing for the same reason. */
.nav a,
.hdr .btn { transition: color .35s ease, background-color .28s ease, border-color .35s ease, transform .12s ease; }

.hdr--over .nav a {
  color: var(--wash);
  text-shadow:
    0 0 22px rgba(147, 175, 217, .6),
    0 0 8px rgba(147, 175, 217, .45),
    0 1px 14px rgba(14, 27, 51, .7);
}
.hdr--over .nav a::after { background: var(--wash); }
.hdr--over .nav a:hover { color: #FFFFFF; }

.hdr--stuck .nav a {
  color: var(--accent);
  text-shadow: none;
}
.hdr--stuck .nav a::after { background: var(--accent); }
.hdr--stuck .nav a:hover { color: var(--ink); }

/* Mandatory snapping is a scroll behaviour change, so it steps aside for
   anyone who has asked for reduced motion. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; }
  .snap { scroll-snap-stop: normal; }

  .js .build .ms-edges path { stroke-dashoffset: 0 !important; transition: none !important; }
  .js .build .ms-ground,
  .js .build .ms-ghost,
  .js .build .ms-fills,
  .js .build .ms-detail,
  .js .build .ms-trees { opacity: 1 !important; transition: none !important; }
}

/* ==========================================================================
   Interior pages
   About, Sites and Contact. Same tokens, same buttons, same rules as the
   homepage. No snapping: these pages are ordinary documents.
   ========================================================================== */

.ie-interior main { display: block; }

/* A label with the short leading rule the interior pages already used. */
.ilabel {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 26px;
}
.ilabel::before {
  content: '';
  width: 42px;
  height: 1px;
  background: currentColor;
  opacity: .75;
  flex: none;
}

/* ------------------------------------------------------------ hero */

.ihero {
  position: relative;
  background: var(--ink);
  color: var(--bg);
  overflow: hidden;
  isolation: isolate;
}

.ihero__media { position: absolute; inset: 0; z-index: -2; }
.ihero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; }

.ihero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(90deg, rgba(var(--ink-rgb), .94) 0%, rgba(var(--ink-rgb), .84) 40%, rgba(var(--ink-rgb), .58) 78%, rgba(var(--ink-rgb), .5) 100%),
    linear-gradient(180deg, rgba(var(--ink-rgb), .6) 0%, rgba(var(--ink-rgb), .28) 45%, rgba(var(--ink-rgb), .72) 100%);
}

.ihero__in {
  padding-top: max(190px, 21svh);
  padding-bottom: clamp(58px, 9svh, 118px);
}

.ihero .ilabel { color: var(--wash); }

.ihero .d1 {
  color: #FFFFFF;
  max-width: 17ch;
  margin-bottom: clamp(18px, 2.6svh, 28px);
  text-shadow: 0 2px 24px rgba(14, 27, 51, .5);
}
.ihero .d1 em { color: var(--wash); }

.ihero .lede {
  color: rgba(242, 242, 240, .82);
  max-width: 58ch;
  margin-bottom: clamp(24px, 3.4svh, 40px);
}

.ihero__actions { display: flex; flex-wrap: wrap; gap: 12px; }

.ihero__meta {
  margin-top: 18px;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  color: rgba(242, 242, 240, .55);
}

/* --------------------------------------------------------- sections */

.iband { padding-block: clamp(72px, 9vw, 132px); }
.iband--ink { background: var(--ink); color: var(--bg); }
.iband--surface { background: var(--surface); }

.iband__head { margin-bottom: clamp(40px, 4.6vw, 72px); }
.iband__head .d2 { max-width: 20ch; }
.iband__head .body-copy { margin-top: 24px; }

.iband--ink .d2 { color: var(--bg); }
.iband--ink .body-copy { color: rgba(242, 242, 240, .72); }
.iband--ink .ilabel { color: var(--wash); }

/* Split intro: heading left, supporting copy right. */
.isplit {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
}

/* ------------------------------------------------------------ cards */

.icards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3vw, 52px);
}

.icard { border-top: 1px solid var(--line); padding-top: 22px; }
.iband--ink .icard { border-top-color: rgba(242, 242, 240, .2); }

.icard__t {
  font-size: clamp(1.125rem, 1.5vw, 1.375rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.15;
  margin-bottom: 12px;
}
.icard__d { color: var(--muted); font-size: 0.9375rem; max-width: 40ch; }
.iband--ink .icard__d { color: rgba(242, 242, 240, .66); }

/* ----------------------------------------------------------- listing */

.ilisting {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: center;
  border-top: 1px solid var(--line);
  padding-top: clamp(28px, 3.4vw, 48px);
}

.ilisting__fig { overflow: hidden; border-radius: var(--r-md); background: var(--line); }
.ilisting__fig img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4 / 3; transition: transform 1.1s cubic-bezier(.16,.84,.28,1); }
.ilisting:hover .ilisting__fig img { transform: scale(1.04); }

.ilisting .d3 { margin: 14px 0 18px; }

.ifacts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }

/* -------------------------------------------------------------- form */

.iform { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.iform label { display: flex; flex-direction: column; gap: 9px; }
.iform .wide { grid-column: span 2; }

.iform input,
.iform textarea {
  font-family: var(--font);
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid rgba(var(--ink-rgb), .22);
  border-radius: var(--r-sm);
  padding: 15px 16px;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.iform textarea { resize: vertical; min-height: 150px; }

.iform input::placeholder,
.iform textarea::placeholder { color: rgba(92, 104, 128, .7); }

.iform input:focus,
.iform textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(36, 69, 127, .16);
}

.iform__submit { grid-column: span 2; margin-top: 6px; }

/* ---------------------------------------------------------- responsive */

@media (max-width: 1024px) {
  .isplit { grid-template-columns: minmax(0, 1fr); }
  .icards { grid-template-columns: repeat(2, 1fr); }
  .ilisting { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
  .ihero__in { padding-top: max(150px, 18svh); }
  .ihero .d1 { max-width: 100%; }
  .ihero__actions .btn { flex: 1 1 auto; justify-content: center; }

  .icards { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .iform { grid-template-columns: minmax(0, 1fr); }
  .iform .wide, .iform__submit { grid-column: span 1; }
  .iform__submit .btn { width: 100%; justify-content: center; }
}

/* A hero with no photograph behind it, used on the contact page. */
.ihero--plain .ihero__in { padding-top: max(170px, 19svh); padding-bottom: clamp(48px, 7svh, 96px); }

/* Contact detail stack. */
.idetails { display: grid; gap: clamp(24px, 3vw, 40px); }
.idetail { border-top: 1px solid var(--line); padding-top: 20px; }
.idetail .label { display: block; margin-bottom: 12px; }
.idetail__v { font-size: 1.0625rem; line-height: 1.5; color: var(--ink); }
.idetail__v + .idetail__v { margin-top: 8px; }
.idetail__v a:not(.btn):hover { color: var(--accent); }
.idetail__v .btn { margin-top: 8px; }

/* The listing block is a single link, so its inner button is decorative. */
.ilisting { color: inherit; }
.ilisting__more { margin-top: 26px; }
.ilisting .btn { pointer-events: none; }
.ilisting:hover .btn--ghost { border-color: var(--ink); background: rgba(var(--ink-rgb), .05); }

@media (max-width: 1024px) {
  .idetails { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 720px) {
  .idetails { grid-template-columns: minmax(0, 1fr); }
}
