/* deckle theme stylesheet — Save The Internet.
 *
 * The campaign look of savetheinternet.eu, carried over from the
 * hand-built page the site started as: one near-black page under a faint
 * technical grid, a monospaced kicker line over every big grotesque
 * heading, mint for what we stand for and orange for what attacks it, an
 * orange warning ticker under the hero, hairlines between the parts of the
 * page.
 *
 * Fork guide
 *
 * - Palette, type and rhythm live in the custom properties on :root below.
 *   Every colour and size in the rules comes from a token. Each colour
 *   token states its role and its WCAG contrast on the page background —
 *   re-check the ratios if you change a value.
 * - One dark palette everywhere, no light surfaces and no dark mode: the
 *   dark is the design. Mint and orange are both light enough to carry
 *   text on the page (11.73:1 and 6.28:1) and to carry dark text as a
 *   button (the same ratios), so there is no "light/dark surface" split.
 * - Tones: an element that comes in mint or orange (headline, statement,
 *   cta) sets --tone and --tone-rgb through .ce-tone--mint /
 *   .ce-tone--orange, and the orange band sets them for everything inside
 *   that has no colour of its own; the rules read only those.
 * - Breakpoints (mobile first, nothing scrolls sideways from 320px up):
 *     < 48em   one column; mosaic in two columns
 *     < 56em   the timeline vertical: two tracks as two lanes down the
 *              screen, one track as one line
 *     >= 40em  image grids go to two columns (a logo wall: two below,
 *              three here)
 *     >= 48em  card, figure and image grids at their column count;
 *              video teaser and text-media side by side; four-column
 *              mosaic; form fields side by side; two-col layout 3:1
 *     >= 56em  the timeline as the horizontal two-track diagram
 *     < 68em   the header's menu behind the Menu button (a numbered
 *              panel); from 68em its links in one row
 * - Fonts are self-hosted (assets/fonts, published at /fonts/ by
 *   baseof.html): Space Grotesk (display), IBM Plex Sans (body) and IBM
 *   Plex Mono (kickers, labels, ticker, timeline). Each family is the
 *   Latin and Latin Extended web subset Google Fonts distributes,
 *   unmodified, split by unicode-range. No third-party request, ever.
 * - The base layer (element defaults: headings, links, lists, images) is
 *   written with :where() at zero specificity, so any class rule wins over
 *   it. Buttons always declare background AND colour, in every state.
 * - Element markup (the ce- classes) is documented in the theme README.
 *   Style hooks only: templates carry no inline styles (the GFM table
 *   alignment hook is the one documented exception).
 * - Spacing between elements is never a margin. Every block element sits
 *   in a div.ce-frame that pads --frame above and below (see "frames"),
 *   so the elements of a column sit close together. The parts of a page
 *   are set apart by the hr element, which brings --section-pad of air on
 *   either side of its line. The hero is a full-bleed band that does its
 *   own padding; an element with a background is a full-bleed band too
 *   (see "bands"), and the spacing where bands meet is under "flat
 *   column".
 */

/* ----------------------------------------------------------------- fonts */

/* The CSS is served at /css/theme.css, so ../fonts/ is the published
   /fonts/. Each face: a Latin file and a Latin Extended file; the browser
   fetches only the one whose unicode-range the page uses. */
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 100 700;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 100 700;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: italic;
  font-weight: 100 700;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans-latin-wght-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: italic;
  font-weight: 100 700;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans-latin-ext-wght-italic.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------------------------------------------------------------- tokens */

:root {
  /* Palette. Ratios are WCAG 2.2 contrast on --color-bg (AA: 4.5:1 text,
     3:1 large text and UI); on --color-surface each is about 6% lower. */
  --color-bg: #0b0d10;             /* the page */
  --color-surface: #12151a;        /* panels: video box, form, teasers, table head */
  --color-strong: #f5f3ee;         /* headings, bold, the light button: 17.55:1 */
  --color-text: #dadde0;           /* body copy: 14.27:1 */
  --color-muted: #b4b8be;          /* secondary copy, card labels, upcoming steps: 9.77:1 */
  --color-faint: #7a7f86;          /* notes, footer, captions' asides: 4.82:1 (4.54:1 on surface) — the floor; nothing dimmer carries text */
  --color-accent: #46e1b0;         /* mint: kickers, figures, the primary button, focus ring, list checks, timeline track 1: 11.73:1 */
  --color-accent-strong: #6be8c1;  /* mint hover */
  --color-alert: #ff5a3c;          /* orange: links in text, the ticker, warnings, timeline track 2: 6.28:1 */
  --color-alert-strong: #ff7a62;   /* orange hover */
  --color-on-tone: #0b0d10;        /* text on mint (11.73:1) and on orange (6.28:1) */
  --on-dark: 245 243 238;          /* --color-strong as an RGB triplet, for hairlines and translucent fills: rgb(var(--on-dark) / .08) */
  --overlay: 11 13 16;             /* --color-bg as an RGB triplet, for scrims over photos */
  --accent-rgb: 70 225 176;
  --alert-rgb: 255 90 60;
  --line: rgb(var(--on-dark) / .08);        /* the hr's hairline, the footer's (decorative) */
  --line-strong: rgb(var(--on-dark) / .12); /* card and figure outlines (decorative) */
  --rail: rgb(var(--on-dark) / .16);        /* timeline lines not reached yet (decorative; the status is in the text) */
  --tone: var(--color-accent);
  --tone-rgb: var(--accent-rgb);
  --band-grey: var(--color-surface);        /* background grey (opaque; text ratios as on surface) */
  --band-mint: rgb(var(--accent-rgb) / .04);  /* background mint: a faint tint, text ratios as on the page */
  --band-orange: rgb(var(--alert-rgb) / .04); /* background orange: a faint tint, text ratios as on the page */

  /* Spacing scale (rem). Also drives the spacer sizes s/m/l/xl = 3/5/6/7. */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2.5rem;
  --space-6: 4rem;
  --space-7: 6rem;
  --frame: .75rem;                 /* each element's half of the gap to its neighbour (see "frames") */
  --section-pad: clamp(4.5rem, 10vw, 7.5rem); /* the air an hr puts on either side of its line, and a band's where it meets other backgrounds */

  /* Type */
  --font-display: "Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --display-weight: 700;
  --display-tracking: -0.01em;
  --text-base: 1.0625rem;          /* 17px body copy, line-height 1.7 */
  --text-lead: clamp(1.0625rem, 1rem + .35vw, 1.1875rem); /* 19px lead copy */
  --text-sm: .875rem;              /* captions, labels, footer */
  --text-kicker: .8125rem;         /* 13px monospaced kicker lines */
  --text-hero: clamp(3rem, 9vw, 8rem);              /* the hero heading */
  --text-h1: clamp(2.5rem, 1.6rem + 4vw, 4.5rem);   /* page title */
  --text-h2: clamp(2rem, 4.5vw, 3.5rem);            /* section heading */
  --text-h3: clamp(1.4rem, 1.2rem + .9vw, 1.9rem);  /* h3 in text */
  --text-h4: clamp(1.15rem, 1.05rem + .4vw, 1.35rem);
  --text-statement: clamp(1.375rem, 1rem + 1.8vw, 2.125rem); /* plain statement */

  /* Layout */
  --radius: 6px;                   /* photos, the video card, panels */
  --radius-sm: 4px;                /* cards, figures, boxes */
  --measure: 52rem;                /* max width of running text */
  --container: 90rem;              /* max width of the content shell (.container) */
  --gutter: clamp(1rem, 8vw, 7.5rem); /* side padding of the shell; >= 16px at every width */
  --bleed: calc((100vw - min(var(--container), 100vw)) / 2 + var(--gutter)); /* content edge to viewport edge */
  --header-h: 4rem;                /* the sticky header bar's height (one line); also how far an anchor jump stops below the top */
}

/* ------------------------------------------------------------------ base */

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  position: relative;
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip; /* classic scrollbars make 100vw (and so --bleed) overshoot by the bar width */
}

/* The faint technical grid behind the top of every page (64px squares,
   3.5% white), fading out towards its foot. Decorative. */
body::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 87.5rem;
  max-height: 100%; /* never makes a short page scroll */
  pointer-events: none;
  background-image:
    linear-gradient(rgb(var(--on-dark) / .035) 1px, transparent 1px),
    linear-gradient(90deg, rgb(var(--on-dark) / .035) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: linear-gradient(#000 60%, transparent);
  mask-image: linear-gradient(#000 60%, transparent);
}

.site-main,
.site-footer { position: relative; }

/* An anchor jump (the header's section links, any #c-<uid> link) stops
   below the sticky header, and glides there unless motion is reduced. */
html:has(.site-header) { scroll-padding-top: calc(var(--header-h) + var(--space-5)); }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

:where(h1, h2, h3, h4, h5, h6) {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  line-height: 1.1;
  letter-spacing: var(--display-tracking);
  color: var(--color-strong);
  margin: 0 0 var(--space-3);
  overflow-wrap: break-word;
  text-wrap: balance;
}

:where(h1) { font-size: var(--text-h1); }
:where(h2) { font-size: var(--text-h2); line-height: 1.05; }
:where(h3) { font-size: var(--text-h3); }
:where(h4) { font-size: var(--text-h4); }

:where(p, ul, ol, address) { margin: 0 0 1.25rem; }

:where(address) { font-style: normal; }

:where(strong, b) { font-weight: 600; color: var(--color-strong); }

:where(blockquote) {
  margin: 0 0 var(--space-3);
  padding-inline-start: var(--space-3);
  border-inline-start: 2px solid var(--line-strong);
}

:where(li)::marker { color: var(--color-accent); }

/* Links in running text: orange, underlined, as on the first site. */
:where(a) {
  color: var(--color-alert);
  text-decoration: underline;
  text-underline-offset: .18em;
  text-decoration-thickness: from-font;
}

:where(a:hover) { color: var(--color-alert-strong); }

:where(img, svg, video, iframe) { max-width: 100%; height: auto; }

:where(img) { display: block; }

:where(pre) { overflow-x: auto; }

/* Focus: 3px mint ring, 3px offset. Never removed. */
:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 3px;
}

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  z-index: 10000;
  padding: var(--space-2) var(--space-3);
  background: var(--color-accent);
  color: var(--color-on-tone);
  font-weight: 600;
  text-decoration: none;
  outline-color: var(--color-strong);
}

