/* How we invest: stage. Every selector is scoped to .invest--stage.

   At rest (no scroll-driven motion, motion reduced, or a screen too small
   to hold the stage) the block is a ruled list on paper: the heading, each
   lead word at display scale with its sentences, the sectors as a ruled row.

   With motion, from 64rem wide and 40rem tall, the same elements are set as
   one stage held under the bar while the reader scrolls: the four lead words
   spread down the left as an index, the sentences of the current one beside
   it on the right, the sectors on the bottom edge.
   Scrolling hands the stage from one principle to the next; after Structure
   the stage scrolls away. Below that size each principle gets a scene of its own:
   a hairline draws, the lead word rises out of it, its sentences follow. */

.invest--stage {
  --stage-rule: rgb(15 16 18 / 0.16);
  --stage-gap: clamp(3rem, 6vw, 7rem);
  position: relative;
  padding-block: clamp(5.5rem, 11vw, 10rem);
  background: var(--paper);
  color: var(--text);
  color-scheme: light;
  --ring: var(--accent);
}

/* Sizes below follow the width of the stage itself */
.invest--stage .invest-stage__pin {
  container-type: inline-size;
}

.invest--stage .invest-stage__grid {
  /* The lead words sit with the page's other large statements (the quote,
     the In preparation sentence): a step above body, below the hero.
     "Verification." is about 5.75em wide: it always holds one line. */
  --stage-word: min(2.375rem, calc((100cqi - 2 * var(--gutter)) / 7.5));
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

/* A section title, as the page sets them, one step below Current projects */
.invest--stage .invest-stage__title {
  font-size: clamp(1.625rem, 0.95rem + 1.6vw, 2.375rem);
  font-weight: 300;
  line-height: 1.3;
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  color: var(--ink);
  text-wrap: balance;
}

/* A lead word. Its box clips only vertically: the word can rise out of its
   own lower edge, which sits on the hairline below it. */
.invest--stage .invest-stage__word {
  margin: clamp(4rem, 15vw, 6rem) 0 0;
  padding: 0 0 0.14em;
  font-size: var(--stage-word);
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
  white-space: nowrap;
  overflow-x: visible;
  overflow-y: clip;
}

.invest--stage .invest-stage__word--protection {
  margin-top: clamp(2.75rem, 9vw, 4.5rem);
}

.invest--stage .invest-stage__word-off,
.invest--stage .invest-stage__word-in,
.invest--stage .invest-stage__text-off {
  display: block;
}

/* The hairline under each word opens on a short steel run */
.invest--stage .invest-stage__line {
  position: relative;
  display: block;
  height: 1px;
  background: var(--stage-rule);
}

.invest--stage .invest-stage__line::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: clamp(2rem, 6vw, 3rem);
  background: var(--accent);
}

.invest--stage .invest-stage__text {
  max-width: 30em;
  margin-top: clamp(1.25rem, 3.5vw, 1.75rem);
  font-size: clamp(1.1875rem, 1rem + 0.8vw, 1.5rem);
  font-weight: 300;
  line-height: 1.55;
  color: var(--text);
  text-wrap: balance;
}

.invest--stage .invest-stage__foot {
  margin-top: clamp(4.5rem, 14vw, 7rem);
}

.invest--stage .invest-stage__foot-rule {
  display: block;
  height: 1px;
  background: var(--stage-rule);
}

/* The sectors: tracked capitals, each opened by a thin upright rule. On
   phones they sit in two even columns; from 64rem they spread across the
   full width of the stage with equal space between them. */
.invest--stage .invest-stage__sectors {
  --stage-sector-pad: clamp(0.75rem, 1.2vw, 1.125rem);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 1.5rem;
  row-gap: 0.75rem;
  padding-block: clamp(1.125rem, 2vw, 1.5rem);
  border-bottom: 1px solid var(--stage-rule);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: var(--track-small);
  text-transform: uppercase;
  color: var(--ink);
}

.invest--stage .invest-stage__sectors > li {
  position: relative;
  padding-left: var(--stage-sector-pad);
  white-space: nowrap;
}

.invest--stage .invest-stage__sectors > li::before {
  content: "";
  position: absolute;
  top: 0.3em;
  bottom: 0.3em;
  left: 0;
  width: 1px;
  background: rgb(15 16 18 / 0.28);
}

.invest--stage .invest-stage__sector--more {
  font-weight: 400;
  color: var(--muted);
}

