/* transitpipeline-web — single-page styles. No framework, no build step.
   COLOR SYSTEM: every color on the page is defined once in :root below and
   referenced via var(). Never hardcode a hex in a rule. Line palette is
   derived from the Transit Automations brand blue in OKLCH (derivation in
   docs/build_docs/color-pass-report.md, per-hue tuning in
   docs/build_docs/shuttle-pass-report.md).
   TYPE SYSTEM: self-hosted Barlow (OFL; license in assets/fonts/OFL.txt).
   Barlow Semi Condensed carries display duty, Barlow carries text. Scale
   and rhythm live in :root variables alongside the palette. */

/* ---------- Self-hosted fonts (latin subsets, ~16 KB each) ---------- */

@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/Barlow-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/Barlow-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('assets/fonts/Barlow-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('assets/fonts/BarlowSemiCondensed-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('assets/fonts/BarlowSemiCondensed-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* TA neutral family (anchors) */
  --bg: #111111;
  --bg-card: #1A1A1A;
  --border: #333333;
  --text: #FFFFFF;
  --muted: #B0B0B0;

  /* Brand blues (anchors). --brand fails AA for text on --bg (2.98:1):
     non-text use only (fills, borders, the loop line). --brand-bright is
     the text-safe accent (5.59:1). */
  --brand: #0D5DBC;
  --brand-bright: #4D8FD6;
  --brand-soft: rgba(13, 93, 188, 0.16);

  /* Transit line palette, derived from --brand in OKLCH, tuned per-hue
     for perceptual parity (pass 2). All five pass AA (>=4.5:1) against
     --bg at text size. */
  --line-red: #EB4E43;     /* oklch(0.640 0.195 28) */
  --line-orange: #D98941;  /* oklch(0.700 0.131 60) */
  --line-yellow: #DABC43;  /* oklch(0.800 0.140 95) */
  --line-green: #39B26F;   /* oklch(0.680 0.146 155) */
  --line-blue: #569AEF;    /* oklch(0.680 0.144 255) */

  /* Semantic states */
  --error: var(--line-red);
  --error-soft: rgba(235, 78, 67, 0.09);
  --success: var(--line-green);

  /* Canonical shuttle glyph neutrals (Ben-approved artwork, pass 4).
     Glyph-scoped: used nowhere else on the page. */
  --shuttle-body: #E9EBEE;
  --shuttle-skirt: #C2C7CD;
  --shuttle-ink: #1B1D20;
  --shuttle-tire: #4A4E55;
  --shuttle-hub: #C9CDD3;
  --shuttle-hubdot: #8E959E;

  /* Type system */
  --font-display: 'Barlow Semi Condensed', 'Avenir Next Condensed', 'Arial Narrow', system-ui, sans-serif;
  --font-text: 'Barlow', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --type-hero: clamp(2.6rem, 2vw + 1.4rem, 3.5rem);
  --type-h2: clamp(1.75rem, 3.4vw, 2.3rem);
  --type-h3: 1.3rem;
  --type-lede: clamp(1.1rem, 2vw, 1.3rem);
  --type-body: 1.0625rem;
  --type-small: 0.9rem;
  --type-meta: 0.8125rem;
  --track-display: -0.015em;
  --track-caps: 0.16em;
  --leading-hero: 1.02;
  --leading-head: 1.12;
  --leading-body: 1.6;

  /* Spacing / rhythm */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;
  --section-pad: clamp(3rem, 7vw, 4.5rem);
  --gutter: clamp(1.5rem, 5vw, 3rem);
  --wrap-max: 70rem;
  --block-max: 40rem;    /* form panels, callout: content blocks on the rail */
  --measure: 62ch;       /* body copy cap */
  --radius: 6px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-text);
  font-size: var(--type-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--brand); color: var(--text); }

/* One grid: a single container, a single left rail. Sections cap their
   own content blocks (--measure / --block-max) but never re-center on a
   different implied column. */
