/* Generated from src/data/theme.json — edit that file, not this one. */
@font-face {
  font-family: "Fredoka";
  src: url("/assets/fonts/fredoka-variable.woff2") format("woff2");
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Source Sans 3";
  src: url("/assets/fonts/source-sans-3-variable.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;

  --color-forest-950: #0a2117;
  --color-forest-900: #0f3324;
  --color-forest-800: #123b2a;
  --color-forest-700: #14432c;
  --color-forest-600: #1a5839;
  --color-forest-500: #226b46;
  --color-forest-300: #8fbda4;
  --color-forest-100: #dcebe2;
  --color-forest-075: #e0e6e1;
  --color-forest-050: #eef6f1;
  --color-forest-025: #f4f8f5;
  --color-gold-800: #6f5212;
  --color-gold-700: #8a6718;
  --color-gold-600: #a97f24;
  --color-gold-500: #c8a13a;
  --color-gold-400: #d9b348;
  --color-gold-300: #eac95e;
  --color-gold-100: #f0dca6;
  --color-gold-050: #fbf5e6;
  --color-bronze-900: #1b130d;
  --color-bronze-800: #241a12;
  --color-bronze-700: #33251a;
  --color-bronze-600: #4a3626;
  --color-bronze-500: #6b4f34;
  --color-bronze-400: #c08a3e;
  --color-bronze-300: #d9a45c;
  --color-bronze-200: #c9b79a;
  --color-bronze-100: #e8d3b0;
  --color-cream-000: #fffaf0;
  --color-cream-050: #fbf3e0;
  --color-cream-100: #f3e7d3;
  --color-cream-200: #f5e9cf;
  --color-cream-300: #eddfc0;
  --color-cream-400: #e4d5b4;
  --color-cream-500: #b5a179;
  --color-earth-950: #2b1f0b;
  --color-earth-900: #3d2c10;
  --color-earth-700: #6a5426;
  --color-earth-500: #9a8352;
  --color-char-950: #0c0a06;
  --color-char-900: #14110a;
  --color-char-800: #1e1a10;
  --color-char-700: #2a2416;
  --color-char-600: #3a3018;
  --color-char-500: #2f2819;
  --color-char-300: #7a6c47;
  --color-char-100: #a8986d;
  --color-char-050: #d8c79a;
  --color-char-000: #f5ecd2;
  --color-plum-600: #4a1a4f;
  --color-plum-100: #e9dcea;
  --color-ink-950: #0f0f0f;
  --color-ink-900: #14201a;
  --color-ink-700: #2c3a33;
  --color-ink-500: #566159;
  --color-ink-400: #6e7a70;
  --color-ink-350: #77817a;
  --color-ink-300: #8e988f;
  --color-ink-200: #b9bdb5;
  --color-ink-100: #dfe3dd;
  --color-paper-000: #ffffff;
  --color-paper-050: #fcfbf8;
  --color-paper-100: #f5f4ee;
  --color-paper-200: #eceae1;
  --color-paper-300: #e6e4dd;
  --color-danger-900: #3a1c16;
  --color-danger-600: #9b2c2c;
  --color-danger-300: #f0a99e;
  --color-danger-050: #fdf1f1;
  --color-success-900: #16301f;
  --color-success-600: #226b46;
  --color-success-300: #8fbda4;
  --color-success-050: #eaf5ee;
  --color-transparent: transparent;
  --color-ruby-025: #fdf5f6;
  --color-ruby-050: #fbecef;
  --color-ruby-075: #f2dbdf;
  --color-ruby-500: #a32540;
  --color-ruby-600: #8a1d34;
  --color-ruby-700: #70172a;
  --color-ruby-800: #57111f;
  --color-earth-025: #faf7f1;
  --color-earth-050: #f5efe4;
  --color-earth-075: #e7dcc8;
  --color-earth-600: #7a6230;
  --color-earth-800: #54401c;
  --font-display: 'Fredoka', 'Trebuchet MS', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Source Sans 3', 'Source Sans Pro', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, 'SFMono-Regular', 'Cascadia Mono', Menlo, monospace;
  --text-2xs: 0.75rem;
  --text-xs: 0.8125rem;
  --text-sm: 0.9375rem;
  --text-md: 1.0625rem;
  --text-lg: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
  --text-xl: clamp(1.3125rem, 1.16rem + 0.7vw, 1.625rem);
  --text-2xl: clamp(1.5rem, 1.25rem + 1.15vw, 2.125rem);
  --text-3xl: clamp(1.875rem, 1.42rem + 2.1vw, 3rem);
  --text-4xl: clamp(2.25rem, 1.5rem + 3.4vw, 4rem);
  --text-display: clamp(2.5rem, 1.5rem + 4.4vw, 4.75rem);
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --leading-tight: 1.06;
  --leading-snug: 1.2;
  --leading-normal: 1.45;
  --leading-relaxed: 1.65;
  --tracking-tight: -0.015em;
  --tracking-normal: 0;
  --tracking-wide: 0.06em;
  --tracking-wider: 0.14em;
  --tracking-widest: 0.3em;
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2rem;
  --space-xl: 3rem;
  --space-2xl: 4rem;
  --space-3xl: clamp(3.5rem, 2rem + 6vw, 7rem);
  --space-gutter: clamp(1.25rem, 0.6rem + 2.6vw, 3rem);
  --radius-none: 0;
  --radius-sm: 0.375rem;
  --radius-md: 0.75rem;
  --radius-lg: 1.25rem;
  --radius-xl: 2rem;
  --radius-pill: 999rem;
  --radius-circle: 50%;
  --shadow-none: none;
  --shadow-sm: 0 1px 2px rgb(20 32 26 / 6%), 0 1px 3px rgb(20 32 26 / 4%);
  --shadow-md: 0 6px 18px -8px rgb(20 32 26 / 18%), 0 2px 6px -2px rgb(20 32 26 / 8%);
  --shadow-lg: 0 24px 60px -28px rgb(20 32 26 / 34%), 0 8px 20px -12px rgb(20 32 26 / 14%);
  --shadow-focus: 0 0 0 3px rgb(200 161 58 / 55%);
  --layout-page-max: 78rem;
  --layout-wide-max: 90rem;
  --layout-measure: 38rem;
  --layout-measure-wide: 52rem;
  --layout-header-height: 4.5rem;
  --layout-rule-thickness: 3px;
  --motion-instant: 80ms;
  --motion-fast: 180ms;
  --motion-base: 280ms;
  --motion-slow: 620ms;
  --motion-cinematic: 1400ms;
  --motion-ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --motion-ease-in-out: cubic-bezier(0.65, 0.05, 0.36, 1);
  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 100;
  --z-overlay: 800;
  --z-modal: 900;
  --z-toast: 1000;

  --surface-page: var(--color-paper-000);
  --surface-raised: var(--color-paper-000);
  --surface-muted: var(--color-paper-100);
  --surface-sunken: var(--color-paper-200);
  --text-primary: var(--color-ink-900);
  --text-secondary: var(--color-ink-500);
  --text-muted: var(--color-ink-400);
  --text-brand: var(--color-earth-700);
  --text-accent: var(--color-gold-700);
  --text-danger: var(--color-danger-600);
  --border-subtle: var(--color-paper-300);
  --border-strong: var(--color-ink-350);
  --border-brand: var(--color-earth-700);
  --border-accent: var(--color-gold-500);
  --surface-feature: var(--color-earth-025);
  --surface-feature-deep: var(--color-paper-000);
  --surface-feature-soft: var(--color-earth-050);
  --on-feature: var(--color-ink-900);
  --on-feature-muted: var(--color-ink-500);
  --on-feature-accent: var(--color-gold-700);
  --on-feature-brand: var(--color-earth-700);
  --border-feature: var(--color-earth-075);
  --overlay-feature-surface: rgb(255 255 255 / 92%);
  --overlay-feature-border: rgb(20 32 26 / 12%);
  --overlay-feature-border-strong: rgb(20 32 26 / 30%);
  --surface-footer: var(--color-paper-100);
  --on-footer: var(--color-ink-900);
  --on-footer-muted: var(--color-ink-500);
  --on-footer-accent: var(--color-gold-700);
  --border-footer: var(--color-paper-300);
  --surface-signature: var(--color-earth-900);
  --on-signature: var(--color-paper-000);
  --accent-primary: var(--color-earth-700);
  --accent-primary-hover: var(--color-earth-800);
  --accent-secondary: var(--color-gold-500);
  --accent-secondary-hover: var(--color-gold-600);
  --accent-heritage: var(--color-plum-600);
  --on-accent-primary: var(--color-paper-000);
  --on-accent-secondary: var(--color-ink-900);
  --surface-accent-soft: var(--color-gold-050);
  --surface-danger-soft: var(--color-danger-050);
  --surface-success-soft: var(--color-success-050);
  --brand-mark: var(--color-ink-950);
  --media-scrim-rgb: 15 51 36;
  --scrim: rgb(43 31 11 / 82%);
  --on-scrim: var(--color-paper-000);
  --theme-opposite: earth;

  --print-page-size: A4;
  --print-margin: 13mm;
  --print-body-size: 10.2pt;
  --print-body-leading: 1.42;
}

/* No explicit choice: follow the system, using the theme nominated for it. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;

    --surface-page: var(--color-forest-900);
    --surface-raised: var(--color-forest-800);
    --surface-muted: var(--color-forest-800);
    --surface-sunken: var(--color-forest-950);
    --text-primary: var(--color-paper-050);
    --text-secondary: var(--color-forest-100);
    --text-muted: var(--color-forest-300);
    --text-brand: var(--color-gold-300);
    --text-accent: var(--color-gold-300);
    --text-danger: var(--color-danger-300);
    --border-subtle: var(--color-forest-700);
    --border-strong: var(--color-forest-300);
    --border-brand: var(--color-gold-400);
    --border-accent: var(--color-gold-500);
    --surface-feature: var(--color-forest-600);
    --surface-feature-deep: var(--color-forest-950);
    --surface-feature-soft: var(--color-forest-800);
    --on-feature: var(--color-paper-000);
    --on-feature-muted: var(--color-forest-100);
    --on-feature-accent: var(--color-gold-300);
    --on-feature-brand: var(--color-gold-300);
    --border-feature: rgb(255 255 255 / 20%);
    --overlay-feature-surface: rgb(255 255 255 / 9%);
    --overlay-feature-border: rgb(255 255 255 / 20%);
    --overlay-feature-border-strong: rgb(255 255 255 / 46%);
    --surface-footer: var(--color-forest-950);
    --on-footer: var(--color-paper-050);
    --on-footer-muted: var(--color-forest-100);
    --on-footer-accent: var(--color-gold-300);
    --border-footer: rgb(255 255 255 / 16%);
    --surface-signature: var(--color-forest-700);
    --on-signature: var(--color-paper-000);
    --accent-primary: var(--color-gold-400);
    --accent-primary-hover: var(--color-gold-300);
    --accent-secondary: var(--color-gold-400);
    --accent-secondary-hover: var(--color-gold-300);
    --accent-heritage: var(--color-gold-300);
    --on-accent-primary: var(--color-forest-950);
    --on-accent-secondary: var(--color-forest-950);
    --surface-accent-soft: var(--color-forest-800);
    --surface-danger-soft: var(--color-danger-900);
    --surface-success-soft: var(--color-success-900);
    --brand-mark: var(--color-paper-000);
    --media-scrim-rgb: 10 33 23;
    --scrim: rgb(6 20 14 / 74%);
    --on-scrim: var(--color-paper-000);
    --theme-opposite: paper;
  }
}

:root[data-theme="paper"],
[data-theme-scope="paper"] {
  color-scheme: light;

  --surface-page: var(--color-paper-000);
  --surface-raised: var(--color-paper-000);
  --surface-muted: var(--color-paper-100);
  --surface-sunken: var(--color-paper-200);
  --text-primary: var(--color-ink-900);
  --text-secondary: var(--color-ink-500);
  --text-muted: var(--color-ink-400);
  --text-brand: var(--color-forest-600);
  --text-accent: var(--color-gold-700);
  --text-danger: var(--color-danger-600);
  --border-subtle: var(--color-paper-300);
  --border-strong: var(--color-ink-350);
  --border-brand: var(--color-forest-600);
  --border-accent: var(--color-gold-500);
  --surface-feature: var(--color-forest-025);
  --surface-feature-deep: var(--color-paper-000);
  --surface-feature-soft: var(--color-forest-050);
  --on-feature: var(--color-ink-900);
  --on-feature-muted: var(--color-ink-500);
  --on-feature-accent: var(--color-gold-700);
  --on-feature-brand: var(--color-forest-600);
  --border-feature: var(--color-forest-075);
  --overlay-feature-surface: rgb(255 255 255 / 92%);
  --overlay-feature-border: rgb(20 32 26 / 12%);
  --overlay-feature-border-strong: rgb(20 32 26 / 30%);
  --surface-footer: var(--color-paper-100);
  --on-footer: var(--color-ink-900);
  --on-footer-muted: var(--color-ink-500);
  --on-footer-accent: var(--color-gold-700);
  --border-footer: var(--color-paper-300);
  --surface-signature: var(--color-forest-700);
  --on-signature: var(--color-paper-000);
  --accent-primary: var(--color-forest-600);
  --accent-primary-hover: var(--color-forest-700);
  --accent-secondary: var(--color-gold-500);
  --accent-secondary-hover: var(--color-gold-600);
  --accent-heritage: var(--color-plum-600);
  --on-accent-primary: var(--color-paper-000);
  --on-accent-secondary: var(--color-ink-900);
  --surface-accent-soft: var(--color-gold-050);
  --surface-danger-soft: var(--color-danger-050);
  --surface-success-soft: var(--color-success-050);
  --brand-mark: var(--color-ink-950);
  --media-scrim-rgb: 15 51 36;
  --scrim: rgb(10 33 23 / 82%);
  --on-scrim: var(--color-paper-000);
  --theme-opposite: forest;
}

:root[data-theme="paper-earth"],
[data-theme-scope="paper-earth"] {
  color-scheme: light;

  --surface-page: var(--color-paper-000);
  --surface-raised: var(--color-paper-000);
  --surface-muted: var(--color-paper-100);
  --surface-sunken: var(--color-paper-200);
  --text-primary: var(--color-ink-900);
  --text-secondary: var(--color-ink-500);
  --text-muted: var(--color-ink-400);
  --text-brand: var(--color-earth-700);
  --text-accent: var(--color-gold-700);
  --text-danger: var(--color-danger-600);
  --border-subtle: var(--color-paper-300);
  --border-strong: var(--color-ink-350);
  --border-brand: var(--color-earth-700);
  --border-accent: var(--color-gold-500);
  --surface-feature: var(--color-earth-025);
  --surface-feature-deep: var(--color-paper-000);
  --surface-feature-soft: var(--color-earth-050);
  --on-feature: var(--color-ink-900);
  --on-feature-muted: var(--color-ink-500);
  --on-feature-accent: var(--color-gold-700);
  --on-feature-brand: var(--color-earth-700);
  --border-feature: var(--color-earth-075);
  --overlay-feature-surface: rgb(255 255 255 / 92%);
  --overlay-feature-border: rgb(20 32 26 / 12%);
  --overlay-feature-border-strong: rgb(20 32 26 / 30%);
  --surface-footer: var(--color-paper-100);
  --on-footer: var(--color-ink-900);
  --on-footer-muted: var(--color-ink-500);
  --on-footer-accent: var(--color-gold-700);
  --border-footer: var(--color-paper-300);
  --surface-signature: var(--color-earth-900);
  --on-signature: var(--color-paper-000);
  --accent-primary: var(--color-earth-700);
  --accent-primary-hover: var(--color-earth-800);
  --accent-secondary: var(--color-gold-500);
  --accent-secondary-hover: var(--color-gold-600);
  --accent-heritage: var(--color-plum-600);
  --on-accent-primary: var(--color-paper-000);
  --on-accent-secondary: var(--color-ink-900);
  --surface-accent-soft: var(--color-gold-050);
  --surface-danger-soft: var(--color-danger-050);
  --surface-success-soft: var(--color-success-050);
  --brand-mark: var(--color-ink-950);
  --media-scrim-rgb: 15 51 36;
  --scrim: rgb(43 31 11 / 82%);
  --on-scrim: var(--color-paper-000);
  --theme-opposite: earth;
}

:root[data-theme="paper-ruby"],
[data-theme-scope="paper-ruby"] {
  color-scheme: light;

  --surface-page: var(--color-paper-000);
  --surface-raised: var(--color-paper-000);
  --surface-muted: var(--color-paper-100);
  --surface-sunken: var(--color-paper-200);
  --text-primary: var(--color-ink-900);
  --text-secondary: var(--color-ink-500);
  --text-muted: var(--color-ink-400);
  --text-brand: var(--color-ruby-700);
  --text-accent: var(--color-gold-700);
  --text-danger: var(--color-danger-600);
  --border-subtle: var(--color-paper-300);
  --border-strong: var(--color-ink-350);
  --border-brand: var(--color-ruby-700);
  --border-accent: var(--color-gold-500);
  --surface-feature: var(--color-ruby-025);
  --surface-feature-deep: var(--color-paper-000);
  --surface-feature-soft: var(--color-ruby-050);
  --on-feature: var(--color-ink-900);
  --on-feature-muted: var(--color-ink-500);
  --on-feature-accent: var(--color-gold-700);
  --on-feature-brand: var(--color-ruby-700);
  --border-feature: var(--color-ruby-075);
  --overlay-feature-surface: rgb(255 255 255 / 92%);
  --overlay-feature-border: rgb(20 32 26 / 12%);
  --overlay-feature-border-strong: rgb(20 32 26 / 30%);
  --surface-footer: var(--color-paper-100);
  --on-footer: var(--color-ink-900);
  --on-footer-muted: var(--color-ink-500);
  --on-footer-accent: var(--color-gold-700);
  --border-footer: var(--color-paper-300);
  --surface-signature: var(--color-ruby-800);
  --on-signature: var(--color-paper-000);
  --accent-primary: var(--color-ruby-700);
  --accent-primary-hover: var(--color-ruby-800);
  --accent-secondary: var(--color-gold-500);
  --accent-secondary-hover: var(--color-gold-600);
  --accent-heritage: var(--color-plum-600);
  --on-accent-primary: var(--color-paper-000);
  --on-accent-secondary: var(--color-ink-900);
  --surface-accent-soft: var(--color-ruby-050);
  --surface-danger-soft: var(--color-danger-050);
  --surface-success-soft: var(--color-success-050);
  --brand-mark: var(--color-ink-950);
  --media-scrim-rgb: 15 51 36;
  --scrim: rgb(46 14 20 / 82%);
  --on-scrim: var(--color-paper-000);
  --theme-opposite: earth;
}

:root[data-theme="forest"],
[data-theme-scope="forest"] {
  color-scheme: dark;

  --surface-page: var(--color-forest-900);
  --surface-raised: var(--color-forest-800);
  --surface-muted: var(--color-forest-800);
  --surface-sunken: var(--color-forest-950);
  --text-primary: var(--color-paper-050);
  --text-secondary: var(--color-forest-100);
  --text-muted: var(--color-forest-300);
  --text-brand: var(--color-gold-300);
  --text-accent: var(--color-gold-300);
  --text-danger: var(--color-danger-300);
  --border-subtle: var(--color-forest-700);
  --border-strong: var(--color-forest-300);
  --border-brand: var(--color-gold-400);
  --border-accent: var(--color-gold-500);
  --surface-feature: var(--color-forest-600);
  --surface-feature-deep: var(--color-forest-950);
  --surface-feature-soft: var(--color-forest-800);
  --on-feature: var(--color-paper-000);
  --on-feature-muted: var(--color-forest-100);
  --on-feature-accent: var(--color-gold-300);
  --on-feature-brand: var(--color-gold-300);
  --border-feature: rgb(255 255 255 / 20%);
  --overlay-feature-surface: rgb(255 255 255 / 9%);
  --overlay-feature-border: rgb(255 255 255 / 20%);
  --overlay-feature-border-strong: rgb(255 255 255 / 46%);
  --surface-footer: var(--color-forest-950);
  --on-footer: var(--color-paper-050);
  --on-footer-muted: var(--color-forest-100);
  --on-footer-accent: var(--color-gold-300);
  --border-footer: rgb(255 255 255 / 16%);
  --surface-signature: var(--color-forest-700);
  --on-signature: var(--color-paper-000);
  --accent-primary: var(--color-gold-400);
  --accent-primary-hover: var(--color-gold-300);
  --accent-secondary: var(--color-gold-400);
  --accent-secondary-hover: var(--color-gold-300);
  --accent-heritage: var(--color-gold-300);
  --on-accent-primary: var(--color-forest-950);
  --on-accent-secondary: var(--color-forest-950);
  --surface-accent-soft: var(--color-forest-800);
  --surface-danger-soft: var(--color-danger-900);
  --surface-success-soft: var(--color-success-900);
  --brand-mark: var(--color-paper-000);
  --media-scrim-rgb: 10 33 23;
  --scrim: rgb(6 20 14 / 74%);
  --on-scrim: var(--color-paper-000);
  --theme-opposite: paper;
}

:root[data-theme="earth"],
[data-theme-scope="earth"] {
  color-scheme: dark;

  --surface-page: var(--color-bronze-800);
  --surface-raised: var(--color-bronze-700);
  --surface-muted: var(--color-bronze-700);
  --surface-sunken: var(--color-bronze-900);
  --text-primary: var(--color-cream-100);
  --text-secondary: var(--color-bronze-100);
  --text-muted: var(--color-bronze-200);
  --text-brand: var(--color-gold-300);
  --text-accent: var(--color-bronze-300);
  --text-danger: var(--color-danger-300);
  --border-subtle: var(--color-bronze-600);
  --border-strong: var(--color-bronze-200);
  --border-brand: var(--color-bronze-400);
  --border-accent: var(--color-gold-300);
  --surface-feature: var(--color-bronze-600);
  --surface-feature-deep: var(--color-bronze-900);
  --surface-feature-soft: var(--color-bronze-700);
  --on-feature: var(--color-cream-000);
  --on-feature-muted: var(--color-bronze-100);
  --on-feature-accent: var(--color-gold-300);
  --on-feature-brand: var(--color-gold-300);
  --border-feature: rgb(255 243 224 / 22%);
  --overlay-feature-surface: rgb(255 243 224 / 10%);
  --overlay-feature-border: rgb(255 243 224 / 22%);
  --overlay-feature-border-strong: rgb(255 243 224 / 48%);
  --surface-footer: var(--color-bronze-900);
  --on-footer: var(--color-cream-100);
  --on-footer-muted: var(--color-bronze-100);
  --on-footer-accent: var(--color-gold-300);
  --border-footer: rgb(255 243 224 / 18%);
  --surface-signature: var(--color-bronze-600);
  --on-signature: var(--color-cream-000);
  --accent-primary: var(--color-bronze-400);
  --accent-primary-hover: var(--color-bronze-300);
  --accent-secondary: var(--color-gold-300);
  --accent-secondary-hover: var(--color-gold-100);
  --accent-heritage: var(--color-bronze-300);
  --on-accent-primary: var(--color-bronze-900);
  --on-accent-secondary: var(--color-bronze-900);
  --surface-accent-soft: var(--color-bronze-700);
  --surface-danger-soft: var(--color-danger-900);
  --surface-success-soft: var(--color-success-900);
  --brand-mark: var(--color-gold-300);
  --media-scrim-rgb: 27 19 13;
  --scrim: rgb(20 12 6 / 76%);
  --on-scrim: var(--color-cream-000);
  --theme-opposite: paper-earth;
}

:root[data-theme="gold-light"],
[data-theme-scope="gold-light"] {
  color-scheme: light;

  --surface-page: var(--color-cream-050);
  --surface-raised: var(--color-cream-000);
  --surface-muted: var(--color-cream-200);
  --surface-sunken: var(--color-cream-300);
  --text-primary: var(--color-earth-900);
  --text-secondary: var(--color-earth-700);
  --text-muted: var(--color-earth-500);
  --text-brand: var(--color-gold-800);
  --text-accent: var(--color-gold-800);
  --text-danger: var(--color-danger-600);
  --border-subtle: var(--color-cream-400);
  --border-strong: var(--color-bronze-500);
  --border-brand: var(--color-gold-800);
  --border-accent: var(--color-gold-500);
  --surface-feature: var(--color-cream-100);
  --surface-feature-deep: var(--color-cream-000);
  --surface-feature-soft: var(--color-cream-200);
  --on-feature: var(--color-earth-900);
  --on-feature-muted: var(--color-earth-700);
  --on-feature-accent: var(--color-gold-800);
  --on-feature-brand: var(--color-gold-800);
  --border-feature: var(--color-cream-400);
  --overlay-feature-surface: rgb(255 250 240 / 78%);
  --overlay-feature-border: rgb(61 44 16 / 14%);
  --overlay-feature-border-strong: rgb(61 44 16 / 32%);
  --surface-footer: var(--color-cream-200);
  --on-footer: var(--color-earth-900);
  --on-footer-muted: var(--color-earth-700);
  --on-footer-accent: var(--color-gold-800);
  --border-footer: var(--color-cream-400);
  --surface-signature: var(--color-earth-950);
  --on-signature: var(--color-cream-000);
  --accent-primary: var(--color-gold-800);
  --accent-primary-hover: var(--color-earth-700);
  --accent-secondary: var(--color-gold-500);
  --accent-secondary-hover: var(--color-gold-400);
  --accent-heritage: var(--color-bronze-500);
  --on-accent-primary: var(--color-cream-000);
  --on-accent-secondary: var(--color-earth-950);
  --surface-accent-soft: var(--color-cream-000);
  --surface-danger-soft: var(--color-danger-050);
  --surface-success-soft: var(--color-success-050);
  --brand-mark: var(--color-earth-950);
  --media-scrim-rgb: 43 31 11;
  --scrim: rgb(27 19 13 / 78%);
  --on-scrim: var(--color-cream-000);
  --theme-opposite: gold-dark;
}

:root[data-theme="gold-dark"],
[data-theme-scope="gold-dark"] {
  color-scheme: dark;

  --surface-page: var(--color-char-900);
  --surface-raised: var(--color-char-800);
  --surface-muted: var(--color-char-700);
  --surface-sunken: var(--color-char-950);
  --text-primary: var(--color-char-000);
  --text-secondary: var(--color-char-050);
  --text-muted: var(--color-char-100);
  --text-brand: var(--color-gold-300);
  --text-accent: var(--color-gold-300);
  --text-danger: var(--color-danger-300);
  --border-subtle: var(--color-char-500);
  --border-strong: var(--color-char-300);
  --border-brand: var(--color-gold-400);
  --border-accent: var(--color-gold-300);
  --surface-feature: var(--color-char-600);
  --surface-feature-deep: var(--color-char-950);
  --surface-feature-soft: var(--color-char-700);
  --on-feature: var(--color-char-000);
  --on-feature-muted: var(--color-char-050);
  --on-feature-accent: var(--color-gold-300);
  --on-feature-brand: var(--color-gold-300);
  --border-feature: rgb(255 246 214 / 22%);
  --overlay-feature-surface: rgb(255 246 214 / 9%);
  --overlay-feature-border: rgb(255 246 214 / 22%);
  --overlay-feature-border-strong: rgb(255 246 214 / 48%);
  --surface-footer: var(--color-char-950);
  --on-footer: var(--color-char-000);
  --on-footer-muted: var(--color-char-050);
  --on-footer-accent: var(--color-gold-300);
  --border-footer: rgb(255 246 214 / 18%);
  --surface-signature: var(--color-char-600);
  --on-signature: var(--color-char-000);
  --accent-primary: var(--color-gold-400);
  --accent-primary-hover: var(--color-gold-300);
  --accent-secondary: var(--color-gold-300);
  --accent-secondary-hover: var(--color-gold-100);
  --accent-heritage: var(--color-gold-300);
  --on-accent-primary: var(--color-char-950);
  --on-accent-secondary: var(--color-char-950);
  --surface-accent-soft: var(--color-char-700);
  --surface-danger-soft: var(--color-danger-900);
  --surface-success-soft: var(--color-success-900);
  --brand-mark: var(--color-gold-300);
  --media-scrim-rgb: 12 10 6;
  --scrim: rgb(8 6 3 / 78%);
  --on-scrim: var(--color-char-000);
  --theme-opposite: gold-light;
}

/*
 * Paper is paper. Whichever theme the visitor was reading in, the printed sheet
 * uses the default theme's colours, so a brochure printed from the site always
 * looks like the brochure.
 */
@media print {
  :root {
    color-scheme: light;

    --surface-page: var(--color-paper-000);
    --surface-raised: var(--color-paper-000);
    --surface-muted: var(--color-paper-100);
    --surface-sunken: var(--color-paper-200);
    --text-primary: var(--color-ink-900);
    --text-secondary: var(--color-ink-500);
    --text-muted: var(--color-ink-400);
    --text-brand: var(--color-earth-700);
    --text-accent: var(--color-gold-700);
    --text-danger: var(--color-danger-600);
    --border-subtle: var(--color-paper-300);
    --border-strong: var(--color-ink-350);
    --border-brand: var(--color-earth-700);
    --border-accent: var(--color-gold-500);
    --surface-feature: var(--color-earth-025);
    --surface-feature-deep: var(--color-paper-000);
    --surface-feature-soft: var(--color-earth-050);
    --on-feature: var(--color-ink-900);
    --on-feature-muted: var(--color-ink-500);
    --on-feature-accent: var(--color-gold-700);
    --on-feature-brand: var(--color-earth-700);
    --border-feature: var(--color-earth-075);
    --overlay-feature-surface: rgb(255 255 255 / 92%);
    --overlay-feature-border: rgb(20 32 26 / 12%);
    --overlay-feature-border-strong: rgb(20 32 26 / 30%);
    --surface-footer: var(--color-paper-100);
    --on-footer: var(--color-ink-900);
    --on-footer-muted: var(--color-ink-500);
    --on-footer-accent: var(--color-gold-700);
    --border-footer: var(--color-paper-300);
    --surface-signature: var(--color-earth-900);
    --on-signature: var(--color-paper-000);
    --accent-primary: var(--color-earth-700);
    --accent-primary-hover: var(--color-earth-800);
    --accent-secondary: var(--color-gold-500);
    --accent-secondary-hover: var(--color-gold-600);
    --accent-heritage: var(--color-plum-600);
    --on-accent-primary: var(--color-paper-000);
    --on-accent-secondary: var(--color-ink-900);
    --surface-accent-soft: var(--color-gold-050);
    --surface-danger-soft: var(--color-danger-050);
    --surface-success-soft: var(--color-success-050);
    --brand-mark: var(--color-ink-950);
    --media-scrim-rgb: 15 51 36;
    --scrim: rgb(43 31 11 / 82%);
    --on-scrim: var(--color-paper-000);
    --theme-opposite: earth;
  }
}

[data-theme-option="paper"] {
  --swatch-background: var(--color-paper-000);
  --swatch-accent: var(--color-forest-600);
  --swatch-mark: var(--color-ink-950);
}

[data-theme-option="paper-earth"] {
  --swatch-background: var(--color-paper-000);
  --swatch-accent: var(--color-earth-700);
  --swatch-mark: var(--color-ink-950);
}

[data-theme-option="paper-ruby"] {
  --swatch-background: var(--color-paper-000);
  --swatch-accent: var(--color-ruby-700);
  --swatch-mark: var(--color-ink-950);
}

[data-theme-option="forest"] {
  --swatch-background: var(--color-forest-900);
  --swatch-accent: var(--color-gold-400);
  --swatch-mark: var(--color-paper-000);
}

[data-theme-option="earth"] {
  --swatch-background: var(--color-bronze-800);
  --swatch-accent: var(--color-bronze-400);
  --swatch-mark: var(--color-gold-300);
}

[data-theme-option="gold-light"] {
  --swatch-background: var(--color-cream-050);
  --swatch-accent: var(--color-gold-600);
  --swatch-mark: var(--color-earth-950);
}

[data-theme-option="gold-dark"] {
  --swatch-background: var(--color-char-900);
  --swatch-accent: var(--color-gold-300);
  --swatch-mark: var(--color-gold-300);
}

/*
 * Stylesheet entry point.
 *
 * The build resolves these imports in order and prepends the design tokens
 * compiled from src/data/theme.json, so no file below declares a raw colour,
 * size or duration — every value is a custom property.
 *
 * `@media (width >= 48rem)` and friends are breakpoint names from theme.json; the build
 * substitutes the real widths, because a media query cannot read a variable.
 */
/* A small, opinionated reset. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--layout-header-height) + var(--space-md));
}

body {
  min-height: 100svh;
  background: var(--surface-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

ul[class],
ol[class] {
  list-style: none;
  padding: 0;
}

a {
  color: inherit;
}

:where(a):focus-visible,
:where(button):focus-visible,
:where(input):focus-visible,
:where(textarea):focus-visible,
:where(select):focus-visible,
:where(summary):focus-visible,
:where([tabindex]):focus-visible {
  outline: 2px solid var(--accent-secondary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::selection {
  background: var(--accent-secondary);
  color: var(--on-accent-secondary);
}

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

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Type scale and the shared text shapes. */
h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

h1 {
  font-size: var(--text-4xl);
  line-height: var(--leading-tight);
}

h2 {
  font-size: var(--text-3xl);
}

h3 {
  font-size: var(--text-xl);
}

h4 {
  font-size: var(--text-lg);
}

p {
  text-wrap: pretty;
}

strong {
  font-weight: var(--weight-semibold);
}

.eyebrow {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-accent);
}

