/* Spectrum Impact. Shared site styles.
   Direction: black and white. The only color on the page is the portfolio
   spectrum, drawn in the gradient of the Spectrum Impact logo mark. */

:root {
  --black: oklch(0.13 0.005 260);
  --white: #fff;
  /* One black. Ink used to carry a navy tint, so every pill and pressed chip on a white band read navy
     beside the black tiles and sections. Text, fills and grounds now share the same black. */
  --ink: var(--black);
  --on-dark: #fff;
  --on-dark-2: oklch(0.8 0.006 260);
  --on-dark-3: oklch(0.67 0.008 260);
  --on-light-2: oklch(0.36 0.008 260);
  --on-light-3: oklch(0.45 0.008 260);
  --line-dark: oklch(1 0 0 / 0.15);
  --line-light: color-mix(in oklch, var(--black) 15%, transparent);
  --spectrum: linear-gradient(90deg, #4B70B5, #795EA6, #A14D98, #ED2F77, #EB695F, #E99D4B, #E8D036, #B5D53C);

  --sans: "Switzer", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: "Boska", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --num: "Tabular", ui-monospace, "SF Mono", Menlo, monospace;

  --gut: clamp(20px, 3.4vw, 56px);
  --nav-h: 76px;
  --sec: clamp(88px, 13vw, 200px);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-q: cubic-bezier(0.25, 1, 0.5, 1);

  --z-follow: 30;
  --z-sheet: 39;
  --z-nav: 40;
  --z-progress: 41;
}

*, *::before, *::after { box-sizing: border-box; }
/* The page sets every color itself. "only light" tells phone browsers not to force-darken the white bands. */
html { color-scheme: only light; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: var(--nav-h); }
body {
  margin: 0;
  background: var(--black);
  color: var(--on-dark);
  font: 400 1rem/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
[hidden] { display: none !important; }
img, svg, canvas { display: block; max-width: 100%; }
h1, h2, h3, p, ul, address { margin: 0; }
ul { padding: 0; list-style: none; }
address { font-style: normal; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; text-align: inherit; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
em { font-family: var(--serif); font-style: italic; font-weight: 300; letter-spacing: -0.025em; }
sup { font: 500 max(0.2em, 11px)/1 var(--num); letter-spacing: 0; vertical-align: top; position: relative; top: 0.7em; margin-left: 0.35em; color: var(--fg3); }
:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; border-radius: 2px; }
main:focus, [data-jump]:focus { outline: 0; }
::selection { background: #ED2F77; color: var(--white); }

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip { position: fixed; left: 12px; top: -80px; z-index: 100; background: var(--white); color: var(--black); padding: 10px 16px; border-radius: 999px; }
.skip:focus { top: 12px; }
.w { width: min(100% - 2 * var(--gut), 1720px); margin-inline: auto; }

[data-tone="dark"] { --bg: var(--black); --fg: var(--on-dark); --fg2: var(--on-dark-2); --fg3: var(--on-dark-3); --line: var(--line-dark); background: var(--bg); color: var(--fg); }
[data-tone="light"] { color-scheme: only light; --bg: var(--white); --fg: var(--ink); --fg2: var(--on-light-2); --fg3: var(--on-light-3); --line: var(--line-light); background: var(--bg); color: var(--fg); }

.progress { position: fixed; inset: 0 0 auto 0; height: 2px; z-index: var(--z-progress); background: var(--spectrum); transform: scaleX(0); transform-origin: left; pointer-events: none; }

/* ------------------------------------------------------------ controls */

.pill {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 22px; border-radius: 999px; overflow: hidden; isolation: isolate;
  background: var(--fg); color: var(--bg);
  font-weight: 500; font-size: 0.9375rem; letter-spacing: -0.005em; white-space: nowrap;
  transition: box-shadow 0.35s var(--ease-q);
}
/* The spectrum is light, never paint: a pressed or hovered button keeps its black and white and draws one
   hairline of the logo gradient along its foot, inside the curve of its ends. */
.pill::before {
  content: ""; position: absolute; left: 22px; right: 22px; bottom: 0; z-index: 1; height: 1px;
  background: var(--spectrum); transform: scaleX(0); transform-origin: left;
  transition: transform 0.55s var(--ease);
}
.pill span { position: relative; display: inline-block; }
.pill-lg { min-height: 56px; padding: 0 32px; font-size: 1.0625rem; }
.pill-lg::before { left: 28px; right: 28px; }
.pill-arrow span::after { content: "\2192"; content: "\2192" / ""; display: inline-block; margin-left: 0.55em; transition: transform 0.45s var(--ease); }
.pill-ghost { background: transparent; color: var(--fg); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fg) 55%, transparent); }
/* Only the send button is ever disabled, while a message is on its way. It stays solid and readable. */
.pill[disabled] { cursor: progress; }
.pill:focus-visible::before { transform: none; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 0.5em; min-height: 44px;
  font-weight: 500; font-size: 1.0625rem; letter-spacing: -0.005em;
  background: linear-gradient(currentColor, currentColor) 0 calc(100% - 9px) / 100% 1px no-repeat;
}
.link-arrow::after { content: "\2192"; content: "\2192" / ""; display: inline-block; transition: transform 0.45s var(--ease); }
a.link-arrow[target="_blank"]::after { content: "\2197"; content: "\2197" / ""; }
/* A way back: its arrow points back and stands before the words. */
.link-back::after { content: none; }
.link-back::before { content: "\2190"; content: "\2190" / ""; display: inline-block; transition: transform 0.45s var(--ease); }

@media (hover: hover) {
  .pill:not([disabled]):hover::before { transform: none; }
  .pill-arrow:not([disabled]):hover span::after { transform: translateX(4px); }
  .pill-ghost:not([disabled]):hover { box-shadow: inset 0 0 0 1px var(--fg); }
  .link-arrow:hover::after { transform: translateX(5px); }
  a.link-arrow[target="_blank"]:hover::after { transform: translate(3px, -3px); }
  .link-back:hover::before { transform: translateX(-5px); }
}

/* ----------------------------------------------------------------- nav */

.nav {
  position: fixed; inset: 0 0 auto 0; z-index: var(--z-nav); height: var(--nav-h);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  padding-inline: var(--gut);
  --bg: var(--black); --fg: var(--on-dark); --fg2: var(--on-dark-2);
  color: var(--fg);
  transition: transform 0.6s var(--ease), color 0.3s linear;
}
.nav[data-over="light"] { --bg: var(--white); --fg: var(--ink); --fg2: var(--on-light-2); }
.nav::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--bg); opacity: 0; transition: opacity 0.3s linear; }
/* Fully opaque: at 0.94 the logos scrolling underneath ghosted through the bar on phones. */
.nav.is-solid::before { opacity: 1; }
.nav.is-hidden { transform: translateY(-101%); }
.nav-logo { justify-self: start; display: block; padding-block: 8px; }
.logo { height: 40px; width: auto; overflow: visible; }
.nav-links { display: flex; gap: clamp(20px, 2.6vw, 44px); font-size: 0.9375rem; font-weight: 500; }
.nav-links a { position: relative; padding-block: 12px; }
.nav-links a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 8px; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: right; transition: transform 0.45s var(--ease); }
.nav-cta { justify-self: end; display: flex; align-items: center; gap: 10px; }
.burger { display: none; width: 44px; height: 44px; position: relative; }
.burger i { position: absolute; left: 11px; right: 11px; height: 1.5px; background: currentColor; transition: transform 0.4s var(--ease); }
.burger i:first-child { top: 18px; }
.burger i:last-child { top: 25px; }
.burger[aria-expanded="true"] i:first-child { transform: translateY(3.5px) rotate(45deg); }
.burger[aria-expanded="true"] i:last-child { transform: translateY(-3.5px) rotate(-45deg); }
.sheet {
  position: fixed; inset: var(--nav-h) 0 0 0; z-index: var(--z-sheet); height: calc(100dvh - var(--nav-h));
  background: var(--black); color: var(--on-dark);
  display: flex; flex-direction: column; gap: 4px; padding: 28px var(--gut) 40px;
  overflow-y: auto; overscroll-behavior: contain;
}
/* The four words grow with the height of the screen as well as its width, so a tall phone is not left half empty. */
.sheet > a { flex: none; font-size: clamp(2.6rem, 11vw, 4rem); font-size: clamp(2.6rem, max(11vw, 6.6dvh), 4.25rem); font-weight: 500; letter-spacing: -0.035em; line-height: 1.12; }
/* The three journal shelves, under Journal. Quiet on purpose: the four words above stay the menu. */
.sheet-sub { flex: none; display: flex; flex-wrap: wrap; gap: 0 26px; margin: 10px 0 56px; font-size: 1.1875rem; font-weight: 500; letter-spacing: -0.01em; color: var(--on-dark-2); }
.sheet-sub a { display: inline-flex; align-items: center; min-height: 44px; }
.sheet-sub a[aria-current="page"] { color: var(--on-dark); }
.sheet-sub a[aria-current="page"] .sheet-sub-t { background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; padding-bottom: 3px; }
.sheet-sub sup { top: -0.1em; margin-left: 0.3em; color: var(--on-dark-3); }
.sheet .sheet-cta { flex: none; margin-top: auto; }
/* The page you are on: the bar keeps its hairline drawn, the sheet underlines the word. */
.nav-links a[aria-current="page"]::after { transform: scaleX(1); }
.sheet > a[aria-current="page"] { align-self: flex-start; background: linear-gradient(currentColor, currentColor) 0 calc(100% - 0.04em) / 100% 2px no-repeat; }
@media (hover: hover) { .nav-links a:hover::after { transform: scaleX(1); transform-origin: left; } }

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

