/* Montserrat, self hosted, so the page asks nothing of Google.

   These are Google's own @font-face blocks for the latin and latin-ext subsets, with only the url()
   changed to the files in fonts/. Those woff2 files are the ones the browser used to fetch from
   fonts.gstatic.com, so the metrics are identical and nothing shifts. The page's own accents (the ä
   of Zählerweg, the á of Fernández, the í of Díaz) all sit inside latin; latin-ext is kept for
   anything beyond it, and a browser only downloads the subsets a page actually uses.
   Google hands out the same variable file for every upright weight, so the upright faces are one
   file per subset declared over the whole weight range, fetched once. The two italics are separate
   static files (300 and 400).
   Licence: fonts/OFL.txt. */

/* latin-ext */
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/montserrat-400-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;
}

/* latin */
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/montserrat-400-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;
}

/* latin-ext */
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(fonts/montserrat-300-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;
}

/* latin */
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(fonts/montserrat-300-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;
}

/* latin-ext, every upright weight: one variable file (its weight axis runs 200 to 600) */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 200 600;
  font-display: swap;
  src: url(fonts/montserrat-normal-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;
}

/* latin, every upright weight: the same variable file for the latin subset */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 200 600;
  font-display: swap;
  src: url(fonts/montserrat-normal-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;
}

/* Natus AG
   Near-black and off-white bands, full-bleed photography,
   Montserrat in wide-tracked capitals, one steel accent. */

:root {
  color-scheme: light;

  --ink: #0F1012;
  --paper: #FAFAF8;
  --stone: #EFEFEC;         /* the Projects band: a quiet step down from paper */
  --text: #2A2C30;          /* body on paper, 13.4:1 */
  --muted: #5C6066;         /* secondary on paper, 6.0:1 */
  --on-dark: #FAFAF8;
  --on-dark-muted: #E2E3E5;
  --accent: #3E5A6E;        /* steel blue-grey from the hero sea, 6.9:1 on paper */
  --accent-on-dark: #9AB0BF;/* same hue, lifted for dark grounds */

  --font: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --nav-h: 64px;
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --max: 80rem;
  --radius: 0;

  --track-display: 0.16em;
  --track-heading: 0.12em;
  --track-small: 0.16em;
}

@media (min-width: 900px) {
  :root { --nav-h: 80px; }
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--ink);
  scrollbar-color: #8A8E94 var(--paper);
}

/* In-page links glide to their section; instant where motion is reduced */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* Every menu target lands below the fixed bar, never under it */
#natus,
#projects,
#team,
#impact,
#contact {
  scroll-margin-top: var(--nav-h);
}

/* A control that receives keyboard focus is scrolled clear of the fixed bar,
   with room for its focus ring, and up from the foot of the screen. (Text
   fields scroll by their caret instead, so contact.js looks after those.) */
:where(a[href], button, summary, input, textarea) {
  scroll-margin-top: calc(var(--nav-h) + 1rem);
  scroll-margin-bottom: 15vh;
}

/* A section that receives focus after a menu jump shows no ring of its own;
   its links and controls keep theirs */
[data-nav-target]:focus { outline: none; }

body {
  margin: 0;
  font-family: var(--font);
  font-weight: 400;
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.125rem);
  line-height: 1.7;
  color: var(--text);
  background: var(--paper);
  caret-color: var(--accent);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-kerning: normal;
}

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

h1, h2, p, figure, blockquote, ul { margin: 0; padding: 0; }
ul { list-style: none; }
address { font-style: normal; }

a { color: inherit; }

::selection { background: var(--accent); color: var(--paper); }

:focus-visible {
  outline: 2px solid var(--ring, var(--accent));
  outline-offset: 4px;
  border-radius: var(--radius);
}

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

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link */
.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--paper);
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus-visible { transform: none; }

/* ------------------------------------------------------------------
   Header
   Transparent over the hero, a solid off-white bar once the hero has
   scrolled away. Colours flip through filter: invert(), so the change
   animates on filter and opacity only.
   ------------------------------------------------------------------ */

/* Fixed at every scroll position. Without JS nothing tracks the hero, so
   the bar is solid from the start and stays legible over every band. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  height: var(--nav-h);
  color: var(--ink);
}

.site-header::before {
  content: "";
  position: absolute;
  /* 2px over the top edge: at a fractional scroll position Firefox can
     otherwise leave the top device pixel row uncovered */
  inset: -2px 0 0;
  background: var(--paper);
  box-shadow: 0 1px 0 rgba(15, 16, 18, 0.08);
  opacity: 0;
}

.site-header__bar {
  position: relative;
  height: 100%;
  max-width: calc(var(--max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  filter: invert(1);
  --ring: var(--ink);
}

.site-header.is-ready::before { transition: opacity 0.5s var(--ease-out); }
.site-header.is-ready .site-header__bar { transition: filter 0.5s var(--ease-out); }

:root:not(.js) .site-header::before,
.site-header.is-solid::before,
.site-header.is-menu-open::before { opacity: 1; }

:root:not(.js) .site-header__bar,
.site-header.is-solid .site-header__bar,
.site-header.is-menu-open .site-header__bar {
  filter: invert(0);
  --ring: var(--accent);
}

.brand {
  display: flex;
  flex: none;
  align-items: center;
  min-height: 44px;
}
/* The wordmark is set by width; its height follows from 683 x 104 */
.brand img { width: 118px; }

@media (min-width: 900px) {
  .brand img { width: 144px; }
}

/* The wordmark is a black image. A forced-colours theme repaints the bars with its own
   Canvas colour but leaves images alone, so on a dark theme the solid bar would hide it. Turn it
   to the theme's contrast (the footer's own case sits with the footer rules). */
@media (forced-colors: active) and (prefers-color-scheme: dark) {
  :root:not(.js) .brand img,
  .site-header.is-solid .brand img,
  .site-header.is-menu-open .brand img { filter: invert(1); }
}

.site-nav { display: none; }

@media (min-width: 900px) {
  .site-nav { display: block; }
  .site-nav ul {
    display: flex;
    align-items: center;
    gap: clamp(1.75rem, 3vw, 2.75rem);
  }
}

.site-nav a,
.menu a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: var(--track-small);
  text-transform: uppercase;
  text-decoration: none;
}

.site-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: var(--track-small);
  bottom: 0.625rem;
  height: 1px;
  background: currentColor;
  opacity: 0.35;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s var(--ease-out), opacity 0.3s var(--ease-out);
}