.wrap {
  max-width: var(--wrap-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.wrap.narrow > * { max-width: var(--block-max); }

p { max-width: var(--measure); }

a { color: var(--brand-bright); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 {
  font-family: var(--font-display);
  letter-spacing: var(--track-display);
  line-height: var(--leading-head);
  margin: 0;
}

/* ---------- Hero (five rotating states synced to the shuttle) ---------- */

.hero { padding: clamp(2.5rem, 6vh, 4rem) 0 0; }

/* Opening composition: single column stacked by default; text left / map
   right on wide screens so the headline and the moving loop share the
   first viewport. */
.hero-grid { display: grid; gap: var(--sp-6); }

@media (min-width: 1080px) {
  .hero-grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    column-gap: var(--sp-7);
    align-items: center;
  }
}

/* Below the map-swap breakpoint the stacked hero tightens: the fixed 2rem
   gap read as dead air above the (now much shorter) mobile map. Scales
   with the viewport and reaches 2rem again by 640px, so nothing jumps at
   the 720px swap or 1080px two-column boundaries (mobile map pass,
   2026-08-19). */
@media (max-width: 719px) {
  .hero-grid { gap: clamp(1rem, 5vw, 2rem); }
}

.brand {
  margin: 0 0 var(--sp-6);
  font-family: var(--font-text);
  font-size: var(--type-meta);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--brand-bright);
}

/* All five states occupy the same grid cell, so the block's height is
   always the tallest state at every breakpoint: zero layout shift when
   states change. States 2-5 are opacity-hidden by default (no-JS,
   reduced-motion, blocked-CDN all render state 1 statically); opacity
   keeps every state readable to assistive tech in source order. */
.hero-states { display: grid; }

.hero-state {
  grid-area: 1 / 1;
  opacity: 0;
  pointer-events: none;
}

.hero-state:first-child { opacity: 1; pointer-events: auto; }

/* The one permitted affordance: a short stop-colored rule tying the
   state to its station. */
.line-tag {
  display: block;
  width: 34px;
  height: 4px;
  border-radius: 2px;
  margin: 0 0 var(--sp-4);
  background: var(--brand);
}

.hero-state[data-line="green"]  .line-tag { background: var(--line-green); }
.hero-state[data-line="orange"] .line-tag { background: var(--line-orange); }
.hero-state[data-line="red"]    .line-tag { background: var(--line-red); }
.hero-state[data-line="blue"]   .line-tag { background: var(--line-blue); }
.hero-state[data-line="yellow"] .line-tag { background: var(--line-yellow); }

.hero-state h1, .hero-h {
  margin: 0 0 var(--sp-5);
  font-family: var(--font-display);
  font-size: var(--type-hero);
  font-weight: 700;
  line-height: var(--leading-hero);
  letter-spacing: var(--track-display);
  color: var(--text);
  max-width: 18ch;
}

.subline {
  margin: 0;
  max-width: 52ch;
  font-size: var(--type-lede);
  line-height: 1.5;
  color: var(--muted);
}

/* ---------- Route map (lives inside the hero grid) ---------- */

.route-map { padding: 0; }

.map { width: 100%; height: auto; display: block; }

.map-wide { max-width: 640px; margin: 0 auto; }

.map-tall { display: none; max-width: 400px; margin: 0 auto; }

@media (max-width: 719px) {
  .map-wide { display: none; }
  .map-tall { display: block; }
}

/* Treatment: colored stations. The loop stays restrained brand blue; each
   stop takes one line color via its --stop-color custom property. */

.route-path {
  fill: none;
  stroke: var(--brand);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Mobile map proportions (mobile map pass, 2026-08-19): the squat mobile
   loop is ~0.7x the desktop loop's user-unit size, so the route stroke and
   stop rings scale down with it and the map keeps desktop's proportions
   relative to the loop. .map-tall only ever displays at <=719px, so these
   cannot touch the desktop render. */
.map-tall .route-path { stroke-width: 4; }

.stop--green  { --stop-color: var(--line-green); }
.stop--orange { --stop-color: var(--line-orange); }
.stop--red    { --stop-color: var(--line-red); }
.stop--blue   { --stop-color: var(--line-blue); }
.stop--yellow { --stop-color: var(--line-yellow); }

.stop circle:not(.stop-hit) {
  fill: var(--bg);
  stroke: var(--stop-color, var(--brand-bright));
  stroke-width: 4;
}

.map-tall .stop circle:not(.stop-hit) { stroke-width: 3; }

.stop text {
  fill: var(--stop-color, var(--text));
  font-family: var(--font-text);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.map-tall .stop text { font-size: 17px; }

/* Labels-VISIBLE is the default state (pass 7): no-JS, blocked-CDN and
   reduced-motion all render the complete labeled map with zero work.
   The inline head script adds html.labels-pending before first paint
   only when JS+motion will run, and main.js removes it once the debark
   choreography owns label visibility. Never "fix" the default by hiding
   labels here. */
html.labels-pending .map .stop text { opacity: 0; }

/* Stops are interactive controls (pass 6): JS upgrades them with
   role=button/tabindex and the .tappable class; the markup itself stays
   non-interactive so no-JS renders a static map. The .stop-hit circle is
   an invisible >=44px touch target; visible circles are unchanged. */

.stop-hit { fill: transparent; stroke: none; pointer-events: all; }

.stop.tappable { cursor: pointer; }

.stop.tappable:hover circle:not(.stop-hit) { r: 11.5; }
.map-tall .stop.tappable:hover circle:not(.stop-hit) { r: 8; }
.stop.tappable:hover text { fill: var(--text); }

@media (prefers-reduced-motion: no-preference) {
  .stop.tappable circle:not(.stop-hit) { transition: r 150ms ease-out; }
  .stop.tappable text { transition: fill 150ms ease-out; }
}

.stop.tappable:focus-visible {
  outline: 2px solid var(--brand-bright);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Scroll reveals (pass 6): JS adds .reveal only when motion is allowed,
   so the default render (no-JS, reduced motion) is fully visible. */
.reveal { opacity: 0; transform: translateY(14px); }
.reveal.revealed { opacity: 1; transform: none; }

@media (prefers-reduced-motion: no-preference) {
  .reveal.revealed { transition: opacity 550ms ease-out, transform 550ms ease-out; }
  .beats-grid .beat.reveal.revealed:nth-child(2) { transition-delay: 90ms; }
  .beats-grid .beat.reveal.revealed:nth-child(3) { transition-delay: 180ms; }
}

/* The shuttle glyph: Ben-approved canonical artwork (pass 4) — do not
   redraw without a new approved reference. Decorative; parked at Early
   Signals by a static transform in the markup. All movement is GSAP-driven
   from main.js and happens only when motion is allowed AND the GSAP CDN
   loaded — the default render (no JS, reduced motion, blocked CDN) is the
   complete static map with the shuttle parked. Line draw is coupled to the
   shuttle's path progress in main.js; see
   docs/build_docs/shuttle-pass-report.md before touching either. The
   wheel-arch circles (.sh-arch) assume the #111111 page background: they
   punch the wheel wells out of the body visually. */

.sh-body { fill: var(--shuttle-body); stroke: var(--shuttle-ink); }
.sh-skirt { fill: var(--shuttle-skirt); }
.sh-glass { fill: var(--brand-bright); stroke: var(--shuttle-ink); }
.sh-ink { stroke: var(--shuttle-ink); }
.sh-headlight { fill: var(--line-yellow); stroke: var(--shuttle-ink); }
.sh-marker { fill: var(--line-orange); stroke: var(--shuttle-ink); }
.sh-bumper { fill: var(--shuttle-ink); }
.sh-arch { fill: var(--bg); }
.sh-tire { fill: var(--shuttle-ink); stroke: var(--shuttle-tire); }
.sh-hub { fill: var(--shuttle-hub); stroke: var(--shuttle-ink); }
.sh-hubdot { fill: var(--shuttle-hubdot); }

/* Figure caption under the map (Part C, pass 4; copy is DRAFT in COPY.md). */
.map-caption {
  margin: var(--sp-4) auto 0;
  max-width: none;
  text-align: center;
  color: var(--muted);
  font-size: var(--type-meta);
  letter-spacing: 0.01em;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ---------- Problem beats ---------- */

/* Sections pad on top only, so the gap between any two sections is one
   consistent interval rather than two stacked pads. */
.beats { padding: var(--section-pad) 0 0; }

.beats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-5);
}

@media (max-width: 719px) {
  .beats-grid { grid-template-columns: 1fr; }
}

.beat {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-6) var(--sp-6) var(--sp-6);
}

/* The one deliberate line-color echo outside the map: beat-card top
   accents mirror the first three stops (green, orange, red). */
.beats-grid .beat:nth-child(1) { border-top-color: var(--line-green); }
.beats-grid .beat:nth-child(2) { border-top-color: var(--line-orange); }
.beats-grid .beat:nth-child(3) { border-top-color: var(--line-red); }

.beat h2 {
  margin: 0 0 var(--sp-3);
  font-size: var(--type-h3);
  font-weight: 600;
}

.beat p { margin: 0; color: var(--muted); font-size: var(--type-small); line-height: 1.55; }

/* ---------- Access model ---------- */

.access { padding: var(--section-pad) 0 0; }

.access h2, .interest h2 {
  font-size: var(--type-h2);
  font-weight: 600;
  margin: 0 0 var(--sp-5);
}

.access p { color: var(--muted); margin: 0 0 var(--sp-4); }

.access .plain {
  color: var(--text);
  font-weight: 500;
  border-left: 3px solid var(--brand);
  padding: var(--sp-4) var(--sp-5);
  background: var(--brand-soft);
  border-radius: 0 var(--radius) var(--radius) 0;
  max-width: var(--block-max);
}

/* Wide screens: intro text left, the not-access callout right, so the
   section earns its width without diluting the callout's prominence. */
@media (min-width: 1080px) {
  .access .wrap.narrow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--sp-7);
    align-items: center;
  }
  .access h2 { grid-column: 1; }
  .access p:not(.plain) { grid-column: 1; margin-bottom: 0; }
  .access .plain { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
}

/* ---------- Form ---------- */

.interest { padding: var(--section-pad) 0 var(--sp-9); }

.form-intro { color: var(--muted); margin: 0 0 var(--sp-6); }

/* Wide screens: section head + intro on the left rail, fields on the
   right, so the form section fills the container width. */
@media (min-width: 1080px) {
  .interest .wrap.narrow > #form-panel { max-width: none; }
  #form-panel {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    column-gap: var(--sp-8);
    align-items: start;
  }
  #form-panel > h2 { grid-column: 1; }
  #form-panel > .form-intro { grid-column: 1; max-width: 36ch; }
  #form-panel > form { grid-column: 2; grid-row: 1 / span 2; max-width: 42rem; }
}

