/* Spectrum Impact. Story pages: about and thesis.
   Built on the tokens and parts in site.css and pages.css (page head, statement, facts, rows, link-arrow).
   Only what is new lives here. Every colour is a token from site.css, and the one colour is var(--spectrum),
   cut into slices with background-size and background-position. Nothing else is written twice.

   Motion: js/motion.js reveals everything marked data-lines, data-fade, data-clip, data-words and data-spot.
   The few resting states this file adds sit under html.js-motion.story-on. js/story.js sets story-on only once
   it is watching, and the head script takes js-motion away if motion never starts, so without either class the
   page is whole. Transform, opacity, clip-path and color only. */

/* ------------------------------------------------------------ page head */

.st-head .pg-meta { margin-top: clamp(20px, 2.2vw, 32px); }
.st-lead { padding-block: clamp(72px, 10.5vw, 168px) var(--sec); }
.st-lead .facts { margin-top: clamp(64px, 9vw, 144px); }
/* One sentence at display size, the rest of the opening at the lead size of the section intros. */
.st-lead-t { margin-top: clamp(28px, 3.6vw, 60px); font-size: clamp(1.25rem, 1.9vw, 1.875rem); line-height: 1.26; letter-spacing: -0.02em; font-weight: 500; color: var(--fg2); max-width: 31em; text-wrap: pretty; }
/* The four facts start on one line, so their values share a baseline however many lines one of them runs to. */
.facts.facts-4 li { align-content: start; }
@media (min-width: 900px) {
  .st-lead-t { margin-left: calc(50% + 12px); }
}

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

.st { padding-block: var(--sec); }
.st-h { font-size: clamp(2.4rem, 6.4vw, 6.75rem); text-wrap: balance; }
.st-top { display: grid; gap: clamp(28px, 3.4vw, 56px); margin-bottom: clamp(56px, 7.4vw, 120px); }
.st-intro { font-size: clamp(1.25rem, 1.9vw, 1.875rem); line-height: 1.24; letter-spacing: -0.02em; font-weight: 500; max-width: 31em; text-wrap: pretty; }
.st-body p { font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); line-height: 1.44; color: var(--fg2); max-width: 35rem; text-wrap: pretty; }
.st-body p:first-child { color: var(--fg); }
.st-body p + p { margin-top: 1.05em; }
.st-body-2 p:first-child { color: var(--fg2); }
.st-key { font-size: clamp(1.625rem, 3.3vw, 3.5rem); font-weight: 500; line-height: 1.08; letter-spacing: -0.034em; max-width: 19em; text-wrap: balance; }
.st-more { margin-top: clamp(36px, 4vw, 64px); }
/* A link inside a fade that has not played yet is shown the moment it takes keyboard focus, so focus never
   lands on something invisible. */
html.js-motion [data-fade]:not(.m-in):focus-within { opacity: 1; transform: none; }

/* A link inside running copy. The rule is the text colour; the hit area is widened without moving a line. */
.tl { --tl-pad: 0.55em; color: var(--fg); padding-block: var(--tl-pad); background: linear-gradient(currentColor, currentColor) 0 calc(100% - var(--tl-pad) + 3px) / 100% 1px no-repeat; transition: background-size 0.45s var(--ease); }
.tl:focus-visible { outline-offset: 2px; }
@media (hover: hover) {
  .tl { background-position: 100% calc(100% - var(--tl-pad) + 3px); }
  .tl:hover { background-size: 0 1px; }
}
/* Under a finger the same link is 44px tall and never narrower than that, and the rule still sits under the word only. */
@media (hover: none) {
  .tl { --tl-pad: 0.8em; padding-inline: 0.5em; margin-inline: -0.5em; background-position: 50% calc(100% - var(--tl-pad) + 3px); background-size: calc(100% - 1em) 1px; }
}

@media (min-width: 700px) {
  .facts.facts-4 { grid-template-columns: repeat(2, 1fr); row-gap: 40px; }
  .st-top { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; align-items: end; }
  .st-top .st-h { grid-column: 1 / -1; }
  .st-top .st-intro, .st-top .st-more { grid-column: 7 / -1; }
}
/* A closing section with no rows under its intro: the link sits under the intro, and nothing is left below. */
.st-top .st-more { margin-top: 0; }
.init .st-top:last-child { margin-bottom: 0; }
@media (min-width: 1000px) {
  .facts.facts-4 { grid-template-columns: repeat(4, 1fr); }
}

/* --------------------------------------------------------------- people */

/* Three people, set in type. Each row is a small ledger line: the name is its headline, the role hangs under
   it in mono, the bio runs beside it on a wide screen. Mirik, the person a visitor is most likely to meet,
   carries a little more: a larger name, and a bio in the page ink instead of the second grey. */
