/* tokens.css */
/*
 * Design tokens (context/guidelines/brand-guide.md). Components use these
 * custom properties, never raw hex values, so a later dark theme only redefines
 * this file.
 */
:root {
  --navy: #1f3869;
  --navy-deep: #00182f;
  --link: #2d5ba8;
  --link-hover: #1e4485;
  --gold: #c9a45c;
  --gold-deep: #8a6a2b;
  --text: #2b313b;
  --text-muted: #5a6270;
  --text-on-dark: #d2d6de;
  --on-dark: #ffffff;
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-alt: #f2f4f7;
  --border: #dde2e8;
  --border-on-dark: rgb(255 255 255 / 14%);
  --focus: var(--link);
  --focus-on-dark: var(--gold);

  --font-heading: "Noto Sans", "Noto Sans CJK SC", "Noto Sans Fallback Arial", "Noto Sans Fallback Roboto", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
  --font-body: "Noto Sans", "Noto Sans CJK SC", "Noto Sans Fallback Arial", "Noto Sans Fallback Roboto", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;

  /* Dotted world maps (assets/brand/, local-scripts/world-map.php): background texture only. */
  --map-light: url("/assets/brand/world-dots-light.3967669bb4.svg");
  --map-dark: url("/assets/brand/world-dots-dark.c79090bb98.svg");
  /* The North Atlantic as flat shapes (local-scripts/atlantic-map.php), after the old site's band. */
  /* The arrow of main actions (button--go, link-cta), as a mask: the same stroke as assets/icons/arrow-right.svg. */
  --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E");
  /* Plus and minus of a box that opens (On this page), as masks. */
  --plus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E");
  --minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");
  --map-atlantic: url("/assets/brand/atlantic-map.a68c0463ca.svg");
  /* Sections of the flat world map, Equal Earth (local-scripts/world-land-map.php): Africa, Europe, the Middle East and South Asia. */
  --map-afro-eurasia: url("/assets/brand/world-land-afro-eurasia.6695788487.svg");

  --step--1: clamp(0.8125rem, 0.8rem + 0.08vw, 0.875rem);
  --step-0: clamp(1rem, 0.98rem + 0.1vw, 1.0625rem);
  --step-1: clamp(1.1875rem, 1.13rem + 0.3vw, 1.3125rem);
  --step-2: clamp(1.4375rem, 1.32rem + 0.6vw, 1.75rem);
  --step-3: clamp(1.75rem, 1.52rem + 1.15vw, 2.375rem);
  --step-4: clamp(2.125rem, 1.75rem + 1.9vw, 3.125rem);
  --step-5: clamp(2.375rem, 1.85rem + 2.6vw, 3.75rem);

  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-s: 0.75rem;
  --space-m: 1rem;
  --space-l: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;
  --space-3xl: clamp(3rem, 2rem + 5vw, 6rem);

  --measure: 68ch;
  --container: 76rem;
  --gutter: clamp(1rem, 0.5rem + 2.5vw, 2rem);
  --radius: 2px;
  --transition: 160ms ease;
}

/* fonts.css */
/*
 * Self-hosted brand font (SIL Open Font Licence, assets/fonts/OFL-NotoSans.txt):
 * Noto Sans as variable WOFF2 files, Latin and Latin Extended subsets as served
 * by Google Fonts, normal and italic, never loaded from a CDN. The build
 * rewrites these URLs to hashed names. Chinese uses the system CJK fonts named
 * in the font stacks.
 */
@font-face {
  font-family: "Noto Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/noto-sans-latin.51ca196f49.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Noto Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/noto-sans-latin-ext.6d5a793155.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Noto Sans";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/noto-sans-italic-latin.b21ff49bef.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Noto Sans";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/noto-sans-italic-latin-ext.7eccdb25ac.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/*
 * Until Noto Sans arrives (font-display: swap), text shows in Noto Sans CJK
 * where the system has it (Android, many Linux desktops: its Latin letters are
 * Noto Sans's own), otherwise in the system's Arial (Windows, macOS, iOS) or
 * Roboto, resized and given Noto
 * Sans's ascent and descent, so lines keep their length and height and the
 * page barely moves when the font swaps in. Measured in Chrome on this site's
 * own text (2026-10-23): Noto Sans sets 5.6% wider than Arial and 6.0% wider
 * than Roboto; its ascent is 1.069 em and its descent 0.293 em (the overrides
 * below are those divided by the size-adjust). Bold uses the same figures.
 */
@font-face {
  font-family: "Noto Sans Fallback Arial";
  font-weight: 400;
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans");
  size-adjust: 105.6%;
  ascent-override: 101.2%;
  descent-override: 27.7%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Noto Sans Fallback Arial";
  font-weight: 700;
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  size-adjust: 105.6%;
  ascent-override: 101.2%;
  descent-override: 27.7%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Noto Sans Fallback Roboto";
  font-weight: 400;
  src: local("Roboto"), local("Roboto-Regular"), local("Roboto Regular");
  size-adjust: 106%;
  ascent-override: 100.8%;
  descent-override: 27.6%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Noto Sans Fallback Roboto";
  font-weight: 700;
  src: local("Roboto Bold"), local("Roboto-Bold");
  size-adjust: 106%;
  ascent-override: 100.8%;
  descent-override: 27.6%;
  line-gap-override: 0%;
}

/* base.css */
/* Base: a small reset, typography and focus. Mobile first. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  overflow-wrap: break-word;
}

body:lang(zh-Hans) {
  line-height: 1.8;
}

h1,
h2,
h3,
h4 {
  margin: 0 0 var(--space-m);
  color: var(--navy);
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.2;
  text-wrap: balance;
}

/*
 * Chinese headings break at punctuation rather than inside a word (balance
 * alone splits 赋能社区，推动全球进步 as 推 / 动), and anywhere only when a line
 * would overflow.
 */
:lang(zh) :is(h1, h2, h3, h4, .hero__title) {
  word-break: keep-all;
  overflow-wrap: anywhere;
}

h1 {
  font-size: var(--step-4);
  letter-spacing: -0.02em;
  line-height: 1.12;
}

h2 {
  font-size: var(--step-3);
  letter-spacing: -0.015em;
}

h3,
h4 {
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.3;
}

/* Chinese is never tracked tighter: the glyphs would touch. */
:lang(zh-Hans) :is(h1, h2, h3, h4) {
  letter-spacing: 0;
}

p,
ul,
ol,
dl,
figure,
blockquote,
table {
  margin: 0 0 var(--space-m);
}

a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--link-hover);
}

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

/*
 * While a photograph downloads, its box (the build writes its width and height)
 * shows a quiet grey on light sections instead of blank white, so a slow
 * connection shows the page's shape at once. On the navy bands the navy
 * behind shows through instead (components.css).
 */
main img {
  background-color: var(--surface-alt);
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

.icon {
  display: inline-block;
  flex: none;
  width: 1.15em;
  height: 1.15em;
  vertical-align: -0.2em;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  --focus: var(--focus-on-dark);
  position: absolute;
  top: -10rem;
  left: var(--space-m);
  z-index: 10;
  padding: var(--space-xs) var(--space-m);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--navy);
  font-weight: 700;
}

.skip-link:focus {
  top: var(--space-m);
}

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

/* layout.css */
/* Layout: container, masthead (header and intro band), sections, footer. */
.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}

.main {
  display: block;
}

.section {
  padding-block: var(--space-3xl);
}

.section__title {
  margin-top: var(--space-2xl);
  margin-bottom: var(--space-l);
  font-size: var(--step-3);
}

.section__title:first-child {
  margin-top: 0;
}

/* A light grey section on a page that does not alternate (an index's text). */
.section--alt {
  background-color: var(--surface-alt);
}

/*
 * Designed pages alternate white and light grey sections after the hero
 * (white, grey, white...). Only .section elements count, so a navy band
 * between two sections does not break the rhythm.
 */
.page--sections .main > .section:nth-child(even of .section) {
  background-color: var(--surface-alt);
}

/*
 * Masthead: the deep navy band of the header, continued by the page's intro at
 * the top of <main>. The glows sit low in the intro so its top edge is plain
 * navy and the two parts meet without a seam.
 */
.masthead {
  background: var(--navy-deep);
  color: var(--text-on-dark);
  --focus: var(--focus-on-dark);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  padding-block: var(--space-m);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  color: var(--on-dark);
  text-decoration: none;
}

.brand:hover {
  color: var(--on-dark);
}

.brand .mark {
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--on-dark);
}

.brand__text {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
}

.brand__name {
  font-family: var(--font-heading);
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.brand__tagline {
  margin-top: 0.15rem;
  color: var(--text-on-dark);
  font-size: var(--step--1);
}

/* Menu: a disclosure on narrow screens, an always-open row on wide ones. */
.menu {
  position: static;
}

.menu__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-s);
  border: 1px solid color-mix(in srgb, var(--on-dark) 28%, transparent);
  border-radius: var(--radius);
  color: var(--on-dark);
  font-family: var(--font-heading);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  list-style: none;
  cursor: pointer;
}

.menu__toggle:hover {
  border-color: var(--on-dark);
}

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

.menu[open] .menu__panel {
  display: flex;
}

.menu__panel {
  flex-direction: column;
  gap: var(--space-l);
  width: 100%;
  padding-block: var(--space-m);
}

.nav__list,
.languages__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav__link {
  display: block;
  white-space: nowrap;
  padding: var(--space-xs) 0;
  color: var(--on-dark);
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
}

.nav__link:hover {
  box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--on-dark) 60%, transparent);
}

.nav__link[aria-current="page"] {
  box-shadow: inset 0 -2px 0 var(--gold);
}

.languages {
  color: var(--text-on-dark);
}

/* The language switcher: a disclosure showing the globe and the current language. */
.languages__menu {
  position: relative;
}

.languages__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-2xs) var(--space-s);
  border: 1px solid color-mix(in srgb, var(--on-dark) 28%, transparent);
  border-radius: var(--radius);
  color: var(--on-dark);
  font-size: var(--step--1);
  font-weight: 600;
  white-space: nowrap;
  list-style: none;
  cursor: pointer;
}

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

.languages__toggle::after {
  content: "";
  width: 0.4em;
  height: 0.4em;
  margin-left: var(--space-2xs);
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-20%) rotate(45deg);
}

.languages__menu[open] > .languages__toggle::after {
  transform: translateY(20%) rotate(-135deg);
}

.languages__toggle:hover {
  border-color: var(--on-dark);
}

.languages__list {
  flex-direction: column;
  margin-top: var(--space-xs);
}

.languages__item {
  display: inline-block;
  white-space: nowrap;
  padding: 0.1rem var(--space-xs);
  border-left: 2px solid transparent;
  color: var(--on-dark);
  font-size: var(--step--1);
  font-weight: 400;
  text-decoration: none;
}

a.languages__item:hover {
  background: color-mix(in srgb, var(--on-dark) 8%, transparent);
  color: var(--on-dark);
}

/* The current language: bold, with a short gold edge on its left. */
.languages__item[aria-current="page"] {
  border-left-color: var(--gold);
  font-weight: 700;
}

.languages__item--unavailable {
  color: color-mix(in srgb, var(--text-on-dark) 65%, transparent);
  cursor: default;
}