/* The spectrum is the banner. The copy sits at the top of the first screen, the lines own the rest of it:
   the canvas runs from the foot of the screen up behind the copy (--rise), and js/spectrometer.js fades it
   into the black over most of its height, so the type stands on the top of the light, not beside it. */
.hero { position: relative; display: flex; flex-direction: column; min-height: 100svh; padding-top: var(--nav-h); overflow: hidden; }
.hero-copy { position: relative; z-index: 1; display: flex; flex-direction: column; gap: clamp(18px, 3vh, 40px); padding-top: clamp(24px, 5.4vh, 64px); pointer-events: none; }
.hero-copy > * { pointer-events: auto; }
h1 {
  font-weight: 500; letter-spacing: -0.04em; line-height: 0.94;
  font-size: clamp(2.7rem, 14vw, 5.4rem);
}
.ln { display: block; overflow: hidden; padding: 0.06em 0.08em 0.14em 0; margin: -0.06em 0 -0.14em 0; }
.ln-in { display: inline-block; }
.hero-side { position: relative; display: flex; flex-direction: column; gap: 22px; max-width: 35rem; }
.hero-side p { font-size: clamp(1.0625rem, 1.35vw, 1.3125rem); line-height: 1.42; color: var(--fg2); text-wrap: pretty; }
/* The lines rise up behind the copy, and a hovered line stands at full height. Behind the paragraph it would
   run through the words, so the paragraph stands on a pool of the page black that fades out in every direction:
   an oval with no edge, so the field is dimmed behind the words and never cut into a box. */
.hero-side::before {
  content: ""; position: absolute; z-index: -1; inset: -110px -220px -120px -220px; pointer-events: none;
  background: radial-gradient(closest-side, var(--black) 0%, var(--black) 64%, color-mix(in oklch, var(--black) 82%, transparent) 76%, color-mix(in oklch, var(--black) 40%, transparent) 89%, transparent 100%);
}
.cta-row { display: grid; gap: 10px; margin-top: 6px; }
.cta { display: grid; grid-template-columns: minmax(0, 13.25rem) minmax(0, 1fr); align-items: center; gap: 14px; }
.cta .pill { width: 100%; padding-inline: 22px; }
.cta .pill span { display: flex; flex: 1; justify-content: space-between; }
.cta small { font-size: 0.8125rem; line-height: 1.3; color: var(--fg2); text-wrap: balance; }

.hero-spectrum {
  position: relative; flex: 1 0 auto; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: clamp(260px, 38svh, 560px); margin-top: clamp(16px, 2.6vh, 36px);
  --rise: clamp(120px, 26svh, 320px); --label-top: clamp(10px, 4svh, 48px);
}
.spectro { position: absolute; inset: calc(-1 * var(--rise)) 0 0 0; }
/* The keyboard ring. The instrument reaches up behind the headline, so the ring is drawn on the band itself,
   inset from its edges and above the floor of the small print, never through the type. */
