/* ============================================================
   BRANDON AREA RESCUE SQUAD — volunteer landing page
   volunteer.brandonrescue.org

   This file adds ONLY the components the volunteer page needs.
   Everything else — the tokens, the type scale, the buttons, the
   header, the footer, .section / .editorial / .detail-list /
   .towns / .notice / .fact-line / .figure / .band / .page-hero —
   comes from assets/css/styles.css, which is a byte-for-byte copy
   of the brandonrescue-lp stylesheet.

   Rules this file follows, taken from that design system:
     · Every color is an existing token. The one addition is an
       error red, because the palette had no red and a form needs
       one; its contrast ratios are recorded beside it.
     · No shadows. A surface is background + 1px --line + --radius,
       the same treatment as .figure__frame.
     · No pills, no gradients, no decorative color.
     · Facts and lists are set typographically with hairline rules,
       never as statistic cards.
     · Serif for headings, system sans for body and UI. No webfonts.
     · Breakpoints reuse the existing ones: 900px for the two-column
       editorial split, 40em for smaller grids.

   If you change a color here, re-check it against WCAG 2.2 AA.
   ============================================================ */

:root {
  /* The only new color. There is no red anywhere in the base palette,
     and a form error indicated by color alone would fail regardless —
     so this pairs with a 4px left rule, the word "Please", and
     aria-invalid. Never the only signal.
       #B3261E   6.5:1 on --white
                 6.1:1 on --paper
                 5.9:1 on --error-tint          (all AA, AAA at large) */
  --error:      #B3261E;
  --error-tint: #FDF2F1;
}

/* ---------- Small extensions to existing patterns ---------- */

/* .label on the deep blue hero field. The base .label is --blue-strong,
   which is a 2.1:1 failure on --blue-ink; amber-light is 8.2:1 there and
   is already the established on-blue accent. */
.label--onblue { color: var(--amber-light); }

/* A section-opening lede that introduces a full-width block rather than
   one column of an .editorial split, so it can run slightly wider than
   the 62ch --measure without losing readability. */
.lede--wide { max-width: 68ch; }

/* ---------- Hero scrim, strengthened for THIS photograph ----------
   styles.css ships the scrim at 0.92 / 0.78 / 0.50 opacity. Measured
   against the station photograph, the amber bold in the 911 notice came
   out at 4.47:1 — three hundredths under the 4.5:1 that 17px bold needs.
   The cause is specific to this image: the sky and a white ambulance side
   sit directly behind that line, so the background there is effectively
   blown-out white rather than mid-tone.

   Raising the stops to 0.94 / 0.86 / 0.62 takes it to 5.2:1 with the
   ambulances still clearly readable on the right. Measured after the
   change, over the real rendered page:
     amber bold, 911 notice   5.23:1  (needs 4.5)
     white lede               6.9:1   (needs 4.5)
     white h1                 8.1:1   (needs 3.0)

   This lives here, not in styles.css — that file is a byte-for-byte copy
   of brandonrescue-lp's and must stay diffable. RE-MEASURE IF THE HERO
   PHOTOGRAPH IS EVER REPLACED; a brighter image may need more. */
.hero__scrim {
  background: linear-gradient(100deg,
    rgba(10, 53, 80, 0.94) 0%,
    rgba(10, 53, 80, 0.86) 46%,
    rgba(10, 53, 80, 0.62) 100%);
}

/* Inline links on the deep blue fields.
   The base rule is `a { color: var(--blue-strong) }`, which is #075A97 on
   #0A3550 — a 1.7:1 failure. brandonrescue-lp never hit this because its
   .hero and .band carry only buttons; this page puts a phone number and
   an email address in the closing band, so the on-blue link colour has
   to exist. --amber-light is 8.2:1 there and is already the established
   on-blue accent. Underlined, so it is not identified by colour alone. */
.hero a:not(.btn),
.band a:not(.btn) {
  color: var(--amber-light);
  text-decoration: underline;
}
.hero a:not(.btn):hover,
.band a:not(.btn):hover { color: var(--white); }

/* ---------- 1. The two volunteer pathways ----------
   Deliberately NOT feature cards: no shadow, no icon badge, no accent
   bar. Each one is a quiet paper surface — the same background + 1px
   --line + --radius that .figure__frame uses — carrying an eyebrow
   label, a serif heading, prose, and a hairline-ruled requirements
   list. Two of them, side by side, because there are exactly two
   pathways and presenting them as equals is the point. */
