/* === tokens.css === */
/* Design tokens — measured from the live WordPress site's computed styles,
   not guessed. Every value here was read off the rendered page. */

/* ---- Self-hosted fonts (no third-party requests; see docs/compliance.md) ---- */

/* Open Sans ships as one variable font covering 300-700; four separate
   weight files from Google were byte-identical, so this is a single request. */
@font-face {
  font-family: "Open Sans";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/assets/fonts/opensans-var.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/poppins-400.woff2") format("woff2");
}
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/poppins-600.woff2") format("woff2");
}
@font-face {
  font-family: "PT Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/ptsans-400.woff2") format("woff2");
}

:root {
  /* ---- Brand ---- */
  --c-blue: #135286;            /* Volunteer button, links */
  --c-blue-light: #1476a8;      /* nav link colour on light header */
  --c-blue-dark: #0d3c63;       /* copyright bar under the footer */
  --c-gold: #c8a100;            /* gold headings */
  --c-gold-hero: #ffce05;       /* hero Volunteer button */
  --c-green: #2aa315;           /* "Completed!" button */
  --c-grey-btn: #747474;        /* "Info" button */
  --c-red: rgba(219, 39, 33, 0.83);   /* Donate button */
  --c-dark-btn: rgba(0, 0, 0, 0.7);   /* hero secondary buttons */

  /* ---- Neutrals ---- */
  --c-white: #ffffff;
  --c-grey-100: #f6f6f6;
  --c-grey-200: #ebebeb;
  --c-grey-400: #c6c5c5;      /* input borders */
  --c-strip: #d4d4d4;         /* contact/hours/address band */
  --c-strip-mid: #c6c5c5;     /* its darker middle column */
  --c-text: #333333;
  --c-black: #000000;

  /* ---- Semantic ---- */
  --c-link: var(--c-blue-light);
  --c-border: var(--c-grey-200);      /* used by forms.css */
  --c-surface: var(--c-white);
  --c-surface-alt: var(--c-grey-100); /* used by forms.css */

  /* ---- Typography ----
     Body and headings are Open Sans; the hero is Poppins; buttons are PT Sans. */
  --font-body: "Open Sans", Verdana, Geneva, sans-serif;
  --font-hero: "Poppins", "Open Sans", sans-serif;
  --font-btn: "PT Sans", "Open Sans", sans-serif;

  --fs-base: 16px;      /* body */
  --lh-base: 1.7;       /* 27.2px, measured */

  --fs-h1: 45px;
  --lh-h1: 63px;

  --fs-h2: 27px;
  --lh-h2: 40.5px;

  --fs-h3: 16px;
  --lh-h3: 24px;

  --fs-btn: 14px;       /* card buttons */
  --fs-nav: 18px;

  /* ---- Spacing ---- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-12: 48px;
  --sp-16: 64px;

  /* ---- Layout ---- */
  --container: 1100px;  /* matches .fusion-row max-width */
  --header-h: 74px;

  /* ---- Effects ---- */
  --radius: 2px;        /* every button on the site is 2px */
  --radius-card: 5px;   /* the theme's clinic column radius */
  --transition: 0.2s ease;
}


/* === base.css === */
/* Reset + element defaults */

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

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--c-text);
  background: var(--c-surface);
  -webkit-font-smoothing: antialiased;
}

/* Section titles are light blue-grey with an optional gold second half,
   written as <h1>Upcoming <b>Free Clinics</b></h1>. */
h1, h2, h3, h4 {
  margin: 0 0 var(--sp-4);
  font-family: var(--font-body);
  text-align: left;
}

h1 {
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: 300;
  color: var(--c-blue);
}

h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: 700;
  color: var(--c-gold);
}

h3 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 600;
  color: var(--c-blue);
}

/* The gold half of a two-tone heading. */
h1 b, h2 b, h3 b {
  font-weight: 700;
  color: var(--c-gold);
}

p { margin: 0 0 var(--sp-4); }

a {
  color: var(--c-link);
  text-decoration: none;
  transition: color var(--transition);
}

a:hover { color: var(--c-gold); }

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

ul, ol {
  margin: 0 0 var(--sp-4);
  padding-left: var(--sp-6);
}

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

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

/* The icon sprite itself is never rendered. */
.sprite { display: none; }

/* Icons inherit colour and sit on the text baseline. */
.icon {
  width: 1em;
  height: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

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

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--sp-4);
  z-index: 200;
  padding: var(--sp-3) var(--sp-4);
  background: var(--c-blue);
  color: var(--c-white);
}

.skip-link:focus { top: 0; color: var(--c-white); }


/* === layout.css === */
/* Container, header, footer, section rhythm */

/* One content width for the whole site: a 1100px box with padding outside it,
   so every page's columns line up. `--full` opts a section out for edge-to-edge
   content, keeping only the side padding. */
.container {
  width: min(100% - (2 * var(--sp-6)), var(--container));
  margin-inline: auto;
}