.people { border-bottom: 1px solid var(--line); }
.pp { display: grid; gap: 20px; padding-block: 34px 42px; border-top: 1px solid var(--line); }
.pp-id { display: grid; gap: 14px; align-content: start; min-width: 0; }
.pp-name { font-size: clamp(2.5rem, 11.5vw, 3.6rem); font-weight: 500; letter-spacing: -0.042em; line-height: 0.96; text-wrap: balance; }
.pp-role { font: 400 0.75rem/1.5 var(--num); color: var(--fg3); max-width: 28rem; text-wrap: balance; }
.pp-r { display: block; }
.pp-body { display: grid; gap: 16px; justify-items: start; }
.pp-body p { font-size: clamp(1.0625rem, 1.3vw, 1.25rem); line-height: 1.44; color: var(--fg2); max-width: 33rem; text-wrap: pretty; }
/* The small mono line under a bio (awards, where the facts come from), the same under every name. */
.pp .pp-body p.pp-note { font: 400 0.75rem/1.55 var(--num); letter-spacing: 0; color: var(--fg3); max-width: 30rem; }
.pp-lead .pp-name { font-size: clamp(2.9rem, 14vw, 4.4rem); }
.pp-lead .pp-body p { color: var(--fg); font-size: clamp(1.125rem, 1.5vw, 1.4375rem); line-height: 1.4; letter-spacing: -0.008em; max-width: 36rem; }
/* The portrait hook (see the comment in the about source): only drawn once a photo is pasted in. */
.pp-fig { margin: 0 0 10px; width: clamp(7.5rem, 32vw, 11.5rem); aspect-ratio: 4 / 5; overflow: hidden; background: var(--line); }
.pp-fig img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.1); }

.origin { display: grid; gap: 22px; justify-items: start; margin-top: clamp(72px, 9vw, 152px); }
.origin-t { font-size: clamp(1.25rem, 1.9vw, 1.875rem); line-height: 1.26; letter-spacing: -0.02em; font-weight: 500; max-width: 31em; text-wrap: pretty; }
/* Aarti Industries in three numbers, the company's own. Rows on a phone, three columns from 700px. */
.origin-nums { display: grid; width: 100%; margin-top: clamp(10px, 2vw, 30px); border-top: 1px solid var(--line); }
.origin-nums li { display: grid; grid-template-columns: 7.25rem minmax(0, 1fr); align-items: baseline; gap: 16px; padding-block: 16px; border-bottom: 1px solid var(--line); }
.origin-nums b { font-weight: 500; font-size: clamp(1.75rem, 3.4vw, 3.5rem); line-height: 1; letter-spacing: -0.04em; font-variant-numeric: tabular-nums; }
.origin-nums span { font: 400 0.75rem/1.4 var(--num); color: var(--fg3); }
/* One short line naming the source, its two pages linked in place. */
.origin-src { font: 400 0.75rem/1.55 var(--num); color: var(--fg3); max-width: 36rem; text-wrap: pretty; }
.origin-src .tl { color: var(--fg); }

@media (min-width: 900px) {
  .pp { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; align-items: start; padding-block: clamp(36px, 3.6vw, 60px) clamp(44px, 4.4vw, 72px); }
  .pp-id { grid-column: 1 / span 7; gap: clamp(16px, 1.6vw, 24px); }
  .pp-name { font-size: clamp(3rem, 5.4vw, 5.75rem); }
  .pp-body { grid-column: 8 / -1; padding-top: 0.5em; }
  .pp-lead .pp-name { font-size: clamp(3.6rem, 7vw, 7.5rem); }
  .pp-lead .pp-body { padding-top: 0.7em; }
  .pp-fig { width: clamp(9rem, 12vw, 13rem); }
  .origin { margin-left: 50%; }
}
@media (min-width: 700px) {
  .origin-nums { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 24px; border-top: 0; }
  .origin-nums li { grid-template-columns: 1fr; gap: 12px; border-top: 1px solid var(--line); border-bottom: 0; padding-block: 18px 0; }
}
@media (min-width: 1200px) {
  .pp-role, .pp .pp-body p.pp-note, .origin-nums span, .origin-src { font-size: clamp(0.8125rem, 0.9vw, 0.875rem); }
}

/* --------------------------------------------------------- why we exist */

.why .st-h { margin-bottom: clamp(48px, 7vw, 112px); }
.why-to { font-size: clamp(4.5rem, 17vw, 17rem); line-height: 0.8; letter-spacing: -0.04em; color: var(--fg); }
.why-to .ln { padding: 0.12em 0.1em 0.16em 0; margin: -0.12em 0 -0.16em 0; }
.why-list { list-style: none; margin: 28px 0 0; padding: 0; border-top: 1px solid var(--line); }
.why-list li { padding-block: clamp(22px, 2.6vw, 40px); border-bottom: 1px solid var(--line); font-size: clamp(1.5rem, 3vw, 3.125rem); font-weight: 500; line-height: 1.08; letter-spacing: -0.034em; text-wrap: balance; }
@media (min-width: 900px) {
  .why-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; align-items: start; }
  .why-to { grid-column: 1 / span 4; position: sticky; top: calc(var(--nav-h) + 24px); }
  .why-list { grid-column: 5 / -1; margin-top: 0; }
}

/* ------------------------------------------------- what we do, and do not */

/* Two equal halves of one white section, what we do and what we do not, split by a hairline. It used to be
   white beside black, but each half then ran on into the section of its own tone above or below it and the
   page read as two L shapes. On a wide screen the two halves share one set of rows (subgrid): the headings
   sit on one line, and the four lines of each half start and end together, so every rule runs straight
   across both. Without subgrid each half simply keeps its own rows. */