/* ------------------------------------------------------------------
   Large screens at rest: a ruled list, each word beside its sentences,
   their first lines level at the cap height
   ------------------------------------------------------------------ */

@media (min-width: 64rem) {
  .invest--stage .invest-stage__grid {
    /* half the stage less the gap, and room for the word's step in */
    --stage-word: min(2.875rem, calc((min(100cqi - 2 * var(--gutter), var(--max)) - var(--stage-gap)) / 13));
    --stage-lede: clamp(1.25rem, 0.85rem + 0.75vw, 1.75rem);
    --stage-row-in: clamp(1.75rem, 2.5vw, 2.5rem);
    --stage-row-out: clamp(3rem, 4.5vw, 4rem);
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--stage-gap);
  }

  .invest--stage .invest-stage__title,
  .invest--stage .invest-stage__line,
  .invest--stage .invest-stage__foot {
    grid-column: 1 / -1;
  }

  .invest--stage .invest-stage__title { grid-row: 1; }

  .invest--stage .invest-stage__line { margin-top: var(--stage-row-out); }
  .invest--stage .invest-stage__line--protection { grid-row: 2; margin-top: clamp(3rem, 5vw, 4.5rem); }
  .invest--stage .invest-stage__line--impact { grid-row: 4; }
  .invest--stage .invest-stage__line--verification { grid-row: 6; }
  .invest--stage .invest-stage__line--structure { grid-row: 8; }

  .invest--stage .invest-stage__word {
    grid-column: 1;
    align-self: start;
    margin-top: var(--stage-row-in);
    padding: 0.03em 0;
  }

  .invest--stage .invest-stage__text {
    grid-column: 2;
    align-self: start;
    max-width: 24em;
    /* the word's cap top is 0.29em into its box, the sentence's 0.41em */
    margin-top: calc(var(--stage-row-in) + var(--stage-word) * 0.2885 - 0.41em);
    font-size: var(--stage-lede);
    line-height: 1.5;
  }

  .invest--stage .invest-stage__word--protection,
  .invest--stage .invest-stage__text--protection { grid-row: 3; }
  .invest--stage .invest-stage__word--impact,
  .invest--stage .invest-stage__text--impact { grid-row: 5; }
  .invest--stage .invest-stage__word--verification,
  .invest--stage .invest-stage__text--verification { grid-row: 7; }
  .invest--stage .invest-stage__word--structure,
  .invest--stage .invest-stage__text--structure { grid-row: 9; }

  .invest--stage .invest-stage__foot {
    grid-row: 10;
    margin-top: var(--stage-row-out);
  }

  .invest--stage .invest-stage__sectors {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    column-gap: 2rem;
    border-bottom: 0;
    padding-bottom: 0;
  }
}

/* ------------------------------------------------------------------
   The pinned stage (layout)
   Applied only where the scene runs: in the @supports block below, and
   under html.sdt-fallback when scroll-fallback.js plays it. The
   two copies are identical; change one, change the other.
   The section is the stage plus 180svh of travel. The stage holds under
   the bar for that travel and lets go after Structure.
   ------------------------------------------------------------------ */