.container--full {
  width: 100%;
  padding-inline: var(--sp-6);
}

.section { padding-block: var(--sp-16); }
.section--alt { background: var(--c-strip); }

/* Lets a child (the info strip) run edge to edge and own its own padding. */
.section--flush { padding-block: 0; }
.section__head { margin-bottom: var(--sp-8); }

/* ---------- Header ----------
   Transparent and absolute so the hero photo runs underneath it. */

/* Solid by default. Only pages with a hero behind it get the overlay
   treatment — otherwise the white logo and nav land on white content. */
.header {
  position: relative;
  z-index: 100;
  height: var(--header-h);
  background: var(--c-blue);
}

.has-hero .header {
  position: absolute;
  inset: 0 0 auto 0;
  /* Slight darkening so the nav stays legible where the photo is light. */
  background: rgba(0, 0, 0, 0.25);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
  height: var(--header-h);
}

.header__logo img {
  width: 133px;
  height: 50px;
  object-fit: contain;
}

.nav__list {
  display: flex;
  align-items: center;
  height: var(--header-h);
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav__link {
  display: flex;
  align-items: center;
  height: var(--header-h);
  padding-inline: 17.5px;
  font-size: var(--fs-nav);
  color: var(--c-white);
}

.nav__link:hover { color: var(--c-gold-hero); }

.nav__link[aria-current="page"] {
  background: var(--c-dark-btn);
  color: var(--c-gold-hero);
}

/* ---- Dropdown ---- */

.nav__parent { position: relative; }

.nav__sub {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 200px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--c-grey-btn);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition), visibility var(--transition);
}

.nav__parent:hover .nav__sub,
.nav__parent:focus-within .nav__sub {
  opacity: 1;
  visibility: visible;
}

.nav__sublink {
  display: block;
  padding: var(--sp-3) var(--sp-4);
  font-size: 15px;
  color: var(--c-white);
  white-space: nowrap;
}

.nav__sublink:hover {
  background: var(--c-blue);
  color: var(--c-white);
}

.nav__toggle {
  display: none;
  padding: var(--sp-2);
  background: none;
  border: 0;
  color: var(--c-white);
  cursor: pointer;
}

@media (max-width: 900px) {
  .nav__toggle { display: block; }

  .nav__list {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    height: auto;
    padding: 0 var(--sp-6) var(--sp-4);
    background: rgba(0, 0, 0, 0.88);
    transform: translateY(-120%);
    visibility: hidden;
    transition: transform var(--transition), visibility var(--transition);
  }

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

  .nav__link {
    height: auto;
    padding: var(--sp-4) 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  }

  /* No hover on touch: the submenu is always expanded in the drawer. */
  .nav__sub {
    position: static;
    min-width: 0;
    background: none;
    opacity: 1;
    visibility: visible;
  }

  .nav__sublink {
    padding: var(--sp-3) 0 var(--sp-3) var(--sp-4);
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  }
}

/* ---------- Footer ---------- */

.footer {
  padding-block: var(--sp-12) 0;
  background: var(--c-blue);
  color: var(--c-white);
  text-align: center;
  font-size: 13px;
}

.footer a { color: var(--c-white); }
.footer a:hover { color: var(--c-gold-hero); }

/* Pipe-separated inline links. */
.footer__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-6);
  margin: 0 0 var(--sp-8);
  padding: 0;
  list-style: none;
}

.footer__links li + li { position: relative; }

.footer__links li + li::before {
  content: "|";
  position: absolute;
  left: calc(var(--sp-6) / -2);
  transform: translateX(-50%);
  opacity: 0.5;
}

.footer__disclaimer {
  max-width: 900px;
  margin-inline: auto;
  font-size: 11px;
  line-height: 1.8;
  opacity: 0.9;
}

.footer__copyright {
  margin: var(--sp-8) 0 0;
  padding-block: var(--sp-4);
  background: var(--c-blue-dark);
  font-size: 11px;
}

/* ---------- Back to top ---------- */

.to-top {
  position: fixed;
  right: var(--sp-6);
  bottom: var(--sp-6);
  z-index: 90;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: var(--radius);
  background: var(--c-gold);
  color: var(--c-white);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition), visibility var(--transition);
}

.to-top[data-visible="true"] { opacity: 1; visibility: visible; }

/* ---- Staff chrome ----
   Visibly different from the public header so nobody has to check the address
   bar to know which side of the login they are on. Darker, flatter, and never
   transparent — there is no hero photo behind it on any staff page. */
.header--staff {
  /* One compact size on every staff page, the same as the scan page uses, but
     with a larger logo. --header-h includes the 3px gold line; the bar and its
     links are that much shorter so nothing paints over the line. */
  --header-h: 61px;
  background: var(--c-blue-dark);
  border-bottom: 3px solid var(--c-gold);
}

