/* =========================================================================
   Effective Altruism Amsterdam — shared stylesheet

   Light mode only, by design. Colours come from the logo: the sky blue of the
   wordmark and the deep teal of the lightbulb mark. Every text/background pair
   below meets WCAG AA (4.5:1) at minimum.

   Sections: tokens, base, header/nav, layout, components, pages, footer
   ========================================================================= */

/* ---------- Typefaces ----------
   Self-hosted, not CDN-loaded: a Google Fonts request would send every visitor's
   IP to a third party, which for an EU organisation is a GDPR exposure and not
   one a community site needs to take on. Of twenty EA sites surveyed, nineteen
   self-host for the same reason.

   Both files are variable fonts clamped to the weights this site actually sets.
   Bricolage across its full opsz/wdth/wght space is 131 KB; at the one weight we
   use it is 22 KB, rendering identically. Total shipped type: 81 KB, less than
   the hero image.

   Nothing here goes above 600. Any rule asking for 700 would get a synthesised
   bold, so `strong` and the old 700 weights were moved down to 600 to match. */
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/bricolage-grotesque-var-latin.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: "Literata";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("fonts/literata-var-latin.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;
}
/* No page currently sets <em> or <i>, so this face is never fetched. It is
   committed anyway: an italic-less serif would quietly force a synthesised
   oblique the first time anyone writes emphasis into the copy. */
@font-face {
  font-family: "Literata";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/literata-italic-var-latin.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;
}

/* ---------- Design tokens ---------- */
:root {
  /* This site is light-only. "only light" also asks browsers not to apply their
     own automatic dark-mode transform (Chrome's force-dark on Android, and
     similar), which would otherwise recolour the page behind our backs. */
  color-scheme: only light;

  /* Brand — teal only.
     The palette used to be nine tokens on one hue: every neutral was a tinted
     blue, so the page had no colour so much as a single lightness ramp, and the
     teal had nothing to stand out against. Here the neutrals are genuinely
     neutral and teal is spent only on things you can act on — links, buttons,
     the figures in a stat. If teal appears somewhere you cannot click and that
     is not a headline number, that is a bug.

     These are the true logo colours rather than the desaturated approximations
     the old file used (--teal was #0a7180 against the logo's actual #008098);
     the saturation had been pulled down by eye to reach contrast targets that
     the real colours turn out to meet anyway. */
  --teal: #00707f;         /* links, buttons — 5.79:1 on white */
  --teal-strong: #005866;  /* hover on light — 8.12:1 on white */
  --teal-lift: #008098;    /* hover on dark; the exact logo teal, 4.62:1 white */
  --deep: #22272b;         /* footer and CTA band — 15.07:1 with white */

  /* Neutrals — warm graphite, no hue borrowed from the brand */
  --bg: #ffffff;
  --surface: #f3f3f1;
  --surface-2: #e8e8e4;
  --tint: #eceae6;         /* soft fills: chips, pills, hover states */
  --text: #1b2024;         /* 16.42:1 on white, 14.78:1 on --surface */
  --muted: #5b6369;        /* 6.12:1 on white, 5.50:1 on --surface */
  --border: #dcdcd7;

  /* Text on the --deep band. Named rather than hardcoded, which is how the old
     file ended up with five different blues scattered through the footer. */
  --deep-text: #dcdfe1;    /* 11.26:1 on --deep */
  --deep-muted: #a8aeb2;   /* 6.72:1 on --deep */

  /* Warning / placeholder — deliberately outside the brand palette so a notice
     never reads as ordinary content. */
  --warn-bg: #fdf3e3;
  --warn-border: #e0a94b;
  --warn-text: #6b4708;
  --shadow: 0 1px 2px rgba(27, 32, 36, 0.05), 0 8px 24px rgba(27, 32, 36, 0.07);

  /* Display is used at h1/h2 only — see the heading rules for why. Georgia is
     the fallback rather than a generic serif because its metrics are closest to
     Literata's, so a swap moves the layout least. */
  --font-display: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --font-body: Literata, Georgia, "Times New Roman", serif;

  --container: 68rem;
  --prose: 42rem;

  /* One radius, and it means something: this is the amount of rounding a thing
     gets because you press it. Containers get none. The old file had --radius
     and --radius-sm applied indiscriminately to cards, buttons, embeds, chips,
     dropdowns, notices and the nav toggle, so every component on the page was a
     variation on one soft rectangle. Round corners on a card are decoration;
     round corners on a button are an affordance. Circles below (avatars, step
     numbers) and the pill are shapes in their own right, not this token. */
  --radius-control: 3px;
}