.split-grid { display: grid; row-gap: clamp(72px, 12vw, 120px); }
.split-side { min-width: 0; }
.split-h { font-size: clamp(2.2rem, 4.6vw, 4.9rem); padding-bottom: clamp(40px, 5vw, 80px); }
.split-list { border-top: 1px solid var(--line); }
.split-list li { padding-block: clamp(20px, 2vw, 30px); border-bottom: 1px solid var(--line); font-size: clamp(1.125rem, 1.5vw, 1.5rem); line-height: 1.34; letter-spacing: -0.012em; color: var(--fg); max-width: 40rem; text-wrap: pretty; }
.split-not li { color: var(--fg2); font-size: clamp(1.0625rem, 1.3vw, 1.25rem); line-height: 1.44; letter-spacing: 0; }
.split-not strong { display: block; margin-bottom: 8px; font-size: clamp(1.5rem, 2.3vw, 2.375rem); font-weight: 500; line-height: 1.08; letter-spacing: -0.032em; color: var(--fg); text-wrap: balance; }
.split-not li strong:last-child { margin-bottom: 0; }
@media (min-width: 900px) {
  .split-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(5, auto); gap: 0; }
  .split-side { grid-row: 1 / span 5; display: grid; grid-template-rows: subgrid; }
  .split-side:first-child { padding-right: clamp(32px, 4vw, 72px); }
  .split-side-not { padding-left: clamp(32px, 4vw, 72px); border-left: 1px solid var(--line); }
  .split-h { align-self: end; }
  .split-list { grid-row: 2 / span 4; display: grid; grid-template-rows: subgrid; }
}

.pull-t { font-size: clamp(2.1rem, 6vw, 6.5rem); font-weight: 500; line-height: 0.98; letter-spacing: -0.042em; }

/* --------------------------------------------------------------- values */

/* Five values, five white words under the section's own headline. The spectrum appears once in this
   section: a hairline under the row being read (the middle of the screen as the page scrolls, a hover, or
   keyboard focus inside the row). The rule drawn above the list is a plain line. The words never take a
   colour; the rows not being read step back a little in opacity, never below 4.5 to 1. */
.spec-rule { height: 1px; margin-top: clamp(44px, 6vw, 100px); background: var(--line); transform-origin: left; }
.vals { border-bottom: 0; }
.val { position: relative; display: grid; gap: 14px; padding-block: clamp(26px, 3vw, 48px) clamp(28px, 3.2vw, 52px); border-bottom: 1px solid var(--line); }
.val::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--spectrum); transform: scaleX(0); transform-origin: left; transition: transform 0.8s var(--ease); }
.val-word { font-size: clamp(2.4rem, 11vw, 4rem); font-weight: 500; letter-spacing: -0.045em; line-height: 0.94; }
.val-ink { color: var(--fg); transition: opacity 0.35s linear; }
.val-text { font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); line-height: 1.38; color: var(--fg2); max-width: 30rem; text-wrap: pretty; }

html.js-motion.story-on .spec-rule:not(.is-in) { transform: scaleX(0); }
html.js-motion.story-on .spec-rule { transition: transform 1.6s var(--ease); }

.val:focus-within::after { transform: scaleX(1); }
@media (hover: hover) {
  /* Lit in turn by the scroll (js/story.js sets .is-now on the value crossing the middle of the screen). */
  html.js-motion .vals.has-now .val:not(.is-now) .val-ink { opacity: 0.62; }
  html.js-motion .val.is-now::after { transform: scaleX(1); }
  /* The pointer outranks the scroll. */
  .vals:hover .val:not(:hover) .val-ink { opacity: 0.62; }
  html.js-motion .vals:hover .val.is-now:not(:hover)::after { transform: scaleX(0); }
  html.js-motion .vals.has-now .val:hover .val-ink { opacity: 1; }
  .val:hover::after { transform: scaleX(1); }
}
@media (hover: none) {
  html.js-motion .vals.has-lit .val:not(.is-lit) .val-ink { opacity: 0.62; }
  html.js-motion .val.is-lit::after { transform: scaleX(1); }
}
@media (min-width: 900px) {
  .val { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); column-gap: 40px; align-items: end; }
  .val-word { font-size: clamp(2.75rem, 5.2vw, 5.75rem); }
  .val-text { padding-bottom: 0.75em; }
}

/* ----------------------------------------------------- rows on these pages */