#interest-form { display: grid; grid-template-columns: 1fr; column-gap: var(--sp-5); }

@media (min-width: 720px) {
  #interest-form { grid-template-columns: 1fr 1fr; }
  #interest-form > * { grid-column: 1 / -1; }
  /* Name and title pair up; everything else keeps the full block width. */
  #interest-form > .field:nth-child(1) { grid-column: 1; }
  #interest-form > .field:nth-child(2) { grid-column: 2; }
}

.field { margin-bottom: var(--sp-5); border: 0; padding: 0; min-width: 0; }

fieldset.field { margin-left: 0; margin-right: 0; }

.field label, .field legend {
  display: block;
  font-weight: 600;
  font-size: var(--type-small);
  margin-bottom: var(--sp-2);
}

.req { color: var(--brand-bright); }
.opt { color: var(--muted); font-weight: 400; font-size: var(--type-meta); }

input[type="text"], input[type="email"], select, textarea {
  width: 100%;
  height: 48px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  font-size: var(--type-body);
  padding: 0 var(--sp-4);
}

textarea { height: auto; padding: var(--sp-3) var(--sp-4); resize: vertical; }

input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--brand-bright);
  outline-offset: 1px;
  border-color: transparent;
}

.field.invalid input, .field.invalid select,
.field.invalid .ms-control { border-color: var(--error); }

