/* Case-study pages (/calsans/ is the first). Colour, corners, motion and the theme
   switch come from shared/ (wm-primitives), as on the homepage; this file is layout and
   type. One face, Cal Sans v2, and every demo on the page is live text in it. */

@font-face {
  font-family: 'CalSans';
  src: url('../shared/fonts/CalSansVF.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  /* v2: opsz 8–45 (14) | GEOM 0–100 (25) | wght 400–700 | YTAS 1440–1600 | SHRP 0–100 | ital 0–1 */
}
/* Cal Sans Flex, from wm-primitives: true HOI — the geometric alternates blend along GEOM on curved
   paths, carried by three hidden helper axes avar2 drives from GEOM. For the Futura demo and the cube. */
@font-face {
  font-family: 'CalSansFlex';
  src: url('../shared/fonts/CalSansFlexVF.woff2?v=2010hoi') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
/* the 2021 release, for the master it was in the 2022 estimate */
@font-face {
  font-family: 'CalSans1';
  src: url('../shared/fonts/CalSans-Bold.woff2') format('woff2');
  font-weight: 600;
  font-display: swap;
}
/* the two faces the 2025 homepage mixed with Cal Sans, for the first highlight. Inter ships (OFL);
   Matter is Cal.com's licence, not this site's, so fonts/Matter.woff2 is a local, gitignored drop-in and
   the live page falls back to the system face until one is there. */
@font-face { font-family: 'Inter'; src: url('../fonts/InterVariable.woff2') format('woff2'); font-weight: 100 900; font-display: swap; }
@font-face { font-family: 'Matter'; src: url('../fonts/Matter.woff2') format('woff2'); font-weight: 100 900; font-display: swap; }
/* the 2021 release, as Google Fonts ships it, for the versions card's first stop */
@font-face { font-family: 'CalSans1'; src: url('../fonts/CalSans-1.000.woff2') format('woff2'); font-weight: 400 700; font-display: swap; }

/* the 2025 release, for its own title in the releases row: wght + GEOM only */
@font-face {
  font-family: 'CalSansUI';
  src: url('../fonts/CalSansUI-VariableFont 1.62 [wght,GEOM].woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
:where(*:not(.wm-chip, .wm-hd-pill)), *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }   /* the chip and the dial's lozenge keep their primitives' padding: an unlayered reset beats a layer. :where() holds it at zero specificity: bare, the :not() counted as a class and zeroed every single-class padding loaded before it (the UI kit's cards, fields and buttons, 2026-10-04) */
.wm-chip, .wm-hd-pill { box-sizing: border-box; margin: 0; }

/* Axes ride custom properties so a parent can move one without restating the rest.
   opsz is left out on purpose: font-optical-sizing:auto supplies it from the size. */
* {
  font-variation-settings: 'wght' var(--wght, 400), 'GEOM' var(--geom, 25), 'SHRP' var(--shrp, 0), 'ital' var(--ital, 0);
}

:root {
  --r: 10px;
  --r-card: 20px;
  --gut: var(--grid-margin);   /* the house margin (shared/src/grid.css), which is this page's own */
  --sec: round(nearest, clamp(72px, 12vw, 168px), 24px);   /* whole body lines */
  --nav-h: 57px;   /* 19 units, so everything under the sticky nav starts on a line */
  --ui-font: 'CalSans', sans-serif;   /* the chrome face for every primitive (dials, chips, switches): never the platform's */
  --ui-fvs: 'opsz' 10, 'GEOM' 25;
  --text-rgb: 232, 232, 232;
  --signal: #eeff41;
  --signal: color(display-p3 0.9333 1 0.2549);
}
/* color-scheme follows the page's theme, not the OS: the browser's own parts (scrollbars, form controls)
   were drawn light-scheme in the dark theme -- a black bar on the statics sheet, or a white track */
:root { color-scheme: dark; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) { --text-rgb: 22, 22, 22; --bg: #f5faff; --signal: #5c6b00; color-scheme: light; }
}
:root[data-theme="dark"]  { --text-rgb: 232, 232, 232; color-scheme: dark; }
:root[data-theme="light"] { --text-rgb: 22, 22, 22; --bg: #f5faff; --signal: #5c6b00; color-scheme: light; }

html { scroll-behavior: smooth; overflow-x: clip; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--text);
  font-family: 'CalSans', -apple-system, sans-serif;
  font-size: 16px;
  --lh: 24px; line-height: var(--lh);   /* 16/24: eight 3px units -- was 1.55, which no unit divides */
  font-optical-sizing: auto;
  font-synthesis: none;
  font-feature-settings: 'liga' 0, 'dlig' 0, 'calt' 0;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  transition: background 0.25s, color 0.25s;
}

h1, h2, h3, strong, b { font-weight: inherit; }
em, cite { font-style: normal; --ital: 1; }
a { color: inherit; }
button:not(.wm-chip) { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }   /* the chip draws its own box (shared/src/chip.css, layered) */
section[id] { scroll-margin-top: var(--nav-h); }

.wrap { padding-inline: var(--gut); }

/* label role: short caps are Geo's job, and caps are the only thing that gets tracked */
.label {
  --geom: 100; --wght: 600;
  font-size: 12px;
  --lh: round(nearest, 1.3em, var(--bl)); line-height: var(--lh);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ═══ NAV ═══════════════════════════════════════════════ */
.cs-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-inline: var(--gut);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}
.cs-home {
  --wght: 700; --geom: 100;
  font-size: 15px;
  letter-spacing: 0.1em;
  text-decoration: none;
}
.cs-links { display: none; gap: clamp(16px, 2.4vw, 32px); }
.cs-links a {
  font-size: 13px;
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.12s;
}
.cs-links a:hover { color: var(--text); }
.cs-nav-end { display: flex; align-items: center; gap: 12px; }
#theme-toggle { opacity: 0.6; transition: opacity 0.15s; }
#theme-toggle:hover { opacity: 1; }
.cs-nav .pill { display: none; }
@media (min-width: 861px) {
  .cs-links { display: flex; }
  .cs-nav .pill { display: inline-flex; }
}

/* ═══ PILLS ═════════════════════════════════════════════ */
.pill {
  --wght: 700; --geom: 50;
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  font-size: 14px;
  --lh: round(nearest, 1.1em, var(--bl)); line-height: var(--lh);
  color: var(--bg);
  background: var(--text);
  /* a lozenge in the flow is a line of type: its HEIGHT is in units (2.2em, rounded) and the
     label is centred in it, so nothing below a row of pills is knocked off the grid */
  height: round(nearest, 2.2em, var(--bl));
  padding: 0 0.95em;
  border-radius: 999px;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity 0.15s;
}
.pill:hover { opacity: 0.78; }
.pill--lg { font-size: clamp(20px, 2.4vw, 30px); height: round(nearest, 1.9em, var(--bl)); padding: 0 0.7em; }
.pill--ghost { color: var(--text); background: transparent; box-shadow: inset 0 0 0 1.5px var(--text); }
.pill .arrow { position: relative; top: 0.06em; }

/* ═══ HERO ══════════════════════════════════════════════ */
.cs-hero { padding-top: round(nearest, clamp(48px, 9vw, 120px), var(--bl)); }
.cs-hero h1 {
  --wght: 640; --geom: 50;
  font-size: clamp(44px, 9.4vw, 148px);
  --lh: round(nearest, 0.98em, var(--bl)); line-height: var(--lh);
  text-wrap: balance;
  margin-top: round(nearest, clamp(16px, 2vw, 28px), var(--bl));
}
/* "Cal Sans" leads the h1 for search, on its own line in the mid-gray token */
.cs-hero h1 .h1-pre { display: block; color: var(--text-muted); }
.hero-cols {
  display: grid;
  gap: 21px;
  margin-top: round(nearest, clamp(28px, 4vw, 56px), var(--bl));
}
.hero-lede {
  font-size: clamp(20px, 2.3vw, 30px);
  --lh: round(nearest, 1.28em, var(--bl)); line-height: var(--lh);
  text-wrap: pretty;
}
.hero-sub {
  font-size: 16px;
  --lh: round(nearest, 1.6em, var(--bl)); line-height: var(--lh);
  color: var(--text-muted);
  max-width: 44ch;
  text-wrap: pretty;
}
.byline { margin-top: 21px; font-size: 13px; color: var(--text-dim); }
@media (min-width: 861px) {
  .hero-cols { grid-template-columns: 7fr 5fr; gap: round(nearest, clamp(32px, 5vw, 80px), var(--bl)); align-items: start; }
  .hero-sub { padding-top: round(nearest, 0.5em, var(--bl)); }
}

/* the hero moment: the Calendso logo heats, four passes of a thermal stripe, the second one
   swaps in Cal.com, the word cools and the effect drains to the plain logo. One SVG filter chain. */
.hero-word-box { margin-top: round(nearest, clamp(40px, 7vw, 96px), var(--bl)); cursor: pointer; }
.hero-thermal { display: block; width: 100%; height: auto; overflow: visible; }
.hero-video { display: none; width: 100%; height: auto; }
/* thermal-hero.js flips to the video on coarse pointers once it knows a source will play */
.hero-word-box.is-video .hero-thermal { display: none; }
.hero-word-box.is-video .hero-video { display: block; }

/* ═══ SECTIONS ══════════════════════════════════════════ */
.sec { padding-top: var(--sec); }
.sec-title {
  --wght: 640; --geom: 50;
  font-size: clamp(30px, 4.6vw, 64px);
  --lh: round(nearest, 1.04em, var(--bl)); line-height: var(--lh);
  text-wrap: balance;
  margin-bottom: round(nearest, clamp(28px, 4vw, 56px), var(--bl));
}

.card {
  background: var(--surface);
  border-radius: var(--r-card);
  padding: round(nearest, clamp(22px, 3vw, 40px), var(--bl));
  min-width: 0;
}

/* ═══ HIGHLIGHTS ════════════════════════════════════════ */
/* ═══ HIGHLIGHTS: four cards, each an animation (js/highlights.js) ══════════════════════
   A card is a stage over a caption. The stage holds an inline SVG (the sentence, the rings) or
   the dials or the count; it is data-nosnap, so the grid snapper leaves its insides alone and
   only the caption below sits on the line. */
.hl-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-bottom: round(nearest, clamp(28px, 4vw, 56px), var(--bl)); }
.hl-head .sec-title { margin-bottom: 0; }
.hl-mode { margin-bottom: 6px; }
.hl-grid { display: grid; gap: 15px; }
.hl {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: round(nearest, clamp(28px, 4vw, 56px), var(--bl));
  position: relative;
}
.hl-stage { position: relative; min-height: 120px; }
.hl-stage svg { display: block; width: 100%; height: auto; overflow: visible; }
/* the Safari fog (js/hl-materialize.js thermalLite): each word's fog its own composited box, so the blur runs on the GPU */
.hl-stage .hm-lite { position: absolute; pointer-events: none; }
.hl-stage .hm-lite .hm-defs { position: absolute; width: 0; height: 0; }
.hl-stage .hm-word, .hl-stage .hm-layer { position: absolute; inset: 0; }
.hl-stage svg.hm-fog { position: absolute; width: auto; height: auto; overflow: visible; will-change: filter, opacity; transform: translateZ(0); }
/* Replay, bottom right of every highlight card: the cube's control, the house restart icon and the word */
.hl > .hl-text { position: relative; padding-inline-end: 96px; }   /* the caption keeps clear of it */
/* lives inside .hl-text and sits on the caption's last line: same size and line as .hl-cap, bottom of the
   caption, right of the card's content. .hl .hl-replay outranks the page's button:not(.wm-chip) reset, which otherwise paints it --text */
.hl .hl-replay { position: absolute; right: 0; bottom: 0; display: flex; align-items: center; gap: 6px; font-size: 14px; --lh: 21px; line-height: var(--lh); color: var(--text-muted); cursor: pointer; transition: color 0.15s; }
.hl .hl-replay:hover { color: var(--text); }
.hl .hl-replay:focus-visible { outline: 1.5px solid var(--signal); outline-offset: 3px; border-radius: 6px; }
/* the icon white, the word gray; the ring's centre (12,13 on the 24 grid) sits on the word's cap middle,
   and the spin turns about that centre, so the ring stays put and only the arrowhead travels */
.hl .hl-replay .wm-icon { color: var(--text); translate: 0 -1px; transform-origin: 50% 54.1667%; }
.hl .hl-replay.is-spun .wm-icon { animation: hl-replay-spin 0.6s cubic-bezier(0.3, 0, 0.2, 1); }
@keyframes hl-replay-spin { to { rotate: -360deg; } }
.hl-stage--rings svg { padding-top: 6px; }
.hl-text {
  --wght: 500;
  font-size: clamp(19px, 1.9vw, 26px);
  --lh: round(nearest, 1.25em, var(--bl)); line-height: var(--lh);
  color: var(--text-muted);
  max-width: none;
  text-wrap: pretty;
}
.hl-text strong { color: var(--text); }
.hl-say { display: block; --wght: 600; color: var(--text); font-size: clamp(19px, 1.9vw, 26px); --lh: round(nearest, 1.25em, var(--bl)); line-height: var(--lh); text-wrap: balance; }
.hl-cap { display: block; font-size: 14px; --lh: 21px; line-height: var(--lh); color: var(--text-muted); margin-top: 6px; max-width: 34ch; text-wrap: pretty; }

/* 3 · the axes: the word, the stamp, six vertical dials that come in from below their rail */
.axes-sample {
  font-size: clamp(56px, 9vw, 132px);
  --lh: round(nearest, 1.05em, var(--bl)); line-height: var(--lh);
  white-space: nowrap;
  overflow-x: clip;
  overflow-y: visible;
  font-variation-settings: 'opsz' 45, 'GEOM' 50, 'wght' 600, 'YTAS' 1440, 'SHRP' 0, 'ital' 0;
}
/* the release, as a timeline over the word: Cal Sans fixed left, the year fixed right, the version a pill
   that zips along the hairline (fast in, fast out) to where its year falls */
.ax-ver { display: flex; align-items: center; gap: 12px; height: 21px; margin-bottom: 12px; font-size: 12px; --lh: 21px; line-height: var(--lh); color: var(--text-muted); font-feature-settings: 'tnum' 1; }
.ax-ver-name, .ax-ver-year { flex: none; --wght: 600; color: var(--text); }
.ax-ver-year { letter-spacing: 0.04em; }
.ax-ver-track { position: relative; flex: 1 1 auto; height: 21px; }
.ax-ver-track > i { position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--border); }
.ax-ver-pill {
  position: absolute; top: 50%; left: calc(var(--p) * 100%); transform: translate(calc(var(--p) * -100%), -50%);
  display: inline-flex; align-items: center; height: 18px; padding: 0 9px; border-radius: 999px;
  background: var(--text); color: var(--bg); font-size: 11px; --lh: 18px; line-height: var(--lh); --wght: 600; white-space: nowrap;
  box-shadow: 0 0 0 3px var(--surface);
  transition: left 240ms cubic-bezier(0.85, 0, 0.15, 1), transform 240ms cubic-bezier(0.85, 0, 0.15, 1);
}
@media (prefers-reduced-motion: reduce) { .ax-ver-pill { transition: none; } }
/* the three releases on the word: Cal Sans 1 (static), UI 1.6 (wght, GEOM), Cal Sans 2 */
.axes-sample[data-face="v1"] { font-family: 'CalSans1', 'CalSans', sans-serif; }
.axes-sample[data-face="ui"] { font-family: 'CalSansUI', 'CalSans', sans-serif; }
.axes { display: flex; justify-content: space-between; gap: var(--grid-gutter); margin-top: 24px; --hd-rail: 96px; }
.axes .wm-hd { flex: 1 1 0; min-width: 0; gap: 6px; }   /* 12 + 6 + 96 = 114, 38 units */
.axes .wm-hd-rail { width: 100%; }
.axes .wm-hd-name { line-height: 12px; }
.axes .wm-hd-pill { box-shadow: 0 0 0 3px var(--surface); }
@media (max-width: 599px) { .axes { gap: 6px; } }
/* phones: six 43px columns. The lozenge's text is 16px so Safari does not zoom on focus (dialHandle.css), which made
   it 45-66px wide and the column's entry mask cut its ends. Drawn at 0.72 (11.5px visual) on 8px sides it is <= 42px.
   The scale sits inside the transform after the centring translate, so the pill stays centred on its rail. */
@media (max-width: 599px) {
  .axes .wm-hd-pill { padding-inline: 8px; transform: translate(-50%, -50%) scale(0.72); }
  .axes .wm-hd-pill input { font-size: 16px; }
}
/* a dial arrives wiped in from the foot of its rail (--enter 0..1, from the script) */
.axes .ax-in { --e: calc(var(--enter, 1) * 114%); mask-image: linear-gradient(to top, #000 calc(var(--e) - 14%), transparent var(--e)); -webkit-mask-image: linear-gradient(to top, #000 calc(var(--e) - 14%), transparent var(--e)); }   /* at --enter 0 the whole dial is hidden, pill included; at 1 the mask has left the box */
.axes-wrap.is-live .ax-reset { opacity: 0; pointer-events: none; }   /* nothing to reset while an axis drifts */

/* 4 · the census: two tabular figures, and beneath them the reel of the outside posts */
.hl-stage--count { min-height: 210px; display: flex; flex-direction: column; justify-content: flex-end; }
.hl-stage--count .hl-fig { z-index: 3;   /* above the reel's edge fades (z 2), which otherwise paint over the first numeral */ text-shadow: 0 27px 54px rgba(0, 0, 0, var(--fig-shade, 0.55)); }   /* the figures float over the reel on a big soft shade */
.hl-stage--count .hl-fig--two { gap: 6px 0.4em; }
.hl-stage--count .hl-fig { pointer-events: none; -webkit-user-select: none; user-select: none; }   /* the figures and icons only float: the posts under them still hover and click, and nothing selects */
.hl-figb { display: flex; flex-direction: column; }
.hl-figb .hl-icon { margin-bottom: 3px; filter: drop-shadow(0 27px 54px rgba(0, 0, 0, var(--fig-shade, 0.55))); }   /* a few pixels above its figure, on the same shade */
/* the two figures always share a line: "1.4M 12.6K" plus its gap is 5.39em, so the size caps at 18% of the stage
   (at 390 the stage is 290 and 64px wrapped 12.6K under 1.4M); the marks shrink with them, never past 72 */
.hl-stage--count { container-type: inline-size; }
.hl-stage--count .hl-fig { font-size: min(var(--hl-size, clamp(64px, 8vw, 112px)), 18cqi); }
.hl-figb .hl-icon { font-size: min(72px, 1.125em); width: 1em; height: 1em; }
:root[data-theme="light"] .hl-stage--count .hl-fig { --fig-shade: 0.16; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .hl-stage--count .hl-fig { --fig-shade: 0.16; } }
/* the reel fills the stage behind the figures: five rows of tiles in date order, the full-height
   ones carrying the post itself; two copies end to end, the track drifting right (js sets the duration) */
.hl-reel { position: absolute; inset: 0; overflow: clip; }   /* the stage's backdrop: behind the mark and the figures */
.hl-reel::before, .hl-reel::after { content: ''; position: absolute; top: 0; bottom: 0; width: 36px; z-index: 2; pointer-events: none; }
.hl-reel::before { left: 0; background: linear-gradient(to right, var(--surface), transparent); }
.hl-reel::after { right: 0; background: linear-gradient(to left, var(--surface), transparent); }
.hl-tiles { position: absolute; left: 0; top: 0; height: 100%; display: grid; grid-auto-flow: column; grid-template-rows: repeat(5, 1fr); grid-auto-columns: max-content; gap: 3px; width: max-content; animation: hl-reel var(--reel-t, 240s) linear infinite; will-change: transform; }
.hl-reel:hover .hl-tiles, .hl-reel:focus-within .hl-tiles { animation-play-state: paused; }
@keyframes hl-reel { from { transform: translateX(-50%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .hl-tiles { animation: none; } }
/* the census develops in place, a fade along the sweep; nothing scales or flies */
.hl-tiles > * { display: block; border-radius: 3px; background: var(--surface-hi); color: var(--text); opacity: 0; transition: opacity 700ms ease-out; text-decoration: none; overflow: hidden; }
.hl-tiles > .on { opacity: 0.5; }
.hl-tiles > a.on:hover, .hl-tiles > a.on:focus-visible { opacity: 1; outline: none; }
/* the teeny cards, five rows of them: the handle and the post's own text at 5px, real words too small to read */
.hl-tiles > a:not(.big):not(.has-img) { width: 66px; box-sizing: border-box; padding: 3px 4px; font-size: 5px; --lh: 6px; line-height: var(--lh); }   /* token-lint: allow -- miniature, a texture of real posts */
.hl-tiles > a:not(.big) b { display: block; --wght: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hl-tiles > a:not(.big) p { margin: 0; color: var(--text-muted); white-space: pre-line; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.hl-tiles > .has-img { background-size: cover; background-position: center; }
.hl-tiles > .has-img:not(.big) { width: 66px; }
.hl-tiles > .has-img.on { opacity: 0.4; }
.hl-tiles > a.has-img.on:hover, .hl-tiles > a.has-img.on:focus-visible { opacity: 1; }
/* the full-height tiles: the post as a small card -- handle, date, text, and its picture across the top */
.hl-tiles > .big { grid-row: 1 / -1; width: 228px; box-sizing: border-box; padding: 9px 12px; border-radius: var(--r); background: var(--surface-hi); color: var(--text); font-size: 12px; --lh: 15px; line-height: var(--lh); overflow: hidden; display: flex; flex-direction: column; }
.hl-tiles > .big.on, .hl-tiles > .big.has-img.on { opacity: 0.85; }
.hl-tiles > .big.on:hover, .hl-tiles > .big.has-img.on:hover { opacity: 1; }
.hl-tiles > .big img { display: block; flex: none; width: calc(100% + 24px); margin: -9px -12px 6px; height: 40%; object-fit: cover; object-position: top; }
.hl-tiles > .big b { --wght: 600; }
.hl-tiles > .big time { float: right; color: var(--text-dim); font-feature-settings: 'tnum' 1; }
.hl-tiles > .big p { margin: 3px 0 0; color: var(--text-muted); white-space: pre-line; flex: 1 1 auto; min-height: 0; overflow: hidden; }   /* the whole post, no clamp */
.hl-tiles > .big span { display: block; flex: none; margin-top: auto; padding-top: 3px; color: var(--text-dim); font-feature-settings: 'tnum' 1; }
/* one small tile at a time, under the pointer: handle, date, the text, its numbers */
.hl-pop { position: absolute; left: 0; top: 0; z-index: 4; width: min(300px, 100%); padding: 12px 15px; border-radius: var(--r); background: var(--surface-hi); color: var(--text); font-size: 13px; --lh: 18px; line-height: var(--lh); pointer-events: none; box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35); }
.hl-pop[hidden] { display: none; }
.hl-pop img { display: block; width: 100%; height: auto; max-height: 150px; object-fit: cover; border-radius: 6px; margin-bottom: 9px; }
.hl-pop b { --wght: 600; }
.hl-pop time { float: right; color: var(--text-dim); font-feature-settings: 'tnum' 1; }
.hl-pop p { margin: 6px 0 0; color: var(--text-muted); white-space: pre-line; display: -webkit-box; -webkit-line-clamp: 8; -webkit-box-orient: vertical; overflow: hidden; }
.hl-pop span { display: block; margin-top: 6px; color: var(--text-dim); font-feature-settings: 'tnum' 1; }
.hl-icon {
  position: relative; display: block; width: 72px; height: 72px; margin: 0;
  font-family: 'Material Symbols Outlined'; font-size: 72px; line-height: 1;   /* token-lint: allow -- a mark drawn at 72, not a text role */
  font-variation-settings: 'FILL' 0, 'wght' 100, 'GRAD' 0, 'opsz' 48;
  color: var(--text); overflow: hidden; white-space: nowrap; letter-spacing: normal; text-transform: none; font-feature-settings: 'liga';
}
.hl-fig {
  position: relative;
  margin: 0;
  --wght: 640; --geom: 50;
  font-size: var(--hl-size, clamp(64px, 8vw, 112px));
  --lh: round(nearest, 1em, var(--bl)); line-height: var(--lh);
  font-feature-settings: 'tnum' 1;
  color: var(--text);
}
.hl-fig--two { display: flex; flex-wrap: wrap; gap: 0 0.4em; }
.hl-fig--two b { --wght: 640; }
.hl-fig--two > :last-child b { color: var(--text-muted); }   /* the second figure a step down */

/* the slideshow: one card at a time, a bar of dots and a play button below */
.hl-grid.is-show { display: block; }
.hl-grid.is-show > .hl { display: none; }
.hl-grid.is-show > .hl.is-current { display: flex; min-height: max(60vh, calc(100svh - var(--nav-h) - 72px)); }   /* a slide is the screen, less the nav and the bar */
/* inside a slide every stage takes the spare height: the sentence and the rings scale up to it, the dials' rails
   grow into it, the census reel fills it */
.hl-grid.is-show > .hl.is-current .hl-stage { flex: 1 1 auto; min-height: 0; }
.hl-grid.is-show .hl-stage--sentence, .hl-grid.is-show .hl-stage--rings { display: flex; flex-direction: column; justify-content: center; }
.hl-grid.is-show .hl-stage--sentence svg, .hl-grid.is-show .hl-stage--rings svg { flex: 1 1 auto; min-height: 0; height: 100%; max-height: 64svh; }
.hl-bar { display: none; align-items: center; justify-content: center; gap: 12px; margin-top: 15px; }
.is-show .hl-bar { display: flex; }
/* the bar's buttons, scoped to the bar: the page's unlayered `button` reset would otherwise blank their fills */
.hl-bar .hl-play { display: inline-flex; align-items: center; justify-content: center; height: 36px; border-radius: 999px; background: var(--surface); color: var(--text); }
.hl-play { width: 36px; }
.hl-bar .hl-arrow { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 999px; background: var(--surface); color: var(--text); }
.hl-bar .hl-arrow:hover { background: var(--surface-hi); }
.hl-arrow:focus-visible { outline: 1.5px solid var(--signal); outline-offset: 3px; }
.hl-arrow-sys { font-family: -apple-system, BlinkMacSystemFont, system-ui, sans-serif; font-size: 18px; --lh: 18px; line-height: var(--lh); }   /* until the icon face spells the chevrons */
.hl-dots { display: flex; align-items: center; gap: 0; height: 36px; padding: 0 9px; border-radius: 999px; background: var(--surface); }
/* a dot is a period you can click: a 24px target around a 6px mark; the current one stretches to a dash */
.hl-bar .hl-dot { position: relative; display: inline-block; width: 18px; height: 24px; padding: 0; border-radius: 999px; background: none; cursor: pointer; transition: width 300ms ease; }
.hl-bar .hl-dot::after { content: ''; position: absolute; left: 50%; top: 50%; width: 6px; height: 6px; transform: translate(-50%, -50%); border-radius: 999px; background: var(--text-dim); transition: width 300ms ease, background 300ms ease; }
.hl-bar .hl-dot:hover::after { background: var(--text-muted); }
.hl-bar .hl-dot.on { width: 36px; }
.hl-bar .hl-dot.on::after { width: 30px; background: var(--text); }
.hl-play:focus-visible, .hl-dot:focus-visible { outline: 1.5px solid var(--signal); outline-offset: 3px; }

/* the three places to get the font, under the close */
/* every range on the page (the tester, the UI kit's GEOM): a 2px track in --border, a 14px ink thumb, the signal on hover */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 21px;
  background: transparent;
  cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track { height: 2px; background: var(--border); border-radius: 1px; }
input[type="range"]::-moz-range-track { height: 2px; background: var(--border); border-radius: 1px; }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px; height: 14px;
  margin-top: -6px;
  border-radius: 50%;
  background: var(--text);
  transition: background 0.12s, transform 0.12s;
}
input[type="range"]::-moz-range-thumb { width: 14px; height: 14px; border: 0; border-radius: 50%; background: var(--text); }
input[type="range"]:hover::-webkit-slider-thumb,
input[type="range"]:active::-webkit-slider-thumb { background: var(--signal); transform: scale(1.15); }
input[type="range"]:hover::-moz-range-thumb { background: var(--signal); }
input[type="range"]:focus-visible { outline: 1.5px solid var(--signal); outline-offset: 4px; border-radius: 4px; }

.get-list { display: grid; gap: 9px; }
.get-list--close { margin-top: 24px; max-width: 520px; }
.code {
  --geom: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  font-size: 14px;
  font-feature-settings: 'tnum' 1, 'zero' 1;
  padding: 12px 16px;
  border-radius: var(--r);
  background: var(--surface-hi);
  text-decoration: none;
  overflow: hidden;
  white-space: nowrap;
}
.code span:first-child { overflow: hidden; text-overflow: ellipsis; }
.code .where { color: var(--text-dim); flex: none; }
a.code:hover .where { color: var(--signal); }

@media (min-width: 861px) {
  .hl-grid { grid-template-columns: 5fr 7fr; }
  .hl--wide { grid-column: 1 / -1; flex-direction: row; align-items: center; }
  .hl--wide > * { flex: 1; }
}

/* the bento's three sizes, each a role: the SCREAMER (the bold lead, two to five words --
   the cell's one line), the FIGURE (a big numeral, or a list of names at half) and the
   CAPTION (the rest of the sentence, UI size, muted). One of the first two per cell, never
   two ideas at one size -- which is what makes a bento read as messy. */
.hl-say { display: block; --wght: 600; color: var(--text); font-size: clamp(19px, 1.9vw, 26px); --lh: round(nearest, 1.25em, var(--bl)); line-height: var(--lh); text-wrap: balance; }
.hl-cap { display: block; font-size: 14px; --lh: 21px; line-height: var(--lh); color: var(--text-muted); margin-top: 6px; max-width: 34ch; text-wrap: pretty; }
.hl-text { max-width: none; }   /* its two spans set their own size and line; the p holds nothing itself */
/* a figure card stacks mark, figure, text: the first two together at the top, the text at
   the bottom -- the card's space-between would spread all three evenly */

/* the thin marks: the Material face at weight 100, its 48 drawing, drawn big -- a sleek
   line where Apple's bento has a photograph */
/* the figure cards: one number (or three names, two of them struck) set in the face at the
   size the Cal.com word was fitted to, so every big thing in the section is one size */
.hl-fig {
  margin: 0;
  font-size: var(--hl-size, clamp(64px, 8vw, 112px));
  --lh: round(nearest, 1.05em, var(--bl)); line-height: var(--lh);
  white-space: nowrap;
  color: var(--text);
  font-variation-settings: 'opsz' 45, 'GEOM' 50, 'wght' 600;
  font-feature-settings: 'tnum' 1;
}

/* ═══ CLOSER LOOK ═══════════════════════════════════════
   Phone: six stacked features, each with its demo. Desktop: the titles become tabs on
   the left and the demos share one pinned stage on the right. */
.look { display: grid; gap: round(nearest, clamp(40px, 8vw, 64px), var(--bl)); }
.look-item { display: grid; gap: 18px; }
.look-tab {
  --wght: 640; --geom: 50;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  font-size: clamp(22px, 2.4vw, 32px);
  --lh: round(nearest, 1.12em, var(--bl)); line-height: var(--lh);
  cursor: default;
}
.look-dot {
  flex: none;
  width: 11px; height: 11px;
  border-radius: 50%;
  corner-shape: round;
  background: var(--text);
}
.look-body p {
  color: var(--text-muted);
  max-width: 40ch;
  padding-left: 23px;
  text-wrap: pretty;
}
.look-demo {
  --pad: clamp(22px, 3.4vw, 48px);
  background: var(--surface);
  border-radius: var(--r-card);
  padding: round(nearest, var(--pad), var(--bl));
  min-height: 260px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 27px;
  min-width: 0;
  overflow: hidden;
}
.demo-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 15px;
  font-size: 12px;
  color: var(--text-dim);
}

@media (min-width: 961px) {
  .look {
    grid-template-columns: 5fr 7fr;
    grid-template-rows: repeat(6, auto) 1fr;
    column-gap: clamp(32px, 5vw, 80px);
    row-gap: 0;
  }
  .look-item { display: contents; }
  .look-head { grid-column: 1; border-top: 1px solid var(--border); padding-block: 18px; }
  .look-item:last-child .look-head { border-bottom: 1px solid var(--border); }
  .look-tab { cursor: pointer; color: var(--text-dim); transition: color var(--dur-med, 240ms); }
  .look-tab:hover { color: var(--text-muted); }
  .look-tab:focus-visible { outline: 1.5px solid var(--signal); outline-offset: 4px; border-radius: 4px; }
  .look-dot { background: currentColor; transition: background var(--dur-med, 240ms); }
  .look-body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--dur-layout, 300ms) ease;
  }
  .look-body p { overflow: hidden; min-height: 0; }
  .look-item.is-active .look-tab { color: var(--text); }
  .look-item.is-active .look-dot { background: var(--signal); animation: shape-cycle 5s linear infinite; }
  .look-item.is-active .look-body { grid-template-rows: 1fr; }
  .look-item.is-active .look-body p { padding-top: 9px; }
  .look-demo {
    grid-column: 2;
    grid-row: 1 / -1;
    position: sticky;
    top: calc(var(--nav-h) + 24px);
    align-self: start;
    height: min(620px, calc(100vh - var(--nav-h) - 80px));
    min-height: 440px;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-slow, 400ms) ease, visibility 0s var(--dur-slow, 400ms);
  }
  .look-item.is-active .look-demo { opacity: 1; visibility: visible; transition-delay: 0s; }
}
/* the homepage's morphing mark: circle to square and round again */
@keyframes shape-cycle {
  0%   { border-radius: 50%; transform: rotate(0deg); }
  25%  { border-radius: 50%; transform: rotate(0deg);  animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22); }
  50%  { border-radius: 1px; transform: rotate(90deg); }
  75%  { border-radius: 1px; transform: rotate(90deg); animation-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1.0); }
  100% { border-radius: 50%; transform: rotate(180deg); }
}
@media (prefers-reduced-motion: reduce) { .look-item.is-active .look-dot { animation: none; } }