/* Hover draws a faint line; only the section in view (and keyboard focus)
   carries the full one, so a resting pointer never reads as a second
   current item */
.site-nav a:hover::after { transform: scaleX(1); }

.site-nav a:focus-visible::after,
.site-nav a[aria-current="true"]::after {
  transform: scaleX(1);
  opacity: 1;
}

/* Menu button (below 900px) */
.menu-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 44px;
  min-height: 44px;
  margin-right: -0.5rem;
  padding: 0 0.5rem;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: var(--track-small);
  text-transform: uppercase;
  cursor: pointer;
}

.menu-toggle__icon { fill: none; stroke: currentColor; stroke-width: 1.5; }
.menu-toggle__line { transform-origin: 12px 12px; transition: transform 0.45s var(--ease-out); }
.is-menu-open .menu-toggle__line--top { transform: translateY(3px) rotate(45deg); }
.is-menu-open .menu-toggle__line--bottom { transform: translateY(-3px) rotate(-45deg); }

@media (min-width: 900px) {
  .menu-toggle { display: none; }
}

/* Only main.js opens the menu; without it the button would do nothing */
:root:not(.js) .menu-toggle { display: none; }

/* Mobile menu sheet */
.menu {
  position: fixed;
  inset: var(--nav-h) 0 0;
  z-index: -1;
  padding: 2rem var(--gutter) 3rem;
  background: var(--paper);
  color: var(--ink);
  overflow-y: auto;
  visibility: hidden;
  opacity: 0;
  transform: translateY(-0.75rem);
  transition:
    opacity 0.35s var(--ease-out),
    transform 0.5s var(--ease-out),
    visibility 0s linear 0.5s;
}

.is-menu-open .menu {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

.menu li { border-bottom: 1px solid rgba(15, 16, 18, 0.1); }
.menu a {
  display: flex;
  align-items: center;
  min-height: 4rem;
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: var(--track-heading);
  scroll-margin-block: 0.75rem;
}

/* Landscape phones: five rows of 3rem fit under the bar, targets stay 48px */
@media (orientation: landscape) and (max-height: 30rem) {
  .menu { padding-block: 0.5rem 1rem; }
  .menu a { min-height: 3rem; }
}

/* The section in view: the steel underline the page's links carry */
.menu a[aria-current="true"] {
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--accent);
  text-underline-offset: 0.55em;
}

@media (min-width: 900px) {
  .menu { display: none; }
}

html.is-locked { overflow: hidden; }

/* ------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------ */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  align-items: start;
  justify-items: center;
  padding-inline: var(--gutter);
  /* The photograph is placed so the far shore always falls at 62.8% of
     the hero's height; the words start one calm step below it, on the
     dark water */
  padding-block: calc(62.8svh + clamp(1.75rem, 6svh, 3.5rem)) 2.5rem;
  overflow: clip;
  background: var(--ink);
  color: var(--on-dark);
  color-scheme: dark;
  --ring: var(--on-dark);
}

.hero__media {
  position: absolute;
  /* a 2px overscan on each side hides the subpixel seam of the scaled
     photograph; .hero clips it */
  inset: 0 -2px;
  overflow: clip;
}

.hero__media img {
  /* 16% taller than the hero and anchored to its foot: the empty top of
     the sky is trimmed so the lake gets the lower third for the words.
     On portrait screens the crop centres on the jagged peaks. */
  position: absolute;
  inset: auto 0 0;
  width: 100%;
  height: 116%;
  object-fit: cover;
  object-position: 46% 56%;
  transform-origin: 50% 62%;
  filter: saturate(0.9);
}

/* Top scrim: deep enough that the transparent links hold AA over the
   paling sky until the bar turns solid */
.hero__media::after {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0 0 auto;
  height: clamp(10rem, 30svh, 17rem);
  background: linear-gradient(
    to bottom,
    rgba(15, 16, 18, 0.56) 0%,
    rgba(15, 16, 18, 0.46) 40%,
    rgba(15, 16, 18, 0.2) 72%,
    rgba(15, 16, 18, 0) 100%
  );
}

/* Bottom scrim: deepens the lake under the words and leaves the dusk
   sky untouched; together with the dark water it holds white type
   above AA */
.hero__media::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: auto 0 0;
  height: 62%;
  background: linear-gradient(
    to top,
    rgba(15, 16, 18, 0.62) 0%,
    rgba(15, 16, 18, 0.46) 38%,
    rgba(15, 16, 18, 0.16) 72%,
    rgba(15, 16, 18, 0) 100%
  );
}

/* Darkening layer driven by scroll; invisible at rest */
.hero__shade {
  position: absolute;
  inset: 0;
  background: var(--ink);
  opacity: 0;
  pointer-events: none;
}

.hero__content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 76rem;
  text-align: center;
}

/* IMPACT INVESTMENTS: one line from tablet up, sized to the viewport so
   it always keeps a margin; two stacked words on phones */