/* Forced-colours mode (Windows High Contrast, and Firefox's colour override in
   about:preferences → Colors). The browser replaces our palette with the user's
   own and drops background images — that is their choice and we should not fight
   it, but these rules keep the layout legible when it happens: borders stay
   visible, and the hero does not end up as pale text on a blank ground. */
@media (forced-colors: active) {
  .hero {
    background-image: none;
  }
  .card,
  .embed,
  .site-header,
  .page-header {
    border: 1px solid CanvasText;
  }
  .button,
  .button-secondary {
    border: 1px solid ButtonText;
  }
  .brand-mark {
    mix-blend-mode: normal;
  }
}

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

html {
  scroll-behavior: smooth;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  /* A serif needs a little more size than the sans this replaced to read the
     same; Literata's large x-height then lets the leading come back down. */
  font-size: 1.0625rem;
  line-height: 1.6;
}

/* Bricolage's irregular, slightly-wrong letterforms are the point of this
   typeface, and they only read as deliberate at display sizes. Below roughly
   1.5rem they read as a rendering fault, so h3/h4 stay in the body serif at its
   heaviest shipped weight and take their hierarchy from size and colour. */
h1,
h2 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
}

h3,
h4 {
  font-family: var(--font-body);
  font-weight: 600;
  line-height: 1.3;
}

h1,
h2,
h3,
h4 {
  margin: 0 0 0.6em;
}

/* Negative tracking is an optical correction for large type, so it is applied
   at the one size large enough to need it rather than to every heading. */
h1 {
  font-size: 2.05rem;
  letter-spacing: -0.015em;
}
h2 {
  font-size: 1.5rem;
}
h3 {
  font-size: 1.15rem;
}

/* Two breakpoints, not fluid type. Every size on this site used to be a clamp(),
   which reads as machine-generated precisely because it is the answer that needs
   no decisions. These are the two widths where the layout actually changes. */
@media (min-width: 46rem) {
  h1 {
    font-size: 2.6rem;
  }
  h2 {
    font-size: 1.85rem;
  }
}

@media (min-width: 68rem) {
  h1 {
    font-size: 2.9rem;
  }
}

/* The shipped Literata stops at 600; the browser default of 700 for strong/b
   would be synthesised, which on a serif smears the stems. */
strong,
b {
  font-weight: 600;
}

p {
  margin: 0 0 1.1rem;
}

a {
  color: var(--teal);
  text-underline-offset: 0.15em;
}

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

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

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 2.5rem 0;
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--teal);
  color: #fff;
  padding: 0.6rem 1rem;
  z-index: 100;
}

.skip-link:focus {
  left: 0;
}

/* ---------- Layout helpers ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding-inline: 1.25rem;
}

.section {
  padding-block: 2.75rem;
}

.section-alt {
  background: var(--surface);
  border-top: 1px solid var(--border);
}

.section-head {
  max-width: var(--prose);
  margin-bottom: 2rem;
}

.section-head p {
  color: var(--muted);
  margin-bottom: 0;
}

.eyebrow {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.5rem;
}

.prose {
  max-width: var(--prose);
}

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

.prose li {
  margin-bottom: 0.5rem;
}

.lead {
  font-size: 1.15rem;
  color: var(--muted);
}

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

/* Column counts, not repeat(auto-fit, minmax(...)) three times over. auto-fit
   is the correct general answer, which is exactly why it is the predicted one —
   and it also means nobody ever decided how many columns these should be. They
   hold 6, 6 and 3 items (.grid), 2, 2, 2 and 3 (.grid-2) and 4 and 4 (.grid-4),
   so the counts below are chosen against the content that exists rather than
   left to whatever the viewport happens to allow. */