.prose {
  max-width: var(--layout-measure-wide);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.prose > * + * {
  margin-block-start: var(--space-md);
}

.pull-quote {
  margin-block: var(--space-xl);
  padding-inline-start: var(--space-md);
  border-inline-start: var(--layout-rule-thickness) solid var(--border-accent);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
  color: var(--text-brand);
}

.source-note {
  max-width: var(--layout-measure-wide);
  margin-block-start: var(--space-xl);
  margin-inline: auto;
  padding-block-start: var(--space-md);
  border-block-start: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  text-align: center;
}

.empty-state {
  padding: var(--space-xl);
  border: 1px dashed var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-muted);
  color: var(--text-secondary);
  text-align: center;
}

/*
 * The line the brochure carries beside its masthead. Every page states what it
 * is for before it says anything else — the device that makes the site read as
 * one printed piece rather than a set of screens.
 */
.strapline {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  margin-block-end: var(--space-sm);
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-accent);
}

.strapline::before {
  content: "";
  flex: none;
  inline-size: 2rem;
  block-size: var(--layout-rule-thickness);
  border-radius: var(--radius-pill);
  background: var(--accent-secondary);
}



/* The few utilities the components actually share. */

/*
 * A component's own `display` would otherwise beat the user agent's rule for
 * [hidden], which silently reveals anything the markup hid. Progressive
 * enhancement depends on this holding.
 */
[hidden] {
  display: none !important;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  inset-block-start: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  z-index: var(--z-toast);
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  color: var(--on-accent-primary);
  font-size: var(--text-sm);
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--motion-fast) var(--motion-ease-out);
}

.skip-link:focus {
  transform: translateY(0);
}

.rule {
  display: block;
  inline-size: 3.5rem;
  block-size: var(--layout-rule-thickness);
  margin-block: var(--space-sm);
  border-radius: var(--radius-pill);
  background: var(--accent-secondary);
}

.rule--center {
  margin-inline: auto;
}

.rule--brand {
  background: var(--accent-primary);
}

/* Medallions take their colours from the theme's own accents, so a new theme
   restyles every icon roundel without touching a component. */
[data-accent="accent"] {
  --medallion-surface: var(--surface-accent-soft);
  --medallion-ink: var(--text-accent);
  --medallion-border: color-mix(in srgb, var(--border-accent) 42%, transparent);
}

[data-accent="brand"] {
  --medallion-surface: var(--surface-feature-soft);
  --medallion-ink: var(--text-brand);
  --medallion-border: color-mix(in srgb, var(--border-brand) 42%, transparent);
}

.signature-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-sm);
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
}

.signature-strip__divider {
  color: var(--accent-secondary);
}

/*
 * The four words as four parts, at the size they carry the page. Each word is
 * its own unit with a gold divider between — the same device as the footer
 * strip and the printed colophon, scaled up.
 */
/*
 * This row is the lockup's tagline in everything but name, so it keeps the
 * lockup's measure: sized from the same symbol variable the extra-large lockup
 * uses, not from a clamp of its own. Set independently it ran to 1.75x the
 * width of ABUSUA AKOMA and hung off both ends of the mark.
 *
 * --signature-fit is the one number to turn: the share of the wordmark's
 * font-size this row is set at. Tracking and gaps are in em so they scale with
 * it, which is what holds the fitted width steady at every viewport.
 */
.signature-strip--hero {
  --signature-fit: 0.29;

  gap: 0.3em 0.85em;
  font-size: calc(var(--lockup-xl-symbol) * 0.38 * var(--signature-fit));
  font-weight: var(--weight-medium);
  letter-spacing: 0.06em;
}

.signature-strip--hero .signature-strip__divider {
  font-weight: var(--weight-regular);
  opacity: 0.7;
}

/*
 * Four words in a row leave a dangling divider when they wrap, so below the
 * small breakpoint they become a two-by-two block and the dividers go.
 *
 * Two columns need roughly twice the type to fill the same measure as one row,
 * so the fit is reset here. The gap is in em for the same reason it is above:
 * it has to scale with the type, or the fitted width drifts with the viewport.
 */
@media (width < 36rem) {
  .signature-strip--hero {
    --signature-fit: 0.58;

    display: grid;
    grid-template-columns: repeat(2, auto);
    gap: 0.35em 1.1em;
    justify-content: center;
  }

  .signature-strip--hero .signature-strip__divider {
    display: none;
  }
}


/* Horizontal measure. */
.container {
  inline-size: 100%;
  margin-inline: auto;
  padding-inline: var(--space-gutter);
}

.container--page {
  max-inline-size: var(--layout-page-max);
}

.container--wide {
  max-inline-size: var(--layout-wide-max);
}

.container--narrow {
  max-inline-size: calc(var(--layout-measure-wide) + var(--space-gutter) * 2);
}

/* Vertical rhythm and the surface each section sits on. */
.section {
  position: relative;
  padding-block: var(--space-3xl);
  background: var(--surface-page);
  color: var(--text-primary);
}

.section--bleed {
  padding-block: 0;
}

.section--raised { background: var(--surface-raised); }
.section--muted { background: var(--surface-muted); }
.section--sunken { background: var(--surface-sunken); }
.section--accent-soft { background: var(--surface-accent-soft); }
.section--none { background: transparent; }

.section--feature { background: var(--surface-feature); }
.section--feature-deep { background: var(--surface-feature-deep); }
.section--feature-soft { background: var(--surface-feature-soft); }

/*
 * Inside a feature band the whole token set is remapped to that band's own
 * declared foregrounds, rather than each component being told about it.
 * Anything using --text-secondary, a subtle border or a raised surface keeps
 * working — and because the theme states both sides of the pairing, a band that
 * is white on Paper and deep green on Forest needs no special case here.
 */
.section--feature,
.section--feature-deep,
.section--feature-soft {
  --text-primary: var(--on-feature);
  --text-secondary: var(--on-feature-muted);
  --text-muted: var(--on-feature-muted);
  --text-brand: var(--on-feature-brand);
  --text-accent: var(--on-feature-accent);
  --border-subtle: var(--border-feature);
  --border-strong: var(--overlay-feature-border-strong);
  --surface-raised: var(--overlay-feature-surface);
  --surface-muted: var(--overlay-feature-surface);

  color: var(--on-feature);
}

/* Consecutive sections sharing a surface should not double their padding. */
.section + .section:where(.section--page, .section--muted, .section--raised) {
  padding-block-start: 0;
}

.section > .container > * + * {
  margin-block-start: var(--space-xl);
}

.grid-columns {
  --grid-columns: 3;

  display: grid;
  gap: var(--space-md);
  grid-template-columns: 1fr;
}

@media (width >= 36rem) {
  .grid-columns {
    grid-template-columns: repeat(min(2, var(--grid-columns)), minmax(0, 1fr));
  }
}

@media (width >= 64rem) {
  .grid-columns {
    grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  }
}

/* Site header. Collapses to a disclosure panel below the large breakpoint. */
.masthead {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
  background: color-mix(in srgb, var(--surface-page) 88%, transparent);
  border-block-end: 1px solid var(--border-subtle);
  backdrop-filter: blur(14px);
}

.masthead__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
  justify-content: space-between;
  min-block-size: var(--layout-header-height);
  padding-block: var(--space-2xs);
}

/* The mark has its own token so each theme states it outright: black on paper,
   white on the green field, gold on the earth and gold themes. */
.masthead__brand {
  color: var(--brand-mark);
  text-decoration: none;
}

.masthead__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  color: var(--text-brand);
}

.masthead__toggle-close { display: none; }
.masthead__toggle[aria-expanded="true"] .masthead__toggle-open { display: none; }
.masthead__toggle[aria-expanded="true"] .masthead__toggle-close { display: block; }

.masthead__panel {
  display: none;
  flex-basis: 100%;
  flex-direction: column;
  gap: var(--space-md);
  padding-block: var(--space-md);
}

.masthead__panel.is-open {
  display: flex;
}

.masthead__nav-list,
.masthead__utility ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: 0;
  list-style: none;
}

/*
 * PINNED PAGES, WHILE THE MENU IS A DRAWER
 *
 * A chapter of About is two taps and a scroll away on a phone, which is far
 * enough that the section reads as somewhere things are hidden. The few worth
 * reaching directly sit under their section here.
 *
 * Pills rather than more menu lines: they are visibly a different kind of thing
 * from the sections above them, and three of them fit on one line where three
 * more list items would make the menu a page of its own.
 */
.masthead__pins {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs);
  margin: var(--space-3xs) 0 var(--space-2xs);
  padding: 0;
  list-style: none;
}

.masthead__pin {
  display: inline-block;
  padding: var(--space-3xs) var(--space-2xs);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  font-size: var(--text-xs);
  text-decoration: none;
}