.skip-link:focus {
  left: var(--space-2);
  top: var(--space-2);
  color: var(--color-on-tone);
}

/* Visually hidden, still in the accessibility tree. */
.sr-only,
.page--home .page__header {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The shared kicker voice: a small monospaced line over a heading. */
.ce-hero__kicker,
.ce-headline__kicker {
  font-family: var(--font-mono);
  font-size: var(--text-kicker);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--tone);
  margin: 0 0 .875rem;
}

/* ---------------------------------------------------------------- loader */

/* The loading screen of the home page (params.loader; markup and the
   inline script in baseof.html). Hidden unless the script set
   html.is-loading, so the page is never hidden without JavaScript. */
.site-loader { display: none; }

.is-loading { overflow: hidden; }

.is-loading .site-loader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.375rem;
  background: var(--color-bg);
  font-family: var(--font-mono);
}

.site-loader__spinner {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  border: 4px solid rgb(var(--on-dark) / .14);
  border-top-color: var(--color-accent);
  animation: site-spin .85s linear infinite;
}

.site-loader__text {
  font-size: var(--text-kicker);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.is-revealed .site-main,
.is-revealed .site-footer { animation: site-fade-up .7s ease both; }

.is-revealed .site-header { animation: site-fade .7s ease both; }

@keyframes site-spin { to { transform: rotate(360deg); } }

@keyframes site-fade { from { opacity: 0; } }

@keyframes site-fade-up {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- header */

/* Only on a page with a menu, section links or a language switch
   (partials/header.html renders nothing otherwise): a bar of
   --header-h that sticks to the top of the screen, the page showing
   faintly through it (82% of the page colour, blurred), a hairline
   under it. A page that opens with a hero pulls the hero up under the
   bar (see "main"), so the hero still fills the first screen. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgb(var(--overlay) / .82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  min-height: var(--header-h);
  padding-block: var(--space-2);
}

.site-header__brand {
  display: block;
  min-width: 0;
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: 1.2rem;
  line-height: 1.2;
  letter-spacing: var(--display-tracking);
  color: var(--color-strong);
  text-decoration: none;
  overflow-wrap: break-word;
}

.site-header__brand:hover { color: var(--color-accent); }

.site-nav__menu,
.site-nav__sub {
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav__toggle {
  flex: none;
  font: inherit;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.2;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-strong);
  background: transparent;
  border: 1px solid rgb(var(--on-dark) / .5);
  border-radius: 2px;
  padding: .7em 1em;
  cursor: pointer;
}

.site-nav__toggle:hover,
.site-nav__toggle[aria-expanded="true"] {
  color: var(--color-strong);
  background: transparent;
  border-color: var(--color-strong);
}

.site-nav__link,
.site-nav__sublink {
  display: block;
  color: var(--color-muted);
  font-family: var(--font-mono);
  font-size: var(--text-kicker);
  line-height: 1.4;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .6em .7em;
}

.site-nav__link:hover,
.site-nav__sublink:hover { color: var(--color-strong); }

/* The current page, and the part of the page being read (nav.js sets
   aria-current="true" on its section link as the page scrolls). */
.site-nav__link[aria-current],
.site-nav__sublink[aria-current] { color: var(--color-accent); }

/* Phone: the Menu button opens a panel under the bar, one entry per
   line, numbered in mint like a table of contents (a CSS counter: no
   markup), the labels in the display face. */
@media (max-width: 67.99em) {
  .site-nav__menu {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 20;
    max-height: calc(100vh - var(--header-h));
    max-height: calc(100dvh - var(--header-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--color-bg);
    border-bottom: 1px solid var(--line-strong);
    padding: var(--space-2) var(--gutter) var(--space-4);
    counter-reset: site-nav;
  }
  .site-nav__toggle[aria-expanded="true"] + .site-nav__menu { display: block; }
  .site-nav__item {
    counter-increment: site-nav;
    border-bottom: 1px solid var(--line);
  }
  .site-nav__link {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding: .85rem 0;
    font-family: var(--font-display);
    font-weight: var(--display-weight);
    font-size: 1.5rem;
    line-height: 1.2;
    letter-spacing: var(--display-tracking);
    text-transform: none;
    color: var(--color-strong);
  }
  .site-nav__link::before {
    content: counter(site-nav, decimal-leading-zero);
    flex: none;
    min-width: 1.75rem;
    font-family: var(--font-mono);
    font-size: var(--text-kicker);
    font-weight: 400;
    letter-spacing: .08em;
    color: var(--color-accent);
  }
  .site-nav__link:hover { color: var(--color-accent); }
  .site-nav__sublink { padding: .6em 0 .6em calc(1.75rem + var(--space-3)); }
  .site-nav__sub { padding-bottom: var(--space-2); }
}

/* Wide: the entries in one row at the right of the bar; the current one
   gets a mint underline that draws in from the left. */
@media (min-width: 68em) {
  .site-nav__toggle { display: none; }
  .site-nav__menu {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    margin-right: calc(-.7 * var(--text-kicker)); /* the last label ends on the shell edge */
  }
  /* A short upright hairline between two entries, so the gap between
     entries never reads as the space between two words of one. */
  .site-nav__item {
    display: flex;
    align-items: center;
  }
  .site-nav__item + .site-nav__item::before {
    content: "";
    flex: none;
    width: 1px;
    height: .875rem;
    background: var(--rail);
  }
  .site-nav__link { position: relative; }
  .site-nav__link::after {
    content: "";
    position: absolute;
    left: .7em;
    right: .7em;
    bottom: .15em;
    height: 2px;
    background: var(--color-accent);
    transform: scaleX(0);
    transform-origin: left;
  }
  .site-nav__link[aria-current]::after { transform: scaleX(1); }
  .site-nav__item--parent { position: relative; }
  .site-nav__sub {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 14rem;
    z-index: 10;
    background: var(--color-surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    padding: var(--space-1);
  }
  .site-nav__item--parent:hover > .site-nav__sub,
  .site-nav__item--parent:focus-within > .site-nav__sub { display: block; }
}

@media (min-width: 68em) and (prefers-reduced-motion: no-preference) {
  .site-nav__link::after { transition: transform .25s ease; }
}

/* Language switch (multilingual sites only; markup: partials/header.html). */
.site-header__inner:has(> .site-lang) > .site-nav { margin-left: auto; }

.site-lang__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-lang__link {
  display: block;
  color: var(--color-muted);
  font-family: var(--font-mono);
  font-size: .8rem;
  letter-spacing: .06em;
  line-height: 1.2;
  text-decoration: none;
  text-transform: uppercase;
  border: 1px solid transparent;
  border-radius: 2px;
  padding: .55em .6em;
}

.site-lang__link:hover { color: var(--color-strong); }

.site-lang__link[aria-current="page"] {
  color: var(--color-strong);
  border-color: rgb(var(--on-dark) / .5);
}

@media (max-width: 67.99em) {
  .site-lang__link { padding: .95em .6em; }
}

/* ------------------------------------------------------- main, page header */

.site-main {
  flex: 1 0 auto;
  padding-block: 0 var(--section-pad);
}

/* A page that ends in a band ends at the band's own padding. */
.site-main:has(.ce-layout__slot--main > .ce-frame--band:last-child) { padding-bottom: 0; }

.page__header {
  padding-top: var(--space-7);
  max-width: var(--measure);
}

.page__title {
  font-size: var(--text-h1);
  line-height: 1;
  margin-bottom: var(--space-3);
}

.page__lead {
  font-size: 1.25rem;
  line-height: 1.5;
  color: var(--color-muted);
  margin: 0;
}

.page__header + .page__content { margin-top: var(--space-5); }

/* Home: the header is visually hidden (above) because the hero is the
   lead; a hero that opens the page sits at the very top. */
.page--home .page__header + .page__content { margin-top: var(--space-6); }

.page--home .page__header + .page__content:is(
  :has(> .ce-layout > .ce-layout__slot--main:first-child > .ce-frame--hero:first-child),
  :has(> .ce-frame--hero:first-child)
) { margin-top: 0; }

/* A page that opens with a hero under a header: the hero moves up under
   the sticky bar, so it still fills exactly the first screen (its own
   top padding is taller than the bar). */
.site-header + .site-main:has(.page__content > .ce-layout > .ce-layout__slot--main:first-child > .ce-frame--hero:first-child) {
  margin-top: calc(-1 * var(--header-h));
}

/* A page that opens with a band: the band brings its own air. */
.page__header + .page__content:has(> .ce-layout > .ce-layout__slot--main:first-child > .ce-frame--band:first-child) { margin-top: var(--space-4); }

.page__content ~ .ce-teasers { margin-top: var(--space-6); }

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

/* Markup: partials/footer.html. With footer content (the Footer cell of
   the backend layout) everything is centred; without, the about column,
   the footer nav and the copyright line. Both end with the credit line. */
.site-footer {
  border-top: 1px solid var(--line);
  color: var(--color-faint);
  font-size: var(--text-sm);
}

.site-footer__inner {
  display: grid;
  gap: var(--space-4);
  padding-block: 3rem 4rem;
}

.site-footer--content .site-footer__inner {
  justify-items: center;
  text-align: center;
  gap: var(--space-3);
}

.site-footer__content { width: 100%; }

.site-footer__content .ce-frame { --frame: var(--space-2); }

.site-footer__content > .ce-frame:first-child { --frame-start: 0px; }

.site-footer__content > .ce-frame:last-child { --frame-end: 0px; }

/* The footer ignores backgrounds: its texts sit on the page. */
.site-footer__content .ce-frame--band {
  --tone: var(--color-accent);
  --tone-rgb: var(--accent-rgb);
  margin-inline: 0;
  padding-inline: 0;
  background: none;
}

.site-footer__content .ce-text {
  max-width: none;
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-faint);
}

.site-footer__content .ce-text p { margin-bottom: var(--space-3); }

.site-footer__content .ce-text > :last-child { margin-bottom: 0; }

/* A list in the footer is a row of links, not a check list. */
.site-footer__content .ce-text ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-1) var(--space-4);
  margin: 0 0 var(--space-3);
  padding: 0;
}

.site-footer__content .ce-text ul > li { padding: 0; margin: 0; }

.site-footer__content .ce-text ul > li::before { display: none; }

.site-footer__content a,
.site-footer__link {
  display: inline-block;
  padding-block: var(--space-1);
  color: var(--color-muted);
  text-decoration: none;
}

.site-footer__content a:hover,
.site-footer__link:hover {
  color: var(--color-strong);
  text-decoration: underline;
}

.site-footer__brand {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: 1.2rem;
  color: var(--color-strong);
  margin-bottom: var(--space-2);
}

.site-footer__about > :not(.site-footer__brand) { margin-bottom: var(--space-2); max-width: 30rem; }

.site-footer__about > :last-child { margin-bottom: 0; }

.site-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-4);
}

