/* ============================================================
   COMPONENTS
   ============================================================ */

/* ---------- Buttons ---------- */
.btn {
  --btn-bg: var(--color-brand);
  --btn-fg: #fff;
  --btn-bd: var(--color-brand);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: var(--touch-min);
  padding: var(--space-3) var(--space-5);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: var(--border-base) solid var(--btn-bd);
  border-radius: var(--radius-md);
  font-family: var(--font-display);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color var(--dur-state) var(--ease-out),
              border-color var(--dur-state) var(--ease-out),
              color var(--dur-state) var(--ease-out),
              box-shadow var(--dur-state) var(--ease-out),
              transform var(--dur-micro) var(--ease-out);
}
/* a:hover carries higher specificity than .btn, so a hovered link-button
   was reverting its label to brand blue against a dark fill. Pin the
   label to the variant's own foreground in every link state. */
.btn, .btn:link, .btn:visited, .btn:hover, .btn:active, .btn:focus { color: var(--btn-fg); }
.btn:hover { box-shadow: var(--elev-2); }
.btn:active { transform: translateY(1px) scale(.99); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; box-shadow: none; transform: none; }
.btn .icon { flex: none; }

.btn--primary { --btn-bg: var(--color-accent); --btn-fg: var(--color-text-on-yellow); --btn-bd: var(--color-text); }
.btn--primary:hover {
  --btn-bg: var(--color-text);
  --btn-fg: var(--color-accent);
  --btn-bd: var(--color-text);
}

.btn--brand { --btn-bg: var(--color-brand); --btn-fg: #fff; --btn-bd: var(--color-brand); }
.btn--brand:hover { --btn-bg: var(--color-brand-hover); --btn-bd: var(--color-brand-hover); }

.btn--outline { --btn-bg: transparent; --btn-fg: var(--color-text); --btn-bd: var(--color-text); }
.btn--outline:hover { --btn-bg: var(--color-text); --btn-fg: var(--color-accent); }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--color-text); --btn-bd: transparent; }
.btn--ghost:hover { --btn-bg: var(--grey-100); box-shadow: none; }

.btn--on-dark { --btn-bg: transparent; --btn-fg: #fff; --btn-bd: rgba(255,255,255,.5); }
.btn--on-dark:hover { --btn-bg: #fff; --btn-fg: var(--color-text); --btn-bd: #fff; }

.btn--lg { font-size: var(--fs-lg); padding: var(--space-4) var(--space-6); min-height: 3.5rem; }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* Back-to-centre control, always visible on branch panels */
.btn-back {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: var(--touch-min); padding: var(--space-2) var(--space-3);
  background: none; border: 0; cursor: pointer;
  color: var(--color-text-muted); font-family: var(--font-display);
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  border-radius: var(--radius-md);
  transition: color var(--dur-state) var(--ease-out), background-color var(--dur-state) var(--ease-out);
}
.btn-back:hover { color: var(--color-text); background: var(--grey-100); }
.btn-back .arrow { transition: transform var(--dur-state) var(--ease-out); }
.btn-back:hover .arrow { transform: translateX(-3px); }

/* ---------- Hero ---------- */
.hero { position: relative; padding-block: clamp(3rem, 9vw, 7rem) var(--section-y); overflow: hidden; }
.hero__grid { display: grid; gap: var(--space-7); align-items: center; }
@media (min-width: 940px) { .hero__grid { grid-template-columns: 1.15fr .85fr; gap: var(--space-8); } }
.hero .hero__title { max-width: 18ch; }
.hero--inverse { background: var(--color-surface-inverse); color: #fff; }
.hero--inverse .hero__title { color: #fff; }

/* Decorative field behind the home hero */
.hero > .container { position: relative; z-index: 1; }

/* ---------- The two-path chooser ---------- */
.paths { display: grid; gap: var(--space-5); }
@media (min-width: 860px) { .paths { grid-template-columns: 1fr 1fr; gap: var(--space-6); } }

.path-card {
  --path: var(--color-brand);
  --path-soft: var(--blue-50);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  background: var(--color-surface);
  border: var(--border-base) solid var(--color-border);
  border-radius: var(--radius-lg);
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--dur-state) var(--ease-out),
              box-shadow var(--dur-state) var(--ease-out),
              transform var(--dur-state) var(--ease-out);
}
.path-card::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: var(--path-soft); opacity: 0;
  transition: opacity var(--dur-state) var(--ease-out);
}
.path-card > * { position: relative; z-index: 1; }
.path-card:hover, .path-card:focus-visible {
  border-color: var(--path);
  box-shadow: var(--elev-3);
  transform: translateY(-4px);
}
.path-card:hover::before, .path-card:focus-visible::before { opacity: 1; }
.path-card:active { transform: translateY(-1px) scale(.995); }
.path-card--volunteer { --path: var(--path-volunteer); --path-soft: var(--path-volunteer-soft); }

.path-card__dir {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-size: var(--fs-label);
  font-weight: var(--fw-semibold); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--path);
}
.path-card h3 { font-size: var(--fs-2xl); margin: 0; }
.path-card p { color: var(--color-text-muted); margin: 0; max-width: 40ch; }
.path-card__list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-2); }
.path-card__list li { display: flex; gap: var(--space-3); align-items: flex-start; font-size: var(--fs-sm); color: var(--color-text-muted); margin: 0; }
.path-card__list svg { flex: none; margin-top: .28em; color: var(--path); }
.path-card__go {
  margin-top: auto; display: inline-flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-display); font-weight: var(--fw-bold); font-size: var(--fs-lg);
  color: var(--path);
}
.path-card__go .arrow { transition: transform var(--dur-move) var(--ease-spring); }
.path-card--left:hover  .path-card__go .arrow { transform: translateX(-8px); }
.path-card--right:hover .path-card__go .arrow { transform: translateX(8px); }