.hero__title {
  --track: 0.12em;
  font-weight: 300;
  font-size: clamp(1.875rem, 0.25rem + 8.6vw, 2.75rem);
  line-height: 1.16;
  letter-spacing: var(--track);
  /* balance the trailing tracking so the caps sit on true centre */
  padding-left: var(--track);
  text-wrap: balance;
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
}

@media (min-width: 700px) {
  .hero__title {
    --track: var(--track-display);
    font-size: clamp(2.25rem, 0.25rem + 5vw, 4.5rem);
    line-height: 1.12;
    white-space: nowrap;
  }
}

.hero__standfirst {
  max-width: 38em;
  margin: clamp(1.25rem, 2.2vw, 1.75rem) auto 0;
  font-size: clamp(1rem, 0.9rem + 0.45vw, 1.25rem);
  font-weight: 400;
  line-height: 1.6;
  color: var(--on-dark);
  text-wrap: balance;
}

@media (orientation: landscape) and (max-height: 30rem) {
  .hero { padding-block: calc(62.8svh + 0.75rem) 1rem; }
  .hero__standfirst { margin-top: 0.625rem; }
}

/* Phones held upright: the title stacks in two lines and the standfirst runs to three, more
   than the lake below a shore at 62.8% can hold once the browser's own bars take their share of
   the screen (an iPhone in Safari gives the page about 390x664, an iPhone SE 375x548). So the
   photograph is taken in closer, trimming only empty sky: the shore rises to 56%, the peaks come
   to the middle of the screen, and the words sit on the lake with room to spare. As a floor, the
   words never start lower than their own height (two title lines, up to four standfirst lines)
   plus the bottom margin allows, so on the smallest screens they rise instead of running off. */
@media (orientation: portrait) and (max-width: 699.98px) {
  .hero {
    --hero-gap: clamp(1.25rem, 4svh, 2.5rem);
    --hero-foot: max(2.5rem, 6svh);
    --hero-words: calc(2.32 * clamp(1.875rem, 0.25rem + 8.6vw, 2.75rem) + 1.25rem
                       + 6.4 * clamp(1rem, 0.9rem + 0.45vw, 1.25rem));
    padding-block:
      min(56svh + var(--hero-gap), 100svh - var(--hero-words) - var(--hero-foot))
      var(--hero-foot);
  }

  /* 137% tall and anchored to the foot puts the far shore at 56% of the hero */
  .hero__media img { height: 137%; }
}

/* On those phones the photograph arrives as its own tall crop (index.html, the <source> with the
   same media query), cut from the full-resolution original around the slice a phone shows. The
   crop is centred on that slice, so it is framed from its centre; its full height keeps the shore
   at 56% as above. */
@media (orientation: portrait) and (max-width: 699.98px) and (max-aspect-ratio: 3/4) {
  .hero__media img { object-position: 50% 56%; }
}

/* Under 700px wide the title stacks in two lines, which a landscape phone has no room for:
   there it takes the one-line setting of the wider screens, sized to fit (568x320, 640x360) */
@media (orientation: landscape) and (max-height: 30rem) and (max-width: 699.98px) {
  .hero__title {
    --track: var(--track-display);
    font-size: min(2.25rem, 5.6vw);
    line-height: 1.12;
    white-space: nowrap;
  }
}

/* The bar turns solid after a short scroll, while the links still sit
   inside the top scrim and long before the pale sky reaches them */
.hero__sentinel {
  position: absolute;
  left: 0;
  top: 8%;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

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

.why__band {
  background: var(--paper);
  color: var(--text);
  color-scheme: light;
  padding-block: clamp(6rem, 11vw, 10rem);
}

.why__grid {
  display: grid;
  gap: clamp(3.5rem, 8vw, 5rem);
}

.why__title {
  max-width: 17em;
  margin-bottom: clamp(2rem, 3.5vw, 3rem);
  font-weight: 300;
  font-size: clamp(1.375rem, 0.95rem + 1.7vw, 2.375rem);
  line-height: 1.38;
  letter-spacing: var(--track-heading);
  text-transform: uppercase;
  color: var(--ink);
  text-wrap: balance;
}

.why__text p {
  max-width: 36em;
  text-wrap: pretty;
}

.why__text p + p { margin-top: 1.25em; }

.why__figure {
  position: relative;
  overflow: clip;
  aspect-ratio: 4 / 5;
  max-width: 100%;
  background: #D8DADB;
  border-radius: var(--radius);
}

.why__figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* keeps the lit vanishing point and the lone figure in frame */
  object-position: 50% 62%;
}

@media (min-width: 960px) {
  /* The Natus link lands the band right under the fixed bar; the bar's
     height comes out of the top padding, so the photograph and words
     still sit on the middle of a 900px screen */
  .why__band {
    padding-top: calc(clamp(6rem, 11vw, 10rem) - var(--nav-h));
  }

  .why__grid {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    column-gap: clamp(4rem, 8vw, 8rem);
    align-items: center;
  }

  .why__figure {
    aspect-ratio: 3 / 4;
  }

  .why__figure img { object-position: 50% 58%; }
}

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

.quote {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(30rem, 80svh, 52rem);
  padding-inline: var(--gutter);
  /* the fixed bar covers the top of the band; centre the words in what stays visible */
  padding-block: calc(clamp(6rem, 12vw, 10rem) + var(--nav-h)) clamp(6rem, 12vw, 10rem);
  overflow: clip;
  background: #2B2C2D;
  color: var(--on-dark);
  color-scheme: dark;
  --ring: var(--accent-on-dark);
}

.quote__media {
  position: absolute;
  inset: -12% 0;
}

.quote__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 55% 45%;
}

/* Guarantees AA for white type over the brightest part of the shaft of light */
.quote__shade {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 55% at 50% 52%, rgba(15, 16, 18, 0.26) 0%, rgba(15, 16, 18, 0) 100%),
    rgba(15, 16, 18, 0.58);
}