.site-footer--content .site-footer__list { justify-content: center; }

.site-footer__copy { margin: 0; }

/* The credit line, last in both shapes: smaller than the footer's own
   text, its two links underlined like any link in a sentence. */
.site-footer__credit {
  margin: var(--space-3) 0 0;
  font-size: var(--text-kicker);
}

.site-footer__credit a { color: var(--color-muted); }

.site-footer__credit a:hover { color: var(--color-strong); }

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

/* Buttons (.ce-btn: the button element, and the submit of deckle-hosted's
   hosted-contact-form element — README "Hosted contact form"). Space
   Grotesk 700, 48px+ tall. Each variant declares background AND colour in
   every state. primary is the tone's colour with dark text (mint, or
   orange inside an orange panel), secondary a light outline, link a
   monospaced underlined text link ("Read more →"). */
.ce-btn {
  display: inline-block;
  font: inherit;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  border: 0;
  border-radius: 2px;
  padding: 1rem 2rem;
}

.ce-btn--primary {
  background: var(--tone);
  color: var(--color-on-tone);
}

.ce-btn--primary:hover {
  background: var(--color-accent-strong);
  color: var(--color-on-tone);
}

.ce-tone--orange .ce-btn--primary:hover { background: var(--color-alert-strong); }

.ce-btn--secondary {
  background: transparent;
  color: var(--color-strong);
  box-shadow: inset 0 0 0 1.5px rgb(var(--on-dark) / .6);
}

.ce-btn--secondary:hover {
  background: transparent;
  color: var(--color-strong);
  box-shadow: inset 0 0 0 1.5px var(--color-strong);
}

.ce-btn--link {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  background: transparent;
  color: var(--tone);
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: var(--text-kicker);
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: .5em 0 2px;
  border-radius: 0;
  border-bottom: 1px solid currentColor;
}

.ce-btn--link:hover {
  background: transparent;
  color: var(--color-strong);
}

/* ==================================================================== */
/* Frames                                                               */
/* ==================================================================== */

/* Every block element is wrapped in one div.ce-frame.ce-frame--<name>,
   emitted by its template; the frame carries the id="c-<uid>" anchor
   (partials/ce/attrs.html). The frame does the spacing, and only the
   frame: --frame of padding above and below, so two neighbours sit
   2 × --frame apart and nothing between elements is ever a margin. The
   first and last frame of a slot drop the outer edge, and the frames next
   to an hr or to another background change theirs (rules under "flat
   column", after the elements). */
.ce-frame {
  --frame-start: var(--frame);
  --frame-end: var(--frame);
  padding-block: var(--frame-start) var(--frame-end);
}

/* A full-bleed frame runs to the viewport edge: the one place a margin is
   used, and it is horizontal. The element inside adds the same value back
   as padding-inline to keep its content on the shell edge. */
.ce-frame--bleed { margin-inline: calc(-1 * var(--bleed)); }

/* The hero does its own padding. */
.ce-frame--hero { padding-block: 0; }

.ce-tone--mint { --tone: var(--color-accent); --tone-rgb: var(--accent-rgb); }

.ce-tone--orange { --tone: var(--color-alert); --tone-rgb: var(--alert-rgb); }

/* ---------------------------------------------------------------- bands */

/* An element whose background is not none (ce/bg.html adds
   ce-frame--band) runs edge to edge like the hero, its content kept on
   the shell edge, and paints its background there; neighbours with the
   same background join into one band. The orange band also turns the
   tone orange for everything inside that has no colour of its own (a
   mono text's bold, the buttons in a body); an element with a tone param
   keeps its own. Inside the two-col columns and in the footer, see
   "backend layouts" and "footer". */
.ce-frame--band {
  margin-inline: calc(-1 * var(--bleed));
  padding-inline: var(--bleed);
}

.ce-frame--bg-grey { background: var(--band-grey); }

.ce-frame--bg-mint {
  --tone: var(--color-accent);
  --tone-rgb: var(--accent-rgb);
  background: var(--band-mint);
}

.ce-frame--bg-orange {
  --tone: var(--color-alert);
  --tone-rgb: var(--alert-rgb);
  background: var(--band-orange);
}

/* ==================================================================== */
/* Element library (ce- vocabulary), one block per element             */
/* ==================================================================== */

/* --- hero and its ticker ----------------------------------------------- */

/* The page lead: at least a screen tall, its content centred on it, the
   kicker, the heading in Space Grotesk at up to 128px, the intro, then
   the orange ticker running edge to edge. With the optional image: a
   photo behind a scrim of at least 80% (below). */
.ce-hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(6rem, 12vw, 8.75rem) var(--bleed) clamp(4rem, 8vw, 6.25rem);
}

.ce-hero__inner { position: relative; z-index: 2; }

.ce-hero__heading {
  font-size: var(--text-hero);
  line-height: .98;
  letter-spacing: -.02em;
  margin: 0;
  text-wrap: wrap;
}

.ce-hero__body {
  margin-top: 2rem;
  max-width: 60rem;
  font-size: clamp(1.125rem, 1rem + .8vw, 1.5rem);
  line-height: 1.5;
  color: var(--color-text);
}

.ce-hero__body > :last-child { margin-bottom: 0; }

.ce-hero__body p:has(.ce-btn) {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-4);
}

.ce-hero--image .ce-hero__img {
  position: absolute;
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* At least 80% of the page colour everywhere, since the text is centred
   on the photo: white on the scrim over a white photo is still 10:1. */
.ce-hero--image::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0;
  background: linear-gradient(rgb(var(--overlay) / .8), rgb(var(--overlay) / .94));
}

.ce-hero--image .ce-ticker { z-index: 2; }

@media (max-width: 47.99em) {
  .ce-hero__heading { font-size: 15vw; }
}

.ce-ticker {
  position: relative;
  margin: 2.75rem calc(-1 * var(--bleed)) 0;
  padding-block: 1rem;
  overflow: hidden;
  background: var(--color-alert);
  color: var(--color-on-tone);
}

.ce-ticker__track {
  display: flex;
  width: max-content;
  animation: ce-ticker 24s linear infinite;
}

.ce-ticker:hover .ce-ticker__track,
.ce-ticker.is-paused .ce-ticker__track { animation-play-state: paused; }

.ce-ticker__list {
  display: flex;
  flex: none;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.ce-ticker__item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 2.75rem;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: var(--text-sm);
  line-height: 1.4;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.ce-ticker__icon { display: block; flex: none; }

.ce-ticker__icon svg { display: block; width: 1.25rem; height: 1.25rem; }

/* The pause button (assets/js/ticker.js unhides it): a dark disc at the
   band's right end showing pause bars, or a play triangle when pressed. */
.ce-ticker__toggle {
  position: absolute;
  right: .5rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--color-bg);
  color: var(--color-alert);
  cursor: pointer;
  outline-color: var(--color-bg);
}

.ce-ticker__toggle[hidden] { display: none; }

.ce-ticker__toggle::before,
.ce-images__toggle::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: .75rem;
  height: .8rem;
  transform: translate(-50%, -50%);
  border-inline: 4px solid currentColor;
}

.ce-ticker__toggle[aria-pressed="true"]::before,
.ce-images__toggle[aria-pressed="true"]::before {
  width: 0;
  height: 0;
  transform: translate(-35%, -50%);
  border-style: solid;
  border-width: .45rem 0 .45rem .75rem;
  border-color: transparent transparent transparent currentColor;
}

@keyframes ce-ticker { to { transform: translateX(-50%); } }

/* --- headline ----------------------------------------------------------- */

/* The kicker (the voice it shares with the hero, under "base") and the
   h2 that open a part of the page. tone colours the kicker; size steps
   the heading up (l, the closing call) or down (s). What follows it sits
   a little closer than two elements do ("flat column"). */
.ce-headline__heading {
  font-size: var(--text-h2);
  line-height: 1.05;
  margin: 0;
}

.ce-headline--l .ce-headline__heading { font-size: clamp(2.25rem, 5.5vw, 4.5rem); line-height: 1.02; }

.ce-headline--s .ce-headline__heading { font-size: clamp(1.75rem, 3.6vw, 2.75rem); line-height: 1.08; }

/* --- hr ----------------------------------------------------------------- */

/* The divider between two parts of the page: a hairline from edge to
   edge with --section-pad of air above and below (its --frame; a slot
   edge or the hero drops the upper half, as for every frame). Its
   background is two halves split at the line: above, the background of
   the element before it (--hr-above), below, that of the element after
   it (--hr-below), set under "flat column" — so two bands meet on the
   line. */
.ce-frame--hr {
  --frame: var(--section-pad);
  background: linear-gradient(var(--hr-above, transparent) var(--frame-start), var(--hr-below, transparent) var(--frame-start));
}

.ce-hr {
  height: 0;
  margin: 0;
  border: 0;
  border-top: 1px solid var(--line);
}

/* --- text --------------------------------------------------------------- */

/* The rte workhorse, capped at the measure. Variants: lead (19px), muted
   (secondary grey), mono (the small monospaced aside; bold in the tone).
   align center puts the block in the middle and centres its lines. */
.ce-text { max-width: var(--measure); }

.ce-text--align-center {
  margin-inline: auto;
  text-align: center;
}

.ce-text > :last-child { margin-bottom: 0; }

.ce-text :is(h2, h3, h4) { margin-top: var(--space-5); }

.ce-text > :is(h2, h3, h4):first-child { margin-top: 0; }

.ce-text--lead { font-size: var(--text-lead); }

.ce-text--muted { color: var(--color-muted); }

.ce-text--mono {
  font-family: var(--font-mono);
  font-size: .9375rem;
  letter-spacing: .02em;
  color: var(--color-muted);
}

.ce-text--mono strong { color: var(--tone); }

.ce-text p:has(> .ce-btn) {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
}

/* Bullet lists in running text are check lists: a mint ring with a tick
   instead of the bullet. */