/* Edge glow hinting which way the site will move */
.path-card::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 5px; z-index: 1;
  background: var(--path); opacity: 0; transition: opacity var(--dur-state) var(--ease-out);
}
.path-card--left::after  { left: 0; }
.path-card--right::after { right: 0; }
.path-card:hover::after, .path-card:focus-visible::after { opacity: 1; }

/* ---------- Cards ---------- */
.card {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5);
  background: var(--color-surface);
  border: var(--border-hair) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-1);
  transition: box-shadow var(--dur-state) var(--ease-out), transform var(--dur-state) var(--ease-out),
              border-color var(--dur-state) var(--ease-out);
}
.card h3 { margin: 0; }
.card p { margin: 0; color: var(--color-text-muted); font-size: var(--fs-sm); line-height: var(--lh-loose); }

a.card, button.card { text-align: left; font: inherit; color: inherit; cursor: pointer; text-decoration: none; }
a.card:hover, button.card:hover, a.card:focus-visible, button.card:focus-visible {
  box-shadow: var(--elev-3); transform: translateY(-3px); border-color: var(--accent-line, var(--color-brand));
}
.card__top { display: flex; align-items: center; gap: var(--space-3); }
.card__icon {
  width: 44px; height: 44px; flex: none; display: grid; place-items: center;
  border-radius: var(--radius-md);
  background: var(--accent-soft, var(--blue-50));
  color: var(--accent-line, var(--color-brand));
  transition: transform var(--dur-state) var(--ease-spring),
              background-color var(--dur-state) var(--ease-out),
              color var(--dur-state) var(--ease-out);
}
a.card:hover .card__icon,
button.card:hover .card__icon,
a.card:focus-visible .card__icon {
  transform: scale(1.12) rotate(-6deg);
  background: var(--color-brand);
  color: #fff;
}
.panel--volunteer a.card:hover .card__icon,
.panel--volunteer button.card:hover .card__icon { background: var(--path-volunteer); }
.section--inverse a.card:hover .card__icon { background: var(--color-accent); color: var(--color-text-on-yellow); }
.card__more {
  margin-top: auto; padding-top: var(--space-2);
  font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-sm);
  color: var(--accent-line, var(--color-brand));
  display: inline-flex; align-items: center; gap: var(--space-2);
}
.card__more .arrow { transition: transform var(--dur-state) var(--ease-out); }
a.card:hover .card__more .arrow, button.card:hover .card__more .arrow { transform: translateX(4px); }

.panel--volunteer .card__icon { background: var(--path-volunteer-soft); color: var(--path-volunteer); }
.panel--volunteer .card__more { color: var(--path-volunteer); }
.panel--volunteer a.card:hover, .panel--volunteer button.card:hover { border-color: var(--path-volunteer); }