.header--staff .header__inner,
.header--staff .nav__list,
.header--staff .nav__link {
  height: calc(var(--header-h) - 3px);
}

.header--staff .nav__link {
  padding-inline: 13px;
  font-size: 15px;
}

/* The page you are on: lighter blue, inside the bar, above the gold line. */
.header--staff .nav__link[aria-current="page"] {
  background: var(--c-blue);
  color: var(--c-gold-hero);
}

.header__logo--staff {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.header__logo--staff img { width: 124px; height: 46px; object-fit: contain; }

/* Push sign-out away from the tools it sits beside, so it is not clicked by
   somebody reaching for Settings. */
.nav__end { margin-inline-start: auto; }

@media (min-width: 900px) {
  .nav__end { border-inline-start: 1px solid rgba(255, 255, 255, .2); }
}

/* Stacked, not inline: the address underneath is often long, and letting it sit
   beside the label forced "Sign out" to wrap onto two lines. */
.nav__link--signout {
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  line-height: 1.2;
  white-space: nowrap;
  color: rgba(255, 255, 255, .75);
}

.nav__link--signout:hover { color: var(--c-gold-hero); }

.nav__who {
  max-width: 14rem;
  overflow: hidden;
  font-size: 11px;
  line-height: 1;
  text-overflow: ellipsis;
  letter-spacing: 0;
  text-transform: none;
  opacity: .7;
}


/* === components.css === */
/* Reusable UI pieces */

/* ---------- Buttons ----------
   `.btn` (cards) and `.hero-btn` share everything but type and padding, so the
   common half lives in one rule. Variants set only a background. */

.btn,
.hero-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius);
  font-weight: 400;
  color: var(--c-white);
  text-align: center;
  cursor: pointer;
  list-style: none;
  transition: opacity var(--transition);
}

.btn:hover,
.hero-btn:hover { color: var(--c-white); opacity: 0.85; }

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

.btn {
  padding: 9px 12px;
  font-family: var(--font-btn);
  font-size: var(--fs-btn);
  line-height: 1.2;
}

.btn--info { background: var(--c-grey-btn); }
.btn--donate { background: var(--c-red); }
.btn--volunteer { background: var(--c-blue); }
.btn--done { background: var(--c-green); }

/* ---------- Hero ----------
   The original is a LayerSlider: everything scales linearly with the viewport
   up to its 1265px design width, then freezes. `--u` is one percent of that
   width, so each multiplier below is the measured pixel value / 12.65 —
   e.g. the title measured 76px, hence 6.008.

   Measured at a 1280 viewport: hero 800 tall, logo 265x100 at y=219,
   title 76px at y=362, buttons 79 tall at y=476 and y=581, 27px gaps. */

.hero {
  --u: min(1vw, 12.65px);

  position: relative;
  min-height: calc(63.2 * var(--u));
  padding-top: calc(17.3 * var(--u));
  padding-bottom: calc(11 * var(--u));
  background: var(--c-blue) url("/assets/img/doctor-slider.jpg") center / cover no-repeat;
  overflow: hidden;
}

/* Solid blue across the left, clearing by ~80% so the stethoscope reads. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    95deg,
    var(--c-blue) 0%,
    var(--c-blue) 43%,
    rgba(19, 82, 134, 0.9) 53%,
    rgba(19, 82, 134, 0.38) 67%,
    rgba(19, 82, 134, 0) 80%
  );
}

.hero__inner {
  position: relative;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
}

.hero__logo {
  width: calc(20.9 * var(--u));
  margin-bottom: calc(3.4 * var(--u));
}

.hero__title {
  margin: 0 0 calc(3 * var(--u));
  font-family: var(--font-hero);
  font-size: calc(6.008 * var(--u));
  font-weight: 600;
  line-height: 1;
  color: var(--c-white);
  text-transform: uppercase;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: calc(2.13 * var(--u));
  max-width: calc(70 * var(--u));
}

.hero-btn {
  padding: calc(1.82 * var(--u)) calc(3.95 * var(--u)) calc(1.58 * var(--u));
  font-family: var(--font-hero);
  font-size: calc(2.53 * var(--u));
  line-height: 1.125;      /* yields the measured 79px button height */
  text-transform: uppercase;
  white-space: nowrap;
  background: var(--c-dark-btn);
}

.hero-btn--gold {
  padding-inline: calc(2.37 * var(--u));
  font-size: calc(2.37 * var(--u));
  background: var(--c-gold-hero);
  color: var(--c-black);
}

.hero-btn--gold:hover { color: var(--c-black); }
.hero-btn--donate { background: var(--c-red); }

/* ---------- Split row (text + stacked media) ----------
   Measured: 634px column, 422px column, 43px gap. */

.split {
  display: grid;
  grid-template-columns: 634fr 422fr;
  gap: 43px;
  align-items: start;
}

.split__media { display: grid; gap: 2px; }

/* Both three-across rows share the same track definition; only the gap differs. */
.info-strip,
.clinic-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