.masthead__pin:hover,
.masthead__pin:focus-visible {
  border-color: var(--accent-primary);
  color: var(--text-brand);
}

.masthead__nav-link {
  display: block;
  padding: var(--space-2xs) 0;
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  text-decoration: none;
  color: var(--text-primary);
  border-block-end: 2px solid transparent;
  transition: color var(--motion-fast) var(--motion-ease-out),
    border-color var(--motion-fast) var(--motion-ease-out);
}

.masthead__nav-link:hover,
.masthead__nav-link.is-current {
  color: var(--text-brand);
  border-block-end-color: var(--accent-secondary);
}

.masthead__aside {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
}

.masthead__utility ul {
  flex-direction: row;
  gap: var(--space-sm);
}

.masthead__utility .masthead__nav-link {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

@media (width >= 64rem) {
  .masthead__toggle {
    display: none;
  }

  .masthead__panel {
    display: flex;
    flex-basis: auto;
    flex-direction: row;
    gap: var(--space-lg);
    align-items: center;
    padding-block: 0;
  }

  .masthead__nav-list {
    flex-direction: row;
    gap: var(--space-md);
  }

  .masthead__nav-link {
    padding-block: var(--space-2xs);
  }

  /*
   * Not on a wide screen. Up here the menu is a row across the top, and a list
   * hanging off one item in it would be a dropdown — a different thing, with
   * its own behaviour to get right. The hub page is one click away and already
   * shows its chapters, which is enough when there is room for it.
   */
  .masthead__pins {
    display: none;
  }
}

/* Site footer. */
/*
 * The footer is its own region, with its own declared foregrounds, so a theme
 * can keep it light. The signature strip is the one band that stays brand
 * coloured in every theme — the device the printed piece ends on.
 */
.site-footer {
  --text-secondary: var(--on-footer-muted);
  --text-accent: var(--on-footer-accent);
  --border-subtle: var(--border-footer);

  padding-block: var(--space-2xl) 0;
  /* A light theme can give the footer the same surface as the section above it,
     so the boundary is drawn rather than implied. */
  border-block-start: 1px solid var(--border-footer);
  background: var(--surface-footer);
  color: var(--on-footer);
}

.site-footer__inner {
  display: grid;
  gap: var(--space-xl);
  align-items: start;
}

.site-footer__promise {
  max-inline-size: var(--layout-measure);
  margin-block-start: var(--space-sm);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  color: var(--on-footer-accent);
}

.site-footer__nav {
  display: grid;
  gap: var(--space-lg);
}

.site-footer__heading {
  margin-block-end: var(--space-2xs);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--on-footer-accent);
}

.site-footer__group ul {
  display: grid;
  gap: var(--space-3xs);
  padding: 0;
  list-style: none;
}

.site-footer__group a {
  color: var(--on-footer-muted);
  text-decoration: none;
  transition: color var(--motion-fast) var(--motion-ease-out);
}

.site-footer__group a:hover {
  color: var(--on-footer);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

.site-footer__signature {
  margin-block-start: var(--space-xl);
  padding-block: var(--space-sm);
  background: var(--surface-signature);
  color: var(--on-signature);
  max-inline-size: none;
  padding-inline: var(--space-gutter);
}

.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-md) var(--space-lg);
  font-size: var(--text-xs);
  color: var(--on-footer-muted);
}

.site-footer__statements {
  display: grid;
  gap: var(--space-3xs);
  max-inline-size: 42rem;
  padding: 0;
  list-style: none;
}

.site-footer__tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  align-items: center;
}

.site-footer__tool {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: center;
  color: inherit;
  font-size: var(--text-xs);
  text-decoration: none;
  transition: color var(--motion-fast) var(--motion-ease-out);
}

.site-footer__tool:hover {
  color: var(--on-footer-accent);
}

.site-footer__top-icon {
  rotate: 180deg;
}

@media (width >= 48rem) {
  .site-footer__nav {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (width >= 64rem) {
  .site-footer__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  }
}


/*
 * Theme switcher.
 *
 * Each option paints its own theme's colours: the swatch reads the
 * --swatch-* variables the token compiler emits per theme, so this file never
 * names a colour and a new theme needs no change here.
 */
.theme-switch {
  position: relative;
}

.theme-switch__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  transition: border-color var(--motion-fast) var(--motion-ease-out);
}

.theme-switch__trigger:hover {
  border-color: var(--border-accent);
}

.theme-switch__swatch {
  position: relative;
  flex: none;
  inline-size: 1.05rem;
  block-size: 1.05rem;
  overflow: hidden;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-circle);
  background: var(--swatch-background, var(--surface-page));
}

/* The accent shows as the lower-right half, the brand mark as a centre dot. */
.theme-switch__swatch::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, transparent 50%, var(--swatch-accent, var(--accent-secondary)) 50%);
}

.theme-switch__swatch::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 0.3rem;
  block-size: 0.3rem;
  translate: -50% -50%;
  border-radius: var(--radius-circle);
  background: var(--swatch-mark, var(--text-primary));
}

/* "Match my device" has no theme of its own, so it shows a neutral split. */
[data-theme-option="system"] .theme-switch__swatch {
  background: linear-gradient(135deg, var(--surface-page) 50%, var(--text-primary) 50%);
}

[data-theme-option="system"] .theme-switch__swatch::before,
[data-theme-option="system"] .theme-switch__swatch::after {
  content: none;
}

.theme-switch__menu {
  position: absolute;
  inset-block-start: calc(100% + var(--space-2xs));
  inset-inline-end: 0;
  z-index: var(--z-overlay);
  display: grid;
  gap: var(--space-3xs);
  min-inline-size: 12rem;
  padding: var(--space-2xs);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg);
}

.theme-switch__option {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  padding: var(--space-3xs) var(--space-2xs);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  text-align: start;
  color: var(--text-primary);
  transition: background-color var(--motion-fast) var(--motion-ease-out);
}

.theme-switch__option:hover {
  background: var(--surface-muted);
}

.theme-switch__option[aria-pressed="true"] {
  background: var(--surface-muted);
  font-weight: var(--weight-semibold);
}

.theme-switch__option[aria-pressed="true"]::after {
  content: "";
  inline-size: 0.4rem;
  block-size: 0.4rem;
  margin-inline-start: auto;
  border-radius: var(--radius-circle);
  background: var(--accent-primary);
}

@media (width < 64rem) {
  .theme-switch__menu {
    inset-inline: auto 0;
  }
}

/**
 * The suggestion bubble.
 *
 * Fixed to the corner, above the page and below nothing. It is added by its
 * module, so the markup here is never visible to a visitor without JavaScript —
 * which is why the container ships hidden and the module unhides it rather than
 * the other way round.
 */
.bubble {
  position: fixed;
  inset-block-end: var(--space-lg);
  inset-inline-end: var(--space-lg);
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-sm);
}

.bubble[hidden] { display: none; }

.bubble__button {
  display: grid;
  place-items: center;
  inline-size: 3rem;
  block-size: 3rem;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface-raised);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  transition: transform 160ms ease, box-shadow 160ms ease;
}

.bubble__button:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.bubble__button:focus-visible { outline-offset: 3px; }
/* The sprite draws in the page's own stroke weight and colour. */
.bubble__icon { color: var(--text-brand); }

.bubble__panel {
  inline-size: min(22rem, calc(100vw - 2 * var(--space-lg)));
  padding: var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg);
}

.bubble__form { display: grid; gap: var(--space-2xs); }
.bubble__title { margin: 0; font-weight: var(--weight-semibold); }
.bubble__lead, .bubble__optional { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }
.bubble__optional { margin-block-start: var(--space-2xs); }

.bubble__field {
  inline-size: 100%;
  padding: var(--space-2xs) var(--space-xs);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: var(--text-primary);
  font: inherit;
}

.bubble__field--tall { resize: vertical; min-block-size: 5rem; }
.bubble__actions { display: flex; gap: var(--space-xs); justify-content: flex-end; margin-block-start: var(--space-2xs); }
.bubble__status:empty { display: none; }
.bubble__status { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }
.bubble__thanks { margin: 0; }

@media print { .bubble { display: none; } }

/** Signing up to hear from us. */
.community__form {
  display: grid;
  gap: var(--space-sm);
  max-inline-size: 34rem;
  margin-block-start: var(--space-md);
}

@media (min-width: 40rem) {
  .community__form {
    grid-template-columns: 1fr 1fr auto;
    align-items: end;
  }
  .community__status { grid-column: 1 / -1; }
}

.community__label { display: grid; gap: var(--space-3xs, 0.25rem); }
.community__label-text { font-size: var(--text-sm); color: var(--text-secondary); }

.community__field {
  inline-size: 100%;
  padding: var(--space-2xs) var(--space-xs);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: var(--text-primary);
  font: inherit;
}

.community__status:empty { display: none; }
.community__status { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }

/**
 * What is coming up.
 *
 * A card per event, ordered soonest first. The time comes before the title
 * because the question somebody brought to this page is "when", and reading a
 * title first only to find the date underneath is the wrong way round for a
 * list you are scanning.
 */
.events {
  list-style: none;
  margin: var(--space-md) 0 0;
  padding: 0;
  display: grid;
  gap: var(--space-md);
}

.event {
  display: grid;
  gap: var(--space-sm);
  padding: var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

@media (min-width: 48rem) {
  .event { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); align-items: start; }
}

.event__media img { inline-size: 100%; border-radius: var(--radius-sm); }
.event__body { display: grid; gap: 0.3rem; }

.event__when {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-brand);
}

/* The reader's own time, added by the browser when it differs from the
   event's. A second line rather than a replacement: the event's own time is
   what somebody at it would say. */
.event__your-time { display: block; font-weight: var(--weight-regular, 400); color: var(--text-secondary); }

.event__title { margin: 0; font-size: var(--text-lg); }
.event__place { margin: 0; color: var(--text-secondary); font-size: var(--text-sm); }
.event__standfirst, .event__detail { margin: 0.2rem 0 0; }

.event__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-block-start: var(--space-xs);
}

.event__action {
  padding: 0.35em 0.9em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  text-decoration: none;
  color: inherit;
}

.event__action:hover { background: var(--surface-muted); }

.event__action--primary {
  border-color: transparent;
  background: var(--accent-primary);
  color: var(--on-accent-primary);
  font-weight: var(--weight-semibold);
}

.events__heading { margin-block: var(--space-xl) var(--space-sm); font-size: var(--text-lg); }

/* Past events stay, dimmed. A page that empties itself looks broken rather
   than quiet, and somebody who missed one still wants to know it happened. */
.events--past .event { background: var(--surface-muted); }
.events--past .event__when { color: var(--text-secondary); }

/** The people behind the Foundation. */
.leadership {
  list-style: none;
  margin: var(--space-md) 0 0;
  padding: 0;
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}

.leader { display: grid; gap: var(--space-xs); align-content: start; }

/* Square, so a row of faces reads as a row rather than a ragged edge. */
.leader__portrait img {
  inline-size: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius-md);
}

.leader__name { margin: 0; font-size: var(--text-lg); }
.leader__role { margin: 0; color: var(--text-brand); font-size: var(--text-sm); font-weight: var(--weight-semibold); }
.leader__about { margin: 0.2rem 0 0; color: var(--text-secondary); }

/**
 * A notice: prose the Foundation is answerable for.
 *
 * Set narrow and plain. Somebody reading a privacy notice is reading, not
 * scanning, and a measure wider than about seventy characters costs them the
 * start of the next line.
 */
.notice__heading {
  margin-block: var(--space-lg) var(--space-xs);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-brand);
}

.notice__heading:first-child { margin-block-start: 0; }
.notice__text { margin-block: 0 var(--space-sm); max-inline-size: 42rem; }

/* Who last changed it and when — the thing a reader of a notice actually wants
   to know, and the thing the Foundation may one day be asked. */
.notice__stamp {
  margin-block-start: var(--space-lg);
  padding-block-start: var(--space-sm);
  border-block-start: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.site-footer__notices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  list-style: none;
  margin: var(--space-xs) 0 0;
  padding: 0;
  font-size: var(--text-sm);
}