.paths {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
@media (min-width: 900px) {
  .paths { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.path {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
/* Paper-on-paper would disappear, so on a --paper section the panels
   invert to white. Same treatment, opposite ground. */
.section--paper .path { background: var(--white); }

.path > * + * { margin-top: 1rem; }
.path h3 { max-width: 24ch; }

.path__lede {
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.5;
  color: var(--blue-strong);
  max-width: 40ch;
}

.path p { color: var(--ink); }

.path__points-heading {
  margin-top: 1.5rem !important;   /* wins over the > * + * rhythm above */
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.85rem;
}

/* Hairline-ruled list, exactly like .detail-list. No checkmark icons:
   a tick beside a requirement reads as "you already qualify". */
.path__points {
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
  max-width: none;
}
.path__points > li {
  margin: 0;
  padding: 0.7rem 0;
  border-top: 1px solid var(--line);
  font-size: 1rem;
  line-height: 1.5;
}
.section--paper .path__points > li { border-top-color: var(--line); }
.path__points > li:last-child { border-bottom: 1px solid var(--line); }

/* ---------- 2. "How it works" steps ----------
   An <ol>, so the sequence is real to a screen reader and survives with
   CSS off. The numeral is decorative (aria-hidden) and the heading
   carries a visually-hidden "Step N:" instead, so the order is
   announced as words rather than as a floating digit. */
.steps {
  margin: clamp(1.75rem, 3.5vw, 2.5rem) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
  display: grid;
  gap: 0;
}
@media (min-width: 60em) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(2rem, 4vw, 3.5rem); }
}

.step {
  display: flex;
  gap: clamp(1rem, 2vw, 1.5rem);
  align-items: flex-start;
  margin: 0;
  padding: 1.35rem 0;
  border-top: 1px solid var(--line-strong);
}

/* Serif numeral, sized like a .price but quieter. Set in --blue not
   --blue-strong: it is a wayfinding mark, not a link or an action. */
.step__n {
  flex: none;
  width: 2.25rem;
  font-family: var(--font-serif);
  font-size: clamp(2rem, 3.5vw, 2.6rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--blue);
}

.step__body { min-width: 0; }
.step__body h3 {
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  font-weight: 700;
  margin-bottom: 0.3rem;
}
.step__body p { margin: 0; font-size: 1rem; color: var(--ink-muted); }

/* ---------- 3. Service-area note ----------
   The counterpart to the towns list in the same .editorial row. A plain
   surface, because there is no map asset and a fake map graphic would be
   worse than a clear statement of the facts. */
.area-note {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.35rem, 3vw, 2rem);
}
.section:not(.section--paper) .area-note { background: var(--paper); }

.area-note__h {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blue-strong);
  margin-bottom: 1rem;
}
.area-note p {
  margin: 0 0 0.85rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--line);
  font-size: 1rem;
  line-height: 1.55;
  max-width: none;
}
.area-note p:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; }
.area-note strong { color: var(--ink); }
.area-note__fine { color: var(--ink-muted); font-size: 0.9rem !important; }

/* ---------- 4. FAQ ----------
   Every answer is visible in full. No <details>, no accordion, no
   "read more" — the Ad Grants brief for this page forbids hidden
   content, and the FAQPage structured data has to match what a visitor
   can actually see. Hairline rules give it rhythm instead. */
.faq {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  max-width: 72ch;
}
.faq__item {
  padding: clamp(1.25rem, 2.5vw, 1.75rem) 0;
  border-top: 1px solid var(--line);
}
.faq__item:last-child { border-bottom: 1px solid var(--line); }

.faq__q {
  font-family: var(--font-serif);
  font-size: clamp(1.2rem, 2vw, 1.4rem);
  margin-bottom: 0.6rem;
  max-width: 46ch;
}
.faq__a { color: var(--ink-muted); margin-bottom: 0.8rem; }
.faq__a:last-child { margin-bottom: 0; }

/* ---------- 5. The volunteer interest form ---------- */
.form-wrap { max-width: 46rem; }