/* ---------- Info strip (contact / hours / address) ----------
   Columns butt together with no gap so the middle one can carry a darker
   panel, and each cell supplies its own padding so that panel fills the band. */

.info-strip {
  gap: 0;
  text-align: center;
}

.info-strip > div { padding: var(--sp-12) var(--sp-6); }

.info-strip > div:nth-child(2) { background: var(--c-strip-mid); }

.info-strip .icon {
  width: 40px;
  height: 40px;
  margin-inline: auto;
  color: var(--c-gold);
  stroke-width: 1.4;
}

.info-strip__label {
  margin: var(--sp-4) 0 var(--sp-4);
  font-weight: 700;
  color: var(--c-blue);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

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

/* ---------- Clinic cards ----------
   Three across at 1100px: 331px columns with 50px gutters. */

.clinic-grid { gap: var(--sp-5); }

.clinic {
  display: flex;
  flex-direction: column;
  padding: var(--sp-3);
  border-radius: var(--radius-card);
  background: var(--c-grey-100);
}

.clinic__media {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--c-grey-200);
}

.clinic__title {
  margin: var(--sp-3) 0 0;
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--c-gold);
  font-size: 13px;
  line-height: 1.4;
}

/* Icon + text rows for city and date. */
.clinic__meta {
  margin: var(--sp-3) 0;
  padding: 0;
  list-style: none;
  font-size: 15px;
}

.clinic__meta li {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.clinic__meta .icon { color: var(--c-gold); }

/* Info / Donate / Volunteer sit in one row. The <details> stays a normal grid
   item in column 1 — `display: contents` would break its closed state — and the
   open panel widens across the other two columns, growing the row beneath the
   buttons rather than overlapping the next card. */
.clinic__foot {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: start;
  gap: 6px;
  margin-top: auto;
}

/* Browsers collapse <details> themselves, but stating it explicitly keeps the
   panel hidden in engines with incomplete support. */
details:not([open]) > .disclosure__body { display: none; }

.disclosure__body {
  width: calc(300% + 12px);   /* 3 columns + the 2 gaps between them */
  margin-top: var(--sp-2);
  padding: var(--sp-3);
  background: var(--c-white);
  border: 1px solid var(--c-grey-200);
  font-size: 13px;
  line-height: 1.6;
  text-align: left;
}

.disclosure__body :last-child { margin-bottom: 0; }
.disclosure__body a { word-break: break-word; }

/* ---------- Interior pages ----------
   Width comes from `.container` alone, so every page lines up. `.prose` only
   sets vertical rhythm — it never constrains width. */

.prose > :first-child { margin-top: 0; }
.prose h2 { margin-top: var(--sp-12); }
.prose h3 { margin-top: var(--sp-8); }
.prose h2 + p { margin-top: var(--sp-2); }
.prose ul,
.prose ol { padding-left: var(--sp-6); }
.prose li { margin-bottom: var(--sp-2); }
.prose li > ul { margin-top: var(--sp-2); }

/* ---------- Page banner ----------
   The 1920x400 strip that sits under the header on interior pages. */

.page-banner {
  position: relative;
  height: clamp(180px, 20.8vw, 400px);
  background: var(--c-blue) center / cover no-repeat;
}

/* ---------- Gallery + quote ---------- */

.gallery-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 50px;
  align-items: center;
}

/* One slide at a time, auto-advancing every 3s. The track is a scroll-snap
   container, so it still swipes and works with the arrows removed if JS fails. */
.gallery { position: relative; }

.gallery__track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.gallery__track::-webkit-scrollbar { display: none; }

.gallery__track img {
  flex: 0 0 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  scroll-snap-align: center;
}

/* Arrows sit on the left and right edges of the image, vertically centred. */
.gallery__nav {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: 30px;
  height: 38px;
  padding: 0;
  border: 0;
  background: rgba(0, 0, 0, 0.55);
  color: var(--c-white);
  cursor: pointer;
  transition: background var(--transition);
}

.gallery__nav:hover { background: rgba(0, 0, 0, 0.78); }
.gallery__nav--prev { left: 0; }
.gallery__nav--next { right: 0; }

.quote {
  margin: 0;
  font-size: 13px;
  line-height: 1.9;
}