/* demos */
/* default spacing: the headline tracks out to +55, where Lexend and Poppins start, and settles back
   in to 0. case.js runs the loop and the readout in the foot. */
.d-headline {
  --wght: 600; --geom: 50;
  font-variation-settings: 'opsz' 45, 'wght' var(--wght), 'GEOM' var(--geom), 'SHRP' var(--shrp, 0), 'ital' var(--ital, 0);
  font-size: clamp(38px, 5.6vw, 84px);
  --lh: round(nearest, 0.98em, var(--bl)); line-height: var(--lh);
  letter-spacing: 0;
  text-wrap: balance;
  outline: none;
  caret-color: var(--signal);
}
/* the readout, big enough to catch: the figure in the headline's face, the reason beside it */
.d-track { flex: 1; display: flex; align-items: baseline; align-content: flex-start; flex-wrap: wrap; gap: 0 14px; margin-top: 9px; }
.d-track b { --wght: 600; font-size: clamp(32px, 4vw, 56px); --lh: round(nearest, 1em, var(--bl)); line-height: var(--lh); font-feature-settings: 'tnum' 1; white-space: nowrap; }
.d-track .d-num { color: color-mix(in oklab, var(--text) calc(var(--k, 0) * 100%), var(--text-dim)); }
.d-track .d-num.is-hot { color: var(--signal); }
.d-track.is-stack > span { flex-basis: 100%; }
.d-track > span { font-size: clamp(14px, 1.3vw, 17px); color: var(--text-muted); }
/* the Tailwind scale up to 9xl; case.js shortens each row's words to what fits */
.d-fall { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; align-content: start; flex: 1; min-height: 0; overflow: hidden; }
.d-fall div { display: flex; align-items: baseline; gap: 16px; white-space: nowrap; line-height: 1.05; }
.d-fall .xl { display: none; }
@media (min-width: 961px) { .d-fall .xl { display: flex; } .d-fall .sm { display: none; } }
/* the last row takes whatever height is left; case.js sizes it */
.d-fall .mon { line-height: 1; }
.d-fall i {
  font-style: normal;
  flex: 0 0 2.2em;
  font-size: 11px;
  color: var(--text-dim);
  font-feature-settings: 'tnum' 1;
}
.d-big {
  --wght: 600;
  font-size: clamp(40px, 6.2vw, 96px);
  --lh: round(nearest, 1.05em, var(--bl)); line-height: var(--lh);
  overflow-wrap: anywhere;
}
.d-big.is-on[data-feat="ss18"] { font-feature-settings: 'ss18' 1; }
/* Cal Sans Flex: the switch slides GEOM 25 to 100 linearly; Flex interpolates the alternates */
.d-futura {
  font-family: 'CalSansFlex', 'CalSans', sans-serif;
  font-variation-settings: 'wght' 600, 'GEOM' 25, 'SHRP' var(--shrp, 0);
  transition: font-variation-settings 1.2s linear;
}
.d-futura.is-on { font-variation-settings: 'wght' 600, 'GEOM' 100, 'SHRP' var(--shrp, 0); }
.d-futura.is-shrp { --shrp: 100; }   /* the SHRP 100 switch: composes with the Futura one */
@media (prefers-reduced-motion: reduce) { .d-futura { transition: none; } }
/* hello in 103 languages: three rows running at their own pace, the middle one the other way, with
   each row's list doubled so the loop is seamless; hover holds a row. Rows run to the box edges and
   fade out before them. */