/* ---------- Numbered steps ---------- */
.steps { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-5); counter-reset: step; }
@media (min-width: 860px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.steps li { margin: 0; padding-top: var(--space-5); border-top: var(--border-heavy) solid var(--color-border); max-width: none; }
.steps li::before {
  counter-increment: step; content: counter(step);
  display: grid; place-items: center; width: 2.75rem; height: 2.75rem; margin-bottom: var(--space-3);
  background: var(--color-accent); color: var(--color-text-on-yellow);
  border: var(--border-base) solid var(--color-text);
  font-family: var(--font-display); font-weight: var(--fw-bold); border-radius: var(--radius-pill);
  transition: transform var(--dur-state) var(--ease-spring),
              box-shadow var(--dur-state) var(--ease-out);
}
.steps li {
  transition: transform var(--dur-state) var(--ease-out),
              border-top-color var(--dur-state) var(--ease-out);
}
.steps li:hover { transform: translateY(-4px); border-top-color: var(--color-brand); }
.steps li:hover::before { transform: scale(1.1) rotate(-6deg); box-shadow: var(--elev-2); }
.panel--volunteer .steps li:hover { border-top-color: var(--path-volunteer); }
.steps h3 { font-size: var(--fs-lg); margin-bottom: var(--space-2); }
.steps p { color: var(--color-text-muted); font-size: var(--fs-sm); margin: 0; }

/* ---------- Stat strip ---------- */
.stats { display: grid; gap: var(--space-5); }
@media (min-width: 700px) { .stats { grid-template-columns: repeat(3, 1fr); } }
.stat__num { font-family: var(--font-display); font-size: var(--fs-3xl); font-weight: var(--fw-bold);
  line-height: 1; letter-spacing: var(--tracking-tight); font-variant-numeric: tabular-nums; }
.stat__label { color: var(--color-text-muted); font-size: var(--fs-sm); margin: var(--space-2) 0 0; }
.panel--inverse .stat__label, .on-dark .stat__label { color: rgba(255,255,255,.72); }

/* ---------- Pull quote / callout ---------- */
.callout {
  border-left: 5px solid var(--color-accent);
  background: var(--grey-50);
  padding: var(--space-5) var(--space-6);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}
.callout p:last-child { margin-bottom: 0; }

/* ---------- Accordion (FAQ) ---------- */
.accordion { border-top: var(--border-hair) solid var(--color-border); }
.accordion details { border-bottom: var(--border-hair) solid var(--color-border); }
.accordion summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  min-height: var(--touch-min); padding: var(--space-4) 0;
  cursor: pointer; list-style: none;
  font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-lg);
  transition: color var(--dur-state) var(--ease-out);
}
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary:hover { color: var(--color-brand); }
.accordion summary .chev { flex: none; transition: transform var(--dur-state) var(--ease-out); color: var(--color-text-muted); }
.accordion details[open] summary .chev { transform: rotate(180deg); }
.accordion__body { padding-bottom: var(--space-5); }
.accordion__body p:last-child { margin-bottom: 0; }

/* ---------- Tag / pill ---------- */
.tags { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: 0; margin: 0; list-style: none; }
.tag {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  background: var(--grey-100); color: var(--color-text);
  border-radius: var(--radius-pill);
  font-size: var(--fs-label); font-weight: var(--fw-medium);
  white-space: normal;
  margin: 0;
}
.tag--brand { background: var(--blue-50); color: var(--blue-900); }
.tag--rust  { background: var(--rust-50); color: var(--rust-900); }

/* ---------- CTA band ---------- */
.cta-band {
  background: var(--color-brand); color: #fff;
  border-radius: var(--radius-xl);
  padding: clamp(2rem, 5vw, 3.5rem);
  display: grid; gap: var(--space-5); align-items: center;
}
@media (min-width: 900px) { .cta-band { grid-template-columns: 1.3fr .7fr; gap: var(--space-7); } }
.cta-band h2 { color: #fff; margin-bottom: var(--space-3); }
.cta-band p { color: rgba(255,255,255,.86); margin: 0; }
.cta-band--rust { background: var(--path-volunteer); }
.cta-band--ink  { background: var(--color-surface-inverse); }

/* ---------- Forms ---------- */
.form { display: grid; gap: var(--space-5); }
.field { display: grid; gap: var(--space-2); }
.field__label {
  font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-base);
  color: var(--color-text);
}
.field__req { color: var(--color-error); margin-left: 2px; }
.field__hint { font-size: var(--fs-sm); color: var(--color-text-muted); margin: 0; }
.field input, .field select, .field textarea {
  width: 100%;
  min-height: 3rem;
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-body);
  font-size: max(1rem, var(--fs-base));
  color: var(--color-text);
  background: var(--color-surface);
  border: var(--border-base) solid var(--color-border);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-state) var(--ease-out), box-shadow var(--dur-state) var(--ease-out);
}
.field textarea { min-height: 8rem; resize: vertical; line-height: var(--lh-body); }
.field select {
  appearance: none;
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  padding-right: var(--space-8);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23626876' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--grey-300); }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--color-brand); box-shadow: 0 0 0 3px var(--blue-100); outline: none;
}
.field--invalid input, .field--invalid select, .field--invalid textarea { border-color: var(--color-error); }
.field--invalid input:focus, .field--invalid textarea:focus { box-shadow: 0 0 0 3px var(--color-error-bg); }
.field__error {
  display: none; align-items: flex-start; gap: var(--space-2);
  color: var(--color-error); font-size: var(--fs-sm); font-weight: var(--fw-medium); margin: 0;
}
.field--invalid .field__error { display: flex; }
.field__error svg { flex: none; margin-top: .2em; }