@media (max-width: 1199px) {
  /* A zero basis keeps the brand beside the menu button; a long name wraps instead. */
  .brand {
    flex: 1 1 0;
    min-width: 0;
  }

  .menu {
    order: 3;
    width: 100%;
  }

  .menu[open] {
    padding-bottom: var(--space-s);
  }

  .site-header__inner > .menu:not([open]) {
    width: auto;
    order: 2;
  }

  /*
   * Open, the menu takes its own row below the brand; the toggle stays where it
   * was tapped (top right) instead of jumping down with it. The brand keeps
   * the room the toggle needs, so the name wraps the same open or closed.
   */
  .site-header__inner {
    position: relative;
  }

  .menu[open] > .menu__toggle {
    position: absolute;
    top: var(--space-m);
    right: 0;
  }

  .site-header__inner:has(> .menu[open]) > .brand {
    padding-right: 7rem;
  }
}

/*
 * Narrow screens, in a browser that will run the script but before it has
 * (a slow connection): the menu, open in the markup, already looks closed,
 * the "Menu" button beside the brand and no list, so the page does not open
 * on the list and jump when the script closes it. A browser without scripts
 * (scripting: none) still shows the simple open list above.
 */
@media (max-width: 1199px) and (scripting: enabled) {
  :root:not(.menu-ready) .menu[open] .menu__panel {
    display: none;
  }

  :root:not(.menu-ready) .site-header__inner > .menu {
    order: 2;
    width: auto;
    padding-bottom: 0;
  }

  :root:not(.menu-ready) .menu[open] > .menu__toggle {
    position: static;
  }

  :root:not(.menu-ready) .site-header__inner:has(> .menu[open]) > .brand {
    padding-right: 0;
  }
}

/* The menu button's two labels: "Menu" while closed, "Close" while the sheet is open. */
.menu__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.menu__label--close,
.menu-ready .menu[open] .menu__label--open {
  display: none;
}

.menu-ready .menu[open] .menu__label--close {
  display: inline-flex;
}

/*
 * Narrow screens, with JavaScript (menu-ready): the open menu is a card of
 * frosted glass that hangs under the header at the right, over the page,
 * which dims behind it (a tap there closes the menu). Links between
 * hairlines, the current one in gold, then the languages as a row of
 * buttons. The page does not scroll behind it (menu-open); it fades out as
 * it closes (menu-closing). Without JavaScript the menu stays the simple list
 * above.
 */
@media (max-width: 1199px) {
  .menu-ready .site-header {
    position: relative;
    z-index: 60;
  }

  .menu-ready .site-header__inner > .menu {
    order: 2;
    width: auto;
    padding-bottom: 0;
  }

  .menu-ready .menu[open] > .menu__toggle {
    position: static;
  }

  .menu-ready .site-header__inner:has(> .menu[open]) > .brand {
    padding-right: 0;
  }

  .menu-open,
  .menu-open body {
    overflow: hidden;
  }

  /* The dimmed page: under the header, which stays as it is, and under the card. */
  .menu-open body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 50;
    background: color-mix(in srgb, var(--navy-deep) 45%, transparent);
    animation: fade-in-menu 0.2s ease-out both;
  }

  .menu-closing body::after {
    animation: fade-out-menu 0.16s ease-in both;
  }

  .menu-ready .menu__panel {
    position: absolute;
    top: calc(100% + var(--space-2xs));
    right: 0;
    width: min(21rem, 100%);
    max-height: calc(100svh - var(--header-height, 4.75rem) - var(--space-l));
    gap: var(--space-l);
    padding: var(--space-s) var(--space-l) var(--space-l);
    overflow-y: auto;
    border: 1px solid color-mix(in srgb, var(--on-dark) 16%, transparent);
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--navy-deep) 97%, transparent);
    transform-origin: top right;
    animation: menu-in 0.22s ease-out both;
  }

  .menu-closing .menu__panel {
    animation: menu-out 0.16s ease-in both;
  }

  @supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .menu-ready .menu__panel {
      background: color-mix(in srgb, var(--navy-deep) 72%, transparent);
      -webkit-backdrop-filter: blur(20px) saturate(1.6);
      backdrop-filter: blur(20px) saturate(1.6);
    }
  }

  .menu-ready .nav__list {
    gap: 0;
  }

  .menu-ready .nav__list li + li {
    border-top: 1px solid var(--border-on-dark);
  }

  .menu-ready .nav__link {
    padding: var(--space-s) 0;
    font-size: var(--step-1);
    white-space: normal;
  }

  .menu-ready .nav__link:hover,
  .menu-ready .nav__link[aria-current="page"] {
    box-shadow: none;
    color: var(--gold);
  }

  .menu-ready .languages {
    padding-top: var(--space-m);
    border-top: 1px solid var(--border-on-dark);
  }

  .menu-ready .languages__toggle {
    display: none;
  }

  .menu-ready .languages__list {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin: 0;
  }

  .menu-ready .languages__item {
    padding: var(--space-2xs) var(--space-m);
    border: 1px solid color-mix(in srgb, var(--on-dark) 30%, transparent);
    border-radius: 999px;
  }

  .menu-ready .languages__item[aria-current="page"] {
    border-color: var(--on-dark);
    background: var(--on-dark);
    color: var(--navy-deep);
  }
}

@keyframes fade-in-menu {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fade-out-menu {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes menu-in {
  from { opacity: 0; transform: scale(0.96); }
  to { opacity: 1; transform: none; }
}

@keyframes menu-out {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: scale(0.96); }
}

/*
 * Back to top: a small round button of frosted glass at the bottom right on
 * narrow screens, shown once the reader is well down the page (site.js).
 */
.to-top {
  position: fixed;
  right: max(var(--gutter), env(safe-area-inset-right, 0px));
  bottom: calc(var(--space-l) + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid color-mix(in srgb, var(--on-dark) 25%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--navy-deep) 90%, transparent);
  color: var(--on-dark);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition), visibility 0s linear 160ms;
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .to-top {
    background: color-mix(in srgb, var(--navy-deep) 60%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.5);
    backdrop-filter: blur(14px) saturate(1.5);
  }
}

.to-top[hidden] {
  display: none;
}

.to-top.is-shown {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--transition), visibility 0s;
}

.to-top .icon {
  width: 1.25rem;
  height: 1.25rem;
}

@media (min-width: 1200px) {
  .to-top {
    display: none;
  }
}

/*
 * Wide screens: the brand on the left; on the right one row with the
 * navigation and, at its end, the language switcher, whose list drops down
 * over the page. The navigation may wrap rather than squeeze the brand.
 */
@media (min-width: 1200px) {
  .site-header__inner {
    flex-wrap: nowrap;
  }

  .brand {
    flex: none;
  }

  .menu__toggle {
    display: none;
  }

  .menu,
  .menu__panel {
    display: flex;
  }

  .menu {
    flex: 1 1 auto;
    justify-content: flex-end;
    min-width: 0;
  }

  .menu__panel {
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-l);
    padding: 0;
  }

  .nav__list {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0 var(--space-l);
  }

  .nav__link {
    padding: var(--space-2xs) 0;
  }

  .languages__list {
    position: absolute;
    top: calc(100% + var(--space-xs));
    right: 0;
    z-index: 10;
    min-width: 10rem;
    margin: 0;
    padding: var(--space-xs);
    border: 1px solid var(--border-on-dark);
    border-radius: var(--radius);
    background: var(--navy-deep);
  }

  .languages__item {
    display: block;
    padding: var(--space-xs) var(--space-s);
  }
}

/* Small phones: the tagline would push the menu button onto its own line. */
@media (max-width: 479px) {
  .brand__tagline {
    display: none;
  }
}

/*
 * A post's or an event's intro band opens on its featured photograph: the
 * photograph fills the band (the window under the header from 700px, most of
 * it on phones), undarkened except for a light shade under the header and a
 * navy gradient rising from the bottom, where the title and the meta line
 * sit low on the left. An agency credit sits at the bottom right.
 */
.masthead--photo {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: min(75svh, 40rem);
  background: var(--navy-deep);
}

.page-intro__photo {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}

.page-intro__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 35%;
}

.page-intro__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 18%),
    linear-gradient(0deg, color-mix(in srgb, var(--navy-deep) 94%, transparent) 0%, color-mix(in srgb, var(--navy-deep) 72%, transparent) 40%, transparent 75%);
}

.masthead--photo .page-intro {
  position: relative;
  width: min(100% - 2 * var(--gutter), var(--container));
  padding-bottom: calc(var(--space-3xl) + var(--space-2xl));
}

.page-intro__credit {
  position: absolute;
  right: 0;
  bottom: calc(var(--space-3xl) + var(--space-l));
  margin: 0;
  color: color-mix(in srgb, var(--on-dark) 75%, transparent);
  font-size: 0.75rem;
}

@media (min-width: 700px) {
  .masthead--photo {
    min-height: calc(100svh - var(--header-height, 4.75rem));
  }

  .page-intro__photo::after {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 18%),
      linear-gradient(0deg, color-mix(in srgb, var(--navy-deep) 92%, transparent) 0%, color-mix(in srgb, var(--navy-deep) 65%, transparent) 35%, transparent 65%),
      linear-gradient(90deg, color-mix(in srgb, var(--navy-deep) 50%, transparent) 0%, transparent 55%);
  }

  .masthead--photo .page-intro__title {
    font-size: var(--step-5);
  }
}

/* Intro band: breadcrumb, H1, meta line. */
.masthead--intro {
  background:
    var(--map-dark) no-repeat right -10rem top 1rem / min(64rem, 160%) auto,
    radial-gradient(ellipse 60% 120% at 85% 100%, color-mix(in srgb, var(--gold) 12%, transparent), transparent 60%),
    radial-gradient(ellipse 70% 140% at 0% 100%, color-mix(in srgb, var(--link) 28%, transparent), transparent 65%),
    var(--navy-deep);
}

.page-intro {
  padding-block: var(--space-2xl) var(--space-3xl);
}

.page-intro__title {
  max-width: 24ch;
  margin-bottom: 0;
  color: var(--on-dark);
}

.page--prose .page-intro__title,
.page--not-found .page-intro__title {
  max-width: 30ch;
}

/* An index opens on its description under the title. */
.page-intro__lead {
  max-width: 42rem;
  margin: var(--space-m) 0 0;
  color: var(--text-on-dark);
  font-size: var(--step-1);
  line-height: 1.6;
}

.page-intro__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-l);
  margin: var(--space-l) 0 0;
  color: var(--text-on-dark);
}

.meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.meta-item .icon {
  color: var(--gold);
}

.meta-item a {
  color: var(--on-dark);
}

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-xs);
  margin: 0 0 var(--space-m);
  padding: 0;
  color: var(--text-on-dark);
  font-size: var(--step--1);
  list-style: none;
}

.breadcrumb__list li + li::before {
  content: "/";
  margin-right: var(--space-xs);
  color: var(--gold);
}

.breadcrumb__list a {
  color: var(--text-on-dark);
  text-decoration-color: color-mix(in srgb, var(--text-on-dark) 40%, transparent);
}

.breadcrumb__list a:hover {
  color: var(--on-dark);
}

/*
 * Footer: four columns whose headings share one line, the same type size and
 * spacing in each, then the copyright under a muted hairline, led by a tiny
 * mark. Plain navy, so the small text reads easily.
 */