.quote__body {
  position: relative;
  z-index: 1;
  max-width: 62rem;
  text-align: center;
}

.quote__text p {
  font-weight: 300;
  font-size: clamp(1.5rem, 0.95rem + 2.1vw, 2.625rem);
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--on-dark);
  text-wrap: balance;
}

.quote__cite {
  display: block;
  margin-top: clamp(2rem, 3.5vw, 2.75rem);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: var(--track-small);
  text-transform: uppercase;
  color: var(--on-dark-muted);
  padding-left: var(--track-small);
  text-wrap: balance;
}

/* Accent moment: a thin steel rule between the words and the name */
.quote__cite::before {
  content: "";
  display: block;
  width: 3rem;
  height: 1px;
  margin: 0 auto clamp(1.75rem, 3vw, 2.25rem);
  margin-left: calc(50% - 1.5rem - var(--track-small) / 2);
  background: var(--accent-on-dark);
}

/* ------------------------------------------------------------------
   Current projects band
   Stone, between the dark quote and the off-white Team band.
   A centred title, then one row per holding: a landscape photograph
   and its words side by side, the photograph on the left, then on the
   right. Each "More on" opens in place beneath its short version, so
   nothing above the control moves. In preparation closes the band as a
   statement: the sentence in large light type with the sectors in ink,
   its heading beside it, and Talk to us under a hairline.
   ------------------------------------------------------------------ */

.projects {
  --rule: rgb(15 16 18 / 0.14);
  background: var(--stone);
  color: var(--text);
  color-scheme: light;
  padding-block: clamp(6rem, 11vw, 10rem);
}

.projects__title {
  font-weight: 300;
  font-size: clamp(1.875rem, 1.2rem + 2.2vw, 2.875rem);
  line-height: 1.2;
  letter-spacing: var(--track-display);
  padding-left: var(--track-display);
  text-transform: uppercase;
  text-align: center;
  color: var(--ink);
  text-wrap: balance;
}

.projects__list {
  display: grid;
  row-gap: clamp(5rem, 10vw, 8rem);
  margin-top: clamp(3rem, 5vw, 4.5rem);
}

.holding {
  display: grid;
  row-gap: clamp(2rem, 4vw, 2.5rem);
}

.holding__media {
  position: relative;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  overflow: clip;
  background: #D8DADB;
  border-radius: var(--radius);
}

.holding__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The harvesters are small in a wide frame: the crop leans in on them
   (the individual scale property composes with the scroll settle) */
.holding--trade .holding__media img {
  object-position: 56% 50%;
  transform-origin: 56% 47%;
  scale: 1.55;
}

/* Our own vessel, shown whole: the photo is 4:3 like the frame */
.holding--shipping .holding__media img {
  object-position: 50% 50%;
}

@media (min-width: 600px) {
  .holding--trade .holding__media img { scale: 1.3; }
}

.holding__body { min-width: 0; }

/* Stacked, the disclosure rule spans the photograph; the words keep
   their measure */
.holding__body p { max-width: 36em; text-wrap: pretty; }

.holding__title {
  margin: 0 0 clamp(1rem, 1.8vw, 1.375rem);
  font-weight: 300;
  font-size: clamp(1.375rem, 1rem + 1.1vw, 1.875rem);
  line-height: 1.3;
  letter-spacing: var(--track-heading);
  text-transform: uppercase;
  color: var(--ink);
  text-wrap: balance;
}


/* The disclosure: a ruled row with the label and a steel plus that turns
   into a minus. The label never changes. */
.holding__more {
  margin-top: clamp(1.75rem, 3vw, 2.25rem);
  border-block: 1px solid var(--rule);
}

.holding__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 3.5rem;
  padding-block: 0.5rem;
  list-style: none;
  cursor: pointer;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: var(--track-small);
  text-transform: uppercase;
  color: var(--ink);
  transition: color 0.3s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}

.holding__toggle::-webkit-details-marker { display: none; }
.holding__toggle::marker { content: ""; }

@media (hover: hover) {
  .holding__toggle:hover { color: var(--accent); }
}

.holding__icon {
  flex: none;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
}

.holding__icon-bar {
  transform-origin: 8px 8px;
  transition: transform 0.5s var(--ease-out);
}

.holding__more[open] .holding__icon-bar { transform: rotate(90deg); }

.holding__detail {
  padding-block: 0.25rem clamp(1.5rem, 2.5vw, 2rem);
}

/* Opening glides: the full explanation unfolds in height and fades in,
   pushing what follows down smoothly. Where ::details-content is not
   supported, or motion is reduced, the disclosure opens at once. */
@media (prefers-reduced-motion: no-preference) {
  @supports selector(::details-content) {
    .holding__more { interpolate-size: allow-keywords; }

    .holding__more::details-content {
      block-size: 0;
      opacity: 0;
      overflow: clip;
      transition:
        block-size 0.5s var(--ease-out),
        opacity 0.4s var(--ease-out),
        content-visibility 0.5s allow-discrete;
    }

    .holding__more[open]::details-content {
      block-size: auto;
      opacity: 1;
    }
  }
}