.d-hello {
  flex: 1; min-height: 0; min-width: 0;
  display: grid; align-content: center; gap: round(nearest, clamp(14px, 2vw, 26px), var(--bl));
  margin-inline: calc(-1 * var(--pad));
}
.hello-row {
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.hello-track { display: flex; width: max-content; animation: hello-run var(--dur, 150s) linear infinite; }
.hello-row:nth-child(1) { --dur: 150s; }
.hello-row:nth-child(2) { --dur: 190s; }
.hello-row:nth-child(2) .hello-track { animation-direction: reverse; }
.hello-row:nth-child(3) { --dur: 130s; }
.hello-row:hover .hello-track { animation-play-state: paused; }
.hello-track ul { display: flex; gap: clamp(28px, 4vw, 48px); padding-right: clamp(28px, 4vw, 48px); list-style: none; }
.hello-track li { display: grid; gap: 4px; white-space: nowrap; }
.hello-track b {
  --wght: 500;
  font-size: clamp(26px, 3.4vw, 50px);
  line-height: 1.05;
}
.hello-track i { font-style: normal; font-size: 11px; color: var(--text-dim); }
@keyframes hello-run { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .hello-track { animation: none; } }

/* the UI-kit board from wm-primitives, as static tiles: the proofer's component gallery in the page's own
   face. GEOM rides the card's slider; the switch pins optical size to the axis default (14) when off, so the 11px helper text and the headings both drift. */
.ukit {
  display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: max-content; gap: 12px; align-items: start; align-content: start;
  --geom: 25; --wght: 400;
  --type-ui-size: 12.5px; --type-lede-size: 15px; --type-body-size: 14px; --vm-lh: 1.45;
  font-size: 13px; line-height: 1.4;
}
.ukit .coss-b { --wght: 640; }
.ukit .coss-card-name { font-size: 30px; --wght: 640; }
/* the board scrolls inside the demo box, like the proofer's board pans; the bottom edge fades so the next row shows */
.ukit { flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-width: thin; scrollbar-color: rgba(var(--text-rgb), 0.28) transparent; padding-bottom: 24px;
  mask-image: linear-gradient(#000 calc(100% - 48px), transparent); -webkit-mask-image: linear-gradient(#000 calc(100% - 48px), transparent); }
@media (max-width: 860px) { .ukit { max-height: 70vh; } }
.ukit .coss-card { background: var(--bg); }
.ukit:not(.is-on) { font-optical-sizing: none; }
.ukit:not(.is-on) * { font-variation-settings: 'wght' var(--wght, 400), 'GEOM' var(--geom, 25), 'SHRP' var(--shrp, 0), 'ital' var(--ital, 0), 'opsz' 14; }
@media (max-width: 560px) { .ukit { grid-template-columns: 1fr; } }
@media (min-width: 1180px) { .ukit { grid-template-columns: 1fr 1fr 1fr; } }

.switch { display: inline-flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-muted); }
.switch-track {
  width: 36px; height: 20px;
  border-radius: 999px;
  background: var(--border);
  position: relative;
  transition: background var(--dur-fast, 140ms);
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 14px; height: 14px;
  border-radius: 50%;
  corner-shape: round;
  background: var(--text);
  transition: transform var(--dur-fast, 140ms);
}
.switch[aria-checked="true"] .switch-track { background: var(--signal); }
.switch[aria-checked="true"] .switch-track::after { transform: translateX(16px); background: var(--bg); }
.switch:focus-visible { outline: 1.5px solid var(--signal); outline-offset: 4px; border-radius: 4px; }

/* a booking card set entirely in the face, so GEOM has an interface to act on */
.bk {
  width: min(100%, 380px);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 20px;
  display: grid;
  gap: 14px;
}
.bk-head { display: flex; gap: 12px; align-items: center; }
.bk-avatar { width: 36px; height: 36px; border-radius: 50%; corner-shape: round; overflow: hidden; flex: none; }
.bk-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bk-title { --wght: 600; font-size: 16px; --lh: round(nearest, 1.25em, var(--bl)); line-height: var(--lh); }
.bk-meta { font-size: 12px; --lh: round(nearest, 1.4em, var(--bl)); line-height: var(--lh); color: var(--text-muted); }
.bk-date { --wght: 600; font-size: 13px; }
.bk-slots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.bk-slots span {
  font-size: 13px;
  text-align: center;
  padding: 8px 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-feature-settings: 'tnum' 1;
}
.bk-slots span.on { background: var(--text); color: var(--bg); border-color: var(--text); }
.bk-confirm {
  --wght: 600;
  font-size: 13px;
  text-align: center;
  padding: 10px;
  border-radius: 8px;
  background: var(--surface-hi);
}
.demo-switches { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px 27px; }
.demo-foot:has(.demo-switches) { flex-wrap: wrap; row-gap: 12px; }   /* the status span drops under the switches when the row runs out */
.demo-foot:has(.demo-switches) > span:last-child { white-space: nowrap; margin-left: auto; }
.demo-read { font-feature-settings: 'tnum' 1; font-variant-numeric: tabular-nums; }   /* the readout holds its width as the switches change it */
.demo-switches .switch { align-items: flex-start; text-align: left; }   /* a wrapped label keeps its track level with the first line */
.demo-switches .switch-track { flex: none; margin-top: 2px; }
.demo-foot .ax { flex: 1; max-width: 360px; grid-template-columns: auto 1fr 2.4em; }

/* ═══ NUMBERS ═══════════════════════════════════════════ */
.nums { display: grid; grid-template-columns: repeat(2, 1fr); gap: 33px 16px; }
.num { border-top: 1px solid var(--text); padding-top: 12px; }
.num b {
  --wght: 640; --geom: 50;
  display: block;
  font-size: clamp(40px, 5.2vw, 80px);   /* the scale holds: six numbers sit as two rows of three, so 13,362 has a third of the page */
  --lh: round(nearest, 1em, var(--bl)); line-height: var(--lh);
  font-feature-settings: 'tnum' 1;   /* tabular, so the count-up never jitters (case.js) */
}
.num span { display: block; margin-top: 9px; font-size: 14px; color: var(--text-muted); }
@media (min-width: 681px) { .nums { grid-template-columns: repeat(4, 1fr); gap: round(nearest, clamp(20px, 3vw, 40px), var(--bl)); } }

/* ═══ HOW IT CAME TO BE ═════════════════════════════════
   picture, then caption with a bold lead; theme pairs swap with the site's switch */
.made { display: grid; gap: round(nearest, clamp(48px, 7vw, 112px), var(--bl)); }
.made-block { margin: 0; min-width: 0; }
.made-block > img, .tool > img { display: block; width: 100%; height: auto; border-radius: var(--r-card); background: var(--surface); }
.made-block .made-tall { max-width: 720px; margin-inline: auto; }
.made-block figcaption, .made-cap {
  max-width: 56ch; margin: round(nearest, clamp(20px, 2.6vw, 32px), var(--bl)) 0 0;
  font-size: clamp(16px, 1.5vw, 21px); --lh: round(nearest, 1.45em, var(--bl)); line-height: var(--lh); color: var(--text-muted); text-wrap: pretty;
}
.made-block figcaption strong, .made-cap strong { --wght: 640; color: var(--text); }
.made-cap--lead { margin-top: 0; margin-bottom: round(nearest, clamp(20px, 2.6vw, 32px), var(--bl)); }
.made-cap--lead:has(+ .tools) { margin-bottom: round(nearest, calc(2 * var(--grid-gutter, 24px)), var(--bl)); }   /* the tools lead: two gutters to the windows' edge, the shots' shadows cut out of the layout */
/* text column and picture, side by side; alternate sides down the chapter */
.mb { display: grid; gap: 24px; }
.mb-text h3 { --wght: 400; --geom: 50; font-size: clamp(28px, 3.6vw, 48px); --lh: round(nearest, 1.06em, var(--bl)); line-height: var(--lh); text-wrap: balance; }
.mb-text p { margin-top: 21px; max-width: 40ch; font-size: clamp(16px, 1.4vw, 19px); --lh: round(nearest, 1.5em, var(--bl)); line-height: var(--lh); color: var(--text-muted); text-wrap: pretty; }
.mb-link { display: inline-flex; align-items: center; gap: 18px; margin-top: 33px; text-decoration: none; color: var(--text); font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; --wght: 600; }
.mb-link .ring { width: 56px; height: 56px; border-radius: 50%; box-shadow: inset 0 0 0 1px var(--border); display: grid; place-items: center; font-size: 18px; transition: background 0.2s, color 0.2s; }
.mb-link:hover .ring { background: var(--text); color: var(--bg); }
.mb-media { min-width: 0; aspect-ratio: 4 / 3; display: grid; align-items: center; }
.mb-media img { display: block; width: 100%; height: 100%; object-fit: contain; border-radius: var(--r-card); }
.mb-media img:not([class]) { background: var(--surface); }
.mb--photo .mb-media img { object-fit: cover; filter: grayscale(1); }
/* a few deck pages in one box: each arrives on an ease-in-out fade, scaling up from a little smaller */
.deck { position: relative; cursor: pointer; background: var(--surface); border-radius: var(--r-card); overflow: hidden; }   /* the card itself, so the letterbox around a slide is surface, not page */
.deck img { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transform: scale(0.9); transition: opacity 480ms cubic-bezier(0.45, 0, 0.2, 1), transform 480ms cubic-bezier(0.45, 0, 0.2, 1); }
.deck img.is-on { opacity: 1; transform: none; }
.deck img.was-on { transform: none; }   /* the page leaving only fades; it never shrinks */
.deck-n { position: absolute; right: 14px; bottom: 12px; font-size: 11px; color: var(--text-dim); font-feature-settings: 'tnum' 1; }
@media (prefers-reduced-motion: reduce) { .deck img { transition: opacity 400ms; transform: none; } }
/* the statics sheet: the whole catalogue in the same box, scrolling, fading out at the bottom */
.mb-scroll { display: block; overflow-y: auto; scrollbar-width: thin; scrollbar-color: rgba(var(--text-rgb), 0.28) transparent; mask-image: linear-gradient(#000 calc(100% - 72px), transparent); padding-bottom: 72px; }
.mb-scroll img { height: auto; object-fit: unset; border-radius: 0; background: none !important; }
.mb-scroll:focus-visible { outline: 1.5px solid var(--signal); outline-offset: 4px; border-radius: 4px; }
.tool--shot > img { aspect-ratio: 4 / 3; object-fit: contain; width: 100%; height: auto; }
/* a macOS window shot sits as its window: the shared [data-shot="mac"] rule cuts the drop shadow out of the
   layout, so the 4:3 contain box would only shrink it again */
/* the shared rule (shared/src/grid.css) restated unlayered for the tool shots: this page's own `width: 100%` on
   them and its margin reset both beat the layered original. The shadow is cut out of the layout, so the window's
   edge, not the image's, sits on the column. */
.tools img[data-shot="mac"][style*="--shot-w"] {
  --_shot-k: calc(100% / (var(--shot-w) - (var(--shot-mac-l) + var(--shot-mac-r)) * var(--shot-scale)));
  display: block; max-width: none; height: auto; aspect-ratio: auto; object-fit: fill;
  width: calc(var(--_shot-k) * var(--shot-w));
  margin: calc(var(--_shot-k) * var(--shot-mac-t) * var(--shot-scale) * -1) calc(var(--_shot-k) * var(--shot-mac-r) * var(--shot-scale) * -1) calc(var(--_shot-k) * var(--shot-mac-b) * var(--shot-scale) * -1) calc(var(--_shot-k) * var(--shot-mac-l) * var(--shot-scale) * -1);   /* token-lint: allow -- the shadow's measured size, cut out of the layout; not spacing */
}
main.wm-lines { overflow-x: clip; }
/* the page's unlayered reset (margin: 0; padding: 0 on everything) beats the layered grid rules, as it did the
   chip's padding: the hero's grid margin and its breaker's pull to the window edge, stated again unlayered */
.cs-hero.wm-grid { padding-inline: var(--grid-margin); }
.cs-hero > .wm-break { margin-inline: calc(-1 * var(--grid-margin)); }   /* the shots' shadows and the hero breaker never scroll the page sideways */
.cs-hero > .hero-word-box.wm-break { padding-inline: clamp(12px, 2.1vw, 30px); }   /* the logo breaks the grid but keeps off the window edge: 30px wide, 12px on a phone */
/* window captures carry their own alpha and shadow; nothing behind them */
.mb--shot .mb-media img, .tool--shot > img { background: none !important; border-radius: 0; }
@media (min-width: 861px) {
  .mb { grid-template-columns: 5fr 7fr; column-gap: clamp(32px, 5vw, 80px); align-items: center; }
}
.made-theme .for-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .made-theme .for-light { display: none; }
  :root:not([data-theme="light"]) .made-theme .for-dark { display: block; }
}
:root[data-theme="dark"] .made-theme .for-light { display: none; }
:root[data-theme="dark"] .made-theme .for-dark { display: block; }
/* and for the tool shots, as specifically as the window-shot rule above (.tools img[data-shot][style]), whose
   display: block otherwise showed both, light and dark stacked */
.tools .made-theme > img.for-dark[data-shot] { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tools .made-theme > img.for-light[data-shot] { display: none; }
  :root:not([data-theme="light"]) .tools .made-theme > img.for-dark[data-shot] { display: block; }
}
:root[data-theme="dark"] .tools .made-theme > img.for-light[data-shot] { display: none; }
:root[data-theme="dark"] .tools .made-theme > img.for-dark[data-shot] { display: block; }

/* the designspace, drawn live: each master is the real glyph at its coordinates */
.ds-panels { display: grid; gap: clamp(16px, 2vw, 24px); }
@media (min-width: 861px) { .ds-panels { grid-template-columns: 1fr 1fr; } }
.ds-panel { background: var(--surface); border-radius: var(--r-card); padding: clamp(18px, 2.4vw, 32px); min-width: 0; container-type: inline-size; }
.ds-title { font-size: 13px; color: var(--text-dim); margin-bottom: 8px; }
.ds { display: block; width: 100%; height: auto; overflow: visible; color: var(--text-dim); }
.ds-l { stroke: var(--border); stroke-width: 1.5; }
.ds-z, .ds-dash { stroke-dasharray: 4 5; }
.ds-n rect { fill: var(--bg); }
.ds-n .ds-g { fill: var(--text); font-family: 'CalSans', sans-serif; font-optical-sizing: none; }
.ds-n .ds-lab { fill: var(--text-muted); font-size: 16px; font-family: 'CalSans', sans-serif; }
.ds-i rect { fill: var(--surface-hi, var(--bg)); }
.ds-ghost rect { fill: none; stroke: var(--border); stroke-width: 1.5; stroke-dasharray: 5 6; }
.ds-cur rect { fill: var(--bg); }
/* the 2022 panel: the proposed masters are the slide's own outlines, dotted; the current master is Cal Sans 1 */
.ds-o path { fill: var(--text); }
.ds-faint { opacity: 0.45; }
.ds-mvp { fill: var(--signal); }
/* the label pairs never read under 10px: case.js scales each pair (and the MVP under it) as an svg transform */
.ds-tag { fill: var(--text); font-size: 13px; font-family: 'CalSans', sans-serif; font-variation-settings: 'wght' 640, 'GEOM' 25, 'opsz' 14; }
.ds-val { fill: var(--text-muted); font-size: 13px; font-family: 'CalSans', sans-serif; font-feature-settings: 'tnum' 1; }
.ds-v1 { font-family: 'CalSans1', 'CalSans', sans-serif; font-size: 64px; fill: var(--text); font-variation-settings: normal; }
.ds-ax line { stroke: var(--text-dim); stroke-width: 1.2; }
.ds-ax text { fill: var(--text-dim); font-size: 16px; font-family: 'CalSans', sans-serif; }
/* the 2026 panel: a real cube, weight, optical size and italic as its edges, the eight masters live at
   the corners and billboarded so they face you while it turns. In view they arrive one by one. */
.cube-stage { --s: 215px; height: 500px; perspective: 1200px; display: grid; place-items: center; position: relative; touch-action: none; cursor: grab; user-select: none; overflow: hidden; border-radius: var(--r-card); }
.cube-stage.is-grabbing { cursor: grabbing; }
/* iOS starts a text selection on a long press, which cancels the hold: no selection, no callout, anywhere on the stage */
.cube-stage, .cube-stage * { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
@media (max-width: 560px) { .cube-stage { --s: 135px; height: 360px; } }
.cube { position: relative; width: 0; height: 0; transform-style: preserve-3d; transform: rotateX(-16deg) rotateY(-32deg); }
.cube .e { position: absolute; left: calc(var(--s) / -2); top: -0.75px; width: var(--s); height: 1.5px; background: var(--text-dim); opacity: 0.55; transition: opacity 900ms ease; }
.cube .ex { transform: translate3d(0, calc(var(--y) * var(--s) / 2), calc(var(--z) * var(--s) / 2)); }
.cube .ey { transform: translate3d(calc(var(--x) * var(--s) / 2), 0, calc(var(--z) * var(--s) / 2)) rotateZ(90deg); }
.cube .ez { transform: translate3d(calc(var(--x) * var(--s) / 2), calc(var(--y) * var(--s) / 2), 0) rotateY(90deg); }
.cube .v { position: absolute; left: 0; top: 0; transform: translate3d(calc(var(--x) * var(--s) / 2), calc(var(--y) * var(--s) / 2), calc(var(--z) * var(--s) / 2)); transform-style: preserve-3d; }
.cube .v > span {
  position: absolute; left: 0; top: 0; width: 170px; margin: -42px 0 0 -85px;
  display: grid; justify-items: center; gap: 4px;
  transform: rotateY(32deg) rotateX(16deg);
  transition: opacity 700ms ease var(--d, 0ms);
}
.cube .v b { display: block; padding: 6px 0; font-size: 40px; line-height: 1; white-space: nowrap; font-family: 'CalSans', sans-serif; font-optical-sizing: none; color: var(--text); transition: transform 700ms cubic-bezier(0.2, 0.7, 0.2, 1) var(--d, 0ms); }
.vlab { display: grid; grid-template-columns: repeat(3, auto); gap: 2px 10px; justify-content: center; text-align: center; font-size: 9px; line-height: 1.15; color: var(--text-muted); white-space: nowrap; }
.vlab > span { display: grid; }
/* the grids read at the 2022 panel's size: its labels are 13 in an 800-wide viewBox that fills the panel, so
   13/800 of the panel's width; a corner's sits about 0.81 deep in the perspective at rest, so it starts that much larger */
.vm .vlab { font-size: max(10px, calc(100cqi * 13 / 800)); gap: 0.17em 0.67em; }
.cube .v .vlab { font-size: max(calc(10px / 0.81), calc(100cqi * 13 / 800 / 0.81)); gap: 0.17em 0.67em; }
.vlab .hot, .vlab .hot i { color: var(--signal); }   /* the axis a virtual master moves, lit; on a corner, the axis being pulled */
.vlab i { font-style: normal; --wght: 640; color: var(--text); }
.vlab-v { font-size: max(10px, calc(100cqi * 15 / 800)); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim); }
@media (max-width: 560px) { .cube .v > span { width: 100px; margin: -27px 0 0 -50px; } .cube .v b { font-size: 25px; } }
.ds-block:not(.is-in) .cube .v > span { opacity: 0 !important; }
/* once live, the depth fade arrives over a second rather than landing on the far corners at once; after that the per-frame values run with no transition */
.ds-block.is-live .cube .v > span, .ds-block.is-live .cube .e { transition: opacity 1000ms ease; }
.ds-block.is-settled .cube .v > span, .ds-block.is-settled .cube .e { transition: none; }
.ds-block:not(.is-in) .cube .v b { transform: scale(0.5); }
.ds-block:not(.is-in) .tie { opacity: 0 !important; }
.ds-block:not(.is-in) .cube .e { opacity: 0 !important; }
.cube-axes { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 10px; font-size: 13px; color: var(--text-dim); }
/* the virtual axes hold still at the corners and tether to the nearest glyph, pulling it along their axis */
/* dotted, one on one off, marching from the virtual master out to the corner it ties to (the line is drawn from the virtual end, so +x is outward) */
.tie { --p: 2px; --dot: 1px; --dur: 0.083s; position: absolute; left: 0; top: 0; height: var(--dot); background: linear-gradient(90deg, rgba(var(--text-rgb), var(--tie-a, 0.38)) 50%, transparent 50%) 0 0 / var(--p) 100% repeat-x; transform-origin: 0 50%; pointer-events: none; opacity: 0.2; animation: tie-march var(--dur) linear infinite; }
@keyframes tie-march { to { background-position-x: var(--p); } }
/* on 2x displays the dots and gaps double, so they stay legible rather than dissolving into the pixel grid */
@media (min-resolution: 2dppx), (-webkit-min-device-pixel-ratio: 2) { .tie { --p: 4px; --dot: 2px; --dur: 0.167s; } }
@media (prefers-reduced-motion: reduce) { .tie { animation: none; } }
.vm { position: absolute; display: grid; justify-items: center; gap: 2px; z-index: 2; pointer-events: none; }
/* the rings fade in as the mouse nears (case.js writes --inf and sizes them). Every virtual master has a ring,
   as large as the stage allows it; the GEOM master also has the arc, which is GEOM 0, faint, and the stage crops it;
   its ring is GEOM 100. Strokes only, no fill. */
.vm::before, .vm::after { content: ''; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 50%; corner-shape: round; border: 1px solid rgba(var(--text-rgb), 0.7); opacity: var(--inf, 0); pointer-events: none; }
.vm::before { width: calc(var(--ring-in, 50px) * 2); height: calc(var(--ring-in, 50px) * 2); }
.vm::after { display: none; width: calc(var(--ring-out, 260px) * 2); height: calc(var(--ring-out, 260px) * 2); border-color: rgba(var(--text-rgb), 0.3); }
.vm[data-arc]::after { display: block; }
.vm b { font-size: 28px; line-height: 1; white-space: nowrap; font-family: 'CalSans', sans-serif; font-optical-sizing: none; color: var(--text); }
@media (max-width: 560px) { .vm b { font-size: 18px; } }
/* on a phone the eight corners keep their names only: their six-value grids at a readable size pile into each other
   on a 135-unit cube. The four virtual masters, at the stage corners, keep theirs */
@media (max-width: 560px) { .cube .v .vlab { display: none; } }
.cube-hint { flex-basis: 100%; }
.cube-switches { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 4px; }
/* the virtual masters can be switched off: no ties, no pull; the corners sit at their own masters */
.cube-stage.no-pull .tie { opacity: 0 !important; }
.cube-stage.no-pull .vm { opacity: 0.45; }
.cube-stage .vm { transition: opacity 400ms; }
/* a virtual master's influence (case.js writes --inf): the master itself comes up from quiet to full ink,
   and its ties' dots do the same, so the pull reads in the lines that carry it; no extra shape */
.vm b { color: rgba(var(--text-rgb), calc(0.45 + 0.55 * var(--inf, 0))); }
/* the same cube in Cal Sans Flex: GEOM blends the letterforms instead of swapping them */
.cube-stage.is-flex .cube .v b, .cube-stage.is-flex .vm b { font-family: 'CalSansFlex', 'CalSans', sans-serif; }
/* levels the tilt, roll and zoom once any of them has moved; the turn is left where it is. It sits in the
   switches row, not on the stage, where it would cover the top-right virtual master */
/* as the highlights' Replay: icon white, word gray (.cube-switches outranks the button reset), the ring on
   the word's cap middle, the spin about the ring's centre so only the arrowhead travels */
.cube-switches .cube-reset { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-muted); cursor: pointer; transition: color 0.15s; }
.cube-reset[hidden] { display: none; }
.cube-switches .cube-reset:hover { color: var(--text); }
.cube-reset .wm-icon { color: var(--text); translate: 0 -1px; transform-origin: 50% 54.1667%; }
.cube-reset.is-spun .wm-icon { animation: hl-replay-spin 0.6s cubic-bezier(0.3, 0, 0.2, 1); }
@media (prefers-reduced-motion: reduce) {
  .cube .v > span, .cube .v b, .cube .e { transition: none; }
  .ds-block:not(.is-in) .cube .v > span { opacity: 1; } .ds-block:not(.is-in) .cube .v b { transform: none; } .ds-block:not(.is-in) .cube .e { opacity: 0.55; }
}

.tools { display: grid; gap: round(nearest, clamp(16px, 2vw, 24px), var(--bl)); row-gap: round(nearest, calc(2 * var(--grid-gutter, 24px)), var(--bl)); }   /* a caption and the window under it: two gutters, as the lead and the first row */
@media (min-width: 681px) { .tools { grid-template-columns: 1fr 1fr; } }
.tool { display: grid; gap: 9px; align-content: start; color: inherit; text-decoration: none; min-width: 0; }
.tool--text { background: var(--surface); border-radius: var(--r-card); padding: round(nearest, clamp(22px, 3vw, 40px), var(--bl)); }
.tool-name { --wght: 400; --geom: 50; font-size: clamp(20px, 2.2vw, 28px); --lh: round(nearest, 1.1em, var(--bl)); line-height: var(--lh); margin-top: 6px; }
.tool-text { font-size: 15px; --lh: round(nearest, 1.45em, var(--bl)); line-height: var(--lh); color: var(--text-muted); max-width: 44ch; }
a.tool:hover .tool-name, a.tool-name:hover { text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 4px; }
a.tool-name { color: inherit; text-decoration: none; }
.tool-text a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.tool-text a:hover { color: var(--text); }
.tool > a > img, .tool--shot > a > img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: contain; }

/* ═══ STUDIO ════════════════════════════════════════════ */
.studio-photo { margin: 0 0 round(nearest, clamp(28px, 4vw, 56px), var(--bl)); }
.studio-photo img { display: block; width: 100%; height: auto; border-radius: var(--r-card); }
.studio { display: grid; gap: 27px; }
.studio-side { display: flex; align-items: center; gap: 15px; }
.studio-side .sec-title { margin: 0; font-size: clamp(22px, 2.4vw, 32px); }
.prose { display: grid; gap: round(nearest, 1.1em, var(--bl)); max-width: 36em; }
.prose > p {
  font-size: clamp(18px, 1.7vw, 22px);
  --lh: round(nearest, 1.5em, var(--bl)); line-height: var(--lh);
  color: var(--text-muted);
  text-wrap: pretty;
}
.prose > p:first-child { color: var(--text); }
.quote { margin-block: round(nearest, clamp(16px, 2.4vw, 32px), var(--bl)); padding-left: 20px; border-left: 1px solid var(--text); }
.quote p {
  --ital: 1;
  font-size: clamp(22px, 2.5vw, 34px);
  --lh: round(nearest, 1.25em, var(--bl)); line-height: var(--lh);
  text-wrap: pretty;
}
.quote p + p { margin-top: round(nearest, 0.1em, var(--bl)); }
.quote--stack p { --ital: 0; --wght: 600; }
.quote footer { margin-top: 15px; font-size: 13px; color: var(--text-dim); }
.quote footer a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.quote footer a:hover { color: var(--text); }
@media (min-width: 861px) {
  .studio { grid-template-columns: 5fr 7fr; gap: round(nearest, clamp(32px, 5vw, 80px), var(--bl)); align-items: start; }
  .studio-side { position: sticky; top: calc(var(--nav-h) + 24px); }
}
.maxim {
  --wght: 640; --geom: 50;
  margin-top: var(--sec);
  font-size: clamp(38px, 8vw, 128px);
  --lh: round(nearest, 0.98em, var(--bl)); line-height: var(--lh);
  text-wrap: balance;
}

/* ═══ TRY IT ════════════════════════════════════════════
   the Framer type tester, in plain HTML: a centred field under a fixed clamp, eight controls
   four-up or two-up, two of them segmented presets that unlock into a slider. */
.tester { position: relative; container-type: inline-size; display: flex; flex-direction: column; gap: 27px; }
.tt-reset, .ax-reset {
  position: absolute; top: 16px; right: 16px; z-index: 2;
  width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); background: none; border: 0; cursor: pointer; opacity: 0.6;
  transition: opacity 0.15s, transform 0.5s;
}
.tt-reset[hidden], .ax-reset[hidden] { display: none; }
.tt-reset:hover, .ax-reset:hover { opacity: 1; }
.tt-reset.is-spun, .ax-reset.is-spun { transform: rotate(360deg); }
.axes-wrap { position: relative; }
/* the Geometry card shares a row with the census, which is taller: its stage takes the spare height and the
   rails grow into it, never shorter than the 96px they are on their own (a phone, a single column) */