/* This copy is the native one; whenever scroll-fallback.js runs the scenes instead (html.sdt-fallback)
   the copy further down owns the pinned layout, and only once invest.js has registered its scenes.
   :where() adds no specificity, so the cascade here is exactly as it was. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 64rem) and (min-height: 40rem) {
    :where(html:not(.sdt-fallback)) .invest--stage {
      height: calc(280svh - var(--nav-h));
      padding-block: 0;
    }

    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__pin {
      position: sticky;
      top: var(--nav-h);
      height: calc(100svh - var(--nav-h));
    }

    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__grid {
      /* The four index rows share all the height between the title and the
         sectors, and the words grow with that height: a row is about 1.85
         words tall, so the index fills the stage with the same calm gap between
         the words at any size of window. The width of the column still caps
         them ("Verification." and its step in hold one line). The row is worked
         out here rather than left to the grid, so the sentences can be set
         level with their word; the two spacers take up any difference. The
         sentences grow with the words. */
      --stage-pad: clamp(2.5rem, 7svh, 5rem);
      --stage-spacer: clamp(1.5rem, 4svh, 3rem);
      --stage-pitch: calc((100svh - var(--nav-h) - 2 * var(--stage-pad) - 1.3 * clamp(1.625rem, 0.95rem + 1.6vw, 2.375rem) - 2 * var(--stage-spacer) - 2.9rem) / 4);
      --stage-word: max(2.875rem, min(6rem, var(--stage-pitch) * 0.54, calc((min(100cqi - 2 * var(--gutter), var(--max)) - var(--stage-gap)) / 13)));
      --stage-row: max(var(--stage-pitch), var(--stage-word) * 1.26);
      --stage-lede: clamp(1.25rem, var(--stage-word) * 0.4, 1.875rem);
      height: 100%;
      padding-block: var(--stage-pad);
      grid-template-rows: auto minmax(var(--stage-spacer), 1fr) repeat(4, var(--stage-row)) minmax(var(--stage-spacer), 1fr) auto;
    }

    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__line { display: none; }

    /* The word steps in by 0.8em when it is current; the others stand
       back on the heading's edge */
    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__word {
      align-self: center;
      margin: 0 0 0 0.8em;
    }

    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__word--protection { grid-row: 3; }
    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__word--impact { grid-row: 4; }
    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__word--verification { grid-row: 5; }
    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__word--structure { grid-row: 6; }

    /* Each set of sentences stands beside its own word, across that row and
       the next, so the set travels down the stage with the index: the upper
       two hang level with their word's cap height, the lower two rest level
       with its baseline. In a row the word's cap top is half a row less 0.3415em
       down and its baseline half a row plus 0.3585em; a sentence's cap top is
       0.41em into its box and its last baseline 0.39em above its foot. */
    :where(html:not(.sdt-fallback)) .invest--stage :is(.invest-stage__text--protection, .invest-stage__text--impact) {
      align-self: start;
      margin: calc(var(--stage-row) / 2 - var(--stage-word) * 0.3415 - var(--stage-lede) * 0.41) 0 0;
    }

    :where(html:not(.sdt-fallback)) .invest--stage :is(.invest-stage__text--verification, .invest-stage__text--structure) {
      align-self: end;
      margin: 0 0 calc(var(--stage-row) / 2 - var(--stage-word) * 0.3585 - var(--stage-lede) * 0.39);
    }

    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__text--protection { grid-row: 3 / 5; }
    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__text--impact { grid-row: 4 / 6; }
    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__text--verification { grid-row: 4 / 6; }
    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__text--structure { grid-row: 5 / 7; }

    :where(html:not(.sdt-fallback)) .invest--stage .invest-stage__foot {
      grid-row: 8;
      margin-top: 0;
    }
  }
}

/* The pinned stage under the JS fallback needs invest.js to play its scenes; the section carries
   data-stage-scenes once invest.js has registered them. Without it (the script failed to load) the
   four principles stay as the static ruled list, legible, instead of four sentence sets stacked
   in one place. */
@media (prefers-reduced-motion: no-preference) and (min-width: 64rem) and (min-height: 40rem) {
  html.sdt-fallback .invest--stage[data-stage-scenes] {
    height: calc(280svh - var(--nav-h));
    padding-block: 0;
  }

  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__pin {
    position: sticky;
    top: var(--nav-h);
    height: calc(100svh - var(--nav-h));
  }

  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__grid {
    --stage-pad: clamp(2.5rem, 7svh, 5rem);
    --stage-spacer: clamp(1.5rem, 4svh, 3rem);
    --stage-pitch: calc((100svh - var(--nav-h) - 2 * var(--stage-pad) - 1.3 * clamp(1.625rem, 0.95rem + 1.6vw, 2.375rem) - 2 * var(--stage-spacer) - 2.9rem) / 4);
    --stage-word: max(2.875rem, min(6rem, var(--stage-pitch) * 0.54, calc((min(100cqi - 2 * var(--gutter), var(--max)) - var(--stage-gap)) / 13)));
    --stage-row: max(var(--stage-pitch), var(--stage-word) * 1.26);
    --stage-lede: clamp(1.25rem, var(--stage-word) * 0.4, 1.875rem);
    height: 100%;
    padding-block: var(--stage-pad);
    grid-template-rows: auto minmax(var(--stage-spacer), 1fr) repeat(4, var(--stage-row)) minmax(var(--stage-spacer), 1fr) auto;
  }

  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__line { display: none; }

  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__word {
    align-self: center;
    margin: 0 0 0 0.8em;
  }

  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__word--protection { grid-row: 3; }
  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__word--impact { grid-row: 4; }
  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__word--verification { grid-row: 5; }
  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__word--structure { grid-row: 6; }

  html.sdt-fallback .invest--stage[data-stage-scenes] :is(.invest-stage__text--protection, .invest-stage__text--impact) {
    align-self: start;
    margin: calc(var(--stage-row) / 2 - var(--stage-word) * 0.3415 - var(--stage-lede) * 0.41) 0 0;
  }

  html.sdt-fallback .invest--stage[data-stage-scenes] :is(.invest-stage__text--verification, .invest-stage__text--structure) {
    align-self: end;
    margin: 0 0 calc(var(--stage-row) / 2 - var(--stage-word) * 0.3585 - var(--stage-lede) * 0.39);
  }

  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__text--protection { grid-row: 3 / 5; }
  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__text--impact { grid-row: 4 / 6; }
  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__text--verification { grid-row: 4 / 6; }
  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__text--structure { grid-row: 5 / 7; }

  html.sdt-fallback .invest--stage[data-stage-scenes] .invest-stage__foot {
    grid-row: 8;
    margin-top: 0;
  }
}