.grid,
.grid-2,
.grid-4 {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: 1fr;
}

/* Four items: two up on narrow screens so the last never sits alone. */
.grid-4 {
  grid-template-columns: repeat(2, 1fr);
}

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

  .grid-4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

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

/* ---------- Header & navigation ---------- */
/* Sticky is kept — it is useful on a site with a dropdown nav. The blurred
   translucent panel is not: it is the default treatment for a sticky header, it
   costs a compositing layer on every scroll frame, and it degrades to a
   half-transparent bar wherever backdrop-filter is unsupported. A solid bar with
   a hairline under it does the same job and reads as a decision. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.header-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0.6rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
}

/* The lightbulb mark. mix-blend-mode hides its baked-in white background
   against the header, so it sits flush without a visible white square. */
.brand-mark {
  width: 2.4rem;
  height: 2.4rem;
  flex: none;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.brand-text {
  font-size: 0.98rem;
  line-height: 1.2;
  max-width: 11rem;
}

@media (max-width: 26rem) {
  .brand-text {
    font-size: 0.9rem;
    max-width: 8.5rem;
  }
}

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.4rem;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
  padding: 0.45rem 0.75rem;
  cursor: pointer;
}

.nav-list {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-link {
  display: inline-block;
  padding: 0.5rem 0.7rem;
  border-radius: var(--radius-control);
  color: var(--muted);
  font-size: 0.95rem;
  text-decoration: none;
  background: none;
  border: 0;
  font-family: inherit;
  cursor: pointer;
}

.nav-link:hover,
.nav-link:focus-visible {
  color: var(--text);
  background: var(--surface-2);
}

.nav-link[aria-current="page"] {
  color: var(--teal);
  font-weight: 600;
}

.nav-cta {
  background: var(--teal);
  color: #fff;
  font-weight: 600;
  margin-left: 0.35rem;
}

.nav-cta:hover,
.nav-cta:focus-visible {
  background: var(--teal-strong);
  color: #fff;
}

/* Dropdown */
.has-dropdown {
  position: relative;
}

.dropdown-toggle::after {
  content: "";
  display: inline-block;
  margin-left: 0.4rem;
  border: 0.3em solid transparent;
  border-top-color: currentColor;
  transform: translateY(0.15em);
}

.dropdown {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  min-width: 14rem;
  list-style: none;
  margin: 0;
  padding: 0.4rem;
  background: var(--bg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.25rem);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}

/* Opens on hover/keyboard focus (works without JS) and on click (with JS). */
.has-dropdown:hover .dropdown,
.has-dropdown:focus-within .dropdown,
.dropdown-toggle[aria-expanded="true"] + .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.dropdown a {
  display: block;
  padding: 0.5rem 0.7rem;
  border-radius: var(--radius-control);
  color: var(--text);
  font-size: 0.93rem;
  text-decoration: none;
}

.dropdown a:hover,
.dropdown a:focus-visible {
  background: var(--tint);
  color: var(--teal-strong);
}

.dropdown a[aria-current="page"] {
  color: var(--teal);
  font-weight: 600;
}

/* Mobile navigation */
@media (max-width: 52rem) {
  .nav-toggle {
    display: inline-flex;
  }

  .site-nav {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow);
    padding: 0.75rem 1.25rem 1.25rem;
  }

  .site-nav.is-open {
    display: block;
  }

  .nav-list {
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
    max-width: var(--container);
    margin: 0 auto;
  }

  .nav-link {
    width: 100%;
    text-align: left;
    padding: 0.65rem 0.7rem;
  }

  .nav-cta {
    margin: 0.4rem 0 0;
    text-align: center;
  }

  .dropdown {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    box-shadow: none;
    border: 0;
    border-left: 2px solid var(--border);
    border-radius: 0;
    margin: 0.1rem 0 0.4rem 0.7rem;
    padding: 0;
    min-width: 0;
  }

  .dropdown-toggle::after {
    float: right;
    transform: translateY(0.5em);
  }
}