.vform { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.vform > * + * { margin-top: clamp(1.35rem, 2.5vw, 1.75rem); }

/* The honeypot. Positioned off-screen rather than display:none, because
   a bot that parses CSS skips display:none fields; tabindex="-1" keeps
   it out of the keyboard path and aria-hidden keeps it out of the
   accessibility tree, so no real person can reach it either way. */
.vform__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.vform__row { display: grid; gap: clamp(1.35rem, 2.5vw, 1.75rem); }
/* Two-up only once there is genuinely room. Stacked fields are easier to
   fill in on a phone, and this form is mostly filled in on phones. */
@media (min-width: 44em) {
  .vform__row--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Align the CONTROLS across a two-up row, not the labels.
     Only one of the two fields carries a hint or an error message, so
     aligning the tops left one input sitting a line lower than its
     neighbour — which read as a mistake. Each field becomes a flex
     column and its last child (always the control) is pushed to the
     bottom, so the inputs share a baseline however many lines of hint
     or error text sit above them. */
  .vform__row--two > .vform__field { display: flex; flex-direction: column; }
  .vform__row--two > .vform__field > :last-child { margin-top: auto; }
}

.vform__field { min-width: 0; }

.vform label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--ink);
}

.vform__req { font-weight: 600; color: var(--error); }
.vform__optional { font-weight: 400; color: var(--ink-muted); }

.vform__hint,
.vform__error {
  margin: 0 0 0.45rem;
  font-size: 0.95rem;
  line-height: 1.5;
  max-width: 52ch;
}
.vform__hint { color: var(--ink-muted); }
/* The message carries the error in words. Color is reinforcement, and
   the 4px rule on the control below is the third, non-color signal. */
.vform__error { color: var(--error); font-weight: 700; }

.vform input[type="text"],
.vform input[type="email"],
.vform input[type="tel"],
.vform select,
.vform textarea {
  display: block;
  width: 100%;
  min-height: 52px;              /* comfortable touch target, > 44px */
  padding: 0.7rem 0.85rem;
  background: var(--white);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  /* 17px. Anything under 16px makes iOS Safari zoom the page on focus,
     which is a genuine usability failure, not a cosmetic one. */
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink);
  /* Let a narrow phone shrink the control rather than overflow the page. */
  max-width: 100%;
}
.vform textarea { min-height: 8rem; resize: vertical; }

/* Native chevron kept: a custom one is one more thing to get wrong, and
   the system control is what visitors already recognise. */
.vform select { appearance: auto; }

.vform input:hover,
.vform select:hover,
.vform textarea:hover { border-color: var(--ink-muted); }

/* :focus-visible in styles.css already draws a 3px --blue ring. This
   darkens the border underneath it so the field reads as active even
   where the ring is hard to see. */
.vform input:focus,
.vform select:focus,
.vform textarea:focus { border-color: var(--blue-strong); outline-offset: 2px; }

.vform ::placeholder { color: #6B7F89; opacity: 1; }  /* 4.6:1 on white */

/* Invalid state: tinted ground, a 2px border, and a 5px left rule — three
   signals, none of them colour alone, alongside the message above the
   field and aria-invalid on the control.

   The `.vform` prefix is load-bearing. Without it this selector is
   (0,1,1) while the base control rule above is (0,2,1) — because of its
   [type="text"] attribute selector — so the base rule won and an invalid
   field rendered indistinguishably from a valid one. Adding `.vform`
   ties the specificity, and being later in the file wins. Do not
   simplify these selectors back. */
.vform .vform__field--invalid input,
.vform .vform__field--invalid select,
.vform .vform__field--invalid textarea {
  border-color: var(--error);
  border-width: 2px;
  border-left-width: 5px;
  background: var(--error-tint);
}

/* ---------- 5b. Checkbox groups ---------- */
.vform__fieldset {
  /* Only the inline margin is zeroed. A blanket `margin: 0` here has the
     same specificity as the `.vform > * + *` rhythm rule and, coming
     later in the file, silently won — which crowded the fieldset up
     against the field above it. Reset what the UA sets, nothing more. */
  margin-inline: 0;
  margin-bottom: 0;
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.section--paper .vform__fieldset { background: var(--white); }

.vform__fieldset legend {
  padding: 0;
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--ink);
}
.vform__fieldset legend .vform__req { font-weight: 400; color: var(--ink-muted); }

.vform__checks {
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
}
.vform__checks > li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 0.75rem;
  margin: 0;
  padding: 0.6rem 0;
  border-top: 1px solid var(--line);
}
.vform__checks > li:first-child { border-top: 0; padding-top: 0; }

/* Checkboxes and the consent box share this. 1.35rem is large enough to
   hit on a phone; the label beside it is also a hit target, which is
   what actually makes these comfortable. */
