/* ==========================================================================
   Kairo brand components: home hero crossword + dot field, partner strip,
   service bars and industry cards (home + services.html).
   Loaded after site.css on every generated page.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Home hero: copy left, crossword right. A canvas dot field spans the whole
   section, centred on the grid by assets/crossword.js and faded by a radial
   mask so it melts into the newsprint before any edge.
   -------------------------------------------------------------------------- */

.home-hero { position: relative; overflow: hidden; padding-block: clamp(56px, 9vw, 120px) clamp(56px, 8vw, 104px); }
.home-hero__inner { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(32px, 5vw, 72px); align-items: center; }
.has-field { position: relative; overflow: hidden; }
.has-field > :not(.xw-field) { position: relative; z-index: 1; }
.xw-field {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0;
  -webkit-mask-image: radial-gradient(ellipse var(--rx, 640px) var(--ry, 420px) at var(--cx, 72%) var(--cy, 50%), #000 0%, rgba(0, 0, 0, .8) 22%, rgba(0, 0, 0, .42) 48%, rgba(0, 0, 0, .14) 74%, transparent 100%);
  mask-image: radial-gradient(ellipse var(--rx, 640px) var(--ry, 420px) at var(--cx, 72%) var(--cy, 50%), #000 0%, rgba(0, 0, 0, .8) 22%, rgba(0, 0, 0, .42) 48%, rgba(0, 0, 0, .14) 74%, transparent 100%);
}

.xw-box { display: grid; gap: 14px; justify-items: center; min-width: 0; }
.xw-stage { padding: clamp(12px, 3vw, 32px); perspective: 900px; max-width: 100%; touch-action: manipulation; }
/* Only the letter squares are drawn. The blank squares are left open so the
   dot field shows through where a printed crossword would be black. */
.xw {
  --c: min(56px, 12vw);
  display: grid; grid-template-columns: repeat(6, var(--c)); grid-auto-rows: var(--c);
  transition: transform .3s var(--ease);
}
.xw__cell {
  position: relative; display: grid; place-items: center; cursor: pointer;
  /* the squares are paper-white with ink letters in BOTH themes, like a printed grid */
  background: var(--cell); color: #0E110F;
  box-shadow: 0 0 0 1.5px #0E110F, 0 14px 26px -18px rgba(14, 17, 15, .45);
  font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 800;
  font-size: calc(var(--c) * .62); line-height: 1;
  transition: background-color var(--fast);
}
.xw__cell sup { position: absolute; top: 3px; left: 4px; font-family: var(--font-mono); font-size: 10px; font-weight: 500; opacity: .8; }
.xw__cell.lit { background: #FBE3D8; }
.xw__cell--x, .xw__cell--x.lit { background: var(--orange); color: #fff; }
.xw__cell.cur { box-shadow: 0 0 0 1.5px #141414, inset 0 0 0 2px #141414; }
.xw__cell--x.cur { box-shadow: 0 0 0 1.5px #0E110F, inset 0 0 0 2px #0E110F; }
.xw__read { font-family: var(--font-mono); font-size: 12.5px; line-height: 1.5; color: var(--text-2); min-height: 3em; margin: 0; text-align: center; max-width: 42ch; }
.xw__read b { color: var(--green); font-weight: 600; }
.xw__clues { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; font-size: 14.5px; line-height: 1.45; max-width: 420px; width: 100%; }
.xw__clues h4 { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; margin: 0 0 6px; }
.xw__clues p { margin: 0 0 6px; color: var(--text-2); }
.xw__clues b { color: var(--text); }

@media (max-width: 900px) {
  .home-hero__inner { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Partner strip as a departure board: a dark board housing between two
   brushed-metal frame rails (with screws), faint module seams, the label as
   a two-row split-flap display (assets/splitflap.js) that fills the board's
   height, and the logos scrolling as crisp vector text in cream, edges faded
   into the board.
   -------------------------------------------------------------------------- */

.partners {
  --rail: 7px;
  position: relative; border: 0; color-scheme: dark;
  background:
    repeating-linear-gradient(90deg, transparent 0 46px, rgba(255, 255, 255, .022) 46px 47px),
    linear-gradient(180deg, #141413, #1C1C1A 50%, #151514);
  box-shadow: inset 0 calc(var(--rail) + 6px) 10px -8px rgba(0, 0, 0, .8), inset 0 calc(-1 * var(--rail) - 6px) 10px -8px rgba(0, 0, 0, .8);
}
/* the frame rails, top and bottom: brushed aluminium with a screw every so often */
.partners::before, .partners::after {
  content: ""; position: absolute; left: 0; right: 0; height: var(--rail); pointer-events: none;
  background:
    radial-gradient(circle at 50% 50%, #5E5E5A 0 1.3px, #2C2C2A 1.6px 2px, transparent 2.4px) 0 50% / 140px var(--rail) repeat-x,
    linear-gradient(180deg, #E4E3DD 0%, #A9A8A2 45%, #8C8B86 55%, #C9C8C2 100%);
  box-shadow: 0 0 0 .5px rgba(0, 0, 0, .5);
}
.partners::before { top: 0; }
.partners::after { bottom: 0; }
.partners__inner { display: flex; align-items: center; gap: 30px; padding-block: calc(var(--rail) + 7px); }
.partners__label { flex: none; display: inline-flex; align-items: center; gap: 12px; }
/* the board's status lamp: lit signal orange (the theme green is too dark to glow on the board) */
.partners__label::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #E2520F; box-shadow: 0 0 2px #E2520F, 0 0 8px rgba(226, 82, 15, .85), inset 0 0 1px rgba(255, 240, 230, .8); }
.partners__track {
  flex: 1; min-width: 0; display: flex; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.partners__row { display: flex; flex: none; gap: 44px; padding: 0 22px; margin: 0; list-style: none; animation: partners 46s linear infinite; }
.partners__track:hover .partners__row { animation-play-state: paused; }
.partners__row li { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; font-size: 19px; color: #D9D3C5; transition: color var(--fast); }
.partners__row li:hover { color: #FFFFFF; }
.partners__row svg { width: 20px; height: 20px; fill: currentColor; }
@keyframes partners { to { transform: translateX(-100%); } }
/* the label as a split-flap display (assets/splitflap.js builds one cell per character,
   rows padded to equal length with blank flaps). A cell is four halves: the new top and old
   bottom sit still behind, while the old top falls forward on the hinge and the new bottom
   swings down over it. */
.sf { display: grid; gap: 3px; }
.sf__row { display: flex; gap: 2px; }
.sf__cell {
  --h: 30px;
  position: relative; width: 21px; height: var(--h); border-radius: 3px; perspective: 110px;
  font: 600 19px/var(--h) var(--font-mono); color: #F1EDE3; text-align: center; letter-spacing: 0;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .05), 0 0 0 .5px #000, 0 2px 3px rgba(0, 0, 0, .5);
}
.sf__cell > span { position: absolute; left: 0; right: 0; height: 50%; overflow: hidden; backface-visibility: hidden; }
.sf__cell b { display: block; height: var(--h); font-weight: 600; }
.sf__t, .sf__ft { top: 0; border-radius: 3px 3px 0 0; background: linear-gradient(180deg, #34332F, #282725); }
.sf__b, .sf__fb { bottom: 0; border-radius: 0 0 3px 3px; background: linear-gradient(180deg, #22211F, #2C2B28); }
.sf__b b, .sf__fb b { margin-top: calc(var(--h) / -2); }
.sf__ft { z-index: 2; transform-origin: 50% 100%; }
.sf__fb { z-index: 2; transform-origin: 50% 0; transform: rotateX(90deg); }
/* the hinge: a dark split across the middle */
.sf__cell::after {
  content: ""; position: absolute; z-index: 3; left: 0; right: 0; top: calc(50% - .5px); height: 1px;
  background: #050505; box-shadow: 0 1px 0 rgba(255, 255, 255, .06);
}
/* the flap falls under its own weight (accelerating), then the new bottom slaps down past
   its stop and bounces back; the falling flap shades the half beneath it until it lands */
.sf__b::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0, 0, 0, .75), rgba(0, 0, 0, .1)); opacity: 0; pointer-events: none; }
.sf__cell.is-flipping .sf__ft { animation: sf-top var(--sf-half, 32ms) cubic-bezier(.55, 0, 1, .45) forwards; }
.sf__cell.is-flipping .sf__b::after { animation: sf-shade var(--sf-half, 32ms) ease-in forwards; }
.sf__cell.is-flipping .sf__fb { animation: sf-bot calc(var(--sf-half, 32ms) * 2.4) cubic-bezier(.25, .8, .35, 1) var(--sf-half, 32ms) both; }
@keyframes sf-top { to { transform: rotateX(-90deg); filter: brightness(.5); } }
@keyframes sf-shade { to { opacity: 1; } }
@keyframes sf-bot {
  0%   { transform: rotateX(90deg); filter: brightness(1.5); }
  45%  { transform: rotateX(-14deg); filter: none; }
  72%  { transform: rotateX(5deg); }
  100% { transform: rotateX(0); }
}
/* landing on its final letter: the character flashes bright and the tile jolts a hair */
.sf__cell.is-landed { animation: sf-jolt 240ms ease-out; }
.sf__cell.is-landed b { animation: sf-pop 340ms ease-out; }
@keyframes sf-jolt { 30% { translate: 0 1.5px; } 60% { translate: 0 -.5px; } }
@keyframes sf-pop { 0% { color: #FFFFFF; text-shadow: 0 0 6px rgba(255, 246, 225, .9); } 100% { color: inherit; text-shadow: none; } }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (max-width: 680px) {
  .partners__inner { flex-direction: column; align-items: flex-start; gap: 14px; }
  .partners__track { width: 100%; }
  .sf__cell { width: 18px; --h: 26px; font-size: 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .partners__row { animation: none; flex-wrap: wrap; row-gap: 14px; }
  .partners__row[aria-hidden="true"] { display: none; }
  .partners__track { -webkit-mask-image: none; mask-image: none; }
}

/* --------------------------------------------------------------------------
   Service bars: compact full-width links, one per practice
   -------------------------------------------------------------------------- */

.svc-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
.svc-col { display: grid; gap: 14px; scroll-margin-top: 96px; min-width: 0; }
.svc-pillar { display: grid; gap: 12px; padding: clamp(22px, 3vw, 34px); }
.svc-pillar h2 em { font-style: italic; color: var(--green); }
.svc-pillar p { margin: 0; }
.svc-pillar__all { font-family: var(--font-mono); font-size: 12px; letter-spacing: .07em; text-transform: uppercase; color: var(--green); margin-top: 6px; }
.svc-pillar__all:hover .arrow { display: inline-block; transform: translateX(4px); }

.svc-bars { display: grid; gap: 8px; }
.svc-bar {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; grid-template-areas: "n name i" "n text i";
  column-gap: 14px; row-gap: 2px; align-items: center;
  padding: 14px 18px; border: 1px solid var(--line-2); border-radius: var(--r-sm); background: var(--surface);
  transition: border-color var(--fast), transform var(--fast) var(--ease);
}
.svc-bar:hover { border-color: var(--text); transform: translateX(3px); }
.svc-bar__n { grid-area: n; font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; color: var(--green); letter-spacing: .04em; }
.svc-bar strong { grid-area: name; font-weight: 500; font-size: 18px; line-height: 1.25; }
.svc-bar strong small { font-family: var(--font-mono); font-size: 11.5px; font-weight: 400; color: var(--text-3); margin-left: 4px; }
.svc-bar__text { grid-area: text; font-size: 14.5px; color: var(--text-2); line-height: 1.4; }
.svc-bar i { grid-area: i; font-style: normal; color: var(--text-3); transition: color var(--fast), transform var(--fast) var(--ease); }
.svc-bar:hover i { color: var(--green); transform: translateX(3px); }
.svc-bar--door { grid-template-columns: 110px minmax(0, 1fr) auto; padding: 20px 22px; }
.svc-bar--door .svc-bar__n { text-transform: uppercase; letter-spacing: .08em; }
.svc-bar--door strong { font-size: 22px; }
@media (max-width: 900px) { .svc-cols { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   Services hero: two people drawn in type (after a typographic portrait
   reference), the left one in Growth's words, the right in Systems', building
   a crossword between them: GROWTH and SYSTEMS down, OUTCOMES across both.
   Generated by _build/make_text_figures.py. The markup is the finished build;
   assets/herobuild.js adds .is-scrub, which makes the section tall and pins
   the stage, and builds the crossword square by square with the scroll.
   -------------------------------------------------------------------------- */

.page-hero--art { position: relative; padding-block: 0; }
.page-hero__stage {
  position: relative; overflow: hidden; display: flex; align-items: center;
  min-height: clamp(560px, min(84vh, 56vw), 800px); padding-block: 72px 48px;
}
.page-hero--art.is-scrub { height: 200vh; }   /* a short run: the build should not outlast the reader's patience */
/* pinned under the sticky nav (herobuild.js measures it into --nav-h), so the stage is exactly the visible area */
.page-hero--art.is-scrub .page-hero__stage { position: sticky; top: var(--nav-h, 0px); height: calc(100vh - var(--nav-h, 0px)); min-height: 0; }
.page-hero__stage > .wrap { position: relative; z-index: 1; }
/* a warm light falling in from the top-left corner, behind the copy and the figures */
.page-hero__stage::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(70% 85% at 0% 0%, rgba(226, 82, 15, .26), rgba(226, 82, 15, .1) 40%, transparent 72%),
    radial-gradient(55% 60% at 8% 0%, rgba(246, 178, 72, .32), transparent 70%);
}
@media (max-width: 900px) {
  .page-hero__stage::before {
    background:
      radial-gradient(130% 70% at 0% 0%, rgba(226, 82, 15, .24), rgba(226, 82, 15, .08) 45%, transparent 75%),
      radial-gradient(100% 50% at 10% 0%, rgba(246, 178, 72, .3), transparent 70%);
  }
}
/* runs to the screen's right edge and down to the stage's bottom: the figures are cropped at
   the thigh by the bottom edge, so they loom rather than stand in the distance */
.page-hero__art { position: absolute; z-index: 0; top: 40px; bottom: 0; right: 0; width: min(62vw, 1120px); pointer-events: none; }
.page-hero--art .lede { max-width: min(40ch, 34vw); }
.figs { display: block; width: 100%; height: 100%; }
.figs text { fill: var(--text); }
/* symbol art: fixed-size mono glyphs on a character grid; spaces are the gaps, so keep them */
.figs__sym text, .figs__f, .figs__clue { font-family: var(--font-mono); font-weight: 600; white-space: pre; }
.figs__sym text { font-size: 9px; }
.figs__f { font-size: 7px; }
.figs__f { opacity: .3; font-weight: 500; }
/* the crossword squares: printed grid squares like the home hero's, crossings in Ember */
.figs__cell rect { fill: #FFFDF8; stroke: #0E110F; stroke-width: 1.5; }
.figs__ch { font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 800; text-anchor: middle; }   /* size comes from the projected cell */
.figs__num { font-family: var(--font-mono); font-size: 7.5px; font-weight: 500; }
.figs__cell--x rect { fill: var(--orange); stroke: #0E110F; }
/* the blank tiles waiting on each stack: tile edges, seen from the side */
.figs__stack rect { fill: #FFFDF8; stroke: #0E110F; stroke-width: 1.2; }
.figs .figs__cell--x .figs__ch, .figs .figs__cell--x .figs__num { fill: #fff; }
.figs__clue { font-size: 10.5px; white-space: normal; letter-spacing: .14em; text-anchor: middle; fill: var(--text-2); }
/* while the scroll is building it, a crossing only turns Ember once its square has landed */
.is-scrub .figs__cell--x:not(.is-set) rect { fill: #FFFDF8; }
.is-scrub .figs .figs__cell--x:not(.is-set) .figs__ch, .is-scrub .figs .figs__cell--x:not(.is-set) .figs__num { fill: var(--text); }
.page-hero__hint {
  position: absolute; z-index: 1; left: 50%; bottom: 22px; translate: -50% 0;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--text);
  background: var(--bg, #F4F3EF); border: 1px solid var(--line-2); padding: 7px 12px;
}
@media (max-width: 900px) { .page-hero__art { display: none; } }

/* --------------------------------------------------------------------------
   Services clue board (services.html): the practices as the clue sheet of a
   crossword, Growth Across and Systems Down, after a dot-matrix LED board.
   Every answer square is a 5x5 field of unlit dots with the letter lit in
   Doto over it, and every track runs the same length, so the empty squares
   carry the grid on past each answer. clueboard.js fills the answers in.
   -------------------------------------------------------------------------- */

/* the board IS the section: full bleed, no card. Tone tokens: ground, lit ink, dim ink,
   unlit dots, rules, the heading italic, and the solved square (--cb-hit, letter --cb-hit-ink) */
.cb-sec {
  --cb-bg: #CFDDE6; --cb-ink: #111315; --cb-dim: rgba(17, 19, 21, .62); --cb-off: rgba(17, 19, 21, .16);
  --cb-rule: rgba(17, 19, 21, .16); --cb-em: #111315; --cb-hit: #111315; --cb-hit-ink: #CFDDE6;
  background: var(--cb-bg); color: var(--cb-ink); padding-block: clamp(48px, 7vw, 96px);
}
.cb-sec[data-tone="ink"] {
  --cb-bg: #15171A; --cb-ink: #F4EFE3; --cb-dim: rgba(244, 239, 227, .58); --cb-off: rgba(244, 239, 227, .11);
  --cb-rule: rgba(244, 239, 227, .13); --cb-em: #F2C230; --cb-hit: #F2C230; --cb-hit-ink: #15171A;
}
.cb-sec[data-tone="paper"] {
  --cb-bg: #E9E4D8; --cb-ink: #111315; --cb-dim: rgba(17, 19, 21, .6); --cb-off: rgba(17, 19, 21, .14);
  --cb-rule: rgba(17, 19, 21, .15); --cb-em: #111315; --cb-hit: #F2C230; --cb-hit-ink: #111315;
}
/* accents on the ink ground (Sunflower read as a certain website): the italic + solved square */
.cb-sec[data-accent="cream"] { --cb-em: #CFC8B8; --cb-hit: #F4EFE3; --cb-hit-ink: #15171A; }
.cb-sec[data-accent="sky"] { --cb-em: #CFDDE6; --cb-hit: #CFDDE6; --cb-hit-ink: #15171A; }
.cb-sec[data-accent="peri"] { --cb-em: #AEB4F0; --cb-hit: #8C95E8; --cb-hit-ink: #15171A; }
.cb { position: relative; color: var(--cb-ink); }

/* the sheet's edges, out in the side margins: sideways serial + barcode on the left,
   instructions on the right, and a timing mark beside every row (OMR sheet, pin #06) */
.cb-edge {
  display: none; position: absolute; top: 0; bottom: 0; writing-mode: vertical-rl;
  align-items: center; justify-content: space-between; gap: 24px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--cb-dim);
}
.cb-edge--l { left: -112px; rotate: 180deg; }
.cb-edge--r { right: -112px; }
.cb-edge__code { fill: var(--cb-dim); writing-mode: horizontal-tb; }
.cb__row, .cb__head { position: relative; }
.cb__row::before, .cb__row::after, .cb__head::before, .cb__head::after {
  content: none; position: absolute; top: 50%; width: 22px; height: 7px; margin-top: -3.5px; background: var(--cb-dim);
  transition: background-color var(--fast), width var(--fast) var(--ease);
}
.cb__head::before, .cb__head::after { top: auto; bottom: 26px; width: 36px; background: var(--cb-ink); }
.cb__row::before, .cb__head::before { left: -58px; }
.cb__row::after, .cb__head::after { right: -58px; }
.cb__row:hover::before, .cb__row:hover::after { background: var(--cb-hit); width: 30px; }
@media (min-width: 1300px) {
  .cb__row::before, .cb__row::after, .cb__head::before, .cb__head::after { content: ""; }
}
@media (min-width: 1400px) { .cb-edge { display: flex; } }
.cb__bar {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-dim);
  padding-bottom: 14px; border-bottom: 1px solid var(--cb-rule);
}
.cb__group { scroll-margin-top: 96px; padding-top: clamp(22px, 3vw, 34px); }
.cb__head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: clamp(14px, 2.4vw, 28px); align-items: end; padding-bottom: 16px; }
.cb__dir {
  font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 800; text-transform: uppercase;
  font-size: clamp(30px, 4.4vw, 54px); line-height: .9; letter-spacing: .02em;
}
.cb__head h2 { margin: 0 0 4px; color: var(--cb-ink); }
.cb__head h2 em { font-style: italic; color: var(--cb-em); }
.cb__head p { margin: 0; color: var(--cb-dim); font-size: 14.5px; max-width: 60ch; }
.cb__all { font-family: var(--font-mono); font-size: 12px; letter-spacing: .07em; text-transform: uppercase; color: var(--cb-ink); white-space: nowrap; }
.cb__all:hover .arrow { display: inline-block; transform: translateX(4px); }

.cb__rows { border-top: 1px solid var(--cb-rule); }
.cb__row {
  display: grid; grid-template-columns: 30px minmax(0, .75fr) minmax(0, 1.7fr) 8.5ch 18px; gap: clamp(10px, 1.6vw, 20px); align-items: center;
  padding: 9px 8px; border-bottom: 1px solid var(--cb-rule); color: var(--cb-ink);
  transition: background-color var(--fast);
}
.cb__row:hover, .cb__row:focus-visible { background: var(--cb-rule); }
.cb__n { font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--cb-dim); }
.cb__clue { font-size: 14.5px; line-height: 1.35; color: var(--cb-dim); transition: color var(--fast); }
.cb__row:hover .cb__clue { color: var(--cb-ink); }
.cb__sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.cb__enum { font-family: var(--font-mono); font-size: 12px; color: var(--cb-dim); text-align: right; white-space: nowrap; }
.cb__row i { font-style: normal; color: var(--cb-dim); transition: color var(--fast), transform var(--fast) var(--ease); }
.cb__row:hover i { color: var(--cb-ink); transform: translateX(3px); }

/* the answer track: --track squares, each a 5x5 dot matrix with its letter lit over it */
.cb__ans { display: grid; grid-template-columns: repeat(var(--track), minmax(0, 1fr)); gap: 2px; container-type: inline-size; }
.cb__c {
  aspect-ratio: 1; display: grid; place-items: center;
  background: radial-gradient(circle, var(--cb-off) 34%, transparent 38%) 0 0 / 20% 20%;
  font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 800;
  font-size: calc(100cqw / var(--track) * .8); line-height: 1; color: var(--cb-ink);
  transition: color 90ms, background-color var(--fast);
}
.cb__c--gap, .cb__c--off { color: transparent; }
/* solved: the answer flashes the tone's hit colour once as it completes, and again on hover */
.cb__row:hover .cb__c:not(.cb__c--gap, .cb__c--off) { background-color: var(--cb-hit); color: var(--cb-hit-ink); }
.cb__row.is-solved .cb__c:not(.cb__c--gap, .cb__c--off) { animation: cb-solve 700ms var(--ease); }
@keyframes cb-solve { 0%, 40% { background-color: var(--cb-hit); color: var(--cb-hit-ink); } 100% { background-color: transparent; } }
/* while clueboard.js is filling a row in, its unrevealed letters stay unlit */
.cb.is-solving .cb__c:not(.on) { color: transparent; }

@media (max-width: 900px) {
  .cb__head { grid-template-columns: 1fr; align-items: start; gap: 8px; }
  .cb__row { grid-template-columns: 26px minmax(0, 1fr) 18px; grid-template-areas: "n clue i" "n ans i"; row-gap: 8px; padding: 12px 4px; }
  .cb__n { grid-area: n; align-self: start; padding-top: 2px; }
  .cb__clue { grid-area: clue; }
  .cb__ans { grid-area: ans; }
  .cb__enum { display: none; }
  .cb__row i { grid-area: i; }
}
@media (prefers-reduced-motion: reduce) { .cb__row.is-solved .cb__c { animation: none; } }

/* --------------------------------------------------------------------------
   Home keyboard into services.html (moodboard pins #04, #05).
   Rows of blank keys in real keyboard widths (15 key units a row); the three
   service keys sit in the main row. Rows above loosen toward the method
   section: build.py drops, tilts, shrinks and lifts keys there (never fades
   them), and the section's negative top margin lets them climb into the space
   above. Rows are padded past both screen edges and clipped by the section,
   so the board always reaches both sides. Sized from one key unit --u.
   Keys are physical objects, so their colours are the same in both themes.
   -------------------------------------------------------------------------- */

.section--keys { padding-block: 0 clamp(8px, 1vw, 14px);   /* the mail window sits right under it, with no rule between */ margin-top: clamp(-250px, -14.5vw, -50px); overflow-x: clip; }
/* the board climbs up level with the method's button; keep that button above any drifting key */
.section--keys { pointer-events: none; }
.section--keys .k { pointer-events: auto; }
.kb {
  /* room above for the drifting keys, below for the key lips and shadows */
  padding-block: clamp(36px, 5vw, 76px) clamp(18px, 2.4vw, 32px);
}
.kb__row {
  --g: clamp(4px, .62vw, 9px);
  --u: clamp(26px, 4.6vw, 68px);
  /* rows are wider than the screen; centring them overflows both edges equally */
  display: flex; justify-content: center; align-items: center; gap: var(--g); margin-top: calc(var(--g) * 1.6);
}
.k {
  flex: none; position: relative; display: block;
  width: calc(var(--w) * var(--u) + (var(--w) - 1) * var(--g)); height: var(--u);
  /* loosening rows: set per key by build.py */
  /* + scroll rattle: keyboard.js drives --sh1/--sh2 on .kb, each key scales them by its own phase */
  translate: 0 calc(var(--y, 0) * var(--u) + var(--sh2, 0) * var(--ph2, 0) * 3px);
  rotate: calc(var(--r, 0deg) + var(--sh1, 0) * var(--ph1, 0) * 3deg);
  scale: var(--s, 1);
  transition: transform 110ms var(--ease);
}
/* The cap itself is a photoreal render (assets/keys/, made by _build/render_keycaps.py
   in Blender + _build/composite_keycaps.py), shadow baked in. Each image spans the cap
   plus fixed margins in key units, so these four insets place every width; they must
   match MARGIN_X / MARGIN_TOP / MARGIN_BOTTOM in render_keycaps.py. */
.k::before {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  inset: calc(var(--u) * -.22) calc(var(--u) * -.32) calc(var(--u) * -.48);
  background: var(--cap) center / 100% 100% no-repeat;
  transition: filter 110ms var(--ease);
}
.k[data-cap="white-1"] { --cap: url(keys/white-1.webp); }
.k[data-cap="white-1.25"] { --cap: url(keys/white-1.25.webp); }
.k[data-cap="white-1.5"] { --cap: url(keys/white-1.5.webp); }
.k[data-cap="white-1.75"] { --cap: url(keys/white-1.75.webp); }
.k[data-cap="white-2.25"] { --cap: url(keys/white-2.25.webp); }
.k[data-cap="white-6.25"] { --cap: url(keys/white-6.25.webp); }
.k[data-cap="grey-1"] { --cap: url(keys/grey-1.webp); }
.k[data-cap="grey-1.25"] { --cap: url(keys/grey-1.25.webp); }
.k[data-cap="grey-1.5"] { --cap: url(keys/grey-1.5.webp); }
.k[data-cap="grey-2"] { --cap: url(keys/grey-2.webp); }
.k[data-cap="signal-1.25"] { --cap: url(keys/signal-1.25.webp); }
.k[data-cap="signal-1"] { --cap: url(keys/signal-1.webp); }
.k[data-cap="cobalt-1"] { --cap: url(keys/cobalt-1.webp); }
.k[data-cap="cobalt-1.25"] { --cap: url(keys/cobalt-1.25.webp); }
.k[data-cap="cobalt-3"] { --cap: url(keys/cobalt-3.webp); }
.k[data-cap="indigo-1"] { --cap: url(keys/indigo-1.webp); }
.k[data-cap="indigo-1.25"] { --cap: url(keys/indigo-1.25.webp); }
.k[data-cap="indigo-1.5"] { --cap: url(keys/indigo-1.5.webp); }
.k[data-cap="indigo-2"] { --cap: url(keys/indigo-2.webp); }
.k[data-cap="moss-1"] { --cap: url(keys/moss-1.webp); }
.k[data-cap="moss-1.25"] { --cap: url(keys/moss-1.25.webp); }
.k[data-cap="moss-1.5"] { --cap: url(keys/moss-1.5.webp); }
.k[data-cap="moss-2"] { --cap: url(keys/moss-2.webp); }
.k[data-cap="teal-1"] { --cap: url(keys/teal-1.webp); }
.k[data-cap="teal-1.25"] { --cap: url(keys/teal-1.25.webp); }
.k[data-cap="teal-3"] { --cap: url(keys/teal-3.webp); }
.k[data-cap="peri-1"] { --cap: url(keys/peri-1.webp); }
.k[data-cap="peri-1.25"] { --cap: url(keys/peri-1.25.webp); }
.k[data-cap="peri-3"] { --cap: url(keys/peri-3.webp); }
.k[data-cap="sunflower-1"] { --cap: url(keys/sunflower-1.webp); }
.k[data-cap="sunflower-1.25"] { --cap: url(keys/sunflower-1.25.webp); }
.k[data-cap="sky-3"] { --cap: url(keys/sky-3.webp); }
.k--gap { visibility: hidden; }

/* every key gives a little under the cursor; pressing sinks it by its full travel */
.k:hover { transform: translateY(calc(var(--u) * .035)); }
.k:active { transform: translateY(calc(var(--u) * .07)); }
.k:active::before { filter: brightness(.96); }

/* the three service keys, one per cool ink (cobalt, deep teal, periwinkle; was all cobalt
   until 2026-10-29). Older note: the only SKY keys on a white board, so they read at a
   glance in both themes. Labels sit on the render's top face (the front skirt takes
   the bottom ~.4u of the key), printed in ink with deep-blue legends, and a
   signal-orange LED that is always on (palette 1, "The Coordinate"). */
.k--main {
  display: flex; flex-direction: column; justify-content: space-between;
  padding: calc(var(--u) * .08) calc(var(--u) * .3) calc(var(--u) * .45);
  color: #FBFAF7; -webkit-tap-highlight-color: transparent;
}
.k--main > * { position: relative; z-index: 1; }
.k--main small { font-family: var(--font-mono); font-size: max(8px, calc(var(--u) * .15)); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: #F2C230; line-height: 1; }
/* legends printed into the plastic: a hairline of light under each stroke, as dye-sub does */
.k--main b { font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 900; font-size: max(12px, calc(var(--u) * .38)); line-height: 1; letter-spacing: .04em; text-transform: uppercase; color: #FFFFFF; text-shadow:  0 1px 0 rgba(0, 0, 0, .25); }
/* the LED sits in a tiny dark well so it reads as a lamp behind the cap, not a sticker on it */
.k--main i { position: absolute; top: calc(var(--u) * .1); right: calc(var(--u) * .3); width: max(5px, calc(var(--u) * .09)); height: max(5px, calc(var(--u) * .09)); background: #E2520F; box-shadow: 0 0 0 1px rgb(30 50 64 / .35), 0 0 6px rgba(226, 82, 15, .85); transition: background var(--fast), box-shadow var(--fast); }
.k--main:hover i, .k--main:focus-visible i { background: #FF8A4C; box-shadow: 0 0 0 1px rgb(30 50 64 / .35), 0 0 0 3px rgba(226, 82, 15, .28), 0 0 14px rgba(226, 82, 15, 1); }
.k--main:focus-visible { outline: 2px solid var(--green); outline-offset: 4px; }

/* phones: a key unit is 26px, too small to print a word on, so the service keys
   widen and deepen, and the blank keys between them drop out so all three fit */
@media (max-width: 640px) {
  .kb__row--main .k--main { --w: 3.8; --cap: url(keys/cobalt-3.8-tall.webp); height: calc(var(--u) * 1.9); padding: 6px 10px 15px; }
  .kb__row--main .k--main[data-cap="teal-3"] { --cap: url(keys/teal-3.8-tall.webp); }
  .kb__row--main .k--main[data-cap="peri-3"] { --cap: url(keys/peri-3.8-tall.webp); }
  .kb__row--main .k--main + .k:not(.k--main) { display: none; }
  .kb__row--main .k--main b { font-size: 11px; letter-spacing: .01em; }
  .kb__row--main .k--main small { font-size: 8px; }
  .kb__row--main .k--main i { top: 8px; right: 9px; }
}
@media (prefers-reduced-motion: reduce) { .k { transition: none; } }

/* --------------------------------------------------------------------------
   Home "Three problems": a board meeting seen from above, table running
   across the page, with the problems PRINTED on the table top as the
   meeting's agenda (the source magazine printed its article the same way).
   The photo is a transparent cut-out, so it sits on either theme's ground.
   Agenda position is a percentage of the photo: the cleared table top runs
   from 18% to 79% across and 33% to 65% down (board_table.py TEXT_BOX, rotated).
   All sizes are cqw so the print scales with the table at every width.
   -------------------------------------------------------------------------- */

/* tighter than a default .section: the table itself fills the space */
.section--board { padding-block: clamp(44px, 5.5vw, 76px) clamp(28px, 4vw, 56px); }
.section--board .sec-head { margin-bottom: 0; gap: 6px; }
.board {
  position: relative; margin: clamp(-8px, -1vw, 0px) auto 0; width: min(100%, 1060px);
  container-type: inline-size;
}
/* a soft pool of light under the table, so the meeting lifts off the page */
.board::before {
  content: ""; position: absolute; inset: 14% 8%; z-index: 0; pointer-events: none;
  background: radial-gradient(closest-side, rgba(var(--ov), .10), transparent);
  filter: blur(18px);
}
/* Layers from _build/board_layers.py: the bare table in flow (it sizes the figure), one
   cut-out per sitter on top. assets/board.js plays the meeting convening on scroll by
   setting, per element, how far it still has to go (0 = the finished scene, which is
   also what shows with no script or reduced motion):
     --pull on each sitter (pushed back from the table along --dx/--dy)
     --k on each sheet (out at its sender's seat, turned), --l on the label
     --sk on the sticker (lifted off the table, before it slaps down) */
.board__scene { position: relative; }
.board__table { position: relative; z-index: 1; display: block; width: 100%; height: auto; filter: drop-shadow(0 2.2cqw 2.4cqw rgba(14, 17, 15, .28)); }
.board__p {
  position: absolute; z-index: 3; height: auto; pointer-events: none;
  translate: calc(var(--dx) * var(--pull, 0) * 4.6cqw) calc(var(--dy) * var(--pull, 0) * 4.6cqw);
  filter: drop-shadow(0 1.1cqw 1.3cqw rgba(14, 17, 15, .2));
  will-change: translate;
}
.board__agenda {
  position: absolute; z-index: 2; left: 23.5%; width: 50%; top: 32%; height: 34%;
  display: flex; flex-direction: column; justify-content: center; gap: 1cqw;
  color: #0E110F;
}
.board__label i { font-style: normal; }
/* the label is still printed on the table: multiply soaks the ink into its grain */
.board__label { font-family: var(--font-mono); font-size: max(9px, 1.05cqw); font-weight: 600; letter-spacing: .16em; text-transform: uppercase; opacity: calc(.7 * (1 - var(--l, 0))); mix-blend-mode: multiply; }
.board__agenda ol { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5cqw; }
/* each problem is a sheet of paper: a hairline contact shadow, a short soft one and a
   long faint one, so it reads as lying ON the table rather than printed into it */
.board__agenda li {
  display: grid; align-content: start; gap: 1cqw; min-height: 17cqw; padding: 1.3cqw 1.3cqw 1.6cqw;
  background: linear-gradient(160deg, #FDFCF8 0%, #F6F4EE 60%, #EFEDE6 100%);
  box-shadow: 0 .06cqw .12cqw rgba(14, 17, 15, .3), 0 .45cqw .9cqw -.2cqw rgba(14, 17, 15, .26), 0 1.6cqw 2.6cqw -1.1cqw rgba(14, 17, 15, .32);
  rotate: calc(var(--rest) + var(--k, 0) * var(--spin));
  translate: calc(var(--k, 0) * var(--fx)) calc(var(--k, 0) * var(--fy));
  opacity: calc(1 - var(--k, 0) * 1.6);
  will-change: translate, rotate;
}
/* where each sheet comes from: the seat that passes it across */
.board__agenda li:nth-child(1) { --rest: -2.2deg; --fx: -9cqw; --fy: 21cqw; --spin: -18deg; }
.board__agenda li:nth-child(2) { --rest: 1.4deg; --fx: 1cqw; --fy: -24cqw; --spin: 14deg; }
.board__agenda li:nth-child(3) { --rest: -.8deg; --fx: 25cqw; --fy: 3cqw; --spin: 22deg; }
.board__agenda b { font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 800; line-height: .88; color: #141414; }
.board__agenda span { font-size: max(12px, 1.85cqw); font-weight: 500; line-height: 1.05; letter-spacing: .005em; font-variation-settings: "opsz" 36; }
/* phones: the table is ~360px wide, so the sheets take more of it */
@container (max-width: 600px) {
  /* kept inside the end sitters' reach (their hands lie on the table's ends) */
  .board__agenda { top: 28%; height: 44%; left: 18%; width: 64%; gap: 2cqw; }
  .board__label { font-size: 2.3cqw; }
  .board__label i { display: none; }
  .board__agenda ol { gap: 1.6cqw; }
  .board__agenda li { min-height: 24cqw; padding: 1.6cqw 1.3cqw 2cqw; gap: 1.4cqw; }
  .board__agenda span { font-size: 2.75cqw; line-height: 1.06; hyphens: auto; }
}

/* a figure still awaiting its real number: visibly a placeholder */
.stat__tbc { color: var(--text-3) !important; opacity: .55; }
@media (max-width: 560px) {
  .svc-bar--door { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "n i" "name i" "text i"; }
}

/* --------------------------------------------------------------------------
   Industries index (services.html#industries, industries.html): the back page
   of the paper the services sheet is printed in. Sectors run in newspaper
   columns with rules between them; each entry has a dotted leader out to its
   number in a lit dot-matrix square. industryindex.js types the find field into squares.
   -------------------------------------------------------------------------- */

/* on newsprint the solved square is ink, not Sunflower */
/* a wider sheet than the site's 1180px, so the columns breathe and the side margins shrink */
.cb-sec.ix-sec { --maxw: 1340px; --cb-hit: #111315; --cb-hit-ink: #E9E4D8; --ix-green: #154530; }
/* The ground is one long gradient: a warm apricot newsprint at the top (the livelier cousin
   of the paper, leaning to Laser Orange), the plain newsprint at the middle, and the page
   ground (--ink, #F6F4EF) at the bottom, so it runs into the section below with no edge.
   Each half is smoothstep-eased through extra stops (t = .104, .352, .648, .896) and mixed in
   oklab, which is what keeps a gradient this long and this pale from banding. */
.cb-sec.ix-sec {
  --ix-top: #F2D2B8; --ix-mid: #E9E4D8; --ix-end: var(--ink);
  background: linear-gradient(in oklab to bottom,
    var(--ix-top) 0%,
    color-mix(in oklab, var(--ix-mid) 10.4%, var(--ix-top)) 10%,
    color-mix(in oklab, var(--ix-mid) 35.2%, var(--ix-top)) 20%,
    color-mix(in oklab, var(--ix-mid) 64.8%, var(--ix-top)) 30%,
    color-mix(in oklab, var(--ix-mid) 89.6%, var(--ix-top)) 40%,
    var(--ix-mid) 50%,
    color-mix(in oklab, var(--ix-end) 10.4%, var(--ix-mid)) 60%,
    color-mix(in oklab, var(--ix-end) 35.2%, var(--ix-mid)) 70%,
    color-mix(in oklab, var(--ix-end) 64.8%, var(--ix-mid)) 80%,
    color-mix(in oklab, var(--ix-end) 89.6%, var(--ix-mid)) 90%,
    var(--ix-end) 100%);
}
.ix-sec + .ix-sec, .cb-sec + .ix-sec { border-top: 0; }
.ix__head {
  display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "dir text";
  column-gap: clamp(14px, 2.4vw, 28px); align-items: end; padding: clamp(22px, 3vw, 34px) 0 22px;
}
/* The find row is sticky for the length of the index only: it pins under the site header
   (68px) and lets go when the index ends, since .ix is its containing block. Pinned, it
   gets a frosted backing like the nav so the entries passing beneath stay out of the way. */
.ix__bar {
  position: sticky; top: 68px; z-index: 5; padding: 12px 0 14px; border-bottom: 2px solid var(--cb-ink);
  transition: background-color var(--fast), box-shadow var(--fast);
}
.ix__bar.is-stuck {
  background: rgba(240, 234, 224, .78); backdrop-filter: blur(12px) saturate(140%); -webkit-backdrop-filter: blur(12px) saturate(140%);
  box-shadow: -100vw 0 0 rgba(240, 234, 224, .78), 100vw 0 0 rgba(240, 234, 224, .78), 0 14px 24px -20px rgba(17, 19, 21, .35);
  clip-path: inset(0 -100vw -40px -100vw);
}
.ix__head .cb__dir { grid-area: dir; }
.ix__head > div { grid-area: text; }
.ix__head h2 { margin: 0 0 4px; color: var(--cb-ink); }
.ix__head h2 em { font-style: italic; }
.ix__head p { margin: 0; color: var(--cb-dim); font-size: 15.5px; max-width: 60ch; }

/* the find field: a full-width row of crossword squares over a real (invisible) input */
.ix__find { position: relative; display: flex; align-items: center; gap: 12px; cursor: text; }
.ix__find-l { font-family: var(--font-mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--cb-dim); }
.ix__cells { --n: 36; flex: 1; display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: 3px; container-type: inline-size; }
.ix__c {
  aspect-ratio: 1; display: grid; place-items: center; border: 1px solid var(--cb-rule);
  background: radial-gradient(circle, var(--cb-off) 34%, transparent 38%) 0 0 / 20% 20%;
  font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 800; font-size: calc(100cqw / var(--n) * .72); line-height: 1;
  text-transform: uppercase; color: var(--cb-ink); transition: background-color 90ms, color 90ms;
}
@media (max-width: 900px) { .ix__cells { --n: 20; } .ix__c:nth-child(n + 21) { display: none; } }
@media (max-width: 520px) { .ix__cells { --n: 14; } .ix__c:nth-child(n + 15) { display: none; } }
.ix__c.on { background-color: var(--cb-hit); color: var(--cb-hit-ink); }
.ix__find:focus-within .ix__c.cur { box-shadow: inset 0 -3px 0 var(--ix-green); animation: ix-blink 1s steps(1) infinite; }
@keyframes ix-blink { 50% { box-shadow: none; } }
.ix__find input { position: absolute; inset: 0; width: 100%; opacity: 0; border: 0; font-size: 16px; cursor: text; }
/* the frame is always on, so the field is easy to spot; focus thickens it */
.ix__cells { outline: 1.5px solid var(--cb-ink); outline-offset: 3px; transition: outline-width var(--fast); }
.ix__find:focus-within .ix__cells { outline-width: 2.5px; }
/* without script the squares can't show typing, so show the plain field instead */
.ix:not(.is-live) .ix__cells { display: none; }
.ix:not(.is-live) .ix__find input { position: static; opacity: 1; width: 16em; padding: 6px 8px; border: 1px solid var(--cb-rule); background: transparent; color: var(--cb-ink); font-family: var(--font-mono); }

.ix__cols { columns: 3 270px; column-gap: clamp(30px, 4vw, 56px); column-rule: 1px solid var(--cb-rule); padding-top: 30px; }
.ix__sec { break-inside: avoid; margin: 0 0 36px; }
.ix__sec[hidden] { display: none; }
/* each sector is printed in its own spot ink (--sx, set by build.py): its glyph, its rule,
   its lit numbers and its search highlight. Names and leaders stay in the black. */
.ix__sec { --sx: var(--cb-ink); }
.ix__sh {
  display: flex; align-items: center; gap: 10px; margin: 0 0 6px; padding-bottom: 9px;
  background: linear-gradient(var(--sx), var(--sx)) 0 100% / 100% 2px no-repeat;
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--cb-ink);
  transition: background-size 520ms var(--ease);
}
.ix__glyph svg { display: block; width: 22px; height: 22px; fill: var(--sx); }
.ix__glyph rect { transition: opacity 140ms; }
.ix__list { list-style: none; margin: 0; padding: 0; }
.ix__list li[hidden] { display: none; }
.ix__row {
  display: grid; grid-template-columns: auto minmax(12px, 1fr) auto; align-items: end; gap: 6px;
  padding: 6px 0; color: var(--cb-ink);
}
.ix__name { font-family: var(--font-display); font-size: 18px; line-height: 1.25; }
.ix__name mark { background: none; color: inherit; box-shadow: inset 0 -.42em color-mix(in srgb, var(--sx) 26%, transparent); }
/* the leader is a line of unlit dot-matrix dots */
.ix__lead { height: 4px; margin-bottom: 6px; background: radial-gradient(circle, var(--cb-off) 45%, transparent 50%) 0 0 / 6px 4px repeat-x; }
.ix__n {
  min-width: 36px; height: 26px; display: grid; place-items: center; padding: 0 3px;
  background: radial-gradient(circle, var(--cb-off) 34%, transparent 38%) 0 0 / 5.2px 5.2px;
  font-family: var(--font-pixel); font-variation-settings: "ROND" 0; font-weight: 800; font-size: 16px; line-height: 1; color: var(--cb-dim);
  transition: background-color var(--fast), color var(--fast);
}
.ix__row:hover .ix__name, .ix__row:focus-visible .ix__name { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.ix__row:hover .ix__n, .ix__row:focus-visible .ix__n { background-color: var(--sx); color: var(--cb-hit-ink); }
.ix__row:hover .ix__lead { background-image: radial-gradient(circle, var(--sx) 45%, transparent 50%); }

/* the masthead word is slightly mis-registered, as cheap two-colour print is: a cobalt
   and an orange plate each a hair off the black */
.ix__head .cb__dir { text-shadow: -1.5px .5px 0 rgba(47, 91, 211, .5), 1.5px -.5px 0 rgba(200, 71, 12, .45); }

/* Typesetting (industryindex.js): each sector sets as it scrolls into view. Its rule draws
   across, its glyph's pixels arrive, then its entries are set one line at a time: the name
   lands, the leader runs out, and the number rolls up to its value and flashes in the
   sector's ink. The markup is the finished page, so no-script and reduced motion see it set. */
.ix.is-typesetting .ix__sec:not(.is-set) .ix__sh { background-size: 0% 2px; }
.ix.is-typesetting .ix__glyph rect:not(.on) { opacity: 0; }
.ix.is-typesetting .ix__list li:not(.is-set) .ix__name { opacity: 0; transform: translateY(4px); }
.ix.is-typesetting .ix__list li:not(.is-set) .ix__lead { transform: scaleX(0); }
.ix.is-typesetting .ix__list li:not(.is-set) .ix__n { color: transparent; }
.ix__name { transition: opacity 260ms var(--ease), transform 260ms var(--ease); }
.ix__lead { transform-origin: left; transition: transform 420ms var(--ease) 80ms; }
.ix__list li.is-set .ix__n { animation: ix-set 900ms var(--ease) 380ms backwards; }
@keyframes ix-set { 0%, 35% { background-color: var(--sx); color: var(--cb-hit-ink); } 100% { background-color: transparent; } }
.ix__none { margin: 8px 0 0; font-family: var(--font-mono); font-size: 13px; color: var(--cb-dim); }
.ix__none a { color: var(--cb-ink); text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 900px) {
  .ix__head { grid-template-columns: 1fr; grid-template-areas: "dir" "text"; align-items: start; row-gap: 12px; }
}
@media (prefers-reduced-motion: reduce) { .ix__find:focus-within .ix__c.cur, .ix__list li.is-set .ix__n { animation: none; } }

@media (prefers-reduced-motion: reduce) {
  .xw { transition: none; }
}

/* home figures: no rule above each figure */
.stats--plain .stat { border-top: 0; padding-top: 0; }

/* --------------------------------------------------------------------------
   Home "The Kairo Method" as a newspaper front page, set straight onto the
   page with no card so it reads as printed on the site's own newsprint.
   Masthead between rules, a tall centred headline, then one
   justified, hyphenated column per stage with column rules and a drop cap.
   -------------------------------------------------------------------------- */

.paper { color: var(--text); }
.paper__mast {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: end; gap: 16px;
  position: relative; padding-bottom: 14px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-2);
}
.paper__mast span:last-child { text-align: right; }
.paper__mast strong {
  font-family: var(--font-display); font-weight: 700; font-size: clamp(30px, 4.6vw, 62px); line-height: .9;
  letter-spacing: -.01em; text-transform: none; color: var(--text); font-variation-settings: "opsz" 72;
}
.paper__dateline {
  position: relative; display: flex; justify-content: space-between; gap: 12px; margin: 0; padding: 7px 0;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--text-2);
}
.paper__headline {
  margin: clamp(22px, 3vw, 36px) auto clamp(20px, 2.6vw, 32px); text-align: center; max-width: 18ch;
  font-size: clamp(40px, 6.4vw, 92px); font-weight: 600; line-height: .94; letter-spacing: -.03em;
}
/* "BREAKING NEWS" rubber stamp at the headline's right (markup: build.py breaking_stamp(),
   motion: assets/stamp.js). The ink multiplies into the newsprint like real ink. The markup
   shows it already stamped; stamp.js adds .is-go, pauses the two animations below and sets
   their time from the scroll position, so the stamp scrubs back and forth with the scroll. */
.paper__head { position: relative; }
.stamp {
  position: absolute; right: 0; top: 50%; width: clamp(150px, 15vw, 214px); aspect-ratio: 2;
  translate: 0 -50%; rotate: -9deg; pointer-events: none;
  color: var(--orange);   /* stamp-pad ink: the brand orange */
}
.stamp__ink { display: block; width: 100%; height: 100%; overflow: visible; mix-blend-mode: multiply; }
/* the rubber squeezes ink past each letter's edge: a stroke in the same ink thickens the face */
.stamp__ink text { fill: currentColor; stroke: currentColor; stroke-width: 2.6px; stroke-linejoin: round; font-family: var(--font-mono); font-weight: 600; }
.stamp__big { font-size: 64px; letter-spacing: .04em; }
.stamp__small { font-size: 34px; letter-spacing: .32em; }
.stamp__tool { position: absolute; max-width: none; height: auto; opacity: 0; transform-origin: 50% 60%; }
.stamp.is-go .stamp__tool { animation: stamp-tool 900ms both; }
.stamp.is-go .stamp__ink { animation: stamp-ink 900ms both; }
.paper__head.is-hit .paper__headline { animation: stamp-jolt 160ms ease-out; }
/* the tool: in from the upper right, high above the page (big, faint far shadow), down
   onto the paper at 52%, a squash as it presses, then lifted away. Shadow tightens as it lands. */
@keyframes stamp-tool {
  0%   { opacity: 0; transform: translate(70%, -125%) rotate(16deg) scale(1.75); filter: drop-shadow(26px 60px 26px rgba(20, 20, 20, .14)); animation-timing-function: cubic-bezier(.3, .6, .4, 1); }
  40%  { opacity: 1; transform: translate(3%, -7%) rotate(-4deg) scale(1.12); filter: drop-shadow(10px 22px 14px rgba(20, 20, 20, .24)); animation-timing-function: cubic-bezier(.6, 0, 1, .6); }
  52%  { opacity: 1; transform: none; filter: drop-shadow(1px 3px 3px rgba(20, 20, 20, .42)); }
  58%  { transform: scale(.975); filter: drop-shadow(1px 2px 2px rgba(20, 20, 20, .45)); }
  66%  { opacity: 1; transform: none; filter: drop-shadow(1px 3px 3px rgba(20, 20, 20, .42)); animation-timing-function: cubic-bezier(.4, 0, .7, .4); }
  100% { opacity: 0; transform: translate(55%, -115%) rotate(12deg) scale(1.7); filter: drop-shadow(26px 60px 26px rgba(20, 20, 20, .12)); }
}
/* the ink is there the instant the rubber touches, spread a hair wider while pressed */
@keyframes stamp-ink {
  0%, 51.9% { opacity: 0; transform: scale(1.02); }
  52%       { opacity: 1; transform: scale(1.012); }
  66%, 100% { opacity: 1; transform: none; }
}
@keyframes stamp-jolt { 40% { translate: 0 1.5px; } }
@media (max-width: 700px) {
  /* the headline fills the column here, so the stamp drops under its right end, over the
     rule below it, where it stays readable and leaves the headline readable */
  .stamp { top: auto; bottom: -56%; translate: 0 0; width: clamp(104px, 30vw, 150px); }
}
.paper__cols { position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* the paper's horizontal rules run to both edges of the screen, not just the text column */
.paper__mast::after, .paper__dateline::after, .paper__cols::before {
  content: ""; position: absolute; left: 50%; width: 100vw; translate: -50% 0; pointer-events: none;
}
.paper__mast::after { bottom: 0; height: 4px; border-block: 1px solid var(--text); }
.paper__dateline::after { bottom: 0; height: 0; border-top: 1px solid var(--text); }
.paper__cols::before { top: 0; height: 0; border-top: 1px solid var(--text); }
.paper__story { padding: 18px 20px 4px; border-left: 1px solid var(--line-2); }
.paper__story:first-child { padding-left: 0; border-left: 0; }
.paper__story:last-child { padding-right: 0; }
.paper__kicker { margin: 0 0 8px; font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--green); }
.paper__story h3 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 10px; font-size: clamp(22px, 2vw, 28px); font-weight: 600; line-height: 1.05; }
/* a small rubber-stamp box, the one pop of signal orange on the page */
.paper__free {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--green); border: 1.5px solid var(--green); padding: 3px 7px 2px; transform: rotate(-4deg);
}
.paper__body { margin: 0; font-size: 15.5px; line-height: 1.5; text-align: justify; hyphens: auto; -webkit-hyphens: auto; color: var(--text-2); }
.paper__story:first-child .paper__body::first-letter {
  float: left; font-family: var(--font-display); font-weight: 600; font-size: 3.4em; line-height: .82;
  padding: 4px 8px 0 0; color: var(--text);
}
@media (max-width: 900px) {
  .paper__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .paper__story:nth-child(3) { padding-left: 0; border-left: 0; }
  .paper__story:nth-child(n+3) { border-top: 1px solid var(--line-2); }
}
@media (max-width: 560px) {
  .paper__mast { grid-template-columns: 1fr; text-align: center; }
  .paper__mast span { display: none; }
  .paper__dateline span:nth-child(2) { display: none; }
  .paper__cols { grid-template-columns: 1fr; }
  .paper__story, .paper__story:nth-child(3) { padding: 16px 0 4px; border-left: 0; border-top: 1px solid var(--line-2); }
  .paper__story:first-child { border-top: 0; }
}

/* --------------------------------------------------------------------------
   Core team trail (about.html, team.html), after moodboard pin #26 "The
   Coordinate": halftone dot field + footprints (canvas, assets/trail.js), a
   glowing line down the middle, a starburst crosshair at each person, and
   the people on alternating sides. The section has no box: the dot field is
   faded at top and bottom so it melts into the page.
   -------------------------------------------------------------------------- */

.trail {
  --line-x: 50%; --glow: 226, 82, 15;
  /* this section is its own poster: pale blue paper, ink type, an orange laser.
     Fixed colours in both themes, so the local tokens override the page's. */
  --text: #14181B; --text-2: #3E4A52; --text-3: #5F6C74; --ov: 20, 24, 27;
  --line-2: rgba(20, 24, 27, .22); --surface: #D8E3EA; --green: #E2520F;
  position: relative; overflow: hidden; padding-block: clamp(80px, 9vw, 140px); color: var(--text);
}
/* the poster's paper, faded into the page at the top and bottom so it has no edge */
.trail::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  /* the reference poster's paper measures about #C8D6DE: a clear pale blue, not near-white */
  background: linear-gradient(180deg, #CEDBE3, #C2D2DD 50%, #CAD8E1);
  -webkit-mask-image: linear-gradient(transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(transparent, #000 7%, #000 93%, transparent);
}
.trail__dots {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0;
  -webkit-mask-image: linear-gradient(transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(transparent, #000 9%, #000 91%, transparent);
}
.trail .wrap { position: relative; z-index: 1; }
.trail__head {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; gap: 16px;
  margin-bottom: clamp(36px, 6vw, 80px);
  font-family: var(--font-mono); font-size: 13px; letter-spacing: .08em; color: var(--text-2);
}
.trail__head span:last-child { text-align: right; }
.trail__head h2 { text-align: center; font-family: var(--font-display); letter-spacing: -.02em; color: var(--text); }
/* vertical caption down the right edge, as on the poster */
.trail__side {
  position: absolute; z-index: 1; right: max(10px, 1.4vw); top: 50%; margin: 0;
  writing-mode: vertical-rl; translate: 0 -50%;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3);
}

.trail__stops { position: relative; list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(36px, 6vw, 96px); }
/* the laser: a wide, soft orange-pink beam with a hotter core, fading at both ends */
.trail__stops::before {
  content: ""; position: absolute; top: -60px; bottom: -60px; left: var(--line-x); width: 64px; translate: -50% 0; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(226, 82, 15, .28) 26%, rgba(226, 82, 15, .78) 46%, rgba(226, 82, 15, .95) 50%, rgba(226, 82, 15, .78) 54%, rgba(226, 82, 15, .28) 74%, transparent);
  -webkit-mask-image: linear-gradient(transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(transparent, #000 5%, #000 95%, transparent);
  filter: blur(3px); mix-blend-mode: multiply;
}
.trail__stop {
  --x-top: 34%;
  position: relative; display: grid; grid-template-columns: 1fr 1fr; column-gap: clamp(56px, 9vw, 140px);
  align-items: center; min-height: clamp(320px, 34vw, 470px);
}
/* crosshair: a faint horizontal line across the whole screen, with a starburst where it meets the line */
.trail__x {
  position: absolute; top: var(--x-top); left: 50%; width: 100vw; height: 1px; translate: -50% 0; pointer-events: none;
  height: 6px; filter: blur(1.5px);
  background: linear-gradient(90deg, transparent, rgba(226, 82, 15, .55) 15%, rgba(226, 82, 15, .55) 85%, transparent);
}
/* the flare where a crosshair meets the laser: a hot yellow-orange core and four long tapering spikes */
.trail__x::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 260px; height: 300px; translate: -50% -50%; filter: blur(2px);
  background:
    radial-gradient(circle, rgba(255, 214, 120, 1) 0 5px, rgba(226, 82, 15, .95) 12px, rgba(226, 82, 15, .45) 34px, transparent 70px),
    radial-gradient(50% 3.5% at 50% 50%, rgba(226, 82, 15, .95), transparent),
    radial-gradient(4% 50% at 50% 50%, rgba(226, 82, 15, .9), transparent);
}
.trail__coord {
  position: absolute; top: var(--x-top); translate: 0 -170%;
  font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .06em; color: var(--text-2); white-space: nowrap;
}
.trail__stop--right .trail__coord { right: calc(50% + 22px); }
.trail__stop--left .trail__coord { left: calc(50% + 22px); }
.trail__stop--right .member { grid-column: 2; justify-self: start; }
.trail__stop--left .member { grid-column: 1; grid-row: 1; justify-self: end; text-align: right; }
.trail__stop--left .member__photo { margin-left: auto; }

.member { display: grid; gap: 18px; max-width: 420px; }
.member__photo, .person__photo {
  position: relative; aspect-ratio: 4 / 5; width: min(100%, 280px); overflow: hidden;
  border: 1px solid var(--line-2); background-color: var(--surface);
  /* a dotted placeholder in the trail's own halftone until the real photo arrives */
  background-image: radial-gradient(circle, rgba(var(--ov), .22) 1.1px, transparent 1.7px);
  background-size: 9px 9px;
  display: grid; place-items: end start; padding: 12px;
}
.member__photo img, .person__photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.member__photo span, .person__photo span { font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.member__title { font-size: clamp(26px, 2.6vw, 36px); font-weight: 600; line-height: 1.05; }
.member__name { margin: 8px 0 0; font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--green); }
.member__desc { margin: 12px 0 0; font-size: 16.5px; line-height: 1.55; color: var(--text-2); max-width: 40ch; }
.trail__stop--left .member__desc { margin-left: auto; }

.trail__cta .page-hero__actions, .trail__cta { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; }

@media (max-width: 760px) {
  .trail { --line-x: 12px; }
  .trail__stop { grid-template-columns: 1fr; min-height: 0; padding-left: 40px; --x-top: 0px; }
  .trail__stop--right .member, .trail__stop--left .member { grid-column: 1; justify-self: start; text-align: left; }
  .trail__stop--left .member__photo, .trail__stop--left .member__desc { margin-left: 0; }
  .trail__x { left: 0; width: 100%; translate: none; }
  .trail__x::after { left: 12px; width: 90px; height: 90px; }
  .trail__coord, .trail__side { display: none; }
  .trail__head { grid-template-columns: 1fr; text-align: center; }
  .trail__head span { display: none; }
}

/* --------------------------------------------------------------------------
   team.html: the whole team in tabs, one per discipline
   -------------------------------------------------------------------------- */

.tabs__list { display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 18px; margin-bottom: 26px; border-bottom: 1px solid var(--line-2); }
.tabs__list button {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  padding: 9px 14px; border: 1px solid var(--line-2); border-radius: var(--r-sm); background: transparent; color: var(--text-2);
  transition: color var(--fast), border-color var(--fast), background var(--fast);
}
.tabs__list button:hover { color: var(--text); border-color: var(--text); }
.tabs__list button[aria-selected="true"] { background: var(--text); border-color: var(--text); color: var(--ink); }
.tabs__list button:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.tabs__line { margin: 0 0 22px; font-size: 18px; color: var(--text-2); }
.people { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 22px; }
.person { display: grid; gap: 14px; align-content: start; }
.person__photo { width: 100%; }
.person__title { font-size: 21px; font-weight: 600; line-height: 1.1; }
.person__name { margin: 6px 0 0; font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--green); }
.person__desc { margin: 8px 0 0; font-size: 15px; line-height: 1.5; color: var(--text-2); }
@media (max-width: 900px) { .people { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .people { grid-template-columns: 1fr; } }

/* team page apply prompt: a classified ad in the paper, framed by a double ink rule */
.join { border-top: 3px double var(--text); border-bottom: 3px double var(--text); padding: 0 0 clamp(28px, 4vw, 44px); }
.join__mast { display: flex; gap: 0; border-bottom: 1px solid var(--line-2); margin-bottom: clamp(24px, 3.5vw, 40px);
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--text-3); }
.join__mast span { padding: 10px 16px; border-right: 1px solid var(--line-2); white-space: nowrap; }
@media (max-width: 480px) { .join__mast { font-size: 10px; letter-spacing: .08em; } .join__mast span { padding: 10px 8px; } }
.join__mast span:first-child { padding-left: 0; color: var(--text); }
.join__mast span:last-child { border-right: 0; }
.join__body { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: clamp(24px, 5vw, 72px); align-items: end; }
.join__body .h2 { margin: 0; }
.join__side { display: grid; gap: 20px; justify-items: start; border-left: 1px solid var(--line-2); padding-left: clamp(20px, 3vw, 36px); }
.join__side .lede { margin: 0; }
.join__side .cta__actions { justify-content: flex-start; }
@media (max-width: 760px) {
  .join__body { grid-template-columns: 1fr; }
  .join__side { border-left: 0; padding-left: 0; }
}

/* --------------------------------------------------------------------------
   Poster system roles outside the posters: the frame stays black and paper.
   -------------------------------------------------------------------------- */
/* the call to action is the frame inverted: a solid black panel */
.cta.card { background: #141414; border-color: #141414; color: #F6F4EF; }
.cta.card .h2, .cta.card .h2 em { color: #F6F4EF; }
.cta.card .lede { color: #CFCBC2; }
.cta.card .btn { border-color: #F6F4EF; color: #F6F4EF; }
.cta.card .btn--primary { background: #F6F4EF; color: #141414; }
.cta.card .btn:hover { background: #F6F4EF; color: #141414; }

/* Services is a Periwinkle + Cobalt poster */
.ind-card__icon { background: #DFE2FA; border-color: transparent; }
.ind-card:hover .ind-card__icon svg { fill: #2F5BD3; }
.ind-card__tags span { background: #DFE2FA; border-color: transparent; color: #141414; }
.calc-out > div { background-color: #DFE2FA; }
/* three problems: Sunflower printed onto the photo as stickers */
.board__agenda b {
  justify-self: start; background: #F2C230; padding: .5cqw .9cqw .4cqw; rotate: -3deg; mix-blend-mode: normal;
  box-shadow: 0 .4cqw .8cqw -.3cqw rgba(20, 20, 20, .5); font-size: max(16px, 2.7cqw);
}
.board__agenda li:nth-child(2) b { rotate: 2deg; }
.board__agenda li:nth-child(3) b { rotate: -1deg; }
.board__sticker {
  position: absolute; z-index: 4; right: 13%; top: 22%; width: max(70px, 11cqw); aspect-ratio: 1; border-radius: 50%;
  background: #F2C230; display: grid; place-items: center; text-align: center;
  /* --sk > 0: still in the air (bigger, turned, faint); board.js overshoots it below 0 so it squashes as it lands */
  rotate: calc(12deg + var(--sk, 0) * 28deg); scale: calc(1 + var(--sk, 0) * .55); opacity: calc(1 - var(--sk, 0) * 1.4);
  font-family: var(--font-mono); font-size: max(8px, 1.05cqw); font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  line-height: 1.3; color: #141414; box-shadow: 0 calc(.6cqw + max(var(--sk, 0), 0) * 3cqw) calc(1.2cqw + max(var(--sk, 0), 0) * 3cqw) -.4cqw rgba(20, 20, 20, .45);
}
@container (max-width: 600px) { .board__agenda b { font-size: 4.4cqw; } .board__sticker { display: none; } }

/* --------------------------------------------------------------------------
   "Where we work" globe (about.html): a glyph globe drawn on a fixed cell
   grid by assets/globe.js, with the 24/7 line set on a ring around it and a
   live clock for each office underneath.
   -------------------------------------------------------------------------- */
/* the Geochron-style world map behind the whole section (drawn by globe.js). globe.js fits
   it so it is fully visible from the top of the headline down to the office clocks, and
   feathers it out above and below that span itself, so no CSS mask here */
.section--atlas { position: relative; overflow: hidden; }
.section--atlas > .wrap { position: relative; z-index: 1; }
.atlas__cv { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.globe { display: grid; justify-items: center; gap: clamp(20px, 3vw, 32px); margin-top: clamp(24px, 4vw, 48px); }
.globe__stage { position: relative; width: min(600px, 100%); aspect-ratio: 1; }
.globe__cv { position: absolute; inset: 0; width: 100%; height: 100%; cursor: grab; touch-action: pan-y; }
.globe__cv:active { cursor: grabbing; }
.globe__ring { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; animation: globe-orbit 90s linear infinite; }
.globe__ring text { font-family: var(--font-mono); font-size: 15px; font-weight: 500; letter-spacing: .16em; fill: var(--text); }
.globe__ring tspan { fill: var(--orange); }
.globe__ring circle { fill: none; stroke: var(--line-2); stroke-dasharray: 2 6; }
@keyframes globe-orbit { to { transform: rotate(-360deg); } }
@media (prefers-reduced-motion: reduce) { .globe__ring { animation: none; } }
.globe__cities { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 28px; list-style: none; margin: 0; padding: 0; font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-2); }
.globe__cities li { display: inline-flex; align-items: center; gap: 8px; }
.globe__cities li::before { content: ""; width: 9px; height: 9px; background: var(--orange); }
.globe__cities time { color: var(--text); font-variant-numeric: tabular-nums; }
@media (max-width: 560px) { .globe__ring text { font-size: 19px; } }

/* --------------------------------------------------------------------------
   The kairos definition (home + about) as a 1990s desktop dictionary app
   (build.py kairos_entry()). It reuses the mail window's frame (.mail,
   .mail__bar), so the two read as windows on the same desktop; only the
   search row and the entry are its own.
   -------------------------------------------------------------------------- */
.dict { max-width: 1080px; }
.dict__find { display: flex; align-items: center; gap: 16px; padding: 16px 26px; border-bottom: 1.5px solid var(--ink); }
.dict__field {
  flex: 1; display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 0 12px;
  border: 1.5px solid var(--ink); border-radius: 18px; font-size: 16px;
}
/* a magnifying glass drawn in two strokes, like a 1-bit icon */
.dict__glass { position: relative; flex: none; width: 11px; height: 11px; border: 1.75px solid var(--ink); border-radius: 50%; margin: -3px 4px 0 0; }
.dict__glass::after { content: ""; position: absolute; width: 1.75px; height: 7px; background: var(--ink); left: 9px; top: 8px; rotate: -45deg; }
/* the looked-up word, selected in the field the way an old desktop highlights it */
.dict__field [data-type-word] { background: #CFDDE6; padding: 1px 3px; }
.dict__field [data-type-word]:empty { background: none; padding: 0; }
.dict__field [data-type-word]::after { content: ""; display: inline-block; width: .55em; height: 1.1em; margin-left: 1px; vertical-align: -.2em; background: var(--ink); animation: mail-caret 1s steps(1) infinite; }
.dict__count { font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase; color: #555; }
.dict__entry { padding: 26px 26px 28px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 22px 34px; align-items: start; }
.dict__text { min-width: 0; }
/* the entry's illustration: the animated clock-K on its own deep plate (assets/kairoclock.js) */
.dict__fig { margin: 0; display: grid; gap: 8px; justify-items: center; width: clamp(150px, 17vw, 210px); }
.dict__fig figcaption { display: grid; gap: 2px; text-align: center; font-size: 11.5px; color: #555; line-height: 1.35; }
.dict__fig [data-kclock-readout] { font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.dict__fig [data-kclock-readout].is-k { color: #C8470C; }
.dict__entry p { margin: 0; }
.dict__hw { display: flex; align-items: center; flex-wrap: wrap; gap: 0 12px; }
.dict__time { width: clamp(26px, 3vw, 38px); height: clamp(26px, 3vw, 38px); fill: #E2520F; flex: none; }
.dict__dot { color: #E2520F; }
.dict__senses li::marker { color: #2F5BD3; }
.dict__see b { color: #2F5BD3; }
.dict__hw b { font-family: var(--font-display); font-weight: 600; font-size: clamp(34px, 4.4vw, 58px); line-height: 1; letter-spacing: -.01em; }
.dict__pr { font-size: 17px; color: #555; }
.dict__pos { margin-top: 10px !important; font-size: 14.5px; color: #555; }
.dict__pos i { color: var(--ink); }
.dict__senses { margin: 18px 0 0; padding-left: 1.6em; font-family: var(--font-display); font-size: clamp(17px, 1.7vw, 21px); line-height: 1.5; max-width: 62ch; }
.dict__senses li::marker { font-family: var(--font-mono); font-weight: 600; font-size: .85em; }
.dict__see { margin-top: 18px !important; padding-top: 14px; border-top: 1px dotted var(--ink); font-size: 14px; color: #444; }
/* the entry shows once the word has been typed into the search field (mailbox.js) */
.dict.is-searching .dict__entry, .dict.is-searching .dict__count { opacity: 0; }
.dict__entry, .dict__count { transition: opacity 360ms ease-out; }
@media (max-width: 640px) {
  .dict__find { padding: 12px 16px; }
  .dict__count { display: none; }
  .dict__entry { padding: 20px 16px 22px; }
  .dict__pr { flex-basis: 100%; margin-top: 6px; }
  .dict__entry { grid-template-columns: 1fr; }
  .dict__fig { justify-self: start; width: 150px; }
}

/* --------------------------------------------------------------------------
   The clock-K's deep plate: the heat mark only reads on its own ground (#15162A),
   never on paper. Shared by the dictionary figure, Kairo time and the sent message.
   -------------------------------------------------------------------------- */
.kplate { width: 100%; aspect-ratio: 1; background: #15162A; display: grid; place-items: center; }
.kplate canvas { width: 86%; height: auto; aspect-ratio: 1; display: block; }
.kplate--sm { width: 72px; }

/* About, Kairo time: the mini section under the globe (build_about) */
.ktime__in { display: grid; justify-items: center; gap: 28px; }
.ktime__fig { margin: 0; width: min(100%, 380px); }
/* the one control in the section, so it is set loud: ember like the clock's arms, larger than a stock button */
.ktime .ktime__btn { background: #C8470C; border-color: #C8470C; color: #F6F4EF; padding: 14px 28px; font-size: 16px; box-shadow: 0 6px 18px rgba(200, 71, 12, .28); transition: transform .2s, box-shadow .2s, background .2s; }
.ktime .ktime__btn:hover { background: #A93A08; border-color: #A93A08; transform: translateY(-2px); box-shadow: 0 10px 24px rgba(200, 71, 12, .34); }
@media (prefers-reduced-motion: reduce) { /* the looked-up word, selected in the field the way an old desktop highlights it */
.dict__field [data-type-word] { background: #CFDDE6; padding: 1px 3px; }
.dict__field [data-type-word]:empty { background: none; padding: 0; }
.dict__field [data-type-word]::after { animation: none; } }

/* --------------------------------------------------------------------------
   About hero: the blueprint sheet. A poster section in Keycap Cobalt with
   paper-white line work, gridded at the brand's 40px cell (8px minor). The
   diagram is generated by blueprint_svg() in build.py; plates arrive stacked
   and come apart into the exploded view when the figure is revealed.
   -------------------------------------------------------------------------- */

.bp-hero {
  --bp: #2F5BD3; --bp-side: #4670DA; --bp-side-r: #3B66D6; --bp-ln: rgba(255, 255, 255, .92);
  --text: #FFFFFF; --text-2: rgba(255, 255, 255, .86); --text-3: rgba(255, 255, 255, .7); --green: #FFFFFF;
  --line-2: rgba(255, 255, 255, .45);
  position: relative; overflow: hidden; color: var(--text);
  padding-block: clamp(36px, 5vw, 64px) clamp(32px, 4vw, 52px);
  background-color: var(--bp);
  background-image: radial-gradient(ellipse 70% 60% at 62% 42%, rgba(255, 255, 255, .09), transparent 70%);
}
/* The sheet's textures, each on its own layer so each can fade on its own curve:
   the ghost crossword (gone well before the join), the grid lines (fading out), and
   a dot field on the grid's intersections (fading in). Below the join, the core-team
   section carries the same lines on (fading to nothing) over its own dots, which
   trail.js nudges onto the same 8px lattice: the grid dissolves into the dots. */
.bp-tex, .bp-grid, .bp-dots { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.bp-tex {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 calc(100% - 330px), rgba(0, 0, 0, .4) calc(100% - 220px), transparent calc(100% - 110px));
  mask-image: linear-gradient(#000 calc(100% - 330px), rgba(0, 0, 0, .4) calc(100% - 220px), transparent calc(100% - 110px));
}
.bp-grid, .bp-hero + .trail::after {
  background-image:
    linear-gradient(rgba(255, 255, 255, .2) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .2) 1px, transparent 1px),
    linear-gradient(rgba(255, 255, 255, .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .07) 1px, transparent 1px);
  background-size: 40px 40px, 40px 40px, 8px 8px, 8px 8px;
  background-position: center top;
}
.bp-grid {
  -webkit-mask-image: linear-gradient(#000 calc(100% - 300px), rgba(0, 0, 0, .78) calc(100% - 200px), rgba(0, 0, 0, .5) calc(100% - 100px), rgba(0, 0, 0, .32));
  mask-image: linear-gradient(#000 calc(100% - 300px), rgba(0, 0, 0, .78) calc(100% - 200px), rgba(0, 0, 0, .5) calc(100% - 100px), rgba(0, 0, 0, .32));
}
/* dots matched to .trail__dots by MEASURED contrast, not by copying its values: a CSS radial
   dot at the canvas's .5 alpha rendered about twice as dark, and left a band at the join */
.bp-dots {
  background-image: radial-gradient(circle, rgba(21, 25, 28, .27) .85px, transparent 1.3px);
  background-size: 8px 8px; background-position: calc(50% - 4px) -4px;
  -webkit-mask-image: linear-gradient(transparent calc(100% - 300px), rgba(0, 0, 0, .12) calc(100% - 200px), rgba(0, 0, 0, .38) calc(100% - 100px), rgba(0, 0, 0, .7));
  mask-image: linear-gradient(transparent calc(100% - 300px), rgba(0, 0, 0, .12) calc(100% - 200px), rgba(0, 0, 0, .38) calc(100% - 100px), rgba(0, 0, 0, .7));
}
/* below the join: the lines carry on, phased by trail.js (--bp-gy) to continue the sheet's */
.bp-hero + .trail::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-position: center var(--bp-gy, 0px);
  -webkit-mask-image: linear-gradient(rgba(0, 0, 0, .32), rgba(0, 0, 0, .14) 90px, transparent 200px);
  mask-image: linear-gradient(rgba(0, 0, 0, .32), rgba(0, 0, 0, .14) 90px, transparent 200px);
}
/* the ghost crossword behind the drawing: blacked squares and clue numbers on the 40px grid,
   centred like the grid so every square lands on its lines, faded off around the copy */
.bp-ghost {
  position: absolute; top: 0; left: 50%; margin-left: -1020px; pointer-events: none; max-width: none;
  -webkit-mask-image: radial-gradient(ellipse 21% 17% at 33% 17%, transparent 50%, #000 100%);
  mask-image: radial-gradient(ellipse 21% 17% at 33% 17%, transparent 50%, #000 100%);
}
.bp-ghost__b { fill: url(#bp-ghost-h); stroke: rgba(255, 255, 255, .22); stroke-width: 1; }
#bp-ghost-h line { stroke: rgba(255, 255, 255, .2); stroke-width: 1.4; }
.bp-ghost__n { fill: rgba(255, 255, 255, .24); font-family: var(--font-mono); font-size: 8px; }
.bp-hero > .wrap { z-index: 2; }
/* The fade into the core-team section. The two sections MEET at a mid blue,
   #7F9BDB (halfway between Keycap Cobalt and the team paper #CEDBE3), instead of the
   hero fading all the way to pale: that left a flat light strip at the join which read
   as a white flash. One smoothstep curve runs across both, split at its midpoint, so
   the colour changes at the same rate on either side of the boundary and there is no
   edge. The team side also brings its dot field in WITH the colour; its default top
   fade left a dot-free strip that looked like a gap. */
.bp-hero { padding-bottom: 200px; }
.bp-hero::after {
  content: ""; position: absolute; inset: auto 0 0; height: 220px; pointer-events: none; z-index: 0;
  background: linear-gradient(180deg, rgba(127, 155, 219, 0.000) 0%, rgba(127, 155, 219, 0.056) 20%, rgba(127, 155, 219, 0.208) 40%, rgba(127, 155, 219, 0.432) 60%, rgba(127, 155, 219, 0.704) 80%, rgba(127, 155, 219, 1.000) 100%);
}
.bp-hero + .trail::before {
  background: linear-gradient(180deg, color-mix(in srgb, #CEDBE3 0.0%, #7F9BDB) 0px, color-mix(in srgb, #CEDBE3 29.6%, #7F9BDB) 44px, color-mix(in srgb, #CEDBE3 56.8%, #7F9BDB) 88px, color-mix(in srgb, #CEDBE3 79.2%, #7F9BDB) 132px, color-mix(in srgb, #CEDBE3 94.4%, #7F9BDB) 176px, color-mix(in srgb, #CEDBE3 100.0%, #7F9BDB) 220px, #C2D2DD 50%, #CAD8E1);
  -webkit-mask-image: linear-gradient(#000 93%, transparent); mask-image: linear-gradient(#000 93%, transparent);
}
.bp-hero + .trail .trail__dots {
  -webkit-mask-image: linear-gradient(rgba(0, 0, 0, .7), #000 160px, #000 91%, transparent);
  mask-image: linear-gradient(rgba(0, 0, 0, .7), #000 160px, #000 91%, transparent);
}
.bp-hero ::selection { background: rgba(255, 255, 255, .3); }
.bp-hero .crumbs { margin-bottom: 26px; }
.bp-hero__grid { display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); gap: clamp(20px, 3vw, 44px); align-items: center; }
.bp-hero .display { margin-top: 20px; font-size: clamp(40px, 5.6vw, 74px); }
.bp-hero .lede { margin-top: 22px; color: var(--text-2); }
.bp-note {
  margin: 26px 0 0; max-width: 44ch; padding: 12px 14px; border: 1px dashed rgba(255, 255, 255, .55);
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.6; letter-spacing: .02em; color: var(--text-2);
}
.bp-hero__fig { margin: 0; min-width: 0; }
.bp-svg { width: 100%; height: auto; overflow: visible; }

/* line work: every stroke is screen-width, whatever the face matrix scales it by */
.bp-svg * { vector-effect: non-scaling-stroke; }
.bp-top { fill: var(--bp); stroke: var(--bp-ln); stroke-width: 1.4; stroke-linejoin: round; }
.bp-sl, .bp-sr { stroke: var(--bp-ln); stroke-width: 1.4; stroke-linejoin: round; }
.bp-sl { fill: var(--bp-side); }
.bp-sr { fill: var(--bp-side-r); }
.bp-face rect, .bp-face circle, .bp-face path, .bp-face polyline, .bp-face line { fill: none; stroke: var(--bp-ln); stroke-width: 1; }
.bp-face .bp-hatch { fill: url(#bp-hatch-p); stroke-width: .75; }
/* crossword paper under every plate's drawing, then the entries printed over it */
.bp-face .bp-paper-grid { stroke: rgba(255, 255, 255, .2); stroke-width: .7; }
.bp-face .bp-cell { fill: rgba(255, 255, 255, .05); stroke: rgba(255, 255, 255, .78); stroke-width: .75; }
.bp-face .bp-entry { stroke: #FFFFFF; stroke-width: 1.7; }
.bp-face .bp-mod { fill: var(--bp); }
.bp-face .bp-sheet { fill: #3864D8; stroke: #FFFFFF; stroke-width: 1.4; }
.bp-face .bp-fold { fill: rgba(255, 255, 255, .28); stroke-width: 1.1; }
.bp-face .bp-dimln { stroke: rgba(255, 255, 255, .7); stroke-width: .8; }
/* the shared 1 Down cell on every layer: printed solid, letter knocked out */
.bp-face .bp-hi { fill: #FFFFFF; stroke: #FFFFFF; }
.bp-face text.bp-xl--hi { fill: var(--bp); }
#bp-hatch-p line { stroke: rgba(255, 255, 255, .8); stroke-width: .8; }
.bp-face .bp-px, .bp-face .bp-node, .bp-face .bp-via { fill: #FFFFFF; stroke: none; }
.bp-face .bp-dot { fill: rgba(255, 255, 255, .55); stroke: none; }
.bp-face .bp-trace { stroke: rgba(255, 255, 255, .78); stroke-width: .9; }
.bp-face .bp-ring { stroke-dasharray: 2 3; }
.bp-face .bp-paper { fill: var(--bp); }
.bp-face text { fill: #FFFFFF; font-family: var(--font-mono); text-anchor: middle; }
.bp-xl { font-size: 5.7px; font-weight: 600; letter-spacing: 0; }
.bp-xn { font-size: 2.1px; opacity: .85; text-anchor: start !important; }
.bp-ml { font-size: 3.3px; font-weight: 500; letter-spacing: .08em; }
.bp-eng { font-size: 4.8px; font-weight: 600; letter-spacing: .12em; }
.bp-sh { font-size: 3.4px; font-weight: 600; letter-spacing: .14em; text-anchor: start !important; }

.bp-guide { stroke: rgba(255, 255, 255, .5); stroke-width: 1; stroke-dasharray: 3 5; }
.bp-drop { fill: none; stroke: #FFFFFF; stroke-width: 1.2; stroke-dasharray: 4 4; }
#bp-arrow path { fill: #FFFFFF; }
#bp-tick path { stroke: #FFFFFF; stroke-width: 1.4; }
.bp-lead { fill: none; stroke: rgba(255, 255, 255, .85); stroke-width: 1; }
.bp-pin { fill: var(--bp); stroke: #FFFFFF; stroke-width: 1.4; }
.bp-fine { stroke: rgba(255, 255, 255, .8); stroke-width: 1; }
.bp-box { fill: rgba(47, 91, 211, .82); stroke: #FFFFFF; stroke-width: 1.2; }
.bp-thumb .bp-top { stroke-width: 1; }
.bp-thumb .bp-sl, .bp-thumb .bp-sr { stroke-width: 1; }

.bp-svg text { fill: #FFFFFF; font-family: var(--font-mono); }
/* labels knock the ghost crossword out behind them, as lettering on a print does */
.bp-ct, .bp-cd, .bp-dim, .bp-fig { paint-order: stroke; stroke: var(--bp); stroke-width: 4px; stroke-linejoin: round; }
.bp-ct { font-size: 11px; font-weight: 600; letter-spacing: .1em; }
.bp-cn { font-weight: 400; opacity: .72; }
.bp-cd { font-size: 10px; letter-spacing: .02em; fill: rgba(255, 255, 255, .84) !important; }
.bp-st { font-size: 9px; letter-spacing: .02em; }
.bp-st--h { font-weight: 600; letter-spacing: .16em; font-size: 8.5px; fill: rgba(255, 255, 255, .78) !important; }
.bp-down { font-size: 9px; font-weight: 600; letter-spacing: .16em; }
.bp-dim { font-size: 8.5px; letter-spacing: .12em; text-anchor: middle; }
.bp-fig { font-size: 8.5px; letter-spacing: .14em; fill: rgba(255, 255, 255, .78) !important; }

/* assembly: each layer starts at its stacked height and drops out to the exploded view */
.bp-layer { transform: translateY(var(--dz)); }
.bp-late { opacity: 0; }
.bp-hero__fig.in .bp-layer { transform: none; transition: transform 1.5s var(--ease); transition-delay: calc(420ms + (4 - var(--i)) * 110ms); }
.bp-hero__fig.in .bp-late { opacity: 1; transition: opacity .9s ease 1.5s; }

/* the drawing's title block and signature line, as on an engineering print */
.bp-title {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr) minmax(0, 1.5fr);
  margin-top: clamp(22px, 3vw, 36px); border: 1px solid rgba(255, 255, 255, .85);
  font-family: var(--font-mono); font-size: 13px; letter-spacing: .03em;
}
.bp-title > * { padding: 12px 16px; min-width: 0; }
.bp-title > * + * { border-left: 1px solid rgba(255, 255, 255, .85); }
.bp-title__lead { display: grid; align-items: center; font-family: var(--font-display); font-size: 17px; letter-spacing: 0; }
.bp-title__stack { display: grid; padding: 0 !important; }
.bp-title__stack span { padding: 9px 16px; }
.bp-title__stack span + span { border-top: 1px solid rgba(255, 255, 255, .85); }
.bp-title__meta { display: grid; grid-template-columns: repeat(4, auto); gap: 4px 18px; margin: 0; align-content: center; }
.bp-title__meta dt { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); }
.bp-title__meta dd { margin: 2px 0 0; white-space: nowrap; }
.bp-sign {
  margin-top: clamp(22px, 3vw, 34px); padding: 14px 0 10px; text-align: right;
  border-top: 1.5px solid rgba(255, 255, 255, .9); border-bottom: 1.5px solid rgba(255, 255, 255, .9);
  box-shadow: 0 -6px 0 -5px rgba(255, 255, 255, .9) inset;
}
.bp-sign span { font-family: var(--font-display); font-style: italic; font-weight: 600; font-size: clamp(22px, 2.6vw, 32px); letter-spacing: .01em; }

@media (max-width: 920px) {
  .bp-hero__grid { grid-template-columns: 1fr; }
  .bp-title { grid-template-columns: 1fr 1fr; }
  .bp-title__meta { grid-column: 1 / -1; border-left: 0 !important; border-top: 1px solid rgba(255, 255, 255, .85); }
}
@media (max-width: 600px) {
  .bp-spec, .bp-fig { display: none; }
  .bp-svg .bp-ct { font-size: 15px; }
  .bp-svg .bp-cd { display: none; }
  .bp-ghost { -webkit-mask-image: none; mask-image: none; opacity: .6; }
  .bp-title { grid-template-columns: 1fr; }
  .bp-title > * + * { border-left: 0; border-top: 1px solid rgba(255, 255, 255, .85); }
  .bp-title__meta { grid-template-columns: repeat(2, auto); }
}
@media (prefers-reduced-motion: reduce) {
  .bp-layer { transform: none; }
  .bp-late { opacity: 1; }
  .bp-hero__fig.in .bp-layer, .bp-hero__fig.in .bp-late { transition: none; }
}

/* About: the team's blue paper runs down behind its buttons (the CTA sits inside the trail,
   build.py core_trail(cta)), then hands over to the world map below. Same recipe as the
   blueprint join: the colour MEETS at half strength on the boundary, one smoothstep split
   at its midpoint over --seam on each side, so it changes at the same rate on both sides.
   The textures cross-fade through it: the team's dots fade out while the map canvas, pulled
   up by --seam to start right under the buttons, fades in over them. */
.trail--cta, .trail--cta + .section--atlas { --seam: 130px; }
.trail--cta { padding-bottom: var(--seam); }
.trail--cta .trail__cta { margin-top: clamp(64px, 8vw, 112px); }
.bp-hero + .trail--cta::before {
  -webkit-mask-image: linear-gradient(#000 calc(100% - var(--seam)), rgba(0, 0, 0, .972) calc(100% - var(--seam) * .8), rgba(0, 0, 0, .896) calc(100% - var(--seam) * .6), rgba(0, 0, 0, .784) calc(100% - var(--seam) * .4), rgba(0, 0, 0, .648) calc(100% - var(--seam) * .2), rgba(0, 0, 0, .5));
  mask-image: linear-gradient(#000 calc(100% - var(--seam)), rgba(0, 0, 0, .972) calc(100% - var(--seam) * .8), rgba(0, 0, 0, .896) calc(100% - var(--seam) * .6), rgba(0, 0, 0, .784) calc(100% - var(--seam) * .4), rgba(0, 0, 0, .648) calc(100% - var(--seam) * .2), rgba(0, 0, 0, .5));
}
.bp-hero + .trail--cta .trail__dots {
  -webkit-mask-image: linear-gradient(rgba(0, 0, 0, .7), #000 160px, #000 calc(100% - var(--seam) - 40px), rgba(0, 0, 0, .5) calc(100% - var(--seam) * .5), transparent);
  mask-image: linear-gradient(rgba(0, 0, 0, .7), #000 160px, #000 calc(100% - var(--seam) - 40px), rgba(0, 0, 0, .5) calc(100% - var(--seam) * .5), transparent);
}
/* the blue's second half: #CAD8E1, the paper's last colour, from .5 to nothing */
.trail--cta + .section--atlas { padding-top: 48px; }
.trail--cta + .section--atlas::before {
  content: ""; position: absolute; inset: 0 0 auto; height: var(--seam); pointer-events: none;
  background: linear-gradient(180deg, rgba(202, 216, 225, .5), rgba(202, 216, 225, .352) 20%, rgba(202, 216, 225, .216) 40%, rgba(202, 216, 225, .104) 60%, rgba(202, 216, 225, .028) 80%, rgba(202, 216, 225, 0));
}
/* the map reaches up into the team section; only its sides are clipped */
.trail--cta + .section--atlas { overflow: clip visible; }
.trail--cta + .section--atlas .atlas__cv { top: calc(-1 * var(--seam)); height: calc(100% + var(--seam)); }