/* The home thesis rows, reused. Rows that are not links keep the hover language and lose the press. */
.st-rows .row-text { max-width: 34rem; }
.st-h + .st-rows { margin-top: clamp(48px, 6.4vw, 108px); }
html.js-motion .row.row-still { --press: 1; }
.row-still { cursor: default; }
h3.row-word { margin: 0; }
.row-led { --fw: clamp(2.4rem, 5.6vw, 6rem); }
.row-led .row-word { font-size: var(--fw); letter-spacing: -0.042em; line-height: 0.96; text-wrap: balance; }
.row-led .row-word sub, .row-text sub { font-size: 0.7em; line-height: 0; }
.row[target="_blank"] .row-go::after { content: "\2197"; }
@media (hover: hover) { .row[target="_blank"]:hover .row-go::after { transform: translate(3px, -3px); } }
@media (min-width: 700px) {
  .row.row-still { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: end; }
  /* The ledger: every row starts from its top hairline with the same padding, and the first line of the copy
     stands on the cap height of the big word beside it, however many lines either runs to. In Switzer a
     line's cap top sits 0.165em below its box at a line height of 0.96 (the word) and 0.365em below at 1.36
     (the copy), from the face's own ascent 0.98, descent 0.25 and cap height 0.68, so the copy is pushed
     down by the difference. */
  /* The second column starts where column 7 of the page grid does, under the section intro and the copy above. */
  .row.row-led { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 24px; align-items: start; }
  .row-led .row-text { line-height: 1.36; padding-top: max(0px, calc(var(--fw) * 0.165 - 0.365em)); }
}
/* On a phone the spotlight steps the big word back, never the copy: on white the copy would fall under 4.5 to 1. */
@media (hover: none) {
  html.js-motion .rows.st-rows.has-lit .row:not(.is-lit) .row-text { opacity: 1; }
  html.js-motion .row[target="_blank"].is-lit .row-go::after { transform: translate(3px, -3px); }
}

/* ------------------------------------------------------- beyond climate */

/* The four other themes as a type led list, the way the home page lists its themes: each row a link into the
   portfolio, the word at the ledger's size, the way in beside it on the word's cap height (the rule in the
   rows section above). Rows, their hover and the theme's hairline are the shared ones in site.css and
   js/app.js. The one line per theme is the home page's, so it is not repeated here. */
@media (min-width: 700px) {
  .row-led .row-go { margin-top: max(0px, calc(var(--fw) * 0.165 - 0.435em)); }
}

/* -------------------------------------------------------------- beliefs */

.bl-grid { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: clamp(40px, 5vw, 88px); }
.bl-grid > * { min-width: 0; }
.st-body-2 { margin-top: calc(-1 * clamp(8px, 1.4vw, 28px)); }
/* In the closing section the grid gap already spaces the link and the source note. */
.bl-grid > .st-more, .bl-grid > .st-note { margin-top: 0; }
@media (min-width: 900px) {
  .bl-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; }
  .bl-grid > * { grid-column: 1 / -1; }
  .bl-grid > .st-body { grid-column: 7 / -1; }
  .bl-grid > .st-key { grid-column: 1 / span 11; margin-top: clamp(16px, 2.4vw, 48px); }
}
/* Room for the index. Only where the index shows. */
@media (min-width: 1100px) and (hover: hover) {
  html.story-js .bl > .w { padding-left: clamp(11rem, 14vw, 15rem); }
}

.st-quote { margin: clamp(24px, 4vw, 72px) 0 0; display: grid; gap: clamp(18px, 2vw, 28px); }
.st-quote blockquote { margin: 0; }
/* The one quote on the page. Set in the headline face like every other big line; the emphasis face is kept
   to the two marks, so the belief heading above it keeps the only Boska word in the section. The opening
   mark hangs into the margin by its own width, so the words start on the text's edge. Both marks are the
   text's size and drop 0.1em, which puts their tops on the cap height of the Switzer beside them (Boska's
   marks rise 0.78em, Switzer's capitals 0.68em). A line's descenders reach 0.23em, so under the tightest
   line height here (1.02) a mark keeps about 0.1em clear of the line above, whatever falls over it. The
   closing mark is tied to the last word, so it never starts a line of its own. */
.st-quote blockquote p { font-size: clamp(2.1rem, 4.9vw, 5.25rem); font-weight: 500; line-height: 1.02; letter-spacing: -0.042em; max-width: 14em; text-wrap: balance; }
.q-m { position: relative; top: 0.1em; font-family: var(--serif); font-style: italic; font-weight: 300; font-size: 1em; line-height: 0; letter-spacing: 0; }
.q-open { margin-left: -0.318em; }
.q-end { white-space: nowrap; }
.st-quote figcaption { font: 400 0.75rem/1.3 var(--num); color: var(--fg3); padding-left: 0.2em; }

/* ------------------------------------------------- the capital spectrum */

.cap { margin: clamp(32px, 5vw, 96px) 0 0; scroll-margin-top: clamp(28px, 5vh, 56px); }
.cap-stops { list-style: none; margin: 0; padding: 0; display: grid; position: relative; }
.cap-stop, .cap-end { position: relative; display: grid; align-content: start; gap: 18px; padding: 26px 0 52px; }
/* The strip. Stop --i shows its own quarter of the gradient, so four strips in a row are one unbroken line. */
.cap-stop::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--spectrum) calc(var(--i, 0) * 33.3333%) 0 / 400% 100% no-repeat; transform-origin: left; }
/* The tick where a stop begins, the way an axis marks a value. */
.cap-stop::after, .cap-end::after { content: ""; position: absolute; left: 0; top: 2px; width: 1px; height: 12px; background: var(--fg3); }
/* Past the last stop the line is no longer ours: no colour, and it fades out. */
.cap-end::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: linear-gradient(90deg, var(--fg2), transparent 92%) 0 0 / 100% 1px no-repeat; transform-origin: left; }
.cap-name { font-size: clamp(1.75rem, 2.3vw, 2.4rem); font-weight: 500; letter-spacing: -0.034em; line-height: 1.02; text-wrap: balance; }
.cap-k { display: block; margin-bottom: 7px; font: 400 0.75rem/1.3 var(--num); letter-spacing: 0; color: var(--fg3); }
.cap-pays, .cap-proof { font-size: 1.0625rem; line-height: 1.42; color: var(--fg2); max-width: 30rem; text-wrap: pretty; }
.cap-end-t { font-size: clamp(2.1rem, 9vw, 3.2rem); font-weight: 500; letter-spacing: -0.04em; line-height: 0.98; }
.cap-end-t em { display: block; }
.cap-end { padding-bottom: 0; }
.cap figcaption { margin-top: clamp(40px, 5vw, 80px); padding-top: 18px; border-top: 1px solid var(--line); font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); color: var(--fg2); text-wrap: balance; }
.cap-cap-t { display: block; }
/* Where the proof points come from, said where they are read. */
.cap-src { display: block; margin-top: 12px; font: 400 0.75rem/1.55 var(--num); color: var(--fg3); max-width: 44rem; text-wrap: pretty; }