.checkgrid { display: grid; gap: var(--space-2); }
@media (min-width: 640px) { .checkgrid { grid-template-columns: 1fr 1fr; } }
.check {
  display: flex; align-items: flex-start; gap: var(--space-3);
  min-height: var(--touch-min); padding: var(--space-3);
  border: var(--border-hair) solid var(--color-border); border-radius: var(--radius-md);
  cursor: pointer; font-size: var(--fs-sm);
  transition: border-color var(--dur-state) var(--ease-out), background-color var(--dur-state) var(--ease-out);
}
.check:hover { border-color: var(--grey-300); background: var(--grey-50); }
.check input { width: 1.25rem; height: 1.25rem; min-height: 0; margin: 0; flex: none; accent-color: var(--color-brand); }
.check:has(input:checked) { border-color: var(--color-brand); background: var(--blue-50); }
.check:has(input:focus-visible) { outline: 3px solid var(--color-focus); outline-offset: 2px; }

fieldset { border: 0; padding: 0; margin: 0; display: grid; gap: var(--space-3); }
legend { padding: 0; font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-base); }

.hp { position: absolute; left: -9999px; opacity: 0; height: 0; overflow: hidden; }

.form__status { display: grid; gap: var(--space-2); }
.alert {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-4); border-radius: var(--radius-md);
  border: var(--border-hair) solid transparent; font-size: var(--fs-sm);
}
.alert svg { flex: none; margin-top: .15em; }
.alert p { margin: 0; }
.alert--error   { background: var(--color-error-bg); border-color: var(--color-error); color: var(--rust-900); }
.alert--success { background: var(--color-success-bg); border-color: var(--color-success); color: #0B4A25; }
.alert--error a { color: var(--color-error); }
.alert ul { margin: var(--space-2) 0 0; padding-left: 1.1em; }

.form-success {
  display: grid; gap: var(--space-3); justify-items: start;
  padding: var(--space-6);
  background: var(--color-success-bg);
  border: var(--border-base) solid var(--color-success);
  border-radius: var(--radius-lg);
}
.form-success h3 { margin: 0; color: #0B4A25; }
.form-success p { margin: 0; color: #14532D; }

/* Spinner used inside submitting buttons */
.spinner {
  width: 1.1em; height: 1.1em; flex: none;
  border: 2.5px solid currentColor; border-right-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Newsletter band ----------
   A light band that closes every panel. Its job is structural as much as
   editorial: it puts a light surface between the last content section and
   the footer, so a dark content band can never run straight into the
   footer and read as one continuous block. */
.subscribe-band {
  background: var(--blue-50);
  border-top: var(--border-heavy) solid var(--color-text);
  padding-block: clamp(2.25rem, 5vw, 3.5rem);
}
.subscribe-band__grid { display: grid; gap: var(--space-5); }
@media (min-width: 900px) {
  .subscribe-band__grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-8);
    align-items: center;
  }
}
.subscribe-band h2 { font-size: var(--fs-xl); margin-bottom: var(--space-2); }
/* Scoped away from .eyebrow, which is also a <p>: the blanket rule was
   zeroing the eyebrow's bottom margin and overriding its label size,
   which left it sitting hard against the heading below. */
.subscribe-band p:not(.eyebrow) { color: var(--color-text-muted); font-size: var(--fs-sm); margin: 0; max-width: 44ch; }
.subscribe-band .form { gap: var(--space-3); }

/* The volunteer branch keeps its own hue right to the end of the page. */
.panel--volunteer .subscribe-band { background: var(--rust-50); }

/* ---------- Meeting / booking block ---------- */
.booking {
  display: grid; gap: var(--space-4);
  padding: var(--space-6);
  border: var(--border-base) dashed var(--color-rule);
  border-radius: var(--radius-lg);
  background: var(--color-bg-sunken);
}
.booking h3 { margin: 0; }
.booking p { margin: 0; color: var(--color-text-muted); font-size: var(--fs-sm); }

/* ---------- Contact strip ---------- */
.contact-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-4); }
.contact-list li { display: flex; gap: var(--space-3); align-items: flex-start; margin: 0; }
.contact-list svg { flex: none; margin-top: .2em; color: var(--color-brand); }