.hero-spectrum::after { content: ""; position: absolute; z-index: 3; inset: 0 6px 6px; border-radius: 2px; outline: 2px solid var(--on-dark); outline-offset: -2px; opacity: 0; pointer-events: none; }
.hero-spectrum:has(> .spectro:focus-visible)::after { opacity: 1; }
.spectro-fallback { position: absolute; inset: 0; -webkit-mask-image: linear-gradient(180deg, transparent, #000 64%, #000 86%, transparent); mask-image: linear-gradient(180deg, transparent, #000 64%, #000 86%, transparent); }
/* The readout. It hangs off the line in focus, over the lines themselves, so it brings its own patch of
   the page black: soft at every edge, and open on the side of its line. */
.spec-label {
  position: absolute; left: 0; top: var(--label-top); z-index: 2; pointer-events: none;
  display: grid; gap: 3px; width: max-content; max-width: min(23rem, calc(100vw - 2 * var(--gut)));
  padding: 2px 0 2px 16px;
  transform: translate3d(var(--x, 40px), 0, 0);
  opacity: 0; transition: opacity 0.3s linear;
}
.spec-label::before {
  content: ""; position: absolute; z-index: -1; inset: -26px -64px -40px 3px;
  background: linear-gradient(90deg, var(--black) 0, var(--black) 56%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 26px, #000 calc(100% - 44px), transparent);
  mask-image: linear-gradient(180deg, transparent, #000 26px, #000 calc(100% - 44px), transparent);
}
.spec-label.is-on { opacity: 1; }
.spec-label.is-flip { padding: 2px 16px 2px 0; text-align: right; justify-items: end; transform: translate3d(calc(var(--x, 40px) - 100%), 0, 0); }
.spec-label.is-flip::before { inset: -26px 3px -40px -64px; background: linear-gradient(270deg, var(--black) 0, var(--black) 56%, transparent); }
.spec-label strong { font-weight: 500; font-size: 1.0625rem; letter-spacing: -0.01em; }
.spec-label span { font-size: 0.875rem; line-height: 1.3; color: var(--fg2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Says the line opens. With a mouse the whole line is the target, so this is a sign, not a button. On a
   phone a finger goes for the words, so there it is a real link (hover: none, below). */
.spec-go { justify-self: start; display: inline-flex; align-items: center; gap: 0.5em; margin-top: 5px; font: 500 0.75rem/1.3 var(--num); color: var(--fg); }
.spec-go::after { content: "\2192"; content: "\2192" / ""; font-family: var(--sans); color: var(--lc, currentColor); }
.is-flip .spec-go { justify-self: end; }
.hero-note { position: relative; z-index: 1; pointer-events: none; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; padding-block: 0 clamp(14px, 2.2vh, 24px); font: 400 0.75rem/1.4 var(--num); color: var(--fg3); }
/* The lines stand on a floor of the page black, so the small print under them stays readable. */
.hero-note::before { content: ""; position: absolute; z-index: -1; left: -100vw; right: -100vw; bottom: 0; height: calc(100% + 64px); background: linear-gradient(180deg, transparent, color-mix(in oklch, var(--black) 90%, transparent) 50%, var(--black) 82%); }
.hero-note b { font-weight: 500; color: var(--fg); }
.hero-note span { text-wrap: balance; }
.hero-hint-fine { display: none; }

/* -------------------------------------------------------------- ticker */

/* A dozen names, rolling under the hero. Not a logo strip: each one is an entry, mark, name and field, ruled
   off from the next like a row of the ledger. Without motion it is a still row: wrapped on a wide screen,
   swiped on a phone. js/motion.js rolls it (data-ticker), css/motion.css holds the rolling layout. */
.ticker { border-bottom: 1px solid var(--line); }
.tk-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 0 var(--gut); min-height: 48px; border-bottom: 1px solid var(--line); font: 400 0.75rem/1.3 var(--num); color: var(--fg3); }
.tk-k b { font-weight: 500; color: var(--fg); }
.tk-all { display: inline-flex; align-items: center; gap: 0.5em; min-height: 44px; font-weight: 500; color: var(--fg); }
.tk-all::after { content: "\2192"; content: "\2192" / ""; font-family: var(--sans); display: inline-block; transition: transform 0.45s var(--ease); }
.tk-view { overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity; }
.tk-view::-webkit-scrollbar { display: none; }
.tk-track { display: flex; margin: 0; }
.tk-item { flex: none; scroll-snap-align: start; border-right: 1px solid var(--line); }
.tk-link { display: grid; grid-template-columns: auto auto; justify-content: start; align-items: center; gap: 0 20px; height: 104px; padding: 0 clamp(26px, 2.6vw, 44px) 0 clamp(22px, 2.2vw, 36px); }
.tk-logo { display: grid; place-items: center; width: 7.75rem; height: 44px; }
.tk-logo.is-trim { display: block; position: relative; overflow: hidden; }          /* cut to the artwork, js/app.js trimLogo() */
.tk-logo.is-trim img { position: absolute; max-width: none; max-height: none; transform: none; }
.tk-logo img { width: auto; height: auto; max-width: 100%; max-height: 40px; object-fit: contain; transform: scale(var(--s, 1)); filter: grayscale(1) invert(1) brightness(2.2) invert(1) brightness(1.04); transition: filter 0.4s linear; }
.tk-item[data-bg="white"] .tk-logo img { filter: grayscale(1) brightness(1.06) invert(1) brightness(2.2) invert(1) brightness(1.04); }
.tk-item[data-bg="dark"] .tk-logo img { filter: grayscale(1) invert(1) contrast(1.3) brightness(1.06); }
.tk-text { display: grid; gap: 5px; white-space: nowrap; }
.tk-name { font-weight: 500; font-size: 1.0625rem; letter-spacing: -0.012em; line-height: 1.15; }
.tk-name::after { content: "\2192"; content: "\2192" / ""; display: inline-block; margin-left: 0.45em; opacity: 0; transform: translateX(-6px); transition: opacity 0.3s linear, transform 0.45s var(--ease); }
.tk-meta { font: 400 0.6875rem/1.3 var(--num); color: var(--fg3); text-transform: uppercase; letter-spacing: 0.04em; }
.tk-link:focus-visible { outline-offset: -6px; }
@media (hover: hover) {
  .tk-all:hover::after { transform: translateX(4px); }
  /* The mark takes its own colors back under the pointer. White artwork has none to take, it stays ink. */
  .tk-item:not([data-bg="dark"]) .tk-link:hover .tk-logo img { filter: none; }
  .tk-link:hover .tk-name::after { opacity: 1; transform: none; }
}
.tk-link:focus-visible .tk-name::after { opacity: 1; transform: none; }
@media (min-width: 900px) {
  /* Wide screens: the label is the first cell of the row, and the names run out from under it. */
  .ticker { display: grid; grid-template-columns: auto minmax(0, 1fr); }
  .tk-head { flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px; min-height: 0; padding: 0 clamp(26px, 2.6vw, 44px) 0 var(--gut); border-bottom: 0; border-right: 1px solid var(--line); }
  .tk-view { overflow: hidden; }
  .tk-track { flex-wrap: wrap; }
  .tk-item { flex: 1 0 auto; border-bottom: 1px solid var(--line); margin-bottom: -1px; }
}

/* ----------------------------------------------------------- statement */

.statement { padding-block: var(--sec); }
/* The statement and the thesis are one dark run. Two full section pauses back to back left a hole of almost
   400px under "About the family", so the seam between them is a hairline with a short pause either side. */
.statement:has(+ .thesis) { padding-bottom: clamp(56px, 6vw, 104px); }
.statement-text { font-size: clamp(1.85rem, 4.3vw, 4.5rem); font-weight: 500; line-height: 1.06; letter-spacing: -0.035em; max-width: 21em; text-wrap: pretty; }
.statement-media { margin-top: clamp(48px, 7vw, 112px); aspect-ratio: 21 / 9; overflow: hidden; }
.statement-media img { width: 100%; height: 112%; object-fit: cover; filter: grayscale(1) contrast(1.04); }
.facts { margin-top: clamp(56px, 8vw, 128px); display: grid; gap: 0; border-top: 1px solid var(--line); }
.facts li { display: grid; grid-template-columns: 8.5rem 1fr; align-items: baseline; gap: 16px; padding-block: 16px; border-bottom: 1px solid var(--line); font-size: 1.0625rem; }
.facts span { font: 400 0.75rem/1.3 var(--num); color: var(--fg3); }
.facts b { font-weight: inherit; font-variant-numeric: tabular-nums; }

.statement-more { margin-top: clamp(28px, 3.4vw, 52px); }

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

.sec-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 28px 40px; margin-bottom: clamp(36px, 5vw, 80px); }
h2 { font-weight: 500; letter-spacing: -0.04em; line-height: 0.94; font-size: clamp(3.1rem, 10.5vw, 11rem); }
.sec-links { display: flex; flex-wrap: wrap; gap: 4px 28px; }

/* ----------------------------------------------------------- portfolio */

/* Chips, the grid and the tiles. The wall itself is on portfolio.html now, and its page parts (segmented
   control, group heads, the two initiative entries) are in css/pages.css. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
/* position: relative keeps the hidden ", " between a chip's word and its count inside the chip, so it scrolls
   with the chip row on a phone instead of widening the page. */
.chip {
  position: relative; min-height: 44px; padding: 0 18px; border-radius: 999px; border: 1px solid var(--line);
  font-size: 0.9375rem; font-weight: 500; display: inline-flex; align-items: center; gap: 8px;
  transition: background-color 0.3s var(--ease-q), color 0.3s var(--ease-q), border-color 0.3s var(--ease-q);
}
.chip i { font: 400 0.6875rem/1 var(--num); font-style: normal; color: var(--fg3); transition: color 0.3s; }
.chip[aria-pressed="true"] { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.chip[aria-pressed="true"] i { color: inherit; opacity: 0.7; }

.pf-grid { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.tile {
  position: relative; aspect-ratio: 1 / 1; display: grid; place-items: center; overflow: hidden; isolation: isolate; background: var(--bg);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.tile img { width: auto; height: auto; max-width: 62%; max-height: 40%; object-fit: contain; filter: grayscale(1) invert(1) brightness(2.2) invert(1) brightness(1.04); transform: scale(var(--s, 1)); transition: transform 0.7s var(--ease); }
.tile[data-bg="white"] img { filter: grayscale(1) brightness(1.06) invert(1) brightness(2.2) invert(1) brightness(1.04); }
.tile[data-bg="dark"] img { filter: grayscale(1) invert(1) contrast(1.3) brightness(1.06); }
.tile[data-ink="deep"] img { filter: grayscale(1) invert(1) contrast(1.3) brightness(1.06) url(#ink-deep); }
/* The mark's box. Until its artwork is found it steps aside and the picture sizes itself as above. Then it is
   cut to the artwork and set at a common area, in shares of the tile's width (js/app.js fitMark). */
.tile-mark { display: contents; }
.tile-mark.is-trim { display: block; position: relative; overflow: hidden; transition: transform 0.7s var(--ease); }
.pf-grid .tile .tile-mark.is-trim img { position: absolute; max-width: none; max-height: none; transform: none; }
.tile-cap { position: absolute; left: 8%; right: 8%; bottom: clamp(10px, 1.1vw, 16px); text-align: center; font: 400 0.6875rem/1.25 var(--num); letter-spacing: 0; color: var(--fg3); text-wrap: balance; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tile-name { padding: 0 12%; text-align: center; font-weight: 500; font-size: clamp(0.8125rem, 1.25vw, 1.25rem); letter-spacing: -0.02em; line-height: 1.1; text-wrap: balance; }
/* A tile with no usable mark: its name set as a wordmark, one size and weight for all of them. The name shows
   once; its caption gives the field of work, set like the field under a name in the home ticker. */
.tile.is-type .tile-name { font-weight: 600; font-size: clamp(0.9375rem, 1.55vw, 1.5rem); letter-spacing: -0.035em; line-height: 1.02; padding: 0 10%; transition: transform 0.7s var(--ease); }
.tile.is-type .tile-cap { text-transform: uppercase; letter-spacing: 0.04em; }
@media (hover: hover) { .tile.is-type:hover .tile-name { transform: scale(0.94); } }
.tile-over {
  position: absolute; inset: 0; z-index: 1; background: var(--black); color: var(--on-dark);
  display: flex; flex-direction: column; justify-content: space-between; gap: 8px;
  padding: clamp(10px, 1.3vw, 22px);
  clip-path: inset(100% 0 0 0); transition: clip-path 0.55s var(--ease);
}
.tile-over::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--tc, var(--on-dark)); }
.tile-over b { display: flex; justify-content: space-between; gap: 8px; font-weight: 500; font-size: clamp(0.8125rem, 1.05vw, 1.0625rem); letter-spacing: -0.01em; line-height: 1.15; }
.tile-over b::after { content: "\2197"; content: "\2197" / ""; flex: none; }
.tile-over span { font-size: 0.8125rem; line-height: 1.35; color: var(--on-dark-2); text-wrap: balance; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.tile-over small { display: none; font: 400 0.6875rem/1.2 var(--num); color: var(--on-dark-3); }
/* No website to open: no arrow, and a plain line where the visit cue would be, on every screen. */
.tile.is-nolink .tile-over b::after { content: none; }
.tile.is-nolink .tile-over small { display: block; }
.tile.is-open .tile-over, .tile:focus-visible .tile-over { clip-path: inset(0); }
.tile.is-gone { display: none; }

@media (hover: hover) {
  .chip:hover { border-color: var(--fg); }
  .tile:hover .tile-over { clip-path: inset(0); }
  .tile:hover img { transform: scale(calc(var(--s, 1) * 0.94)); }
  .tile:hover .tile-mark.is-trim { transform: scale(0.94); }
}

/* -------------------------------------------------------------- thesis */

.thesis { padding-top: var(--sec); overflow: hidden; }
.statement + .thesis { padding-top: 0; }
.statement + .thesis > .w:first-child { border-top: 1px solid var(--line); padding-top: clamp(56px, 6vw, 104px); }
.thesis-lede { font-size: clamp(2.4rem, 6.4vw, 6.75rem); margin-bottom: clamp(48px, 7vw, 112px); }
.rows { border-top: 1px solid var(--line); }
.row {
  position: relative; display: grid; grid-template-columns: 1fr; gap: 10px; align-items: baseline;
  padding-block: clamp(20px, 2.6vw, 40px); border-bottom: 1px solid var(--line);
  transition: opacity 0.4s linear;
}
.row::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--rc, var(--spectrum)); transform: scaleX(0); transform-origin: left; transition: transform 0.8s var(--ease); }
.row-word { font-size: clamp(3.2rem, 10.2vw, 10.5rem); font-weight: 500; letter-spacing: -0.045em; line-height: 0.92; transition: transform 0.7s var(--ease); }
.row-word sup { top: 0.55em; font-size: max(0.16em, 11px); }
.row-text { font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); line-height: 1.36; color: var(--fg2); max-width: 27rem; text-wrap: pretty; }
.row-go { display: inline-flex; align-items: center; gap: 0.5em; justify-self: start; margin-top: 4px; font-weight: 500; font-size: 1rem; letter-spacing: -0.005em; white-space: nowrap; background: linear-gradient(currentColor, currentColor) 0 calc(100% - 1px) / 100% 1px no-repeat; padding-bottom: 5px; }
.row-go::after { content: "\2192"; content: "\2192" / ""; display: inline-block; transition: transform 0.45s var(--ease); }

.thesis-more { margin-top: clamp(24px, 2.8vw, 44px); }

/* position: relative so the words' screen reader text (.sr, absolute) is clipped with them: without motion there is no
   transformed track to hold it, and it pushed the page wider than the screen. */
.marquee { position: relative; margin-top: calc(var(--sec) - 0.12em); padding-block: 0.12em; display: flex; white-space: nowrap; overflow: hidden; user-select: none; font-size: clamp(3.2rem, 9vw, 9.5rem); font-weight: 500; letter-spacing: -0.04em; line-height: 1.08; }
/* The band is a way in: every word links to the capital section of the thesis, and the band stands still
   under a pointer or a keyboard focus (js/motion.js). The slash between words stays outside the links. */
.marquee a { display: inline-block; color: inherit; transition: color 0.35s var(--ease-q); }
.marquee a:focus-visible { outline-offset: -0.06em; }
@media (hover: hover) { .marquee:hover a:not(:hover) { color: var(--fg3); } }
.marquee > span, .marquee-track > span { flex: none; padding-right: 0.22em; }
.marquee > span::after, .marquee-track > span::after { content: "/"; content: "/" / ""; font-family: var(--sans); font-style: normal; font-weight: 400; color: var(--fg3); padding-left: 0.22em; }
.marquee > span:nth-child(even), .marquee-track > span:nth-child(even) { font-family: var(--serif); font-style: italic; font-weight: 300; letter-spacing: -0.03em; }
.marquee-track { display: flex; flex: none; will-change: transform; }
.marquee-cap { padding-block: clamp(20px, 2.4vw, 36px) calc(var(--sec) * 0.5); font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); color: var(--fg2); text-wrap: balance; }

@media (hover: hover) {
  /* A hovered row steps its siblings back: the big type only, and no further than 0.62. The whole row at
     0.36 left the body copy near 2:1. The count rides inside the headline, so it is lent the headline's
     white while it steps back. Same floor as the touch spotlight in css/motion.css. */
  .row-word { transition: opacity 0.35s linear, transform 0.7s var(--ease); }
  .row-go { transition: opacity 0.35s linear; }
  .row-word sup { transition: color 0.35s linear; }
  .rows:hover .row:not(:hover) :is(.row-word, .row-go) { opacity: 0.62; }
  .rows:hover .row:not(:hover) .row-word sup { color: var(--fg); }
  .row:hover::after { transform: scaleX(1); }
  .row:hover .row-word { transform: translateX(0.12em); }
  .row:hover .row-go::after { transform: translateX(5px); }
}
.row:focus-visible::after { transform: scaleX(1); }

/* --------------------------------------------------------- initiatives */

/* Two not-for-profit initiatives the team runs itself, given the same weight. SCALE has photographs, so it
   keeps its full bleed frame. ITRI has none, so it is set in type alone: the same giant word, hung from
   the top of its band where SCALE stands on the foot of its own, so the two read as a pair across the rule
   between them. */
.init { padding-block: var(--sec) clamp(56px, 7vw, 112px); border-top: 1px solid var(--line); }
/* After the capital caption, one section gap in all, split by the hairline. */
.thesis + .init { padding-top: calc(var(--sec) * 0.5); }
.init-in { display: grid; gap: clamp(20px, 2.4vw, 36px); }
.init-k, .init-n { font: 400 0.75rem/1.3 var(--num); color: var(--fg3); }
.init-lede { font-size: clamp(2.4rem, 6.4vw, 6.75rem); }
.init-text { max-width: 34rem; font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); line-height: 1.4; color: var(--fg2); text-wrap: pretty; }

.scale { position: relative; min-height: 100svh; display: flex; overflow: hidden; border-top: 1px solid var(--line); }
.scale-media { position: absolute; inset: 0; overflow: hidden; }
.scale-media img { width: 100%; height: 112%; object-fit: cover; object-position: 50% 30%; filter: grayscale(1) contrast(1.05) brightness(0.6); }
.scale-media::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, color-mix(in oklch, var(--black) 82%, transparent), color-mix(in oklch, var(--black) 55%, transparent) 24%, transparent 46%, transparent 52%, color-mix(in oklch, var(--black) 78%, transparent) 100%); }
.scale-in { position: relative; display: flex; flex-direction: column-reverse; justify-content: space-between; gap: 40px; padding-block: calc(var(--nav-h) + 20px) clamp(14px, 2vw, 32px); }
.scale-word { font-weight: 600; font-size: clamp(5.4rem, 27.5vw, 30rem); letter-spacing: -0.055em; line-height: 0.8; margin-left: -0.04em; }
.scale-word .ln { padding-bottom: 0.06em; margin-bottom: -0.06em; }
.scale-side { display: grid; gap: 12px; justify-items: start; max-width: 27rem; }
.scale-side p { font-size: clamp(1.0625rem, 1.45vw, 1.4375rem); line-height: 1.36; color: var(--on-dark); text-wrap: pretty; }
.scale-side .init-n { font: 400 0.75rem/1.3 var(--num); color: var(--on-dark-2); }
/* The acronym's expansion, as scale-climate.org writes it, sits under the wordmark in mono. The sentence-case
   line beside it carries the section's one Boska word. */
.scale-exp { font: 400 0.75rem/1.45 var(--num); letter-spacing: 0.01em; color: var(--fg2); margin-top: 16px; max-width: 34rem; text-wrap: balance; }
.scale-side .scale-name, .ev-lede .scale-name { font-size: clamp(1.5rem, 2.3vw, 2.4rem); font-weight: 500; line-height: 1.06; letter-spacing: -0.035em; max-width: 13em; color: var(--on-dark); text-wrap: balance; margin-bottom: 6px; }
/* A phone crops a wide photograph to a thin upright slice. The copy keeps the black above the picture and the
   picture starts under it, framed on the speaker, so his face sits in the open middle of the screen and the
   word stands on his shoulders, not over his head. */
@media (max-width: 699px) {
  .scale { display: block; min-height: 0; }
  .scale-media { position: relative; inset: auto; height: min(118vw, 66svh); }
  .scale-media img { object-position: 36% 12%; }
  .scale-media::after { background: linear-gradient(180deg, transparent 0%, transparent 55%, color-mix(in oklch, var(--black) 70%, transparent) 80%, var(--black) 100%); }
  .scale-in { flex-direction: column; justify-content: flex-start; gap: 28px; margin-top: -0.62em; font-size: clamp(5.4rem, 27.5vw, 30rem); padding-block: 0 var(--sec); }
  .scale-in > * { font-size: 1rem; }
  .scale-in > .scale-word { font-size: 1em; }
}

/* ITRI ends the dark run with half a section, the way the other dark bands end before a light one. */
.itri { border-top: 1px solid var(--line); padding-block: clamp(20px, 2.6vw, 40px) calc(var(--sec) * 0.5); overflow: hidden; }
.itri-in { display: grid; gap: clamp(40px, 6vw, 104px); }
.itri-word { letter-spacing: -0.045em; }
.itri-word .ln { padding-top: 0.1em; margin-top: -0.1em; }
.itri-body { display: grid; gap: 36px; }
.itri-name { font-size: clamp(1.85rem, 4.3vw, 4.5rem); font-weight: 500; line-height: 1.04; letter-spacing: -0.035em; max-width: 11em; text-wrap: balance; }
/* Wide screens: SCALE fills a screen with its photograph, so ITRI answers it in type across the full width.
   The word takes the left, and its full name, the line and the link fill the right, standing on the same
   floor as the word. Nothing is left half empty. */
@media (min-width: 900px) {
  .itri { padding-block: clamp(40px, 4.4vw, 72px) calc(var(--sec) * 0.5); }
  .itri-in { grid-template-columns: auto minmax(0, 1fr); align-items: end; column-gap: clamp(40px, 5.6vw, 104px); }
  .itri-word { font-size: clamp(8rem, 25vw, 26rem); }
  /* .itri-in > .itri-body: the 700px two column body further down must not win here. */
  .itri-in > .itri-body { grid-template-columns: minmax(0, 1fr); align-items: start; gap: clamp(24px, 2.6vw, 40px); padding-bottom: 0.4em; }
  .itri-name { font-size: clamp(2.2rem, 3.6vw, 4rem); max-width: 12em; }
  .itri-body .itri-side { max-width: 30rem; }
}

/* ------------------------------------------------------------- journal */

.journal { padding-block: var(--sec); }
.jr-list { border-top: 1px solid var(--line); }
.jr { position: relative; display: grid; grid-template-columns: 1fr auto; gap: 6px 20px; padding-block: clamp(20px, 2.2vw, 34px); border-bottom: 1px solid var(--line); align-items: baseline; }
.jr-date, .jr-kind { font: 400 0.75rem/1.3 var(--num); color: var(--fg3); }
.jr-date { grid-column: 1 / -1; }
.jr-title { grid-column: 1 / -1; font-size: clamp(1.3125rem, 2.5vw, 2.5rem); font-weight: 500; letter-spacing: -0.03em; line-height: 1.08; text-wrap: balance; transition: transform 0.6s var(--ease); }
.jr-kind { grid-column: 1; }
.jr-ex { display: block; margin-top: 10px; max-width: 40rem; font-size: 1rem; font-weight: 400; letter-spacing: -0.005em; line-height: 1.42; color: var(--fg2); text-wrap: pretty; }
/* Whom a story is about, or what it is when it is not press coverage (js/app.js pressTag). */
.jr-own { display: block; margin-top: 8px; font: 400 0.75rem/1.5 var(--num); letter-spacing: 0; color: var(--fg3); }
.jr-arrow { grid-column: 2; font-size: 1.5rem; line-height: 1; transition: transform 0.6s var(--ease); }
.follow { position: fixed; left: 0; top: 0; z-index: var(--z-follow); width: clamp(220px, 22vw, 360px); aspect-ratio: 4 / 3; overflow: hidden; pointer-events: none; opacity: 0; background: var(--black); }
.follow img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.05); }
.follow.is-whole img { object-fit: contain; }
.dlg-addr { white-space: nowrap; }
/* The row being read draws its hairline in the spectrum, the way a thesis row and an essay do: the hovered
   row with a mouse, the row in the reading band on a phone (.is-lit, css/motion.css). */