@media (min-width: 960px) {
  .holding {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    column-gap: clamp(3.5rem, 7vw, 7rem);
    align-items: start;
  }

  .holding--shipping { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .holding--shipping .holding__media { order: 2; }

  .holding--trade .holding__media img { scale: 1.16; }

  /* Landed from the Projects link, the title and the whole first row sit
     in a 900px screen below the bar */
  .projects { padding-top: calc(clamp(6rem, 11vw, 10rem) - 2.5rem); }

  /* Closed, the words sit on the photograph's middle; the offset grows
     with the photograph, so opening only ever extends downward */
  .holding__body { padding-top: clamp(0rem, (100vw - 56rem) * 0.25, 7.5rem); }
}

/* In preparation: the pipeline said as one statement, set about as large
   as the Why headline. The sector words carry the ink and the words that
   join them step back, so the sectors read first. Each phrase keeps a line
   of its own (on phones it wraps within itself, balanced); the heading
   takes a narrow column beside the statement from 960px and sits above
   it below that. Talk to us closes the block under a hairline, on the
   statement's edge. */
.projects__next {
  --quiet: #686C72;   /* the joining words: 4.6:1 on stone */
  margin-top: clamp(6.5rem, 12vw, 10rem);
}

.projects__next .holding__title {
  margin: 0 0 clamp(1.25rem, 2.5vw, 1.75rem);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: var(--track-small);
}

.projects__statement {
  /* Under about 440px the size follows the column, so "an automated
     trading algorithm," always holds one line and "an" never stands alone */
  font-size: min(clamp(1.5rem, 0.8rem + 2vw, 2.75rem), 5.9vw - 0.125rem);
  font-weight: 300;
  line-height: 1.26;
  letter-spacing: -0.01em;
  color: var(--quiet);
}

/* Each line is a block of its own (not an inline block), so the sentence
   also reads and copies with the breaks between its lines in every browser */
.projects__line {
  display: block;
  text-wrap: balance;
}

/* A sector name never breaks: on phones, and just above 960px where the
   statement's column is at its narrowest */
.projects__sector {
  color: var(--ink);
  white-space: nowrap;
}

.projects__keep { display: inline-block; max-width: 100%; }
.projects__keep .projects__sector { white-space: normal; }

.projects__rule {
  display: block;
  height: 1px;
  margin-top: clamp(2.25rem, 4vw, 3.25rem);
  background: rgb(15 16 18 / 0.24);
}

.projects__cta {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  width: max-content;
  min-height: 2.75rem;
  margin-top: clamp(0.75rem, 1.5vw, 1.125rem);
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: var(--track-small);
  text-transform: uppercase;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.projects__cta-arrow {
  flex: none;
  width: 1.375rem;
  height: 0.75rem;
  overflow: visible;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.25;
}

@media (hover: hover) {
  .projects__cta:hover { color: var(--accent); }
  .projects__cta:hover .projects__cta-arrow { transform: translateX(0.25rem); }
}

@media (prefers-reduced-motion: no-preference) {
  .projects__cta { transition: color 0.3s var(--ease-out); }
  .projects__cta-arrow { transition: transform 0.45s var(--ease-out); }
}

@media (min-width: 960px) {
  .projects__next {
    display: grid;
    grid-template-columns: 13rem minmax(0, 1fr);
    column-gap: clamp(2.5rem, 5vw, 5rem);
    align-items: baseline;
  }

  .projects__next > * { grid-column: 2; }

  /* on the first line's baseline */
  .projects__next .holding__title {
    grid-column: 1;
    grid-row: 1;
    margin: 0;
  }

  .projects__cta { justify-self: start; }
}

/* ------------------------------------------------------------------
   Team band
   Off-white, centred: the two groups stacked on phones and tablets and
   side by side in one row of six from 1200px, every portrait the same
   size, names in tracked capitals, roles beneath in the secondary tone.
   ------------------------------------------------------------------ */

.team {
  background: var(--paper);
  color: var(--text);
  color-scheme: light;
  padding-block: clamp(6rem, 11vw, 10rem);
  text-align: center;
  --portrait: 12rem;
  --col: 17rem;
  --col-gap: clamp(1rem, 4vw, 3rem);
}

.team__title {
  font-weight: 300;
  font-size: clamp(1.875rem, 1.2rem + 2.2vw, 2.875rem);
  line-height: 1.2;
  letter-spacing: var(--track-display);
  padding-left: var(--track-display);
  text-transform: uppercase;
  color: var(--ink);
}

/* The Team link lands the band right under the fixed bar; as in the Why
   band, the bar's height comes out of the top padding, so the whole team
   is in view and resolved on a short laptop screen */
@media (min-width: 960px) {
  .team { padding-top: calc(clamp(6rem, 11vw, 10rem) - var(--nav-h)); }
}

.team__groups { margin-top: clamp(3.5rem, 6vw, 5rem); }

@media (min-width: 1200px) and (max-height: 42.5rem) {
  .team__groups { margin-top: 2rem; }
}
.team__group + .team__group { margin-top: clamp(4.5rem, 8vw, 7rem); }

/* Wide screens: the two groups share one centred row, so the whole team
   is in view where the Team link lands. Each group keeps its heading
   centred over its own people; the gap between groups is clearly wider
   than the gap between people. Without container units the groups
   shrink in proportion, which keeps the columns within a pixel. */
@media (min-width: 1200px) {
  /* 13.75rem columns: the three Management roles hold one line, so the
     links sit level; the longer board roles wrap within their own block */
  .team {
    --col: 13.75rem;
    --col-gap: 2rem;
    --group-gap: clamp(4rem, 6vw, 6rem);
  }

  .team__groups {
    display: flex;
    justify-content: center;
    align-items: start;
    column-gap: var(--group-gap);
  }

  .team__group { flex: 0 1 auto; min-width: 0; }
  .team__group + .team__group { margin-top: 0; }
}

.team__group-title {
  margin: 0 0 clamp(2rem, 3.5vw, 2.75rem);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: var(--track-small);
  padding-left: var(--track-small);
  text-transform: uppercase;
  color: var(--ink);
}

/* Phones: two columns, an odd last portrait centred beneath.
   Three row tracks per row of people (portrait, caption, link), shared by
   every person in that row through subgrid, so a role that wraps moves
   both links down together and they stay level. */
.team__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 11rem));
  grid-template-rows: auto auto auto;
  justify-content: center;
  column-gap: var(--col-gap);
  row-gap: 0;
}