:is(.ce-text, .ce-video-teaser__body, .ce-cta__body) ul {
  list-style: none;
  padding: 0;
}

:is(.ce-text, .ce-video-teaser__body, .ce-cta__body) ul > li {
  position: relative;
  padding-left: 2rem;
  margin-bottom: .75rem;
}

:is(.ce-text, .ce-video-teaser__body, .ce-cta__body) ul > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .3em;
  width: 1.125rem;
  height: 1.125rem;
  background: var(--color-accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Ccircle cx='9' cy='9' r='8' stroke='%23000' stroke-width='1.4'/%3E%3Cpath d='M5 9l2.5 2.5L13 6' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Ccircle cx='9' cy='9' r='8' stroke='%23000' stroke-width='1.4'/%3E%3Cpath d='M5 9l2.5 2.5L13 6' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

:is(.ce-text, .ce-video-teaser__body, .ce-cta__body) ol { padding-left: 1.4em; }

/* GFM pipe tables in any rich-text body (render-table.html wraps them). */
.ce-table {
  overflow-x: auto;
  margin: 0 0 var(--space-4);
  max-width: 100%;
}

.ce-table__table {
  border-collapse: collapse;
  min-width: 100%;
  font-size: .95rem;
}

.ce-table__table :is(th, td) {
  border: 1px solid var(--line-strong);
  padding: .55rem .8rem;
  text-align: left;
  vertical-align: top;
}

.ce-table__table th {
  background: var(--color-surface);
  color: var(--color-strong);
  font-weight: 600;
}

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

/* One sentence in the display face. plain: the text in the tone colour;
   bar: a tinted box with a 4px tone bar on the left; box: a tone outline
   with an optional monospaced label, bold words in the tone. */
.ce-statement {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: var(--text-statement);
  line-height: 1.25;
  color: var(--color-strong);
}

.ce-statement__body > * { margin: 0 0 .5em; }

.ce-statement__body > :last-child { margin-bottom: 0; }

.ce-statement strong { font-weight: inherit; }

.ce-statement__label {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: .75rem;
  line-height: 1.4;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tone);
  margin: 0 0 .875rem;
}

.ce-statement--plain { color: var(--tone); }

.ce-statement--plain strong { color: inherit; }

.ce-statement--bar,
.ce-statement--box {
  font-size: clamp(1.25rem, 1rem + 1.2vw, 1.75rem);
  line-height: 1.3;
  border-radius: var(--radius-sm);
}

.ce-statement--bar {
  border: 1px solid rgb(var(--tone-rgb) / .45);
  border-left: 4px solid var(--tone);
  background: rgb(var(--tone-rgb) / .16);
  padding: 1.5rem 1.75rem;
}

.ce-statement--box {
  border: 1px solid rgb(var(--tone-rgb) / .35);
  padding: 1.75rem 2rem;
}

:is(.ce-statement--bar, .ce-statement--box) strong { color: var(--tone); }

.ce-statement a { color: inherit; }

/* --- stats -------------------------------------------------------------- */

.ce-stats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
}

@media (min-width: 40em) {
  .ce-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 48em) {
  .ce-stats--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ce-stats--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.ce-stats__item {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 1.75rem;
}

.ce-stats__value {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-size: 2.5rem;
  line-height: 1.1;
  color: var(--color-accent);
  overflow-wrap: anywhere;
}

.ce-stats__label {
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-muted);
}

/* --- mosaic ------------------------------------------------------------- */

/* Two columns of 130px rows on a phone, four of 150px from 48em; small
   1×1, wide 2×1, large 2×2, full the whole row. Photos are cropped to
   their tile; the focus class picks the visible band. */
.ce-mosaic {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 130px;
  grid-auto-flow: dense;
  gap: 12px;
}

.ce-mosaic__tile {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--color-surface);
}

.ce-mosaic__tile--small { grid-column: span 1; }

.ce-mosaic__tile--wide,
.ce-mosaic__tile--full { grid-column: span 2; }

.ce-mosaic__tile--large { grid-column: span 2; grid-row: span 2; }

@media (min-width: 48em) {
  .ce-mosaic {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: 150px;
  }
  .ce-mosaic__tile--full { grid-column: span 4; }
}

.ce-mosaic__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

.ce-mosaic__img--focus-0 { object-position: 50% 0%; }
.ce-mosaic__img--focus-10 { object-position: 50% 10%; }
.ce-mosaic__img--focus-20 { object-position: 50% 20%; }
.ce-mosaic__img--focus-30 { object-position: 50% 30%; }
.ce-mosaic__img--focus-40 { object-position: 50% 40%; }
.ce-mosaic__img--focus-60 { object-position: 50% 60%; }
.ce-mosaic__img--focus-70 { object-position: 50% 70%; }
.ce-mosaic__img--focus-80 { object-position: 50% 80%; }
.ce-mosaic__img--focus-90 { object-position: 50% 90%; }
.ce-mosaic__img--focus-100 { object-position: 50% 100%; }

/* --- cards, with its hidden card rows ----------------------------------- */

/* Outlined boxes that lift on hover: an optional photo on top, an
   optional icon beside the monospaced uppercase heading, plain text. A
   linked card is one <a>. */
.ce-cards {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: 1fr;
}

@media (min-width: 48em) {
  .ce-cards--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ce-cards--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ce-cards--cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 64em) {
  .ce-cards--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.ce-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 2rem;
  color: var(--color-text);
  text-decoration: none;
  transition: transform .2s ease, border-color .2s ease;
}

.ce-card:hover { transform: translateY(-4px); }

a.ce-card:hover { border-color: var(--color-accent); color: var(--color-text); }

.ce-card__img {
  width: calc(100% + 4rem);
  max-width: none;
  margin: -2rem -2rem 1.5rem;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.ce-card__heading {
  display: flex;
  align-items: center;
  gap: .625rem;
  margin: 0 0 1rem;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: .9375rem;
  line-height: 1.4;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-strong);
}

.ce-card__icon { flex: none; display: block; color: var(--color-accent); }

.ce-card__icon svg { display: block; width: 1.375rem; height: 1.375rem; stroke-width: 1.6; }

.ce-card__text {
  margin: 0;
  font-size: 1rem;
  line-height: 1.65;
}

/* --- video-teaser ------------------------------------------------------- */

/* The linked thumbnail card (16:9, a dark scrim, a mint play disc, the
   caption under it) and the body column, side by side from 48em. */
.ce-video-teaser {
  display: grid;
  gap: 2.5rem;
  align-items: center;
}

@media (min-width: 48em) {
  .ce-video-teaser { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
  .ce-video-teaser--right .ce-video-teaser__card { order: 2; }
}

.ce-video-teaser__card {
  display: block;
  overflow: hidden;
  border: 1px solid rgb(var(--on-dark) / .14);
  border-radius: var(--radius);
  color: var(--color-muted);
  text-decoration: none;
  transition: border-color .2s ease;
}

.ce-video-teaser__card:hover { border-color: var(--color-accent); color: var(--color-muted); }

.ce-video-teaser__media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--color-surface);
  overflow: hidden;
}

.ce-video-teaser__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ce-video-teaser__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(var(--overlay) / .35);
}

.ce-video-teaser__play {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: var(--color-accent);
  transform: translate(-50%, -50%);
  transition: transform .15s ease;
}

.ce-video-teaser__play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-38%, -50%);
  border-style: solid;
  border-width: .8rem 0 .8rem 1.35rem;
  border-color: transparent transparent transparent var(--color-on-tone);
}

.ce-video-teaser__card:is(:hover, :focus-visible) .ce-video-teaser__play { transform: translate(-50%, -50%) scale(1.08); }

.ce-video-teaser__caption {
  display: block;
  padding: 1.25rem 1.375rem;
  font-size: var(--text-sm);
  line-height: 1.5;
}

.ce-video-teaser__note { color: var(--color-faint); }

.ce-video-teaser__body { font-size: 1rem; }

.ce-video-teaser__body > :last-child { margin-bottom: 0; }

.ce-video-teaser__body ul { margin-bottom: 1.5rem; }

.ce-video-teaser__body ul > li { margin-bottom: 1rem; }

/* Italic text in the body is the muted aside ("It's a simple idea."). */
.ce-video-teaser__body em {
  color: var(--color-faint);
  font-size: .9375rem;
}

/* --- timeline ----------------------------------------------------------- */

/* Markup: shortcodes/timeline.html — start, one block per track (an h3
   and an ordered list of steps), end. Below 56em two tracks run down the
   screen as two lanes (ce-timeline--lanes: track 1 on the left, track 2
   on the right, every step in a row of its own) and one track as one
   vertical line down the left; from 56em the same markup becomes the
   horizontal diagram: the start point, a fork into the two tracks (track 1
   above, labels under its dots; track 2 below, mirrored), a join, the end
   point. Every line segment draws itself: in the tone of its track once
   reached, else in --rail. Statuses: done (filled), current (filled with
   a ring), upcoming (grey). The end point is white, and orange once every
   step is done. */
.ce-timeline {
  --dot: 1.125rem;
  --stroke: 4px;
  --row: 2.5rem;
  --track: var(--color-accent);
  position: relative;
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.4;
  color: var(--color-muted);
}

.ce-timeline__track--2 { --track: var(--color-alert); }

.ce-timeline__dot {
  display: block;
  width: var(--dot);
  height: var(--dot);
  border-radius: 50%;
  background: rgb(var(--on-dark) / .4);
}

.ce-timeline__start .ce-timeline__dot { background: var(--color-accent); }

.ce-timeline__step--done .ce-timeline__dot { background: var(--track); }

.ce-timeline__step--current .ce-timeline__dot {
  background: var(--track);
  box-shadow: 0 0 0 4px var(--color-bg), 0 0 0 6px var(--track);
}

.ce-timeline__end .ce-timeline__dot {
  background: var(--color-strong);
  box-shadow: 0 0 0 3px var(--color-bg), 0 0 0 5px var(--color-strong);
}

.ce-timeline__end.is-complete .ce-timeline__dot {
  background: var(--color-alert);
  box-shadow: 0 0 0 3px var(--color-bg), 0 0 0 5px var(--color-alert);
}

.ce-timeline__label { margin: 0; }

.ce-timeline__start .ce-timeline__label,
.ce-timeline__end .ce-timeline__label,
:is(.ce-timeline__step--done, .ce-timeline__step--current) .ce-timeline__label { color: var(--color-strong); }