.site-footer {
  --focus: var(--focus-on-dark);
  background: var(--navy-deep);
  color: var(--text-on-dark);
  font-size: var(--step--1);
  line-height: 1.65;
}

.site-footer p {
  margin: 0 0 var(--space-s);
}

.site-footer p:last-child {
  margin-bottom: 0;
}

.site-footer__grid {
  display: grid;
  gap: var(--space-xl);
  padding-block: var(--space-2xl) var(--space-xl);
}

/*
 * Phones: the vision and the news across the width, then the contact and the
 * links side by side; each row opens with a faint hairline, the same space
 * above and below every block.
 */
@media (max-width: 639px) {
  .site-footer__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--space-l);
    padding-block: var(--space-m) 0;
  }

  .site-footer__grid > section {
    padding-block: var(--space-l);
    border-top: 1px solid color-mix(in srgb, var(--on-dark) 8%, transparent);
  }

  .site-footer__grid > :first-child {
    border-top: 0;
  }

  .site-footer__grid > :nth-child(-n + 2) {
    grid-column: 1 / -1;
  }

  .site-footer .site-footer__about p,
  .site-footer .site-footer__about p:lang(zh) {
    max-width: none;
  }

  .site-footer .subscribe {
    margin-bottom: 0;
  }
}

@media (min-width: 640px) {
  .site-footer__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .site-footer__grid {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.8fr);
    column-gap: var(--space-2xl);
  }
}

.site-footer__heading {
  margin-bottom: var(--space-m);
  color: var(--gold);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1.4;
  text-transform: uppercase;
}

.site-footer__heading:lang(zh) {
  font-size: 0.875rem;
  letter-spacing: 0.04em;
}

.site-footer__about p {
  max-width: 34ch;
}

.site-footer__about p:lang(zh) {
  max-width: 22em;
}

.site-footer__address {
  margin-bottom: var(--space-s);
  font-style: normal;
}

.site-footer__address strong {
  color: var(--on-dark);
  font-weight: 600;
}

.site-footer__link,
.site-footer .email:not(.button) {
  color: var(--on-dark);
  text-decoration: none;
}

.site-footer__link:hover,
.site-footer .email:not(.button):hover {
  color: var(--on-dark);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

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

.site-footer__mail .icon {
  color: var(--gold);
}

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

.site-footer__bottom {
  padding-block: var(--space-m);
  border-top: 1px solid color-mix(in srgb, var(--on-dark) 8%, transparent);
  color: color-mix(in srgb, var(--text-on-dark) 80%, transparent);
}

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

.site-footer__copyright .mark {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  color: var(--on-dark);
}

/* Newsletter signup in the footer. */
.subscribe {
  margin-block: var(--space-m);
}

.subscribe__label {
  display: block;
  margin-bottom: var(--space-2xs);
  color: var(--on-dark);
  font-weight: 600;
}

.subscribe__row {
  display: grid;
  justify-items: start;
  gap: var(--space-s);
}

.subscribe__input {
  width: 100%;
  min-width: 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid color-mix(in srgb, var(--on-dark) 40%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--on-dark) 6%, transparent);
  color: var(--on-dark);
  font: inherit;
}

.subscribe__input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.site-footer .subscribe__note {
  margin-top: var(--space-s);
}

.subscribe__note a {
  white-space: nowrap;
}

/* The bot trap: out of sight and out of the tab order, but present for scripts that fill every field. */
.subscribe__trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* components.css */
/*
 * Components: buttons, prose (including the fragment components on the
 * allowlist in src/fragment.php: figure.gallery, figure.pair, figure.wide,
 * blockquote.pull, aside.callout, table.facts), cards, event facts, and the
 * sections of designed pages (hero, carousel, features, prose, stats, band,
 * photo band, events, faq, locations, press kit, council, person).
 */

/*
 * A mail link before the address is revealed (site.js): a button that looks
 * like the link it will become; with the button class it is a button already.
 */
.email:not(.button, .link-cta) {
  padding: 0;
  border: 0;
  background: none;
  color: var(--link);
  font: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  cursor: pointer;
}

.email:not(.button, .link-cta):hover {
  color: var(--link-hover);
}

.button.email,
.link-cta.email {
  cursor: pointer;
}

/*
 * Buttons: the label in sentence case at reading size (the same in English,
 * French and Chinese), square corners. A section has one button, its main
 * action (button--go: an arrow after the label that moves on hover); a second
 * action is a text link (link-cta), not a second box.
 */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  min-height: 3rem;
  padding: 0.75rem 1.25rem 0.75rem 1.375rem;
  border: 1px solid var(--navy);
  border-radius: var(--radius);
  background: var(--navy);
  color: var(--on-dark);
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.25;
  text-decoration: none;
  transition: background-color var(--transition), border-color var(--transition), color var(--transition);
}

/* The arrow of a main action and of a text-link action: a mask, so it takes the text colour. */
.button--go::after,
.link-cta::after {
  content: "";
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  background: currentColor;
  -webkit-mask: var(--arrow) no-repeat center / contain;
  mask: var(--arrow) no-repeat center / contain;
  transition: transform var(--transition);
}

.button--go:hover::after,
.link-cta:hover::after {
  transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
  .button--go:hover::after,
  .link-cta:hover::after {
    transform: none;
  }
}

/* A second action beside a button: an underlined link with the arrow, gold-underlined on navy. */
.link-cta {
  display: inline-flex;
  padding: 0;
  border: 0;
  background: none;
  align-items: center;
  gap: 0.5rem;
  min-height: 3rem;
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.25;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.35em;
}

.link-cta:hover {
  color: var(--link-hover);
}

.link-cta--on-dark,
.link-cta--on-dark:hover {
  color: var(--on-dark);
  text-decoration-color: var(--gold);
  text-decoration-thickness: 2px;
}

.button:hover {
  border-color: var(--navy-deep);
  background: var(--navy-deep);
  color: var(--on-dark);
}

.button--outline {
  background: transparent;
  color: var(--navy);
}

.button--outline:hover {
  border-color: var(--navy);
  background: var(--navy);
  color: var(--on-dark);
}

/* On navy: the primary is solid white, the secondary a white outline; hovering swaps them. */
.button--on-dark {
  border-color: var(--on-dark);
  background: var(--on-dark);
  color: var(--navy-deep);
}

.button--on-dark:hover {
  border-color: var(--on-dark);
  background: transparent;
  color: var(--on-dark);
}


.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-heading);
  font-size: var(--step--1);
  font-weight: 600;
  text-decoration: none;
}

.link-arrow:hover {
  text-decoration: underline;
}

.lead {
  max-width: var(--measure);
  margin-bottom: var(--space-2xl);
  color: var(--text);
  font-size: var(--step-1);
  line-height: 1.55;
}

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

/* Prose: the reading column for fragments. */
.prose {
  max-width: var(--measure);
}

.prose--intro {
  margin-bottom: var(--space-2xl);
}

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

.prose h2 {
  margin-top: var(--space-2xl);
  font-size: var(--step-2);
}

.prose h3 {
  margin-top: var(--space-xl);
  font-size: var(--step-1);
}

.prose h2:first-child,
.prose h3:first-child {
  margin-top: 0;
}

.prose ul,
.prose ol {
  padding-left: 1.25em;
}

.prose li + li {
  margin-top: var(--space-2xs);
}

.prose li::marker {
  color: var(--gold-deep);
}

.prose hr {
  margin-block: var(--space-2xl);
  border: 0;
  border-top: 1px solid var(--border);
}

.prose figure {
  margin-block: var(--space-xl);
}

.prose figure img {
  border-radius: var(--radius);
}

/*
 * A figure.phone is for phones only: from tablets up it is not shown. A
 * figure.desktop is its counterpart, shown from 700px only, for the same
 * picture cropped for wide screens (an upright rendering on phones, a
 * landscape crop of it beside the text). A hidden lazy image is not fetched.
 */
@media (min-width: 700px) {
  .prose figure.phone {
    display: none;
  }
}

@media (max-width: 699.98px) {
  .prose figure.desktop {
    display: none;
  }
}

/* Where a short window trims a wide crop (85svh, below), the top stays: a sign, the faces. */
.prose figure.desktop > img {
  object-position: top;
}

/* A portrait image (a poster) stays within the screen's height instead of filling the column. */
.prose figure:not(.gallery, .pair) > img {
  width: auto;
  max-height: 85vh;
}

.prose figcaption {
  margin-top: var(--space-xs);
  color: var(--text-muted);
  font-size: var(--step--1);
}

.prose blockquote {
  margin-inline: 0;
  padding-left: var(--space-l);
  border-left: 1px solid var(--gold-deep);
  color: var(--navy);
}

.prose blockquote.pull {
  padding: 0;
  border: 0;
  font-family: var(--font-heading);
  font-size: var(--step-2);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* On a phone a long pull quote at heading size runs to a dozen lines. */
@media (max-width: 639px) {
  .prose blockquote.pull {
    font-size: var(--step-1);
  }
}

.prose blockquote.pull cite {
  display: block;
  margin-top: var(--space-s);
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-style: normal;
  font-weight: 400;
}

.prose blockquote.pull::before {
  content: "";
  display: block;
  width: 2.5rem;
  height: 2px;
  margin-bottom: var(--space-m);
  background: var(--gold);
}

.prose aside.callout {
  margin-block: var(--space-xl);
  padding: var(--space-l);
  border: 1px solid var(--border);
  border-left: 2px solid var(--navy);
  border-radius: var(--radius);
  background: var(--surface-alt);
}

.prose aside.callout > :last-child {
  margin-bottom: 0;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
}

.prose caption {
  margin-bottom: var(--space-xs);
  color: var(--text-muted);
  text-align: left;
}

.prose th,
.prose td {
  padding: var(--space-xs) var(--space-s);
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.prose th {
  color: var(--navy);
  font-family: var(--font-heading);
}

.prose table.facts th {
  width: 40%;
}

.prose figure.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--space-s);
}

.prose figure.gallery figcaption,
.prose figure.pair figcaption {
  grid-column: 1 / -1;
}

.prose figure.gallery img,
.prose figure.pair img {
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.prose figure.pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-s);
}

/*
 * Long text (posts, events and the text sections of designed pages) runs the
 * full width of the content, at the site's normal text size. Each section
 * heading stands above its text under a short gold rule; photographs, pairs
 * and galleries span the width too, while an upright photograph (portrait,
 * marked by the build) keeps its own proportions so it is not cropped.
 */
.prose--split {
  max-width: none;
}

.prose--split > h2,
.prose--split:not(:has(> h2)) > h3 {
  margin-top: var(--space-3xl);
  font-size: var(--step-3);
  line-height: 1.2;
}

/* The same short rule over every section heading, whatever the heading's length. */
.prose--split > h2::before,
.prose--split:not(:has(> h2)) > h3::before {
  content: "";
  display: block;
  width: 3rem;
  height: 2px;
  margin-bottom: var(--space-s);
  background: var(--gold);
}

.prose--split:not(:has(> h2)) > h3 {
  font-size: var(--step-2);
}

.prose--split > h2:first-child,
.prose--split:not(:has(> h2)) > h3:first-child {
  margin-top: 0;
}