.team__list > .member:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  justify-self: center;
  width: calc(50% - var(--col-gap) / 2);
  margin-top: 3rem;
}

/* From tablet up: every group is one centred row */
@media (min-width: 768px) {
  .team__list {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, var(--col));
  }

  .team__list > .member:last-child:nth-child(odd) {
    grid-column: auto;
    justify-self: auto;
    width: auto;
    margin-top: 0;
  }
}

/* Every person is one block with a fixed inner rhythm: portrait, then
   name and role as one caption, then the link. Portraits are all the same
   size, so portrait tops and name tops stay level across a row; the
   caption row is as tall as the longest caption in it, so a name or role
   that wraps never opens a gap inside a neighbour's caption, and the
   links below share one line. */
.member {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  row-gap: 0;
  justify-items: center;
  align-content: start;
  min-width: 0;
}

.member > * { align-self: start; }

.member__portrait {
  position: relative;
  width: min(100%, var(--portrait));
  aspect-ratio: 4 / 5;
  overflow: clip;
  background: #E6E7E8;
  border-radius: var(--radius);
}

/* Pinned inside the frame. The portraits are one matched 4:5 studio set, so no per-person crop. */
.member__portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.member__caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 100%;
  min-width: 0;
  margin-top: clamp(1.25rem, 2vw, 1.625rem);
}

.member__name {
  margin: 0 auto;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: var(--track-heading);
  padding-left: var(--track-heading);
  text-transform: uppercase;
  color: var(--ink);
  /* pretty, not balance: a three-line name breaks by its parts
     (DIEGO FERNÁNDEZ / DE CEVALLOS / GUTIÉRREZ) instead of stranding
     the first name on its own line */
  text-wrap: pretty;
  /* A name never runs wider than this, whatever the column allows, so the long
     names break into a similar number of lines at every size and no card in a
     row stands much taller than its neighbours. */
  max-width: 16.5em;
}

.member__role {
  max-width: 100%;
  margin-top: 0.375rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--muted);
  text-wrap: balance;
}

.member__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.875rem;
  padding-inline: 0.25rem;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--accent);
  text-underline-offset: 0.35em;
  transition: color 0.3s var(--ease-out), text-decoration-color 0.3s var(--ease-out);
}

/* The visible link sits close under the role; this invisible layer keeps
   the touch target at least 44px tall */
.member__link::before {
  content: "";
  position: absolute;
  inset: -0.75rem -0.5rem;
}

.member__link-icon {
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-linecap: square;
  transition: transform 0.45s var(--ease-out);
}

.member__link:hover { color: var(--accent); text-decoration-color: currentColor; }
.member__link:hover .member__link-icon { transform: translate(1px, -1px); }

@media (max-width: 767px) {
  .team {
    --col-gap: 1.25rem;
  }
  .member__name { font-size: 0.8125rem; letter-spacing: 0.1em; padding-left: 0.1em; }
  .member__role { font-size: 0.875rem; }
}

/* Small phones: a little more width per column and a step down in size,
   so names and roles break into fewer, calmer lines */
@media (max-width: 400px) {
  .team {
    --col-gap: 1rem;
  }
  .member__name { font-size: 0.75rem; letter-spacing: 0.08em; padding-left: 0.08em; }
  .member__role { font-size: 0.8125rem; }
}

/* One row of six (see .team__groups): a step down so the roles fit the
   narrower columns */
@media (min-width: 1200px) {
  .member__role { font-size: 0.875rem; }

  /* The columns are at their narrowest here, so the names are tracked a little tighter: the long
     board names then break into the same number of lines as they do on wider layouts. */
  .member__name { letter-spacing: 0.08em; padding-left: 0.08em; }

  /* Up to 1399 the six columns are tightest of all; a step down in the name keeps the longest one
     to three lines here too, and no name strands a single word per line, so no card towers over
     its neighbours. */
  @media (max-width: 1399px) {
    .member__name { font-size: 0.8125rem; }
  }

  @media (max-width: 1299px) {
    .member__name { font-size: 0.75rem; letter-spacing: 0.06em; padding-left: 0.06em; }
  }

  /* Where container units exist, the six columns are sized exactly from
     the width available, so every column and portrait is identical */
  @supports (width: 1cqi) {
    .team > .container { container-type: inline-size; }
    .team__list {
      grid-auto-columns: min(var(--col), calc((100cqi - 4 * var(--col-gap) - var(--group-gap)) / 6));
    }
    .team__group { flex: none; }
  }
}

/* ------------------------------------------------------------------
   Footer
   The closing near-black band
   ------------------------------------------------------------------ */

.site-footer {
  background: var(--ink);
  color: var(--on-dark-muted);
  color-scheme: dark;
  --ring: var(--on-dark);
  padding-block: clamp(4rem, 8vw, 6.5rem) clamp(2.5rem, 4vw, 3.5rem);
  font-size: 0.9375rem;
  line-height: 1.7;
}

.site-footer ::selection { background: var(--accent-on-dark); color: var(--ink); }

.site-footer__top {
  display: grid;
  gap: 2rem;
  align-items: center;
}

.site-footer__brand { display: inline-flex; align-items: center; justify-self: start; min-height: 44px; }
.site-footer__brand img { width: 144px; filter: invert(1); }

/* On a light forced-colours theme the footer is repainted light, so its wordmark stays black */
@media (forced-colors: active) and (prefers-color-scheme: light) {
  .site-footer__brand img { filter: none; }
}