.jr::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; z-index: 1; background: var(--spectrum); transform: scaleX(0); transform-origin: left; transition: transform 0.7s var(--ease); pointer-events: none; }
.jr:focus-visible::after { transform: scaleX(1); }
@media (hover: hover) {
  /* Siblings of a hovered row step back: headline and arrow only, to 0.62. The row itself keeps
     its opacity, so the small mono date and outlet keep their contrast, and the scroll reveal, which
     animates the row's opacity, never meets a hover on the same property. */
  .jr-title, .jr-arrow { transition: opacity 0.35s linear, transform 0.6s var(--ease); }
  .jr-list:hover .jr:not(:hover) :is(.jr-title, .jr-arrow) { opacity: 0.62; }
  .jr:hover::after { transform: scaleX(1); }
  .jr:hover .jr-title { transform: translateX(0.5em); }
  .jr:hover .jr-arrow { transform: translate(3px, -3px); }             /* the glyph sits 3px in from the gutter, so it lands on it */
}

/* --------------------------------------------------------------- doors */

/* The closing band. One door, "Get in touch", at the scale of a headline, and under it two quiet side doors
   for the two visitors who know what they came for. The door is a black slab with white type at every
   moment. Its one colour is light: a hairline of the logo gradient that draws along its foot, over the gray
   rule, under a mouse or keyboard focus (and once, as it arrives, on a phone: css/motion.css). */