.ce-timeline__end .ce-timeline__label { font-weight: 600; }

.ce-timeline__note {
  margin: 0;
  font-weight: 400;
  font-size: .8125rem;
  color: var(--color-faint);
}

.ce-timeline__track-label {
  margin: 0;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .9375rem;
  line-height: 1.4;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--track);
}

.ce-timeline__steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Vertical (below 56em). Every block is indented past the line; its dot
   sits on the line, and its ::before (and ::after) draw the line's piece
   beside it. */
.ce-timeline__start,
.ce-timeline__end,
.ce-timeline__track-label,
.ce-timeline__step {
  position: relative;
  padding-left: 2.25rem;
}

.ce-timeline__start,
.ce-timeline__end,
.ce-timeline__step { min-height: calc(var(--dot) + .3rem); }

.ce-timeline__start { padding-bottom: 1.5rem; }

.ce-timeline__track-label { padding-block: .5rem 1rem; }

.ce-timeline__step { padding-bottom: 1.25rem; }

.ce-timeline__end { padding-top: .25rem; }

.ce-timeline__start .ce-timeline__dot,
.ce-timeline__end .ce-timeline__dot,
.ce-timeline__step .ce-timeline__dot {
  position: absolute;
  z-index: 1;
  left: 0;
  top: .15rem;
}

.ce-timeline__end .ce-timeline__dot { top: .4rem; }

.ce-timeline__start::after,
.ce-timeline__end::before,
.ce-timeline__track-label::before,
.ce-timeline__step::before,
.ce-timeline__step::after {
  content: "";
  position: absolute;
  left: calc(var(--dot) / 2 - var(--stroke) / 2);
  width: var(--stroke);
  background: var(--rail);
}

.ce-timeline__start::after { top: .5rem; bottom: 0; background: var(--color-accent); }

.ce-timeline__track-label::before { top: 0; bottom: 0; }

.ce-timeline__track.is-started .ce-timeline__track-label::before { background: var(--track); }

.ce-timeline__step::before { top: 0; height: .6rem; }

.ce-timeline__step::after { top: .6rem; bottom: 0; }

.ce-timeline__step:not(.ce-timeline__step--upcoming)::before,
.ce-timeline__step--done::after { background: var(--track); }

.ce-timeline__end::before { top: 0; height: .9rem; }

.ce-timeline__end.is-complete::before { background: var(--color-alert); }

.ce-timeline__track::before,
.ce-timeline__track::after { content: none; }

/* Two lanes (below 56em, two tracks: ce-timeline--lanes). One grid for
   the whole diagram. Columns: lane 1 at the left edge | the labels | lane
   2 at the right edge. Rows: start | fork | track 1 name | track 2 name |
   20 step rows | join | end. Each track is a subgrid over every row from
   the fork to the join, its list a subgrid over the name and step rows,
   and each step sits in the row the template gave it
   (ce-timeline__step--row-<n>, row n + 2 of the list), so no two dots
   share a height and a label may use the full width between the lanes.
   Step rows nobody uses stay empty and take no height. The list draws its
   lane's rail and clips the line pieces its steps draw: a started step's
   piece in (::before) reaches all the way up and every piece out
   (::after) all the way down, so the gap to the step's neighbour in its
   track is covered across the other track's rows, and a later step
   paints over what an earlier one drew past it. Browsers without subgrid
   keep the one vertical line. */
@supports (grid-template-rows: subgrid) {
  @media (max-width: 55.99em) {
    .ce-timeline--lanes {
      --lane: calc(var(--dot) / 2 - var(--stroke) / 2); /* a lane's line, from its edge */
      --fork: 1.5rem;
      --bend: 1.25rem;
      display: grid;
      grid-template-columns: [lane1] var(--dot) [mid] minmax(0, 1fr) [lane2] var(--dot) [edge];
      grid-template-rows: [start] auto [fork] var(--fork) [names] auto auto [steps] repeat(20, auto) [join] var(--fork) [end] auto;
      column-gap: .75rem;
    }

    .ce-timeline--lanes :is(.ce-timeline__start, .ce-timeline__end, .ce-timeline__track-label, .ce-timeline__step) {
      padding: 0;
      min-height: 0;
    }

    .ce-timeline--lanes .ce-timeline__track-label::before { content: none; }

    .ce-timeline--lanes .ce-timeline__dot {
      position: relative;
      top: auto;
      left: auto;
      z-index: 1;
      flex: none;
    }

    /* start and end: centred, the label above the start point and below
       the end point, a line down to the fork and up from the join */
    .ce-timeline--lanes .ce-timeline__start,
    .ce-timeline--lanes .ce-timeline__end {
      grid-column: 1 / -1;
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
    }

    .ce-timeline--lanes .ce-timeline__start { grid-row: start; gap: .5rem; padding-bottom: 1.25rem; }

    .ce-timeline--lanes .ce-timeline__start .ce-timeline__label { order: -1; }

    .ce-timeline--lanes .ce-timeline__end { grid-row: end; padding-top: 1.25rem; }

    .ce-timeline--lanes .ce-timeline__end .ce-timeline__label { margin-top: .75rem; }

    .ce-timeline--lanes .ce-timeline__start::after,
    .ce-timeline--lanes .ce-timeline__end::before {
      left: calc(50% - var(--stroke) / 2);
      height: calc(1.25rem + var(--dot) / 2 + var(--stroke));
    }

    .ce-timeline--lanes .ce-timeline__start::after { top: auto; bottom: calc(-1 * var(--stroke)); }

    .ce-timeline--lanes .ce-timeline__end::before { top: calc(-1 * var(--stroke)); }

    /* the tracks and their lists */
    .ce-timeline--lanes .ce-timeline__track {
      display: grid;
      grid-column: 1 / -1;
      grid-row: fork / end;
      grid-template-columns: subgrid;
      grid-template-rows: subgrid;
    }

    .ce-timeline--lanes .ce-timeline__track-label {
      grid-column: mid;
      grid-row: 2;
      z-index: 1;
      padding-block: .375rem .875rem;
    }

    .ce-timeline--lanes .ce-timeline__track--2 .ce-timeline__track-label { grid-row: 3; text-align: right; }

    .ce-timeline--lanes .ce-timeline__steps {
      display: grid;
      grid-column: 1 / -1;
      grid-row: 2 / -2;
      grid-template-columns: subgrid;
      grid-template-rows: subgrid;
      position: relative;
      overflow-x: visible;
      overflow-y: clip;
    }

    .ce-timeline--lanes .ce-timeline__step {
      display: grid;
      grid-column: 1 / -1;
      grid-template-columns: subgrid;
      min-height: calc(var(--dot) + 1.3rem);
      padding-bottom: 1rem;
    }

    .ce-timeline--lanes .ce-timeline__step--row-1 { grid-row: 3; }
    .ce-timeline--lanes .ce-timeline__step--row-2 { grid-row: 4; }
    .ce-timeline--lanes .ce-timeline__step--row-3 { grid-row: 5; }
    .ce-timeline--lanes .ce-timeline__step--row-4 { grid-row: 6; }
    .ce-timeline--lanes .ce-timeline__step--row-5 { grid-row: 7; }
    .ce-timeline--lanes .ce-timeline__step--row-6 { grid-row: 8; }
    .ce-timeline--lanes .ce-timeline__step--row-7 { grid-row: 9; }
    .ce-timeline--lanes .ce-timeline__step--row-8 { grid-row: 10; }
    .ce-timeline--lanes .ce-timeline__step--row-9 { grid-row: 11; }
    .ce-timeline--lanes .ce-timeline__step--row-10 { grid-row: 12; }
    .ce-timeline--lanes .ce-timeline__step--row-11 { grid-row: 13; }
    .ce-timeline--lanes .ce-timeline__step--row-12 { grid-row: 14; }
    .ce-timeline--lanes .ce-timeline__step--row-13 { grid-row: 15; }
    .ce-timeline--lanes .ce-timeline__step--row-14 { grid-row: 16; }
    .ce-timeline--lanes .ce-timeline__step--row-15 { grid-row: 17; }
    .ce-timeline--lanes .ce-timeline__step--row-16 { grid-row: 18; }
    .ce-timeline--lanes .ce-timeline__step--row-17 { grid-row: 19; }
    .ce-timeline--lanes .ce-timeline__step--row-18 { grid-row: 20; }
    .ce-timeline--lanes .ce-timeline__step--row-19 { grid-row: 21; }
    .ce-timeline--lanes .ce-timeline__step--row-20 { grid-row: 22; }

    .ce-timeline--lanes .ce-timeline__step .ce-timeline__dot { grid-column: lane1; grid-row: 1; margin-top: .15rem; }

    .ce-timeline--lanes .ce-timeline__step .ce-timeline__label { grid-column: mid; grid-row: 1; position: relative; z-index: 1; }

    .ce-timeline--lanes .ce-timeline__track--2 .ce-timeline__step .ce-timeline__dot { grid-column: lane2; }

    .ce-timeline--lanes .ce-timeline__track--2 .ce-timeline__step .ce-timeline__label { text-align: right; }

    /* the lines: the rail, then the steps' pieces (coloured by the rules
       above) */
    .ce-timeline--lanes .ce-timeline__steps::before {
      content: "";
      position: absolute;
      top: 0;
      bottom: 0;
      left: var(--lane);
      width: var(--stroke);
      background: var(--rail);
    }

    .ce-timeline--lanes .ce-timeline__step::before { top: auto; bottom: calc(100% - .15rem - var(--dot) / 2); height: .6rem; }

    .ce-timeline--lanes .ce-timeline__step:not(.ce-timeline__step--upcoming)::before { height: 200vh; }

    .ce-timeline--lanes .ce-timeline__step::after { top: calc(.15rem + var(--dot) / 2); bottom: auto; height: 200vh; }

    .ce-timeline--lanes .ce-timeline__track--2 .ce-timeline__steps::before,
    .ce-timeline--lanes .ce-timeline__track--2 .ce-timeline__step::before,
    .ce-timeline--lanes .ce-timeline__track--2 .ce-timeline__step::after { left: auto; right: var(--lane); }

    /* the fork (the track's ::before) and the join (::after): from the
       centre out to the lane, with a rounded corner */
    .ce-timeline--lanes .ce-timeline__track::before,
    .ce-timeline--lanes .ce-timeline__track::after {
      content: "";
      grid-column: 1 / -1;
      justify-self: start;
      width: calc(50% - var(--lane) + var(--stroke) / 2);
      margin-left: var(--lane);
      border: 0 solid var(--rail);
      border-left-width: var(--stroke);
    }

    .ce-timeline--lanes .ce-timeline__track::before { grid-row: 1; border-top-width: var(--stroke); border-top-left-radius: var(--bend); }

    .ce-timeline--lanes .ce-timeline__track::after { grid-row: -2 / -1; border-bottom-width: var(--stroke); border-bottom-left-radius: var(--bend); }

    .ce-timeline--lanes .ce-timeline__track--2::before,
    .ce-timeline--lanes .ce-timeline__track--2::after {
      justify-self: end;
      margin-left: 0;
      margin-right: var(--lane);
      border-left-width: 0;
      border-right-width: var(--stroke);
    }

    .ce-timeline--lanes .ce-timeline__track--2::before { border-top-left-radius: 0; border-top-right-radius: var(--bend); }

    .ce-timeline--lanes .ce-timeline__track--2::after { border-bottom-left-radius: 0; border-bottom-right-radius: var(--bend); }

    .ce-timeline--lanes .ce-timeline__track.is-started::before { border-color: var(--track); }

    .ce-timeline--lanes .ce-timeline__track.is-complete::after { border-color: var(--track); }
  }
}