/* ---------- Detail panels ---------- */
.detail__hero { padding-block: clamp(2.5rem, 6vw, 4.5rem) var(--space-6); }
.detail__hero .hero__title { max-width: 16ch; }
/* A detail hero has no card beside it, so the lede would otherwise run to
   the full 58ch of the base rule, which is a long measure at --fs-lg and
   pushed body copy under the hero motif. 50ch tightens the line and keeps
   the type column clear of the mask without a per-panel mask exception. */
.detail__hero .lede { max-width: 50ch; }

/* The body sat flush against the tinted hero, because padding-top was
   zeroed and the hero's own padding stops at its edge. The bottom is the
   opposite problem: .section already contributes --section-y here and the
   CTA section contributes another below it, so the two stacked to roughly
   190px of dead space under a column that often ends early. */
.detail__grid {
  display: grid;
  gap: var(--space-7);
  align-items: start;
  padding-top: var(--space-7);
  padding-bottom: var(--space-6);
}
@media (min-width: 940px) { .detail__grid { grid-template-columns: 1.25fr .75fr; gap: var(--space-8); } }

.detail__main { display: grid; gap: var(--space-6); }
.detail__section h2 { font-size: var(--fs-xl); margin-bottom: var(--space-3); }
.detail__section p { font-size: var(--fs-lg); line-height: var(--lh-loose); color: var(--color-text-muted); margin: 0; }

.detail__aside { display: grid; gap: var(--space-5); }
.detail__list-block,
.detail__facts {
  padding: var(--space-5);
  background: var(--color-bg-sunken);
  border: var(--border-hair) solid var(--color-border);
  border-radius: var(--radius-lg);
}
.detail__list-block h3,
.detail__facts h3 {
  font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); color: var(--color-text-muted);
  margin-bottom: var(--space-4);
}
.ticklist { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-3); }
.ticklist li { display: flex; gap: var(--space-3); align-items: flex-start; margin: 0; font-size: var(--fs-sm); line-height: var(--lh-body); }
.ticklist svg { flex: none; margin-top: .15em; color: var(--color-brand); }
.panel--volunteer .ticklist svg { color: var(--path-volunteer); }

.detail__facts dl { margin: 0; display: grid; gap: var(--space-4); }
.detail__facts dt {
  display: flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-sm);
  margin-bottom: var(--space-1);
}
.detail__facts dt svg { color: var(--color-text-muted); }
.detail__facts dd { margin: 0; font-size: var(--fs-sm); color: var(--color-text-muted); }
.detail__facts p { display: flex; gap: var(--space-3); align-items: flex-start; font-size: var(--fs-sm); color: var(--color-text-muted); }
.detail__facts p svg { flex: none; margin-top: .15em; }

/* (The newsletter form moved out of the footer — see .subscribe-band.) */

/* ---------- Hero summary card ---------- */
.hero-card {
  background: var(--color-surface);
  border: var(--border-base) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-2);
  padding: var(--space-5) var(--space-6) var(--space-6);
}
.hero-card .eyebrow { margin-bottom: var(--space-2); }
.hero-card .stats { grid-template-columns: 1fr; gap: 0; }
.hero-card .stats > div { padding-block: var(--space-4); }
.hero-card .stats > div + div { border-top: var(--border-hair) solid var(--color-border); }
.hero-card .stat__num { font-size: var(--fs-2xl); color: var(--color-brand); }
.hero-card .stat__label { font-size: var(--fs-base); color: var(--color-text); max-width: 34ch; }

/* ---------- Hero fact list (branch heroes) ---------- */
.factlist {
  list-style: none; padding: var(--space-5); margin: 0;
  display: grid; gap: var(--space-4);
  background: var(--color-surface);
  border: var(--border-base) solid var(--color-border);
  border-left: 5px solid var(--color-brand);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-2);
}
.factlist--volunteer { border-left-color: var(--path-volunteer); }
.factlist li { display: flex; gap: var(--space-4); align-items: flex-start; margin: 0; }
.factlist svg { flex: none; margin-top: .15em; color: var(--color-brand); }
.factlist--volunteer svg { color: var(--path-volunteer); }
.factlist strong {
  display: block; font-family: var(--font-display); font-weight: var(--fw-semibold);
  font-size: var(--fs-base); margin-bottom: 2px;
}
.factlist span { display: block; font-size: var(--fs-sm); color: var(--color-text-muted); line-height: var(--lh-body); }