.cap-stop::before, .cap-end::before { transition: transform 1s var(--ease-q); }
.cap-stop > *, .cap-end > *, .cap-stop::after, .cap-end::after { transition: opacity 0.7s linear, transform 0.9s var(--ease); }
html.js-motion.story-on .cap-stop:not(.is-in)::before, html.js-motion.story-on .cap-end:not(.is-in)::before { transform: scaleX(0); }
html.js-motion.story-on :is(.cap-stop, .cap-end):not(.is-in) > * { opacity: 0; transform: translateY(14px); }
html.js-motion.story-on :is(.cap-stop, .cap-end):not(.is-in)::after { opacity: 0; }

@media (min-width: 1000px) {
  .cap-stops { grid-template-columns: repeat(4, minmax(0, 1fr)) minmax(0, 1.08fr); grid-template-rows: auto auto auto; }
  .cap-stop, .cap-end { grid-row: 1 / span 3; grid-template-rows: subgrid; gap: 0; row-gap: 22px; padding: 30px 22px 0 0; }
  .cap-end { padding-right: 0; padding-left: 0; }
  .cap-name { font-size: clamp(1.5rem, 2.1vw, 2.25rem); padding-bottom: 6px; }
  .cap-pays, .cap-proof { font-size: clamp(0.9375rem, 1.05vw, 1.0625rem); line-height: 1.44; }
  .cap-end-t { font-size: clamp(1.75rem, 2.5vw, 2.7rem); grid-row: 1 / span 3; padding-left: 0; }
  /* One glow under the four strips, the way the lines of the home spectrum glow. */
  .cap-stops::before { content: ""; position: absolute; left: 0; top: -3px; width: calc(100% * 4 / 5.08); height: 8px; background: var(--spectrum); filter: blur(14px); opacity: 0.5; pointer-events: none; transition: opacity 2.2s linear 0.4s; }
  html.js-motion.story-on .cap-stops:not(.is-in)::before { opacity: 0; }
  /* The line travels at one speed: each strip starts as the one before it ends, then the tail eases out. */
  .cap-stop::before { transition: transform 0.5s linear calc(var(--i, 0) * 0.5s); }
  .cap-end::before { transition: transform 1.1s var(--ease) 2s; }
  .cap-stop > *, .cap-end > *, .cap-stop::after, .cap-end::after { transition-delay: calc(var(--i, 0) * 0.5s + 0.1s); }
}

/* ------------------------------------------------------------ the relay */

.relay { --rl-h: 24rem; position: relative; margin: 0; }
.relay-stages { list-style: none; margin: 0; padding: 0; }
.relay-stage { position: relative; height: calc(var(--rl-h) / 3); padding-left: 32px; }
.relay-who { margin: 0 0 6px; font-size: 1.375rem; font-weight: 500; letter-spacing: -0.026em; line-height: 1.08; }
.relay-stage p { font-size: 1.0625rem; line-height: 1.4; color: var(--fg2); max-width: 26rem; text-wrap: pretty; }
.relay-dot { position: absolute; left: 0; top: 5px; width: 11px; height: 11px; border-radius: 50%; background: var(--bg); box-shadow: inset 0 0 0 1px var(--fg2); z-index: 1; }
.relay-dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--fg); transition: transform 0.5s var(--spring, var(--ease)), opacity 0.3s linear; }
/* The track is one horizontal line. On a phone it is turned to run down the side: its length is known
   (--rl-h), which is the one thing a turned element needs. */
.relay-track { position: absolute; left: 6.5px; top: 10px; width: calc(var(--rl-h) - 18px); height: 2px; transform: rotate(90deg); transform-origin: 0 0; }
.relay-rail, .relay-baton { position: absolute; inset: 0; }
.relay-rail { background: linear-gradient(var(--fg3), var(--fg3)) 0 50% / 100% 1px no-repeat; opacity: 0.6; }
.relay-baton { background: var(--spectrum); }
html.js-motion.story-on .relay.is-live .relay-baton { clip-path: inset(-2px calc((1 - var(--p, 0)) * 84%) -2px calc(var(--p, 0) * 84%)); }
html.js-motion.story-on .relay.is-live .relay-stage:not(.is-on) .relay-dot::after { transform: scale(0); opacity: 0; }
@media (min-width: 900px) {
  .relay { padding-top: 34px; margin-block: clamp(8px, 2vw, 32px); }
  .relay-stages { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 24px; }
  .relay-stage { height: auto; padding: 0 12px 0 0; }
  .relay-dot { top: -39.5px; }
  .relay-track { left: 0; right: 0; top: 0; width: auto; transform: none; }
  .relay-who { font-size: clamp(1.375rem, 1.9vw, 2rem); margin-bottom: 10px; }
  .relay-stage p { font-size: clamp(1rem, 1.2vw, 1.1875rem); }
}