.quote__cite {
  display: block;
  margin-top: var(--sp-2);
  font-style: normal;
}

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
  /* Below the slider's breakpoint the scaled hero type gets too small to
     read, so switch to fixed sizes and let the hero grow with its content. */
  .hero {
    min-height: 0;
    padding: calc(var(--header-h) + 32px) var(--sp-6) 44px;
  }

  .hero::before {
    background: linear-gradient(
      95deg,
      rgba(19, 82, 134, 0.96) 0%,
      rgba(19, 82, 134, 0.86) 60%,
      rgba(19, 82, 134, 0.62) 100%
    );
  }

  /* The header already shows the mark; a second one right below it reads as a
     duplicate on a narrow screen. */
  .hero__logo { display: none; }
  .hero__title { font-size: 34px; margin-bottom: var(--sp-5); }
  .hero__actions { gap: 8px; max-width: none; }
  .hero-btn { padding: 11px 16px 10px; font-size: 13px; }
  .hero-btn--gold { padding-inline: 16px; font-size: 13px; }

  .split,
  .info-strip,
  .clinic-grid,
  .gallery-row {
    grid-template-columns: 1fr;
    gap: var(--sp-8);
  }

  /* Stacked, the darker panel would read as a stray stripe. */
  .info-strip { gap: 0; }
  .info-strip > div { padding-block: var(--sp-8); }
  .info-strip > div:nth-child(2) { background: none; }

  .split__media img { width: 100%; }

  /* Card buttons go full width and stack, as in the mobile design. */
  .clinic__foot { grid-template-columns: 1fr; }
  .clinic__foot .btn { padding-block: 12px; }
  .disclosure__body { width: 100%; }
}

/* ---- Staff home: the tools ---- */
.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--sp-4);
  margin: var(--sp-6) 0;
  padding: 0;
  list-style: none;
}

.tool__link {
  display: block;
  height: 100%;
  padding: var(--sp-5);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-surface);
  color: inherit;
  text-decoration: none;
  transition: border-color .12s, box-shadow .12s;
}

.tool__link:hover,
.tool__link:focus-visible {
  border-color: var(--c-blue);
  box-shadow: 0 1px 6px rgba(0, 0, 0, .08);
}

.tool__name {
  display: block;
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--c-blue);
  margin-bottom: var(--sp-2);
}

.tool__note {
  display: block;
  font-size: .9rem;
  color: #666;
}


/* === forms.css === */
/* Forms — contact, host-a-clinic, and later the patient-facing forms. */

/* `hidden` must always win. A class that sets `display` (.field-row is a grid)
   otherwise overrides the browser's own rule, and a follow-up question that
   is meant to be hidden stays on screen. */
[hidden] { display: none !important; }

/* Width comes from the page container, same as every other block. */
.form__section {
  margin: 0 0 var(--sp-12);
  padding: 0 0 var(--sp-8);
  border: 0;
  border-bottom: 1px solid var(--c-border);
}

.form__section:last-of-type { border-bottom: 0; }

.form__legend {
  padding: 0;
  margin-bottom: var(--sp-6);
  font-size: 20px;
  font-weight: 700;
  color: var(--c-blue);
}

.field { margin-bottom: var(--sp-4); }

.field__label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: 15px;
  font-weight: 600;
}

.field__label .req,
.req {
  margin-left: 2px;
  color: var(--c-red);
}

.field__hint {
  display: block;
  margin-top: var(--sp-1);
  font-size: 13px;
  color: var(--c-grey-btn);
}

.input,
.select,
.textarea {
  width: 100%;
  padding: var(--sp-3);
  font-family: inherit;
  font-size: var(--fs-base);
  color: var(--c-text);
  background: var(--c-white);
  border: 1px solid var(--c-grey-400);
  border-radius: var(--radius);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.input:focus,
.select:focus,
.textarea:focus {
  border-color: var(--c-blue);
  box-shadow: 0 0 0 3px rgba(19, 82, 134, 0.15);
  outline: none;
}

.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"] { border-color: var(--c-red); }

.textarea {
  min-height: 130px;
  resize: vertical;
}

.field-row {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

/* ---- Choice inputs ---- */

.choice-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.choice-group--inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--sp-4);
}

.choice {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: 15px;
  cursor: pointer;
}

.choice input {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--c-blue);
}

/* Long option lists (languages, specialties, roles) run in columns rather than
   one tall stack — the live form uses three across. */
.choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: var(--sp-2) var(--sp-4);
}

/* ---- Donate buttons overlaid on a page banner ----
   A translucent black band across the foot of the banner. The buttons sit on
   the container's left edge so they line up with the heading below.
   Red by default, yellow with black text on hover, matching the live site. */

.banner-actions {
  position: absolute;
  inset: auto 0 0 0;
  padding-block: var(--sp-5);
  background: rgba(0, 0, 0, 0.35);
}

.banner-actions .container {
  display: flex;
  gap: var(--sp-5);
}

.btn--donate-hero {
  padding: 11px 26px;
  border-radius: var(--radius-card);
  font-size: 17px;
  background: linear-gradient(#c10303, #e00404);
  color: var(--c-white);
}

.btn--donate-hero:hover {
  background: #ffce05;
  color: var(--c-black);
  opacity: 1;
}

/* ---- Donation modal ---- */

.modal {
  width: min(100% - 2rem, 640px);
  padding: 0;
  border: 0;
  border-radius: var(--radius-card);
  background: #f6f6f6;
  color: var(--c-text);
}

.modal::backdrop { background: rgba(0, 0, 0, 0.55); }

.modal__body { padding: var(--sp-6); }

.modal__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
}