/* ---------- Buttons ---------- */
.button,
.button-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.7rem 1.35rem;
  border-radius: var(--radius-control);
  font-weight: 600;
  font-size: 0.98rem;
  font-family: inherit;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
}

.button {
  background: var(--teal);
  color: #fff;
}

.button:hover {
  background: var(--teal-strong);
  color: #fff;
}

.button-secondary {
  background: rgba(255, 255, 255, 0.85);
  color: var(--text);
  border-color: var(--border);
}

.button-secondary:hover {
  background: #fff;
  border-color: var(--teal);
  color: var(--text);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

/* ---------- Cards ---------- */
/* A border and a two-layer shadow do the same job — separate this box from the
   page — so doing both is saying it twice. The border stays because it works in
   forced-colours mode and at any zoom; the shadow goes. Shadow is now reserved
   for things that genuinely float above the page, which is the dropdown and the
   mobile nav panel and nothing else. */
.card {
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 1.5rem;
}

.card h3 {
  margin-bottom: 0.5rem;
}

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

.card-link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.card-link:hover {
  border-color: var(--teal);
  color: inherit;
}

.card-meta {
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 0.35rem;
}

.arrow::after {
  content: " →";
  white-space: nowrap;
}

/* ---------- Hero ---------- */
/* Everything the hero has regardless of treatment. The map, the wash and the
   text colour depend on which treatment is active and live in the generated
   block at the foot of this file — see tools/set_hero.py. */
.hero {
  position: relative;
  border-bottom: 1px solid var(--border);
  background-color: var(--surface-2);
  background-size: cover;
  background-position: center;
  color: var(--hero-ink);
}

.hero-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 3rem 1.25rem;
}

.hero h1 {
  max-width: 18ch;
}

.hero .eyebrow {
  color: inherit;
  opacity: 0.75;
}

.hero .lead {
  max-width: 46ch;
  color: inherit;
}

.hero p {
  max-width: 52ch;
}

.hero-note {
  margin-top: 1.5rem;
  font-size: 0.95rem;
  color: var(--hero-ink);
  background: var(--hero-note-bg);
  display: inline-block;
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-control);
}

/* ---------- Page header (interior pages) ---------- */
.page-header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.page-header .container {
  padding-block: 2.25rem;
}

.page-header h1 {
  margin-bottom: 0.5rem;
}

.page-header p {
  max-width: var(--prose);
  color: var(--muted);
  margin-bottom: 0;
  font-size: 1.05rem;
}

.breadcrumb {
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

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

/* ---------- Stats ---------- */
.stat {
  text-align: left;
}

.stat-number {
  display: block;
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--teal);
  line-height: 1.1;
}

.stat-label {
  display: block;
  font-weight: 600;
  margin-top: 0.35rem;
}

.stat-note {
  display: block;
  font-size: 0.9rem;
  color: var(--muted);
  margin-top: 0.25rem;
}

/* ---------- Embeds ---------- */
.embed {
  border: 1px solid var(--border);
  overflow: hidden;
  background: var(--bg);
}