.prose--split > figure:not(.portrait, .gallery, .pair) > img {
  width: 100%;
  max-height: 85svh;
  object-fit: cover;
}

/*
 * How to take part (event pages and the events index): a callout across the
 * content, the navy left edge on the light grey surface, the mail button
 * under the text.
 */
.attend {
  margin-top: var(--space-3xl);
  padding: var(--space-xl) var(--space-l);
  border: 1px solid var(--border);
  border-left: 2px solid var(--navy);
  border-radius: var(--radius);
  background: var(--surface-alt);
}

.attend__title {
  margin-bottom: var(--space-s);
  font-size: var(--step-2);
}

.attend p {
  max-width: none;
}

.attend__actions {
  margin: var(--space-l) 0 0;
}

/* A past event says so at the top of its details. */
.event-facts__past {
  margin: 0;
  color: var(--gold-deep);
  font-weight: 600;
}

/* Cards. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
  gap: var(--space-xl);
}

/*
 * The home page's events and highlights teasers: on phones a row of cards
 * that swipes sideways, each card most of the width so the next one shows at
 * the edge; from 48rem, three in a row (never two and a lonely third).
 */
@media (max-width: 47.99rem) {
  :is(.events-teaser, .posts-teaser) .card-grid {
    display: flex;
    gap: var(--space-m);
    margin-inline: calc(-1 * var(--gutter));
    padding: 0 var(--gutter) var(--space-s);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-padding-inline: var(--gutter);
    scroll-snap-type: x mandatory;
    scrollbar-width: thin;
  }

  :is(.events-teaser, .posts-teaser) .card {
    flex: 0 0 min(82%, 20rem);
    scroll-snap-align: start;
  }
}

@media (min-width: 48rem) {
  :is(.events-teaser, .posts-teaser) .card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* A flat card: the image, then the text, no box. Without an image a hairline opens it. */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
}

.card:not(:has(.card__media)) {
  border-top: 1px solid var(--border);
}

.card__media img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius);
}

.card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding-top: var(--space-m);
}

.card__eyebrow {
  margin-bottom: var(--space-xs);
  color: var(--gold-deep);
  font-family: var(--font-heading);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.card__title {
  margin-bottom: var(--space-xs);
  font-size: var(--step-1);
}

.card__title a {
  color: var(--navy);
  text-decoration: none;
}

.card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.card__title a:hover {
  color: var(--link-hover);
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

.card__summary {
  color: var(--text-muted);
  font-size: var(--step--1);
}

.card__date {
  margin: auto 0 0;
  padding-top: var(--space-s);
  color: var(--text-muted);
  font-size: var(--step--1);
}

/*
 * The lead story (the newest post on the blog index and category pages): across
 * the width from 48rem, its photograph on the left, larger, beside its text,
 * a hairline under it before the grid of the others.
 */
@media (min-width: 48rem) {
  .card-grid--lead > .card--lead {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: var(--space-xl);
    align-items: center;
    padding-bottom: var(--space-xl);
    border-bottom: 1px solid var(--border);
  }

  .card--lead .card__media img {
    aspect-ratio: 3 / 2;
  }

  .card--lead .card__body {
    padding-top: 0;
  }

  .card--lead .card__title {
    font-size: var(--step-3);
  }

  .card--lead .card__summary {
    font-size: var(--step-0);
  }
}

/*
 * Under the lead story the others go two to a row on tablets and three from
 * 64rem. A card that would stand alone on the last row spans it instead: its
 * photograph in the first column, its text across the rest (subgrid keeps
 * both on the grid's tracks), so no row ends with a lonely card.
 */
@media (min-width: 48rem) {
  .card-grid--lead {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .card-grid--lead > .card:not(.card--lead):last-child:nth-child(2n) {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    align-items: center;
  }

  .card-grid--lead > .card:not(.card--lead):last-child:nth-child(2n) > .card__body {
    padding-top: 0;
  }
}

@media (min-width: 64rem) {
  .card-grid--lead {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .card-grid--lead > .card:not(.card--lead):last-child:nth-child(2n) {
    display: flex;
    grid-column: auto;
  }

  .card-grid--lead > .card:not(.card--lead):last-child:nth-child(2n) > .card__body {
    padding-top: var(--space-m);
  }

  .card-grid--lead > .card:not(.card--lead):last-child:nth-child(3n+2) {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    align-items: center;
  }

  .card-grid--lead > .card:not(.card--lead):last-child:nth-child(3n+2) > .card__body {
    padding-top: 0;
  }
}

.card-grid--lead > .card:not(.card--lead):last-child > .card__body {
  grid-column: 2 / -1;
}

/*
 * The agenda (the events index): each event a row led by a calendar tile,
 * then the photograph, then the city, the title, the summary and the dates.
 * The title's link covers the row. Phones: the photograph across the top, the tile beside the text.
 * From 48rem: tile, photograph, text in one row.
 */
.agenda {
  margin: 0 0 var(--space-3xl);
  padding: 0;
  border-top: 1px solid var(--border);
  list-style: none;
}

.agenda:last-child {
  margin-bottom: 0;
}

.agenda__item {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "media media" "tile body";
  gap: var(--space-m) var(--space-l);
  padding-block: var(--space-l);
  border-bottom: 1px solid var(--border);
}

.agenda__item:not(:has(.agenda__media)) {
  grid-template-areas: "tile body";
}

.agenda__item > .date-tile {
  grid-area: tile;
}

.agenda__media {
  grid-area: media;
}

.agenda__media img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius);
}

.agenda__body {
  grid-area: body;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.agenda__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-bottom: var(--space-xs);
  color: var(--gold-deep);
  font-family: var(--font-heading);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.agenda__eyebrow:lang(zh) {
  font-size: 0.875rem;
  letter-spacing: 0.04em;
}

.agenda__title {
  margin-bottom: var(--space-xs);
  font-size: var(--step-2);
}

.agenda__title a {
  color: var(--navy);
  text-decoration: none;
}

.agenda__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.agenda__title a:hover {
  color: var(--link-hover);
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

.agenda__summary {
  max-width: var(--measure);
  margin-bottom: var(--space-s);
  color: var(--text-muted);
}

.agenda__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-l);
  margin: auto 0 0;
  color: var(--text-muted);
  font-size: var(--step--1);
}

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

.agenda__when .icon {
  color: var(--gold-deep);
}

@media (min-width: 48rem) {
  .agenda__item {
    grid-template-columns: auto 15rem minmax(0, 1fr);
    grid-template-areas: "tile media body";
    gap: var(--space-xl);
    align-items: start;
  }

  .agenda__item:not(:has(.agenda__media)) {
    grid-template-columns: auto minmax(0, 1fr);
  }
}

@media (min-width: 64rem) {
  .agenda__item {
    grid-template-columns: auto 20rem minmax(0, 1fr);
    column-gap: var(--space-2xl);
  }
}

/*
 * A calendar tile: a leaf of a calendar, the day large under the month, the
 * year beneath, the top edge a navy bar; Chinese reads the year first.
 */
.date-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 5.25rem;
  padding: var(--space-s) var(--space-xs);
  border: 1px solid var(--border);
  border-top: 2px solid var(--navy);
  border-radius: var(--radius);
  background: var(--surface);
  font-family: var(--font-heading);
  line-height: 1;
  text-align: center;
}

.date-tile__month {
  color: var(--gold-deep);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.date-tile__month:lang(zh) {
  font-size: 0.8rem;
  letter-spacing: 0.04em;
}

.date-tile__day {
  margin-block: var(--space-2xs);
  color: var(--navy);
  font-size: var(--step-4);
  font-weight: 700;
  letter-spacing: -0.02em;
}

.date-tile__year {
  color: var(--text-muted);
  font-size: 0.75rem;
}

.date-tile:lang(zh) .date-tile__year {
  order: -2;
}

.date-tile:lang(zh) .date-tile__month {
  order: -1;
}

/*
 * "On this page" (templates/components/toc.php), the FAQ's list of questions.
 * Narrow screens: a light grey bar above the text, closed until tapped, the
 * title at reading size with the count of entries and a plus (a minus when
 * open); open, numbered rows between hairlines. Wide screens (from 1100px):
 * the list stands open in the column to the right of the text and stays in
 * view while the reader scrolls; the question being read is marked with a
 * gold edge (site.js).
 */
.text-layout {
  display: grid;
  gap: var(--space-xl);
}

.toc__box {
  border-radius: var(--radius);
  background: var(--surface-alt);
}

.toc__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  min-height: 3.25rem;
  padding: 0 var(--space-m);
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
  list-style: none;
  cursor: pointer;
}

.toc__count {
  color: var(--text-muted);
  font-weight: 400;
}

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

/* A plus while closed, a minus while open. */
.toc__title::after {
  content: "";
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  background: currentColor;
  -webkit-mask: var(--plus) no-repeat center / contain;
  mask: var(--plus) no-repeat center / contain;
}

.toc__box[open] > .toc__title::after {
  -webkit-mask-image: var(--minus);
  mask-image: var(--minus);
}

/* Numbered rows between hairlines. */
.toc__list {
  display: grid;
  margin: 0;
  padding: 0 var(--space-m) var(--space-xs);
  list-style: none;
}

.toc__list > li {
  border-top: 1px solid var(--border);
}

.toc__link {
  display: flex;
  gap: var(--space-s);
  padding: var(--space-s) 0;
  color: var(--link);
  font-size: var(--step--1);
  line-height: 1.4;
  text-decoration: none;
}

.toc__number {
  flex: none;
  min-width: 1.25em;
  color: var(--gold-deep);
  font-weight: 600;
}

.toc__link:hover {
  color: var(--link-hover);
  text-decoration: underline;
}

@media (min-width: 1100px) {
  .text-layout {
    grid-template-columns: minmax(0, var(--measure)) minmax(12rem, 17rem);
    justify-content: space-between;
    align-items: start;
    column-gap: var(--space-3xl);
  }

  .text-layout > .prose {
    grid-column: 1;
    grid-row: 1;
  }

  .text-layout > .toc {
    position: sticky;
    top: var(--space-l);
    grid-column: 2;
    grid-row: 1;
  }
}

@media (min-width: 1100px) {
  .text-layout > .toc .toc__box {
    max-height: calc(100svh - 2 * var(--space-l));
    overflow-y: auto;
    border: 0;
    background: none;
  }

  .text-layout > .toc .toc__title,
  .text-layout > .toc .toc__list {
    padding-inline: 0;
  }

  .text-layout > .toc .toc__title {
    min-height: 0;
    padding-block: 0 var(--space-s);
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: default;
  }

  .text-layout > .toc .toc__title:lang(zh) {
    font-size: 0.875rem;
    letter-spacing: 0.04em;
  }

  .text-layout > .toc .toc__title::after,
  .text-layout > .toc .toc__count {
    display: none;
  }

  .text-layout > .toc .toc__list > li {
    border-top: 0;
  }

  /* Beside the text: the list as before, a hairline edge that turns gold for the section being read. */
  .text-layout > .toc .toc__link {
    padding: var(--space-2xs) 0 var(--space-2xs) var(--space-s);
    border-left: 2px solid var(--border);
    color: var(--text-muted);
  }

  .text-layout > .toc .toc__link[aria-current="true"] {
    border-left-color: var(--gold);
    color: var(--navy);
    font-weight: 600;
  }
}

/* A long text section of a designed page opens with a heading the size of the other sections' headings. */
.section--prose .prose > h2:first-child {
  font-size: var(--step-3);
}

/*
 * Event facts: a band across the page under the opening photograph, raised a
 * little into it. Phones: the facts one under another, then the buttons.
 * From 900px: the title on the left, the facts side by side, the buttons at
 * the end of the row.
 */
.event-layout {
  display: grid;
  gap: var(--space-2xl);
}

.event-facts {
  position: relative;
  z-index: 1;
  margin-top: calc(-1 * var(--space-3xl) - var(--space-xl));
  padding: var(--space-l);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 1px 0 var(--border);
}

@media (min-width: 900px) {
  .event-facts {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-xl);
    padding: var(--space-l) var(--space-xl);
  }

  .event-facts__title {
    margin: 0;
  }

  .event-facts .event-facts__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-m) var(--space-2xl);
    margin: 0;
  }

  .event-facts .event-facts__row + .event-facts__row {
    margin-top: 0;
  }
}