.site-footer__contact p + p { margin-top: 0.25rem; }

.site-footer__contact a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--on-dark);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--accent-on-dark);
  text-underline-offset: 0.35em;
  transition: text-decoration-color 0.3s var(--ease-out);
}

.site-footer__contact a:hover { text-decoration-color: var(--on-dark); }

/* The closing line: the two legal pages, and the notice that ends the site */
.site-footer__foot {
  display: grid;
  gap: 1rem;
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding-top: clamp(1.5rem, 2.5vw, 2rem);
  border-top: 1px solid rgb(250 250 248 / 0.16);
}

.site-footer__legal {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: var(--track-small);
  text-transform: uppercase;
}

.site-footer__legal a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-left: var(--track-small);
  color: var(--on-dark);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--accent-on-dark);
  text-underline-offset: 0.35em;
  transition: text-decoration-color 0.3s var(--ease-out);
}

.site-footer__legal a:hover { text-decoration-color: var(--on-dark); }
.site-footer__dot { color: var(--on-dark-muted); }

/* The same voice as the legal fine print on the Impact scene: light italic, quiet, still plain
   to read, one step larger here since it closes the page */
.site-footer__notice {
  max-width: 44em;
  font-size: 0.8125rem;
  font-style: italic;
  font-weight: 300;
  line-height: 1.6;
  letter-spacing: 0.01em;
  color: var(--on-dark-muted);
  text-wrap: balance;
}

@media (min-width: 768px) {
  .site-footer__foot {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 4rem;
  }

  .site-footer__notice { justify-self: end; text-align: right; }
}

/* Marks the end of the page for the nav state; takes no space */
.site-footer__end { display: block; height: 1px; margin-top: -1px; }

@media (min-width: 768px) {
  .site-footer__top {
    grid-template-columns: auto 1fr;
    column-gap: 4rem;
  }
  .site-footer__contact { justify-self: end; text-align: right; }
}

/* ------------------------------------------------------------------
   Scroll choreography
   Everything above is the complete static page. The scenes below only
   run where scroll-driven animations exist and motion is welcome.
   ------------------------------------------------------------------ */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* Scene 1: the lake settles in and the words lift away */
    .hero { view-timeline: --hero block; }

    .hero__media img {
      animation: hero-zoom linear both;
      animation-timeline: --hero;
      animation-range: exit 0% exit 100%;
    }

    .hero__shade {
      animation: hero-shade linear both;
      animation-timeline: --hero;
      animation-range: exit 0% exit 100%;
    }

    .hero__content {
      animation: hero-lift linear both;
      animation-timeline: --hero;
      animation-range: exit 0% exit 60%;
    }

    /* Scene 2: the walkway eases back to size, the text rises in */
    .why__figure { view-timeline: --why-figure block; }

    .why__figure img {
      animation: figure-settle linear both;
      animation-timeline: --why-figure;
      animation-range: entry 0% cover 45%;
    }

    .why__text > * {
      animation: text-rise linear both;
      animation-timeline: view();
    }
    /* each line has settled by the time it is fully on screen, so the
       Natus link never lands on a half-faded paragraph */
    .why__text > :nth-child(1) { animation-range: entry 0% entry 100%; }
    .why__text > :nth-child(2) { animation-range: entry 15% entry 100%; }
    .why__text > :nth-child(3) { animation-range: entry 30% entry 100%; }
    .why__text > :nth-child(4) { animation-range: entry 45% entry 100%; }

    /* Scene 3: the light on the wall drifts slower than the page */
    .quote { view-timeline: --quote block; }

    .quote__media {
      animation: quote-drift linear both;
      animation-timeline: --quote;
      animation-range: cover 0% cover 100%;
    }

    /* Scene 4: Current projects. Each photograph opens out from the page
       edge toward its words while the picture settles; the words rise
       after it. Resolved by the time the Projects link lands the row. */
    .projects__title {
      animation: text-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }

    /* In preparation: the statement rises line by line (each line on its
       own box, so the beat follows the lines down), the hairline draws
       from the statement's edge, and Talk to us rises under it. Every
       part has settled while the band's closing space is still below the
       screen, before Team comes into view. The title rises with the
       holding titles below. */
    .projects__line {
      animation: text-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 15%;
    }

    .projects__rule {
      --open-from: inset(0 100% 0 0);
      animation: holding-open linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 13%;
    }

    .projects__cta {
      animation: text-rise-short linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 12%;
    }

    .holding__media {
      --open-from: inset(0 14% 0 0);
      view-timeline: --holding block;
      animation: holding-open linear both;
      animation-timeline: --holding;
      animation-range: entry 0% cover 30%;
    }

    .holding--shipping .holding__media { --open-from: inset(0 0 0 14%); }

    .holding__media img {
      animation: figure-settle linear both;
      animation-timeline: --holding;
      animation-range: entry 0% cover 34%;
    }

    /* The disclosure's own box grows when it opens, which would rewind a
       view() entry on it; only its summary row moves, and that never
       changes size */
    .holding__title,
    .holding__body > p,
    .holding__toggle {
      animation: text-rise linear both;
      animation-timeline: view();
    }
    /* A one-line title's entry is only its own height, so a full rise
       would snap past; titles take the shorter one. This also covers the
       In preparation title, which sits in .projects__next. */
    .holding__title {
      animation-name: text-rise-short;
      animation-range: entry 0% entry 100%;
    }
    .holding__body > p { animation-range: entry 15% entry 100%; }
    .holding__toggle {
      animation-name: text-rise-short;
      animation-range: entry 30% entry 100%;
    }

    /* Scene 5: each portrait opens from a narrower frame while its
       photograph settles, name and role rising after it, one column
       a beat behind the one before */
    .team__title,
    .team__group-title {
      animation: text-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
    /* one short line: the shorter rise, as for the holding titles */
    .team__group-title { animation-name: text-rise-short; }

    .member { view-timeline: --member block; }

    /* A row has fully resolved once it is about a third of the way up
       the screen, which is where the Team link lands it */
    .member__portrait {
      animation: portrait-open linear both;
      animation-timeline: --member;
      animation-range: entry 0% cover 24%;
    }

    .member__portrait img {
      animation: figure-settle linear both;
      animation-timeline: --member;
      animation-range: entry 0% cover 30%;
    }

    .member__caption,
    .member__link {
      animation: text-rise-short linear both;
      animation-timeline: --member;
      animation-range: entry 25% cover 28%;
    }

    .member:nth-child(2) .member__portrait { animation-range: entry 8% cover 27%; }
    .member:nth-child(2) .member__portrait img { animation-range: entry 8% cover 33%; }
    .member:nth-child(2) :is(.member__caption, .member__link) { animation-range: entry 40% cover 31%; }

    .member:nth-child(3) .member__portrait { animation-range: entry 16% cover 30%; }
    .member:nth-child(3) .member__portrait img { animation-range: entry 16% cover 36%; }
    .member:nth-child(3) :is(.member__caption, .member__link) { animation-range: entry 55% cover 34%; }

    /* One row of six: management then the board, one beat left to right
       across the whole team, a little closer than on narrower screens.
       The last column has resolved by cover 32%, so the whole row has
       settled, with room to spare, where the Team link lands it on short
       laptop screens (1366 x 768, 1280 x 800). main.js mirrors this table
       for the fallback. */
    @media (min-width: 1200px) {
      .team__group:first-child .member:nth-child(2) .member__portrait { animation-range: entry 6% cover 25.2%; }
      .team__group:first-child .member:nth-child(2) .member__portrait img { animation-range: entry 6% cover 30.4%; }
      .team__group:first-child .member:nth-child(2) :is(.member__caption, .member__link) { animation-range: entry 34% cover 28.8%; }

      .team__group:first-child .member:nth-child(3) .member__portrait { animation-range: entry 12% cover 26.4%; }
      .team__group:first-child .member:nth-child(3) .member__portrait img { animation-range: entry 12% cover 30.8%; }
      .team__group:first-child .member:nth-child(3) :is(.member__caption, .member__link) { animation-range: entry 43% cover 29.6%; }

      .team__group + .team__group .member:nth-child(1) .member__portrait { animation-range: entry 18% cover 27.6%; }
      .team__group + .team__group .member:nth-child(1) .member__portrait img { animation-range: entry 18% cover 31.2%; }
      .team__group + .team__group .member:nth-child(1) :is(.member__caption, .member__link) { animation-range: entry 52% cover 30.4%; }

      .team__group + .team__group .member:nth-child(2) .member__portrait { animation-range: entry 24% cover 28.8%; }
      .team__group + .team__group .member:nth-child(2) .member__portrait img { animation-range: entry 24% cover 31.6%; }
      .team__group + .team__group .member:nth-child(2) :is(.member__caption, .member__link) { animation-range: entry 61% cover 31.2%; }

      .team__group + .team__group .member:nth-child(3) .member__portrait { animation-range: entry 30% cover 30%; }
      .team__group + .team__group .member:nth-child(3) .member__portrait img { animation-range: entry 30% cover 32%; }
      .team__group + .team__group .member:nth-child(3) :is(.member__caption, .member__link) { animation-range: entry 70% cover 32%; }
    }
  }
}