/* The Luma calendar is a cross-origin iframe carrying its own
   prefers-color-scheme rules, so on a machine set to dark mode it renders dark
   inside an otherwise light page. The :root declaration cannot reach it —
   color-scheme does not cross a frame boundary — but declaring it on the frame
   itself is the mechanism intended for pushing a scheme into an embedded
   document. Unverified: confirm by opening the site with the OS in dark mode.
   If Luma still renders dark, ask them whether the embed takes a theme
   parameter, because nothing on our side can override it. */
.embed iframe {
  color-scheme: light;
}

/* Luma sizes its own iframe content; we force it to fill the width and give it
   a sensible height that shrinks on small screens. */
.embed iframe {
  display: block;
  width: 100%;
  height: 44rem;
  border: 0;
}

@media (max-width: 40rem) {
  .embed iframe {
    height: 34rem;
  }
}

/* ---------- Team ---------- */
.person {
  text-align: center;
}

.person-photo {
  width: 6.5rem;
  height: 6.5rem;
  margin: 0 auto 0.9rem;
  border-radius: 50%;
  object-fit: cover;
  display: grid;
  place-items: center;
  background: var(--tint);
  color: var(--muted);
  font-size: 1.6rem;
  font-weight: 600;
}

.person h3 {
  margin-bottom: 0.15rem;
}

.person .role {
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.6rem;
}

.person p {
  font-size: 0.95rem;
  color: var(--muted);
}

/* ---------- Organisations ---------- */
.org-logo {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  margin-bottom: 1rem;
  border-radius: var(--radius-control);
  object-fit: contain;
  background: var(--tint);
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.25rem;
  text-align: center;
}

/* ---------- Notice (placeholder / warning banner) ---------- */
.notice {
  border: 2px solid var(--warn-border);
  background: var(--warn-bg);
  padding: 1.1rem 1.25rem;
  margin-bottom: 2rem;
}

.notice p {
  margin: 0;
  color: var(--warn-text);
}

.pill-warn {
  background: var(--warn-bg);
  color: var(--warn-text);
  border: 1px solid var(--warn-border);
  text-transform: none;
  letter-spacing: 0;
  vertical-align: middle;
  margin-left: 0.4rem;
}

/* Placeholder figures carry a visible texture so they are never mistaken for
   measured data, even if the banner above scrolls out of view. */
.is-placeholder {
  border-style: dashed;
  background-image: repeating-linear-gradient(
    135deg,
    transparent,
    transparent 10px,
    var(--warn-bg) 10px,
    var(--warn-bg) 20px
  );
}

.is-placeholder .stat-number {
  color: var(--warn-text);
}

/* ---------- Charts ---------- */
.chart {
  margin: 0;
  background: var(--bg);
  border: 1px dashed var(--border);
  padding: 1.25rem;
}

.chart figcaption h3 {
  margin-bottom: 0.2rem;
  font-size: 1rem;
}

.chart figcaption p {
  font-size: 0.85rem;
  margin-bottom: 0.9rem;
}

.chart svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Recessive grid, hairline and solid */
.chart .cg {
  stroke: var(--border);
  stroke-width: 1;
}

/* 2px line, round joins; area is a ~10% wash of the same hue */
.chart .cl {
  fill: none;
  stroke: var(--teal);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.chart .ca {
  fill: var(--teal);
  fill-opacity: 0.1;
  stroke: none;
}

/* End marker with a surface ring so it stays legible over the line */
.chart .cd {
  fill: var(--teal);
  stroke: var(--bg);
  stroke-width: 2;
}

/* Axis text wears text tokens, never the data colour */
.chart .cy,
.chart .cx {
  fill: var(--muted);
  font-size: 9px;
  font-family: inherit;
}

.chart .cy {
  text-anchor: end;
}

.chart-value {
  margin: 0.75rem 0 0;
  font-size: 0.9rem;
  color: var(--muted);
}

.chart-value strong {
  font-size: 1.25rem;
  color: var(--text);
}

/* ---------- Data table ---------- */
.data-table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.92rem;
  margin-top: 0.5rem;
}