.modal__head h2 { margin: 0 0 var(--sp-6); }

.modal__close {
  padding: 0 var(--sp-2);
  border: 0;
  background: none;
  font-size: 28px;
  line-height: 1;
  color: var(--c-grey-btn);
  cursor: pointer;
}

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

/* Amount pills */
.amount-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

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

.amount span {
  display: block;
  padding: 8px 18px;
  border: 1px solid var(--c-grey-400);
  border-radius: var(--radius);
  background: var(--c-white);
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}

.amount input:checked + span {
  background: #5b8fd4;
  border-color: #5b8fd4;
  color: var(--c-white);
}

.amount input:focus-visible + span {
  outline: 3px solid var(--c-gold);
  outline-offset: 2px;
}

/* ---- Clinic strapline on the volunteer form ---- */

.clinic-strap {
  margin-top: calc(var(--sp-4) * -1);
  font-weight: 600;
  color: var(--c-blue);
}

/* "Look up another ticket" on the clearance chart: a button, set off from
   the ticket number beside it. */
#cl-another { margin-left: var(--sp-3); font-weight: 700; }

/* ---- Messaging ---- */

.field__error {
  display: block;
  margin-top: var(--sp-1);
  font-size: 13px;
  font-weight: 600;
  color: var(--c-red);
}

.form__status {
  /* Top margin too: the status usually follows a button, and butting straight
     up against it reads as part of the control. */
  margin-block: var(--sp-6);
  padding: var(--sp-4);
  border-radius: var(--radius);
  font-size: 15px;
}

.form__status--error {
  background: rgba(219, 39, 33, 0.08);
  border: 1px solid var(--c-red);
  color: var(--c-red);
}

.form__status--ok {
  background: rgba(42, 163, 21, 0.08);
  border: 1px solid var(--c-green);
  color: var(--c-green);
}

/* Something worked, but not the way it was meant to — the message went out via
   a fallback. Deliberately distinct from both --ok and --error: treating a
   degraded success as a plain success is how a misconfiguration survives for
   months, and treating it as a failure would have staff re-sending invites that
   already arrived. Gold matches the existing warning-ish accent. */
.form__status--warn {
  background: rgba(200, 161, 0, 0.10);
  border: 1px solid var(--c-gold);
  color: #7a6200;
}

/* ---- Consent / legal blocks (patient forms) ----
   Scrollable so the full text is present without pushing submit off screen. */

.consent {
  max-height: 300px;
  overflow-y: auto;
  margin-bottom: var(--sp-4);
  padding: var(--sp-4);
  background: var(--c-surface-alt);
  border: 1px solid var(--c-border);
  font-size: 15px;
  line-height: 1.4;
}

.consent h3 {
  margin-top: var(--sp-4);
  font-size: var(--fs-base);
}

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

/* ---- Multi-step forms ----
   Steps are sections toggled with the `hidden` attribute, so the form still
   submits every field if JavaScript never runs. */

.form__actions {
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-6);
}

.form__actions .btn { padding-inline: var(--sp-6); }

/* ---- Contact details list ---- */

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

.contact-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

.contact-list .icon {
  flex: none;
  width: 26px;
  height: 26px;
  padding: 6px;
  border-radius: 50%;
  background: var(--c-gold);
  color: var(--c-white);
  stroke-width: 2;
}

/* ---- Honeypot: hidden from people, visible to naive bots ---- */

.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---- Tickets ----
   Rendered on the page so they can be checked before printing, then printed
   from there. Screen and paper share one set of rules; @media print only
   removes the surrounding page and adds the page breaks. */

.ticket-sheet {
  display: grid;
  gap: var(--sp-6);
  margin-top: var(--sp-6);
}

.ticket {
  width: 3in;
  padding: var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-card);
  background: #fff;
  color: #000;
}

.ticket__head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ticket__logo {
  width: 120px;
  height: auto;
}

.ticket__kicker {
  font-weight: 900;
  font-size: 17px;
  letter-spacing: 0.01em;
}

.ticket__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
}

.ticket__seq {
  font-size: 60px;
  font-weight: 900;
  line-height: 1.1;
}

.ticket__qr svg {
  display: block;
  width: 75px;
  height: 75px;
}

.ticket__foot {
  margin-top: var(--sp-2);
  font-size: 14px;
  text-align: center;
}

@media print {
  /* Nesting-proof: `body > *` would miss the sheet, which sits inside <main>.
     Hiding by visibility keeps the sheet's own subtree visible. */
  body * { visibility: hidden; }
  .ticket-sheet,
  .ticket-sheet * { visibility: visible; }

  /* Overlay chrome sets `visibility: visible` on itself, and those selectors
     carry more specificity than `body *`, so it survives the rule above. Being
     position:fixed it then prints once, on the first page — which is where the
     gold back-to-top button was landing. Remove it from layout outright. */
  .to-top,
  .nav__list,
  .modal { display: none !important; }

  .ticket-sheet {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
    gap: 0;
    margin: 0;
  }

  .ticket {
    border: 0;
    border-radius: 0;
    padding: 0;
    page-break-after: always;
    break-after: page;
  }

  .ticket:last-child {
    page-break-after: auto;
    break-after: auto;
  }
}