/* Branch heroes sit in a two-column grid, so their headline needs a
 step down from the full display size used on the home panel. */
.panel--campaign .hero .hero__title,
.panel--volunteer .hero .hero__title { font-size: var(--fs-3xl); max-width: 15ch; }
.detail__hero .hero__title { font-size: var(--fs-3xl); }


/* ============================================================
   PATCH 1.1 — colour containment, alignment, hover life
   ============================================================ */

/* ---------- Newsletter: input and button share a row and a height ----------
   The whole block keeps the .field class so the validation logic still
   finds its error node; the grid areas do the alignment. */
.subscribe__field {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "label label"
    "input button"
    "error error";
  column-gap: var(--space-3);
  row-gap: var(--space-2);
  align-items: stretch;
}
.subscribe__field > .field__label { grid-area: label; }
.subscribe__field > input        { grid-area: input; margin: 0; }
.subscribe__field > .field__error { grid-area: error; }
.subscribe__btn {
  grid-area: button;
  margin: 0;
  min-height: 0;
  height: 100%;
  white-space: nowrap;
}
@media (max-width: 699px) {
  .subscribe__field {
    grid-template-columns: 1fr;
    grid-template-areas: "label" "input" "button" "error";
  }
  .subscribe__btn { height: 3.25rem; }
}

/* The subscribe button is a normal primary action on a light band, so it
   keeps the standard ink border and inverting hover. */

/* ---------- Ambient hover on informational blocks ---------- */
.factlist li {
  transition: transform var(--dur-state) var(--ease-out);
}
.factlist li:hover { transform: translateX(4px); }
.factlist li svg { transition: transform var(--dur-state) var(--ease-spring); }
.factlist li:hover svg { transform: scale(1.15); }

.callout {
  transition: transform var(--dur-state) var(--ease-out),
              box-shadow var(--dur-state) var(--ease-out);
}
.callout:hover { transform: translateX(4px); box-shadow: var(--elev-2); }

.detail__list-block,
.detail__facts {
  transition: border-color var(--dur-state) var(--ease-out),
              box-shadow var(--dur-state) var(--ease-out);
}
.detail__list-block:hover,
.detail__facts:hover { border-color: var(--color-rule); box-shadow: var(--elev-1); }

.ticklist li { transition: transform var(--dur-state) var(--ease-out); }
.ticklist li:hover { transform: translateX(3px); }

.hero-card .stats > div {
  transition: transform var(--dur-state) var(--ease-out);
}
.hero-card .stats > div:hover { transform: translateX(4px); }

.accordion summary .chev { transition: transform var(--dur-state) var(--ease-spring); }
.accordion summary:hover .chev { transform: translateY(3px); }
.accordion details[open] summary:hover .chev { transform: rotate(180deg) translateY(3px); }

.tag { transition: background-color var(--dur-state) var(--ease-out), transform var(--dur-state) var(--ease-out); }

.rail__btn { transition: color var(--dur-state) var(--ease-out), transform var(--dur-micro) var(--ease-out); }
.rail__btn:active { transform: scale(.97); }

.brand__mark { transition: transform var(--dur-state) var(--ease-spring); }
.brand:hover .brand__mark { transform: translateY(-3px) rotate(-4deg); }

/* ---------- Detail views carry their branch colour ---------- */
.panel--campaign .detail__hero { background: var(--path-campaign-soft); }
.panel--volunteer .detail__hero { background: var(--path-volunteer-soft); }
.panel--campaign .detail__hero,
.panel--volunteer .detail__hero {
  border-bottom: var(--border-hair) solid var(--color-border);
  padding-bottom: var(--space-7);
}

/* Reduced motion strips every ambient hover added above. */
@media (prefers-reduced-motion: reduce) {
  .steps li:hover,
  .factlist li:hover,
  .callout:hover,
  .ticklist li:hover,
  .hero-card .stats > div:hover { transform: none; }
  .steps li:hover::before,
  .factlist li:hover svg,
  .accordion summary:hover .chev,
  .brand:hover .brand__mark,
  a.card:hover .card__icon,
  button.card:hover .card__icon { transform: none; }
  .footer a::after { transition: none; }
}