.axes-wrap.hl-stage { flex: 1 1 auto; display: flex; flex-direction: column; }
.axes-wrap .axes { flex: 1 1 auto; }
.axes .wm-hd--vertical .wm-hd-rail { flex: 1 1 auto; height: auto; min-height: var(--hd-rail); }
.ax-reset { top: 33px; right: 0; }   /* under the release row */
.axes-wrap.is-live .ax-reset { opacity: 0; pointer-events: none; }   /* nothing to reset while the axes move on their own */   /* the axes card: the same reset, tucked in the sample's corner */
.tt-clamp { height: var(--tt-clamp, 180px); overflow: hidden; display: flex; flex-direction: column; }
@media (min-width: 861px) { .tt-clamp { --tt-clamp: 260px; } }
.tt-preview {
  display: block; width: 100%; margin: auto 0;
  font: inherit; font-family: 'CalSans', sans-serif;
  font-size: var(--tt-size, 100px); --lh: round(nearest, 1.3em, var(--bl)); line-height: var(--lh); letter-spacing: var(--tt-track, 0);
  font-optical-sizing: none;
  font-variation-settings: 'wght' var(--tt-wght, 400), 'GEOM' var(--tt-geom, 25), 'opsz' var(--tt-opsz, 45), 'YTAS' var(--tt-ytas, 1440), 'SHRP' var(--tt-shrp, 0), 'ital' var(--tt-ital, 0);
  color: var(--text); text-align: center; background: transparent; border: 0; outline: none; resize: none; overflow: auto;
  caret-color: var(--signal);
}
.tt-controls { display: grid; grid-template-columns: repeat(2, minmax(0, 150px)); justify-content: center; column-gap: clamp(24px, 4cqi, 40px); row-gap: 33px; padding: 8px 0 16px; }
.tt-row { display: flex; flex-direction: column; gap: var(--spacing-02, 6px); min-width: 0; order: var(--o2); }
@container (min-width: 720px) { .tt-controls { grid-template-columns: repeat(4, 150px); } .tt-row { order: 0; } }
.tt-head { display: flex; justify-content: space-between; align-items: baseline; height: 15px; font-size: var(--type-ui-size, 12px); --lh: 15px; line-height: var(--lh); position: relative; top: var(--hair, 1px); color: var(--text-muted); --wght: 500; }
.tt-row > input[type="range"] { height: 33px; }
.tt-head output { color: var(--text); font-feature-settings: 'tnum' 1; }
.tt-morph .tt-head output { opacity: 0; transition: opacity 0.2s; }
.tt-morph.is-open .tt-head output { opacity: 1; }
.tt-area { position: relative; height: 33px; display: flex; align-items: center; }
.tt-seg { display: flex; width: 100%; height: 100%; padding: var(--bl, 3px); box-sizing: border-box; gap: 0; background: var(--border); border-radius: 999px; transition: opacity 0.2s; }
.tt-seg button {
  flex: 1 1 auto; min-height: 27px; white-space: nowrap; padding: calc(var(--spacing-02, 6px) + var(--hair, 1px)) var(--spacing-01, 4px) calc(var(--spacing-02, 6px) - var(--hair, 1px));
  font: inherit; font-size: var(--type-ui-size, 12px); line-height: 15px;
  font-variation-settings: 'wght' 400, 'GEOM' var(--geom, 25), 'SHRP' var(--shrp, 0), 'ital' var(--ital, 0);
  border: 0; border-radius: 999px; min-width: 0; overflow: hidden; text-overflow: clip;
  background: transparent; color: var(--text-muted); cursor: pointer;
}
.tt-seg button[aria-pressed="true"] { background: var(--bg); color: var(--text); box-shadow: none; }
.tt-area input[type="range"] { position: absolute; inset: 0; margin: auto; opacity: 0; pointer-events: none; }
.tt-track { position: absolute; left: 0; top: 50%; height: 2px; width: 0; margin-top: -1px; background: var(--border); border-radius: 1px; transition: width 380ms cubic-bezier(0.2, 0.7, 0.2, 1); }
/* the handle: a small grey pill with a tick either side; on unlock it grows into the thumb and slides to the value */
/* .tt-area .tt-unlock: the page's button:not(.wm-chip) reset outranks a single class and cleared its fill, so the
   pill drew in neither theme; restated here it takes --text-dim, which follows light and dark */
