/* ==========================================================================
   Trans Health South Australia

   Theming
   -------
   Colour is driven entirely by light-dark() tokens below, which resolve
   against the `color-scheme` property. That means the theme switch is just:

       :root                    -> color-scheme: light dark   (follows system)
       :root[data-theme=light]  -> color-scheme: light        (forced light)
       :root[data-theme=dark]   -> color-scheme: dark         (forced dark)

   No duplicated palettes, and native form controls / scrollbars follow along.

   Every token declares its light value first as a plain fallback, so browsers
   without light-dark() (pre-2024) simply get the light theme rather than an
   unstyled page.
   ========================================================================== */

:root {
  color-scheme: light dark;
}

:root[data-theme="light"] {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
}

:root {
  /* Trans flag — accent only, identical in both themes */
  --flag-blue: #5bcefa;
  --flag-pink: #f5a9b8;

  /* ---- Surfaces + text ---- */
  --bg: #fbfcfd;
  --bg: light-dark(#fbfcfd, #0e1419);
  --surface: #ffffff;
  --surface: light-dark(#ffffff, #161e26);
  --surface-alt: #f4f7f9;
  --surface-alt: light-dark(#f4f7f9, #1b242d);
  --text: #1d2731;
  --text: light-dark(#1d2731, #e6edf3);
  --text-muted: #5b6b7b;
  --text-muted: light-dark(#5b6b7b, #9fb0be);
  --border: #d9e0e7;
  --border: light-dark(#d9e0e7, #2a3742);
  --border-soft: #e9eef2;
  --border-soft: light-dark(#e9eef2, #222d36);

  /* ---- Accent ---- */
  --accent: #0d7ead;
  --accent: light-dark(#0d7ead, #6bc5e8);
  --accent-hover: #0b6a95;
  --accent-hover: light-dark(#0b6a95, #93d6f0);
  --accent-soft: #f1fafe;
  --accent-soft: light-dark(#f1fafe, #16303c);
  --on-accent: #ffffff;
  --on-accent: light-dark(#ffffff, #12181f);

  --pink: #c25a72;
  --pink: light-dark(#c25a72, #e8879f);
  --pink-hover: #a3475c;
  --pink-hover: light-dark(#a3475c, #f0a3b6);
  --on-pink: #ffffff;
  --on-pink: light-dark(#ffffff, #12181f);
  --pink-icon-bg: #fdeaef;
  --pink-icon-bg: light-dark(#fdeaef, #3a2028);
  --pink-icon-fg: #a3475c;
  --pink-icon-fg: light-dark(#a3475c, #f5a9b8);

  /* ---- Crisis strip ---- */
  --urgent-bg: #fff8f9;
  --urgent-bg: light-dark(#fff8f9, #2a1a20);
  --urgent-border: #f0c4ce;
  --urgent-border: light-dark(#f0c4ce, #4d2d38);
  --urgent-text: #8f3a4d;
  --urgent-text: light-dark(#8f3a4d, #f3b9c6);

  /* ---- Hero glow ---- */
  --hero-glow-1: rgba(91, 206, 250, 0.26);
  --hero-glow-1: light-dark(rgba(91, 206, 250, 0.26), rgba(91, 206, 250, 0.1));
  --hero-glow-2: rgba(245, 169, 184, 0.22);
  --hero-glow-2: light-dark(rgba(245, 169, 184, 0.22), rgba(245, 169, 184, 0.09));
  --accent-grad-from: #0d7ead;
  --accent-grad-from: light-dark(#0d7ead, #5bcefa);
  --accent-grad-to: #c25a72;
  --accent-grad-to: light-dark(#c25a72, #f5a9b8);

  /* ---- Directory feature panel ---- */
  --feature-from: #f1fafe;
  --feature-from: light-dark(#f1fafe, #16303c);
  --feature-to: #fef6f8;
  --feature-to: light-dark(#fef6f8, #2a1f26);

  /* ---- Dark CTA band ---- */
  --band-bg: #1d2731;
  --band-bg: light-dark(#1d2731, #1b242d);
  --band-border: #1d2731;
  --band-border: light-dark(#1d2731, #2a3742);
  --band-text: #ffffff;
  --band-text: light-dark(#ffffff, #e6edf3);
  --band-muted: rgba(255, 255, 255, 0.72);
  --band-muted: light-dark(rgba(255, 255, 255, 0.72), #9fb0be);
  --band-ghost-bg: rgba(255, 255, 255, 0.1);
  --band-ghost-bg: light-dark(rgba(255, 255, 255, 0.1), #161e26);
  --band-ghost-border: rgba(255, 255, 255, 0.25);
  --band-ghost-border: light-dark(rgba(255, 255, 255, 0.25), #2a3742);
  --band-ghost-hover: rgba(255, 255, 255, 0.18);
  --band-ghost-hover: light-dark(rgba(255, 255, 255, 0.18), #16303c);

  /* ---- Event categories ---------------------------------------------------
     One trio per key in EVENT_CATEGORIES (tools/event_lib.py), consumed by the
     fixed .evt--<key> rules further down.

     This vocabulary is closed on purpose. The CSP is `style-src 'self'`, so a
     style attribute carrying a per-event colour is dropped in production —
     colour cannot be data here, it has to be a class. Adding a category means
     adding a trio here, a rule below, and an entry in that Python tuple.

     Backgrounds stay pale enough for the -fg text to clear 4.5:1 in both
     themes, and each -bd is picked to hold 3:1 against --surface-alt, which
     is what a calendar day cell is painted with. ---------------------------- */
  --evt-clinic-bg: #e6f3fb;
  --evt-clinic-bg: light-dark(#e6f3fb, #11303f);
  --evt-clinic-fg: #0a5877;
  --evt-clinic-fg: light-dark(#0a5877, #93d6f0);
  --evt-clinic-bd: #a8d4ea;
  --evt-clinic-bd: light-dark(#a8d4ea, #1f5670);

  --evt-group-bg: #fdeaef;
  --evt-group-bg: light-dark(#fdeaef, #3b1f29);
  --evt-group-fg: #97354b;
  --evt-group-fg: light-dark(#97354b, #f0a8bb);
  --evt-group-bd: #efb9c8;
  --evt-group-bd: light-dark(#efb9c8, #6b3446);

  --evt-workshop-bg: #fdf0dd;
  --evt-workshop-bg: light-dark(#fdf0dd, #3a2a12);
  --evt-workshop-fg: #7d4f0c;
  --evt-workshop-fg: light-dark(#7d4f0c, #e9b866);
  --evt-workshop-bd: #ecc891;
  --evt-workshop-bd: light-dark(#ecc891, #6a4a1c);

  --evt-awareness-bg: #f0ebfc;
  --evt-awareness-bg: light-dark(#f0ebfc, #29213f);
  --evt-awareness-fg: #543a91;
  --evt-awareness-fg: light-dark(#543a91, #bfaaf0);
  --evt-awareness-bd: #c7b6ec;
  --evt-awareness-bd: light-dark(#c7b6ec, #4b3d73);

  --evt-community-bg: #e4f4e9;
  --evt-community-bg: light-dark(#e4f4e9, #14301f);
  --evt-community-fg: #1f6339;
  --evt-community-fg: light-dark(#1f6339, #86d3a2);
  --evt-community-bd: #a6d7b8;
  --evt-community-bd: light-dark(#a6d7b8, #285a3b);

  --evt-online-bg: #e2f3f2;
  --evt-online-bg: light-dark(#e2f3f2, #123230);
  --evt-online-fg: #12615c;
  --evt-online-fg: light-dark(#12615c, #7fd0c9);
  --evt-online-bd: #9fd3cf;
  --evt-online-bd: light-dark(#9fd3cf, #1f5b56);

  --evt-event-bg: #eef1f4;
  --evt-event-bg: light-dark(#eef1f4, #232e38);
  --evt-event-fg: #3f4d5a;
  --evt-event-fg: light-dark(#3f4d5a, #b9c7d3);
  --evt-event-bd: #c8d1da;
  --evt-event-bd: light-dark(#c8d1da, #3c4a57);

  /* ---- Shadows (colour tokens, composed below) ---- */
  --sh-1: rgba(18, 24, 31, 0.05);
  --sh-1: light-dark(rgba(18, 24, 31, 0.05), rgba(0, 0, 0, 0.4));
  --sh-2: rgba(18, 24, 31, 0.06);
  --sh-2: light-dark(rgba(18, 24, 31, 0.06), rgba(0, 0, 0, 0.35));
  --sh-3: rgba(18, 24, 31, 0.1);
  --sh-3: light-dark(rgba(18, 24, 31, 0.1), rgba(0, 0, 0, 0.5));

  --shadow-sm: 0 1px 2px var(--sh-1), 0 1px 3px var(--sh-1);
  --shadow: 0 4px 12px var(--sh-2), 0 2px 4px var(--sh-1);
  --shadow-lg: 0 18px 40px var(--sh-3), 0 4px 12px var(--sh-2);

  /* ---- Type ---- */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --body-line-height: 1.65;
  --heading-line-height: 1.2;
  --paragraph-spacing: 1.15em;

  /* ---- Space + shape ---- */
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;
  --wrap: 1160px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
}

/* ==========================================================================
   Base
   ========================================================================== */

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

[hidden] {
  display: none !important;
}

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

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: var(--body-line-height);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
h4 {
  margin: 0 0 0.5em;
  line-height: var(--heading-line-height);
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--text);
}

h1 {
  font-size: clamp(2.25rem, 5.5vw, 3.75rem);
  letter-spacing: -0.035em;
}
h2 {
  font-size: clamp(1.6rem, 3.2vw, 2.25rem);
}
h3 {
  font-size: 1.15rem;
}

p {
  margin: 0 0 var(--paragraph-spacing);
}

a {
  color: var(--accent);
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
  text-underline-offset: 0.18em;
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}

a:hover {
  color: var(--accent-hover);
  text-decoration-color: currentColor;
}

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

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

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

/* ==========================================================================
   Layout helpers
   ========================================================================== */

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

.section {
  padding-block: clamp(3.5rem, 8vw, 6rem);
}

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

.section__head {
  max-width: 46rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.section__head p {
  color: var(--text-muted);
  font-size: 1.075rem;
  margin-bottom: 0;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.85rem;
}

.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--flag-blue), var(--flag-pink));
}

/* Available to screen readers, removed from the visual flow */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 0.75rem;
  top: -100px;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  text-decoration: none;
  transition: top 0.18s ease;
}

.skip-link:focus {
  top: 0;
  color: var(--on-accent);
}

/* Flag stripe — the one overt nod to the flag */
.flagline {
  height: 4px;
  background: linear-gradient(
    90deg,
    var(--flag-blue) 0%,
    var(--flag-blue) 20%,
    var(--flag-pink) 20%,
    var(--flag-pink) 40%,
    #ffffff 40%,
    #ffffff 60%,
    var(--flag-pink) 60%,
    var(--flag-pink) 80%,
    var(--flag-blue) 80%
  );
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.8rem 1.4rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

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

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

.btn--primary {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-sm);
}

.btn--primary:hover {
  background: var(--accent-hover);
  color: var(--on-accent);
  box-shadow: var(--shadow);
}

.btn--ghost {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
  box-shadow: var(--shadow-sm);
}

.btn--ghost:hover {
  color: var(--text);
  border-color: var(--accent);
  background: var(--accent-soft);
}

.btn--pink {
  background: var(--pink);
  color: var(--on-pink);
}

.btn--pink:hover {
  background: var(--pink-hover);
  color: var(--on-pink);
}

.btn--sm {
  padding: 0.55rem 1.05rem;
  font-size: 0.875rem;
}

.btn svg {
  flex: none;
}

/* ==========================================================================
   Header + navigation
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(12px);
  -webkit-backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--border-soft);
}

.header-bar {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 76px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  color: var(--text);
  flex: none;
}

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

.brand img {
  width: 42px;
  height: 42px;
  flex: none;
}

.brand__name {
  display: flex;
  flex-direction: column;
  line-height: 1.12;
}

.brand__name strong {
  font-size: 1.02rem;
  font-weight: 750;
  letter-spacing: -0.02em;
}

.brand__name span {
  font-size: 0.76rem;
  font-weight: 550;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

.nav {
  margin-left: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: 0.15rem;
}

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.55rem 0.8rem;
  border-radius: var(--radius-sm);
  font-size: 0.925rem;
  font-weight: 550;
  color: var(--text);
  text-decoration: none;
  background: none;
  border: 0;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.nav__link:hover,
.nav__link[aria-expanded="true"] {
  background: var(--accent-soft);
  color: var(--accent-hover);
}

.nav__link .chev {
  transition: transform 0.2s ease;
}

.nav__link[aria-expanded="true"] .chev {
  transform: rotate(180deg);
}

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

.menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  min-width: 270px;
  padding: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}

.menu[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.menu--right {
  left: auto;
  right: 0;
  min-width: 190px;
}

.menu a,
.menu button {
  display: block;
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease;
}

.menu a:hover,
.menu button:hover {
  background: var(--accent-soft);
  color: var(--accent-hover);
}

.menu a small {
  display: block;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--text-muted);
  margin-top: 0.05rem;
}

.menu a:hover small {
  color: inherit;
  opacity: 0.8;
}

.menu__group {
  padding: 0.65rem 0.7rem 0.3rem;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.menu__sep {
  height: 1px;
  margin: 0.4rem 0.35rem;
  background: var(--border-soft);
}

/* ==========================================================================
   Theme switch
   ========================================================================== */

.theme__btn {
  padding: 0.5rem;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
}

.theme__btn:hover,
.theme__btn[aria-expanded="true"] {
  color: var(--accent-hover);
}

/* Which icon shows depends on the stored preference, not the resolved theme,
   so "Auto" keeps reading as Auto even when the system is dark. */
.theme__btn svg {
  display: none;
}

:root:not([data-theme]) .theme__btn .ico-auto,
:root[data-theme="light"] .theme__btn .ico-light,
:root[data-theme="dark"] .theme__btn .ico-dark {
  display: block;
}

.theme__opt {
  display: flex !important;
  align-items: center;
  gap: 0.6rem;
}

.theme__opt svg:first-child {
  flex: none;
  opacity: 0.75;
}

.theme__opt .tick {
  margin-left: auto;
  flex: none;
  color: var(--accent);
  visibility: hidden;
}

.theme__opt[aria-checked="true"] {
  font-weight: 620;
}

.theme__opt[aria-checked="true"] .tick {
  visibility: visible;
}

/* ==========================================================================
   Accessibility and display options
   ========================================================================== */

.accessibility-options {
  position: relative;
  flex: none;
}

.accessibility-options__trigger {
  position: relative;
  width: 44px;
  min-width: 44px;
  height: 44px;
  justify-content: center;
  padding: 0.45rem;
  border: 1px solid var(--border);
  background: var(--surface-alt);
  color: var(--text);
}

.accessibility-options__trigger:hover,
.accessibility-options__trigger[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-hover);
}

.accessibility-options__glyph {
  font-size: 0.88rem;
  font-weight: 750;
  line-height: 1;
  letter-spacing: -0.08em;
}

.accessibility-options__count {
  position: absolute;
  inset: -0.35rem -0.35rem auto auto;
  min-width: 1.2rem;
  height: 1.2rem;
  padding-inline: 0.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--surface);
  border-radius: 999px;
  background: var(--pink);
  color: var(--on-pink);
  font-size: 0.68rem;
  font-weight: 750;
  line-height: 1;
}

.accessibility-dialog {
  width: min(52rem, calc(100vw - 2rem));
  inline-size: min(52rem, calc(100vw - 2rem));
  max-width: none;
  max-inline-size: calc(100vw - 2rem);
  max-height: calc(100dvh - 2rem);
  max-block-size: calc(100dvh - 2rem);
  margin: auto;
  padding: 0;
  overflow: auto;
  color: var(--text);
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.accessibility-dialog::backdrop {
  background: rgba(5, 12, 18, 0.72);
  backdrop-filter: blur(2px);
}

.accessibility-dialog__inner {
  position: relative;
  padding: clamp(1.25rem, 4vw, 2rem);
}

.accessibility-dialog__close {
  position: absolute;
  inset: 1rem 1rem auto auto;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.accessibility-dialog__close:hover {
  color: var(--accent-hover);
  background: var(--accent-soft);
  border-color: var(--accent);
}

.accessibility-dialog__heading {
  padding-right: 3.5rem;
  margin-bottom: 1.5rem;
}

.accessibility-dialog__heading h2 {
  font-size: clamp(1.45rem, 3vw, 2rem);
}

.accessibility-dialog__heading p {
  max-width: 38rem;
  margin-bottom: 0;
  color: var(--text-muted);
}

.accessibility-dialog__body {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.accessibility-group {
  min-width: 0;
  margin: 0;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-alt);
}

.accessibility-group legend {
  padding-inline: 0.35rem;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
}

.accessibility-group--rows {
  grid-column: 1 / -1;
}

.accessibility-choices {
  display: grid;
  gap: 0.5rem;
}

.accessibility-choices--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.accessibility-choices--three,
.accessibility-choices--sizes {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.accessibility-choice {
  position: relative;
  min-width: 0;
  min-height: 44px;
  display: flex;
  align-items: stretch;
  cursor: pointer;
}

.accessibility-choice input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.accessibility-choice span {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.55rem 0.6rem;
  text-align: center;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.25;
}

.accessibility-choice:hover span {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.accessibility-choice input:checked + span {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}

.accessibility-choice input:focus-visible + span {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.accessibility-toggle {
  min-height: 44px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 0.75rem;
  padding: 0.75rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.accessibility-toggle + .accessibility-toggle {
  border-top: 1px solid var(--border-soft);
}

.accessibility-toggle:hover {
  background: var(--surface);
}

.accessibility-toggle input {
  width: 1.3rem;
  height: 1.3rem;
  margin: 0.15rem 0 0;
  accent-color: var(--accent);
}

.accessibility-toggle span,
.accessibility-toggle strong,
.accessibility-toggle small {
  display: block;
}

.accessibility-toggle strong {
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1.35;
}

.accessibility-toggle small,
.accessibility-group__hint {
  margin: 0.25rem 0 0;
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1.45;
}

.accessibility-toggle small[data-a11y-system-motion],
.accessibility-group__hint[data-a11y-system-contrast] {
  color: var(--urgent-text);
  font-weight: 650;
}

.accessibility-dialog__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  padding-top: 1.25rem;
}

.accessibility-dialog__status {
  flex: 1 1 20rem;
  min-height: 1.5em;
  margin: 0;
  color: var(--text-muted);
  font-size: 0.88rem;
}

/* Header actions */
.header-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: none;
}

.search {
  position: relative;
  display: flex;
  align-items: center;
}

.search input {
  width: 172px;
  padding: 0.5rem 0.75rem 0.5rem 2.15rem;
  font: inherit;
  font-size: 0.875rem;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  transition: width 0.2s ease, border-color 0.15s ease,
    background-color 0.15s ease;
}

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

.search input:focus {
  width: 210px;
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.search svg {
  position: absolute;
  left: 0.7rem;
  color: var(--text-muted);
  pointer-events: none;
}

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
}

.nav-toggle:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3.5rem, 9vw, 7rem);
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
      58rem 30rem at 78% -12%,
      var(--hero-glow-1),
      transparent 62%
    ),
    radial-gradient(46rem 26rem at 8% 8%, var(--hero-glow-2), transparent 60%);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  display: grid;
  grid-template-columns: 1.25fr 0.75fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.hero h1 {
  margin-bottom: 0.35em;
  text-wrap: balance;
}

.hero h1 .accent {
  background: linear-gradient(
    100deg,
    var(--accent-grad-from) 10%,
    var(--accent-grad-to) 92%
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__lede {
  font-size: clamp(1.075rem, 1.9vw, 1.3rem);
  line-height: 1.55;
  color: var(--text-muted);
  max-width: 34rem;
  text-wrap: pretty;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

.hero__motto {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: 2.25rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  font-size: 0.9rem;
  font-weight: 550;
  font-style: italic;
  color: var(--text-muted);
  width: 100%;
  max-width: 34rem;
}

.hero__art {
  display: flex;
  justify-content: center;
}

.hero__art img {
  width: min(100%, 300px);
  filter: drop-shadow(0 22px 40px var(--sh-3));
}

/* ==========================================================================
   Crisis strip
   ========================================================================== */

.crisis {
  background: var(--urgent-bg);
  border-block: 1px solid var(--urgent-border);
}

.crisis__inner {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding-block: 1.15rem;
  flex-wrap: wrap;
}

.crisis__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--urgent-text) 12%, transparent);
  color: var(--urgent-text);
}

.crisis__text {
  flex: 1 1 22rem;
  font-size: 0.95rem;
  color: var(--urgent-text);
}

.crisis__text strong {
  display: block;
  font-size: 1rem;
  font-weight: 700;
}

.crisis__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  align-items: center;
}

.crisis__links a {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--urgent-text);
  white-space: nowrap;
}

.crisis__links a:hover {
  color: var(--urgent-text);
}

/* ==========================================================================
   Card grid
   ========================================================================== */

.grid {
  display: grid;
  gap: 1.15rem;
}

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

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

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.6rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: transform 0.18s ease, box-shadow 0.18s ease,
    border-color 0.18s ease;
}

.card::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--flag-blue), var(--flag-pink));
  opacity: 0;
  transition: opacity 0.18s ease;
}

a.card:hover,
.card:not(a):hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  color: inherit;
}

a.card:hover::after,
.card:not(a):hover::after {
  opacity: 1;
}

.card__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: 1.1rem;
  border-radius: 12px;
  background: var(--accent-soft);
  color: var(--accent);
  flex: none;
}

.card--pink .card__icon {
  background: var(--pink-icon-bg);
  color: var(--pink-icon-fg);
}

.card :is(h2, h3) {
  margin-top: 0;
  margin-bottom: 0.4rem;
  font-size: 1.075rem;
}

/* Heading links read as headings until hovered */
.card :is(h2, h3) a {
  color: inherit;
  text-decoration: none;
}

.card :is(h2, h3) a:hover {
  color: var(--accent);
}

.card p {
  margin-bottom: 0;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--text-muted);
}

.card__more {
  margin-top: 1.1rem;
  font-size: 0.875rem;
  font-weight: 620;
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

a.card:hover .card__more {
  gap: 0.6rem;
}

.card__more svg {
  transition: transform 0.18s ease;
}

/* Sub-links inside a card */
.card__links {
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border-soft);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.card__links a {
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.card__links a::before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
  flex: none;
}

.card__links a:hover {
  color: var(--accent);
}

/* ==========================================================================
   Directory feature
   ========================================================================== */

.feature {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  padding: clamp(2rem, 4.5vw, 3.5rem);
  background: linear-gradient(135deg, var(--feature-from), var(--feature-to));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.feature h2 {
  margin-bottom: 0.5rem;
}

.feature p {
  color: var(--text-muted);
  font-size: 1.05rem;
}

.feature__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.feature__panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 0.5rem;
}

.dir-row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.85rem 0.9rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: inherit;
  transition: background-color 0.15s ease;
}

.dir-row:hover {
  background: var(--surface-alt);
  color: inherit;
}

.dir-row + .dir-row {
  border-top: 1px solid var(--border-soft);
}

/* Pastel avatars stay light in both themes, so the dark ink on them is
   readable either way. */
.dir-row__avatar,
.donor__mark {
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--flag-blue) 55%, #ffffff),
    color-mix(in srgb, var(--flag-pink) 55%, #ffffff)
  );
  color: #1d2731;
  font-weight: 700;
}

.dir-row__avatar {
  width: 40px;
  height: 40px;
  font-size: 0.85rem;
}

.dir-row__body {
  min-width: 0;
}

.dir-row__body strong {
  display: block;
  font-size: 0.925rem;
  font-weight: 620;
}

.dir-row__body span {
  font-size: 0.82rem;
  color: var(--text-muted);
}

.dir-row__go {
  margin-left: auto;
  color: var(--text-muted);
  flex: none;
}

.dir-row:hover .dir-row__go {
  color: var(--accent);
}

/* ==========================================================================
   About + acknowledgements
   ========================================================================== */

.about {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

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

.note {
  padding: 1.5rem 1.6rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--flag-pink);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.note h3 {
  font-size: 0.95rem;
  margin-bottom: 0.6rem;
}

.note p {
  font-size: 0.92rem;
  color: var(--text-muted);
  margin-bottom: 0;
}

.note p + p {
  margin-top: 0.75rem;
}

/* ==========================================================================
   Donors
   ========================================================================== */

.donor {
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  height: 100%;
}

.donor__mark {
  width: 46px;
  height: 46px;
  margin-bottom: 1rem;
  font-size: 0.95rem;
}

.donor h3 {
  font-size: 1rem;
  margin-bottom: 0.35rem;
}

.donor p {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-bottom: 0;
}

.donor a {
  margin-top: 1rem;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}

.donor a:hover {
  text-decoration: underline;
}

/* ==========================================================================
   Poster / CTA band
   ========================================================================== */

.cta-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  padding: clamp(1.75rem, 4vw, 2.75rem);
  background: var(--band-bg);
  border: 1px solid var(--band-border);
  border-radius: var(--radius-lg);
  color: var(--band-text);
  overflow: hidden;
  position: relative;
}

.cta-band::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  background: linear-gradient(
    90deg,
    var(--flag-blue),
    var(--flag-pink),
    #fff,
    var(--flag-pink),
    var(--flag-blue)
  );
}

.cta-band h2 {
  color: var(--band-text);
  margin-bottom: 0.35rem;
  font-size: clamp(1.35rem, 2.6vw, 1.75rem);
}

.cta-band p {
  margin-bottom: 0;
  color: var(--band-muted);
  font-size: 0.975rem;
  max-width: 40rem;
}

.cta-band .btn--ghost {
  background: var(--band-ghost-bg);
  border-color: var(--band-ghost-border);
  color: var(--band-text);
}

.cta-band .btn--ghost:hover {
  background: var(--band-ghost-hover);
  color: var(--band-text);
}

.cta-band__actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding-top: clamp(3rem, 6vw, 4.5rem);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(4, 1fr);
  gap: 2.5rem 2rem;
  padding-bottom: 3rem;
}

/* A grid item's default min-width is auto, which means `1fr` refuses to
   shrink below its longest word. At 200% text on a 390px screen that is wider
   than the column it is in, and the whole page scrolls sideways. Let the
   columns shrink, and let long words break rather than propping them open. */
.footer-grid > * {
  min-width: 0;
}

.footer-grid :is(a, p, h2, li) {
  overflow-wrap: break-word;
}

.footer-brand p {
  font-size: 0.9rem;
  color: var(--text-muted);
  max-width: 24rem;
  margin-top: 1rem;
}

.footer-social {
  display: flex;
  gap: 0.5rem;
  margin-top: 1.25rem;
}

.footer-social a {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  color: var(--text-muted);
  transition: all 0.15s ease;
}

.footer-social a:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-2px);
}

.footer-col h2 {
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.footer-col li + li {
  margin-top: 0.55rem;
}

.footer-col a {
  font-size: 0.9rem;
  color: var(--text);
  text-decoration: none;
  font-weight: 480;
}

.footer-col a:hover {
  color: var(--accent);
  text-decoration: underline;
}

.acknowledgement {
  padding: 1.4rem 1.6rem;
  margin-bottom: 2.5rem;
  background: var(--surface-alt);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  font-size: 0.88rem;
  line-height: 1.65;
  color: var(--text-muted);
}

.acknowledgement strong {
  color: var(--text);
  font-weight: 620;
}

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  flex-wrap: wrap;
  padding-block: 1.5rem;
  border-top: 1px solid var(--border-soft);
  font-size: 0.85rem;
  color: var(--text-muted);
}

.footer-bottom p {
  margin: 0;
}

.footer-bottom nav {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.footer-bottom a {
  color: var(--text-muted);
  text-decoration: none;
}

.footer-bottom a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* ==========================================================================
   Interior pages
   --------------------------------------------------------------------------
   The homepage is a landing page; every other page is a document. These
   components carry the same tokens into long-form content.
   ========================================================================== */

/* Compact hero — same glow as the homepage, a third of the height */
.page-hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(2.25rem, 5vw, 3.5rem);
  border-bottom: 1px solid var(--border-soft);
}

.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
      42rem 22rem at 82% -30%,
      var(--hero-glow-1),
      transparent 62%
    ),
    radial-gradient(34rem 20rem at 4% 0%, var(--hero-glow-2), transparent 60%);
  pointer-events: none;
}

.page-hero__inner {
  position: relative;
  max-width: 52rem;
}

/* Optional decorative artwork beside the hero heading.

   A flex row rather than an absolutely positioned image: overlaying it meant
   that at in-between window widths the art sat on top of the lede and turned
   it into texture. As a flex sibling it can only ever take space the text
   isn't using. Pages without art render one flex child that keeps its own
   max-width, so their hero is unchanged. */
.page-hero .wrap {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
}

.page-hero__inner {
  flex: 1 1 auto;
}

.page-hero__art {
  flex: 0 0 auto;
  align-self: flex-end;
  width: clamp(7rem, 14vw, 12rem);
  height: auto;
  pointer-events: none;
}

/* Below this the hero is too narrow to give the art room without squeezing
   the heading, and the heading is the point. */
@media (max-width: 62rem) {
  .page-hero__art {
    display: none;
  }
}

.page-hero h1 {
  font-size: clamp(1.9rem, 4.2vw, 2.9rem);
  margin-bottom: 0.3em;
  text-wrap: balance;
}

.page-hero__lede {
  font-size: clamp(1rem, 1.6vw, 1.175rem);
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: 0;
  text-wrap: pretty;
}

/* Breadcrumb */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1rem;
  font-size: 0.82rem;
  color: var(--text-muted);
}

.crumbs a {
  color: var(--text-muted);
  text-decoration: none;
  font-weight: 500;
}

.crumbs a:hover {
  color: var(--accent);
  text-decoration: underline;
}

.crumbs svg {
  flex: none;
  opacity: 0.55;
}

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

/* ---- Long-form content -------------------------------------------------- */

.prose {
  max-width: 46rem;
}

.prose > :first-child {
  margin-top: 0;
}

.prose h2 {
  margin-top: 2.5rem;
  margin-bottom: 0.6rem;
  font-size: clamp(1.35rem, 2.4vw, 1.6rem);
}

.prose h3 {
  margin-top: 1.85rem;
  margin-bottom: 0.5rem;
  font-size: 1.075rem;
}

.prose p,
.prose li {
  color: var(--text-muted);
}

.prose strong {
  color: var(--text);
  font-weight: 620;
}

.prose ul {
  margin: 0 0 1.15em;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.prose ul li {
  position: relative;
  padding-left: 1.4rem;
}

.prose ul li::before {
  content: "";
  position: absolute;
  left: 0.35rem;
  top: 0.72em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.55;
}

.prose blockquote {
  margin: 1.5rem 0;
  padding: 0.15rem 0 0.15rem 1.25rem;
  border-left: 3px solid var(--flag-blue);
  color: var(--text-muted);
  font-style: italic;
}

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

.prose hr {
  height: 1px;
  border: 0;
  margin: 2.5rem 0;
  background: var(--border-soft);
}

/* ---- Two-column page shell: content + sticky aside ---------------------- */

.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 17.5rem;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.layout .prose {
  max-width: none;
}

.aside {
  position: sticky;
  top: 96px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.aside__card {
  padding: 1.25rem 1.35rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.aside__card h2 {
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 0.85rem;
}

.aside__card ul {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.aside__card a {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
}

.aside__card a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* ---- Resource entries --------------------------------------------------- */

.res-list {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin: 1.5rem 0 0;
}

.res {
  padding: 1.25rem 1.4rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.18s ease, box-shadow 0.18s ease,
    transform 0.18s ease;
}

.res:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  box-shadow: var(--shadow);
}

.res :is(h2, h3) {
  /* margin-top is reset because a card title may be an h2 (when the card
     list is the page's first section) and .prose h2 would otherwise add
     its section spacing inside the card. */
  margin-top: 0;
  margin-bottom: 0.35rem;
  font-size: 1.02rem;
}

.res :is(h2, h3) a {
  color: inherit;
  text-decoration: none;
}

.res :is(h2, h3) a:hover {
  color: var(--accent);
}

.res p {
  margin-bottom: 0;
  font-size: 0.92rem;
  color: var(--text-muted);
}

.res p + p {
  margin-top: 0.6rem;
}

/* Grid variant — turns a long single column into a scannable board.
   Cards stretch to equal height so the chips line up along the bottom. */
.res-list--grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: 0.9rem;
}

.res-list--grid .res {
  display: flex;
  flex-direction: column;
}

.res-list--grid .res__links {
  margin-top: auto;
  padding-top: 0.9rem;
}

/* Meta rows: phone, email, hours, location */
.res__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin-top: 0.85rem;
  font-size: 0.875rem;
}

.res__meta span,
.res__meta a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-muted);
  text-decoration: none;
}

.res__meta a:hover {
  color: var(--accent);
  text-decoration: underline;
}

.res__meta svg {
  flex: none;
  opacity: 0.7;
}

/* Outbound / download link chips */
.res__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.9rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.75rem;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  font-size: 0.8rem;
  font-weight: 550;
  color: var(--text);
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    color 0.15s ease;
}

.chip:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-hover);
}

.chip svg {
  flex: none;
  opacity: 0.75;
}

/* ---- Events + calendar --------------------------------------------------
   The page underneath is a complete, plain list of every date grouped by
   month. calendar.js adds the grid on top and only ever *adds* — nothing here
   hides .events-list, so a browser that never runs the script still shows
   every clinic.

   Colour is carried entirely by the .evt--<key> classes below, because the CSP
   is `style-src 'self'` and a per-event style attribute would be dropped. The
   keys come from EVENT_CATEGORIES in tools/event_lib.py; the two lists have to
   be edited together.
   -------------------------------------------------------------------------- */

/* The wrapper is the first thing in the section, so it carries no top margin
   of its own — the section padding is already the gap. */
.events,
.events .cal {
  margin-top: 0;
}

/* ---- Event pills --------------------------------------------------------- */

.evt {
  display: block;
  border: 1px solid;
  border-radius: 999px;
  background: var(--evt-event-bg);
  border-color: var(--evt-event-bd);
  color: var(--evt-event-fg);
}

.evt--clinic {
  background: var(--evt-clinic-bg);
  border-color: var(--evt-clinic-bd);
  color: var(--evt-clinic-fg);
}
.evt--group {
  background: var(--evt-group-bg);
  border-color: var(--evt-group-bd);
  color: var(--evt-group-fg);
}
.evt--workshop {
  background: var(--evt-workshop-bg);
  border-color: var(--evt-workshop-bd);
  color: var(--evt-workshop-fg);
}
.evt--awareness {
  background: var(--evt-awareness-bg);
  border-color: var(--evt-awareness-bd);
  color: var(--evt-awareness-fg);
}
.evt--community {
  background: var(--evt-community-bg);
  border-color: var(--evt-community-bd);
  color: var(--evt-community-fg);
}
.evt--online {
  background: var(--evt-online-bg);
  border-color: var(--evt-online-bd);
  color: var(--evt-online-fg);
}
.evt--event {
  background: var(--evt-event-bg);
  border-color: var(--evt-event-bd);
  color: var(--evt-event-fg);
}

/* Cancelled and draft always spell themselves out in the markup as well —
   these rules are the reinforcement, never the only signal.

   As a standalone chip the word "Cancelled" is the content, so the urgent
   palette reads correctly. */
.evt--cancelled {
  background: var(--urgent-bg);
  border-color: var(--urgent-border);
  color: var(--urgent-text);
  text-decoration: line-through;
}

.evt--draft {
  border-style: dashed;
}

/* Inside a calendar cell the pill's text is the event title, and recolouring
   it would both lose the category and land close enough to the pink "group"
   colour to be misread. Keep the category, strike it through, fade it. */
.cal__events .evt--cancelled {
  background: var(--surface-alt);
  opacity: 0.75;
  border-style: dashed;
  text-decoration: line-through;
}

/* ---- Legend -------------------------------------------------------------- */

.evt-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.1rem;
  margin-top: 1.1rem;
}

.evt-legend__title {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.evt-legend__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.82rem;
  color: var(--text-muted);
}

.evt-legend__list li {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.evt-legend__swatch {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 999px;
}

/* ---- Calendar panel ------------------------------------------------------ */

.cal {
  margin-top: 1.5rem;
  padding: clamp(0.9rem, 2vw, 1.4rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

/* Visible until calendar.js takes over, so a script-less browser gets an
   explanation instead of an empty box. */
.cal__fallback {
  margin: 0;
  font-size: 0.9rem;
  color: var(--text-muted);
}

.cal.is-ready .cal__fallback {
  display: none;
}

.cal__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  margin-bottom: 1rem;
}

.cal__nav {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.cal__title {
  min-width: 9.5em;
  margin: 0;
  font-size: 1.05rem;
  font-weight: 650;
  text-align: center;
}

.cal__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.cal__step:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-hover);
}

/* Segmented view switch. Quiet by default; the chosen view is marked with the
   flag gradient underline used by .eyebrow::before and the filter chips. */
.cal__views {
  display: flex;
  gap: 0.15rem;
  padding: 0.2rem;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
}

.cal__view {
  position: relative;
  padding: 0.35rem 0.8rem;
  background: none;
  border: 0;
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 550;
  color: var(--text-muted);
  cursor: pointer;
}

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

.cal__view[aria-pressed="true"] {
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  color: var(--text);
}

.cal__view[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  right: 0.8rem;
  bottom: 0.18rem;
  left: 0.8rem;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--flag-blue), var(--flag-pink));
}

/* ---- Calendar grid -------------------------------------------------------
   A real <table>, not a hand-rolled role="grid". Native row and column
   semantics are announced correctly for free, and this is a health service.
   -------------------------------------------------------------------------- */

.cal__grids {
  display: grid;
  gap: 1.25rem;
}

.cal__table {
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 3px;
}

.cal__weekday {
  padding: 0.2rem 0;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.cal__weekday abbr {
  text-decoration: none;
}

.cal__cell {
  position: relative;
  height: 1px; /* lets the inner content stretch to the row height */
  padding: 0.3rem;
  vertical-align: top;
  background: var(--surface-alt);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
}

.cal__cell.is-outside {
  opacity: 0.5;
}

.cal__cell.is-today {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  box-shadow: inset 0 2px 0 0 var(--flag-blue);
}

.cal__day {
  display: block;
  width: 100%;
  padding: 0.1rem 0.2rem;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  text-align: left;
  cursor: pointer;
}

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

.cal__cell.is-today .cal__day {
  color: var(--accent-hover);
}

.cal__cell.is-selected {
  border-color: var(--accent);
}

.cal__events {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin: 0.15rem 0 0;
  padding: 0;
  list-style: none;
}

.cal__events .evt {
  /* Positioned so `overflow: hidden` actually clips the .visually-hidden span
     carrying the pill's accessible name. Without it that span's containing
     block is the cell, it escapes the clip, and its static position sits past
     the right edge of the page — invisible, 1px wide, and enough to make the
     whole document scroll sideways at large text sizes. */
  position: relative;
  overflow: hidden;
  padding: 0.12rem 0.45rem;
  font-size: 0.72rem;
  font-weight: 550;
  line-height: 1.35;
  text-decoration: none;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cal__events .evt:hover {
  filter: brightness(0.97);
  text-decoration: underline;
}

.evt__time {
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}

.cal__more {
  margin-top: 0.15rem;
  padding: 0.05rem 0.3rem;
  background: none;
  border: 0;
  font: inherit;
  font-size: 0.7rem;
  color: var(--text-muted);
  cursor: pointer;
  text-decoration: underline;
}

.cal__empty {
  margin: 0;
  padding: 0.6rem 0.2rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Month view — the default. */
.cal--month .cal__cell {
  min-height: clamp(6.25rem, 10vw, 8.5rem);
}

/* Week view — one row, so every pill fits without a "+n more". */
.cal--week .cal__cell {
  min-height: 11rem;
}

.cal--week .cal__events .evt {
  overflow: visible;
  white-space: normal;
}

/* Three months ahead — compact, and pills collapse to dots. */
.cal--quarter .cal__grids {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.cal--quarter .cal__cell {
  min-height: 2.6rem;
  padding: 0.15rem;
}

.cal--quarter .cal__day {
  font-size: 0.7rem;
}

.cal--quarter .cal__events {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 2px;
}

.cal--quarter .evt--dot {
  width: 0.42rem;
  height: 0.42rem;
  padding: 0;
  border-radius: 999px;
}

.cal__month-title {
  margin: 0 0 0.4rem;
  font-size: 0.88rem;
  font-weight: 650;
  color: var(--text-muted);
}

/* ---- The day panel ------------------------------------------------------- */

.cal__day-panel {
  margin-top: 1rem;
  padding: 1rem 1.1rem;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.cal__day-panel[hidden] {
  display: none;
}

.cal__day-panel h3 {
  margin: 0 0 0.75rem;
  font-size: 1rem;
}

.cal__day-panel h3:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.cal__day-panel .res-list {
  margin-top: 0;
}

.cal__panel-close {
  float: right;
  padding: 0.2rem 0.5rem;
  background: none;
  border: 0;
  font: inherit;
  font-size: 0.82rem;
  color: var(--text-muted);
  cursor: pointer;
  text-decoration: underline;
}

.cal__panel-add {
  display: inline-block;
  margin-top: 0.75rem;
  font-size: 0.85rem;
}

/* ---- The plain list underneath ------------------------------------------- */

.events-month {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  scroll-margin-top: 6rem;
}

.events-month h2 {
  margin-bottom: 0;
  font-size: 1.15rem;
}

.events-past {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
}

/* Date tear-off on an event card, same geometry as .res__avatar. */
.res--event {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.res--event.is-cancelled .res__body h3 {
  text-decoration: line-through;
}

.evt-date {
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 3.1rem;
  height: 3.1rem;
  background: var(--surface-alt);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  line-height: 1.1;
}

.evt-date__day {
  font-size: 1.15rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.evt-date__month {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.res--event .res__body {
  min-width: 0;
  flex: 1;
}

.res--event .res__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 0.5rem;
}

.res--event .res__badges .evt {
  padding: 0.2rem 0.6rem;
  font-size: 0.74rem;
}

.res__note {
  margin-top: 0.5rem;
  padding-left: 0.7rem;
  border-left: 3px solid var(--flag-pink);
  font-size: 0.88rem;
}

/* ---- One event's own page ------------------------------------------------ */

.event-detail__type {
  margin-top: 0;
}

.event-dates__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.event-date {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--border-soft);
  font-size: 0.95rem;
}

.event-date.is-past {
  color: var(--text-muted);
}

.event-date.is-cancelled time {
  text-decoration: line-through;
}

.event-date__note {
  font-size: 0.88rem;
  color: var(--text-muted);
}

.event-facts {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
}

.event-facts li {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-soft);
}

.event-facts li:last-child {
  border-bottom: 0;
}

.event-facts strong {
  font-size: 0.75rem;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ---- Filter -------------------------------------------------------------
   Built by filter.js and injected at runtime, so it never appears without
   working JS. Everything it hides is visible by default.

   Deliberately quiet. An earlier version used filled pills, which read as a
   row of primary buttons and fought the real CTAs. Categories are plain text
   instead, and the active one is marked with the flag gradient as a thin rule
   — the same device as .flagline, .eyebrow::before and .card::after.
   -------------------------------------------------------------------------- */

.filter {
  margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
  padding-bottom: 1.35rem;
  border-bottom: 1px solid var(--border-soft);
}

.filter__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.9rem 1.5rem;
  margin-bottom: 1.15rem;
}

/* The eyebrow already carries its own gradient rule; don't double the margin */
.filter__top .eyebrow {
  margin-bottom: 0;
}

.filter__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 15rem;
  max-width: 21rem;
}

.filter__search svg {
  position: absolute;
  left: 0.85rem;
  color: var(--text-muted);
  pointer-events: none;
}

/* Matches the header search rather than inventing a second input style */
.filter__search input {
  width: 100%;
  padding: 0.55rem 2.3rem 0.55rem 2.3rem;
  font: inherit;
  font-size: 0.9rem;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease,
    background-color 0.15s ease;
}

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

.filter__search input:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.filter__clear {
  position: absolute;
  right: 0.5rem;
  display: none;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
}

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

.filter__clear[data-show="true"] {
  display: grid;
}

.filter__cats {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.6rem;
}

.filter__cat {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0 0.55rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 550;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s ease;
}

/* The one overt nod to the flag, same as everywhere else on the site */
.filter__cat::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--flag-blue), var(--flag-pink));
  opacity: 0;
  transition: opacity 0.18s ease;
}

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

.filter__cat:hover::after {
  opacity: 0.4;
}

.filter__cat[aria-pressed="true"] {
  color: var(--text);
  font-weight: 650;
}

.filter__cat[aria-pressed="true"]::after {
  opacity: 1;
}

.filter__count {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.filter__cat[aria-pressed="true"] .filter__count {
  color: var(--accent);
}

.filter__status {
  margin: 1.1rem 0 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Hidden by filtering — distinct from [hidden] so nothing fights over it */
.is-filtered {
  display: none !important;
}

.no-results {
  padding: 2.5rem 1.5rem;
  text-align: center;
  color: var(--text-muted);
  background: var(--surface-alt);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}

.no-results p {
  margin-bottom: 0;
}

/* A search hit inside an otherwise-filtered group still needs its heading */
.fgroup {
  scroll-margin-top: 6rem;
}

/* ---- Accordion (crisis supports uses these) ----------------------------- */

.acc {
  margin-top: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.acc + .acc {
  margin-top: 0.75rem;
}

.acc > summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.05rem 1.35rem;
  font-size: 1.02rem;
  font-weight: 650;
  color: var(--text);
  cursor: pointer;
  list-style: none;
  transition: background-color 0.15s ease;
}

.acc > summary::-webkit-details-marker {
  display: none;
}

/* The label is a real heading so the accordion groups appear in the document
   outline — a screen reader browsing by heading would otherwise jump from the
   page h1 straight to the h3 of the first card inside. Typography still comes
   from the summary. */
.acc > summary > h2 {
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  margin: 0;
}

.acc > summary:hover {
  background: var(--surface-alt);
}

.acc > summary::after {
  content: "";
  margin-left: auto;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.2s ease;
}

.acc[open] > summary::after {
  transform: rotate(225deg) translate(-2px, -2px);
}

.acc[open] > summary {
  border-bottom: 1px solid var(--border-soft);
}

.acc__body {
  padding: 1.35rem;
}

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

/* ---- Callouts ----------------------------------------------------------- */

.callout {
  display: flex;
  gap: 0.9rem;
  padding: 1.15rem 1.35rem;
  margin: 1.75rem 0;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface-alt);
  font-size: 0.92rem;
  color: var(--text-muted);
}

.callout svg {
  flex: none;
  margin-top: 0.15rem;
  color: var(--accent);
}

.callout strong {
  color: var(--text);
}

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

.callout--urgent {
  background: var(--urgent-bg);
  border-color: var(--urgent-border);
  color: var(--urgent-text);
}

.callout--urgent svg,
.callout--urgent strong {
  color: var(--urgent-text);
}

.callout--urgent a {
  color: var(--urgent-text);
  font-weight: 600;
}

/* ---- Admin-published static pages --------------------------------------- */

.managed-article,
.managed-update,
.managed-guide__intro,
.managed-resource-copy,
.managed-landing__intro {
  max-width: 46rem;
}

.managed-action {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.aside__card .managed-action {
  margin-top: 0;
}

.managed-sidebar-copy p,
.managed-sidebar-copy li {
  color: var(--text-muted);
  font-size: 0.875rem;
}

.managed-sidebar-copy p:last-child,
.managed-sidebar-copy ul:last-child {
  margin-bottom: 0;
}

.managed-download {
  position: relative;
  padding-top: 3.2rem;
}

.managed-download__type {
  position: absolute;
  inset: 1rem auto auto 1.35rem;
  display: inline-flex;
  padding: 0.2rem 0.45rem;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 750;
  letter-spacing: 0.06em;
}

.managed-download .managed-download__meta {
  margin-top: 0.6rem;
  font-size: 0.78rem;
}

.managed-callout {
  max-width: 46rem;
}

.managed-steps {
  position: relative;
  max-width: 52rem;
  margin-top: 2rem;
}

.managed-steps::before {
  content: "";
  position: absolute;
  top: 1.25rem;
  bottom: 1.25rem;
  left: 1.25rem;
  width: 1px;
  background: var(--border);
}

.managed-step {
  position: relative;
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: 1.1rem;
  padding-bottom: 2rem;
}

.managed-step:last-child {
  padding-bottom: 0;
}

.managed-step__number {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--accent);
  border-radius: 50%;
  background: var(--surface);
  color: var(--accent);
  font-size: 0.9rem;
  font-weight: 700;
}

.managed-step .prose h2 {
  margin-top: 0.35rem;
}

.managed-resource-section + .managed-resource-copy {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--border-soft);
}

.managed-landing-grid {
  margin-top: clamp(2rem, 5vw, 3.5rem);
}

.managed-landing-card h2 {
  margin: 0 0 0.6rem;
  font-size: 1.15rem;
}

.managed-landing-card .prose {
  max-width: none;
}

.managed-landing-card .prose h3:first-child {
  margin-top: 0.75rem;
}

.managed-landing-action {
  grid-template-columns: minmax(0, 42rem);
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
}

.managed-landing-action h2 {
  margin-bottom: 0.25rem;
}

.managed-update {
  position: relative;
  padding-left: clamp(1.1rem, 3vw, 2rem);
  border-left: 3px solid var(--flag-blue);
}

.managed-update__date {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 1.5rem;
  color: var(--text-muted);
  font-size: 0.85rem;
}

.managed-update__date span {
  font-weight: 650;
  color: var(--text);
}

.managed-page-index .card .eyebrow {
  margin-bottom: 0.65rem;
}

.managed-page-index .card .eyebrow::before {
  width: 1rem;
}

/* ---- Forms -------------------------------------------------------------- */

.form {
  max-width: 38rem;
  margin-top: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.field label {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
}

.field label .req {
  color: var(--pink);
  font-weight: 700;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  padding: 0.7rem 0.9rem;
  font: inherit;
  font-size: 0.95rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field textarea {
  min-height: 9rem;
  resize: vertical;
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.field__hint {
  font-size: 0.82rem;
  color: var(--text-muted);
}

/* ---- Practitioner listing request -------------------------------------- */

.intake-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 17.5rem;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.intake-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  max-width: 58rem;
}

.intake-section {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: clamp(1.15rem, 3vw, 1.75rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.intake-section__head {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border-soft);
}

.intake-section__head > span {
  display: grid;
  place-items: center;
  flex: 0 0 2rem;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 700;
}

.intake-section__head h2 {
  margin: 0;
  font-size: clamp(1.2rem, 2.5vw, 1.5rem);
}

.intake-section__head p {
  margin: 0.25rem 0 0;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.intake-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem 1.15rem;
}

.intake-field--full {
  grid-column: 1 / -1;
}

.intake-options {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.intake-options > legend {
  padding: 0;
  font-size: 0.9rem;
  font-weight: 600;
}

.intake-choices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
  margin-top: 0.65rem;
}

.intake-choice {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.75rem 0.85rem;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 500;
  line-height: 1.5;
}

.intake-choice:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}

.intake-choice:has(input:checked) {
  background: var(--accent-soft);
  border-color: var(--accent);
}

.intake-choice input,
.field .intake-choice input {
  flex: 0 0 auto;
  width: auto;
  margin: 0.24rem 0 0;
  accent-color: var(--accent);
}

.intake-choice input:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.intake-error {
  color: var(--urgent-text);
  font-size: 0.82rem;
  font-weight: 600;
}

.intake-invalid input,
.intake-invalid textarea,
.intake-invalid select,
.intake-invalid .intake-choice {
  border-color: var(--urgent-text);
}

.intake-validation-summary {
  max-width: 58rem;
  margin-bottom: 1.25rem;
  padding: 1rem 1.15rem;
  color: var(--urgent-text);
  background: var(--urgent-bg);
  border: 1px solid var(--urgent-border);
  border-radius: var(--radius-sm);
}

.intake-validation-summary ul {
  margin: 0.45rem 0 0;
  padding-left: 1.25rem;
}

.intake-success {
  max-width: 58rem;
  margin-bottom: 1.5rem;
  border-color: var(--accent);
  background: var(--accent-soft);
}

.intake-success h2 {
  margin-bottom: 0.35rem;
  font-size: 1.35rem;
}

.intake-check-panel {
  padding: clamp(1rem, 3vw, 1.4rem);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.intake-check-panel .eyebrow {
  margin-bottom: 0.5rem;
}

.intake-check-panel h3 {
  margin-bottom: 0.4rem;
  font-size: 1.2rem;
}

.intake-check-panel > p {
  max-width: 70ch;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.intake-turnstile {
  min-height: 4.1rem;
  margin-top: 1rem;
}

.intake-setup-error {
  color: var(--urgent-text);
  font-weight: 600;
}

.intake-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-top: 1rem;
}

.intake-actions--submit {
  padding-top: 0.25rem;
  border-top: 1px solid var(--border-soft);
}

.intake-actions .btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
  transform: none;
}

.intake-check-output {
  margin-top: 1rem;
}

.intake-check-card {
  padding: 1rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
}

.intake-check-card--warn {
  border-left-color: var(--pink);
}

.intake-check-card--bad {
  border-left-color: var(--urgent-text);
}

.intake-check-card h4 {
  margin-bottom: 0.35rem;
  font-size: 1rem;
}

.intake-check-card h5 {
  margin: 1rem 0 0.35rem;
  color: var(--text-muted);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.intake-check-card p,
.intake-check-card li {
  font-size: 0.88rem;
}

.intake-check-card ul {
  margin: 0;
  padding-left: 1.25rem;
}

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

.intake-badge {
  display: inline-flex;
  margin-top: 0.5rem;
  padding: 0.25rem 0.65rem;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border));
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.intake-badge--warn {
  color: var(--pink);
  background: color-mix(in srgb, var(--pink) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--pink) 45%, var(--border));
}

.intake-badge--bad {
  color: var(--urgent-text);
  background: var(--urgent-bg);
  border-color: var(--urgent-border);
}

.intake-loading {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.intake-loading > span {
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: intake-spin 0.8s linear infinite;
}

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

.intake-honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

@media (max-width: 760px) {
  .intake-intro,
  .intake-grid,
  .intake-choices {
    grid-template-columns: 1fr;
  }

  .intake-intro .aside {
    position: static;
  }

  .intake-field--full {
    grid-column: auto;
  }

  .intake-actions {
    justify-content: stretch;
  }

  .intake-actions .btn {
    width: 100%;
  }
}

/* ==========================================================================
   Directory
   --------------------------------------------------------------------------
   Listing cards reuse .res / .res-list--grid from the resource-list
   component; this block adds only what's new — the avatar, the category
   badges, the two-facet select row that sits alongside filter.js's search
   box, and the "show more" pager.
   ========================================================================== */

.directory__intro {
  max-width: 46rem;
  color: var(--text-muted);
  margin-bottom: 1.75rem;
}

/* Printable-PDF offer. The button is a plain link to a static file, so the
   busy states below are progressive feedback only — with JavaScript off the
   meter and status line never appear and the link just downloads. */
.directory-pdf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  margin: 0 0 1.75rem;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--surface);
}

.directory-pdf__text {
  flex: 1 1 20rem;
}

.directory-pdf__text h2 {
  margin: 0 0 0.2rem;
  font-size: 1.05rem;
}

.directory-pdf__text p {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.88rem;
}

.directory-pdf__action {
  flex: 0 1 16rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* A native <details> disclosure — it opens with JavaScript off, and the
   browser gives us the button semantics and keyboard handling for free. */
.directory-pdf__menu {
  position: relative;
}

.directory-pdf__menu > summary {
  width: 100%;
  list-style: none;
  cursor: pointer;
}

/* Safari still paints the disclosure triangle without this. */
.directory-pdf__menu > summary::-webkit-details-marker {
  display: none;
}

.directory-pdf__menu > summary::marker {
  content: "";
}

.directory-pdf__chev {
  transition: transform 0.15s ease;
}

.directory-pdf__menu[open] .directory-pdf__chev {
  transform: rotate(180deg);
}

.directory-pdf__list {
  position: absolute;
  z-index: 20;
  top: calc(100% + 0.4rem);
  right: 0;
  left: 0;
  min-width: 18rem;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.directory-pdf__option {
  display: block;
  padding: 0.55rem 0.7rem;
  border-radius: calc(var(--radius) - 0.35rem);
  color: var(--text);
  text-decoration: none;
}

.directory-pdf__option:hover,
.directory-pdf__option:focus-visible {
  background: var(--accent-soft);
}

.directory-pdf__option-name {
  display: block;
  font-weight: 600;
  font-size: 0.92rem;
}

.directory-pdf__option-hint,
.directory-pdf__option-size {
  display: block;
  color: var(--text-muted);
  font-size: 0.78rem;
  line-height: 1.35;
}

.directory-pdf__option-size {
  margin-top: 0.1rem;
  font-variant-numeric: tabular-nums;
}

.directory-pdf__btn[aria-busy="true"] {
  pointer-events: none;
}

/* While a download runs the menu is closed and the choice is made, so the
   whole control is inert rather than only the option that was clicked. */
.directory-pdf.is-busy .directory-pdf__menu > summary {
  pointer-events: none;
}

/* The spinner replaces the download arrow rather than sitting beside it, so
   the button keeps its width and the row doesn't reflow mid-download. */
.directory-pdf.is-busy .directory-pdf__icon {
  animation: directory-pdf-spin 0.8s linear infinite;
  transform-origin: 50% 50%;
}

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

.directory-pdf__meter {
  height: 0.4rem;
  border-radius: 999px;
  background: var(--border-soft);
  overflow: hidden;
}

.directory-pdf__fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width 0.18s ease-out;
}

/* No Content-Length (compressed or chunked response) means no honest
   percentage, so the bar sweeps instead of claiming a figure. */
.directory-pdf.is-indeterminate .directory-pdf__fill {
  width: 40%;
  animation: directory-pdf-sweep 1.1s ease-in-out infinite;
}

@keyframes directory-pdf-sweep {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(250%);
  }
}

.directory-pdf__status {
  margin: 0;
  min-height: 1.1em;
  color: var(--text-muted);
  font-size: 0.82rem;
}

.directory-pdf__status:empty {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  /* The sweeping bar stops but keeps its partial width: a full bar would read
     as "finished", which is the one thing it must not say. The status line
     above it is doing the real work here. */
  .directory-pdf.is-busy .directory-pdf__icon,
  .directory-pdf.is-indeterminate .directory-pdf__fill {
    animation: none;
  }

  .directory-pdf__chev {
    transition: none;
  }

  .directory-pdf__fill {
    transition: none;
  }
}

/* The map is an enhancement to the complete HTML directory below it. Its
   canvas stays absent until directory.js has successfully attached Leaflet,
   leaving a short, useful fallback for JavaScript-disabled visitors. */
.directory-map {
  margin: 0 0 2.25rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}

.directory-map__head {
  padding: 1rem 1.2rem 0.75rem;
}

.directory-map__head h2 {
  margin: 0 0 0.2rem;
  font-size: 1.15rem;
}

.directory-map__head p,
.directory-map__fallback,
.directory-map__attribution {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.88rem;
}

/* Leaflet stacks its panes from z-index 200 (tiles) up to 1000 (controls). Left
   in the page's root stacking context those beat anything the rest of the page
   paints over the map — the PDF menu above it opened *behind* the tiles. The
   z-index here traps the whole Leaflet range in a stacking context of its own,
   so only this 0 competes with the site's z-index scale. */
.directory-map__canvas {
  display: none;
  position: relative;
  z-index: 0;
  height: clamp(21rem, 48vw, 34rem);
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
  background: var(--surface-alt);
}

.directory-map.is-ready .directory-map__canvas {
  display: block;
}

.directory-map__fallback {
  padding: 0 1.2rem 1rem;
}

.directory-map.is-ready .directory-map__fallback {
  display: none;
}

.directory-map__attribution {
  padding: 0.65rem 1.2rem 0.75rem;
}

.directory-map .leaflet-container {
  font: inherit;
}

.directory-map .leaflet-control-attribution,
.directory-map .leaflet-control-zoom a {
  color: var(--text);
}

.directory-map .leaflet-popup-content {
  margin: 0.8rem 1rem;
  font-size: 0.9rem;
}

.directory-map .leaflet-popup-content p {
  margin: 0;
}

:root[data-theme="dark"] .directory-map__canvas {
  filter: brightness(0.82) contrast(1.06);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .directory-map__canvas {
    filter: brightness(0.82) contrast(1.06);
  }
}

@media (prefers-reduced-motion: reduce) {
  .directory-map .leaflet-fade-anim .leaflet-map-pane .leaflet-popup,
  .directory-map .leaflet-fade-anim .leaflet-tile {
    transition: none;
  }
}

@media (max-width: 40rem) {
  .directory-map__canvas {
    height: 22rem;
  }
}

.res--listing {
  display: flex;
  gap: 0.9rem;
}

/* .res-list--grid makes every card a column so its chips can bottom-align.
   A listing card wants the avatar *beside* the body, so it opts back into a
   row and moves that column one level down, onto .res__body. */
.res-list--grid .res--listing {
  flex-direction: row;
}

.res--listing .res__avatar {
  align-self: flex-start;
}

.res--listing .res__body {
  display: flex;
  flex-direction: column;
}

/* Pins the "View listing" chip to the bottom edge so the chips line up across
   a row of cards no matter how long each name or tagline runs. */
.res--listing .res__links {
  margin-top: auto;
}

.res__avatar {
  flex: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--flag-blue) 55%, #ffffff),
    color-mix(in srgb, var(--flag-pink) 55%, #ffffff)
  );
  color: #1d2731;
  font-weight: 700;
  font-size: 0.85rem;
}

.res__body {
  min-width: 0;
  flex: 1 1 auto;
}

.res__tagline {
  margin: 0 0 0.35rem;
  font-size: 0.92rem;
  color: var(--text-muted);
}

.res__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.7rem;
}

.res__badges:empty,
.res__meta:empty {
  display: none;
}

/* Badges already carry a bottom margin. Without this, a card that has them
   opens a gap almost twice as wide above its meta row as one that doesn't,
   and the phone numbers stop lining up across a row of cards. */
.res__badges:not(:empty) + .res__meta {
  margin-top: 0.15rem;
}

/* Informational, not interactive — no hover-as-link affordance */
.chip--tag {
  cursor: default;
}

.chip--tag:hover {
  background: var(--surface-alt);
  border-color: var(--border);
  color: var(--text);
}

.listing-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 1.75rem;
}

/* ---- Listing detail ----------------------------------------------------- */

/* Categories and locations, at the head of the listing. Same chips as the
   index cards' badges, so the two views describe a listing the same way. */
.listing-facets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1.6rem;
}

/* Unique-visitor count. Deliberately quiet: it is metadata about the page,
   not a rating of the practitioner, and it sits below the facet chips at the
   muted weight the practice-site meta lines already use. The number is
   tabular so a live update cannot make the line jitter as digits change. */
.listing-views {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: -0.9rem 0 1.6rem;
  font-size: 0.82rem;
  color: var(--text-muted);
}

.listing-views svg {
  flex: none;
  opacity: 0.75;
}

.listing-views__count {
  font-variant-numeric: tabular-nums;
}

/* Practice locations. One card per clinic, each carrying the phone number
   that actually reaches it — the whole point of merging the duplicates. */
.listing-sites {
  margin-top: 2.25rem;
}

.listing-sites > h2 {
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.9rem;
}

.site {
  padding: 1.15rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.site + .site {
  margin-top: 0.75rem;
}

.site h3 {
  margin-bottom: 0.3rem;
  font-size: 1rem;
}

.site__address {
  margin: 0;
  font-size: 0.92rem;
  color: var(--text-muted);
}

.site__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.9rem;
}

/* OpenStreetMap embed, one per practice site. Only rendered for addresses that
   geocoded to a precise match, so a card without a map is expected, not
   broken — nothing here should reserve space when the iframe is absent. */
.site__map {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 260px;
  margin-top: 0.9rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

/* The embed renders OSM's own light tile set and can't be restyled through
   an iframe, so it gets dimmed rather than left glaring out of a dark page.
   filter can't go through light-dark(), so unlike every other token here this
   needs the two explicit dark cases: following the system, and forced dark. */
:root[data-theme="dark"] .site__map {
  filter: brightness(0.86) contrast(1.04);
  transition: filter 0.2s ease;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .site__map {
    filter: brightness(0.86) contrast(1.04);
    transition: filter 0.2s ease;
  }
}

/* Restore full fidelity for anyone actually reading the map. */
:root[data-theme="dark"] .site__map:hover,
:root[data-theme="dark"] .site__map:focus-within {
  filter: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .site__map:hover,
  :root:not([data-theme]) .site__map:focus-within {
    filter: none;
  }
}

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

@media (max-width: 40rem) {
  .site__map {
    aspect-ratio: 4 / 3;
  }
}

.listing-back {
  margin: 2.5rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border-soft);
}

/* Aside cards on listing pages carry prose and chips, not just link lists */
.aside__card p {
  margin: 0 0 0.85rem;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--text-muted);
}

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

/* Scoped to the contact list rather than every aside link: inline-flex would
   stop long link text on the hand-authored pages from wrapping. */
.aside__contact a {
  display: inline-flex;
  align-items: flex-start;
  gap: 0.45rem;
  max-width: 100%;
  /* Long email addresses and domains have nowhere to break; without this they
     run straight out through the side of the card. */
  overflow-wrap: anywhere;
}

.aside__contact svg {
  flex: none;
  margin-top: 0.28em;
  opacity: 0.7;
}

/* ---- Toolbar: search (from filter.js styles) + category/location selects */

.filter__selects {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.15rem;
}

.filter__select-wrap {
  flex: 1 1 12rem;
  max-width: 16rem;
}

.filter__select {
  width: 100%;
  padding: 0.5rem 2rem 0.5rem 0.9rem;
  font: inherit;
  font-size: 0.88rem;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5' stroke='%235b6b7b' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.filter__select:focus {
  outline: none;
  background-color: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.filter__reset {
  flex: none;
}

.directory-pager {
  margin-top: 1.75rem;
  text-align: center;
}

/* ==========================================================================
   Saved accessibility preference effects
   ========================================================================== */

:root[data-a11y-text="110"] { font-size: 110%; }
:root[data-a11y-text="125"] { font-size: 125%; }
:root[data-a11y-text="150"] { font-size: 150%; }
:root[data-a11y-text="175"] { font-size: 175%; }
:root[data-a11y-text="200"] { font-size: 200%; }

:root[data-a11y-font="plain"] {
  --font-sans: Verdana, Arial, Helvetica, sans-serif;
}

:root[data-a11y-line="relaxed"] {
  --body-line-height: 1.8;
  --heading-line-height: 1.4;
}

:root[data-a11y-line="extra"] {
  --body-line-height: 2;
  --heading-line-height: 1.6;
}

:root[data-a11y-spacing="medium"] {
  --a11y-letter-spacing: 0.04em;
  --a11y-word-spacing: 0.08em;
  --paragraph-spacing: 1.5em;
}

:root[data-a11y-spacing="maximum"] {
  --a11y-letter-spacing: 0.12em;
  --a11y-word-spacing: 0.16em;
  --paragraph-spacing: 2em;
}

:root[data-a11y-spacing] body {
  letter-spacing: var(--a11y-letter-spacing);
  word-spacing: var(--a11y-word-spacing);
}

:root[data-a11y-spacing] p:not(.accessibility-dialog__status) {
  margin-bottom: var(--paragraph-spacing);
}

:root[data-a11y-spacing] :where(
  h1, h2, h3, h4, p, li, dt, dd, label, input, textarea, select, button,
  .eyebrow, .brand__name, .chip, .card, .btn
) {
  letter-spacing: var(--a11y-letter-spacing);
  word-spacing: var(--a11y-word-spacing);
}

:root[data-a11y-spacing="maximum"] :where(
  p, li, dt, dd, label, input, textarea, select, button, .chip, .card, .btn
) {
  line-height: 1.5;
}

:root[data-a11y-line] :where(
  p, li, dt, dd, label, input, textarea, select, button, small, .chip, .card,
  .btn, .hero__lede, .page-hero__lede, .callout, .acknowledgement
) {
  line-height: var(--body-line-height);
}

/* Token-based contrast, never a filter over the whole page. Measured against
   its surfaces: light accent 8.14:1, pink 9.57:1, muted text 16.29:1;
   dark accent 13.72:1, pink 12.32:1, muted text 17.57:1. */
:root {
  --hc-bg: light-dark(#ffffff, #000000);
  --hc-surface: light-dark(#ffffff, #050505);
  --hc-surface-alt: light-dark(#f5f5f5, #101010);
  --hc-text: light-dark(#000000, #ffffff);
  --hc-muted: light-dark(#202020, #eeeeee);
  --hc-border: light-dark(#3b3b3b, #d8d8d8);
  --hc-border-soft: light-dark(#666666, #a8a8a8);
  --hc-accent: light-dark(#00557a, #8ddfff);
  --hc-accent-hover: light-dark(#003b57, #c9f2ff);
  --hc-accent-soft: light-dark(#e6f7ff, #082f3d);
  --hc-on-accent: light-dark(#ffffff, #000000);
  --hc-pink: light-dark(#85183d, #ffb5c8);
  --hc-pink-hover: light-dark(#650d2b, #ffd5df);
  --hc-on-pink: light-dark(#ffffff, #000000);
  --hc-urgent-bg: light-dark(#ffffff, #000000);
  --hc-urgent-border: light-dark(#760020, #ffb5c8);
  --hc-urgent-text: light-dark(#650019, #ffdbe4);
}

:root[data-a11y-contrast="high"] {
  --bg: var(--hc-bg);
  --surface: var(--hc-surface);
  --surface-alt: var(--hc-surface-alt);
  --text: var(--hc-text);
  --text-muted: var(--hc-muted);
  --border: var(--hc-border);
  --border-soft: var(--hc-border-soft);
  --accent: var(--hc-accent);
  --accent-hover: var(--hc-accent-hover);
  --accent-soft: var(--hc-accent-soft);
  --on-accent: var(--hc-on-accent);
  --pink: var(--hc-pink);
  --pink-hover: var(--hc-pink-hover);
  --on-pink: var(--hc-on-pink);
  --pink-icon-bg: var(--hc-surface-alt);
  --pink-icon-fg: var(--hc-pink);
  --urgent-bg: var(--hc-urgent-bg);
  --urgent-border: var(--hc-urgent-border);
  --urgent-text: var(--hc-urgent-text);
  --hero-glow-1: transparent;
  --hero-glow-2: transparent;
  --feature-from: var(--hc-surface);
  --feature-to: var(--hc-surface-alt);
  --band-bg: #000000;
  --band-border: light-dark(#000000, #ffffff);
  --band-text: #ffffff;
  --band-muted: #ffffff;
  --band-ghost-bg: #000000;
  --band-ghost-border: #ffffff;
  --band-ghost-hover: #202020;
  --evt-clinic-bg: var(--hc-surface);
  --evt-clinic-fg: var(--hc-text);
  --evt-clinic-bd: var(--hc-border);
  --evt-group-bg: var(--hc-surface);
  --evt-group-fg: var(--hc-text);
  --evt-group-bd: var(--hc-border);
  --evt-workshop-bg: var(--hc-surface);
  --evt-workshop-fg: var(--hc-text);
  --evt-workshop-bd: var(--hc-border);
  --evt-awareness-bg: var(--hc-surface);
  --evt-awareness-fg: var(--hc-text);
  --evt-awareness-bd: var(--hc-border);
  --evt-community-bg: var(--hc-surface);
  --evt-community-fg: var(--hc-text);
  --evt-community-bd: var(--hc-border);
  --evt-online-bg: var(--hc-surface);
  --evt-online-fg: var(--hc-text);
  --evt-online-bd: var(--hc-border);
  --evt-event-bg: var(--hc-surface);
  --evt-event-fg: var(--hc-text);
  --evt-event-bd: var(--hc-border);
  --shadow-sm: none;
  --shadow: none;
  --shadow-lg: none;
}

@media (prefers-contrast: more) {
  :root:not([data-a11y-contrast]) {
    --bg: var(--hc-bg);
    --surface: var(--hc-surface);
    --surface-alt: var(--hc-surface-alt);
    --text: var(--hc-text);
    --text-muted: var(--hc-muted);
    --border: var(--hc-border);
    --border-soft: var(--hc-border-soft);
    --accent: var(--hc-accent);
    --accent-hover: var(--hc-accent-hover);
    --accent-soft: var(--hc-accent-soft);
    --on-accent: var(--hc-on-accent);
    --pink: var(--hc-pink);
    --pink-hover: var(--hc-pink-hover);
    --on-pink: var(--hc-on-pink);
    --pink-icon-bg: var(--hc-surface-alt);
    --pink-icon-fg: var(--hc-pink);
    --urgent-bg: var(--hc-urgent-bg);
    --urgent-border: var(--hc-urgent-border);
    --urgent-text: var(--hc-urgent-text);
    --hero-glow-1: transparent;
    --hero-glow-2: transparent;
    --feature-from: var(--hc-surface);
    --feature-to: var(--hc-surface-alt);
    --band-bg: #000000;
    --band-border: light-dark(#000000, #ffffff);
    --band-text: #ffffff;
    --band-muted: #ffffff;
    --band-ghost-bg: #000000;
    --band-ghost-border: #ffffff;
    --band-ghost-hover: #202020;
    --evt-clinic-bg: var(--hc-surface);
    --evt-clinic-fg: var(--hc-text);
    --evt-clinic-bd: var(--hc-border);
    --evt-group-bg: var(--hc-surface);
    --evt-group-fg: var(--hc-text);
    --evt-group-bd: var(--hc-border);
    --evt-workshop-bg: var(--hc-surface);
    --evt-workshop-fg: var(--hc-text);
    --evt-workshop-bd: var(--hc-border);
    --evt-awareness-bg: var(--hc-surface);
    --evt-awareness-fg: var(--hc-text);
    --evt-awareness-bd: var(--hc-border);
    --evt-community-bg: var(--hc-surface);
    --evt-community-fg: var(--hc-text);
    --evt-community-bd: var(--hc-border);
    --evt-online-bg: var(--hc-surface);
    --evt-online-fg: var(--hc-text);
    --evt-online-bd: var(--hc-border);
    --evt-event-bg: var(--hc-surface);
    --evt-event-fg: var(--hc-text);
    --evt-event-bd: var(--hc-border);
    --shadow-sm: none;
    --shadow: none;
    --shadow-lg: none;
  }
}

:root[data-a11y-contrast="high"] .hero h1 .accent {
  background: none;
  color: var(--accent);
}

@media (prefers-contrast: more) {
  :root:not([data-a11y-contrast]) .hero h1 .accent {
    background: none;
    color: var(--accent);
  }
}

:root[data-a11y-links="strong"] a:not(.btn):not(.brand):not(.nav__link):not(.card):not(.chip) {
  text-decoration-line: underline;
  text-decoration-thickness: 0.16em;
  text-decoration-color: currentColor;
  text-underline-offset: 0.2em;
}

:root[data-a11y-links="strong"] :where(.btn, .chip, .card, .nav__link) {
  border-color: currentColor;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px currentColor;
}

:root[data-a11y-images="reduced"] :where(
  .flagline, .hero::before, .page-hero__art, .error-page__art,
  img[alt=""]:not(.leaflet-tile)
) {
  display: none !important;
}

:root[data-a11y-images="reduced"] .eyebrow::before {
  content: none;
}

@media (pointer: fine) {
  :root[data-a11y-cursor="large"],
  :root[data-a11y-cursor="large"] body {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M4 2 25 19l-10 1 5 9-5 2-5-9-6 7Z' fill='%23fff' stroke='%23000159' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E") 4 2, default;
  }

  :root[data-a11y-cursor="large"] :where(a, button, label, summary, select, [role="button"]) {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M11 3a3 3 0 0 1 3 3v7-4a3 3 0 0 1 6 0v5-3a3 3 0 0 1 6 0v9c0 6-4 10-10 10h-1c-4 0-7-2-9-5l-4-7a3 3 0 0 1 5-3l4 5V6a3 3 0 0 1 0-3Z' fill='%23fff' stroke='%23000159' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E") 11 3, pointer;
  }

  :root[data-a11y-cursor="large"] :where(
    input:not([type]), input[type="text"], input[type="email"], input[type="url"],
    input[type="search"], input[type="tel"], input[type="number"], input[type="password"],
    textarea, [contenteditable="true"]
  ) {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M11 3h10M16 3v26M11 29h10M12 8h8M12 24h8' fill='none' stroke='%23fff' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M11 3h10M16 3v26M11 29h10M12 8h8M12 24h8' fill='none' stroke='%23000159' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") 16 16, text;
  }
}

.reading-guide {
  position: fixed;
  inset: 0 0 auto;
  z-index: 90;
  height: 2.5rem;
  pointer-events: none;
  border-block: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent-soft) 55%, transparent);
  box-shadow: 0 0 0 1px var(--surface);
  transform: translateY(-200%);
}

:root[data-a11y-motion="reduce"] {
  scroll-behavior: auto;
}

:root[data-a11y-motion="reduce"] *,
:root[data-a11y-motion="reduce"] *::before,
:root[data-a11y-motion="reduce"] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  scroll-behavior: auto !important;
  transition-duration: 0.01ms !important;
}

:root[data-a11y-motion="reduce"] .directory-pdf.is-busy .directory-pdf__icon,
:root[data-a11y-motion="reduce"] .directory-pdf.is-indeterminate .directory-pdf__fill {
  animation: none;
}

@media (forced-colors: active) {
  .accessibility-dialog,
  .accessibility-group,
  .accessibility-choice span,
  .accessibility-toggle,
  .accessibility-options__trigger {
    border: 2px solid CanvasText;
  }

  .accessibility-choice input:checked + span {
    color: HighlightText;
    background: Highlight;
  }

  .reading-guide {
    border-color: Highlight;
    background: transparent;
  }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1080px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr 1fr;
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 1120px) {
  /* Three months side by side stop being readable well before the nav
     collapses; stack them and let the page scroll instead. */
  .cal--quarter .cal__grids {
    grid-template-columns: minmax(0, 1fr);
  }

  .nav-toggle {
    display: inline-flex;
  }

  .search {
    display: none;
  }

  .nav {
    position: fixed;
    inset: 76px 0 auto 0;
    max-height: calc(100dvh - 76px);
    overflow-y: auto;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    padding: 1rem var(--gutter) 2rem;
    display: none;
  }

  .nav[data-open="true"] {
    display: block;
  }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
  }

  .nav__link {
    width: 100%;
    justify-content: space-between;
    padding: 0.8rem 0.75rem;
    font-size: 1rem;
  }

  .accessibility-options__trigger {
    width: 44px;
    justify-content: center;
    padding: 0.45rem;
  }

  /* Legacy theme markup may remain briefly during a rolling deployment. */
  .has-menu {
    position: static;
  }

  .theme.has-menu {
    position: relative;
  }

  .menu {
    position: static;
    min-width: 0;
    opacity: 1;
    visibility: visible;
    transform: none;
    display: none;
    box-shadow: none;
    border: 0;
    border-left: 2px solid var(--border);
    border-radius: 0;
    margin: 0.15rem 0 0.5rem 0.75rem;
    padding: 0.15rem 0 0.15rem 0.5rem;
  }

  .menu[data-open="true"] {
    display: block;
  }

  /* Keep that legacy popup floating rather than expanding inline. */
  .theme .menu {
    position: absolute;
    top: calc(100% + 0.5rem);
    left: auto;
    right: 0;
    min-width: 190px;
    margin: 0;
    padding: 0.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
  }

  .theme__btn {
    width: auto;
    justify-content: center;
  }

  .hero__inner {
    grid-template-columns: 1fr;
  }

  .hero__art {
    order: -1;
  }

  .hero__art img {
    width: min(52%, 200px);
  }

  .feature,
  .about {
    grid-template-columns: 1fr;
  }

  .feature__panel {
    order: -1;
  }

  /* Aside drops below the content and stops sticking */
  .layout {
    grid-template-columns: 1fr;
  }

  .aside {
    position: static;
  }
}

@media (max-width: 620px) {
  .accessibility-dialog {
    width: calc(100vw - 1rem);
    inline-size: calc(100vw - 1rem);
    max-inline-size: calc(100vw - 1rem);
    max-height: calc(100dvh - 1rem);
    max-block-size: calc(100dvh - 1rem);
    border-radius: var(--radius);
  }

  .accessibility-dialog__body {
    grid-template-columns: minmax(0, 1fr);
  }

  .accessibility-group--rows {
    grid-column: auto;
  }

  .accessibility-choices--three,
  .accessibility-choices--sizes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* A seven-column grid on a 390px screen leaves ~48px per day. Titles can't
     survive that, so month view drops to dots too and the day panel — opened
     by tapping a date — becomes the way to read what's on. */
  .cal {
    padding: 0.75rem;
  }

  .cal__toolbar {
    justify-content: center;
  }

  .cal__table {
    border-spacing: 2px;
  }

  .cal--month .cal__cell {
    min-height: 3.1rem;
  }

  .cal--month .cal__events {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 2px;
  }

  .cal--month .cal__events .evt {
    width: 0.42rem;
    height: 0.42rem;
    padding: 0;
    border-radius: 999px;
    font-size: 0;
  }

  .cal__more {
    font-size: 0.62rem;
  }

  .res--event {
    gap: 0.75rem;
  }

  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }

  .brand__name span {
    display: none;
  }

  /* Brand + display options + Donate + burger overran a 375px viewport, which
     scrolled the whole page sideways. Trim the gaps and the logo rather than
     dropping the Donate button. */
  .header-bar {
    gap: 0.75rem;
  }

  .header-bar .brand {
    gap: 0.55rem;
  }

  .header-bar .brand img {
    width: 36px;
    height: 36px;
  }

  .header-actions {
    gap: 0.4rem;
  }

  .header-actions .btn--sm {
    padding-inline: 0.8rem;
  }

  .cta-band__actions,
  .hero__actions {
    width: 100%;
  }

  .cta-band__actions .btn,
  .hero__actions .btn {
    flex: 1 1 auto;
  }
}

/* Enlarged text on a narrow screen is where horizontal overflow shows up, and
   it is almost always the same two causes: a grid or flex child's default
   min-width is `auto`, so it refuses to shrink below its longest word, and
   that word is itself wider than the column at 200%. Let those children
   shrink, and let long words break rather than propping the page open.
   Scoped to the attribute so ordinary rendering is untouched, and checked by
   tools/devharness/overflow.html, which runs every page at 390px in this
   exact mode. */
:root[data-a11y-text] :is(
    .hero, .hero__inner, .page-hero, .page-hero__inner, .layout, .grid,
    .wrap, .res, .res__body, .card, .footer-grid, .cta-band, .feature,
    .callout, .acc, .events, .res-list
  ) > * {
  min-width: 0;
}

:root[data-a11y-text] :is(
    p, li, a, strong, em, h1, h2, h3, h4, dt, dd, td, th, summary,
    figcaption, blockquote, code
  ) {
  overflow-wrap: break-word;
}

/* Buttons and chips are `white-space: nowrap` so a label never breaks across
   two lines mid-phrase. At 200% "Browse the Directory" on one line is 662px,
   which is wider than the screen it has to fit in — there, wrapping is the
   lesser evil. */
:root[data-a11y-text] :is(.btn, .chip) {
  max-width: 100%;
  white-space: normal;
}

/* The calendar toolbar reserves 9.5em for the month name so it stops jittering
   as the label changes length. That reservation is in em, so it doubles along
   with the text and stops fitting; let the row wrap instead. */
:root[data-a11y-text] .cal__nav {
  flex-wrap: wrap;
}

:root[data-a11y-text] .cal__title {
  min-width: 0;
}

/* Month / Week / 3 months is a single pill-shaped row of three. At 200% those
   three labels are 467px side by side, so let them stack — and drop the pill
   radius, which reads as a mistake once the row is two lines tall. */
:root[data-a11y-text] .cal__views {
  flex-wrap: wrap;
  justify-content: center;
  border-radius: var(--radius);
}

/* Time / place / cost / host sit on one wrapped row. At 200% a single one of
   them is most of the width, so give each its own line rather than letting
   them straddle the edge. */
:root[data-a11y-text] .res__meta {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
}

:root[data-a11y-text] .res__meta > * {
  max-width: 100%;
  min-width: 0;
}

/* Any explicit text enlargement simplifies the header. Its actual height can
   grow freely, so the menu stays in document flow instead of relying on the
   default header's fixed 76px mobile offset. */
:root[data-a11y-text] .site-header {
  position: static;
}

:root[data-a11y-text] .header-bar {
  flex-wrap: wrap;
  align-items: center;
  padding-block: 0.65rem;
}

:root[data-a11y-text] .header-bar > .brand {
  flex: 1 1 auto;
  min-width: 0;
}

:root[data-a11y-text] .search {
  display: none;
}

:root[data-a11y-text] .nav-toggle {
  display: inline-flex;
}

:root[data-a11y-text] .nav {
  position: static;
  order: 3;
  flex: 1 0 100%;
  width: 100%;
  max-height: none;
  margin: 0;
  padding: 0.75rem 0 0.5rem;
  overflow: visible;
  background: var(--surface);
  border: 0;
  border-top: 1px solid var(--border);
  box-shadow: none;
  display: none;
}

:root[data-a11y-text] .nav[data-open="true"] {
  display: block;
}

:root[data-a11y-text] .nav__list {
  flex-direction: column;
  align-items: stretch;
  gap: 0.15rem;
}

:root[data-a11y-text] .nav .nav__link {
  width: 100%;
  justify-content: space-between;
  padding: 0.8rem 0.75rem;
}

:root[data-a11y-text] .nav .has-menu {
  position: static;
}

:root[data-a11y-text] .nav .menu {
  position: static;
  min-width: 0;
  margin: 0.15rem 0 0.5rem 0.75rem;
  padding: 0.15rem 0 0.15rem 0.5rem;
  display: none;
  opacity: 1;
  visibility: visible;
  transform: none;
  border: 0;
  border-left: 2px solid var(--border);
  border-radius: 0;
  box-shadow: none;
}

:root[data-a11y-text] .nav .menu[data-open="true"] {
  display: block;
}

:root[data-nav-open="true"]:not([data-a11y-text]) {
  overflow: hidden;
}

:root[data-a11y-text] .accessibility-dialog__inner {
  padding: 16px;
}

/* ==========================================================================
   Motion + print
   ========================================================================== */

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

@media print {
  .site-header,
  .accessibility-dialog,
  .accessibility-options,
  .reading-guide,
  .cta-band,
  .hero__art,
  .page-hero__art,
  /* The grid is an on-screen navigation aid. .events-list underneath is the
     actual schedule, and a printed clinic schedule is a genuinely useful
     thing to hand someone. */
  .cal,
  .evt-legend {
    display: none;
  }
  body {
    background: #fff;
    color: #000;
  }
}

/* ==========================================================================
   Utilities
   --------------------------------------------------------------------------
   These exist because the CSP is `style-src 'self'` with no 'unsafe-inline',
   so a style attribute is silently dropped in production. Put one-off layout
   adjustments here instead.
   ========================================================================== */

.u-flush {
  margin-top: 0;
}
.u-mt-sm {
  margin-top: 1rem;
}
.u-mt-md {
  margin-top: 1.25rem;
}
.u-mt-lg {
  margin-top: 1.5rem;
}
.u-mt-xl {
  margin-top: 2rem;
}
.u-mt-section {
  margin-top: clamp(2rem, 4vw, 3rem);
}
.u-center {
  justify-content: center;
}
.u-mi-auto {
  margin-inline: auto;
}
.u-ml-auto {
  margin-left: auto;
}
.u-measure {
  max-width: 46rem;
}

/* The 404's centred column */
.error-page {
  max-width: 44rem;
  text-align: center;
  padding-block: clamp(2rem, 6vw, 4rem);
}

/* Unlike .page-hero__art this one stays at every width. A 404 has no other
   job, so the illustration is the page's whole warmth — hiding it on phones
   would remove it from where most people meet a broken link. */
.error-page__art {
  display: block;
  width: clamp(10rem, 40vw, 16rem);
  height: auto;
  margin: 0 auto clamp(0.75rem, 2vw, 1.5rem);
}