/* The back control's arrow leans the way the site will travel. */
.btn-back--east:hover .arrow { transform: translateX(3px); }
.btn-back--east:hover .arrow,
.btn-back:hover .arrow { transition: transform var(--dur-state) var(--ease-out); }
@media (prefers-reduced-motion: reduce) {
  .btn-back:hover .arrow, .btn-back--east:hover .arrow { transform: none; }
}

/* Footer list rows: icon and label on one line, long addresses wrap. */
/* Centred rather than top-aligned. The links carry a 44px minimum height
   for tap targets, so their text sits in the middle of a box taller than
   itself, and a top-aligned icon with a hand-tuned nudge no longer lined
   up with it. Centring both needs no magic number and follows the link if
   its height changes again. The labels do not wrap down to 320px, which
   is narrower than any real phone, so first-line alignment is not a case
   that arises here. */
.footer li { display: flex; align-items: center; gap: var(--space-2); }
.footer li svg { flex: none; opacity: .8; }
.footer li a { overflow-wrap: anywhere; min-width: 0; }


/* ============================================================
   PATCH 1.2 — art direction
   ------------------------------------------------------------
   Two kinds of imagery:

   1. Generated motifs (.artfield) — one parameterised family,
      seeded per page so each view has its own stable artwork.
      Grid = precinct/turf, rising lines = turnout, nodes =
      contacts made. See js/artwork.js.
   2. Photography (.section--photo) — duotoned into the palette
      so a photograph reads as art-directed rather than dropped
      in, with a scrim sized for text contrast.
   ============================================================ */

/* ---------- Generated motifs ---------- */
.artfield {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  color: var(--color-text);
}
.artfield .af { display: block; width: 100%; height: 100%; }

.af-cell        { fill: currentColor; opacity: .22; }
.af-cell--on    { fill: var(--art-accent, var(--color-brand)); opacity: .62; }
.af-path        { fill: none; stroke: currentColor; stroke-width: 1.8; opacity: .28; }
.af-path--lead  { stroke: var(--art-accent, var(--color-brand)); stroke-width: 2.6; opacity: .55; }
.af-node        { fill: var(--color-accent); stroke: var(--color-text); stroke-width: 1.8; }

/* Each branch tints its own artwork. */
.panel--campaign  { --art-accent: var(--path-campaign); }
.panel--volunteer { --art-accent: var(--path-volunteer); }
.path-card--volunteer { --art-accent: var(--path-volunteer); }