.doors { border-top: 1px solid var(--line); }
.door {
  position: relative; overflow: hidden; isolation: isolate; width: 100%;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 18px 20px;
  padding: clamp(64px, 9vw, 168px) var(--gut) clamp(32px, 4vw, 68px);
  background: var(--bg); color: var(--fg);
}
.door::before, .door::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; pointer-events: none; }
.door::before { background: var(--line); }
.door::after { z-index: 1; background: var(--spectrum); transform: scaleX(0); transform-origin: left; transition: transform 1.1s var(--ease); }
.door-t { font-size: clamp(3.25rem, 13.4vw, 14.5rem); font-weight: 500; letter-spacing: -0.05em; line-height: 0.9; padding-bottom: 0.12em; transition: transform 0.7s var(--ease); }
.door-s { grid-column: 1; grid-row: 2; max-width: 34rem; font-size: clamp(1.0625rem, 1.35vw, 1.3125rem); line-height: 1.42; color: var(--fg2); text-wrap: pretty; transition: color 0.35s var(--ease-q); }
.door-a { grid-column: 2; grid-row: 1; align-self: end; padding-bottom: 0.2em; font-size: clamp(2rem, 5.4vw, 6rem); line-height: 1; transition: transform 0.6s var(--ease); }
.doors-alt { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; align-items: center; gap: 0 14px; padding-block: 28px; color: var(--fg2); font-size: 1.0625rem; }
.doors-alt .link-arrow { color: var(--fg); }
.doors-or { margin-top: 16px; }
@media (hover: hover) {
  .door:hover::after { transform: none; }
  .door:hover .door-s { color: var(--fg); }
  .door:hover .door-t { transform: translateX(0.06em); }
  .door:hover .door-a { transform: translate(8px, -8px); }
}
.door:focus-visible { outline-offset: -6px; }
.door:focus-visible::after { transform: none; }
.door:focus-visible .door-s { color: var(--fg); }
/* A phone without the motion layer has no arrival to wait for: the hairline is simply drawn. */
@media (hover: none) { html:not(.js-motion) .door::after { transform: none; } }

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