.field-error { color: var(--error); font-size: var(--type-small); margin: var(--sp-2) 0 0; }
.field-hint { color: var(--muted); font-size: var(--type-small); margin: var(--sp-2) 0 0; }

.checks { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5); padding-top: var(--sp-1); }

.checks label {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 400;
  font-size: var(--type-body);
  margin: 0;
  color: var(--text);
}

.checks input { accent-color: var(--brand); width: 18px; height: 18px; }

/* ---------- Searchable multi-select (States you operate in) ----------
   Built by main.js from the native <select multiple> in index.html, which
   stays the source of truth for both the option list and the selection.
   These rules only style the enhanced control; the native select is the
   no-JS fallback and keeps UA styling. */

.ms { position: relative; }

.ms-control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  min-height: 48px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-2) var(--sp-3);
  cursor: text;
}

/* Match the focus treatment the other inputs get, on the wrapper. */
.ms:focus-within .ms-control {
  outline: 2px solid var(--brand-bright);
  outline-offset: 1px;
  border-color: transparent;
}

/* Beat input[type="text"] (0,1,1) with (0,2,1) so the search box reads as
   bare text inside the control rather than as a second input. */
.ms-control input.ms-search {
  flex: 1 1 10ch;
  width: auto;
  min-width: 10ch;
  height: auto;
  min-height: 30px;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0 var(--sp-1);
}