.tt-area .tt-unlock { background: var(--text-dim); }
.tt-area .tt-unlock:hover { background: var(--text-muted); }
.tt-unlock {
  position: absolute; left: 100%; top: 50%; width: 6px; height: 15px; margin: -7.5px 0 0 9px;
  border: 0; border-radius: 3px; background: var(--text-dim); cursor: pointer;
  transition: left 380ms cubic-bezier(0.2, 0.7, 0.2, 1), margin 380ms cubic-bezier(0.2, 0.7, 0.2, 1), width 380ms, height 380ms, border-radius 380ms, background 380ms, opacity 200ms 380ms;
}
.tt-unlock::before, .tt-unlock::after { content: ''; position: absolute; top: 7px; width: 4px; height: var(--hair, 1px); margin-top: 0; background: var(--text-dim); border-radius: 0; transition: width 200ms, opacity 200ms; }
.tt-unlock::before { right: 100%; margin-right: 2px; }   /* the ticks show with the pill, always: hidden until hover they read as missing */
.tt-unlock::after { left: 100%; margin-left: 2px; }
.tt-unlock:hover::before, .tt-unlock:hover::after, .tt-unlock:focus-visible::before, .tt-unlock:focus-visible::after { background: var(--text-muted); }
.tt-unlock:hover { background: var(--text-muted); }
.tt-morph.is-opening .tt-seg { opacity: 0; pointer-events: none; }
.tt-morph.is-opening .tt-track { width: 100%; }
.tt-morph.is-opening .tt-unlock { left: var(--at, 0%); margin: -7px 0 0 -7px; width: 14px; height: 14px; border-radius: 50%; background: var(--text); }
.tt-morph.is-opening .tt-unlock::before, .tt-morph.is-opening .tt-unlock::after { width: 0; opacity: 0; }
.tt-morph.is-open .tt-unlock { opacity: 0; pointer-events: none; }
.tt-morph.is-open .tt-track { opacity: 0; }
.tt-morph.is-open input[type="range"] { opacity: 1; pointer-events: auto; }
.tt-more { display: flex; justify-content: center; }