/* ------------------------------------------------------ index and progress */

.tix, .tpb { display: none; }
.tix ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
/* Each label is the opening words of its heading, word for word, so the index and the page never disagree. */
/* Two inks. The list itself is in the ink for black sections; js/story.js lays a copy in the ink for white
   sections, on the white ground, over it and clips the copy to the part of the list a white section is behind.
   No colour transitions, so no label ever passes through a grey that reads on neither tone. */
.tix { --tx: var(--on-dark); --tx3: var(--on-dark-3); }
.tix-ink { --tx: var(--ink); --tx3: var(--on-light-3); position: absolute; inset: 0; background: var(--white); pointer-events: none; clip-path: inset(100% 0 0 0); }
.tix a { display: flex; align-items: flex-start; gap: 10px; min-height: 32px; padding-block: 5px; font: 400 0.75rem/1.3 var(--num); color: var(--tx3); }
.tix a::before { content: ""; flex: none; width: 18px; height: 1px; margin-top: 0.65em; background: currentColor; transform: scaleX(0.34); transform-origin: left; transition: transform 0.6s var(--ease); }
.tix a[aria-current], .tix a.is-cur { color: var(--tx); }
.tix a[aria-current]::before, .tix a.is-cur::before { transform: scaleX(1); }
.tix-ink a.is-foc { outline: 2px solid currentColor; outline-offset: 4px; border-radius: 2px; }
/* The focused label takes the full ink, so its ring is as strong as the current label on either ground. */
.tix a:focus-visible, .tix-ink a.is-foc { color: var(--tx); }
@media (min-width: 1100px) and (hover: hover) {
  /* The list is drawn in the ink of the section behind it, to the pixel (the two layers above), so it stays
     on screen from the first belief to the last, across every edge between a black and a white section. It stays in the tab order: a keyboard that reaches it before the beliefs are on screen scrolls
     them in (js/story.js), so the list is shown in its own margin and never over the opening text. */
  html.story-js .tix { display: block; position: fixed; z-index: 20; left: max(var(--gut), calc((100vw - 1720px) / 2)); top: 50%; width: clamp(9rem, 11vw, 12rem); transform: translateY(-50%); opacity: 0; pointer-events: none; transition: opacity 0.3s linear; }
  html.story-js .tix.is-on, html.story-js .tix:focus-within { opacity: 1; pointer-events: auto; }
  .tix a:hover, .tix a.is-hov { color: var(--tx); }
  .tix a:hover::before, .tix a.is-hov::before { transform: scaleX(1); }
}
@media (max-width: 1099px), (hover: none) {
  html.story-js .tpb {
    display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: 8px 14px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; padding: 11px var(--gut) calc(12px + env(safe-area-inset-bottom, 0px));
    font: 400 0.75rem/1.3 var(--num); border-top: 1px solid var(--line);
    transform: translateY(101%); visibility: hidden; transition: transform 0.5s var(--ease), visibility 0s linear 0.5s, background-color 0.3s linear, color 0.3s linear;
  }
  html.story-js .tpb.is-on { transform: none; visibility: visible; transition: transform 0.6s var(--ease), visibility 0s, background-color 0.3s linear, color 0.3s linear; }
  .tpb-k { color: var(--fg3); }
  .tpb-k b { font-weight: 500; color: var(--fg); }
  .tpb-t { color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tpb-segs { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
  .tpb-segs i { position: relative; height: 2px; background: var(--line); overflow: hidden; }
  .tpb-segs i::after { content: ""; position: absolute; inset: 0; background: var(--fg); transform: scaleX(var(--f, 0)); transform-origin: left; }
}

/* ---------------------------------------------------------- source note */

.st-note { display: grid; gap: 10px; margin-top: clamp(72px, 9vw, 152px); padding-top: 18px; border-top: 1px solid var(--line); }
.st-note > p:first-child { font: 400 0.75rem/1.55 var(--num); color: var(--fg3); max-width: 44rem; }
.st-note-links { display: flex; flex-wrap: wrap; gap: 0 28px; }

/* --------------------------------------------------------- breakpoints */

@media (max-width: 699px) {
  .st-lead { padding-top: 80px; }
  .st-top { margin-bottom: 56px; }
  .st-key { line-height: 1.1; letter-spacing: -0.03em; }
  .pull-t { line-height: 1.02; }
  .row-led { gap: 12px; padding-block: 28px; }
  .st-quote blockquote p { line-height: 1.06; }
}
@media (min-width: 1200px) {
  .cap-k, .cap-src, .st-note > p:first-child, .st-quote figcaption, .tix a { font-size: clamp(0.8125rem, 0.9vw, 0.875rem); }
}

@media (prefers-reduced-motion: reduce) {
  html.js-motion .spec-rule, html.js-motion .cap-stop::before, html.js-motion .cap-end::before { transform: none !important; }
  html.js-motion :is(.cap-stop, .cap-end) > *, html.js-motion .cap-stop::after, html.js-motion .cap-end::after, html.js-motion .cap-stops::before { opacity: 1 !important; transform: none !important; }
  html.js-motion .cap-stops::before { opacity: 0.5 !important; }
  html.js-motion .relay .relay-baton { clip-path: none !important; }
  html.js-motion .relay .relay-dot::after { transform: none !important; opacity: 1 !important; }
}

/* ---------------------------------------------------------- portrait slot */

/* One portrait slot for the family page and the team. Until a photo exists the slot is set in type: the first
   name in the Boska italic, sized to the slot's width (container units, --n is the name's length), on a quiet
   panel one step off the section ground. A 3px foot carries one slice of the spectrum (--i, a third each), so
   three slots in a row read as one line. js/story.js puts the photo in when its file loads; the photo is
   greyed like every photo on the site. Motion: the slot opens from its centre (data-clip), the foot draws. */
.pt { position: relative; margin: 0; aspect-ratio: 4 / 5; overflow: hidden; container-type: inline-size; background: color-mix(in oklch, var(--fg) 5%, var(--bg)); box-shadow: inset 0 0 0 1px var(--line); }
.pt::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; z-index: 1; background: var(--spectrum) calc(var(--i, 0) * 50%) 0 / 300% 100% no-repeat; transform-origin: left; transition: transform 1.3s var(--ease) 0.35s; }
.pt-mono { position: absolute; left: 7cqi; right: 4cqi; bottom: 9cqi; font-family: var(--serif); font-style: italic; font-weight: 300; font-size: min(36cqi, calc(205cqi / var(--n, 6))); line-height: 0.9; letter-spacing: -0.035em; color: var(--fg); white-space: nowrap; transition: transform 1.3s var(--ease) 0.15s, opacity 0.9s linear 0.15s; }
.pt img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; filter: grayscale(1) contrast(1.06); }
.pt.has-photo .pt-mono { display: none; }
html.js-motion .pt[data-clip]:not(.m-in)::after { transform: scaleX(0); }
html.js-motion .pt[data-clip]:not(.m-in) .pt-mono { transform: translateY(22%); opacity: 0; }