/* Behind a hero: strongest on the side away from the type. */
.artfield--hero {
  opacity: .95;
  /* A single radial mask weighted to the right of the frame. One layer,
     so there is no mask-composite support to depend on, and it falls off
     in every direction, so the motif never reaches the type. The centre
     sits at 92%, inside the frame: at 104% the densest part of the field
     was off-canvas and every visible pixel was falloff.

     The horizontal radius is set from measurement rather than taste. At
     68% the mask was still ~23% opaque where the lede ends, and the lead
     trend line crossing body copy there measured 3.6:1 against the 4.5:1
     floor in the design system. 46% puts the transparent stop at 56.1% of
     the frame, which clears every hero lede on the site. Re-measure if any
     lede's max-width ever changes. */
  -webkit-mask-image: radial-gradient(46% 112% at 92% 50%, #000 16%, rgba(0,0,0,.62) 46%, transparent 78%);
          mask-image: radial-gradient(46% 112% at 92% 50%, #000 16%, rgba(0,0,0,.62) 46%, transparent 78%);
}
@media (max-width: 899px) {
  /* Type runs full width on a phone, so the motif retreats to the floor
     and drops to a level where it cannot compete with body copy. */
  .artfield--hero {
    opacity: .3;
    -webkit-mask-image: linear-gradient(to bottom, transparent 62%, #000 100%);
            mask-image: linear-gradient(to bottom, transparent 62%, #000 100%);
  }
  .artfield--hero .af-node { display: none; }
}

/* Inside a path card: a corner wash that never reaches the copy. */
.path-card > .artfield--card {
  position: absolute;
  z-index: 0;
  opacity: .8;
  -webkit-mask-image: radial-gradient(130% 105% at 100% 100%, #000 0%, transparent 60%);
          mask-image: radial-gradient(130% 105% at 100% 100%, #000 0%, transparent 60%);
}
.path-card:hover > .artfield--card { opacity: 1; }
.path-card > .artfield--card,
.path-card:hover > .artfield--card { transition: opacity var(--dur-state) var(--ease-out); }

/* Detail heroes need a positioning context for their motif. */
.detail__hero { position: relative; overflow: hidden; }
.detail__hero > .container { position: relative; z-index: 1; }

/* Motifs on dark ground: no ink outline on the nodes, it disappears. */
.section--inverse .af-node,
.section--photo .af-node { stroke: none; }
.section--inverse .af-cell--on,
.section--photo .af-cell--on { fill: var(--color-accent); opacity: .55; }

/* The lines draw themselves in once, then stop. */
.js .af-grid  { opacity: 0; animation: af-fade 900ms var(--ease-out) 120ms forwards; }
.js .af-nodes { opacity: 0; animation: af-fade 600ms var(--ease-out) 1000ms forwards; }
.js .af-path  {
  stroke-dasharray: 1600;
  stroke-dashoffset: 1600;
  animation: af-draw 1800ms var(--ease-out) 220ms forwards;
}
@keyframes af-fade { to { opacity: 1; } }
@keyframes af-draw { to { stroke-dashoffset: 0; } }

/* ---------- Photography ---------- */
.section--photo {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.section__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  isolation: isolate;   /* contains the duotone blend */
}
.section__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The subject is the crowd and the signs, low in the frame — not the
     rooftops. Bias the crop downward. */
  object-position: 50% 60%;
  filter: grayscale(1) contrast(1.16) brightness(.86);
}
/* Duotone: greyscale underneath, brand hue laid over with the colour
   blend mode, which keeps the photograph's luminance intact. */
.section__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--tpt-blue);
  mix-blend-mode: color;
  opacity: .7;
}
@supports not (mix-blend-mode: color) {
  .section__media::after { background: rgba(10,44,202,.42); mix-blend-mode: normal; }
}
/* Legibility scrim, sized so body copy clears 4.5:1 over the busiest
   part of the frame. Horizontal on desktop where type sits left. */
.section--photo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(95deg, rgba(11,7,7,.95) 0%, rgba(11,7,7,.88) 42%, rgba(11,7,7,.40) 100%),
    linear-gradient(to bottom, rgba(11,7,7,.5) 0%, rgba(11,7,7,.06) 100%);
}
@media (max-width: 899px) {
  .section--photo::after {
    background: linear-gradient(to bottom, rgba(11,7,7,.9) 0%, rgba(11,7,7,.86) 55%, rgba(11,7,7,.92) 100%);
  }
  .section__media img { object-position: 50% 30%; }
}
.section--photo > .container { position: relative; z-index: 2; }

/* Cards floating on a photograph need a real surface, not a 6% wash. */
.section--photo .card {
  background: rgba(9,6,6,.74);
  border-color: rgba(255,255,255,.24);
  backdrop-filter: blur(7px) saturate(1.1);
}
@supports not (backdrop-filter: blur(2px)) {
  .section--photo .card { background: rgba(9,6,6,.9); }
}

.section__credit {
  margin-top: var(--space-5);
  font-size: var(--fs-label);
  letter-spacing: .02em;
  color: rgba(255,255,255,.62);
}

/* ---------- Logo motion: the arrow lifts off its floor ---------- */
.brand:hover .brand__mark { transform: none; }
.brand__arrow { transition: transform var(--dur-move) var(--ease-spring); }
.brand:hover .brand__arrow,
.brand:focus-visible .brand__arrow { transform: translateY(-5px); }

/* ---------- Mobile home: the fork comes first ---------- */
@media (max-width: 600px) {
  /* A 40px headline over five lines was pushing the fork off the second
     screen. Stepping it down buys a whole line back. */
  .panel--home .hero .hero__title { font-size: clamp(2rem, 8.4vw, 2.75rem); }
  .panel--home .hero { padding-block: var(--space-5) var(--space-6); }
  .panel--home .hero__grid { gap: var(--space-5); }
}
/* The "At a glance" card is desktop only. On a phone it pushed the fork,
   which is the whole point of the home page, roughly two screens down,
   and all three of its facts are carried elsewhere: the fork states the
   two ways in, the campaigns branch states the cost, and both the header
   and the hero lede state the region. Hidden rather than re-sequenced, so
   it is out of the reading order for everyone on a phone rather than
   being announced to screen readers but skipped by everyone else. */
@media (max-width: 899px) {
  .panel--home .hero-aside { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .js .af-grid, .js .af-nodes { opacity: 1; animation: none; }
  .js .af-path { stroke-dashoffset: 0; animation: none; }
  .brand:hover .brand__arrow { transform: none; }
}