.vform input[type="checkbox"] {
  /* 24px exactly. WCAG 2.2 SC 2.5.8 (Target Size, Minimum) asks for
     24x24 unless neighbouring targets are far enough apart. These rows
     sit ~50px apart so the spacing exception would already cover a
     smaller box — but meeting the size outright leaves nothing to argue
     about, and it is genuinely easier to hit on a phone. */
  width: 1.5rem;
  height: 1.5rem;
  margin: 0.2rem 0 0;
  flex: none;
  accent-color: var(--blue-strong);
  cursor: pointer;
}
.vform__checks label,
.vform__consent label {
  margin: 0;
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.5;
  cursor: pointer;
  /* A tall label makes the whole line a comfortable target on mobile. */
  padding-block: 0.15rem;
}

.vform__fieldset .vform__hint { margin: 1rem 0 0; }

/* ---------- 5c. Consent ----------
   Required, so it gets its own block rather than sitting inside the
   optional checkbox group where it could be mistaken for one of them. */
.vform__consent {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 0.75rem;
  padding: clamp(1.1rem, 2.5vw, 1.35rem);
  background: var(--white);
  border: 1px solid var(--line-strong);
  border-left: 4px solid var(--amber);   /* same signal as .notice */
  border-radius: var(--radius);
}
.vform__consent .vform__error {
  grid-column: 1 / -1;
  margin-bottom: 0;
}
.vform__consent.vform__field--invalid {
  border-color: var(--error);
  border-left-color: var(--error);
  background: var(--error-tint);
}

.vform .actions { margin-top: clamp(1.5rem, 3vw, 2rem); }
.vform .fineprint { margin-top: 1.25rem; }

/* ---------- 6. Error summary callout ----------
   role="alert" and tabindex="-1"; site.js moves focus here on load
   after a failed submit, which is the accessible pattern for reporting
   a form error. The links jump to the field that needs fixing. */
.callout {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
  background: var(--white);
  border: 1px solid var(--line-strong);
  border-left: 5px solid var(--blue);
  border-radius: var(--radius);
}
.callout--error {
  background: var(--error-tint);
  border-color: var(--error);
  border-left-color: var(--error);
}
.callout__h {
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--error);
  margin-bottom: 0.5rem;
}
/* The same callout used for an informational note rather than an error. */
.callout__h--plain { color: var(--ink); }
.callout p { margin-bottom: 0.75rem; }
.callout p:last-child { margin-bottom: 0; }
.callout ul { margin: 0; padding-left: 1.25rem; }
.callout li { margin-bottom: 0.35rem; }
.callout a { color: var(--error); font-weight: 700; }
.callout a:hover { color: var(--ink); }
/* The callout itself takes focus (site.js focuses it after a failed
   submit), so the ring is needed on the element AND on its links. */
.callout--error:focus-visible,
.callout--error :focus-visible { outline-color: var(--error); }

/* ---------- 7. Long-form prose pages (privacy) ----------
   The privacy policy is the one page here that is genuinely a document.
   It gets a single measured column and the standard vertical rhythm. */
.prose-page { max-width: 68ch; }
.prose-page > * + * { margin-top: 1.15em; }
.prose-page h2 {
  font-size: clamp(1.4rem, 2.6vw, 1.85rem);
  margin-top: 2.25em;
  padding-top: 1.15rem;
  border-top: 1px solid var(--line);
}
.prose-page > h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.prose-page h2 + p, .prose-page h2 + ul { margin-top: 0.85em; }
.prose-page ul { max-width: var(--measure); }
.prose-page li { line-height: 1.65; }
.prose-page code {
  padding: 0.1em 0.35em;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 3px;
  font-size: 0.9em;
  /* Wrap rather than force a horizontal scrollbar on a phone. */
  overflow-wrap: anywhere;
}
.prose-page .actions { margin-top: 2.5rem; }

/* ---------- 8. Print ----------
   Someone will print this to take to a squad meeting. Make the form
   fillable on paper and keep the contact details. */
@media print {
  .paths, .steps { display: block; }
  .path, .area-note, .vform__fieldset, .vform__consent, .callout {
    background: none;
    border: 1px solid #999;
  }
  .vform input, .vform select, .vform textarea { border: 1px solid #999; }
  .faq__item { break-inside: avoid; }
  .step { break-inside: avoid; }
}