.event-facts__title {
  font-size: var(--step-1);
}

.event-facts__list {
  margin-bottom: var(--space-l);
}

.event-facts__row + .event-facts__row {
  margin-top: var(--space-m);
}

.event-facts__row dt {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: var(--step--1);
  font-weight: 600;
}

.event-facts__row dt .icon {
  color: var(--gold-deep);
}

.event-facts__row dd {
  margin: var(--space-2xs) 0 0;
}

.event-facts__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin: 0;
}

/* Section heads of designed pages. */
.section__head {
  max-width: 46rem;
  margin-bottom: var(--space-2xl);
}

.section__head--row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s) var(--space-xl);
  max-width: none;
}

.section__heading {
  margin-bottom: var(--space-s);
  font-size: var(--step-3);
}

.section__head--row .section__heading {
  margin-bottom: 0;
}

.section__intro {
  margin: 0;
  font-size: var(--step-1);
  line-height: 1.55;
}

/*
 * Hero: the opening of a designed page, in place of the intro band. Without a
 * photograph the dotted world map fills its right side, over the glows.
 */
.hero {
  overflow: hidden;
  padding-block: var(--space-2xl) var(--space-3xl);
  background:
    var(--map-dark) no-repeat left 55% center / auto 125%,
    radial-gradient(ellipse 55% 110% at 90% 100%, color-mix(in srgb, var(--gold) 14%, transparent), transparent 60%),
    radial-gradient(ellipse 70% 140% at 0% 100%, color-mix(in srgb, var(--link) 30%, transparent), transparent 65%),
    var(--navy-deep);
}

.hero__text {
  max-width: 48rem;
}

.hero__eyebrow {
  margin-bottom: var(--space-m);
  color: var(--gold);
  font-family: var(--font-heading);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.hero__title {
  max-width: 18ch;
  margin-bottom: var(--space-l);
  color: var(--on-dark);
  font-family: var(--font-heading);
  font-weight: 700;
  text-wrap: balance;
  font-size: var(--step-5);
  letter-spacing: -0.025em;
  line-height: 1.08;
}

.hero__lead {
  max-width: 40rem;
  margin: 0;
  font-size: var(--step-1);
  line-height: 1.6;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s) var(--space-l);
  margin: var(--space-xl) 0 0;
}

@media (min-width: 900px) {
  .hero {
    padding-block: var(--space-3xl) calc(var(--space-3xl) + var(--space-l));
    background-position: right -12rem center, 0 0, 0 0;
    background-size: min(78rem, 110%) auto, auto, auto;
  }
}

/*
 * Feature cards: one column on phones, two on tablets, then rows of three
 * (three, five, six or nine cards) or four (four, seven or eight), so no row is
 * left with a lonely card where it can be helped.
 */
@media (min-width: 40rem) {
  .features .features__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Three cards stay one row: never two and a lonely third. */
  .features .features__list:has(> li:nth-child(3):last-child) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  .features .features__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  .features .features__list:has(> li:nth-child(4):last-child),
  .features .features__list:has(> li:nth-child(7):last-child),
  .features .features__list:has(> li:nth-child(8):last-child) {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Hero with a photograph: the image fills the band under a deep navy gradient. */
.hero--photo {
  position: relative;
  isolation: isolate;
  background: var(--navy-deep);
}

.hero__photo {
  position: absolute;
  inset: 0;
  z-index: -1;
}

.hero__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Photographs on navy wait on the navy: no grey box while they download (base.css). */
.hero__photo img,
.page-intro__photo img,
.photo-band__photo img {
  background-color: transparent;
}

.band__photo img {
  background-color: var(--navy);
}

.hero__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, color-mix(in srgb, var(--navy-deep) 92%, transparent) 0%, color-mix(in srgb, var(--navy-deep) 82%, transparent) 60%, color-mix(in srgb, var(--navy-deep) 45%, transparent) 100%);
}

/*
 * The overlay keeps the gold eyebrow at 4.5:1 and the lead above 6:1 even over
 * a white patch of the photograph: at least 82% navy under the text column
 * on wide screens, 85% across the whole band on narrow ones.
 */
@media (max-width: 899px) {
  .hero__photo::after {
    background: color-mix(in srgb, var(--navy-deep) 85%, transparent);
  }
}

/*
 * Tablets and desktops: a hero with a photograph fills the window under the
 * header (--header-height, measured by assets/js/site.js), like the home
 * page's carousel; the words sit low on the left, over the darkest part of
 * the photograph's gradient.
 */
@media (min-width: 700px) {
  .hero--photo:not(.carousel) {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: calc(100svh - var(--header-height, 4.75rem));
  }

  /*
   * Dark only where the words are (low on the left: at least 85% navy under
   * them, so the lead and the gold eyebrow keep their contrast); the rest of
   * the photograph stays light, with a light shade under the header.
   */
  .hero--photo:not(.carousel) .hero__photo::after {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 18%),
      linear-gradient(0deg, color-mix(in srgb, var(--navy-deep) 92%, transparent) 0%, color-mix(in srgb, var(--navy-deep) 70%, transparent) 38%, transparent 72%),
      linear-gradient(90deg, color-mix(in srgb, var(--navy-deep) 60%, transparent) 0%, transparent 60%);
  }
}

/*
 * Split hero (tablets and desktops): the words on the navy band's left part,
 * under its glows, and the photograph across the rest of the band, its
 * subject uncovered: only a light shade under the header and a short fade
 * into the navy along its left edge. The words keep inside the panel.
 */
@media (min-width: 700px) {
  .hero--split {
    --hero-panel: 42vw;
  }

  .hero--split .hero__photo {
    left: var(--hero-panel);
  }

  .hero--split .hero__photo img {
    object-position: 40% center;
  }

  .hero--photo.hero--split:not(.carousel) .hero__photo::after {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 18%),
      linear-gradient(90deg, var(--navy-deep) 0%, transparent 6%);
  }

  .hero--split .hero__text {
    max-width: calc(var(--hero-panel) - (100vw - min(100vw - 2 * var(--gutter), var(--container))) / 2 - var(--space-xl));
  }
}

/* Portrait tablets: the panel would leave too narrow a photograph, so it runs across the top and the words follow below. */
@media (min-width: 700px) and (orientation: portrait) {
  .hero--split .hero__photo {
    left: 0;
    bottom: auto;
    height: 58%;
  }

  .hero--photo.hero--split:not(.carousel) .hero__photo::after {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 18%),
      linear-gradient(0deg, var(--navy-deep) 0%, transparent 25%);
  }

  .hero--split .hero__text {
    max-width: 48rem;
  }
}

/*
 * Phones: like the home page's carousel, every hero fills the window under
 * the header (--header-height, measured by assets/js/site.js). With a
 * photograph, the photograph comes first, clear, taking whatever height the
 * text leaves (at least 14rem) and fading into navy under the breadcrumb and
 * heading. Without one, the words sit at the foot of the band and the dotted
 * map fills the space above them.
 */
@media (max-width: 699px) {
  .hero:not(.carousel) {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: calc(100svh - var(--header-height, 4.75rem));
    background-position: center top var(--space-xl), 0 0, 0 0;
    background-size: 190% auto, auto, auto;
  }

  .hero--photo:not(.carousel) {
    justify-content: flex-start;
    padding-top: 0;
  }

  .hero--photo:not(.carousel) .hero__photo {
    position: relative;
    inset: auto;
    z-index: 0;
    flex: 1 1 0;
    min-height: 14rem;
    overflow: hidden;
  }

  .hero--photo:not(.carousel) .hero__photo::after {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 15%),
      linear-gradient(0deg, var(--navy-deep) 0%, color-mix(in srgb, var(--navy-deep) 70%, transparent) 14%, transparent 38%);
  }

  .hero--photo:not(.carousel) .hero__inner {
    position: relative;
    z-index: 1;
    margin-top: -2.75rem;
  }
}

/*
 * Carousel: the home page's hero, with slides that take turns (site.js). The
 * slides share one grid cell, so the band is as tall as the tallest slide;
 * the active one fades in while its photograph zooms in slowly. Without
 * JavaScript only the first slide shows.
 *
 * The photographs keep their subject in the centre, so no text covers it:
 * each slide is a full-width photograph (cinematic on wide screens, 16:9 on
 * phones) whose lower edge fades into the navy, the headline overlapping that
 * edge, and the text and buttons below on navy.
 */
.carousel {
  --slide-delay: 5s; /* the bars fill in the time data-slideshow gives the slides (templates/components/carousel.php) */
  --overlap: 2.75rem; /* how far the headline rises into the photograph */
  position: relative;
  padding-block: 0;
  background: var(--navy-deep);
}

.carousel__slides {
  display: grid;
}

.carousel__slide {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  grid-area: 1 / 1;
  padding-block: 0 calc(var(--space-2xl) + 3rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity 1s ease, visibility 0s linear 1s;
}

.carousel__slide.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity 1s ease, visibility 0s;
}

/*
 * A slide's photograph is left out of the page until its turn is near (the
 * current, outgoing or next slide, marked by site.js), so a slow connection
 * downloads the photograph on screen first and the others one at a time,
 * not all of them at once: a hidden image in the window still downloads.
 */
.carousel__slide:not(.is-active, .is-leaving, .is-next) .carousel__photo img {
  display: none;
}

/*
 * At every width the hero fills the window under the header (its height
 * measured by assets/js/site.js; 4.75rem without JavaScript): the photograph
 * takes whatever height the headline, the text and the slide bars leave, and
 * never less than 14rem (20rem from 700px), so a short or turned phone
 * scrolls instead of squeezing it.
 */
.carousel__slide {
  min-height: calc(100svh - var(--header-height, 4.75rem));
}

.carousel__photo {
  position: relative;
  z-index: 0;
  flex: 1 1 0;
  min-height: 14rem;
  overflow: hidden;
}

.carousel__photo img {
  object-position: center 35%;
}

/* Undarkened except for a light shade under the header and the fade into the navy, under the headline. */
.carousel__photo::after {
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 15%),
    linear-gradient(0deg, var(--navy-deep) 0%, color-mix(in srgb, var(--navy-deep) 70%, transparent) 14%, transparent 38%);
}

.carousel__text {
  position: relative;
  z-index: 1;
  margin-top: calc(-1 * var(--overlap));
}