/* Horizontal (from 56em): one grid for the whole diagram.
   Columns: start | fork | steps | join | end.
   Rows: track 1 label | track 1 line | track 1 step labels | middle (two
   halves: the fork's and join's turning point is the line between them,
   where the start and end points sit) | track 2 step labels | track 2 line
   | track 2 label. Each track is a subgrid over its four rows and the
   fork, steps and join columns; its ordered list is a subgrid over the
   line and labels rows, so every step's dot lands on the line and its
   label beside it. */
@media (min-width: 56em) {
  .ce-timeline {
    display: grid;
    grid-template-columns: [start] minmax(7rem, 9rem) [fork] 3rem [steps] minmax(0, 1fr) [join] 3rem [end] minmax(7rem, 9rem) [last];
    grid-template-rows: auto var(--row) minmax(2.5rem, auto) 1.25rem 1.25rem minmax(2.5rem, auto) var(--row) auto;
    margin-top: var(--space-5);
  }

  .ce-timeline__start,
  .ce-timeline__end,
  .ce-timeline__track-label,
  .ce-timeline__step {
    padding: 0;
    min-height: 0;
  }

  .ce-timeline__start::after,
  .ce-timeline__end::before,
  .ce-timeline__track-label::before,
  .ce-timeline__step::before,
  .ce-timeline__step::after { content: none; }

  /* start and end: on the turning point, the dot at the outer edge, the
     label above, a line to the fork / from the join */
  .ce-timeline__start,
  .ce-timeline__end {
    grid-row: 4 / 6;
    position: relative;
    display: flex;
    align-items: center;
  }

  .ce-timeline__start { grid-column: start / fork; }

  .ce-timeline__end { grid-column: end / last; justify-content: flex-end; }

  .ce-timeline__start .ce-timeline__dot,
  .ce-timeline__end .ce-timeline__dot {
    position: relative;
    top: auto;
    flex: none;
  }

  .ce-timeline__start::after,
  .ce-timeline__end::before {
    content: "";
    position: static;
    flex: 1;
    width: auto;
    height: var(--stroke);
  }

  .ce-timeline__end::before { order: -1; }

  .ce-timeline__start .ce-timeline__label,
  .ce-timeline__end .ce-timeline__label {
    position: absolute;
    bottom: calc(50% + var(--dot));
  }

  .ce-timeline__start .ce-timeline__label { left: 0; max-width: 100%; }

  .ce-timeline__end .ce-timeline__label { right: 0; text-align: right; max-width: 100%; }

  .ce-timeline__end .ce-timeline__note {
    position: absolute;
    top: calc(50% + var(--dot) / 2 + .6rem);
    right: 0;
    text-align: right;
  }

  /* the tracks */
  .ce-timeline__track {
    display: grid;
    grid-column: fork / end;
    grid-template-columns: subgrid;
    grid-template-rows: subgrid;
    position: relative;
  }

  .ce-timeline__track--1 { grid-row: 1 / 5; }

  .ce-timeline__track--2 { grid-row: 5 / 9; }

  .ce-timeline__track-label { grid-column: 2; padding-bottom: .5rem; }

  .ce-timeline__track--2 .ce-timeline__track-label { grid-row: 4; padding: .5rem 0 0; }

  .ce-timeline__steps {
    display: grid;
    grid-column: 2;
    grid-template-rows: subgrid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }

  .ce-timeline__track--1 .ce-timeline__steps { grid-row: 2 / 4; }

  .ce-timeline__track--2 .ce-timeline__steps { grid-row: 2 / 4; }

  .ce-timeline__step {
    display: grid;
    grid-row: 1 / 3;
    grid-template-rows: subgrid;
    justify-items: center;
    position: relative;
    text-align: center;
  }

  .ce-timeline__step .ce-timeline__dot {
    position: relative;
    top: auto;
    left: auto;
    align-self: center;
  }

  .ce-timeline__step .ce-timeline__label { padding: .5rem .5rem 0; }

  /* track 2 is mirrored: labels above the line */
  .ce-timeline__track--2 .ce-timeline__step .ce-timeline__dot { grid-row: 2; }

  .ce-timeline__track--2 .ce-timeline__step .ce-timeline__label {
    grid-row: 1;
    align-self: end;
    padding: 0 .5rem .5rem;
  }

  /* each step draws the line into its dot (::before) and out of it */
  .ce-timeline__step::before,
  .ce-timeline__step::after {
    content: "";
    position: absolute;
    top: calc(var(--row) / 2 - var(--stroke) / 2);
    bottom: auto;
    width: 50%;
    height: var(--stroke);
  }

  .ce-timeline__track--2 .ce-timeline__step::before,
  .ce-timeline__track--2 .ce-timeline__step::after {
    top: auto;
    bottom: calc(var(--row) / 2 - var(--stroke) / 2);
  }

  .ce-timeline__step::before { left: 0; }

  .ce-timeline__step::after { left: 50%; }

  /* the fork (::before, in the fork column) and the join (::after, in
     the join column): from the track's line to the turning point, with a
     rounded corner */
  .ce-timeline__track::before,
  .ce-timeline__track::after {
    content: "";
    grid-row: 2 / 5;
    border: 0 solid var(--rail);
    margin-top: calc(var(--row) / 2 - var(--stroke) / 2);
    margin-bottom: calc(-1 * var(--stroke) / 2);
  }

  .ce-timeline__track::before {
    grid-column: 1;
    border-top-width: var(--stroke);
    border-left-width: var(--stroke);
    border-top-left-radius: 1.25rem;
  }

  .ce-timeline__track::after {
    grid-column: 3;
    border-top-width: var(--stroke);
    border-right-width: var(--stroke);
    border-top-right-radius: 1.25rem;
  }

  .ce-timeline__track--2::before,
  .ce-timeline__track--2::after {
    grid-row: 1 / 4;
    margin-top: calc(-1 * var(--stroke) / 2);
    margin-bottom: calc(var(--row) / 2 - var(--stroke) / 2);
    border-top-width: 0;
    border-bottom-width: var(--stroke);
  }

  .ce-timeline__track--2::before { border-top-left-radius: 0; border-bottom-left-radius: 1.25rem; }

  .ce-timeline__track--2::after { border-top-right-radius: 0; border-bottom-right-radius: 1.25rem; }

  .ce-timeline__track.is-started::before { border-color: var(--track); }

  .ce-timeline__track.is-complete::after { border-color: var(--track); }

  /* one track only: no fork, everything on one line */
  .ce-timeline--single { grid-template-rows: auto var(--row) minmax(2.5rem, auto); }

  .ce-timeline--single :is(.ce-timeline__start, .ce-timeline__end) { grid-row: 2; }

  .ce-timeline--single .ce-timeline__track { grid-row: 1 / 4; }

  .ce-timeline--single .ce-timeline__track .ce-timeline__track-label { grid-row: 1; padding: 0 0 .5rem; }

  .ce-timeline--single .ce-timeline__track::before,
  .ce-timeline--single .ce-timeline__track::after {
    grid-row: 2;
    align-self: center;
    margin: 0;
    height: var(--stroke);
    border: 0;
    border-radius: 0;
    background: var(--rail);
  }

  .ce-timeline--single .ce-timeline__track.is-started::before,
  .ce-timeline--single .ce-timeline__track.is-complete::after { background: var(--track); }

  .ce-timeline--single .ce-timeline__track--2 .ce-timeline__step .ce-timeline__dot { grid-row: 1; }

  .ce-timeline--single .ce-timeline__track--2 .ce-timeline__step .ce-timeline__label { grid-row: 2; align-self: start; padding: .5rem .5rem 0; }

  .ce-timeline--single .ce-timeline__track--2 .ce-timeline__step::before,
  .ce-timeline--single .ce-timeline__track--2 .ce-timeline__step::after {
    top: calc(var(--row) / 2 - var(--stroke) / 2);
    bottom: auto;
  }
}

/* --- cta ---------------------------------------------------------------- */

/* An outlined panel: the small monospaced heading in the tone, the text,
   the buttons (primary in the tone). */
.ce-cta {
  border: 1px solid rgb(var(--on-dark) / .14);
  border-radius: var(--radius);
  background: rgb(var(--on-dark) / .03);
  padding: 2rem;
}

.ce-cta.ce-tone--orange {
  border-color: rgb(var(--alert-rgb) / .35);
  background: rgb(var(--alert-rgb) / .06);
}

.ce-cta__heading {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: .75rem;
  line-height: 1.4;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tone);
  margin: 0 0 .875rem;
}

.ce-cta__body {
  font-size: var(--text-base);
  line-height: 1.6;
  max-width: var(--measure);
}

.ce-cta__body p { margin-bottom: .875rem; }

.ce-cta__body > :last-child { margin-bottom: 0; }