.data-table caption {
  text-align: left;
  color: var(--muted);
  font-size: 0.85rem;
  padding-bottom: 0.6rem;
}

.data-table th,
.data-table td {
  text-align: right;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.data-table thead th,
.data-table tbody th {
  text-align: left;
}

.data-table thead th {
  color: var(--muted);
  font-weight: 600;
}

/* ---------- Big statement ---------- */
.statement {
  max-width: 48rem;
  margin: 0 auto;
  text-align: center;
  padding-block: 1rem;
}

.statement-text {
  font-size: 1.55rem;
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0;
}

/* ---------- Misc components ---------- */
.pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
}

.pill {
  display: inline-block;
  padding: 0.3rem 0.8rem;
  border-radius: 999px;
  background: var(--tint);
  color: var(--text);
  font-size: 0.85rem;
  font-weight: 600;
}

/* The coloured left border with the radius squared off on that edge is the
   single most-cited tell of generated UI, and a tinted panel is the next one
   along. This is neither: a rule above the block and space below it, the way an
   aside is set in print. It carries no colour at all, so it cannot compete with
   the teal that now means "you can act on this". */
.callout {
  border-top: 2px solid var(--text);
  padding: 1rem 0 0;
  margin: 1.75rem 0;
}

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

.steps {
  list-style: none;
  counter-reset: step;
  padding: 0;
  margin: 0;
}

.steps li {
  counter-increment: step;
  position: relative;
  padding-left: 3rem;
  margin-bottom: 1.5rem;
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--text);
  color: #fff;
  font-weight: 600;
  font-size: 0.9rem;
}

.steps h3 {
  margin-bottom: 0.3rem;
}

.faq {
  border-top: 1px solid var(--border);
  padding-top: 1.25rem;
  margin-top: 1.25rem;
}

.faq summary {
  cursor: pointer;
  font-weight: 600;
  margin-bottom: 0.6rem;
}

.cta-band {
  background: var(--deep);
  color: #fff;
}

.cta-band .container {
  padding-block: 2.5rem;
  text-align: center;
}

.cta-band h2 {
  color: #fff;
}

.cta-band p {
  color: var(--deep-muted);
  max-width: 40rem;
  margin-inline: auto;
}

.cta-band .button {
  background: var(--teal);
  color: #fff;
}

.cta-band .button:hover {
  background: var(--teal-lift);
  color: #fff;
}

.cta-band .button-row {
  justify-content: center;
}

.definition-list {
  margin: 0;
}

.definition-list dt {
  font-weight: 600;
  margin-top: 1.1rem;
}

.definition-list dd {
  margin: 0.2rem 0 0;
  color: var(--muted);
}

/* ---------- WhatsApp join (click to reveal) ---------- */
.reveal-note {
  font-size: 0.9rem;
  color: var(--muted);
  margin-top: 0.75rem;
}

/* The hidden attribute must beat the display values set by .button and friends,
   which would otherwise win on specificity and leave hidden elements visible. */
[hidden] {
  display: none !important;
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--deep);
  color: var(--deep-text);
}

.site-footer a {
  color: var(--deep-text);
}

/* A logo column and three link columns — a fixed structure, so it is stated
   rather than inferred. The logo column is given more room than the link
   columns instead of all four sharing the width equally. */
.footer-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
  padding-block: 3rem 2rem;
}

@media (min-width: 40rem) {
  .footer-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 62rem) {
  .footer-grid {
    grid-template-columns: 1.4fr repeat(3, 1fr);
  }
}

.footer-logo {
  width: 13rem;
  max-width: 100%;
  height: auto;
  margin-bottom: 1rem;
}

.footer-grid h2 {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--deep-text);
  margin-bottom: 0.9rem;
}

.footer-grid ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-grid li {
  margin-bottom: 0.5rem;
}

.footer-grid a {
  text-decoration: none;
  font-size: 0.95rem;
}