.ms-control input.ms-search:focus { outline: none; border-color: transparent; }

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

.ms-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  background: var(--brand-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2px var(--sp-1) 2px var(--sp-2);
  font-size: var(--type-small);
  font-weight: 600;
  line-height: 1.5;
}

.ms-chip button {
  background: none;
  border: 0;
  color: var(--muted);
  font: inherit;
  font-size: var(--type-body);
  line-height: 1;
  padding: 0 var(--sp-1);
  cursor: pointer;
}

.ms-chip button:hover { color: var(--text); }

.ms-chip button:focus-visible {
  outline: 2px solid var(--brand-bright);
  outline-offset: 1px;
  border-radius: 2px;
}

.ms-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 30;
  margin: 0;
  padding: var(--sp-1);
  list-style: none;
  max-height: 260px;
  overflow-y: auto;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
}

.ms-opt {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 44px;
  padding: 0 var(--sp-3);
  border-radius: var(--radius);
  font-size: var(--type-body);
  cursor: pointer;
}

/* Fixed-width tick column so the labels stay on one left edge. */
.ms-opt::before {
  content: '';
  flex: 0 0 auto;
  width: 1ch;
  color: var(--brand-bright);
  font-weight: 600;
}

.ms-opt[aria-selected="true"]::before { content: '\2713'; }

.ms-opt.is-active { background: var(--brand-soft); }

.ms-code { margin-left: auto; color: var(--muted); font-size: var(--type-meta); }

.ms-empty {
  padding: var(--sp-3);
  color: var(--muted);
  font-size: var(--type-small);
}


.turnstile-field { min-height: 70px; }

#submit-btn {
  background: var(--brand);
  color: var(--text);
  border: 0;
  border-radius: var(--radius);
  font: inherit;
  font-size: var(--type-body);
  font-weight: 600;
  padding: 0.85rem 2.25rem;
  cursor: pointer;
  justify-self: start;
}

#submit-btn:hover:not(:disabled) { filter: brightness(1.15); }

#submit-btn:focus-visible { outline: 2px solid var(--brand-bright); outline-offset: 2px; }

#submit-btn:disabled {
  background: var(--border);
  color: var(--muted);
  cursor: not-allowed;
}

.submit-fallback {
  margin-top: var(--sp-5);
  border: 1px solid var(--error);
  border-radius: var(--radius);
  padding: var(--sp-4) var(--sp-5);
  background: var(--error-soft);
}

.submit-fallback p { margin: 0; font-size: var(--type-small); }

#success-panel h2 { color: var(--success); }
#success-panel p { color: var(--muted); max-width: 52ch; }

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

footer {
  border-top: 1px solid var(--border);
  padding: var(--sp-7) 0 var(--sp-8);
}

footer .wrap {
  display: grid;
  grid-template-columns: max-content minmax(0, 42ch);
  justify-content: space-between;
  align-items: start;
  gap: var(--sp-5);
}

@media (max-width: 719px) {
  footer .wrap { grid-template-columns: 1fr; }
}

.foot-contact { margin: 0; font-weight: 600; font-size: var(--type-body); }

.foot-privacy {
  margin: 0;
  color: var(--muted);
  font-size: var(--type-meta);
  line-height: 1.55;
}