/* ---------------------------------------------------------- family page */

.fm-idx { margin-top: clamp(64px, 9vw, 144px); }
.fm-idx div { font-size: clamp(1.0625rem, 1.3vw, 1.25rem); }
@media (min-width: 900px) { .fm-head .st-lead-t { margin-left: calc(50% + 12px); } }

/* Aarti Industries in three figures, at poster size. */
.fm-nums { display: grid; border-top: 1px solid var(--line); }
.fm-nums li { display: grid; gap: 12px; padding-block: 22px 28px; border-bottom: 1px solid var(--line); }
.fm-nums b { font-weight: 500; font-size: clamp(5rem, 26vw, 11rem); line-height: 0.84; letter-spacing: -0.06em; font-variant-numeric: tabular-nums; }
.fm-nums span { font: 400 0.75rem/1.45 var(--num); color: var(--fg3); max-width: 17rem; text-wrap: pretty; }
.fm-src { margin-top: 22px; }
@media (min-width: 700px) {
  .fm-nums { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 24px; border-top: 0; }
  .fm-nums li { border-top: 1px solid var(--line); border-bottom: 0; padding-block: 26px 0; }
  .fm-nums b { font-size: clamp(4.5rem, 10.4vw, 11rem); }
}

/* The principals. A phone reads portrait, name, role, the one paragraph, then the marks. From 900px the
   portrait holds the left third while the rest runs beside it. */
.fm-people .st-h { margin-bottom: clamp(48px, 7vw, 112px); }
.fps { border-top: 1px solid var(--line); }
.fp { display: grid; gap: 26px; padding-block: clamp(36px, 5vw, 88px); border-bottom: 1px solid var(--line); scroll-margin-top: var(--nav-h); }
.fp .pt { width: min(64%, 20rem); }
.fp-marks li:last-child { border-bottom: 0; }
.fp-id { display: grid; gap: 14px; min-width: 0; }
.fp-name { font-size: clamp(2.6rem, 11.5vw, 7rem); font-weight: 500; letter-spacing: -0.045em; line-height: 0.96; text-wrap: balance; }
.fp-role { font: 400 0.75rem/1.55 var(--num); color: var(--fg3); }
.fp-role span { display: block; }
.fp-role span:first-child { color: var(--fg); }
.fp-body { display: grid; gap: 22px; justify-items: start; }
.fp-body p { font-size: clamp(1.125rem, 1.55vw, 1.5rem); line-height: 1.36; letter-spacing: -0.012em; max-width: 34rem; text-wrap: pretty; }
.fp-marks { border-top: 1px solid var(--line); }
.fp-marks li { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: 16px; align-items: baseline; padding-block: 14px; border-bottom: 1px solid var(--line); }
.fp-marks span { font: 400 0.75rem/1.4 var(--num); color: var(--fg3); }
.fp-marks p { font-size: 0.9375rem; line-height: 1.45; color: var(--fg2); max-width: 26rem; text-wrap: pretty; }
@media (min-width: 900px) {
  .fp { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; row-gap: clamp(28px, 2.8vw, 44px); align-items: start; }
  .fp .pt { grid-column: 1 / span 4; grid-row: 1 / span 3; width: 100%; }
  .fp-id, .fp-body, .fp-marks { grid-column: 6 / -1; }
  .fp-body p { max-width: 36rem; }
  .fp-marks { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 24px; border-top: 0; margin-top: clamp(8px, 1.6vw, 24px); }
  .fp-marks li { grid-template-columns: 1fr; gap: 10px; align-content: start; border-top: 1px solid var(--line); border-bottom: 0; padding-block: 16px 0; }
}
@media (min-width: 1200px) {
  .fp-role, .fp-marks span, .fm-nums span, .tm-role { font-size: clamp(0.8125rem, 0.9vw, 0.875rem); }
}