/* The same scenes where the browser does not run the block above, or
   claims to and does not advance: scroll-fallback.js plays them
   from the scroll position (configured in main.js) and marks <html> with
   .sdt-fallback. These scenes pin nothing and change no layout: the class
   only switches the CSS animations off, and the two never run at once.
   Without JS, or with motion reduced, the page stays static. */
@media (prefers-reduced-motion: no-preference) {
  html.sdt-fallback .hero__media img,
  html.sdt-fallback .hero__shade,
  html.sdt-fallback .hero__content,
  html.sdt-fallback .why__figure img,
  html.sdt-fallback .why__text > *,
  html.sdt-fallback .quote__media,
  html.sdt-fallback .projects__title,
  html.sdt-fallback .projects__line,
  html.sdt-fallback .projects__rule,
  html.sdt-fallback .projects__cta,
  html.sdt-fallback .holding__media,
  html.sdt-fallback .holding__media img,
  html.sdt-fallback .holding__title,
  html.sdt-fallback .holding__body > p,
  html.sdt-fallback .holding__toggle,
  html.sdt-fallback .team__title,
  html.sdt-fallback .team__group-title,
  html.sdt-fallback .member__portrait,
  html.sdt-fallback .member__portrait img,
  html.sdt-fallback .member__caption,
  html.sdt-fallback .member__link {
    animation: none;
  }
}

@keyframes hero-zoom {
  from { transform: scale(1); }
  to { transform: scale(1.1); }
}

@keyframes hero-shade {
  from { opacity: 0; }
  to { opacity: 0.5; }
}

@keyframes hero-lift {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-12svh); }
}

@keyframes figure-settle {
  from { transform: scale(1.08); }
  to { transform: scale(1); }
}

@keyframes text-rise {
  from { opacity: 0; transform: translateY(2.25rem); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes holding-open {
  from { clip-path: var(--open-from); }
  to { clip-path: inset(0); }
}

@keyframes portrait-open {
  from { clip-path: inset(7% 9%); }
  to { clip-path: inset(0); }
}

@keyframes text-rise-short {
  from { opacity: 0; transform: translateY(1rem); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes quote-drift {
  from { transform: translateY(-9%); }
  to { transform: translateY(9%); }
}