.carousel__text .hero__title {
  max-width: 24ch;
  font-size: var(--step-4);
}

.carousel__text .hero__lead {
  max-width: 40rem;
}

@media (min-width: 700px) {
  .carousel {
    --overlap: 4.5rem;
  }

  .carousel__photo {
    min-height: 20rem;
  }
}

/*
 * Wide screens: the headline on the left, its first line on the middle of the
 * photograph's fade; on the right the buttons and then the text, their bottom
 * level with the headline's, rising as far as they need (the headline alone
 * sets the height, so the hero is no taller than the headline needs).
 */
@media (min-width: 1100px) {
  /* A larger headline; the overlap and the fade are sized from its line. */
  .carousel {
    --title-size: clamp(3.25rem, 1.5rem + 3.6vw, 4.75rem);
    --title-line: calc(var(--title-size) * 1.08);
    --overlap: calc(var(--title-line) * 1.1);
  }

  /* Chinese characters are wider: a step smaller keeps every headline on one line. */
  .carousel:lang(zh) {
    --title-size: clamp(2.75rem, 1rem + 3.2vw, 4rem);
  }

  /* Navy from the edge, half way at the first line's top, clear a line above it. */
  .carousel__photo::after {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--navy-deep) 35%, transparent) 0%, transparent 15%),
      linear-gradient(0deg, var(--navy-deep) 0, color-mix(in srgb, var(--navy-deep) 55%, transparent) calc(var(--title-line) * 0.95), transparent calc(var(--title-line) * 2.3));
  }

  .carousel__text {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    column-gap: var(--space-2xl);
    align-items: start;
    max-width: none;
  }

  .carousel__text .hero__title {
    grid-column: 1;
    margin-bottom: 0;
    font-size: var(--title-size);
  }

  /*
   * No height of its own at the foot of the headline's row: the buttons and
   * the text stack up from there. The margin evens out the two line heights,
   * so the last baselines meet.
   */
  .carousel__details {
    grid-column: 2;
    grid-row: 1;
    align-self: end;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 0;
    margin-bottom: calc(0.05 * var(--title-size));
  }

  .carousel__details .hero__actions {
    order: -1;
    margin: 0 0 var(--space-l);
  }
}

.carousel__slide.is-active .carousel__photo img,
.carousel__slide.is-leaving .carousel__photo img,
.photo-band__photo.is-active img,
.photo-band__photo.is-leaving img {
  animation: slow-zoom 8s ease-out both;
}

@keyframes slow-zoom {
  from { transform: scale(1); }
  to { transform: scale(1.08); }
}

/* The text fades in with its slide; it never moves, so nothing jumps under the reader's eye. */
.carousel__slide.is-active .carousel__text {
  animation: fade-in 0.8s ease-out 0.2s both;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/*
 * The headline follows a moment later, uncovered from left to right as the
 * new photograph settles: a mask moves, the words stay where they are. The
 * mask reaches a little past the line box so accents and descenders are never
 * cut.
 */
.carousel__slide.is-active .hero__title {
  animation: wipe-in 0.9s cubic-bezier(0.65, 0, 0.35, 1) 0.6s both;
}

@keyframes wipe-in {
  from { clip-path: inset(-0.3em 100% -0.3em -0.3em); }
  to { clip-path: inset(-0.3em -0.3em -0.3em -0.3em); }
}

[data-slide-controls][hidden] {
  display: none;
}

/*
 * Centred along the bottom: one wide bar per slide, the current one filling
 * in gold while it shows. The bars are buttons: a click shows that slide.
 */
.carousel__controls {
  position: absolute;
  inset: auto 0 var(--space-xl);
  display: flex;
  justify-content: center;
}

.carousel__markers {
  display: flex;
  gap: var(--space-s);
  margin: 0;
  padding: 0;
  list-style: none;
}

.carousel__marker {
  display: block;
  width: clamp(3.5rem, 12vw, 6.5rem);
  padding: var(--space-s) 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.carousel__marker::before {
  content: "";
  display: block;
  height: 3px;
  background:
    linear-gradient(var(--gold), var(--gold)) no-repeat left / 0 100%,
    color-mix(in srgb, var(--on-dark) 35%, transparent);
}

.carousel__marker:hover::before {
  background-color: color-mix(in srgb, var(--on-dark) 60%, transparent);
}

.carousel__marker[aria-current="true"]::before {
  animation: fill var(--slide-delay) linear both;
}

.is-held .carousel__marker::before {
  animation-play-state: paused;
}

@keyframes fill {
  to { background-size: 100% 100%, auto; }
}

/*
 * The pause button (WCAG 2.2.2), after the bars of the carousel and at the
 * bottom right of the photo band: a small round button of the frosted glass
 * of the back-to-top button, the pause icon while the slides run and the play
 * icon while they are paused. Paused, the zoom and the bar's filling stop too.
 */
.carousel__controls {
  align-items: center;
  gap: var(--space-m);
}

.slideshow-pause {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--on-dark) 30%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--navy-deep) 60%, transparent);
  color: var(--on-dark);
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition);
}

.slideshow-pause:hover {
  border-color: color-mix(in srgb, var(--on-dark) 60%, transparent);
  background: var(--navy-deep);
}

.slideshow-pause[hidden] {
  display: none;
}

.slideshow-pause .icon {
  width: 1rem;
  height: 1rem;
}

.slideshow-pause[aria-pressed="false"] .icon:last-child,
.slideshow-pause[aria-pressed="true"] .icon:first-child {
  display: none;
}

.is-paused [data-slide] img,
.is-paused .carousel__marker::before {
  animation-play-state: paused;
}

.photo-band__controls {
  position: absolute;
  right: var(--gutter);
  bottom: var(--space-m);
  z-index: 2;
}

/* Reduced motion: no filling; the current bar is simply gold. */
@media (prefers-reduced-motion: reduce) {
  .carousel__marker[aria-current="true"]::before {
    background-size: 100% 100%, auto;
  }
}

/*
 * Photo band: a low strip of photographs that take turns above the footer,
 * with a light fade into the footer's navy along the bottom edge.
 */
.photo-band {
  position: relative;
  isolation: isolate;
  height: clamp(11rem, 26vw, 26rem);
  overflow: hidden;
  background: var(--navy-deep);
}

.photo-band::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(0deg, color-mix(in srgb, var(--navy-deep) 55%, transparent) 0%, transparent 35%);
}

.photo-band__photo {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.2s ease;
}

.photo-band__photo.is-active {
  opacity: 1;
}

/*
 * A single photograph: the old site's slow zoom, in and out over 16 seconds
 * each way and on all the time, so it is still moving when the reader
 * arrives; the pause button stops it (WCAG 2.2.2), as does reduced motion.
 */
.photo-band--still .photo-band__photo img {
  animation: slow-zoom 16s ease-in-out infinite alternate;
}

.photo-band--still.is-paused .photo-band__photo img {
  animation-play-state: paused;
}

.photo-band__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The top of the photograph: faces are in its upper part, and the band fades into the footer below. */
  object-position: center top;
}

/* Features: numbered cards. */
.features__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: feature;
}

/* A flat feature: a hairline, the number small in gold, the title, the text. */
.feature {
  display: flex;
  flex-direction: column;
  padding-top: var(--space-l);
  border-top: 1px solid var(--border);
  counter-increment: feature;
}

.feature::before {
  content: counter(feature, decimal-leading-zero);
  margin-bottom: var(--space-s);
  color: var(--gold-deep);
  font-family: var(--font-heading);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1;
}

.feature__title {
  margin-bottom: var(--space-xs);
  font-size: var(--step-1);
}

.feature__text {
  margin: 0;
  color: var(--text-muted);
}

.feature__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: auto;
  padding-top: var(--space-m);
  font-family: var(--font-heading);
  font-size: var(--step--1);
  font-weight: 600;
  text-decoration: none;
}

.feature__link:hover {
  text-decoration: underline;
}

/*
 * Feature tiles (every card with an icon), each icon on a soft blob of its
 * own shape that turns a little on hover. On phones: rows, the icon on the
 * left of the title, text and link, between hairlines. From 48rem: one row of
 * centred tiles (never a short last row) under a centred heading with a short
 * gold rule.
 */
.features--tiles .section__heading::after {
  content: "";
  display: block;
  width: 3rem;
  height: 2px;
  margin-top: var(--space-m);
  background: var(--gold);
}

.features--tiles .features__list {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  border-bottom: 1px solid var(--border);
}

.features--tiles .feature {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  column-gap: var(--space-l);
  align-content: start;
  padding-block: var(--space-l);
}

.features--tiles .feature::before {
  content: none;
}

.features--tiles .feature > :not(.feature__icon) {
  grid-column: 2;
}

.feature__icon {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-row: 1 / span 3;
  place-items: center;
  width: 4.5rem;
  height: 4.5rem;
  color: var(--link);
}

.features--tiles .feature__link {
  padding-top: var(--space-xs);
}

@media (min-width: 48rem) {
  .features--tiles .section__head {
    margin-inline: auto;
    text-align: center;
  }

  .features--tiles .section__heading::after {
    margin-inline: auto;
  }

  .features--tiles .features__list {
    grid-template-columns: none;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
    gap: var(--space-l);
    border-bottom: 0;
  }

  .features--tiles .feature {
    display: flex;
    align-items: center;
    padding: var(--space-xl) var(--space-l);
    border: 1px solid transparent;
    border-radius: var(--radius);
    text-align: center;
    transition: border-color var(--transition);
  }

  .features--tiles .feature:hover,
  .features--tiles .feature:focus-within {
    border-color: var(--border);
  }

  .feature__icon {
    width: 6.5rem;
    height: 6.5rem;
    margin-bottom: var(--space-l);
  }

  .features--tiles .feature__link {
    padding-top: var(--space-m);
  }
}

.feature__icon::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 58% 42% 63% 37% / 45% 52% 48% 55%;
  background: color-mix(in srgb, var(--link) 12%, transparent);
  transition: transform 600ms ease;
}

.feature:nth-child(3n + 2) .feature__icon::before {
  border-radius: 41% 59% 45% 55% / 57% 43% 57% 43%;
}

.feature:nth-child(3n) .feature__icon::before {
  border-radius: 63% 37% 52% 48% / 38% 58% 42% 62%;
}

.feature:hover .feature__icon::before {
  transform: rotate(16deg) scale(1.06);
}

.feature__icon .icon {
  width: 2rem;
  height: 2rem;
}

@media (min-width: 48rem) {
  .feature__icon .icon {
    width: 2.5rem;
    height: 2.5rem;
  }
}

/*
 * The light dotted map on the light sections with room beside their text
 * (figures, the FAQ, the addresses), on wide screens only, where it stays to
 * the right of the reading column.
 */
@media (min-width: 900px) {
  .stats,
  .section--faq,
  .locations {
    background-image: var(--map-light);
    background-repeat: no-repeat;
    background-position: right -16rem center;
    background-size: auto min(100%, 34rem);
  }

  .section--faq {
    background-position: right -18rem top var(--space-3xl);
    background-size: 60rem auto;
  }
}

/* Stats: figures as a description list, the value shown large above its label. */
.stats__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr));
  gap: var(--space-xl);
  margin: 0;
}