/* What the family built beyond the company: one real photograph, then the ledger rows. */
.fm-photo { margin: 0 0 clamp(48px, 6vw, 104px); }
.fm-photo-box { position: relative; overflow: hidden; aspect-ratio: 4 / 3; background: var(--line); }
.fm-photo-box img { width: 100%; height: 112%; object-fit: cover; object-position: 30% 40%; filter: grayscale(1) contrast(1.05); }
.fm-photo figcaption { margin-top: 12px; font: 400 0.75rem/1.4 var(--num); color: var(--fg3); }
@media (min-width: 700px) { .fm-photo-box { aspect-ratio: 21 / 9; } }

.fm-close .pull-t { max-width: 13em; }
.fm-close-t { margin-top: clamp(32px, 4vw, 64px); font-size: clamp(1.125rem, 1.55vw, 1.5rem); line-height: 1.36; color: var(--fg2); max-width: 30rem; text-wrap: pretty; }
.fm-close-links { display: flex; flex-wrap: wrap; gap: 14px 36px; }
@media (min-width: 900px) { .fm-close-t, .fm-close-links { margin-left: calc(50% + 12px); } }

/* ------------------------------------------------------- about: family, team */

/* The one way from About to the family page: the three first names at display size, the whole row a link. */
.fam .st-top { margin-bottom: clamp(40px, 5vw, 80px); }
.fam-go { display: grid; gap: 14px; padding-block: clamp(24px, 3vw, 44px); border-block: 1px solid var(--line); position: relative; }
.fam-go-k { font: 400 0.75rem/1.4 var(--num); color: var(--fg3); }
.fam-go-ns { font-size: clamp(2.2rem, 7.4vw, 7.5rem); font-weight: 500; letter-spacing: -0.045em; line-height: 0.98; padding-right: 1.4em; text-wrap: balance; }
.fam-go-a { position: absolute; right: 0; bottom: clamp(24px, 3vw, 44px); font-size: clamp(2rem, 5vw, 5rem); line-height: 1; transition: transform 0.6s var(--ease); }
.fam-go::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--spectrum); transform: scaleX(0); transform-origin: left; transition: transform 0.8s var(--ease); }
.fam-go:focus-visible::after, .fam-go.is-lit::after { transform: scaleX(1); }
@media (hover: hover) {
  .fam-go:hover::after { transform: scaleX(1); }
  .fam-go:hover .fam-go-a { transform: translateX(8px); }
}

/* The team, from data/team.js. The heading holds the left half; the cards fill the right half two to a row,
   so two people or twelve look settled. */
.team-grid { margin-top: clamp(88px, 11vw, 176px); display: grid; gap: clamp(40px, 5vw, 72px); }
.team-top { display: grid; gap: clamp(20px, 2.4vw, 36px); align-content: start; }
.team-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 16px; }
.tm { display: grid; gap: 8px; align-content: start; }
.tm .pt { margin-bottom: 10px; }
.tm-name { font-size: clamp(1.375rem, 2.2vw, 2.25rem); font-weight: 500; letter-spacing: -0.03em; line-height: 1.04; }
.tm-role { font: 400 0.75rem/1.4 var(--num); color: var(--fg3); }
.tm-line { font-size: clamp(0.9375rem, 1.1vw, 1.0625rem); line-height: 1.45; color: var(--fg2); max-width: 24rem; text-wrap: pretty; }
.tm-in { justify-self: start; margin-top: 6px; }
@media (min-width: 900px) {
  .team-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; }
  .team-top { grid-column: 1 / span 5; position: sticky; top: calc(var(--nav-h) + 24px); }
  .team-list { grid-column: 7 / -1; gap: 56px 24px; }
}
@media (max-width: 419px) {
  .team-list { gap: 32px 12px; }
}

@media (prefers-reduced-motion: reduce) {
  html.js-motion .pt::after, html.js-motion .pt .pt-mono { transform: none !important; opacity: 1 !important; }
}

/* Team page: the people lead, straight under the title, four to a row on a wide screen. */
.st-head .team-grid { margin-top: clamp(40px, 5vw, 88px); display: block; }
.st-head .team-list { grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); gap: 48px 24px; }
.st-head .team-grid + .st-lead { margin-top: clamp(88px, 11vw, 176px); }
@media (max-width: 599px) { .st-head .team-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px 12px; } }