.icon {
  flex: none;
  inline-size: 1.25em;
  block-size: 1.25em;
  fill: none;
  stroke: currentcolor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon--sm { inline-size: 1.05em; block-size: 1.05em; }
.icon--md { inline-size: 1.4em; block-size: 1.4em; }
.icon--lg { inline-size: 1.75em; block-size: 1.75em; }

/*
 * The Foundation mark.
 *
 * A filled outline, not line art: the shape carries its own weight, so it is
 * painted rather than drawn. That is why there is no stroke width anywhere —
 * the mark stays exactly itself at a favicon or at half a screen, with nothing
 * to keep in proportion as it scales.
 */
.brand-symbol {
  inline-size: 1em;
  block-size: 1em;
  fill: currentcolor;
  stroke: none;
}

/*
 * The Foundation lockup.
 *
 * Sizes derive from one variable. The ratios below are the logo specification:
 * FOUNDATION at 57% of the ABUSUA AKOMA cap height, the tagline at 40%, and the
 * wordmark block at about 90% of the symbol height.
 *
 * Measured off the supplied artwork, the three rows are all but the same width
 * — ABUSUA AKOMA 1.000, FOUNDATION 0.986, the tagline 0.983 — on one centre
 * line. That is what makes the lockup read as a block rather than a heading
 * with things loose underneath it, and it is why FOUNDATION is tracked as far
 * as it is: the spacing is doing the work of filling the measure.
 */
/*
 * Published so anything sitting beside an extra-large lockup — the living
 * panel's signature, which is the tagline row in everything but name — can size
 * itself from the same number and stay in the same measure.
 */
:root {
  --lockup-xl-symbol: clamp(5.5rem, 3.4rem + 7vw, 10rem);
}

.lockup {
  --lockup-symbol: 3rem;
  /* Tracking wide enough to carry FOUNDATION out to the wordmark's width. */
  --lockup-secondary-tracking: 0.64em;
  --lockup-primary: calc(var(--lockup-symbol) * 0.38);
  --lockup-secondary: calc(var(--lockup-primary) * 0.57);
  --lockup-tagline: calc(var(--lockup-primary) * 0.4);

  display: inline-flex;
  gap: calc(var(--lockup-symbol) * 0.28);
  align-items: center;
  font-family: var(--font-display);
  color: inherit;
  text-decoration: none;
}

.lockup--sm { --lockup-symbol: 2.5rem; }
.lockup--md { --lockup-symbol: 3.5rem; }
.lockup--lg { --lockup-symbol: clamp(4rem, 3rem + 3vw, 5.5rem); }
.lockup--xl { --lockup-symbol: var(--lockup-xl-symbol); }

/* Symbol above the name: the arrangement a mark takes when it is the first
   thing on the page rather than a label in the corner. */
.lockup--vertical {
  flex-direction: column;
  gap: calc(var(--lockup-symbol) * 0.2);
  align-items: center;
  text-align: center;
}

.lockup--vertical .lockup__text {
  align-items: center;
}

.lockup--xl .lockup__primary {
  letter-spacing: 0.01em;
}

/* The mark is a filled outline, so there is no stroke to set a width on. */
.lockup__symbol {
  inline-size: var(--lockup-symbol);
  block-size: var(--lockup-symbol);
}

.lockup__text {
  display: flex;
  flex-direction: column;
  gap: calc(var(--lockup-primary) * 0.12);
}

.lockup__primary {
  font-size: var(--lockup-primary);
  font-weight: var(--weight-semibold);
  line-height: 1;
  letter-spacing: 0.005em;
  text-transform: uppercase;
}

.lockup__secondary {
  font-size: var(--lockup-secondary);
  font-weight: var(--weight-regular);
  line-height: 1;
  letter-spacing: var(--lockup-secondary-tracking);
  text-indent: var(--lockup-secondary-tracking);
  text-transform: uppercase;
}

.lockup__tagline {
  margin-block-start: calc(var(--lockup-primary) * 0.16);
  font-size: var(--lockup-tagline);
  font-weight: var(--weight-regular);
  line-height: 1.15;
  color: inherit;
  opacity: 0.85;
}

.lockup--no-tagline .lockup__tagline {
  display: none;
}

/* Buttons and button-shaped links. Variants carry role, never a raw colour. */
.action {
  display: inline-flex;
  gap: var(--space-2xs);
  align-items: center;
  justify-content: center;
  padding: 0.7em 1.35em;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  transition: background-color var(--motion-fast) var(--motion-ease-out),
    color var(--motion-fast) var(--motion-ease-out),
    border-color var(--motion-fast) var(--motion-ease-out),
    transform var(--motion-fast) var(--motion-ease-out);
}

.action:hover {
  transform: translateY(-1px);
}

.action:active {
  transform: translateY(0);
}

.action--sm {
  padding: 0.5em 1em;
  font-size: var(--text-xs);
}

.action--block {
  inline-size: 100%;
}

.action--primary {
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

.action--primary:hover {
  background: var(--accent-primary-hover);
}

.action--accent {
  background: var(--accent-secondary);
  color: var(--on-accent-secondary);
}

.action--accent:hover {
  background: var(--accent-secondary-hover);
}

.action--ghost {
  border-color: var(--border-strong);
  color: var(--text-primary);
}

.action--ghost:hover {
  border-color: var(--accent-primary);
  color: var(--text-brand);
}

.action--ghost-inverse {
  border-color: var(--overlay-feature-border-strong);
  color: var(--on-feature);
}

.action--ghost-inverse:hover {
  border-color: var(--accent-secondary);
  color: var(--accent-secondary);
}

.action--text {
  padding-inline: 0;
  color: var(--text-brand);
}

.action--text:hover {
  color: var(--accent-primary-hover);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

.section--feature .action--ghost,
.section--feature-deep .action--ghost,
.section--feature-soft .action--ghost {
  border-color: var(--overlay-feature-border-strong);
  color: var(--on-feature);
}

.section--feature .action--ghost:hover,
.section--feature-deep .action--ghost:hover,
.section--feature-soft .action--ghost:hover {
  border-color: var(--accent-secondary);
  color: var(--accent-secondary);
}

.section--feature .action--text,
.section--feature-deep .action--text,
.section--feature-soft .action--text {
  color: var(--on-feature-accent);
}

.action__icon {
  transition: translate var(--motion-fast) var(--motion-ease-out);
}

.action:hover .action__icon {
  translate: 0.15em 0;
}

.action-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
  margin-block-start: var(--space-md);
}

.heading-block--center + .rule--center + .action-group,
.statement .action-group {
  justify-content: center;
}

.heading-block {
  display: grid;
  gap: var(--space-2xs);
  max-inline-size: var(--layout-measure-wide);
}

.heading-block--center {
  justify-items: center;
  margin-inline: auto;
  text-align: center;
}

.heading-block__lead {
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
}

.heading-block__body {
  color: var(--text-secondary);
}

.heading-block__body + .heading-block__body {
  margin-block-start: var(--space-2xs);
}

.image {
  display: block;
  overflow: hidden;
  block-size: 100%;
}

/*
 * HOW A PICTURE SITS IN A FRAME IT DOES NOT MATCH
 *
 * Two things somebody can say about a photograph: which part of it survives
 * when the frame is a different shape, and how far into it to go. Both are
 * properties of the picture rather than of any one place it appears, and both
 * are CSS — the file on disk is never touched, so the same photograph can be
 * held one way here and another way there without a second copy existing.
 *
 * Custom properties rather than the real ones, because the hover effects set
 * scale themselves and would otherwise throw the zoom away the moment somebody
 * pointed at the picture.
 */
.image__img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: var(--hold-x, 50%) var(--hold-y, 50%);
  scale: var(--hold-zoom, 1);
  /* Scaling from the held point, so going closer does not slide off it. */
  transform-origin: var(--hold-x, 50%) var(--hold-y, 50%);
}

.image__img--contain {
  object-fit: contain;
}

/*
 * Frames.
 *
 * `feathered` is the one that makes a photograph sit inside the page rather
 * than on top of it: the image is masked with a soft radial falloff so its
 * edges dissolve into whatever surface is behind it.
 */
.frame {
  position: relative;
  margin: 0;
}

.frame--plain .image {
  border-radius: var(--radius-lg);
}

/*
 * Feathering dissolves the four edges of a photograph into whatever surface is
 * behind it, so the image reads as part of the page rather than as a tile
 * dropped on top of it. Two linear masks intersected, rather than a radial
 * vignette, because the rectangle should stay a rectangle — only its boundary
 * softens.
 */
.frame--feathered .image {
  --feather-x: 7%;
  --feather-y: 6%;

  border-radius: var(--radius-lg);
  mask-image:
    linear-gradient(to right, transparent 0, #000 var(--feather-x), #000 calc(100% - var(--feather-x)), transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 var(--feather-y), #000 calc(100% - var(--feather-y)), transparent 100%);
  mask-composite: intersect;
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 var(--feather-x), #000 calc(100% - var(--feather-x)), transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 var(--feather-y), #000 calc(100% - var(--feather-y)), transparent 100%);
  -webkit-mask-composite: source-in;
}

.frame--sheet .image {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  background: var(--surface-raised);
}

.frame--card .image {
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.frame__caption {
  margin-block-start: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/*
 * The opening panel on an inner page, and the gold wave that closes any
 * feature band off against the section beneath it.
 */
/*
 * The wave. Two stacked curves — gold above, page colour below — drawn with
 * radial gradients so they scale with the viewport and need no image. On a
 * light theme the band behind it is near-white, so what shows is a single gold
 * curve: the brochure's own divider rather than a slab of colour.
 */
.hero__wave {
  position: absolute;
  inset-inline: -10%;
  inset-block-end: -1px;
  block-size: clamp(1.5rem, 3.4vw, 2.75rem);
  background:
    radial-gradient(120% 100% at 50% 100%, var(--surface-page) 0 60%, transparent 60.5%),
    radial-gradient(120% 100% at 50% 100%, var(--accent-secondary) 0 68%, transparent 68.5%);
  pointer-events: none;
}

.page-header {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-2xl) calc(var(--space-2xl) + 2vw);
  background:
    radial-gradient(120% 90% at 85% 0%, color-mix(in srgb, var(--surface-feature) 64%, transparent) 0%, transparent 60%),
    var(--surface-feature-deep);
  color: var(--on-feature);
}

.page-header__inner {
  display: grid;
  gap: var(--space-xl);
  align-items: center;
}

.page-header__copy .heading-block__lead {
  color: var(--on-feature-muted);
}

@media (width >= 64rem) {
  .page-header--with-media .page-header__inner {
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  }
}

/*
 * The living panel.
 *
 * The pictures are the panel's background — they span the whole of it — and
 * the content is laid over them at full strength. Each line of reading carries
 * its own backing, shaped to the words, so the panel stays legible without
 * anything being laid over the picture as a whole.
 *
 * Everything is in the document whether or not scripts run. The [data-js]
 * rules, set before first paint, collapse it into the control; without them the
 * visitor reads every paragraph in turn and sees no transport.
 */
/*
 * The glow.
 *
 * The mark and the signature carry a halo in the panel's own surface colour,
 * which is what a drawn shape needs and a text box cannot give it. Running
 * copy uses the backing below instead.
 */
.living-panel {
  --panel-glow: var(--surface-feature-deep);
  --panel-halo:
    0 0 0.12em var(--panel-glow),
    0 0 0.3em var(--panel-glow),
    0 0 0.8em var(--panel-glow),
    0 0 1.8em var(--panel-glow);

  /*
   * A tight edge only. The reading no longer leans on a spread halo to lift
   * itself off the photograph — it sits on a backing of its own — so this is
   * back to what it is good at: keeping a glyph crisp where the backing ends.
   */
  --panel-halo-tight:
    0 0 0.08em var(--panel-glow),
    0 0 0.2em var(--panel-glow);

  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding-block: var(--space-xl) var(--space-2xl);
  background: var(--surface-feature-deep);
  color: var(--on-feature);
}

/* --- the changing background -------------------------------------------- */

.living-panel__stage {
  position: absolute;
  inset: 0;
  z-index: -2;
  display: grid;
}

.living-panel__frame {
  grid-area: 1 / 1;
  margin: 0;
  overflow: hidden;
}

.living-panel__frame .image,
.living-panel__frame .image__img {
  inline-size: 100%;
  block-size: 100%;
}

/*
 * The service photographs come in at 1536px, near enough one-to-one with the
 * panel, so they are shown sharp. The slight scale is headroom for the drift,
 * not a cover for upscaling.
 */
.living-panel__frame .image__img {
  object-fit: cover;
  /* Multiplied, not replaced: a picture somebody zoomed stays zoomed. */
  scale: calc(var(--hold-zoom, 1) * 1.02);
}

/*
 * Stacked in one cell and cross-faded: exactly one picture is ever visible,
 * whether or not scripts run. Without them the first simply stays put.
 */
.living-panel__frame {
  opacity: 0;
  /* Same reason as the lines below: a hidden picture is not a click target. */
  pointer-events: none;
  transition: opacity var(--motion-cinematic) var(--motion-ease-in-out);
}

.living-panel__frame.is-active {
  opacity: 1;
  pointer-events: auto;
}

/* A slow drift, so a still photograph still feels like it is breathing. */
.living-panel__frame.is-active .image__img {
  animation: panel-drift 22s var(--motion-ease-in-out) infinite alternate;
}

/* --- content ------------------------------------------------------------ */

.living-panel__inner {
  position: relative;
  display: grid;
  gap: var(--space-md);
  justify-items: center;
  text-align: center;
}

.living-panel__title {
  display: grid;
  gap: var(--space-md);
  justify-items: center;
}

.living-panel__lockup {
  color: var(--brand-mark);
  /* On a mark the halo has to follow the drawn shape, not a text box. */
  filter:
    drop-shadow(0 0 6px var(--panel-glow))
    drop-shadow(0 0 16px var(--panel-glow))
    drop-shadow(0 0 32px var(--panel-glow));
}

/* Buttons sit on their own solid fill, so they are deliberately left out.
   The signature's size is set with the hero variant, in utilities. */
.living-panel__signature {
  text-shadow: var(--panel-halo);
}

.living-panel__header,
.living-panel__title-line,
.living-panel__paragraph {
  text-shadow: var(--panel-halo-tight);
}

/*
 * The backing.
 *
 * A line of reading sits on a wash of the panel's own surface colour — so it is
 * black type on semi-transparent white on the paper theme, and the reverse on
 * the dark ones, without either being named here.
 *
 * `box-decoration-break: clone` is what makes it worth doing: the wash is drawn
 * once per line box, so it takes the ragged shape of the words themselves. A
 * blurred shadow in the same colour bleeds it outwards, which rounds the ends
 * off and closes the gaps between lines into one soft cloud instead of a stack
 * of highlighter bars. Nothing is laid over the panel, so the photograph is at
 * full strength everywhere the words are not.
 */
.living-panel__ink {
  --ink-fill: 86%;
  --ink-bleed: 0.5em;
  --ink-wash: color-mix(in srgb, var(--panel-glow) var(--ink-fill), transparent);

  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;

  /*
   * The block padding is set against the leading, not chosen for looks: an
   * inline background is only as tall as the em box, so at a relaxed line
   * height the lines would read as separate highlighter bars. This closes the
   * gap to a hair without letting the boxes overlap — overlapping washes
   * double their opacity and band.
   */
  padding: 0.26em 0.34em;
  border-radius: 0.5em;
  background: var(--ink-wash);
  box-shadow: 0 0 var(--ink-bleed) calc(var(--ink-bleed) * 0.34) var(--ink-wash);
}

/*
 * Each level's wash is set by what it needs, not by eye. `npm run audit`
 * composites the wash over black and over white — a photograph can be either —
 * and reports the worse of the two, so these are the smallest values at which
 * every theme still clears WCAG AA at the size the level actually renders:
 *
 *   section heading  34px semibold  3.0 needs 67%   (paper 61, gold-light 67)
 *   title line       17px semibold  4.5 needs 61%   (forest and earth 60)
 *   paragraph        21px regular   4.5 needs 85%   (paper 85, gold-light 82)
 *   eyebrow          13px caps      4.5 needs 94%   (paper: gold on white has
 *                                                    nothing to give away)
 *
 * The default covers the paragraph and the title line. Change a level's size or
 * colour and the audit will say so before it ships.
 */
.living-panel__header-title .living-panel__ink {
  --ink-fill: 70%;
  --ink-bleed: 0.4em;
}

.living-panel__eyebrow .living-panel__ink {
  --ink-fill: 95%;
  --ink-bleed: 0.35em;
}

.living-panel .rule {
  box-shadow: var(--panel-halo);
}

/* A word lights up while the scene that speaks for it is on screen. */
.living-panel__signature .signature-strip__word {
  transition: color var(--motion-base) var(--motion-ease-out),
    font-weight var(--motion-base) var(--motion-ease-out);
}

.living-panel__signature .signature-strip__word.is-lit {
  font-weight: var(--weight-semibold);
  color: var(--on-feature-accent);
}

/*
 * Each level gets a stack, because a header outlives the titles beneath it and
 * a title outlives its paragraphs.
 */
.living-panel__reading {
  display: grid;
  gap: var(--space-md);
  justify-items: center;
  inline-size: 100%;
}

/*
 * Every stack is one grid cell deep, so the panel does not jump as the levels
 * change and a scene with no title leaves its space reserved.
 */
.living-panel__headers,
.living-panel__titles,
.living-panel__scenes {
  display: grid;
  inline-size: 100%;
  max-inline-size: var(--layout-measure-wide);
}

.living-panel__header {
  grid-area: 1 / 1;
  display: grid;
  /*
   * Set against the washes, not by eye. Each line's wash is padded 0.26em in
   * its own size and then spread further by its shadow, and the title's size is
   * twice the eyebrow's — so a gap chosen for the text leaves none for the
   * backing. At the old 0.25rem the two washes overlapped by 5px on a phone and
   * 7px on a desktop, which is the doubling-and-banding the backing rule above
   * says to avoid, and it read as the eyebrow sitting on the heading.
   *
   * This leaves a few pixels of clear air between the solid edges at every
   * width. The blurred edges still meet, which is the point — one soft cloud,
   * not two bars welded together.
   */
  gap: var(--space-md);
  justify-items: center;
}

.living-panel__eyebrow {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--on-feature-accent);
}

.living-panel__header-title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--on-feature);
  text-wrap: balance;
}

.living-panel__title-line {
  grid-area: 1 / 1;
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--on-feature-accent);
}

/*
 * The outgoing line clears quickly and the incoming one waits for it, so two
 * sets of words are never legible over each other during a change.
 */
.living-panel__header,
.living-panel__title-line,
.living-panel__paragraph {
  opacity: 0;
  translate: 0 var(--space-2xs);
  transition: opacity var(--motion-fast) var(--motion-ease-out),
    translate var(--motion-fast) var(--motion-ease-out);
}

/*
 * Every level stacks all of its lines in one cell and fades between them, so a
 * line that is not on screen is transparent but still there — and still the
 * thing a click lands on, because the last one in the stack sits on top.
 *
 * Invisible to the eye has to mean invisible to the pointer too. Without this,
 * clicking the sentence you can read selects a sentence you cannot, which is
 * how editing the panel appeared to be stuck on one paragraph.
 */
.living-panel__header,
.living-panel__title-line,
.living-panel__paragraph {
  pointer-events: none;
}

.living-panel__header.is-active,
.living-panel__title-line.is-active,
.living-panel__paragraph.is-active {
  opacity: 1;
  translate: 0 0;
  pointer-events: auto;
  transition: opacity var(--motion-base) var(--motion-ease-out) var(--motion-fast),
    translate var(--motion-base) var(--motion-ease-out) var(--motion-fast);
}

/*
 * The hidden ones stay in the document and in the accessibility tree — only
 * their opacity changes — so a screen reader still reaches every paragraph
 * even though only one is ever visible.
 */
.living-panel__paragraph {
  grid-area: 1 / 1;
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--on-feature);
}

/* --- the player, in the corner ------------------------------------------ */

.living-panel__player {
  position: relative;
  z-index: var(--z-raised);
  display: none;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  align-items: center;
  justify-content: center;
  inline-size: fit-content;
  padding: var(--space-3xs) var(--space-2xs);
  border: 1px solid var(--border-feature);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--surface-feature-deep) 84%, transparent);
  backdrop-filter: blur(8px);
  margin-block-start: var(--space-lg);
  margin-inline: auto;
}

[data-js] .living-panel__player {
  display: flex;
}

.living-panel__counter {
  padding-inline: var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--on-feature-muted);
}

.living-panel__ticks {
  display: flex;
  gap: var(--space-3xs);
  align-items: center;
}

.living-panel__tick {
  position: relative;
  overflow: hidden;
  inline-size: 1.5rem;
  block-size: 0.2rem;
  border-radius: var(--radius-pill);
  background: var(--overlay-feature-border-strong);
  cursor: pointer;
}

.living-panel__tick-fill {
  position: absolute;
  inset: 0;
  transform-origin: left center;
  scale: 0 1;
  background: var(--accent-secondary);
}

.living-panel__tick.is-active .living-panel__tick-fill {
  scale: 1 1;
  transition: scale var(--motion-base) var(--motion-ease-out);
}

.living-panel.is-playing .living-panel__tick.is-active .living-panel__tick-fill {
  animation-name: panel-progress;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

.living-panel__buttons {
  display: flex;
  gap: var(--space-3xs);
  align-items: center;
}

.living-panel__control {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2rem;
  block-size: 2rem;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  color: var(--on-feature);
  transition: border-color var(--motion-fast) var(--motion-ease-out),
    background-color var(--motion-fast) var(--motion-ease-out),
    opacity var(--motion-fast) var(--motion-ease-out);
}

.living-panel__control:hover {
  border-color: var(--accent-secondary);
  background: var(--overlay-feature-surface);
}

.living-panel__control--play {
  border-color: var(--border-feature);
}

.living-panel__icon-play { display: none; }
.living-panel__control--play.is-paused .living-panel__icon-play { display: block; }
.living-panel__control--play.is-paused .living-panel__icon-pause { display: none; }

/* Looping is on by default; off is shown by the control receding. */
.living-panel__control--loop.is-off {
  opacity: 0.45;
}

@keyframes panel-progress {
  from { scale: 0 1; }
  to { scale: 1 1; }
}

@keyframes panel-drift {
  from { scale: 1; }
  to { scale: 1.08; }
}

@media (width >= 64rem) {
  .living-panel {
    padding-block: var(--space-2xl) var(--space-3xl);
  }

  /* On a wide panel the player sits in the corner, out of the reading. */
  [data-js] .living-panel__player {
    position: absolute;
    inset-block-end: var(--space-xl);
    inset-inline-end: var(--space-gutter);
    margin-block-start: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-js] .living-panel__frame.is-active .image__img {
    animation: none;
  }
}

/* Text beside media, with the side chosen in the page data. */
.split {
  display: grid;
  gap: var(--space-xl);
  align-items: center;
}

.split__copy {
  display: grid;
  gap: var(--space-2xs);
  align-content: start;
  max-inline-size: var(--layout-measure-wide);
}

.split__paragraph {
  color: var(--text-secondary);
}

.split__media {
  min-inline-size: 0;
}

.split__media .frame,
.split__media .image {
  inline-size: 100%;
}

.split__media .image__img {
  aspect-ratio: 5 / 4;
}

.split__media .frame--sheet .image__img {
  aspect-ratio: auto;
}

@media (width >= 64rem) {
  .split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-2xl);
  }

  .split--media-start .split__copy {
    order: 2;
  }

  .split--media-start .split__media {
    order: 1;
  }
}

.value-grid {
  --grid-columns: 4;

  display: grid;
  gap: var(--space-lg) var(--space-md);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.value-grid__item {
  display: grid;
  gap: var(--space-2xs);
  justify-items: center;
  text-align: center;
}

.value-grid__medallion {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 3.75rem;
  block-size: 3.75rem;
  border: 1px solid var(--medallion-border);
  border-radius: var(--radius-circle);
  background: var(--medallion-surface);
  color: var(--medallion-ink);
}

.value-grid__label {
  font-size: var(--text-lg);
}

.value-grid__summary {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-accent);
}

.value-grid__body {
  max-inline-size: 22rem;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.value-grid--medallion .value-grid__medallion {
  inline-size: 4.5rem;
  block-size: 4.5rem;
}

@media (width >= 48rem) {
  .value-grid {
    grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  }
}

/* Keep the medallions, labels and summaries on shared baselines across the row. */
@supports (grid-template-rows: subgrid) {
  .value-grid {
    grid-template-rows: auto auto auto auto;
  }

  .value-grid__item {
    grid-row: span 4;
    grid-template-rows: subgrid;
    gap: 0;
  }

  .value-grid__item > * {
    margin-block-end: var(--space-2xs);
  }
}


.value-grid__link { color: inherit; }
.value-grid__link:hover { color: var(--accent-primary); }

/* The four stages, in the brochure's column layout or opened out in full. */
/*
 * The four summary columns share their rows through subgrid, so the titles,
 * subtitles and body copy line up across the row however unevenly each one
 * wraps. Browsers without subgrid simply get the natural stacking.
 */
.steps--summary {
  display: grid;
  gap: var(--space-lg);
  grid-template-rows: auto auto auto auto;
}

.step {
  display: grid;
  gap: var(--space-2xs);
  padding-block-start: var(--space-sm);
  border-block-start: 1px solid var(--border-subtle);
}

.step__medallion {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 3.5rem;
  block-size: 3.5rem;
  border: 1px solid var(--medallion-border);
  border-radius: var(--radius-circle);
  background: var(--medallion-surface);
  color: var(--medallion-ink);
}

.step__number {
  position: absolute;
  inset-block-end: -0.7rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  border-radius: var(--radius-circle);
  background: var(--medallion-ink);
  color: var(--surface-raised);
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
}

.step__title {
  margin-block-start: var(--space-xs);
  font-size: var(--text-lg);
}

.step__subtitle {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--medallion-ink);
}

.step__body {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.steps--full {
  display: grid;
  gap: var(--space-xl);
}

.step--full {
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-md);
  align-items: start;
  padding-block-start: var(--space-lg);
}

.step--full .step__title {
  margin-block-start: 0;
  font-size: var(--text-2xl);
}

.step--full .step__body {
  max-inline-size: var(--layout-measure-wide);
  font-size: var(--text-md);
}

.step__highlights {
  display: grid;
  gap: var(--space-3xs);
  margin-block-start: var(--space-sm);
  padding: 0;
  list-style: none;
}

.step__highlights li {
  display: flex;
  gap: var(--space-2xs);
  align-items: start;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.step__highlights .icon {
  margin-block-start: 0.15em;
  color: var(--medallion-ink);
}

@media (width >= 48rem) {
  .steps--summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (width >= 64rem) {
  .steps--summary {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-md);
  }
}

@supports (grid-template-rows: subgrid) {
  @media (width >= 48rem) {
    .steps--summary > .step {
      grid-row: span 4;
      grid-template-rows: subgrid;
      gap: 0;
    }

    .steps--summary > .step > * {
      margin-block-end: var(--space-2xs);
    }
  }
}

.principles {
  --grid-columns: 3;

  display: grid;
  gap: var(--space-md);
  grid-template-columns: 1fr;
}

.principle {
  display: grid;
  gap: var(--space-2xs);
  align-content: start;
  padding: var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
}

.principle__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border-radius: var(--radius-md);
  background: var(--surface-feature-soft);
  color: var(--text-brand);
}

.principle__title {
  font-size: var(--text-lg);
}