/* ------------------------------------------------------------------
   Scroll choreography
   Pinned: every part runs on the section's view timeline, inset by the
   bar. "entry" is the stage arriving (section top from the foot of the
   screen to the bar); "contain" is the pinned travel. The principles hand
   over at 20%, 50% and 80% of the travel, briskly: the words change across
   2% either side, the outgoing sentences leave in the 2%
   before and the incoming ones arrive in the 2% after, so no two sets ever
   overlap and every principle rests fully resolved between handovers.
   Elsewhere every part runs on its own view.
   invest.js mirrors all of it for scroll-fallback.js.
   ------------------------------------------------------------------ */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 64rem) and (min-height: 40rem) {
    .invest--stage {
      view-timeline: --stage-scene block;
      view-timeline-inset: var(--nav-h) 0px;
    }

    .invest--stage :is(
      .invest-stage__title,
      .invest-stage__word,
      .invest-stage__word-off,
      .invest-stage__word-in,
      .invest-stage__text,
      .invest-stage__text-off,
      .invest-stage__foot-rule,
      .invest-stage__sectors
    ) {
      animation-timeline: --stage-scene;
      animation-fill-mode: both;
    }

    /* Arrival: the heading, then the index assembles word by word in grey,
       Protection comes forward with its sentences, and the sectors settle
       on the bottom edge */
    .invest--stage .invest-stage__title {
      animation-name: stage-rise-short;
      animation-timing-function: linear;
      animation-range: entry 12% entry 42%;
    }

    .invest--stage .invest-stage__word-in {
      animation-name: stage-mask;
      animation-timing-function: linear;
    }
    .invest--stage .invest-stage__word--protection .invest-stage__word-in { animation-range: entry 36% entry 60%; }
    .invest--stage .invest-stage__word--impact .invest-stage__word-in { animation-range: entry 43% entry 67%; }
    .invest--stage .invest-stage__word--verification .invest-stage__word-in { animation-range: entry 50% entry 74%; }
    .invest--stage .invest-stage__word--structure .invest-stage__word-in { animation-range: entry 57% entry 81%; }

    .invest--stage .invest-stage__foot-rule {
      animation-name: stage-draw;
      animation-timing-function: linear;
      animation-range: entry 78% entry 100%;
    }

    .invest--stage .invest-stage__sectors {
      animation-name: stage-rise-short;
      animation-timing-function: linear;
      animation-range: entry 84% entry 100%;
    }

    /* The current word: full ink, stepped in */
    .invest--stage .invest-stage__word {
      animation-name: stage-word-on;
      animation-timing-function: linear;
    }
    .invest--stage .invest-stage__word--protection { animation-range: entry 58% entry 82%; }
    .invest--stage .invest-stage__word--impact { animation-range: contain 18% contain 22%; }
    .invest--stage .invest-stage__word--verification { animation-range: contain 48% contain 52%; }
    .invest--stage .invest-stage__word--structure { animation-range: contain 78% contain 82%; }

    .invest--stage .invest-stage__word-off {
      animation-name: stage-word-off;
      animation-timing-function: linear;
    }
    .invest--stage .invest-stage__word--protection .invest-stage__word-off { animation-range: contain 18% contain 22%; }
    .invest--stage .invest-stage__word--impact .invest-stage__word-off { animation-range: contain 48% contain 52%; }
    .invest--stage .invest-stage__word--verification .invest-stage__word-off { animation-range: contain 78% contain 82%; }
    .invest--stage .invest-stage__word--structure .invest-stage__word-off { animation: none; }

    /* The sentences: each set rises in after the one before has risen away */
    .invest--stage .invest-stage__text {
      animation-name: stage-rise;
      animation-timing-function: linear;
    }
    .invest--stage .invest-stage__text--protection { animation-range: entry 62% entry 88%; }
    .invest--stage .invest-stage__text--impact { animation-range: contain 20% contain 22%; }
    .invest--stage .invest-stage__text--verification { animation-range: contain 50% contain 52%; }
    .invest--stage .invest-stage__text--structure { animation-range: contain 80% contain 82%; }

    .invest--stage .invest-stage__text-off {
      animation-name: stage-leave;
      animation-timing-function: linear;
    }
    .invest--stage .invest-stage__text--protection .invest-stage__text-off { animation-range: contain 18% contain 20%; }
    .invest--stage .invest-stage__text--impact .invest-stage__text-off { animation-range: contain 48% contain 50%; }
    .invest--stage .invest-stage__text--verification .invest-stage__text-off { animation-range: contain 78% contain 80%; }
    .invest--stage .invest-stage__text--structure .invest-stage__text-off { animation: none; }

  }

  /* Phones, tablets and short screens: one moment per principle. The
     hairline draws, the word rises out of it, the sentences follow. It
     plays in the lower middle of the screen, where the eye is while
     scrolling, and is resolved before the principle reaches mid screen. */
  @media (prefers-reduced-motion: no-preference) {
    @media not all and (min-width: 64rem) and (min-height: 40rem) {
      .invest--stage .invest-stage__title {
        animation: stage-rise-short linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 100%;
      }

      .invest--stage .invest-stage__line,
      .invest--stage .invest-stage__foot-rule {
        animation: stage-draw linear both;
        animation-timeline: view();
        animation-range: cover 8% cover 26%;
      }

      .invest--stage .invest-stage__word {
        view-timeline: --stage-word block;
      }

      .invest--stage .invest-stage__word-in {
        animation: stage-mask linear both;
        animation-timeline: --stage-word;
        animation-range: cover 20% cover 34%;
      }

      .invest--stage .invest-stage__text {
        animation: stage-rise linear both;
        animation-timeline: view();
        animation-range: cover 16% cover 32%;
      }

      .invest--stage .invest-stage__sectors {
        animation: stage-rise-short linear both;
        animation-timeline: view();
        animation-range: cover 12% cover 28%;
      }
    }
  }
}