/* ═══ RELEASES ══════════════════════════════════════════ */
.rel-grid { display: grid; gap: 39px; }
.rel { position: relative; border-top: 1px solid var(--text); padding-top: 21px; }
.rel::before {
  content: "";
  position: absolute;
  top: -6px; left: 0;
  width: 11px; height: 11px;
  border-radius: 50%;
  corner-shape: round;
  background: var(--text);
}
.rel h3 { font-size: clamp(34px, 4vw, 60px); --lh: round(nearest, 1em, var(--bl)); line-height: var(--lh); margin: 15px 0 15px; white-space: nowrap; }
.rel--2021 h3 { --wght: 600; --geom: 50; }
.rel--2025 h3 { font-family: 'CalSansUI', 'CalSans', sans-serif; font-variation-settings: 'wght' 500, 'GEOM' 0; }
.rel--2026 h3 { --wght: 700; --geom: 50; }
.rel p { color: var(--text-muted); max-width: 34ch; text-wrap: pretty; }
@media (min-width: 861px) { .rel-grid { grid-template-columns: repeat(3, 1fr); gap: round(nearest, clamp(24px, 4vw, 64px), var(--bl)); } }

/* ═══ CLOSE + FOOTER ════════════════════════════════════ */
.close { padding-block: var(--sec); }
.close .sec-title { margin-bottom: 21px; }
.close-para {
  font-size: clamp(18px, 1.7vw, 22px);
  --lh: round(nearest, 1.5em, var(--bl)); line-height: var(--lh);
  color: var(--text-muted);
  max-width: 34em;
  text-wrap: pretty;
}
.close-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: round(nearest, clamp(28px, 4vw, 48px), var(--bl)); }