.ce-cta__body p:has(.ce-btn) {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* --- image, with its hidden img rows ----------------------------------- */

.ce-images {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr;
}

@media (min-width: 40em) {
  .ce-images--cols-2,
  .ce-images--cols-3,
  .ce-images--cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 48em) {
  .ce-images--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ce-images--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.ce-figure { margin: 0; min-width: 0; }

.ce-figure__img {
  width: 100%;
  border-radius: var(--radius);
}

.ce-images--cols-2 .ce-figure__img,
.ce-images--cols-3 .ce-figure__img,
.ce-images--cols-4 .ce-figure__img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.ce-figure a { display: block; border-radius: var(--radius); }

.ce-figure__caption {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-faint);
}

/* The logos variant: a wall of partner logos. Every logo sits whole
   (contain, never cropped) in a 5:2 box, so a logo file drawn on a 5:2
   canvas fills it exactly; a multi-column wall keeps two logos to a row
   on a phone and reaches three from 40em, its column count from 48em.
   In one column the logos stand in a narrow centred column (a single
   partner logo, say) instead of spanning the page. */
.ce-images--logos { gap: var(--space-3) var(--space-4); }

.ce-images--logos.ce-images--cols-1 {
  grid-template-columns: minmax(0, 16rem);
  justify-content: center;
}

.ce-images--logos:not(.ce-images--cols-1) { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (min-width: 40em) {
  .ce-images--logos.ce-images--cols-3,
  .ce-images--logos.ce-images--cols-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 48em) {
  .ce-images--logos.ce-images--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.ce-images--logos .ce-figure__img {
  aspect-ratio: 5 / 2;
  object-fit: contain;
  border-radius: 0;
}

.ce-images--logos .ce-figure a { transition: background-color .15s ease; }

.ce-images--logos .ce-figure a:hover { background: rgb(var(--on-dark) / .05); }

/* The logo cloud (variant logo-cloud) is the logos wall above, except on a
   wide screen whose browser has not asked for reduced motion: there the
   wall dissolves into a drifting cloud. The logos stand in centred, ragged
   rows (widths, nudges and margins from nth-child cycles of 7 and 5, so
   any number of logos scatters without a setting per logo). Each one
   circles on a small orbit of its own at an even pace, never stopping,
   with a slight tilt; the tilt also keeps browsers from moving a slowly
   drifting image in whole-pixel steps. The orbit is a ring seen at an
   angle: passing its bottom a logo comes forward (larger, white), passing
   its top it recedes (smaller, light grey), so depth moves with the drift,
   at its pace, and the logos in front keep changing as their orbits run
   out of step. All of it is one animation per logo, on translate, rotate,
   scale and opacity only. A pointer or keyboard focus inside freezes the
   whole cloud, depth included, lifts the logo under it and dims the rest;
   the pause button (assets/js/logo-cloud.js) freezes it until pressed
   again. Below 64em or under prefers-reduced-motion none of this applies:
   the button stays hidden and the logos stand in the wall. */
.ce-images__toggle { display: none; }

@media (min-width: 64em) and (prefers-reduced-motion: no-preference) {
  .ce-frame:has(> .ce-images--logo-cloud) { position: relative; }

  .ce-images--logo-cloud {
    --cloud-scale: .8;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--space-4);
    padding-block: var(--space-6);
    background: radial-gradient(closest-side, rgb(var(--accent-rgb) / .08), rgb(var(--accent-rgb) / .03) 55%, rgb(var(--accent-rgb) / 0));
  }

  .ce-images--logo-cloud .ce-figure {
    --cloud-w: 12.5rem;
    --cloud-orbit: 17s;
    --cloud-start: 0s;
    --cloud-rx: 14px;
    --cloud-ry: 9px;
    position: relative;
    flex: none;
    width: calc(var(--cloud-w) * var(--cloud-scale));
  }

  .ce-images--logo-cloud .ce-figure > :is(a, img) {
    animation: ce-cloud-orbit var(--cloud-orbit) linear var(--cloud-start) infinite;
  }

  /* Every logo drawn white, so full opacity at the front is white and the
     opacity of the back (see the orbit) a light grey. */
  .ce-images--logo-cloud .ce-figure__img {
    filter: grayscale(1) brightness(1.25);
    transition: opacity .3s ease, scale .3s ease;
  }

  /* Full size from 80em; below it a fifth smaller, so a 64em screen still
     fits four or five to a row. */
  @media (min-width: 80em) {
    .ce-images--logo-cloud { --cloud-scale: 1; }
  }

  /* Width in the row, a cycle of 7: wide, narrow, mid, narrow, wide, mid,
     narrow. */
  .ce-images--logo-cloud .ce-figure:is(:nth-child(7n+1), :nth-child(7n+5)) { --cloud-w: 14rem; }
  .ce-images--logo-cloud .ce-figure:is(:nth-child(7n+2), :nth-child(7n+4), :nth-child(7n+7)) { --cloud-w: 11rem; }

  /* A nudge out of the row line and off the neighbours, a cycle of 5, so
     no two rows line up in columns. */
  .ce-images--logo-cloud .ce-figure:nth-child(5n+1) { top: 6px; }
  .ce-images--logo-cloud .ce-figure:nth-child(5n+2) { top: -26px; margin-left: 2.5rem; }
  .ce-images--logo-cloud .ce-figure:nth-child(5n+3) { top: 16px; }
  .ce-images--logo-cloud .ce-figure:nth-child(5n+4) { top: -10px; margin-right: 3.5rem; }
  .ce-images--logo-cloud .ce-figure:nth-child(5n+5) { top: 28px; margin-left: 1rem; }

  /* The orbit: period and size a cycle of 4, the starting point a cycle
     of 6, and every other logo circles the other way. */
  .ce-images--logo-cloud .ce-figure:nth-child(4n+1) { --cloud-orbit: 15s; --cloud-rx: 14px; --cloud-ry: 9px; }
  .ce-images--logo-cloud .ce-figure:nth-child(4n+2) { --cloud-orbit: 19s; --cloud-rx: 18px; --cloud-ry: 11px; }
  .ce-images--logo-cloud .ce-figure:nth-child(4n+3) { --cloud-orbit: 13s; --cloud-rx: 11px; --cloud-ry: 8px; }
  .ce-images--logo-cloud .ce-figure:nth-child(4n+4) { --cloud-orbit: 21s; --cloud-rx: 16px; --cloud-ry: 12px; }

  .ce-images--logo-cloud .ce-figure:nth-child(6n+1) { --cloud-start: -2s; }
  .ce-images--logo-cloud .ce-figure:nth-child(6n+2) { --cloud-start: -11s; }
  .ce-images--logo-cloud .ce-figure:nth-child(6n+3) { --cloud-start: -6s; }
  .ce-images--logo-cloud .ce-figure:nth-child(6n+4) { --cloud-start: -15s; }
  .ce-images--logo-cloud .ce-figure:nth-child(6n+5) { --cloud-start: -4s; }
  .ce-images--logo-cloud .ce-figure:nth-child(6n+6) { --cloud-start: -9s; }

  .ce-images--logo-cloud .ce-figure:nth-child(2n) > :is(a, img) { animation-direction: reverse; }

  .ce-images--logo-cloud:is(:hover, :focus-within, .is-paused) .ce-figure > :is(a, img) {
    animation-play-state: paused;
  }

  .ce-images--logo-cloud .ce-figure a:hover { background: none; }

  .ce-images--logo-cloud .ce-figure:has(a:is(:hover, :focus-visible)) { z-index: 1; }

  .ce-images--logo-cloud:has(a:is(:hover, :focus-visible)) .ce-figure__img { opacity: .3; }

  .ce-images--logo-cloud a:is(:hover, :focus-visible) .ce-figure__img { opacity: 1; scale: 1.15; }

  /* The pause button: a small dark disc at the cloud's lower right, its
     glyph shared with the ticker's (pause bars, or a play triangle when
     pressed). */
  .ce-images__toggle:not([hidden]) {
    display: block;
    position: absolute;
    right: 0;
    bottom: var(--frame);
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    background: var(--color-bg);
    color: var(--color-muted);
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
  }

  .ce-images__toggle:hover { color: var(--color-strong); border-color: var(--rail); }
}

/* One lap of a logo's orbit: an ellipse of --cloud-rx by --cloud-ry walked
   through twelve points at an even pace, tilting up to .8deg either way.
   Its depth follows the same lap: largest and fully opaque at the bottom
   (25%), smallest and faintest at the top (75%), between them along a
   sine. */
@keyframes ce-cloud-orbit {
  0%, 100% { translate: var(--cloud-rx) 0; rotate: 0deg; scale: .88; opacity: .85; }
  8.333% { translate: calc(.866 * var(--cloud-rx)) calc(.5 * var(--cloud-ry)); scale: 1; opacity: .925; }
  16.667% { translate: calc(.5 * var(--cloud-rx)) calc(.866 * var(--cloud-ry)); scale: 1.088; opacity: .98; }
  25% { translate: 0 var(--cloud-ry); rotate: .8deg; scale: 1.12; opacity: 1; }
  33.333% { translate: calc(-.5 * var(--cloud-rx)) calc(.866 * var(--cloud-ry)); scale: 1.088; opacity: .98; }
  41.667% { translate: calc(-.866 * var(--cloud-rx)) calc(.5 * var(--cloud-ry)); scale: 1; opacity: .925; }
  50% { translate: calc(-1 * var(--cloud-rx)) 0; rotate: 0deg; scale: .88; opacity: .85; }
  58.333% { translate: calc(-.866 * var(--cloud-rx)) calc(-.5 * var(--cloud-ry)); scale: .76; opacity: .775; }
  66.667% { translate: calc(-.5 * var(--cloud-rx)) calc(-.866 * var(--cloud-ry)); scale: .672; opacity: .72; }
  75% { translate: 0 calc(-1 * var(--cloud-ry)); rotate: -.8deg; scale: .64; opacity: .7; }
  83.333% { translate: calc(.5 * var(--cloud-rx)) calc(-.866 * var(--cloud-ry)); scale: .672; opacity: .72; }
  91.667% { translate: calc(.866 * var(--cloud-rx)) calc(-.5 * var(--cloud-ry)); scale: .76; opacity: .775; }
}

/* --- section lists ---------------------------------------------------- */

.ce-teasers__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fill, minmax(min(18rem, 100%), 1fr));
}