/* Where scroll-fallback.js plays the scenes instead, the CSS
   versions stand down so the two never run at once */
@media (prefers-reduced-motion: no-preference) {
  html.sdt-fallback .invest--stage .invest-stage__title,
  html.sdt-fallback .invest--stage .invest-stage__word,
  html.sdt-fallback .invest--stage .invest-stage__word-off,
  html.sdt-fallback .invest--stage .invest-stage__word-in,
  html.sdt-fallback .invest--stage .invest-stage__line,
  html.sdt-fallback .invest--stage .invest-stage__text,
  html.sdt-fallback .invest--stage .invest-stage__text-off,
  html.sdt-fallback .invest--stage .invest-stage__foot-rule,
  html.sdt-fallback .invest--stage .invest-stage__sectors {
    animation: none;
  }
}

@keyframes stage-rise {
  from { opacity: 0; transform: translateY(2.25rem); animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); }
  to { opacity: 1; transform: translateY(0rem); }
}

@keyframes stage-rise-short {
  from { opacity: 0; transform: translateY(1rem); animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); }
  to { opacity: 1; transform: translateY(0rem); }
}

@keyframes stage-leave {
  from { opacity: 1; transform: translateY(0rem); animation-timing-function: cubic-bezier(0.7, 0, 0.84, 0); }
  to { opacity: 0; transform: translateY(-1.5rem); }
}

@keyframes stage-mask {
  from { transform: translateY(100%); animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); }
  to { transform: translateY(0%); }
}

/* Ink at 0.48 on paper reads as grey at 3.3:1 */
@keyframes stage-word-on {
  from { opacity: 0.48; transform: translateX(-0.8em); animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1); }
  to { opacity: 1; transform: translateX(0em); }
}

@keyframes stage-word-off {
  from { opacity: 1; transform: translateX(0em); animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1); }
  to { opacity: 0.48; transform: translateX(-0.8em); }
}

@keyframes stage-draw {
  from { clip-path: inset(0 100% 0 0); animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); }
  to { clip-path: inset(0 0% 0 0); }
}