.foot { padding-top: clamp(48px, 6vw, 96px); }
.foot-top { display: grid; gap: 36px; font-size: 1.0625rem; line-height: 1.5; }
.foot-top > * { display: grid; gap: 4px; align-content: start; justify-items: start; max-width: 24rem; }
.foot-logo .logo { height: 52px; }
.foot-k { font: 400 0.75rem/1.3 var(--num); color: var(--fg3); margin-bottom: 8px; }
.foot-top nav a, .foot-top div a { background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size 0.45s var(--ease); padding-block: 3px; }
.foot-social { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-top: 10px; }
.foot-strip { height: clamp(56px, 9vw, 132px); margin-top: clamp(56px, 8vw, 128px); background-repeat: no-repeat; -webkit-mask-image: linear-gradient(180deg, transparent, #000 55%); mask-image: linear-gradient(180deg, transparent, #000 55%); opacity: 0.9; }
.foot-base { position: relative; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 28px; padding-block: 18px 22px; font: 400 0.75rem/1.4 var(--num); color: var(--fg3); }
@media (hover: hover) { .foot-top nav a:hover, .foot-top div a:hover { background-size: 100% 1px; } }

/* -------------------------------------------------------------- dialog */

.dlg {
  margin: 0 0 0 auto; width: min(620px, 100vw); max-width: none; height: 100dvh; max-height: none;
  border: 0; padding: 0; overflow: auto; overscroll-behavior: contain;
  transform: translateX(100%);
  transition: transform 0.7s var(--ease), overlay 0.7s allow-discrete, display 0.7s allow-discrete;
}
.dlg[open] { transform: none; }
@starting-style { .dlg[open] { transform: translateX(100%); } }
/* The backdrop inherits no custom properties in older browsers, so its ink is spelled out: --black at 62%. */
.dlg::backdrop { background: oklch(0.13 0.005 260 / 0); transition: background-color 0.5s linear, overlay 0.5s allow-discrete, display 0.5s allow-discrete; }
.dlg[open]::backdrop { background: oklch(0.13 0.005 260 / 0.62); }
@starting-style { .dlg[open]::backdrop { background: oklch(0.13 0.005 260 / 0); } }
.dlg-in { min-height: 100%; display: flex; flex-direction: column; gap: 26px; padding: clamp(24px, 4vw, 48px); }
/* Close is the same X the menu button turns into, in a 44px target. It follows the heading in the markup,
   so focus runs heading, Close, form. order puts it back at the top right for the eye. */
.dlg-x { order: -1; align-self: flex-end; flex: none; position: relative; width: 44px; height: 44px; margin: -6px -11px -14px 0; border-radius: 50%; transition: transform 0.6s var(--ease); }
.dlg-x i { position: absolute; left: 11px; right: 11px; top: 21.25px; height: 1.5px; background: currentColor; }
.dlg-x i:first-child { transform: rotate(45deg); }
.dlg-x i:last-child { transform: rotate(-45deg); }
.dlg-x:focus-visible { outline-offset: -2px; border-radius: 50%; }
@media (hover: hover) { .dlg-x:hover { transform: rotate(90deg); } }
.dlg h2 { font-size: clamp(2.6rem, 6vw, 4.25rem); letter-spacing: -0.04em; }
/* The panel opens with focus on its heading (js/app.js), so a ring only ever shows for someone using the keyboard. */
.dlg h2:focus { outline: 0; }
.madlib { font-size: clamp(1.25rem, 2.1vw, 1.5rem); line-height: 1.5; letter-spacing: -0.015em; color: var(--fg2); }
.madlib select {
  appearance: none; -webkit-appearance: none; font: inherit; font-weight: 500; color: var(--fg); border: 0; border-bottom: 1px solid currentColor; border-radius: 0;
  padding: 0 1.1em 0 0; margin: 0 0.1em; cursor: pointer; letter-spacing: inherit;
  field-sizing: content;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%230A0B0D' stroke-width='1.4'/%3E%3C/svg%3E") right 0.1em center / 0.6em no-repeat;
}
/* Nothing chosen yet: the blank reads as a blank. */
.madlib select.is-blank { color: var(--fg3); }
/* The routing note. A hairline and two lines of type, like every other row on the site. */
.verdict { display: grid; gap: 4px; padding-top: 18px; border-top: 1px solid var(--line); font-size: 1.0625rem; line-height: 1.45; color: var(--fg2); text-wrap: pretty; }
.verdict b { font-weight: 500; color: var(--fg); }
.fields { display: grid; grid-template-columns: 1fr 1fr; gap: 20px 24px; }
.field { display: grid; gap: 6px; min-width: 0; align-content: start; }
.field.wide { grid-column: 1 / -1; }
.field label { font: 400 0.75rem/1.3 var(--num); color: var(--fg2); }
.field input, .field select, .field textarea {
  width: 100%; font: inherit; font-size: 1rem; color: var(--fg); background: transparent;
  border: 0; border-bottom: 1px solid var(--on-light-3); border-radius: 0; padding: 10px 0; min-height: 44px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.field textarea { resize: none; field-sizing: content; min-height: 96px; max-height: 40vh; }
.field input:focus, .field select:focus, .field textarea:focus { outline: 0; border-color: var(--fg); box-shadow: 0 1px 0 0 var(--fg); }
.field .err { font-size: 0.8125rem; color: oklch(0.5 0.19 25); }
@supports (grid-template-rows: subgrid) {
  .fields { grid-auto-rows: auto; row-gap: 0; }
  .field { grid-row: span 3; grid-template-rows: subgrid; row-gap: 6px; padding-bottom: 20px; }
  .field label { align-self: end; }
}
.dlg-foot { margin-top: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; padding-top: 8px; }
.dlg-note { font: 400 0.75rem/1.4 var(--num); color: var(--fg2); }
.dlg-note a { color: var(--fg); background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; }
/* The field only a bot fills in. Out of sight, out of the tab order, silent to a screen reader. */
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.dlg-done { display: grid; gap: 14px; align-content: start; font-size: 1.25rem; line-height: 1.4; color: var(--fg2); }
.dlg-done .dlg-done-t { color: var(--fg); font-size: clamp(1.5rem, 2.6vw, 2rem); font-weight: 500; letter-spacing: -0.02em; line-height: 1.2; }
.dlg-done p:focus { outline: 0; }
.dlg-done-go { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; margin-top: 14px; }
.dlg-done-go .pill { white-space: normal; text-align: left; }

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

@media (max-width: 699px) {
  /* Phones get the same air as the desktop page: bigger pauses between beats, looser long-form type. */
  :root { --sec: 120px; }
  .statement-text { font-size: 1.75rem; line-height: 1.17; letter-spacing: -0.028em; }
  .facts { margin-top: 64px; }
  .facts li { padding-block: 20px; }
  .sec-head { gap: 24px; margin-bottom: 44px; }
  .sec-links { gap: 0 22px; }
  .spec-label { max-width: calc(100vw - 2 * var(--gut) - 16px); }
  /* On a phone the readout is as wide as the screen, so its ground is a band across the lines, not a patch:
     thin enough that the line being read still shows through it. */
  .spec-label::before, .spec-label.is-flip::before {
    inset: -34px -100vw -52px; background: color-mix(in oklch, var(--black) 84%, transparent);
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 34px, #000 calc(100% - 56px), transparent);
    mask-image: linear-gradient(180deg, transparent, #000 34px, #000 calc(100% - 56px), transparent);
  }
  /* Phone: mark over name, so two and a bit entries share the screen and the band reads as a list. */
  .tk-link { grid-template-columns: auto; grid-template-rows: 2.75rem auto; align-content: center; justify-items: start; gap: 12px; height: 148px; min-width: 9.75rem; padding: 0 26px 0 20px; }
  .tk-logo { align-self: center; font-size: 0.9375rem; }
  .tk-name { font-size: 1rem; }

  .chips { flex-wrap: nowrap; overflow-x: auto; margin-inline: calc(-1 * var(--gut)); padding-inline: var(--gut); scroll-padding-inline: var(--gut); scrollbar-width: none; scroll-snap-type: x proximity; width: 100vw; }
  .chips::-webkit-scrollbar { display: none; }
  .chip { flex: none; scroll-snap-align: start; }
  .chips { padding-right: 96px; -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 88px), transparent calc(100% - 8px)); mask-image: linear-gradient(90deg, #000 calc(100% - 88px), transparent calc(100% - 8px)); }
  .pf-grid { grid-template-columns: repeat(2, 1fr); }
  .tile { aspect-ratio: 5 / 4; }
  .tile img { max-width: 60%; max-height: 34%; }
  .tile-over { padding: 12px 12px 14px; gap: 6px; }
  .tile-over b { font-size: 0.9375rem; }
  .tile-over b.is-long { font-size: 0.8125rem; line-height: 1.2; }
  .tile-over span { margin-top: auto; font-size: 0.78125rem; line-height: 1.32; }

  .thesis-lede { margin-bottom: 64px; }
  .row { gap: 16px; padding-block: 34px; }
  .row-text { line-height: 1.42; }
  .row-go { margin-top: 6px; }
  .marquee-cap { padding-top: 28px; }

  .jr { row-gap: 10px; padding-block: 30px; }
  .jr-title { font-size: 1.375rem; line-height: 1.17; letter-spacing: -0.022em; }

  .door { padding-block: 96px 44px; }
  .doors-alt { padding-block: 30px 40px; }
  .foot-top { gap: 44px; }
}

/* The narrowest phones. Two columns leave about 21 characters a line, so a tile gets a fourth line of
   description and the height to hold it. js/app.js reads the clamp and fits the text to it. */
@media (max-width: 383px) {
  .tile { aspect-ratio: 1; }
  .tile-over span { -webkit-line-clamp: 4; }
}

@media (max-width: 859px) {
  .nav { grid-template-columns: 1fr auto; }
  .nav-links { display: none; }
  .burger { display: block; }
  /* A narrow bar opens as logo and menu only, so the first screen stays clean. "Get in touch" joins it once
     the page has scrolled and the bar has turned solid, and steps out again while the menu is open: the
     sheet carries the same button. */
  .nav-cta .pill { transition: color 0.35s var(--ease-q), opacity 0.3s linear, visibility 0s linear 0s; }
  .nav:not(.is-solid) .nav-cta .pill, .nav.is-open .nav-cta .pill { opacity: 0; visibility: hidden; transition: color 0.35s var(--ease-q), opacity 0.3s linear, visibility 0s linear 0.3s; }
  .sec-links { gap: 4px 18px; }
  .sec-links .link-arrow { font-size: 1rem; }
  .logo { height: 34px; }
  .fields { grid-template-columns: 1fr; }
}

@media (min-width: 700px) {
  h1 { font-size: clamp(3.4rem, min(8.4vw, 15.2vh), 9rem); }
  .ln-join { display: inline-block; vertical-align: top; }
  .ln-join + .ln-join { margin-left: -0.1em; }
  /* A full line of the paragraph's own leading between it and the last line of the headline. */
  .hero-side { margin-left: 50%; padding-top: 1.45em; font-size: clamp(1.0625rem, 1.35vw, 1.3125rem); }
  .cta-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px 14px; }
  .cta { display: grid; grid-template-columns: auto; justify-items: start; gap: 10px; }
  .cta .pill { width: auto; padding-inline: 32px; }
  .cta .pill span { display: inline-block; }
  .cta small { padding-left: 6px; }
  .facts { grid-template-columns: repeat(3, 1fr); gap: 0 40px; border-top: 0; }
  .facts li { grid-template-columns: 1fr; gap: 10px; border-top: 1px solid var(--line); border-bottom: 0; padding-block: 18px 0; }
  .pf-grid { grid-template-columns: repeat(4, 1fr); }
  .tile { aspect-ratio: 4 / 3; }
  /* The word takes the left and is sized to its column (the longest theme word is about 5 em wide with its
     count), so it can never run into the text. The line and the way in stand in a column on the right. */
  .rows { container-type: inline-size; }
  .row { grid-template-columns: minmax(0, 1fr) min(24rem, 40cqi); column-gap: 40px; row-gap: 10px; align-items: end; }
  .row-word { grid-row: 1 / span 2; font-size: min(10.5rem, 10.2vw, calc((100cqi - 40px - min(24rem, 40cqi)) / 5.3)); }
  .row-text { grid-column: 2; }
  .row-go { grid-column: 2; justify-self: start; margin: 4px 0 0.3em; font-size: 1.0625rem; }
  .jr { grid-template-columns: 8.5rem minmax(0, 1fr) 11rem 2rem; gap: 24px; }
  .jr-date, .jr-title, .jr-kind, .jr-arrow { grid-column: auto; }
  .jr-arrow { justify-self: end; }
  .foot-top { grid-template-columns: 1.3fr 1.3fr 1fr auto; gap: 40px; }
  .foot-top > nav { justify-self: end; }
  .scale-side { align-self: flex-end; }
  .itri-body { grid-template-columns: minmax(0, 1fr) minmax(0, 27rem); gap: 40px; align-items: end; }
  .init-in { grid-template-columns: minmax(0, 1fr) minmax(0, 27rem); column-gap: 40px; align-items: end; }
  .init-k { grid-column: 1 / -1; }
  .init-text { padding-bottom: 0.5em; }
  .doors-alt { grid-template-columns: max-content max-content; justify-content: start; }
  .doors-or { margin-top: 0; }
}

/* Short laptop screens: tighten the copy so the bright part of the spectrum stays inside the first screen. */
@media (min-width: 700px) and (max-height: 800px) {
  .hero-copy { padding-top: clamp(16px, 3.4vh, 36px); gap: clamp(14px, 2.4vh, 28px); }
  .hero-spectrum { margin-top: 12px; --label-top: 8px; }
}

@media (min-width: 1100px) {
  .pf-grid { grid-template-columns: repeat(6, 1fr); }
  .doors-alt { grid-template-columns: max-content max-content minmax(0, 1fr) max-content; }
  .doors-or { justify-self: end; }
}

@media (hover: none) {
  /* A real link on a phone, a 44px target that one tap follows. It only takes a finger while its label shows. */
  .spec-go { min-height: 44px; min-width: 44px; padding-right: 10px; margin-top: -6px; margin-bottom: -12px; font-size: 0.8125rem; }
  .spec-label.is-on .spec-go { pointer-events: auto; }
  .is-flip .spec-go { padding: 0 0 0 10px; }
  .tile-over small { display: block; }
  /* Footer links are 44px tap targets. The label and the gaps give the space back, so the columns keep their rhythm. */
  .foot-top > * { gap: 0; }
  .foot-top nav .foot-k, .foot-top div .foot-k { margin-bottom: -2px; }
  .foot-top nav a, .foot-top div a { display: inline-flex; align-items: center; min-height: 44px; padding-block: 0; background-position: 0 calc(100% - 9px); }
  .foot-social { margin-top: 0; }
}

/* Phones: the bar is logo and menu only, scrolled or not. The menu sheet carries "Get in touch".
   The footer is short enough to sit under the screen as one piece (js/motion.js pins it only when it
   fits). Explore runs in four columns (the four pages, then the three journal pages), the gaps and the strip are tighter, the address a step smaller.
   A tile caption may take a third line, so the longest names and fields are read whole under the mark. */
@media (max-width: 699px) {
  .nav-cta .pill { display: none; }
  .tile-cap { -webkit-line-clamp: 3; }
  .foot { padding-top: 40px; }
  .foot-top { gap: 26px; }
  .foot-top address { font-size: 0.9375rem; line-height: 1.45; }
  .foot-top > nav { grid-template-columns: repeat(4, max-content); column-gap: clamp(18px, 6vw, 36px); max-width: none; }
  .foot-top > nav .foot-k { grid-column: 1 / -1; }
  .foot-strip { height: 40px; margin-top: 36px; }
  .foot-base { padding-block: 14px 18px; }
}

@media (hover: hover) and (pointer: fine) {
  .hero-hint-fine { display: inline; }
  .hero-hint-touch { display: none; }
}

/* ---------------------------------------------------- page transitions */
/* Between the home page and the journal pages the old page lifts away and the new one rises in,
   while the bar stays put. Browsers without cross-document view transitions simply navigate. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .nav { view-transition-name: site-nav; }
  ::view-transition-old(root) { animation: vt-out 0.26s cubic-bezier(0.4, 0, 1, 1) both; }
  ::view-transition-new(root) { animation: vt-in 0.62s cubic-bezier(0.16, 1, 0.3, 1) 0.08s both; }
}
@keyframes vt-out { to { opacity: 0; transform: translateY(-18px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(28px); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important; }
}