.stats__list--detailed {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

.stat {
  display: flex;
  flex-direction: column;
  padding-top: var(--space-m);
  border-top: 1px solid var(--border);
}

.stat__value {
  order: -1;
  margin: 0;
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: var(--step-5);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.stat__label {
  margin-top: var(--space-xs);
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: var(--step-0);
  font-weight: 600;
}

.stat__text {
  margin: var(--space-xs) 0 0;
  color: var(--text-muted);
}

.stats__note {
  margin: var(--space-xl) 0 0;
  color: var(--text-muted);
  font-size: var(--step--1);
}

.stats__action {
  margin: var(--space-xl) 0 0;
}

/*
 * Stats as a band: deep navy under the dark dotted map, the figures very
 * large in white, each under a short gold rule, divided by vertical hairlines
 * (two columns on phones, four from 48rem).
 */
.stats--band {
  --focus: var(--focus-on-dark);
  padding-block: var(--space-3xl);
  background:
    var(--map-dark) no-repeat center / min(80rem, 160%) auto,
    radial-gradient(ellipse 60% 90% at 50% 0%, color-mix(in srgb, var(--navy) 80%, transparent), transparent 70%),
    var(--navy-deep);
  color: var(--text-on-dark);
  text-align: center;
}

.stats--band .section__head {
  margin-inline: auto;
}

.stats--band .section__heading {
  color: var(--on-dark);
}

.stats--band .stats__list {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-l) 0;
}

.stats--band .stat {
  align-items: center;
  padding: var(--space-m) var(--space-s);
  border-top: 0;
  border-left: 1px solid var(--border-on-dark);
}

.stats--band .stat:nth-child(odd) {
  border-left: 0;
}

.stats--band .stat::before {
  content: "";
  order: -2;
  width: 2.5rem;
  height: 2px;
  margin-bottom: var(--space-l);
  background: var(--gold);
}

.stats--band .stat__value {
  color: var(--on-dark);
  font-size: clamp(3.25rem, 1.5rem + 5.5vw, 7rem);
  line-height: 1;
}

.stats--band .stat__label {
  margin-top: var(--space-s);
  color: var(--text-on-dark);
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.stats--band .stat__label:lang(zh) {
  letter-spacing: 0.04em;
}

.stats--band .stats__note {
  margin-top: var(--space-2xl);
  color: var(--text-on-dark);
}

@media (min-width: 48rem) {
  /* One row, however many figures. */
  .stats--band .stats__list:not(.stats__list--detailed) {
    grid-template-columns: none;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
  }

  .stats--band .stat:nth-child(odd) {
    border-left: 1px solid var(--border-on-dark);
  }

  .stats--band .stat:first-child {
    border-left: 0;
  }
}

/*
 * Collage, as on the old site's climate section: on wide screens the heading
 * at the top left, the large photograph at the right with the text under it,
 * and the second photograph low on the left, its foot level with the text's.
 * The fragment's own elements are the grid's items (display: contents). On
 * phones: the heading and the text, then the photographs side by side,
 * staggered. With JavaScript each photograph rises into place once, when it
 * scrolls into view (assets/js/site.js).
 */
.collage__inner {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: var(--space-m);
  align-items: start;
}

.collage__text {
  display: contents;
}

.collage__text > * {
  grid-column: 1 / -1;
}

.collage__text > h2 {
  margin-bottom: var(--space-l);
  font-size: var(--step-3);
  letter-spacing: -0.02em;
}

.collage__text > p {
  max-width: 36rem;
  font-size: var(--step-1);
  line-height: 1.6;
}

.collage__text > p + p {
  color: var(--text-muted);
  font-size: var(--step-0);
}

.collage__photo {
  margin-top: var(--space-xl);
  overflow: hidden;
}

.collage__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.collage__photo--large {
  grid-column: 1;
  aspect-ratio: 2 / 3;
}

.collage__photo--small {
  grid-column: 2;
  aspect-ratio: 4 / 7;
  margin-top: calc(var(--space-xl) + var(--space-3xl));
}

@media (min-width: 56rem) {
  .collage__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto 1fr auto auto;
    column-gap: var(--space-3xl);
  }

  .collage__text > h2 {
    grid-column: 1;
    grid-row: 1;
    margin-bottom: 0;
    font-size: var(--step-4);
  }

  .collage__text > p {
    grid-column: 2;
    margin-left: 15%;
  }

  .collage__text > p:first-of-type {
    margin-top: var(--space-2xl);
  }

  .collage__photo {
    margin-top: 0;
  }

  .collage__photo--large {
    grid-column: 2;
    grid-row: 1 / 3;
    margin-left: 15%;
  }

  .collage__photo--small {
    grid-column: 1;
    grid-row: 2 / -1;
    justify-self: end;
    align-self: end;
    width: 70%;
    margin-top: var(--space-2xl);
  }
}

.reveal-ready .collage__photo {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity 0.9s ease, transform 0.9s ease;
}

.reveal-ready .collage__photo--small {
  transition-delay: 0.2s;
}

.reveal-ready .collage__photo.is-visible {
  opacity: 1;
  transform: none;
}

/* Band: one cause or call to action on navy. */
.band {
  --focus: var(--focus-on-dark);
  padding-block: var(--space-3xl);
  background:
    var(--map-dark) no-repeat right -12rem center / min(72rem, 140%) auto,
    radial-gradient(ellipse 50% 120% at 100% 0%, color-mix(in srgb, var(--gold) 12%, transparent), transparent 60%),
    var(--navy);
  color: var(--text-on-dark);
}

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

@media (min-width: 900px) {
  .band__inner {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  }
}

.band__title {
  color: var(--on-dark);
  font-size: var(--step-3);
}

.band__lead {
  margin: 0;
  font-size: var(--step-1);
  line-height: 1.55;
}

.band__action {
  margin: var(--space-xl) 0 0;
}

.band__points {
  display: grid;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid var(--border-on-dark);
  list-style: none;
}

.band__points li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-s);
  padding-block: var(--space-m);
  border-top: 1px solid var(--border-on-dark);
  color: var(--on-dark);
  font-family: var(--font-heading);
  font-size: var(--step-1);
  font-weight: 600;
}

.band__points .icon {
  margin-top: 0.2em;
  color: var(--gold);
}

/*
 * Band with a map (map names a section, no photograph): that section of the
 * flat world map, whole and uncropped, as texture on --navy-deep. From 48rem
 * it stands at the band's full height against its right edge, so the land the
 * section cuts (the top, right and bottom of afro-eurasia) meets the band's own
 * edges and open sea faces the words. On phones it spans the width at the
 * band's foot, behind the points, its top edge faded into the navy.
 */
.band--map {
  --band-map-ratio: 0.9675; /* the section's height / width (viewBox 1200 x 1161) */
  background:
    linear-gradient(180deg, var(--navy-deep) calc(100% - 100vw * var(--band-map-ratio)), transparent calc(100% - 80vw * var(--band-map-ratio))),
    var(--band-map) no-repeat right bottom / 100% auto,
    var(--navy-deep);
}

@media (min-width: 48rem) {
  .band--map {
    background: var(--band-map) no-repeat right center / auto 100%, var(--navy-deep);
  }
}

.band--map-afro-eurasia {
  --band-map: var(--map-afro-eurasia);
}

/*
 * Band with a photograph, as on the old site: on wide screens a large panel
 * of the flat North Atlantic map on navy fills the band from a quarter of the
 * width to the right edge, and the photograph, smaller, sits on the left with
 * room above and below, overlapping the panel's left part; the words sit on
 * the panel's right half, aligned with the container. On narrow screens the
 * photograph comes first, 3:2, then the panel.
 */
.band--photo {
  position: relative;
  isolation: isolate;
  display: grid;
  padding-block: 0;
  background: var(--navy-deep);
}

.band__photo {
  aspect-ratio: 3 / 2;
  overflow: hidden;
}

.band__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.band__panel {
  display: grid;
  gap: var(--space-xl);
  align-content: center;
  padding: var(--space-3xl) var(--gutter);
  background: var(--map-atlantic) no-repeat center / cover, var(--navy-deep);
}

.band--photo .band__title {
  font-size: var(--step-4);
}

.band--photo .band__action {
  margin: 0;
}

@media (min-width: 900px) {
  .band--photo {
    --edge: max(var(--gutter), (100vw - var(--container)) / 2);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    background: transparent;
  }

  /* The map panel behind both columns, from a quarter of the width. */
  .band--photo::before {
    content: "";
    position: absolute;
    inset: 0 0 0 25%;
    z-index: -1;
    background: var(--map-atlantic) no-repeat left center / cover, var(--navy-deep);
  }

  .band__photo {
    z-index: 1;
    aspect-ratio: 4 / 5;
    max-height: 40rem;
    margin-block: var(--space-3xl);
    margin-left: var(--edge);
  }

  .band__panel {
    padding: var(--space-3xl) var(--edge) var(--space-3xl) var(--space-3xl);
    background: none;
  }

  .band__panel > * {
    max-width: 32rem;
  }

  /* The panel is narrow until wide screens: the heading grows with it. */
  .band--photo .band__title {
    font-size: clamp(var(--step-3), 3.4vw, var(--step-4));
  }
}

/*
 * FAQ (a prose section with faq: true): every answer always visible. A group
 * heading (h2) stands over a hairline; each question (h3) opens with a
 * hairline of its own, except the first after a heading. Without groups (no
 * h3), the h2s are the questions and look like them.
 */
.section--faq .prose > h2 {
  margin-top: var(--space-3xl);
  padding-bottom: var(--space-s);
  border-bottom: 1px solid var(--border);
  font-size: var(--step-3);
}

.section--faq .prose > h3 {
  margin-top: var(--space-l);
  padding-top: var(--space-l);
  border-top: 1px solid var(--border);
  font-size: var(--step-1);
}

.section--faq .prose > h2 + h3,
.section--faq .prose > h3:first-child {
  padding-top: 0;
  border-top: 0;
}

.section--faq .prose:not(:has(> h3)) > h2 {
  margin-top: var(--space-l);
  padding-top: var(--space-l);
  padding-bottom: 0;
  border-top: 1px solid var(--border);
  border-bottom: 0;
  font-size: var(--step-1);
}

.section--faq .prose:not(:has(> h3)) > h2:first-child {
  padding-top: 0;
  border-top: 0;
}

.section--faq .prose li::marker {
  color: var(--gold-deep);
}

/*
 * Contact: the heading, a subheading and a line of text on the left; on the
 * right a deep navy panel with the postal address and the contact address as
 * a button, under small gold labels. The panel follows the text on phones.
 */
.contact__inner {
  display: grid;
  gap: var(--space-xl);
}

.contact__text .section__heading {
  margin-bottom: var(--space-m);
}

.contact__subheading {
  margin-bottom: var(--space-s);
  font-size: var(--step-1);
}

.contact__panel {
  --focus: var(--focus-on-dark);
  display: grid;
  gap: var(--space-xl);
  padding: var(--space-xl);
  border-radius: var(--radius);
  background:
    var(--map-dark) no-repeat right -14rem top -4rem / 44rem auto,
    radial-gradient(ellipse 60% 80% at 100% 100%, color-mix(in srgb, var(--gold) 12%, transparent), transparent 60%),
    var(--navy-deep);
  color: var(--text-on-dark);
}