/* ---- Patient forms ---- */

/* The text box behind an "Other" choice. Indented so it reads as belonging to
   the option above it rather than as a new question. */
.other-box {
  max-width: 420px;
  margin-top: var(--sp-2);
  margin-left: 26px;
}

/* Consent signature. Sized for a finger on a tablet; `touch-action: none`
   stops the drawing stroke scrolling the page underneath it. */
.signature {
  display: block;
  width: 100%;
  max-width: 480px;
  height: 150px;
  margin-bottom: var(--sp-2);
  background: var(--c-white);
  border: 1px solid var(--c-grey-400);
  border-radius: var(--radius);
  touch-action: none;
  cursor: crosshair;
}

/* ---- Simple data table (issued tickets, scan log) ---- */

.table {
  width: 100%;
  margin-bottom: var(--sp-6);
  border-collapse: collapse;
  font-size: 15px;
}

.table th,
.table td {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--c-border);
  text-align: left;
}

.table th {
  font-weight: 700;
  color: var(--c-blue);
}

/* ---- Scanning station ----
   Built to be read across a room: one huge sequence number, and colour doing
   the talking so a volunteer does not have to read anything to know it worked. */

.scan__stage {
  margin: var(--sp-6) 0;
  padding: var(--sp-8) var(--sp-6);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-card);
  background: var(--c-grey-100);
  text-align: center;
  transition: background var(--transition);
}