.footer-grid a:hover {
  color: #fff;
  text-decoration: underline;
}

.footer-about p {
  color: var(--deep-muted);
  font-size: 0.95rem;
  max-width: 24rem;
}

.footer-bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  padding-block: 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  justify-content: space-between;
  align-items: center;
  font-size: 0.88rem;
  color: var(--deep-muted);
}

.footer-bottom p {
  margin: 0;
}

/* ---------- Scale at wider viewports ----------
   The sizes above are the small-screen values. These are the same handful of
   things the old stylesheet scaled fluidly with clamp(); they now step once, at
   the width where the layout stops being a single narrow column. Kept together
   at the end of the file so each one wins over its base rule without needing to
   out-specify it. */
@media (min-width: 46rem) {
  .section {
    padding-block: 4.25rem;
  }

  .hero-inner {
    padding: 5rem 1.25rem;
  }

  .page-header .container {
    padding-block: 3rem;
  }

  .cta-band .container {
    padding-block: 3.25rem;
  }

  .lead {
    font-size: 1.25rem;
  }

  .stat-number {
    font-size: 2.35rem;
  }

  .statement-text {
    font-size: 2.1rem;
  }
}


/* ---------- Hero treatment ----------
   Generated by tools/set_hero.py — do not hand-edit; run
   `PYTHONPATH=./.pylibs python3 tools/set_hero.py <b|c|f>` instead, which
   re-renders img/hero-amsterdam.webp to match and re-solves both washes against
   the new pixels. The three treatments are the shortlist from
   build/03-hero-variants.html; switching between them is this block plus the
   image, and touches no markup. */
/* >>> HERO */
/* Treatment C — Defocused under the text.
   Map defocused where the text sits and sharp where it does not, so the
   noise behind the glyphs goes without softening the part of the map
   anyone looks at. Removing the darkest specks means this needs a lighter
   wash than B, and the right-hand map stays uncovered.
   Washes solved against the real pixels: worst case 7.04:1 desktop,
   7.11:1 mobile, against a 4.5:1 AA floor. */
:root {
  --hero-ink: var(--text);
  --hero-note-bg: rgba(255, 255, 255, 0.88);
}

.hero {
  background-image: linear-gradient(
      90deg,
      rgba(255, 255, 255, 0.6) 0%,
      rgba(255, 255, 255, 0.34) 55%,
      rgba(255, 255, 255, 0.08) 100%
    ),
    url("img/hero-amsterdam.webp");
}

@media (max-width: 52rem) {
  /* Narrow screens put the text across the full width, so the wash has to
     cover the whole image rather than fading out to one side. */
  .hero {
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.6) 0%,
        rgba(255, 255, 255, 0.56) 55%,
        rgba(255, 255, 255, 0.52) 100%
      ),
      url("img/hero-amsterdam.webp");
  }
}
/* <<< HERO */


/* ---------- Section rhythm ----------
   The homepage was five bands of identical width, identical padding, and a
   perfect white / tinted / white / tinted / dark alternation. Nothing was wrong
   with any one of them; the problem was that knowing one told you all five.

   This breaks that without touching a word of the copy, and hangs off a named
   class rather than :nth-child, so sections can be reordered without silently
   changing which one is which — and so the other ten pages sharing this
   stylesheet are unaffected.

   An earlier version also ran this section wider than the 68rem measure
   everything else holds to, to give the page something that broke the grid. One
   wider band on its own just read as a mistake, so the width went back and only
   the spacing stayed. Breaking the tint alternation turned out to be the part
   that mattered. */

/* This section leads the page body and carries the calendar, so it gets more
   air than those below it. Being untinted, it also needs its own edge against
   the untinted section that follows. */
.section-lead {
  border-bottom: 1px solid var(--border);
  padding-block: 3.25rem;
}

@media (min-width: 46rem) {
  .section-lead {
    padding-block: 5.25rem;
  }
}