.contact__label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-s);
  color: var(--gold);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.contact__label:lang(zh) {
  font-size: 0.875rem;
  letter-spacing: 0.04em;
}

.contact__address {
  color: var(--on-dark);
  font-size: var(--step-1);
  font-style: normal;
  line-height: 1.5;
}

.contact__action {
  margin: 0;
}

/* The contact address as a button: lowercase, as an address is written, wrapping on a narrow screen. */
.button--address {
  max-width: 100%;
  font-size: var(--step-0);
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
}

@media (min-width: 56rem) {
  .contact__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--space-3xl);
    align-items: start;
  }

  .contact__panel {
    padding: var(--space-2xl);
  }
}

/* Locations: the offices as an open list, each under a hairline, the country large. */
.locations__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Two cards a row on tablets, then up to four in one row. */
@media (min-width: 40rem) {
  .locations__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  .locations__list:not(:has(> :nth-child(5))) {
    grid-template-columns: none;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
  }

  .locations__list:has(> :nth-child(5)) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.location {
  padding-top: var(--space-l);
  border-top: 1px solid var(--border);
}

.location__name {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-s);
  font-size: var(--step-2);
}

.location__name .icon {
  flex: none;
  color: var(--gold-deep);
}

.location__note {
  margin: 0 0 var(--space-xs);
  color: var(--gold-deep);
  font-family: var(--font-heading);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.location__address {
  color: var(--text-muted);
  font-style: normal;
  line-height: 1.6;
}

.location__address:first-line {
  color: var(--text);
  font-weight: 600;
}

/*
 * Press kit: the photographs for the press in a grid (one column on phones,
 * two on tablets, three from 64rem), each cropped to 4:3 around the faces,
 * with its caption, the credit and the download link.
 */
.press-kit__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2xl) var(--space-xl);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 40rem) {
  .press-kit__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64rem) {
  .press-kit__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.press-kit__item {
  display: flex;
  flex-direction: column;
}

.press-kit__figure {
  margin: 0;
}

.press-kit__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  background: var(--surface-alt);
  object-fit: cover;
  object-position: 50% 25%;
}

.press-kit__caption {
  margin-top: var(--space-s);
  color: var(--text-muted);
  font-size: var(--step--1);
}

.press-kit__credit {
  color: var(--text);
  font-weight: 600;
}

.press-kit__downloads {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-m);
  margin: auto 0 0;
  padding-top: var(--space-s);
}

.press-kit__size {
  color: var(--text-muted);
  font-size: var(--step--1);
}

/*
 * Logos for the press: a grid, each logo whole on a white tile (the navy
 * logos carry their own background), its name, when to use it and the
 * downloads.
 */
.logos__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2xl) var(--space-xl);
  margin: 0;
  padding: 0;
  list-style: none;
}

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

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

.logos__item {
  display: flex;
  flex-direction: column;
}

.logos__tile {
  position: relative;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.logos__tile img {
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding: var(--space-l);
  object-fit: contain;
}

.logos__name {
  margin: var(--space-s) 0 0;
  font-size: var(--step-0);
}

.logos__caption {
  margin: var(--space-2xs) 0 0;
  color: var(--text-muted);
  font-size: var(--step--1);
}

.logos__downloads {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-m);
  margin: auto 0 0;
  padding-top: var(--space-s);
}

.logos__size {
  color: var(--text-muted);
  font-size: var(--step--1);
}

/*
 * A member of the Council: the portrait (4:5) beside the facts from 48rem,
 * the facts under it on phones; then the profile text full width.
 */
.person__head {
  display: grid;
  gap: var(--space-xl);
  margin-bottom: var(--space-2xl);
  padding-bottom: var(--space-2xl);
  border-bottom: 1px solid var(--border);
}

@media (min-width: 48rem) {
  .person__head:not(.person__head--no-portrait) {
    grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
    align-items: end;
  }
}

.person__portrait {
  margin: 0;
}

.person__portrait img {
  width: 100%;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius);
  background: var(--surface-alt);
  object-fit: cover;
  object-position: 50% 20%;
}

.person__credit {
  margin-top: var(--space-xs);
  color: var(--text-muted);
  font-size: var(--step--1);
}

.person__role {
  margin: 0 0 var(--space-l);
  padding-top: var(--space-m);
  border-top: 2px solid var(--gold);
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: var(--step-2);
  font-weight: 700;
  line-height: 1.3;
}

.person__list {
  margin: 0 0 var(--space-l);
}

.person__row + .person__row {
  margin-top: var(--space-m);
}

.person__row dt {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: var(--step--1);
  font-weight: 600;
}

.person__row dt .icon {
  color: var(--gold-deep);
}

.person__row dd {
  margin: var(--space-2xs) 0 0;
}

.person__actions {
  margin: 0 0 var(--space-l);
}

.person__honorary {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--step--1);
}

.person__back {
  padding-block: var(--space-xl);
}

/*
 * The Council: one group per honorary title under a small gold-deep heading
 * and a hairline; cards of portrait (4:5), title, name and one line. One
 * column on phones, two on tablets, four from 64rem; the President's card
 * lays the portrait beside the text from 48rem.
 */
.council__group + .council__group {
  margin-top: var(--space-2xl);
}

.council__title {
  margin-bottom: var(--space-l);
  padding-bottom: var(--space-s);
  border-bottom: 1px solid var(--border);
  color: var(--gold-deep);
  font-family: var(--font-heading);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

:lang(zh) .council__title {
  font-size: var(--step-0);
  letter-spacing: 0;
}

.council__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2xl) var(--space-xl);
  margin: 0;
  padding: 0;
  list-style: none;
}

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

@media (min-width: 64rem) {
  .council__list {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.council__person {
  position: relative;
}

.council__group--president .council__list {
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 48rem) {
  .council__group--president .council__person {
    display: grid;
    grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
    gap: var(--space-xl);
    align-items: end;
  }
}

.council__media img,
.council__mark {
  width: 100%;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius);
  background: var(--surface-alt);
  object-fit: cover;
  object-position: 50% 20%;
}

.council__mark {
  display: grid;
  place-items: center;
  background: var(--navy);
  color: var(--on-dark);
}

.council__mark .mark {
  width: 40%;
  height: auto;
}

.council__body {
  padding-top: var(--space-m);
}

.council__role {
  margin: 0 0 var(--space-2xs);
  color: var(--gold-deep);
  font-family: var(--font-heading);
  font-size: var(--step--1);
  font-weight: 600;
}

.council__name {
  margin-bottom: var(--space-xs);
  font-size: var(--step-2);
}

.council__name a {
  color: var(--navy);
  text-decoration: none;
}

.council__name a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.council__name a:hover {
  color: var(--link-hover);
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

.council__summary {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--step--1);
}

.council__honorary {
  margin: var(--space-2xl) 0 0;
  color: var(--text-muted);
  font-size: var(--step--1);
}

/* Under a member story: the link to the member's profile. */
.post-person {
  margin: var(--space-xl) 0 0;
  padding-top: var(--space-m);
  border-top: 1px solid var(--border);
}

/*
 * The newsletter invitation (newsletter-popup.php, opened by newsletter.js).
 * From 700px a modal: the navy side with the dotted map and the mark, the
 * form on white, the page dimmed behind. On phones a card at the foot of the
 * window, over the page, which stays readable and scrollable.
 */
.newsletter-popup {
  width: calc(100% - 2 * var(--space-m));
  max-width: 46rem;
  max-height: calc(100dvh - 2 * var(--space-m));
  padding: 0;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
}

/* A browser without <dialog> would show it in the page: it stays hidden there. */
.newsletter-popup:not([open]) {
  display: none;
}

.newsletter-popup::backdrop {
  background: color-mix(in srgb, var(--navy-deep) 45%, transparent);
}

.newsletter-popup__aside {
  display: none;
}

.newsletter-popup__main {
  position: relative;
  padding: var(--space-l) var(--space-m) var(--space-m);
}

.newsletter-popup__close {
  position: absolute;
  top: var(--space-2xs);
  right: var(--space-2xs);
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--navy);
  cursor: pointer;
}

.newsletter-popup__close:hover {
  color: var(--link-hover);
}

.newsletter-popup__close .icon {
  width: 1.5rem;
  height: 1.5rem;
}

.newsletter-popup__eyebrow {
  margin: 0 0 var(--space-xs);
  color: var(--gold-deep);
  font-family: var(--font-heading);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.newsletter-popup__eyebrow:lang(zh) {
  font-size: 0.875rem;
  letter-spacing: 0.04em;
}

.newsletter-popup__title {
  margin: 0 var(--space-xl) var(--space-xs) 0;
  font-size: var(--step-2);
}

.newsletter-popup__title:focus {
  outline: none;
}

.newsletter-popup__text {
  margin: 0 0 var(--space-m);
}

.newsletter-popup__label {
  display: block;
  margin-bottom: var(--space-2xs);
  color: var(--navy);
  font-weight: 600;
}

.newsletter-popup__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-xs);
}

.newsletter-popup__input {
  width: 100%;
  min-width: 0;
  min-height: 3rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--text-muted);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font: inherit;
}

.newsletter-popup__input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.newsletter-popup__error {
  margin: var(--space-xs) 0 0;
  padding-left: var(--space-s);
  border-left: 2px solid var(--navy);
}

.newsletter-popup__error:empty {
  display: none;
}

.newsletter-popup__note {
  margin: var(--space-s) 0 0;
  color: var(--text-muted);
  font-size: var(--step--1);
}

.newsletter-popup__dismiss {
  min-height: 2.75rem;
  margin-top: var(--space-2xs);
  padding: 0;
  border: 0;
  background: none;
  color: var(--navy);
  font-family: var(--font-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.35em;
  cursor: pointer;
}

.newsletter-popup__dismiss:hover {
  color: var(--link-hover);
}

@media (max-width: 699.98px) {
  /* A card at the foot of the window (opened non-modal), sliding up. */
  .newsletter-popup {
    position: fixed;
    inset: auto 0 0;
    width: 100%;
    max-width: none;
    max-height: 60dvh;
    margin: 0;
    border-width: 1px 0 0;
    border-radius: 0;
    transform: translateY(100%);
    transition: transform 0.3s ease-out;
  }

  .newsletter-popup--in {
    transform: none;
  }

  .newsletter-popup__text {
    margin-bottom: var(--space-s);
  }
}

@media (max-width: 699.98px) and (prefers-reduced-motion: reduce) {
  .newsletter-popup {
    transition: none;
  }
}

@media (min-width: 700px) {
  .newsletter-popup[open] {
    display: grid;
    grid-template-columns: 2fr 3fr;
  }

  .newsletter-popup__aside {
    display: grid;
    place-items: center;
    background:
      radial-gradient(ellipse 80% 70% at 50% 100%, color-mix(in srgb, var(--gold) 14%, transparent), transparent 70%),
      var(--map-dark) no-repeat 30% 50% / 320% auto,
      var(--navy-deep);
    color: var(--on-dark);
  }

  .newsletter-popup__aside .mark {
    width: 7rem;
    height: auto;
  }

  .newsletter-popup__main {
    padding: var(--space-2xl) var(--space-xl) var(--space-xl);
  }

  .newsletter-popup__title {
    font-size: var(--step-3);
  }
}