.ce-teasers__item {
  min-width: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.ce-teasers__title {
  font-size: var(--text-h4);
  line-height: 1.25;
  margin: 0;
}

.ce-teasers__link {
  color: inherit;
  text-decoration: none;
}

.ce-teasers__link::after {
  content: " \2192";
  content: " \2192" / "";
  color: var(--color-accent);
}

.ce-teasers__link:hover {
  color: var(--color-accent);
  text-decoration: underline;
}

.ce-teasers__summary {
  color: var(--color-muted);
  margin: 0;
  font-size: .95rem;
}

/* --- ce-form (deckle-hosted's hosted-contact-form) -------------------- */

/* deckle ships no contact form. These ce-form* classes are the contract of
   deckle-hosted's hosted-contact-form element (README "Hosted contact
   form") and must survive a redesign. An outlined panel; inputs are 16px
   so phones do not zoom on focus; focus is the mint ring with the border
   turning mint. */
.ce-form {
  max-width: var(--measure);
  border: 1px solid rgb(var(--on-dark) / .14);
  border-radius: var(--radius);
  background: rgb(var(--on-dark) / .03);
  padding: var(--space-4);
}

.ce-form__heading {
  font-size: var(--text-h3);
  margin-bottom: var(--space-4);
}

.ce-form__form {
  display: grid;
  gap: var(--space-3);
}

.ce-form__field { margin: 0; min-width: 0; }

.ce-form__label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-kicker);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: var(--space-1);
}

.ce-form__input,
.ce-form__textarea {
  display: block;
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--color-strong);
  background: var(--color-bg);
  border: 1px solid rgb(var(--on-dark) / .25);
  border-radius: 2px;
  padding: .75em .9em;
}

.ce-form__input:focus-visible,
.ce-form__textarea:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 0;
  border-color: var(--color-accent);
}

.ce-form__textarea {
  resize: vertical;
  min-height: 8rem;
}

.ce-form__submit {
  justify-self: start;
  margin-top: var(--space-1);
}

@media (min-width: 48em) {
  .ce-form { padding: var(--space-5); }
  .ce-form__form { grid-template-columns: 1fr 1fr; }
  .ce-form__field:has(.ce-form__textarea),
  .ce-form__submit { grid-column: 1 / -1; }
}

/* ------------------------------------------------------- backend layouts */

/* The slot grids emitted by layouts/partials/backendlayouts/*.html. This
   block comes after the frames and elements on purpose: the slot-edge
   rules below must win over the frame's own padding. */
.ce-layout__slot > .ce-frame:first-child { --frame-start: 0px; }

.ce-layout__slot > .ce-frame:last-child { --frame-end: 0px; }

/* The flat column. A slot's elements sit 2 × --frame apart; a part of the
   page opens with a headline and ends at an hr, which brings the big air
   itself, so the frames on either side of it drop their padding towards
   it. A frame without ce-frame--band (the hero, an element on no
   background) counts as the page background, so where two neighbours'
   backgrounds differ without an hr between them, both get --section-pad
   on that side: the same air as an hr, without the line. The selectors are ordered and
   weighted on purpose: each later group outranks the one before. */

/* Wide blocks that follow running text get a little more air above. */
.ce-layout__slot > .ce-frame--text + :is(.ce-frame--video-teaser, .ce-frame--timeline, .ce-frame--cards) { --frame-start: var(--space-4); }

/* A headline sits closer to what follows it. */
.ce-layout__slot > .ce-frame--headline { --frame-end: var(--space-3); }

.ce-layout__slot > .ce-frame--headline + .ce-frame:not(.ce-frame--hr) { --frame-start: 0px; }

/* Next to an hr: the hr's padding is the gap. Right under the hero, whose
   own padding is the air, the hr drops its upper half. */
.ce-layout__slot > .ce-frame--hr + .ce-frame { --frame-start: 0px; }

.ce-layout__slot > .ce-frame:has(+ .ce-frame--hr) { --frame-end: 0px; }

.ce-layout__slot > .ce-frame--hero + .ce-frame--hr { --frame-start: 0px; }

/* Each half of an hr takes its neighbour's background. */
.ce-layout__slot > .ce-frame--bg-grey + .ce-frame--hr { --hr-above: var(--band-grey); }

.ce-layout__slot > .ce-frame--bg-mint + .ce-frame--hr { --hr-above: var(--band-mint); }

.ce-layout__slot > .ce-frame--bg-orange + .ce-frame--hr { --hr-above: var(--band-orange); }

.ce-layout__slot > .ce-frame--hr:has(+ .ce-frame--bg-grey) { --hr-below: var(--band-grey); }

.ce-layout__slot > .ce-frame--hr:has(+ .ce-frame--bg-mint) { --hr-below: var(--band-mint); }

.ce-layout__slot > .ce-frame--hr:has(+ .ce-frame--bg-orange) { --hr-below: var(--band-orange); }

/* Two different backgrounds meet without an hr. */
.ce-layout__slot > .ce-frame:not(.ce-frame--band, .ce-frame--hr) + .ce-frame--band,
.ce-layout__slot > .ce-frame--bg-grey + .ce-frame:not(.ce-frame--bg-grey, .ce-frame--hr),
.ce-layout__slot > .ce-frame--bg-mint + .ce-frame:not(.ce-frame--bg-mint, .ce-frame--hr),
.ce-layout__slot > .ce-frame--bg-orange + .ce-frame:not(.ce-frame--bg-orange, .ce-frame--hr) { --frame-start: var(--section-pad); }

.ce-layout__slot > .ce-frame:not(.ce-frame--band, .ce-frame--hr):has(+ .ce-frame--band),
.ce-layout__slot > .ce-frame--bg-grey:has(+ .ce-frame:not(.ce-frame--bg-grey, .ce-frame--hr)),
.ce-layout__slot > .ce-frame--bg-mint:has(+ .ce-frame:not(.ce-frame--bg-mint, .ce-frame--hr)),
.ce-layout__slot > .ce-frame--bg-orange:has(+ .ce-frame:not(.ce-frame--bg-orange, .ce-frame--hr)) { --frame-end: var(--section-pad); }

/* A band at the top or the foot of a slot keeps its air inside. */
.ce-layout__slot > .ce-frame--band:first-child { --frame-start: var(--section-pad); }

.ce-layout__slot > .ce-frame--band:last-child { --frame-end: var(--section-pad); }

.ce-layout__cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  min-width: 0;
}

.ce-layout__slot--main,
.ce-layout__slot--sidebar { min-width: 0; }

/* The 3fr/1fr split is the colspan 3 + colspan 1 that two-col.yaml
   declares to the editor — keep them equal. */
@media (min-width: 48em) {
  .ce-layout--two-col .ce-layout__cols { grid-template-columns: 3fr 1fr; }
}

/* Inside the columns a viewport bleed would cross the neighbouring
   column: bands stay inside their column. */
.ce-layout__cols .ce-frame--bleed { margin-inline: 0; }

.ce-layout__cols .ce-hero { padding-inline: 0; }

.ce-layout__cols .ce-frame--band {
  margin-inline: 0;
  padding-inline: var(--space-4);
}

.ce-layout__cols .ce-ticker { margin-inline: 0; }

.ce-layout__slot--sidebar :is(.ce-cards, .ce-images, .ce-stats, .ce-video-teaser) { grid-template-columns: 1fr; }

.ce-layout__slot--sidebar .ce-headline__heading { font-size: var(--text-h3); }

/* -------------------------------------------------------------- lightbox */

.ce-lightbox__dialog {
  padding: 0;
  border: 0;
  width: 100vw;
  height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  background: transparent;
  color: var(--color-strong);
}

.ce-lightbox__dialog[open] {
  display: flex;
  align-items: center;
  justify-content: center;
}

.ce-lightbox__dialog::backdrop { background: rgb(var(--overlay) / .94); }

.ce-lightbox__img {
  display: block;
  max-width: min(92vw, 90rem);
  max-height: 86vh;
  width: auto;
  height: auto;
  border-radius: var(--radius);
}

.ce-lightbox__close,
.ce-lightbox__prev,
.ce-lightbox__next {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  background: rgb(var(--on-dark) / .12);
  color: var(--color-strong);
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  font: inherit;
  font-size: 1.5rem;
  line-height: 1;
}

.ce-lightbox__close:hover,
.ce-lightbox__prev:hover,
.ce-lightbox__next:hover {
  background: rgb(var(--on-dark) / .24);
  color: var(--color-strong);
}

.ce-lightbox__close { top: var(--space-3); right: var(--space-3); }

.ce-lightbox__prev,
.ce-lightbox__next {
  top: 50%;
  transform: translateY(-50%);
}

.ce-lightbox__prev { left: var(--space-3); }

.ce-lightbox__next { right: var(--space-3); }

.ce-lightbox__prev[hidden],
.ce-lightbox__next[hidden] { display: none; }

/* ------------------------------------------------------- feature bundles */

/* The news and categories bundles (not installed today) reuse the teaser
   markup above and inherit the tokens; these few rules lay out their
   extra parts. */
.ce-news-list__image,
.news-item__image {
  width: 100%;
  object-fit: cover;
  border-radius: var(--radius);
}

.news-item__media { margin: 0 0 var(--space-5); }

:is(.ce-news-list__date, .news-item__date, .news-item__author) {
  display: block;
  color: var(--color-faint);
  font-family: var(--font-mono);
  font-size: var(--text-kicker);
}

:is(.ce-news-list__categories, .news-item__categories) {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
}

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-5);
}

.pager__pages {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.pager__number,
.pager__link {
  display: inline-block;
  min-width: 2.75rem;
  padding: .6em .8em;
  text-align: center;
}

.pager__number[aria-current="page"] {
  color: var(--color-strong);
  font-weight: 600;
  text-decoration: none;
}

.pager__link[aria-disabled="true"] { color: var(--color-faint); }

/* --------------------------------------------------------- reduced motion */

/* No marquee (the lines wrap, centred, and the copies go), no lifts, no
   fades. The loader never starts (baseof.html checks the same query). */
@media (prefers-reduced-motion: reduce) {
  .ce-ticker__track {
    animation: none;
    width: auto;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: .5rem;
  }
  .ce-ticker__list { flex: 1 1 100%; min-width: 0; flex-wrap: wrap; justify-content: center; row-gap: .5rem; }
  .ce-ticker__list[aria-hidden="true"] { display: none; }
  .ce-ticker__item { white-space: normal; padding-inline: 1.5rem; }
  .ce-card,
  .ce-video-teaser__play { transition: none; }
  .ce-card:hover { transform: none; }
  .ce-video-teaser__card:is(:hover, :focus-visible) .ce-video-teaser__play { transform: translate(-50%, -50%); }
  .is-revealed .site-main,
  .is-revealed .site-footer { animation: none; }
}