.cs-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 15px 40px;
  padding: 27px var(--gut) 39px;
  border-top: 1px solid var(--border);
  font-size: 14px;
}
.cs-footer nav { display: flex; flex-wrap: wrap; gap: 9px 24px; }
.cs-footer a { color: var(--text-muted); text-decoration: none; transition: color 0.12s; }
.cs-footer a:hover { color: var(--text); }
.cs-footer p { color: var(--text-dim); }

/* ═══ THE GRID ══════════════════════════════════════════
   shared/src/grid.css: 24 columns from 1024px, 12 below, a 24px gutter (12 on a phone), the
   page margin as before. Every section grid that used to split by fr runs on those columns
   now, so every edge on the page is a column line and every gap is the gutter (or a gutter,
   a skipped column and a gutter -- the 72px the page had chosen by eye). Each section keeps
   the width it used to stack at. Cards step their contents in one column + one gutter
   (rule A). Leadings and vertical space above are in 3px units; gridSnap.js puts what follows
   an image or a demo back on the line. */
.hero-cols, .hl-grid, .look, .mb, .studio, .rel-grid, .nums, .tools, .ds-panels {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  container-type: inline-size;
  --col: calc((100cqw - (var(--grid-cols) - 1) * var(--grid-gutter)) / var(--grid-cols));
}
.hero-cols > *, .hl-grid > *, .mb > *, .studio > *, .rel-grid > *, .nums > *, .tools > *, .ds-panels > * { grid-column: 1 / -1; }
/* below 961 a .look-item is a box of its own in the .look grid and takes the whole width;
   from 961 it is display: contents and its head and demo are placed below -- without this
   the six items sat side by side in one column each (18px at 390; shipped 2026-10-01) */