.scan__stage[data-state="ok"] { background: #98fb98; }
.scan__stage[data-state="unknown"] { background: #fa5f55; }
.scan__stage[data-state="duplicate"] { background: #ffce05; }
.scan__stage[data-state="error"] { background: #fa5f55; }

.scan__input {
  max-width: 420px;
  margin-inline: auto;
  text-align: center;
  font-size: 18px;
}

.scan__result { min-height: 0; }

.scan__result {
  margin: var(--sp-4) 0 0;
  font-size: 72px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--c-blue);
  min-height: 79px;
}

.scan__note {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
}

/* Compact layout: one line for where you are, the scan box, one line of stats. */
.scan-page .footer { display: none; }
.scan { padding: var(--sp-3) 0 var(--sp-4); }
.scan__wrap { max-width: 720px; }
.scan__bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
}
.scan__where { flex: 1 1 12rem; min-width: 0; display: flex; align-items: center; gap: var(--sp-2); }
.scan__clinic {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 14px; font-weight: 600; color: var(--c-blue);
}
.scan__station-label { font-size: 13px; font-weight: 600; }
.scan__station { width: auto; min-width: 9rem; padding-block: 6px; }
.scan-page .scan__stage { margin: var(--sp-3) 0; padding: var(--sp-6) var(--sp-4); }
.scan-page .scan__result { font-size: 56px; min-height: 62px; margin-top: var(--sp-3); }
.scan__hint { margin: 0 0 var(--sp-2); font-size: 13px; color: #555; }
.scan__stats { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); font-size: 14px; }
.scan__stats b { color: var(--c-blue); font-size: 17px; }
@media (max-width: 600px) {
  .scan-page .scan__result { font-size: 44px; }
  .scan__station { flex: 1 1 8rem; }
}

/* ---- Live-connection indicator ----
   A station scanning against a stale ticket list would hand out wrong numbers,
   so the connection state is stated plainly rather than assumed. */

.conn {
  display: inline-block;
  padding: 2px var(--sp-3);
  border-radius: 999px;
  background: var(--c-red);
  color: var(--c-white);
  font-size: 13px;
  font-weight: 600;
}

.conn--on { background: var(--c-green); }

/* ---- Waitlist status pills ---- */

/* Reprint button in the scan waitlist, and its dialog. */
.reprint-btn {
  display: inline-flex;
  padding: var(--sp-1, 4px);
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  color: var(--c-text);
  cursor: pointer;
}
.reprint-btn:hover,
.reprint-btn:focus-visible { border-color: currentColor; }
.reprint-btn svg { width: 22px; height: 22px; }

.reprint__who {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 16px;
  margin: 0 0 var(--sp-6);
}
.reprint__who dt { font-weight: 600; }
.reprint__who dd { margin: 0; }
.modal .field__hint[hidden] { display: none; }

.pill {
  display: inline-block;
  padding: 2px var(--sp-2);
  border-radius: 999px;
  background: var(--c-grey-200);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.pill--added { background: var(--c-grey-200); }
.pill--registered { background: #cfe3f5; }
.pill--pending-medical-clearance { background: #ffe9a8; }
.pill--medical-clearance { background: #ffce05; }
.pill--cleared { background: #b8e6b8; }
.pill--printed { background: #d6c9f0; }
.pill--serving { background: var(--c-green); color: var(--c-white); }

/* A ticket printed without its QR: nothing sits opposite the number, so centre
   it rather than leaving it hanging on the left. */
.ticket--no-qr .ticket__body { justify-content: center; }

/* WAITING replaces the date line on a ticket with no QR — it is the message,
   so it carries the weight the date never needed. */
.ticket--no-qr .ticket__foot {
  margin-top: var(--sp-3);
  font-size: 24px;
  font-weight: 900;
  letter-spacing: 0.02em;
}

/* ---- Patient serving board (/serving/) ----
   Full-screen display. Sizes are in viewport units so the longest list the
   settings allow still fits on one screen with no scrolling. */
.serving-page { background: #fff; overflow: hidden; }
.serving {
  --rows: 8;
  min-height: 100vh; padding: 1vh 2vw; display: flex; flex-direction: column; }
.serving__title {
  margin: 0; text-align: center; font-weight: 400; color: #2b2b2b;
  font-size: 5.5vh; line-height: 1.3;
}
.serving__bar { display: flex; gap: 1rem; align-items: center; min-height: 3vh; }
.serving__sound { font: inherit; font-size: 14px; padding: 2px 8px; cursor: pointer; }
.serving__sound[disabled] { cursor: default; opacity: .6; }
.serving__conn { font-size: 14px; color: #8a1f11; }
.serving__cols { flex: 1; display: grid; grid-template-columns: repeat(4, 1fr); gap: 2vw; padding-top: 2vh; }
.serving__col ul { list-style: none; margin: 0; padding: 0; }
.serving__col li {
  font-weight: 700; color: #2d7018; line-height: 1.2; white-space: nowrap;
  /* --rows is set from the clinic's per-column limit, so every row fits. */
  font-size: min(9vh, 7vw, calc(76vh / (var(--rows) * 1.2)));
}
.serving__col li.serving__wait { font-size: 16px; font-weight: 400; color: #555; padding-top: 2vh; }
.serving__gate { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 1rem; }
.serving__gate[hidden], .serving[hidden] { display: none; }
.serving__form { width: 100%; max-width: 26rem; }

/* Row actions on /records/: add a service, remove one, reprint — kept on one
   line and big enough to hit. */
.r-actions { white-space: nowrap; }
.r-actions .reprint-btn {
  min-width: 30px; height: 30px; align-items: center; justify-content: center;
  font-size: 20px; line-height: 1; color: var(--c-blue); cursor: pointer;
}
.r-actions .reprint-btn:hover { border-color: var(--c-border); background: var(--c-grey-100); }

/* ---- Registration: language picker and the rules list ---- */

.lang-pick { max-width: 14rem; margin-bottom: var(--sp-4); }

.intake-rules { padding-left: 1.2em; margin: 0 0 var(--sp-4); }
.intake-rules li { margin-bottom: var(--sp-1); }

/* Date of birth: month, day and year side by side. */
.dob { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.dob .select { flex: 1 1 8rem; min-width: 0; }

/* ---- Settings page: compact, two columns on a wide screen ----
   Every section used to be a full-width block with generous margins, which
   made the page several screens tall. Short sections now sit side by side,
   the long ones span both columns, and the explanatory text folds away. */

.settings .form__section {
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-4);
}
.settings .form__legend { margin-bottom: var(--sp-3); font-size: 18px; }
.settings .field { margin-bottom: var(--sp-3); }
.settings .form__actions { margin-top: var(--sp-3); }
.settings .table { margin-bottom: var(--sp-3); }
.settings .table th,
.settings .table td { padding: 4px var(--sp-2); }

.settings__bar {
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
  flex-wrap: wrap;
  margin-bottom: var(--sp-3);
}
.settings__bar .field { flex: 0 1 22rem; margin-bottom: 0; }
.settings__bar .field__hint { flex: 1 1 22rem; margin: 0; }

.settings__jump {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-4);
}
.settings__jump a {
  padding: 4px 12px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.settings__jump a:hover,
.settings__jump a:focus-visible { border-color: currentColor; }

/* Sections are anchors: keep their heading clear of the top of the window. */
.settings [id] { scroll-margin-top: var(--sp-4); }

.settings__grid {
  display: grid;
  gap: 0 var(--sp-8);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .settings__grid { grid-template-columns: 1fr 1fr; }
  .settings__wide { grid-column: 1 / -1; }
}

.settings__help { margin: 0 0 var(--sp-3); }
.settings__help > summary {
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  color: var(--c-blue);
}
.settings__grid > * { min-width: 0; }
.settings .input,
.settings .select { padding-top: 6px; padding-bottom: 6px; }
.settings textarea.input { min-height: 0; }