.principle__body {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

@media (width >= 36rem) {
  .principles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (width >= 64rem) {
  .principles {
    grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  }
}

/* The five ways to give, as reading cards or as a selectable set. */
.contributions {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: 1fr;
}

/* Cards stretch to the row rather than to a percentage, so a long note on one
   card lifts the whole row instead of leaving ragged bottoms. */
.contribution,
.contribution__surface {
  display: grid;
  gap: var(--space-2xs);
  align-content: start;
  padding: var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
}

.contribution__medallion {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 3rem;
  block-size: 3rem;
  border: 1px solid var(--medallion-border);
  border-radius: var(--radius-circle);
  background: var(--medallion-surface);
  color: var(--medallion-ink);
}

.contribution__label {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
}

.contribution__short {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--medallion-ink);
}

.contribution__body {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.contribution__examples {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs);
  margin-block-start: var(--space-3xs);
}

.contribution__example {
  padding: 0.25em 0.7em;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  color: var(--text-secondary);
}

.contribution__next {
  display: flex;
  gap: var(--space-2xs);
  align-items: start;
  margin-block-start: var(--space-2xs);
  padding-block-start: var(--space-2xs);
  border-block-start: 1px solid var(--border-subtle);
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

.contribution__next .icon {
  margin-block-start: 0.2em;
  color: var(--medallion-ink);
}

.contribution__note {
  font-size: var(--text-xs);
  font-style: italic;
  color: var(--text-accent);
}

/* Selectable variant */
.contribution--selectable {
  display: grid;
  /* Overrides the card's own `align-content: start`, which would otherwise
     leave the selectable surface at its content height inside a taller row. */
  align-content: stretch;
  padding: 0;
  border: 0;
  background: none;
}

.contribution__choice {
  display: grid;
  align-content: stretch;
  cursor: pointer;
}

.contribution__radio {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.contribution__surface {
  position: relative;
  transition: border-color var(--motion-fast) var(--motion-ease-out),
    box-shadow var(--motion-fast) var(--motion-ease-out);
}

.contribution__choice:hover .contribution__surface {
  border-color: var(--border-accent);
}

.contribution__radio:focus-visible + .contribution__surface {
  outline: 2px solid var(--accent-secondary);
  outline-offset: 2px;
}

.contribution__radio:checked + .contribution__surface {
  border-color: var(--accent-primary);
  box-shadow: var(--shadow-md), inset 0 0 0 1px var(--accent-primary);
}

.contribution__tick {
  position: absolute;
  inset-block-start: var(--space-sm);
  inset-inline-end: var(--space-sm);
  display: none;
  align-items: center;
  justify-content: center;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  border-radius: var(--radius-circle);
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

.contribution__radio:checked + .contribution__surface .contribution__tick {
  display: inline-flex;
}

@media (width >= 48rem) {
  .contributions {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (width >= 64rem) {
  .contributions {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .contributions--selectable {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }

  .contributions--selectable .contribution__body,
  .contributions--selectable .contribution__examples,
  .contributions--selectable .contribution__next {
    display: none;
  }
}

/* The offer form. */
.pledge {
  display: grid;
  gap: var(--space-xl);
}

.pledge__modes {
  padding: 0;
  border: 0;
  margin: 0;
}

.pledge__legend {
  padding: 0;
  margin-block-end: var(--space-sm);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

.pledge__body {
  display: grid;
  gap: var(--space-md);
  padding: var(--space-lg);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
}

.pledge__heading {
  font-size: var(--text-xl);
}

.pledge__intro {
  max-inline-size: var(--layout-measure-wide);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.pledge__mode-fields,
.pledge__base-fields {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: 1fr;
}

.field {
  display: grid;
  gap: var(--space-3xs);
}

.field__label {
  display: flex;
  gap: var(--space-3xs);
  align-items: baseline;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.field__required {
  color: var(--text-danger);
}

.field__control {
  inline-size: 100%;
  padding: 0.65em 0.85em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-page);
  font-size: var(--text-md);
  transition: border-color var(--motion-fast) var(--motion-ease-out),
    box-shadow var(--motion-fast) var(--motion-ease-out);
}

.field__control:focus {
  border-color: var(--accent-primary);
  outline: none;
  box-shadow: var(--shadow-focus);
}

textarea.field__control {
  resize: vertical;
  min-block-size: 5rem;
}

.field__help {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

.field__error {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-danger);
}

.field.is-invalid .field__control {
  border-color: var(--text-danger);
  background: var(--surface-danger-soft);
}

.field__options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.field__option,
.field__inline {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  font-size: var(--text-sm);
  cursor: pointer;
}

.field__inline {
  align-items: start;
}

.field__checkbox {
  margin-block-start: 0.15em;
  inline-size: 1.05rem;
  block-size: 1.05rem;
  accent-color: var(--accent-primary);
}

.field--checkbox .field__label-text {
  font-weight: var(--weight-regular);
}

.pledge__status {
  padding: var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
  font-size: var(--text-sm);
}

.pledge__status[data-tone="success"] {
  border-color: var(--border-brand);
  background: var(--surface-success-soft);
}

.pledge__status[data-tone="error"] {
  border-color: var(--text-danger);
  background: var(--surface-danger-soft);
  color: var(--text-danger);
}

.pledge__status-heading {
  display: block;
  margin-block-end: var(--space-3xs);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.pledge__status-summary {
  display: grid;
  gap: var(--space-3xs);
  margin-block-start: var(--space-2xs);
  padding-block-start: var(--space-2xs);
  border-block-start: 1px solid var(--border-subtle);
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

.pledge__submit {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
}

.pledge__submit .action[aria-busy="true"] {
  opacity: 0.7;
  pointer-events: none;
}

@media (width >= 48rem) {
  .pledge__mode-fields,
  .pledge__base-fields {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .field--wide {
    grid-column: 1 / -1;
  }
}

.story-grid {
  --grid-columns: 3;

  display: grid;
  gap: var(--space-lg);
  grid-template-columns: 1fr;
}

.story-card__link {
  display: grid;
  gap: var(--space-sm);
  block-size: 100%;
  align-content: start;
  text-decoration: none;
  color: inherit;
}

.story-card__media {
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  background: var(--surface-muted);
}

.story-card__media .image,
.story-card__media .image__img {
  block-size: 100%;
}

.story-card__link:hover .story-card__media .image__img {
  /* Multiplied, not replaced: a picture somebody zoomed stays zoomed. */
  scale: calc(var(--hold-zoom, 1) * 1.03);
}

.story-card__media .image__img {
  transition: scale var(--motion-slow) var(--motion-ease-out);
}

.story-card__content {
  display: grid;
  gap: var(--space-3xs);
}

.story-card__topic {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-accent);
}

.story-card__title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
}

.story-card__link:hover .story-card__title {
  color: var(--text-brand);
}

.story-card__standfirst {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.story-card__cue {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: center;
  margin-block-start: var(--space-3xs);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-brand);
}

.story-grid--feature {
  --grid-columns: 2;
}

.story-grid--feature .story-card__title {
  font-size: var(--text-2xl);
}

/* Article */
.article {
  display: grid;
  gap: var(--space-lg);
}

.article__header {
  display: grid;
  gap: var(--space-2xs);
}

.article__back {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: center;
  margin-block-end: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--text-brand);
  text-decoration: none;
}

.article__back:hover {
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

.article__title {
  font-size: var(--text-4xl);
}

.article__standfirst {
  font-size: var(--text-xl);
  line-height: var(--leading-snug);
  color: var(--text-secondary);
}

.article__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-sm);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

@media (width >= 36rem) {
  .story-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (width >= 64rem) {
  .story-grid {
    grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  }
}

/*
 * Share rows across the cards so the images, titles, standfirsts and cues line
 * up however unevenly each card's text wraps. Five rows: media, topic, title,
 * standfirst, cue — carried down through the card, the link and the content.
 */
@supports (grid-template-rows: subgrid) {
  @media (width >= 36rem) {
    .story-grid {
      grid-template-rows: auto auto auto 1fr auto;
    }

    .story-card,
    .story-card__link {
      grid-row: span 5;
      display: grid;
      grid-template-rows: subgrid;
      gap: 0;
    }

    .story-card__media {
      grid-row: span 1;
      margin-block-end: var(--space-sm);
    }

    .story-card__content {
      grid-row: span 4;
      display: grid;
      grid-template-rows: subgrid;
      gap: 0;
    }

    .story-card__title,
    .story-card__standfirst {
      margin-block-start: var(--space-3xs);
    }
  }
}

.gallery {
  --grid-columns: 3;

  display: grid;
  gap: var(--space-md);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.gallery__link {
  display: grid;
  gap: var(--space-2xs);
  block-size: 100%;
  align-content: start;
  color: inherit;
  text-decoration: none;
}

.gallery__media {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-muted);
}

.gallery__media .image,
.gallery__media .image__img {
  block-size: 100%;
}

.gallery__media .image__img--contain {
  padding: var(--space-md);
}

.gallery__media .image__img {
  transition: scale var(--motion-slow) var(--motion-ease-out);
}

.gallery__link:hover .image__img {
  /* Multiplied, not replaced: a picture somebody zoomed stays zoomed. */
  scale: calc(var(--hold-zoom, 1) * 1.04);
}

.gallery__zoom {
  position: absolute;
  inset-block-end: var(--space-2xs);
  inset-inline-end: var(--space-2xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: var(--radius-circle);
  background: var(--surface-raised);
  color: var(--text-brand);
  box-shadow: var(--shadow-sm);
  opacity: 0;
  transition: opacity var(--motion-fast) var(--motion-ease-out);
}

.gallery__link:hover .gallery__zoom,
.gallery__link:focus-visible .gallery__zoom {
  opacity: 1;
}

.gallery__caption {
  display: grid;
  gap: 0.1rem;
}

.gallery__title {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.gallery__text {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

.gallery__credit {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

@media (width >= 64rem) {
  .gallery {
    grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  }
}

/* Built by the browser module; styled here so it matches the rest of the site. */

/*
 * An author `display` beats the user agent's `dialog:not([open]) { display:none }`
 * whatever the specificity, so the closed state has to be restated here — without
 * it the viewer sits permanently open over the gallery.
 */
.lightbox:not([open]) {
  display: none;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  border: 0;
  background: var(--scrim);
  backdrop-filter: blur(6px);
  color: var(--on-scrim);
  max-inline-size: none;
  max-block-size: none;
  inline-size: 100%;
  block-size: 100%;
}

.lightbox::backdrop {
  background: var(--scrim);
}

/*
 * The layout lives here rather than on the dialog, because this is the element
 * that goes full screen — a <dialog> cannot, so the request names this instead.
 * When it does, it is the whole display and has to paint its own ground.
 */
.lightbox__inner {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: var(--space-sm);
  padding: var(--space-sm);
  min-block-size: 0;
}

.lightbox__inner:fullscreen {
  background: inherit;
  color: inherit;
  padding: var(--space-md);
}

.lightbox__bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-sm);
  align-items: center;
  justify-content: space-between;
}

.lightbox__counter {
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
}

.lightbox__figure {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: var(--space-2xs);
  min-block-size: 0;
  margin: 0;
}

/*
 * Looking at one picture, it is shown at its own size and no larger. Several of
 * the gallery's files are small — 290px on the long edge for a few — and
 * enlarging those to fill a screen makes them soft. Somebody who clicked one
 * photograph to see it properly is owed the sharp version of it.
 *
 * A slideshow is a different request: a stamp in the middle of a black screen
 * is not a slideshow, so there the picture fills the frame and a small file
 * pays for being small. See the mode rule further down.
 */
.lightbox__image {
  min-block-size: 0;
  max-inline-size: 100%;
  max-block-size: 100%;
  margin-inline: auto;
  object-fit: contain;
  border-radius: var(--radius-md);
}

.lightbox__caption {
  display: grid;
  gap: 0.15rem;
  text-align: center;
}

.lightbox__title {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
}

.lightbox__text {
  font-size: var(--text-sm);
  opacity: 0.85;
}

.lightbox__credit {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  opacity: 0.7;
}

.lightbox__controls {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  justify-content: center;
}

.lightbox__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border: 1px solid color-mix(in srgb, var(--on-scrim) 38%, transparent);
  border-radius: var(--radius-pill);
  color: var(--on-scrim);
}

.lightbox__button:hover {
  border-color: var(--accent-secondary);
  background: color-mix(in srgb, var(--on-scrim) 14%, transparent);
}


/* --- playing, filling the screen, and choosing a topic --------------------------- */

.lightbox__tools {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/*
 * Each of the two state buttons carries both icons and shows one. Swapping the
 * <use> href instead would refetch nothing and cost nothing — but it leaves a
 * frame where the button is empty, and these sit still while a picture behind
 * them changes, so the flicker is the only thing moving.
 */
.lightbox__button [data-icon='pause'],
.lightbox__button [data-icon='shrink'] { display: none; }

.lightbox[data-playing] .lightbox__button [data-icon='play'] { display: none; }
.lightbox[data-playing] .lightbox__button [data-icon='pause'] { display: inline-block; }

.lightbox[data-full] .lightbox__button [data-icon='expand'] { display: none; }
.lightbox[data-full] .lightbox__button [data-icon='shrink'] { display: inline-block; }

/* The topics, as plain words rather than the page's chips: in here they sit on
   a photograph, and a row of filled pills would compete with it. */
.lightbox__topics {
  display: flex;
  gap: var(--space-3xs);
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

.lightbox__topic {
  padding: 0.3rem 0.7rem;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--on-scrim);
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--on-scrim) 28%, transparent);
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.lightbox__topic:hover {
  border-color: var(--accent-secondary);
  background: color-mix(in srgb, var(--on-scrim) 12%, transparent);
}

.lightbox__topic.is-active {
  color: var(--on-accent-primary);
  background: var(--accent-primary);
  border-color: var(--accent-primary);
}

/* How long is left on this picture. The only moving thing on the screen while
   a slideshow plays, so it is a hairline rather than a bar. */
.lightbox__progress {
  block-size: 2px;
  background: color-mix(in srgb, var(--on-scrim) 20%, transparent);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.lightbox__progress-bar {
  display: block;
  block-size: 100%;
  inline-size: 0;
  background: var(--accent-secondary);
  transform-origin: left;
}

@keyframes lightbox-progress {
  from { inline-size: 0; }
  to { inline-size: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  /* The slideshow still plays if somebody presses play — they asked for it.
     The countdown does not need to animate to say what it is saying. */
  .lightbox__progress-bar { animation: none !important; inline-size: 100%; }
}


/* --- one picture, or a slideshow ------------------------------------------------- */

/*
 * Opened by clicking a picture, the viewer is what it always was: the counter,
 * the caption, and a way to step through. Playing, the topics and the
 * full-screen button belong to the slideshow, and are not offered to somebody
 * who asked to look at one photograph.
 */
.lightbox[data-mode='quiet'] [data-play],
.lightbox[data-mode='quiet'] [data-full],
.lightbox[data-mode='quiet'] .lightbox__progress {
  display: none;
}

/* Filling the frame is the slideshow's job alone. */
.lightbox[data-mode='show'] .lightbox__image {
  inline-size: 100%;
  block-size: 100%;
}


/* --- what sits behind the picture ------------------------------------------------ */

/*
 * The slideshow plays in the theme the reader chose, rather than under a black
 * scrim. Only the slideshow: clicking a single picture still dims the page
 * behind it, which is what that gesture has always meant.
 */
.lightbox[data-mode='show'] {
  background: var(--surface-page);
  color: var(--text-primary);
}

.lightbox[data-mode='show']::backdrop {
  background: var(--surface-page);
}

/* Inverted borrows the opposite theme's colours through [data-theme-scope],
   so every token below it answers in that theme without anything here naming
   a single colour. */
.lightbox[data-mode='show'][data-backdrop='inverted'] {
  background: var(--surface-page);
  color: var(--text-primary);
}

.lightbox[data-mode='show'] .lightbox__button {
  border-color: var(--border-strong);
  color: var(--text-primary);
}

.lightbox[data-mode='show'] .lightbox__button:hover {
  border-color: var(--accent-primary);
  background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
}

.lightbox[data-mode='show'] .lightbox__topic {
  color: var(--text-primary);
  border-color: var(--border-subtle);
}

.lightbox[data-mode='show'] .lightbox__progress {
  background: color-mix(in srgb, var(--text-primary) 18%, transparent);
}

/*
 * Natural: the picture again, blurred and enlarged, filling the space around
 * itself. The blur is heavy enough that nothing in it reads as detail — it is
 * meant to be colour, not a second copy of the photograph competing with the
 * first.
 */
.lightbox__wash {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  border-radius: inherit;
}

.lightbox[data-backdrop='natural'] .lightbox__wash { display: block; }

.lightbox__wash img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Scaled past the edges because a blur pulls transparency in from them. */
  transform: scale(1.2);
  filter: blur(2.2rem) saturate(1.25);
}

/* A veil over the wash. Without it the text lands on whatever the photograph
   happens to be doing there, which is different in every picture. */
.lightbox__wash::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--scrim);
}

/* On the natural ground the words sit over a photograph, so they take the
   colour that is made for that, whatever the theme is doing. */
.lightbox[data-mode='show'][data-backdrop='natural'] {
  color: var(--on-scrim);
}

.lightbox[data-mode='show'][data-backdrop='natural'] .lightbox__button,
.lightbox[data-mode='show'][data-backdrop='natural'] .lightbox__topic {
  color: var(--on-scrim);
  border-color: color-mix(in srgb, var(--on-scrim) 38%, transparent);
}

.lightbox[data-mode='show'][data-backdrop='natural'] .lightbox__topic.is-active {
  color: var(--on-accent-primary);
  background: var(--accent-primary);
  border-color: var(--accent-primary);
}

/*
 * The wash lies inside the box that goes full screen — it has to, or it would
 * vanish the moment somebody filled the screen with it. Being positioned, it
 * paints above its plain siblings whatever the source order says, so everything
 * else is lifted over it explicitly. Raising the box itself does nothing: they
 * are all inside it together.
 */
.lightbox__inner { position: relative; }

.lightbox__inner > *:not(.lightbox__wash) {
  position: relative;
  z-index: 1;
}

/* Topics and grounds share a row under the counter. */
.lightbox__choices {
  display: flex;
  flex-basis: 100%;
  gap: var(--space-2xs) var(--space-md);
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

.lightbox__backdrops {
  display: flex;
  gap: var(--space-3xs);
  align-items: center;
  flex-wrap: wrap;
}

.lightbox[data-mode='quiet'] .lightbox__choices { display: none; }

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

/*
 * The gallery shown one picture at a time, in the page rather than over it.
 *
 * Built by the browser module; styled here so it matches the rest of the site.
 * Every colour and length below is a token — this block should survive somebody
 * adding an eighth theme without anyone looking at it.
 */
.gallery-inline {
  display: grid;
  gap: var(--space-sm);
  margin-block-start: var(--space-lg);
}

.gallery-inline__stage {
  position: relative;
  display: grid;
  place-items: center;
  min-block-size: min(42vh, 16rem);
  padding: var(--space-sm);
  background: var(--surface-muted);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

/* One at a time means the picture is the point, so it takes the room it is
   given rather than sitting at whatever size the file happens to be. */
.gallery-inline__image {
  inline-size: 100%;
  block-size: auto;
  max-block-size: min(60vh, 32rem);
  object-fit: contain;
  border-radius: var(--radius-md);
}

.gallery-inline__step {
  position: absolute;
  inset-block-start: 50%;
  translate: 0 -50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--text-primary);
  cursor: pointer;
}

.gallery-inline__step:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

.gallery-inline__step--back { inset-inline-start: var(--space-sm); }
.gallery-inline__step--on { inset-inline-end: var(--space-sm); }

.gallery-inline__caption {
  display: grid;
  gap: var(--space-3xs);
  text-align: center;
}

.gallery-inline__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.gallery-inline__text {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.gallery-inline__credit {
  margin: 0;
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.gallery-inline__bar {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  justify-content: center;
}

.gallery-inline__play {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  cursor: pointer;
}

.gallery-inline__play:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

/* Both icons are carried and one is shown, so the button never blinks empty
   between states. */
.gallery-inline__play [data-icon='pause'] { display: none; }
.gallery-inline[data-playing] .gallery-inline__play [data-icon='play'] { display: none; }
.gallery-inline[data-playing] .gallery-inline__play [data-icon='pause'] { display: inline-block; }

.gallery-inline__counter {
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
}

/* The strip along the bottom: where you are in the set, and a way to jump. */
.gallery-inline__strip {
  display: flex;
  gap: var(--space-2xs);
  margin: 0;
  padding: 0 0 var(--space-2xs);
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
}

/*
 * A thumbnail keeps its size, whatever the strip has to fit.
 *
 * Without this the twenty-four of them were flex items with nothing stopping
 * them shrinking, so on a phone they squeezed to slivers a few pixels across —
 * unreadable, and far too narrow to hit with a thumb. The strip scrolls
 * instead, which is what a strip is for.
 */
.gallery-inline__thumb {
  flex: none;
  scroll-snap-align: start;
}

.gallery-inline__thumb button {
  display: block;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
  opacity: 0.6;
}

.gallery-inline__thumb button:hover { opacity: 1; }

.gallery-inline__thumb.is-current button {
  border-color: var(--accent-primary);
  opacity: 1;
}

.gallery-inline__thumb img {
  display: block;
  /* Never below the size a thumb can hit. */
  inline-size: max(3.5rem, 12vw);
  max-inline-size: 5.5rem;
  block-size: 3.25rem;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/* The three ways to look at the gallery, beside the filters. */
.filter-bar__views { display: none; }

[data-js] .filter-bar__views {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--space-3xs);
  align-items: center;
  margin-inline-start: auto;
}

.filter-bar__view {
  /* A label is a name, not a paragraph: "Pop-out" broke across two lines with a
     hyphen, and "One at a time" stacked into three words tall. They wrap as
     whole buttons onto the next row instead. */
  white-space: nowrap;
  hyphens: none;
  padding: 0.4em 0.95em;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
  cursor: pointer;
}

.filter-bar__view:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

.filter-bar__view.is-active {
  border-color: var(--accent-primary);
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}


/* --- what sits under the big picture --------------------------------------------- */

.gallery-inline__unders {
  display: flex;
  gap: var(--space-3xs);
  align-items: center;
  justify-content: center;
}

.gallery-inline__under {
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: transparent;
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
  cursor: pointer;
}

.gallery-inline__under:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

.gallery-inline__under.is-active {
  border-color: var(--accent-primary);
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

/*
 * The same thumbnails, laid out three ways. Nothing is rebuilt between them —
 * a picture that has already been fetched should not be fetched again because
 * somebody changed their mind about the shape of the list.
 *
 *   strip   one row, scrolling sideways
 *   large   all of them, wrapped, at the size the strip uses
 *   small   all of them, wrapped, smaller, in a box that scrolls down
 */
.gallery-inline[data-under='large'] .gallery-inline__strip,
.gallery-inline[data-under='small'] .gallery-inline__strip {
  flex-wrap: wrap;
  justify-content: center;
  overflow-x: visible;
}

.gallery-inline[data-under='small'] .gallery-inline__strip {
  max-block-size: 14rem;
  overflow-y: auto;
  overscroll-behavior-y: contain;
}

.gallery-inline[data-under='small'] .gallery-inline__thumb img {
  inline-size: max(2.75rem, 9vw);
  max-inline-size: 3.5rem;
  block-size: 2.25rem;
}

/*
 * The chapter row.
 *
 * Every chapter is listed on every chapter, the current one marked rather than
 * removed: a row that changes length and order as you move through it is a row
 * nobody can learn the shape of.
 */
.chapters {
  display: flex;
  justify-content: center;
}

.chapters__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  justify-content: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chapters__pill {
  display: inline-block;
  padding: 0.45em 1.1em;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  text-decoration: none;
  /* A chapter name is a name; it should not break across two lines. */
  white-space: nowrap;
}

.chapters__pill:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

.chapters__pill.is-current {
  border-color: var(--accent-primary);
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

/* Every page, with a box to narrow them down. */

.site-map { display: grid; gap: var(--space-md); }

.site-map__find { display: grid; gap: var(--space-3xs); max-inline-size: 28rem; }

.site-map__find-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.site-map__input {
  padding: 0.6em 0.9em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text-primary);
}

.site-map__input:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}

.site-map__count,
.site-map__empty {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.site-map__group { display: grid; gap: var(--space-2xs); }

.site-map__group-title {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.site-map__list {
  display: grid;
  gap: var(--space-2xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-map__link {
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.site-map__note {
  margin: 0.1rem 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

@media (min-width: 48rem) {
  .site-map__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Sharing the page, and the Foundation's own card. Built by the browser module. */

.masthead__share {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}

/*
 * THE WORD OR THE ICON
 *
 * Both are in the markup and the stylesheet picks, because which one is right
 * is a setting somebody changes while the site is running — and a label that
 * needs a rebuild to change is not a setting, it is a deploy.
 *
 * The icon stays the default: a setting that changes how a site looks the day
 * it is added has changed it without being asked.
 */
.masthead__share-word { display: none; }

[data-share-word] .masthead__share {
  inline-size: auto;
  gap: var(--space-3xs);
  padding-inline: var(--space-xs);
}

[data-share-word] .masthead__share .icon { display: none; }

[data-share-word] .masthead__share-word {
  display: inline;
  font-size: var(--text-sm);
}

.masthead__share:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

.share:not([open]) { display: none; }

.share {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
  max-inline-size: none;
  max-block-size: none;
  padding: var(--space-sm);
  border: 0;
  background: var(--scrim);
}

.share::backdrop { background: var(--scrim); }

.share__inner {
  display: grid;
  gap: var(--space-sm);
  inline-size: min(26rem, 100%);
  padding: var(--space-md);
  background: var(--surface-page);
  color: var(--text-primary);
  border-radius: var(--radius-lg);
}

.share__head {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  justify-content: space-between;
}

.share__tabs { display: flex; gap: var(--space-3xs); }

.share__tab {
  padding: 0.35em 0.9em;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: transparent;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  cursor: pointer;
}

.share__tab.is-active {
  border-color: var(--accent-primary);
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

.share__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-primary);
  cursor: pointer;
}

.share__lead {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/*
 * The square itself is always drawn on white with black modules, whatever the
 * theme. A reader's camera is looking for that contrast, and a code tinted to
 * match the page is a code that takes three tries to scan.
 */
.share__code {
  display: grid;
  place-items: center;
  padding: var(--space-sm);
  background: #ffffff;
  border-radius: var(--radius-md);
}

.share__code svg {
  inline-size: min(15rem, 100%);
  block-size: auto;
}

.share__none {
  margin: 0;
  padding: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-ink-900);
  text-align: center;
}

.share__address {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

.share__row { display: flex; gap: var(--space-2xs); flex-wrap: wrap; }

.share__button {
  flex: 1 1 auto;
  padding: 0.55em 1em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.share__button:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

/*
 * The square offered beside Contact. Small, in the same ink as the link it sits
 * with, and plainly a control rather than part of the word next to it.
 */
.masthead__utility-code {
  margin-inline-start: var(--space-3xs);
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.masthead__utility-code:hover,
.masthead__utility-code:focus-visible {
  color: var(--accent-primary);
  text-decoration: underline;
}

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-sm);
  align-items: center;
  padding-block-end: var(--space-sm);
  border-block-end: 1px solid var(--border-subtle);
}

.filter-bar__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.filter-bar__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs);
}

.chip {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: center;
  padding: 0.4em 0.95em;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  transition: border-color var(--motion-fast) var(--motion-ease-out),
    background-color var(--motion-fast) var(--motion-ease-out),
    color var(--motion-fast) var(--motion-ease-out);
}

.chip:hover {
  border-color: var(--border-accent);
  color: var(--text-primary);
}

.chip.is-active {
  border-color: var(--accent-primary);
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

.chip__count {
  font-size: var(--text-2xs);
  opacity: 0.75;
}

[data-filter-hidden] {
  display: none !important;
}

/* The three traditional symbols, then the union mark. */
.lineage {
  display: grid;
  gap: var(--space-lg);
  grid-template-columns: 1fr;
}

.lineage__item {
  display: grid;
  gap: var(--space-2xs);
  justify-items: center;
  padding-inline: var(--space-md);
  text-align: center;
}

.lineage__art {
  display: grid;
  place-items: center;
  inline-size: clamp(6rem, 14vw, 9rem);
  block-size: clamp(6rem, 14vw, 9rem);
  color: var(--text-primary);
}

/* The traditional symbols are vectors carrying no colour of their own, so they
   take the colour set on the frame around them. That is what lets them follow a
   theme instead of sitting as flat black on a dark page — and what finally makes
   each item's declared accent mean something. A picture chosen in the editing
   area replaces the vector and simply ignores all of this. */
.lineage__art .image {
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
}

.lineage__vector {
  inline-size: 100%;
  block-size: 100%;
}

/* All three take the brand colour rather than each item's declared accent.
   Tinting one with --accent-secondary was tried and measured: it lands at
   2.2-2.4:1 against the page on the four light themes, under the 3:1 a
   graphical object needs, so Abusua Pa alone would have gone faint on paper.
   --text-brand measures 6.6:1 to 11.7:1 across all seven. The accent field is
   left in the data for whatever else wants it. */
.lineage__item .lineage__art { color: var(--text-brand); }

.lineage__name {
  font-size: var(--text-xl);
  color: var(--text-brand);
}

.lineage__translation {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-accent);
}

.lineage__body {
  max-inline-size: 22rem;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.union {
  display: grid;
  gap: var(--space-md);
  justify-items: center;
  margin-block-start: var(--space-2xl);
  padding: var(--space-xl) var(--space-md);
  border: 1px solid var(--border-accent);
  border-radius: var(--radius-xl);
  background: var(--surface-accent-soft);
  text-align: center;
}

.union__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border-radius: var(--radius-circle);
  background: var(--accent-secondary);
  color: var(--on-accent-secondary);
  rotate: 90deg;
  margin-block-start: calc(var(--space-xl) * -1.5);
}

.union__symbol {
  inline-size: clamp(6rem, 16vw, 9rem);
  block-size: clamp(6rem, 16vw, 9rem);
  color: var(--text-primary);
}

.union__copy {
  display: grid;
  gap: var(--space-2xs);
  max-inline-size: var(--layout-measure-wide);
}

.union__name {
  font-size: var(--text-2xl);
}

.union__translation {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--text-brand);
}

.union__body {
  color: var(--text-secondary);
}

.union__closing {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  color: var(--text-brand);
}

@media (width >= 48rem) {
  .lineage {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .lineage__item + .lineage__item {
    border-inline-start: 1px solid var(--border-subtle);
  }
}

.faq {
  display: grid;
  gap: var(--space-lg);
}

.faq__group-title {
  margin-block-end: var(--space-2xs);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-accent);
}

.faq__item {
  border-block-end: 1px solid var(--border-subtle);
}

.faq__question {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-sm);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  cursor: pointer;
  list-style: none;
}

.faq__question::-webkit-details-marker {
  display: none;
}

.faq__question:hover {
  color: var(--text-brand);
}

.faq__chevron {
  flex: none;
  color: var(--text-accent);
  transition: rotate var(--motion-fast) var(--motion-ease-out);
}

.faq__item[open] .faq__chevron {
  rotate: 180deg;
}

.faq__answer {
  padding-block-end: var(--space-md);
  max-inline-size: var(--layout-measure-wide);
  color: var(--text-secondary);
}

.contact-list {
  display: grid;
  gap: var(--space-sm);
  margin: 0;
}

.contact-list__row {
  display: grid;
  gap: var(--space-3xs);
  padding-block-end: var(--space-sm);
  border-block-end: 1px solid var(--border-subtle);
}

.contact-list__label {
  display: flex;
  gap: var(--space-3xs);
  align-items: center;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-accent);
}

.contact-list__value {
  display: grid;
  gap: 0.1rem;
  margin: 0;
  font-size: var(--text-lg);
}

.contact-list__value a {
  color: var(--text-brand);
  text-decoration: none;
}

.contact-list__value a:hover {
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

.contact-social {
  margin-block-start: var(--space-lg);
}

.contact-social__label {
  margin-block-end: var(--space-2xs);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.contact-social ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  padding: 0;
  list-style: none;
}

.contact-social a {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: center;
  color: var(--text-brand);
  text-decoration: none;
}

.statement {
  display: grid;
  gap: var(--space-sm);
  justify-items: center;
  text-align: center;
}

.statement .heading-block__body {
  font-size: var(--text-lg);
  color: var(--text-secondary);
}

/* The surface comes from the section's `background` setting, not from here —
   the same band is used on a brand field and on a light one. */
.cta-band {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-3xl);
}

.cta-band__watermark {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: -6%;
  translate: 0 -50%;
  color: currentcolor;
  opacity: 0.07;
  pointer-events: none;
}

.cta-band__watermark .brand-symbol {
  inline-size: clamp(14rem, 34vw, 26rem);
  block-size: clamp(14rem, 34vw, 26rem);
}

.cta-band__inner {
  position: relative;
  display: grid;
  gap: var(--space-sm);
  justify-items: center;
  text-align: center;
}

.cta-band .action-group {
  justify-content: center;
}

/*
 * Sizes written out here are exempt for the same reason as admin.css, which
 * carries the full explanation: this styles a tool rather than the site.
 * Colours are not exempt, and there are none written by hand.
 */

/*
 * In-page copy editing.
 *
 * Only ever present when the mode is on, so none of this costs an ordinary
 * visitor anything. The marks are drawn with pseudo-elements rather than
 * injected nodes: the page being edited must look like the page, and adding
 * buttons into the content would change the layout being reviewed.
 *
 * Colours come from the theme like everything else, so the editor follows
 * whichever theme the reviewer is looking at.
 */
:root[data-copy-editing='on'] .copy-target {
  position: relative;
  cursor: text;
}

/*
 * The corner dot that says "this can be edited".
 *
 * Fixed size, not em: a marker means the same thing on a heading as on a
 * caption, so it should not grow into a disc on the largest type on the page.
 */
:root[data-copy-editable='on'] .copy-target::after {
  position: absolute;
  inset-block-start: -0.2rem;
  inset-inline-start: -0.4rem;
  z-index: 2;
  inline-size: 0.4rem;
  block-size: 0.4rem;
  border-radius: 50%;
  background: var(--accent-secondary);
  opacity: 0.55;
  content: '';
  pointer-events: none;
}

:root[data-copy-editable='on'] .copy-target:hover {
  outline: 1px dashed var(--accent-secondary);
  outline-offset: 0.25rem;
}

/* A string with drafts against it. The count rides in the corner. */
:root[data-copy-changed='on'] .copy-target--changed::before {
  position: absolute;
  inset-block-start: -0.55rem;
  inset-inline-end: -0.55rem;
  z-index: 2;
  min-inline-size: 1.1rem;
  padding: 0.05rem 0.25rem;
  border-radius: 1rem;
  background: var(--accent-primary);
  color: var(--on-accent-primary);
  font-family: var(--font-body);
  font-size: 0.6rem;
  font-weight: var(--weight-semibold);
  line-height: 1.4;
  text-align: center;
  content: attr(data-copy-drafts);
  pointer-events: none;
}

:root[data-copy-changed='on'] .copy-target--showing-draft {
  background: color-mix(in srgb, var(--accent-secondary) 18%, transparent);
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--accent-secondary) 18%, transparent);
}

/* --- the toolbar ---------------------------------------------------------- */

.copy-bar {
  position: fixed;
  inset-block-end: var(--space-md);
  inset-inline-start: var(--space-md);
  z-index: 60;
  display: grid;
  gap: var(--space-2xs);
  inline-size: min(17rem, calc(100vw - 2 * var(--space-md)));
  padding: var(--space-sm);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg, 0 10px 30px rgb(0 0 0 / 0.18));
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 0.8rem;
}

.copy-bar__head {
  display: flex;
  gap: var(--space-2xs);
  align-items: baseline;
  justify-content: space-between;
}

.copy-bar__title {
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  font-size: 0.65rem;
  color: var(--text-muted);
}

.copy-bar__name { font-weight: var(--weight-semibold); }
.copy-bar__count, .copy-bar__missing { color: var(--text-secondary); font-size: 0.72rem; }
.copy-bar__missing { color: var(--text-danger); }

.copy-bar__row {
  display: flex;
  gap: var(--space-2xs);
  flex-wrap: wrap;
}

.copy-bar__toggle,
.copy-bar__action,
.copy-bar__resume,
.copy-bar__off {
  padding: 0.3em 0.7em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.72rem;
  cursor: pointer;
}

.copy-bar__toggle.is-on {
  border-color: transparent;
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

.copy-bar__off { border: 0; background: none; color: var(--text-muted); padding-inline: 0; }
.copy-bar__resume { text-align: start; }

.copy-bar__field {
  flex: 1 1 6rem;
  min-inline-size: 0;
  padding: 0.3em 0.5em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.72rem;
}

/* --- the editing dialog --------------------------------------------------- */

.copy-dialog {
  position: fixed;
  inset-block-end: var(--space-md);
  inset-inline-end: var(--space-md);
  z-index: 70;
  display: grid;
  gap: var(--space-2xs);
  inline-size: min(26rem, calc(100vw - 2 * var(--space-md)));
  padding: var(--space-sm) var(--space-md) var(--space-md);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg, 0 14px 40px rgb(0 0 0 / 0.22));
  color: var(--text-primary);
  font-family: var(--font-body);
}

.copy-dialog__head {
  display: flex;
  gap: var(--space-sm);
  align-items: start;
  justify-content: space-between;
}

.copy-dialog__where { font-weight: var(--weight-semibold); font-size: 0.82rem; }

.copy-dialog__key {
  color: var(--text-muted);
  font-size: 0.65rem;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.copy-dialog__close {
  border: 0;
  background: none;
  color: var(--text-muted);
  font: inherit;
  cursor: pointer;
}

.copy-dialog__cycle {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-2xs);
  align-items: center;
  padding-block: var(--space-2xs);
}

.copy-dialog__position {
  color: var(--text-secondary);
  font-size: 0.72rem;
  text-align: center;
}

.copy-dialog__step {
  padding: 0.1em 0.5em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.copy-dialog__text,
.copy-dialog__field {
  inline-size: 100%;
  padding: 0.5em 0.6em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
}

.copy-dialog__text { resize: vertical; line-height: var(--leading-normal, 1.5); }
.copy-dialog__fields { display: grid; gap: var(--space-2xs); grid-template-columns: 1fr 1fr; }
.copy-dialog__fields .copy-dialog__field { font-size: 0.75rem; }
.copy-dialog__note { color: var(--text-danger); font-size: 0.72rem; }

.copy-dialog__actions { display: flex; gap: var(--space-2xs); margin-block-start: var(--space-2xs); }

.copy-dialog__save,
.copy-dialog__revert {
  padding: 0.45em 1em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}

.copy-dialog__save {
  border-color: transparent;
  background: var(--accent-primary);
  color: var(--on-accent-primary);
  font-weight: var(--weight-semibold);
}

/* None of the editing furniture belongs on paper. */
@media print {
  .copy-bar,
  .copy-dialog { display: none; }
  .copy-target::before,
  .copy-target::after { content: none; }
}

.copy-dialog__status { color: var(--text-muted); font-size: 0.72rem; }

.copy-dialog__save:disabled {
  border-color: var(--border-subtle);
  background: var(--surface-muted);
  color: var(--text-muted);
  cursor: not-allowed;
}

/* --- the compact toolbar -------------------------------------------------- */

.copy-bar__head-actions { display: flex; gap: var(--space-2xs); align-items: center; }

.copy-bar__shrink {
  padding: 0 0.4em;
  border: 0;
  background: none;
  color: var(--text-muted);
  font: inherit;
  line-height: 1;
  cursor: pointer;
}

/*
 * The pill. Sized by its contents rather than the panel width, so it takes
 * only the room the session name needs and leaves the page visible.
 */
.copy-bar--compact {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  inline-size: auto;
  max-inline-size: min(17rem, calc(100vw - 2 * var(--space-md)));
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
}

.copy-bar__grow {
  display: flex;
  gap: 0.45em;
  align-items: center;
  min-inline-size: 0;
  padding: 0.15em 0.2em;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
}

.copy-bar__pip {
  flex: none;
  inline-size: 0.5em;
  block-size: 0.5em;
  border-radius: 50%;
  background: var(--accent-secondary);
}

.copy-bar__pill-name {
  overflow: hidden;
  font-weight: var(--weight-semibold);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.copy-bar__pill-count {
  flex: none;
  min-inline-size: 1.4em;
  padding: 0.05em 0.4em;
  border-radius: 999px;
  background: var(--accent-primary);
  color: var(--on-accent-primary);
  font-size: 0.65rem;
  font-weight: var(--weight-semibold);
  text-align: center;
}

.copy-bar__off--tight { padding: 0 0.3em; font-size: 0.75rem; line-height: 1; }

/*
 * The offer of editing, for somebody who is signed in and simply reading.
 *
 * Deliberately small and out of the way: most of the time a signed-in person is
 * looking at the site, not working on it, and a permanent toolbar would be in
 * the way of the thing they came to look at.
 */
.copy-launch {
  position: fixed;
  inset-block-end: var(--space-md);
  inset-inline-start: var(--space-md);
  z-index: 55;
  display: flex;
  gap: 0.45em;
  align-items: center;
  padding: 0.4em 0.9em;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg, 0 8px 24px rgb(0 0 0 / 0.14));
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 0.78rem;
  cursor: pointer;
}

.copy-launch__pip {
  inline-size: 0.45em;
  block-size: 0.45em;
  border-radius: 50%;
  background: var(--accent-secondary);
}

@media print { .copy-launch { display: none; } }

/*
 * Manage, in the navigation, for somebody signed in.
 *
 * The dot is the same one the editing marks use, so the two read as one system
 * rather than two tools that happen to share a site. It opens to the sections
 * because reaching Checkpoints should not mean arriving at Sessions first.
 */
.masthead__manage { position: relative; }

.masthead__nav-link--manage {
  display: inline-flex;
  gap: 0.45em;
  align-items: center;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}

.masthead__manage-pip {
  flex: none;
  inline-size: 0.4rem;
  block-size: 0.4rem;
  border-radius: 50%;
  background: var(--accent-secondary);
}

.masthead__manage-menu {
  position: absolute;
  inset-block-start: calc(100% + 0.4rem);
  inset-inline-start: 0;
  z-index: 40;
  display: grid;
  min-inline-size: 9rem;
  padding: var(--space-3xs, 0.25rem);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg, 0 10px 28px rgb(0 0 0 / 0.16));
}

.masthead__manage-menu[hidden] { display: none; }

.masthead__manage-link {
  padding: 0.4em 0.7em;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.85rem;
  text-decoration: none;
}

.masthead__manage-link:hover,
.masthead__manage-link:focus-visible { background: var(--surface-muted); }

/*
 * Below the large breakpoint the whole navigation is already an open panel, so
 * the sections are simply listed rather than tucked behind a second tap.
 */
@media (width < 64rem) {
  .masthead__manage-menu {
    position: static;
    display: grid;
    border: 0;
    box-shadow: none;
    background: none;
    padding-inline-start: var(--space-sm);
  }

  .masthead__manage-menu[hidden] { display: grid; }
}

/*
 * The string somebody followed a link to.
 *
 * It fades rather than stays lit: the point is to say "here", not to mark the
 * sentence permanently for everybody who reads the page afterwards.
 */
.copy-target--found {
  animation: copy-found 2.4s var(--motion-ease-out) 1;
}

@keyframes copy-found {
  0%, 60% { background: color-mix(in srgb, var(--accent-secondary) 34%, transparent); }
  100% { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
  .copy-target--found { animation: none; outline: 2px solid var(--accent-secondary); }
}

.copy-bar__locked {
  color: var(--text-danger);
  font-size: 0.72rem;
}

.copy-bar__resume {
  display: grid;
  gap: 0.1em;
  text-align: start;
}

.copy-bar__resume-name { font-weight: var(--weight-medium); }

.copy-bar__resume-meta {
  color: var(--text-muted);
  font-size: 0.66rem;
}

/* A session that can be read but not changed, said before it is opened. */
.copy-bar__resume.is-shut { opacity: 0.72; }
.copy-bar__resume.is-shut .copy-bar__resume-meta { color: var(--text-danger); }

/*
 * The staged/live switch.
 *
 * Sits opposite the edit button so the two do not stack, and states which of
 * the two things you are looking at rather than what pressing it would do —
 * "Viewing staged" is a fact about the page; "Show live" would be a promise
 * about the next one.
 */
.staged-switch {
  position: fixed;
  inset-block-end: var(--space-md);
  inset-inline-end: var(--space-md);
  z-index: 55;
  padding: 0.4em 0.9em;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg, 0 8px 24px rgb(0 0 0 / 0.14));
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: 0.78rem;
  cursor: pointer;
}

.staged-switch.is-on {
  border-color: transparent;
  background: var(--accent-secondary);
  color: var(--on-accent-secondary);
  font-weight: var(--weight-semibold);
}

@media print { .staged-switch { display: none; } }

/*
 * A panel holding still while its words are edited.
 *
 * The transport is dimmed rather than hidden: it says the panel is paused and
 * why, where hiding it would look like the controls had broken.
 */
.living-panel.is-holding .living-panel__player {
  opacity: 0.45;
  pointer-events: none;
}


/* Searching the sessions, and the rest of them. */
.copy-bar__search { inline-size: 100%; }

.copy-bar__more {
  padding: 0.3em 0;
  border: 0;
  background: none;
  color: var(--text-brand);
  font: inherit;
  font-size: 0.85rem;
  text-align: start;
  text-decoration: underline;
  cursor: pointer;
}

/* The panel is fixed to the corner, so it must never grow past the screen it
   is fixed to. Long lists scroll inside it rather than off the bottom. */
.copy-bar {
  max-block-size: min(80vh, 40rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}


/* Minimise reads as the ordinary thing to do, and turning off as the deliberate
   one. They were the other way round: a chevron nobody could see beside the
   only labelled button on the panel. */
.copy-bar__shrink {
  display: inline-flex;
  gap: 0.3rem;
  align-items: center;
  padding: 0.25em 0.6em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}

.copy-bar__shrink:hover { background: var(--surface-muted); }

.copy-bar__off--quiet {
  border-color: transparent;
  color: var(--text-secondary);
  font-size: 0.8rem;
}

.copy-bar__off--quiet:hover { color: var(--text-primary); text-decoration: underline; }


/* --- changing a picture from the page it is on ----------------------------------- */

/*
 * Only while the Pictures button is on. An outline on every photograph the rest
 * of the time would make reading the page harder for the sake of something
 * nobody is doing yet.
 *
 * The button sits on the card rather than on the picture, because the picture
 * is usually inside a link and that link still belongs to the reader.
 */
.has-changeable-picture { position: relative; }

.picture-edit { display: none; }

.is-editing-pictures [data-slot] {
  outline: 2px dashed var(--accent-primary);
  outline-offset: 3px;
}

.is-editing-pictures .picture-edit {
  position: absolute;
  inset-block-start: var(--space-2xs);
  inset-inline-end: var(--space-2xs);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  padding: 0;
  border: 1px solid var(--accent-primary);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--accent-primary);
  font-size: var(--text-sm);
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}

.is-editing-pictures .picture-edit:hover {
  background: var(--accent-primary);
  color: var(--on-accent-primary);
}

.picture-picker {
  position: fixed;
  inset-block-end: var(--space-md);
  inset-inline: var(--space-md);
  z-index: calc(var(--z-modal) + 1);
  display: grid;
  gap: var(--space-2xs);
  max-block-size: 70vh;
  max-inline-size: 44rem;
  margin-inline: auto;
  padding: var(--space-sm);
  overflow-y: auto;
  background: var(--surface-raised);
  color: var(--text-primary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.picture-picker__head { display: flex; justify-content: space-between; align-items: center; }
.picture-picker__title { margin: 0; font-weight: var(--weight-semibold); }
.picture-picker__tools { display: flex; gap: var(--space-2xs); flex-wrap: wrap; }
.picture-picker__status { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }

.picture-picker__close,
.picture-picker__revert,
.picture-picker__add {
  padding: 0.4em 0.9em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  font-size: var(--text-sm);
  color: var(--text-primary);
  cursor: pointer;
}

.picture-picker__file { display: none; }

.picture-picker__grid {
  display: grid;
  gap: var(--space-2xs);
  grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
}

.picture-picker__choice {
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
}

.picture-picker__choice:hover { border-color: var(--accent-primary); }

.picture-picker__choice img {
  display: block;
  inline-size: 100%;
  block-size: 4.5rem;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/*
 * SIZES WRITTEN OUT IN THIS FILE
 *
 * The site's own stylesheets take every size from a token, and a literal in one
 * of them is a fault. This file and copy-editor.css are the exception, on
 * purpose: they style tools rather than the site, the tools need sizes the
 * reading scale does not have — a 0.65rem badge, a 3.6rem thumbnail — and
 * inventing tokens for one-off pieces of furniture would grow the scale for
 * everybody to serve a screen most people never open.
 *
 * COLOURS ARE NOT EXEMPT. Every colour here still comes from a token, because a
 * colour that does not follow the theme is visibly wrong the moment somebody
 * switches to a dark one. Sizes do not have that problem.
 */

/*
 * The managing area.
 *
 * A section of the site rather than a separate tool: it sits inside the same
 * masthead and footer, and takes the page's own container for its width. What
 * it does differently is density — this is a desk, and everything on it is a
 * list of facts somebody has to scan.
 */
.admin {
  padding-block: var(--space-lg) var(--space-2xl);
  font-family: var(--font-body);
}

.admin.is-busy { opacity: 0.6; }

.admin-note,
.admin__lead { color: var(--text-secondary); }

.admin__lead { margin-block: var(--space-2xs) var(--space-md); max-inline-size: 60ch; }

.admin__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: end;
  justify-content: space-between;
  padding-block-end: var(--space-sm);
  border-block-end: 1px solid var(--border-subtle);
}

.admin__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
}

.admin__who { margin: 0.2em 0 0; color: var(--text-muted); font-size: 0.85rem; }
.admin__heading { margin-block: var(--space-lg) var(--space-2xs); font-size: var(--text-lg); }

/* --- the shell -------------------------------------------------------------- */

/*
 * Sections down the side, the section itself beside them.
 *
 * Seventeen equally-weighted buttons in a wrapping row was not a menu; it was a
 * wall, and people cope with a wall by learning where their two things are and
 * never reading the rest. Groups give the eye somewhere to start.
 */
.admin__shell {
  display: grid;
  gap: var(--space-lg);
  align-items: start;
}

@media (min-width: 60rem) {
  .admin__shell { grid-template-columns: 14rem minmax(0, 1fr); }
}

.admin__nav { display: grid; gap: var(--space-md); }
.admin__nav-group { display: grid; gap: 0.25rem; }

.admin__nav-label {
  margin: 0;
  font-size: 0.7rem;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.admin__nav-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }

.admin__nav-item {
  inline-size: 100%;
  padding: 0.4em 0.7em;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: inherit;
  font: inherit;
  font-size: 0.9rem;
  text-align: start;
  cursor: pointer;
}

.admin__nav-item:hover { background: var(--surface-muted); }

/* The current section is marked by weight and a rule, not by a filled block:
   seventeen filled blocks competing for attention is what this replaced. */
.admin__nav-item.is-current {
  background: var(--surface-muted);
  box-shadow: inset 3px 0 0 var(--accent-primary);
  font-weight: var(--weight-semibold);
}

/* On a narrow screen the same list runs across the top. A sidebar that eats
   half a phone is not a sidebar. */
@media (max-width: 59.99rem) {
  .admin__nav {
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    overflow-x: auto;
    padding-block-end: var(--space-2xs);
  }
  .admin__nav-list { grid-auto-flow: column; grid-auto-columns: max-content; gap: var(--space-2xs); }
  .admin__nav-item { white-space: nowrap; }
  .admin__nav-item.is-current { box-shadow: inset 0 -3px 0 var(--accent-primary); }
}

/* One heading in one place, in every section, so a reader is not hunting for
   what this screen is each time they arrive. */
.admin__panel-head {
  padding-block-end: var(--space-sm);
  margin-block-end: var(--space-md);
  border-block-end: 1px solid var(--border-subtle);
}

.admin__panel-group {
  margin: 0;
  font-size: 0.7rem;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.admin__panel-title { margin: 0.1rem 0 0; font-size: var(--text-2xl); line-height: 1.2; }
.admin__panel-detail { margin: 0.2rem 0 0; color: var(--text-secondary); }

.admin__panel {
  padding: var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-page);
}

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

.admin__form { display: grid; gap: var(--space-2xs); max-inline-size: 30rem; }
.admin__form--inline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  max-inline-size: none;
}

.admin__label { font-size: 0.8rem; color: var(--text-secondary); }
.admin__row { display: flex; gap: var(--space-2xs); flex-wrap: wrap; align-items: center; }

.admin__field,
.admin__select {
  padding: 0.45em 0.6em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
}

.admin__field { min-inline-size: 12rem; flex: 1 1 12rem; }

.admin__button {
  display: inline-block;
  padding: 0.45em 0.9em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.82rem;
  text-decoration: none;
  cursor: pointer;
}

.admin__button--primary {
  border-color: transparent;
  background: var(--accent-primary);
  color: var(--on-accent-primary);
  font-weight: var(--weight-semibold);
}

.admin__button--quiet { border-color: var(--border-subtle); color: var(--text-secondary); }

.admin__link {
  border: 0;
  background: none;
  color: var(--text-brand);
  font: inherit;
  text-align: start;
  text-decoration: underline;
  cursor: pointer;
}

.admin__notice {
  margin-block-end: var(--space-sm);
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  border-inline-start: 3px solid var(--accent-secondary);
  font-size: 0.85rem;
}

.admin__notice--error { border-inline-start-color: var(--text-danger); color: var(--text-danger); }

/* --- tables --------------------------------------------------------------- */

.admin__table {
  inline-size: 100%;
  margin-block: var(--space-2xs) var(--space-md);
  border-collapse: collapse;
  font-size: 0.85rem;
}

.admin__table th,
.admin__table td {
  padding: 0.5em 0.6em;
  border-block-end: 1px solid var(--border-subtle);
  text-align: start;
  vertical-align: top;
}

.admin__table th {
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.admin__actions { display: flex; gap: var(--space-2xs); flex-wrap: wrap; }
.admin__detail { max-inline-size: 22rem; overflow-wrap: anywhere; color: var(--text-secondary); }
.admin__plain { margin: 0; padding-inline-start: 1.2em; color: var(--text-secondary); font-size: 0.88rem; }

/* --- a session's edits ---------------------------------------------------- */

.admin__edits { display: grid; gap: var(--space-md); }

.admin__edit {
  padding: var(--space-sm);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
}

.admin__address { margin: 0; font-size: 0.72rem; color: var(--text-muted); letter-spacing: var(--tracking-wide); }
.admin__baseline { margin: 0.3em 0 0.6em; color: var(--text-secondary); text-decoration: line-through; }
.admin__versions { display: grid; gap: var(--space-2xs); margin: 0; padding-inline-start: 1.2em; }
.admin__versions .is-withdrawn { opacity: 0.55; }
.admin__value { margin: 0; font-weight: var(--weight-medium); }
.admin__meta { margin: 0.15em 0 0; color: var(--text-muted); font-size: 0.75rem; }

@media print { .admin { display: none; } }

.admin__session-head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: start;
  justify-content: space-between;
}

.admin__address {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: baseline;
  justify-content: space-between;
}

.admin__address-link { font-size: 0.72rem; white-space: nowrap; }

.admin__setting {
  display: flex;
  gap: var(--space-md);
  align-items: start;
  justify-content: space-between;
  padding-block: var(--space-sm);
  border-block-end: 1px solid var(--border-subtle);
  max-inline-size: 48rem;
}

.admin__setting .admin__meta { max-inline-size: 36rem; }

/* --- the grid editor ------------------------------------------------------ */

.admin__grid-session {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
  margin-block-end: var(--space-md);
  padding: var(--space-sm);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
}

.admin__grid-session .admin__meta { flex: 1 1 16rem; }

.admin__grid-body {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr);
  align-items: start;
}

@media (width < 60rem) {
  .admin__grid-body { grid-template-columns: minmax(0, 1fr); }
}

.admin__grid-sections { display: grid; gap: var(--space-2xs); }

.admin__grid-list {
  display: grid;
  gap: 0.1rem;
  max-block-size: 34rem;
  overflow-y: auto;
  padding-inline-start: 0;
  list-style: none;
}

.admin__grid-tab {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  justify-content: space-between;
  inline-size: 100%;
  padding: 0.35em 0.6em;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: inherit;
  font: inherit;
  font-size: 0.78rem;
  text-align: start;
  cursor: pointer;
}

.admin__grid-tab:hover { background: var(--surface-muted); }

.admin__grid-tab.is-current {
  background: var(--accent-primary);
  color: var(--on-accent-primary);
  font-weight: var(--weight-semibold);
}

.admin__grid-count {
  flex: none;
  min-inline-size: 1.4em;
  padding: 0.05em 0.35em;
  border-radius: 999px;
  background: var(--accent-secondary);
  color: var(--on-accent-secondary);
  font-size: 0.62rem;
  text-align: center;
}

.admin__grid-table { table-layout: fixed; }
.admin__grid-table th:nth-child(1) { inline-size: 22%; }
.admin__grid-table th:nth-child(2),
.admin__grid-table th:nth-child(3) { inline-size: 35%; }

.admin__grid-key { display: grid; gap: 0.15em; font-size: 0.78rem; }
.admin__grid-current { color: var(--text-secondary); }

.admin__grid-input {
  inline-size: 100%;
  padding: 0.4em 0.5em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  font-size: 0.82rem;
  resize: vertical;
}

/* A cell somebody has already proposed something in. */
.admin__grid-input.is-changed {
  border-color: var(--accent-secondary);
  background: color-mix(in srgb, var(--accent-secondary) 10%, var(--surface-page));
}

.admin__grid-input:disabled { background: var(--surface-muted); cursor: not-allowed; }

/* A short read of the log before the log itself: totals, and anything failing. */
.admin__summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--space-sm);
  margin-block: var(--space-md);
}

.admin__figure {
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
}

.admin__figure-number {
  margin: 0;
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  line-height: 1.1;
}

/* Failed sign-ins are the one thing here worth catching an eye. */
.admin__figure-number.is-warning { color: var(--text-danger); }
.admin__table tr.is-warning { background: var(--surface-danger-soft); }

/* --- the picture library ----------------------------------------------------------- */

.admin__drop {
  display: grid;
  gap: var(--space-2xs);
  justify-items: center;
  padding: var(--space-lg);
  border: 2px dashed var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
  text-align: center;
  margin-block: var(--space-md);
}

.admin__drop.is-over { border-color: var(--accent-secondary); background: var(--surface-raised); }
.admin__drop-lead { margin: 0; font-weight: var(--weight-semibold); }
.admin__drop-button { margin-block-start: var(--space-xs); cursor: pointer; }
.admin__file { position: absolute; inline-size: 1px; block-size: 1px; opacity: 0; pointer-events: none; }

.admin__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: var(--space-sm);
  margin-block-start: var(--space-md);
}

.admin__tiles--small { grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); }

/*
 * The panel for the picture somebody just clicked, in the grid rather than
 * above it. Spanning every column puts it on its own row directly beneath the
 * tile, so what opened is next to what was clicked.
 */
.admin__tiles-detail {
  grid-column: 1 / -1;
}

.admin__tile {
  margin: 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-raised);
}

/* A hidden picture is still listed — it is easier to bring one back than to
   wonder where it went — so it is dimmed rather than removed. */
.admin__tile.is-off { opacity: 0.5; }

.admin__tile-picture {
  display: block;
  inline-size: 100%;
  padding: 0;
  border: 0;
  background: var(--surface-muted);
  cursor: pointer;
}

.admin__tile-picture img { display: block; inline-size: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.admin__tile-caption { padding: var(--space-2xs) var(--space-xs); }
.admin__tile-name { margin: 0; font-size: var(--text-sm); font-weight: var(--weight-semibold); }

.admin__detail-panel {
  display: grid;
  gap: var(--space-md);
  padding: var(--space-md);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  margin-block: var(--space-md);
}

@media (min-width: 60rem) {
  .admin__detail-panel { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.admin__detail-picture img { inline-size: 100%; border-radius: var(--radius-sm); }
.admin__detail-fields { display: grid; gap: var(--space-sm); align-content: start; }

.admin__stack-label { display: grid; gap: 0.25rem; }
.admin__stack-label > span:first-child { font-size: var(--text-sm); font-weight: var(--weight-semibold); }

/* --- the entry editors ------------------------------------------------------------- */

.admin__table--entries td { vertical-align: top; }
.admin__thumb-cell { inline-size: 6rem; }
.admin__thumb { inline-size: 5rem; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius-sm); }

.admin__table tr.is-off td { opacity: 0.55; }
.admin__table tr.is-untouched td { color: var(--text-secondary); }

.admin__standing { font-size: var(--text-sm); }
.admin__standing.is-on { color: var(--text-brand); }
.admin__standing.is-off { color: var(--text-secondary); }
.admin__standing.is-waiting { color: var(--text-danger); }

.admin__entry { display: grid; gap: var(--space-md); padding-block: var(--space-sm); }
@media (min-width: 64rem) {
  .admin__entry { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
.admin__entry-fields { display: grid; gap: var(--space-sm); align-content: start; }

.admin__schedule {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: end;
  padding: var(--space-sm);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
}

.admin__inline-label { display: grid; gap: 0.25rem; font-size: var(--text-sm); }
.admin__inline-label--check { display: flex; gap: 0.4rem; align-items: center; }
.admin__field--narrow { inline-size: 6rem; }
.admin__field--tall { resize: vertical; }
.admin__row { display: flex; flex-wrap: wrap; gap: var(--space-xs); align-items: center; }

/* --- notes -------------------------------------------------------------------------- */

.admin__marker {
  display: inline-grid;
  place-items: center;
  min-inline-size: 1.25rem;
  padding-inline: 0.3rem;
  margin-inline-start: 0.4rem;
  border-radius: 999px;
  background: var(--surface-muted);
  color: var(--text-secondary);
  font-size: 0.75rem;
  line-height: 1.5;
}

/* Open notes are the ones worth looking at; settled ones are just history. */
.admin__marker.is-open { background: var(--surface-danger-soft); color: var(--text-danger); }

.admin__notes { margin-block-start: var(--space-sm); display: grid; gap: var(--space-xs); }
.admin__note-form { display: grid; gap: var(--space-2xs); }
.admin__note-list { display: grid; gap: var(--space-xs); padding: 0; margin: 0; list-style: none; }

.admin__note {
  padding: var(--space-xs);
  border: 1px solid var(--border-subtle);
  border-inline-start: 3px solid var(--accent-secondary);
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
}

.admin__note.is-settled { border-inline-start-color: var(--border-subtle); opacity: 0.7; }

/* The error log. The message is the part somebody scans for, so it is the only
   thing here set larger than the surrounding notes; the trace is folded away
   because it is long, useful, and would otherwise push everything else off a
   phone. */
.admin__error-message {
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}

.admin__error-agent {
  overflow-wrap: anywhere;
  opacity: 0.8;
}

.admin__error-stack summary {
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.admin__pre {
  margin: var(--space-2xs) 0 0;
  padding: var(--space-xs);
  overflow-x: auto;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-xs);
  line-height: 1.5;
  white-space: pre;
  background: var(--surface-muted);
  border-radius: var(--radius-sm);
}
.admin__note-body { margin: 0; white-space: pre-wrap; }
.admin__note-tags { margin: 0.25rem 0 0; display: flex; gap: 0.3rem; flex-wrap: wrap; }

.admin__tag {
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: var(--surface-raised);
  font-size: 0.75rem;
  color: var(--text-secondary);
}

/* --- what people sent --------------------------------------------------------------- */

.admin__cards { display: grid; gap: var(--space-sm); margin-block-start: var(--space-md); }
@media (min-width: 60rem) { .admin__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.admin__card {
  padding: var(--space-sm);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  display: grid;
  gap: var(--space-2xs);
  align-content: start;
}

.admin__card.is-off { opacity: 0.6; }
.admin__card-body { margin: 0; white-space: pre-wrap; }
.admin__card-more summary { cursor: pointer; font-size: var(--text-sm); color: var(--text-secondary); }
.admin__link.is-current { font-weight: var(--weight-semibold); text-decoration: none; }

.admin__pairs { display: grid; grid-template-columns: auto 1fr; gap: 0.2rem var(--space-sm); margin: 0; }
.admin__pairs dt { font-weight: var(--weight-semibold); color: var(--text-secondary); }
.admin__pairs dd { margin: 0; }

.admin__quote {
  margin: var(--space-xs) 0;
  padding-inline-start: var(--space-sm);
  border-inline-start: 3px solid var(--accent-secondary);
  white-space: pre-wrap;
}

.admin__open-row > td { background: var(--surface-muted); }
.admin__chooser { display: grid; gap: var(--space-sm); }


/* A control that pairs a word with a drawing sits them on one line. */
.admin__link--back,
.admin__address-link {
  display: inline-flex;
  gap: 0.3rem;
  align-items: center;
}


/* The sign-in code, shown only on a development machine. Marked out clearly so
   nobody mistakes it for part of the real sign-in screen. */
.admin__dev {
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-sm) var(--space-md);
  margin-block: var(--space-sm);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
}

.admin__dev-label {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.admin__dev-code {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-2xl);
  letter-spacing: 0.3em;
  font-variant-numeric: tabular-nums;
}


/* The two order arrows. Small, quiet, and beside the row they move. */
.admin__move { display: inline-flex; gap: 0.1rem; margin-inline-start: 0.4rem; }

.admin__icon-button {
  display: grid;
  place-items: center;
  padding: 0.1rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
}

.admin__icon-button:hover:not(:disabled) { border-color: var(--border-subtle); color: var(--text-primary); }

/* Disabled rather than hidden: an arrow that disappears at the top of a list
   makes the row jump as you move through it. */
.admin__icon-button:disabled { opacity: 0.3; cursor: default; }


/* Pictures grouped by where they sit on the site. */
.admin__group { margin-block-start: var(--space-lg); }

.admin__group-title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

/* A place whose picture has been changed from the built-in one. */
.admin__tile.is-changed { border-color: var(--accent-secondary); }

@media (min-width: 48rem) {
  .admin__contact-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .admin__contact-fields > p,
  .admin__contact-fields > .admin__notes { grid-column: 1 / -1; }
}


/* A field whose value was refused, and the sentence saying why. */
.admin__stack-label.is-wrong .admin__field { border-color: var(--text-danger); }

.admin__problem {
  margin: 0.25rem 0 0;
  font-size: var(--text-sm);
  color: var(--text-danger);
}

/* One number and what it answers, kept together so the marks read as belonging
   to the number above them rather than floating beside it. */
.admin__numbers { display: grid; gap: var(--space-md); }

@media (min-width: 48rem) {
  .admin__numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.admin__number {
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-sm);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
  align-content: start;
}

.admin__marks { display: flex; flex-wrap: wrap; gap: var(--space-md); }

/* --- what is happening to each file being uploaded -------------------------------- */

.admin__queue {
  margin-block: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.admin__queue-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-sm); }
.admin__queue-title { margin: 0; font-weight: var(--weight-semibold); }
.admin__queue-list { list-style: none; margin: var(--space-sm) 0 0; padding: 0; display: grid; gap: var(--space-sm); }
.admin__queue-item { display: grid; gap: 0.2rem; }
.admin__queue-row { display: flex; justify-content: space-between; gap: var(--space-sm); }
.admin__queue-name { font-size: var(--text-sm); word-break: break-all; }

.admin__bar {
  block-size: 0.35rem;
  border-radius: 999px;
  background: var(--surface-muted);
  overflow: hidden;
}

/* The same bar sitting in a table cell beside its own number, on the Statistics
   screen. The block form above fills its container, which is right for an upload
   in progress and wrong next to a percentage that has to stay on the same line. */
.admin__bar--inline {
  display: inline-block;
  inline-size: 5rem;
  vertical-align: middle;
}

.admin__bar-fill {
  display: block;
  block-size: 100%;
  background: var(--accent-secondary);
  /* Only the width animates. A bar that eases its colour as well reads as
     decoration, and this one is reporting a fact. */
  transition: width 140ms linear;
}

/* A file already held is not a failure and must not look like one; a file that
   failed has to be findable in a list of twelve. */
.admin__queue-item.is-done .admin__bar-fill { background: var(--text-brand); }
.admin__queue-item.is-duplicate .admin__bar-fill { background: var(--border-strong); }
.admin__queue-item.is-failed .admin__bar-fill { background: var(--text-danger); }
.admin__queue-item.is-failed .admin__queue-name { color: var(--text-danger); }


/* The nav sticks to the top on a narrow screen, so the section you are reading
   can be changed without scrolling back up to the list. */
@media (max-width: 59.99rem) {
  .admin__nav {
    position: sticky;
    inset-block-start: 0;
    z-index: 2;
    background: var(--surface-page);
    scroll-padding-inline: var(--space-md);
  }

  /* A heading scrolled to sits under the sticky list without this. */
  .admin__panel-head { scroll-margin-block-start: 5.5rem; }
}

/* The invitation, as it will arrive. */
.admin__invite { grid-template-columns: minmax(0, 1fr); }

@media (min-width: 64rem) {
  .admin__invite { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.admin__letter {
  margin-block: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
}

.admin__letter-subject { margin: 0 0 var(--space-xs); font-weight: var(--weight-semibold); }

.admin__letter-body {
  margin: 0;
  font: inherit;
  white-space: pre-wrap;
  color: var(--text-secondary);
}

/* --- the wording grid on a narrow screen ------------------------------------------ */

@media (max-width: 60rem) {
  /* The table is drawn inside the list, under the row that opened it, so the
     form is where the finger was rather than below sixty other sections. */
  .admin__grid-inline {
    padding: var(--space-sm) 0 var(--space-md);
    border-inline-start: 3px solid var(--accent-primary);
    padding-inline-start: var(--space-sm);
    margin-block-start: var(--space-2xs);
  }

  .admin__grid-inline .admin__grid-table { margin-block-start: var(--space-2xs); }

  /* Three columns of prose do not fit a phone. Each string becomes a block:
     what it is, what it says, and a box to say something else. */
  .admin__grid-inline .admin__grid-table,
  .admin__grid-inline .admin__grid-table tbody,
  .admin__grid-inline .admin__grid-table tr,
  .admin__grid-inline .admin__grid-table td { display: block; inline-size: auto; }

  .admin__grid-inline .admin__grid-table thead { display: none; }

  .admin__grid-inline .admin__grid-table tr {
    padding-block: var(--space-sm);
    border-block-end: 1px solid var(--border-subtle);
  }

  .admin__grid-inline .admin__grid-key { font-weight: var(--weight-semibold); }

  .admin__grid-inline .admin__grid-current {
    color: var(--text-secondary);
    margin-block: 0.2rem;
  }

  .admin__grid-inline .admin__grid-input { inline-size: 100%; min-block-size: 3.5rem; }

  /* The list of sections is the navigation here, so the chosen one is marked
     down its side as well as filled, and stays readable while its table is
     open beneath it. */
  .admin__grid-list li.is-open { margin-block-end: var(--space-sm); }
}

/* --- where somebody lands --------------------------------------------------------- */

.admin__start-group { margin-block-start: var(--space-lg); }

.admin__start-cards {
  display: grid;
  gap: var(--space-sm);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  margin-block-start: var(--space-sm);
}

.admin__start-card {
  display: grid;
  gap: 0.2rem;
  align-content: start;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.admin__start-card:hover { border-color: var(--border-strong); background: var(--surface-muted); }
.admin__start-title { font-weight: var(--weight-semibold); }
.admin__start-detail { font-size: var(--text-sm); color: var(--text-secondary); }
.admin__tile-tags { font-size: 0.75rem; }

/* Hiding a whole section, above the list of what is in it. */
.admin__section-control {
  margin-block: var(--space-sm) var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
}

.admin__section-control summary {
  display: flex;
  gap: var(--space-sm);
  align-items: baseline;
  cursor: pointer;
  font-weight: var(--weight-semibold);
}

/* --- renderings and versions ------------------------------------------------------- */

.admin__renderings, .admin__versions {
  display: grid;
  gap: 0.3rem;
  padding: var(--space-sm) 0;
  border-block-start: 1px solid var(--border-subtle);
}

.admin__rendering-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-block: var(--space-2xs);
}

.admin__rendering {
  display: grid;
  gap: 0.2rem;
  justify-items: center;
  padding: 0.3rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--surface-page);
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.admin__rendering img {
  inline-size: 6rem;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/* The one this picture is shown as. Marked by a border rather than a fill, so
   the thumbnails stay comparable — which is the whole reason they are here. */
.admin__rendering.is-current {
  border-color: var(--accent-primary);
  box-shadow: inset 0 0 0 1px var(--accent-primary);
  font-weight: var(--weight-semibold);
}

/* HOW A PICTURE SITS IN A FRAME
 *
 * The stage is the story card's shape, because that is the frame that crops
 * hardest — what somebody sees here is what that card will show. The picture
 * inside is held by the same two custom properties the site uses, so this is
 * not a drawing of the result, it is the result.
 */
.admin__focal {
  display: grid;
  gap: var(--space-3xs);
  margin-block-start: var(--space-sm);
  max-inline-size: 22rem;
}

.admin__hold-stage {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
  cursor: grab;
  touch-action: none;
}

.admin__hold-stage:active {
  cursor: grabbing;
}

.admin__hold-stage img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: var(--hold-x, 50%) var(--hold-y, 50%);
  scale: var(--hold-zoom, 1);
  transform-origin: var(--hold-x, 50%) var(--hold-y, 50%);
  display: block;
  user-select: none;
}

.admin__hold-slider {
  inline-size: 100%;
  accent-color: var(--accent-primary);
}



/* What a tile says about itself before you open it. */
.admin__tile-picture { position: relative; }

.admin__tile-badges {
  position: absolute;
  inset-block-start: 0.3rem;
  inset-inline-start: 0.3rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
}

.admin__badge {
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--text-secondary);
  font-size: 0.65rem;
  letter-spacing: 0.02em;
  box-shadow: var(--shadow-sm);
}

.admin__badge.is-marked { background: var(--accent-primary); color: var(--on-accent-primary); }

/* Missing renderings are a thing to act on, not an error — the picture works,
   it simply has no watermarked copy yet. */
.admin__badge.is-missing { background: var(--surface-danger-soft); color: var(--text-danger); }

.admin__needs-rendering {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
  justify-content: space-between;
}

/* --- the media guide --------------------------------------------------------------- */

.admin__mark-preview {
  display: grid;
  place-items: center;
  padding: var(--space-md);
  background: var(--surface-muted);
}

.admin__mark-preview img { inline-size: 5rem; block-size: 5rem; object-fit: contain; }

/* The Adinkra previews are live sprite symbols rather than pictures, so they
   need the size the tile gives its images. Without this they inherit the 1em
   the mark uses inline and arrive at seventeen pixels. */
.admin__mark-preview svg { inline-size: 5rem; block-size: 5rem; }

.admin__palette { margin-block: var(--space-md); }

.admin__palette-name {
  margin: 0 0 var(--space-2xs);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.admin__swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
  gap: var(--space-xs);
}

.admin__swatch { display: grid; gap: 0.15rem; }

.admin__swatch-chip {
  display: block;
  block-size: 2.6rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.admin__swatch-chip--small { inline-size: 1rem; block-size: 1rem; display: inline-block; }
.admin__swatch-inline { display: inline-flex; gap: 0.35rem; align-items: center; }
.admin__swatch-name { margin: 0; font-size: 0.72rem; color: var(--text-secondary); }

/* A code is what somebody came for, so it is a button, not text to select. */
.admin__copy {
  padding: 0.1rem 0.3rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: inherit;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.72rem;
  text-align: start;
  cursor: pointer;
}

.admin__copy:hover { border-color: var(--border-subtle); background: var(--surface-muted); }
.admin__copy[data-copied] { border-color: var(--accent-primary); }

.admin__font-sample { margin: 0; font-size: var(--text-lg); }

/* Seven themes will not fit a phone; the table scrolls inside itself rather
   than the page scrolling sideways. */
.admin__scroller { overflow-x: auto; }
.admin__theme-table { min-inline-size: 42rem; }

/* --- saying that something saved --------------------------------------------------- */

/*
 * These screens save when you leave a field, with no button — so a save with
 * no sign is indistinguishable from nothing happening, and the honest response
 * to that is to type it again or stop trusting the screen.
 *
 * The glow is for the moment, aimed at the eye that is still on the field just
 * left. The line stays, because five minutes later the question is no longer
 * "did that save" but "did I save this one at all".
 */
@keyframes admin-saved {
  from { box-shadow: 0 0 0 3px var(--accent-secondary); border-color: var(--accent-primary); }
  to   { box-shadow: 0 0 0 0 transparent; }
}

.admin__field.is-just-saved,
.admin__select.is-just-saved {
  animation: admin-saved 2.4s ease-out;
  border-color: var(--accent-primary);
}

.admin__saved {
  margin: 0.2rem 0 0;
  font-size: 0.75rem;
  color: var(--text-secondary);
  transition: color 600ms ease;
}

.admin__saved.is-fresh {
  color: var(--text-brand);
  font-weight: var(--weight-semibold);
}

/* Somebody who has asked not to be moved about should not be flashed at. */
@media (prefers-reduced-motion: reduce) {
  .admin__field.is-just-saved,
  .admin__select.is-just-saved { animation: none; }
}

/* Said while somebody is deciding whether to type their address, not after. */
.admin__gate-note {
  margin-block-start: var(--space-sm);
  padding-block-start: var(--space-sm);
  border-block-start: 1px solid var(--border-subtle);
  max-inline-size: 34rem;
}


/* The Structure screen: chapters sit inside the page they belong to. */
.admin__note-list--nested {
  margin-block-start: var(--space-2xs);
  padding-inline-start: var(--space-sm);
  border-inline-start: 2px solid var(--border-subtle);
}

.admin__note.is-nested {
  border-inline-start-color: transparent;
  background: transparent;
}


/* Other ways to reach an account holder, under their row. */
.admin__contacts { display: grid; gap: var(--space-2xs); }
.admin__contact-list { display: grid; gap: var(--space-3xs); }
.admin__contact-list li { display: flex; gap: var(--space-2xs); align-items: baseline; flex-wrap: wrap; }
.admin__field--tight { max-inline-size: 12rem; }


/*
 * The wait while the page works out who is here.
 *
 * Deliberately quiet: a mark and a word. Anything more definite would be a
 * claim the page cannot yet make.
 */
.admin__waiting {
  display: grid;
  gap: var(--space-sm);
  place-items: center;
  min-block-size: 40vh;
  padding: var(--space-xl) var(--space-md);
  text-align: center;
}

.admin__waiting-mark .brand-symbol {
  inline-size: 4rem;
  block-size: 4rem;
  color: var(--text-brand);
  animation: admin-waiting 1.8s ease-in-out infinite;
}

.admin__waiting-word {
  margin: 0;
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
}

@keyframes admin-waiting {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  /* The pulse is decoration; the mark says enough standing still. */
  .admin__waiting-mark .brand-symbol { animation: none; opacity: 0.8; }
}

/* PEOPLE, READ BEFORE CHANGED
 *
 * The list answers who is here and what they may do; nothing on it changes
 * anything. Editing opens under the person asked for, so what you are changing
 * is directly beneath the name you clicked.
 */
.admin__table--clickable tbody tr:hover .admin__person-open {
  text-decoration: underline;
}

.admin__table--clickable tbody tr.is-open > td {
  background: var(--surface-muted);
}

.admin__person-open {
  font: inherit;
  text-align: start;
}

.admin__person-editor {
  display: grid;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
}

.admin__person-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  align-items: center;
}

/* An action that is offered rather than presented: a line of text until
 * somebody wants it, and the form underneath once they do. */
.admin__add-link {
  display: inline-block;
  margin-block-start: var(--space-md);
  font-weight: var(--weight-semibold);
}

.admin__form--adding {
  margin-block-start: var(--space-2xs);
  padding: var(--space-sm);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
}


/*
 * Print.
 *
 * The website is the brochure, so printing any page has to produce a piece you
 * would be willing to hand someone: a branded masthead, the page's own content
 * laid out on A4, the four signature words across the foot, and none of the
 * interactive chrome.
 *
 * Page size, margins and body size come from theme.json (`print`), compiled
 * into the --print-* custom properties alongside the rest of the tokens.
 */

/* Hidden on screen; print.css is the only place these appear. */
.print-only {
  display: none;
}

@media print {
  @page {
    size: var(--print-page-size);
    margin: var(--print-margin);
  }

  :root {
    /* Paper is white whichever theme the visitor was reading in. */
    color-scheme: light;
  }

  html,
  body {
    background: #fff;
    color: #000;
    font-size: var(--print-body-size);
    line-height: var(--print-body-leading);
  }

  /* Interactive chrome has no meaning on paper. */
  .masthead,
  .site-footer,
  .skip-link,
  .theme-switch,
  .filter-bar,
  .action-group,
  .gallery__zoom,
  .article__back,
  .pledge__submit,
  .lightbox,
  [data-filter-hidden] {
    display: none !important;
  }

  .print-only {
    display: block;
  }

  /* --- sheet masthead ------------------------------------------------- */

  .print-masthead {
    display: flex;
    flex-wrap: wrap;
    gap: 6mm;
    align-items: flex-end;
    justify-content: space-between;
    padding-block-end: 3mm;
    margin-block-end: 6mm;
    border-block-end: 0.8mm solid var(--accent-secondary);
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .print-masthead .lockup {
    --lockup-symbol: 16mm;

    color: #000;
  }

  .print-masthead__aside {
    text-align: end;
  }

  .print-masthead__strapline {
    font-family: var(--font-display);
    font-size: 8pt;
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--text-brand);
  }

  .print-masthead__title {
    font-family: var(--font-display);
    font-size: 11pt;
    font-weight: var(--weight-semibold);
  }

  /* --- page body ------------------------------------------------------ */

  .section {
    padding-block: 4mm;
    background: transparent !important;
    color: #000 !important;
  }

  .section--feature,
  .section--feature-deep,
  .section--feature-soft,
  .section--feature *,
  .section--feature-deep *,
  .section--feature-soft * {
    color: #000 !important;
  }

  .hero,
  .page-header {
    padding-block: 0 4mm;
    background: transparent !important;
  }

  .hero__wave,
  .cta-band__watermark,
  .strapline::before {
    display: none !important;
  }

  /* The strapline and the mark are already in the printed masthead. */
  .hero .strapline,
  .page-header .strapline,
  .hero__lockup {
    display: none;
  }

  .hero__brand {
    gap: 3mm;
  }

  /* The printed masthead already carries the signature as the page title. */
  .signature-strip--hero {
    display: none;
  }

  .container {
    max-inline-size: none;
    padding-inline: 0;
  }

  h1 {
    font-size: 22pt;
  }

  h2 {
    font-size: 15pt;
  }

  h3 {
    font-size: 11.5pt;
  }

  h1,
  h2,
  h3 {
    break-after: avoid;
  }

  p,
  li,
  figure,
  .step,
  .principle,
  .contribution,
  .union,
  .story-card,
  .lineage__item,
  .value-grid__item,
  .faq__item {
    break-inside: avoid;
  }

  /* Accents carry the brand onto paper; everything else is ink on white. */
  .rule,
  .medallion,
  .step__medallion,
  .step__number,
  .value-grid__medallion,
  .contribution__medallion,
  .principle__icon,
  .union,
  .print-colophon__band {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  /* Feathered edges are a screen device; on paper they read as a printing fault. */
  .frame--feathered .image,

  .image__img {
    max-block-size: 8cm;
    object-fit: contain;
  }


  /* Say where a link goes, unless it is an in-page anchor. */
  .prose a[href^="http"]::after,
  .contact-list__value a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }

  /* --- sheet colophon ------------------------------------------------- */

  .print-colophon {
    margin-block-start: 5mm;
    /* Keep the colophon with the content it closes rather than letting it
       start a page of its own. */
    break-before: avoid;
    break-inside: avoid;
    text-align: center;
  }

  .cta-band {
    padding-block: 4mm 0;
    break-after: avoid;
  }

  .print-colophon__band {
    padding: 2.5mm;
    background: var(--surface-signature);
    color: var(--on-signature);
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .print-colophon__band .signature-strip {
    font-size: 8pt;
    letter-spacing: 0.22em;
    color: var(--on-signature);
  }

  .print-colophon__line {
    margin-block-start: 2mm;
    font-size: 7.5pt;
    color: #444;
  }
}

@media print {
  /*
   * The living panel is not a control on paper: the background pictures and
   * the transport go, and every paragraph prints in turn beneath the title.
   */
  .living-panel__stage,
  .living-panel__veil,
  .living-panel__transport {
    display: none !important;
  }

  .living-panel {
    padding-block: 0 4mm;
    background: transparent !important;
  }

  .living-panel__inner {
    gap: 4mm;
  }

  /*
   * Paper cannot cycle, so the cascade is laid out instead: every title with
   * its paragraphs beneath it, in order. The pictures are dropped — they were
   * the panel's background, not its content.
   */
  .living-panel__reading,
  .living-panel__headers,
  .living-panel__titles,
  .living-panel__scenes {
    display: contents;
  }

  /* `display: contents` lifts both stacks into this grid, and each line then
     takes the place it holds in the cascade read end to end. */
  .living-panel__inner {
    display: flex;
    flex-direction: column;
  }

  .living-panel__title {
    order: 0;
  }

  .living-panel__header,
  .living-panel__title-line,
  .living-panel__paragraph {
    order: var(--flow);
  }

  .living-panel__header {
    display: grid;
    gap: 1mm;
    justify-items: center;
    margin-block-start: 6mm;
    break-after: avoid;
  }

  .living-panel .action-group {
    order: 9999;
  }

  .living-panel__header,
  .living-panel__title-line,
  .living-panel__paragraph {
    grid-area: auto;
    opacity: 1 !important;
    translate: none !important;
  }

  .living-panel__title-line {
    margin-block-start: 3mm;
    font-size: 12pt;
  }

  .living-panel__title-line:empty {
    display: none;
  }

  /* The mark is already in the printed masthead. */
  .living-panel__lockup {
    display: none;
  }

  .living-panel__signature {
    display: none;
  }
}