.look > * { grid-column: 1 / -1; }
.look-item > * { grid-column: 1 / -1; }

/* cards: one gutter top and bottom, one column + one gutter each side */
.hl-grid > .card { padding: var(--grid-gutter) calc(var(--col) + var(--grid-gutter)); }
/* the cube's panel is a stage, and the cube is short of room as it is: its masters sit at
   12/10px insets and its rings are sized from the edge distance. It keeps the padding it had,
   on the unit, so the stage keeps its width (543px at 1440). */
.ds-panels > .ds-panel { padding: round(nearest, clamp(18px, 2.4vw, 32px), var(--bl)) clamp(18px, 2.4vw, 32px); }   /* top/bottom on the unit; the sides exactly as they were */
.look-demo { --pad: calc(var(--col) + var(--grid-gutter)); padding: var(--grid-gutter) var(--pad); }
/* a demo is a stage for specimens, not a text card: on 12 columns a column is wide enough that
   the card inset pushed the big words past the box (+38px at 900), so below 1024 a stage
   insets by the gutter alone */
@media (max-width: 1023px) { .look-demo { --pad: var(--grid-gutter); } }
/* the tester spans the page: its column is the page's */
.tester { padding: var(--grid-gutter) calc((100vw - 2 * var(--grid-margin) - (var(--grid-cols) - 1) * var(--grid-gutter)) / var(--grid-cols) + var(--grid-gutter)); }

@media (min-width: 681px) {
  .nums > * { grid-column: span 4; }   /* 12 columns: six numbers as two rows of three */
  .tools > * { grid-column: span 6; }
}
@media (min-width: 681px) and (max-width: 1023px) { .nums { row-gap: 33px; } }
@media (max-width: 680px) { .nums > * { grid-column: span 6; } }
@media (max-width: 380px) { .num b { font-size: 36px; } }   /* two across at 360: 402,680 overran its half by 1px at 40 */

@media (min-width: 861px) {
  /* 12 columns: 7 | 5 and 5 | 7, the old 7fr/5fr exactly */
  .hero-cols > :first-child { grid-column: 1 / span 7; }
  .hero-cols > :last-child  { grid-column: 8 / span 5; }
  .hl-grid > .hl { grid-column: span 6; }
  .hl-grid.is-show > .hl { grid-column: auto; }
  .mb > .mb-text { grid-column: 1 / span 5; }
  .mb > .mb-media { grid-column: 6 / span 7; }
  .studio > .studio-side { grid-column: 1 / span 5; }
  .studio > .prose { grid-column: 6 / span 7; }
  .rel-grid > * { grid-column: span 4; }
  .ds-panels > * { grid-column: span 6; }
  .hero-cols, .mb, .studio { column-gap: var(--grid-gutter); }
}
@media (min-width: 961px) and (max-width: 1023px) {
  .look-head { grid-column: 1 / span 5; }
  .look-demo { grid-column: 6 / span 7; }
}
@media (min-width: 1024px) {
  .nums > * { grid-column: span 8; }   /* two rows of three on the page's 24 columns: six across at this scale would need 209px of a 186px sixth at 1440 */
  /* 24 columns: the hero is 13 | skip | 10; text beside a picture is 9 | skip | 14, keeping
     the wide gap those sections had; side-by-side cards are 10 | 14 on the gutter */
  .hero-cols > :first-child { grid-column: 1 / span 13; }
  .hero-cols > :last-child  { grid-column: 15 / span 10; }
  .hl-grid > .hl { grid-column: span 12; }
  .mb > .mb-text { grid-column: 1 / span 9; }
  .mb > .mb-media { grid-column: 11 / span 14; }
  .studio > .studio-side { grid-column: 1 / span 9; }
  .studio > .prose { grid-column: 11 / span 14; }
  .look-head { grid-column: 1 / span 9; }
  .look-demo { grid-column: 11 / span 14; }
  .rel-grid > * { grid-column: span 8; }
  .tools > * { grid-column: span 12; }
  .ds-panels > * { grid-column: span 12; }
}
