/* ==========================================================================
   Public org website ("front door") — Cub Scout "trail badge" design system.

   Brand basis: org_types/cub_scout_pack/brand_guidelines.md
     Foundation (used heavily): Cub Scouts Blue #003F87 + Gold #FDC116.
     Accents (sparing): SA Red #CE1126, Tan #D6CEBD, Gray #515354.
     Type: Montserrat (official free alternate for Proxima Nova).
   Design language: badge/patch "stitching" (dashed gold details), deep blue
   grounds, parchment-canvas content bands, trail-marker numbered steps.
   Mobile-first; the design must hold with zero photos.
   ========================================================================== */

/* Brand values flow from the ORG_TYPE theme (org_types/<type>/public_theme.css,
   the `--brand-*` contract) inlined into <head> ahead of this file. The literal
   fallbacks below keep this stylesheet self-sufficient: if an org type ships no
   theme, the page still renders in the Cub Scout palette. Structural rules below
   reference only these `--cs-*` aliases, so the brand seam is this block alone. */
:root {
  --cs-blue:      var(--brand-primary, #003F87);
  --cs-blue-dark: var(--brand-primary-dark, #002a5c);  /* SA Dark Blue #003366 family */
  --cs-blue-pale: var(--brand-primary-pale, #9AB3D5);
  --cs-gold:      var(--brand-accent, #FDC116);
  --cs-gold-deep: var(--brand-accent-deep, #e0a800);
  --cs-red:       var(--brand-danger, #CE1126);        /* sparing accent; never tinted */
  --cs-tan:       var(--brand-tan, #D6CEBD);
  --cs-tan-light: var(--brand-tan-light, #E9E9E4);
  --cs-gray:      var(--brand-muted, #515354);
  --cs-gray-dark: var(--brand-ink, #232528);
  --cs-canvas:    var(--brand-paper, #f8f6f0);          /* warm paper band */
  --cs-white:     var(--brand-surface, #ffffff);
  --cs-font-display: var(--brand-font-display, "Montserrat", "Helvetica Neue", Arial, sans-serif);
  --cs-font-body:    var(--brand-font-body, "Montserrat", "Helvetica Neue", Arial, sans-serif);
  /* Per-tenant accent: a tenant's own color layered WITHIN the Blue/Gold frame
     (brand_guidelines.md). Defaults to the org-type accent; overridden inline
     per tenant in the page <head>. Consumed by accent surfaces below. */
  --tenant-accent: var(--cs-gold);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --shadow-card: 0 2px 6px rgba(0, 42, 92, 0.10), 0 12px 32px rgba(0, 42, 92, 0.12);
  --stitch: 2px dashed var(--brand-stitch-color, rgba(253, 193, 22, 0.55));
}

* { box-sizing: border-box; }

/* [hidden] always wins — same rule components.css carries for the admin system.
   Any author display rule (even a bare class) outranks the UA stylesheet's
   [hidden] { display: none }, so `hidden` was a silent no-op on every styled
   element here: the header monogram is `display: grid`, so a tenant WITH a logo
   got the logo AND the gold initial circle beside it. !important so no component
   display can defeat the attribute; to show an element, remove the attribute. */
[hidden] { display: none !important; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body.cs-site {
  margin: 0;
  font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  color: var(--cs-gray-dark);
  background: var(--cs-canvas);
  -webkit-font-smoothing: antialiased;
}

.cs-site h1, .cs-site h2, .cs-site h3 {
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0 0 0.5em;
  color: var(--cs-blue);
  text-wrap: balance;
}

.cs-site p { margin: 0 0 1em; }
.cs-site a { color: var(--cs-blue); }
.cs-site img { max-width: 100%; display: block; }

.cs-container { width: min(1080px, 100% - 2.5rem); margin-inline: auto; }

/* --- The "stitch" motif: dashed gold rule, like patch embroidery --------- */
.cs-stitch {
  border: 0; border-top: var(--stitch);
  margin: 0 auto; width: 72px;
}

/* Sentence-case section label, above a heading or beside a card title.
   Mirrors components.css's .section-label (body font, small size, weight
   600, secondary text) in this file's own --cs-* tokens — the public site
   doesn't load components.css, so the rule is restated here. Replaces the
   retired uppercase small-caps tracker pattern (banned; see
   docs/design/admin-ui-patterns.md). */
.cs-section-label {
  display: inline-block;
  font-family: var(--cs-font-body);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--cs-blue);
  margin-bottom: 0.6rem;
}
.cs-on-blue .cs-section-label { color: var(--cs-gold); }

/* ==========================================================================
   Header / nav
   ========================================================================== */
.cs-header {
  background: var(--cs-blue);
  color: var(--cs-white);
  border-bottom: 4px solid var(--cs-gold);
  position: sticky; top: 0; z-index: 50;
}
/* Branding-only header for the embedded form: no nav, and not sticky (the embed
   is served standalone on the tenant's domain, where a sticky bar is unwanted). */
.cs-embed-header { position: static; }
.cs-header-inner {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.65rem 0;
}
.cs-site .cs-brand {
  display: flex; align-items: center; gap: 0.7rem;
  text-decoration: none; color: var(--cs-white);
  min-width: 0;
}
/* A logo's aspect ratio is unbounded — a wordmark banner can be 5:1 or wider —
   so cap the rendered WIDTH as well as the height. Without the cap a wide logo
   takes the whole header row and starves the org name sitting beside it.
   object-fit keeps a clamped logo scaled rather than stretched. */
.cs-brand img { height: 42px; width: auto; max-width: 220px; object-fit: contain; }
.cs-brand-mark {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  background: var(--cs-gold); color: var(--cs-blue);
  font-weight: 800; font-size: 1.05rem;
  border-radius: 50%;
  outline: var(--stitch); outline-offset: -5px;
}
.cs-brand-name {
  font-weight: 800; font-size: 1.02rem; line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cs-brand-sub {
  /* Wrap (don't inherit the name's nowrap/clip) so a long "Chartered by ..."
     line shows in full on narrow screens instead of getting cut off. */
  display: block; white-space: normal; font-weight: 500; font-size: 0.7rem;
  letter-spacing: 0.14em; text-transform: uppercase; line-height: 1.3;
  color: var(--cs-blue-pale);
}

/* flex-wrap: with up to 3 catalog links added beyond the core 3 + CTA, a
   single row can outgrow tablet-ish desktop widths — wrap onto a second row
   (header height grows a touch) rather than squeeze link labels into an
   illegible mid-word break. white-space: nowrap on the links themselves keeps
   each label intact when a row does get tight. */
.cs-nav {
  margin-left: auto; display: flex; flex-wrap: wrap;
  align-items: center; justify-content: flex-end;
  gap: 0.25rem 0.25rem;
}
.cs-site .cs-nav a {
  color: var(--cs-white); text-decoration: none; white-space: nowrap;
  font-weight: 600; font-size: 0.9rem;
  padding: 0.45rem 0.7rem; border-radius: 8px;
}
.cs-nav a:hover { background: rgba(255, 255, 255, 0.12); }
.cs-nav a[aria-current="page"] {
  color: var(--cs-gold);
  box-shadow: inset 0 -3px 0 var(--cs-gold);
  border-radius: 8px 8px 0 0;
}
.cs-nav .cs-btn { margin-left: 0.4rem; }
/* A button keeps its own ink wherever it sits. `.cs-site .cs-nav a` and
   `.cs-site .cs-footer a` paint every link white for the dark bars, and both
   outrank the single-context `.cs-site .cs-btn-gold` rule above, so the gold
   nav CTA rendered white-on-gold: 1.64:1, measured by the layout probe's
   contrast check (2026-08-05) and plainly washed out on screen. */
.cs-site .cs-nav .cs-btn-gold,
.cs-site .cs-footer .cs-btn-gold { color: var(--cs-blue); }
.cs-site .cs-nav .cs-btn-blue,
.cs-site .cs-footer .cs-btn-blue { color: var(--cs-white); }

/* Desktop "More" overflow for catalog pages beyond the first 3 — a details
   popover under the nav, same pattern as .cs-nav-toggle-menu below. */
.cs-nav-more { position: relative; }
.cs-nav-more > summary {
  list-style: none; cursor: pointer;
  color: var(--cs-white); font-weight: 600; font-size: 0.9rem;
  padding: 0.45rem 0.7rem; border-radius: 8px;
}
.cs-nav-more > summary::-webkit-details-marker { display: none; }
.cs-nav-more > summary:hover { background: rgba(255, 255, 255, 0.12); }
.cs-nav-more[open] > summary { background: rgba(255, 255, 255, 0.12); }
.cs-nav-more-menu {
  position: absolute; left: 0; top: calc(100% + 8px);
  min-width: 200px; padding: 0.5rem;
  background: var(--cs-blue-dark);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 12px; box-shadow: var(--shadow-card);
  display: grid; gap: 0.15rem;
  z-index: 60;
}
.cs-site .cs-nav-more-menu a {
  color: var(--cs-white); text-decoration: none; font-weight: 600;
  padding: 0.6rem 0.8rem; border-radius: 8px; font-size: 0.92rem;
}
.cs-nav-more-menu a:hover { background: rgba(255, 255, 255, 0.1); }
.cs-nav-more-menu a[aria-current="page"] { color: var(--cs-gold); }

/* Mobile nav: collapses to a details popover, no JS required */
.cs-nav-toggle { display: none; }
@media (max-width: 720px) {
  /* Brand drops to a second line on phones only when it has to. A wordmark-
     shaped logo (a 512x111 one renders ~194px wide) left the name a 30px column
     beside it: the org name clipped to "Pac…" and "Chartered by …" wrapped one
     word per line, for a 160px sticky header. Wrapping with a floor on the
     name's width moves it under the logo in exactly that case, while a narrow
     logo or the monogram circle keeps the name alongside it. */
  .cs-site .cs-brand { flex: 1 1 auto; flex-wrap: wrap; gap: 0.35rem 0.7rem; }
  .cs-brand img { max-width: 100%; }
  /* Wrap the org name rather than ellipsing it — a clipped "Pac…" is never the
     right way to run out of room for someone's group name. The basis is the
     narrowest the name may get before it takes a line of its own instead. */
  .cs-brand-name { flex: 1 1 8rem; white-space: normal; overflow: visible; }
  /* Charter org and location ride in the footer on phones: three uppercase,
     letter-spaced lines cost more of a sticky bar than they earn. The embedded
     form has no footer, so its header keeps them. */
  .cs-header:not(.cs-embed-header) .cs-brand-sub { display: none; }

  .cs-nav { display: none; }
  .cs-nav-toggle { display: block; margin-left: auto; position: relative; }
  .cs-nav-toggle > summary {
    list-style: none; cursor: pointer;
    color: var(--cs-white); font-weight: 700; font-size: 0.9rem;
    padding: 0.5rem 0.8rem; border: 1.5px solid rgba(255,255,255,0.45);
    border-radius: 8px;
  }
  .cs-nav-toggle > summary::-webkit-details-marker { display: none; }
  .cs-nav-toggle[open] > summary { background: rgba(255,255,255,0.12); }
  .cs-nav-toggle-menu {
    position: absolute; right: 0; top: calc(100% + 8px);
    min-width: 220px; padding: 0.5rem;
    background: var(--cs-blue-dark);
    border: 1px solid rgba(255,255,255,0.18);
    border-radius: 12px; box-shadow: var(--shadow-card);
    display: grid; gap: 0.15rem;
  }
  .cs-site .cs-nav-toggle-menu a {
    color: var(--cs-white); text-decoration: none; font-weight: 600;
    padding: 0.6rem 0.8rem; border-radius: 8px; font-size: 0.95rem;
  }
  .cs-nav-toggle-menu a:hover { background: rgba(255,255,255,0.1); }
  .cs-nav-toggle-menu a[aria-current="page"] { color: var(--cs-gold); }
}

/* ==========================================================================
   Buttons
   ========================================================================== */
.cs-btn {
  display: inline-block;
  font-family: inherit; font-weight: 800; font-size: 0.95rem;
  letter-spacing: 0.02em; text-decoration: none; text-align: center;
  /* Long labels (e.g. a registration CTA) must wrap inside a narrow mobile
     panel rather than overflow it -- max-width bounds the button to its
     container, white-space: normal lets it wrap to a second line. */
  white-space: normal; max-width: 100%;
  padding: 0.78rem 1.5rem;
  border-radius: 999px;
  border: 0; cursor: pointer;
  transition: transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out);
}
.cs-btn:hover { transform: translateY(-2px); }
.cs-btn:active { transform: translateY(0); }
/* Disabled / in-flight (the interest form swaps the label to "Sending…"). */
.cs-btn:disabled, .cs-btn[aria-disabled="true"] {
  opacity: 0.7; cursor: default; transform: none; box-shadow: none;
}
/* `.cs-site a` (below) outranks single-class button colors on <a> buttons,
   so button color rules carry the .cs-site prefix to win specificity. */
.cs-site .cs-btn-gold, .cs-btn-gold {
  background: var(--cs-gold); color: var(--cs-blue);
  outline: var(--stitch); outline-offset: -6px;
  box-shadow: 0 6px 18px rgba(253, 193, 22, 0.35);
}
.cs-btn-gold:hover { box-shadow: 0 10px 26px rgba(253, 193, 22, 0.45); }
.cs-site .cs-btn-ghost, .cs-btn-ghost {
  background: transparent; color: var(--cs-white);
  border: 2px solid rgba(255, 255, 255, 0.65);
}
.cs-site .cs-btn-ghost:hover { border-color: var(--cs-gold); color: var(--cs-gold); }
.cs-site .cs-btn-blue, .cs-btn-blue {
  background: var(--cs-blue); color: var(--cs-white);
  box-shadow: 0 6px 18px rgba(0, 63, 135, 0.3);
}

/* Keyboard focus: explicit ring everywhere; the gold button's decorative
   stitch uses `outline`, so focus there switches to a blue ring. */
.cs-site :focus-visible {
  outline: 3px solid var(--cs-gold);
  outline-offset: 2px;
}
.cs-site .cs-btn-gold:focus-visible,
.cs-site .cs-cta-panel a:focus-visible {
  outline: 3px solid var(--cs-blue);
  outline-offset: 2px;
}
/* The default gold ring above is invisible on a blue band (e.g. the hero's
   gold button, and the sticky header's own gold button), low-contrast
   gold-on-tan (any cs-band-tan section), and low-contrast gold-on-cream
   under a cs-btn-blue (the outline-offset gap keeps the ring visually
   separate from the button's own blue fill) -- override per band/button. */
.cs-site .cs-on-blue .cs-btn-gold:focus-visible { outline-color: var(--cs-white); }
.cs-site .cs-header .cs-btn-gold:focus-visible { outline-color: var(--cs-white); }
.cs-site .cs-band-tan :focus-visible { outline-color: var(--cs-blue); }
.cs-site .cs-btn-blue:focus-visible { outline-color: var(--cs-blue); }

/* Screen-reader-only text (calendar dates for the visual date chip). */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* ==========================================================================
   Hero (Home)
   ========================================================================== */
.cs-hero {
  position: relative;
  display: grid; align-items: center;
  /* Photo-forward hero: tall enough that the tenant's own photo reads as the
     opening statement, content-bound so a short tagline never floats in a
     void. (Front-door UX revamp Phase 4: bolder, photo carries the warmth.) */
  min-height: clamp(380px, 52vh, 580px);
  background: var(--cs-blue-dark);
  color: var(--cs-white);
  overflow: hidden;
}
.cs-hero-photo {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  /* Let the photo carry the warmth (authentic outdoor adventure). A whisper
     of desaturation keeps it on-brand without crushing it to a flat panel. */
  filter: saturate(0.96);
  opacity: 1;
}
.cs-hero::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  /* Graded diagonal scrim, lighter than the original flat wash: anchor the
     headline zone (left) and the CTA zone (bottom), let the photo actually
     show elsewhere. Text legibility over bright tenant photos is guaranteed
     by the text-shadow floor below, not by drowning the image. */
  background:
    linear-gradient(97deg,
      rgba(0, 42, 92, 0.84) 0%,
      rgba(0, 42, 92, 0.55) 46%,
      rgba(0, 42, 92, 0.18) 100%),
    linear-gradient(0deg,
      rgba(0, 30, 66, 0.62) 0%,
      rgba(0, 30, 66, 0) 40%);
}
.cs-hero-inner {
  position: relative; z-index: 2;
  padding: clamp(1.9rem, 5vw, 3rem) 0 clamp(2.1rem, 5vw, 3.25rem);
  max-width: 760px;
}
/* Hero layout: single column by default. When an upcoming join event is present
   the intro and the event card sit side by side (photo shows past the card on
   the right) so the event no longer eats its own full-width band below the fold. */
.cs-hero-grid { position: relative; z-index: 2; display: grid; align-items: center; }
/* With an event card, the hero band owns its top/bottom breathing room on the GRID
   (uniform padding-block) so both the intro and the card clear the header's gold
   line above and the section below — otherwise the card's gold top-border kisses
   the header line and its bottom edge the next section. The inner then drops its
   own vertical padding so it isn't doubled, and the grid gap spaces intro from
   card when they stack. */
.cs-hero--with-event .cs-hero-inner { padding-block: 0; }
.cs-hero--with-event .cs-hero-grid {
  padding-block: clamp(2.25rem, 5.5vw, 3.25rem);
  gap: clamp(1.5rem, 4vw, 2rem);
}
@media (min-width: 880px) {
  .cs-hero--with-event .cs-hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 25rem);
    gap: clamp(1.75rem, 4vw, 3rem);
    align-items: center;
  }
  /* let the intro breathe across its share of the row rather than cap at 760px */
  .cs-hero--with-event .cs-hero-inner { max-width: none; }
}
/* the card carries z-index/padding itself; the grid wrapper owns positioning */
.cs-hero-grid .cs-hero-inner { z-index: auto; }
.cs-hero-event { position: relative; }
/* Inside the hero the card fills its column (its own max-width/auto-centering is
   for the old standalone band); trim its top margin so it aligns in the row. */
.cs-hero-event .cs-event-cta { max-width: 34rem; margin-inline: auto; }
@media (min-width: 880px) {
  .cs-hero-event .cs-event-cta { max-width: none; margin-inline: 0; }
}
/* Tighten the hero's vertical rhythm: trim the label gap, the default h1
   margins, and the subtitle/CTA spacing so the band reads compact. */
.cs-hero .cs-section-label { margin-bottom: 0.35rem; }
.cs-hero h1 { margin: 0.1em 0 0.3em; }
.cs-hero-sub { margin: 0; }
.cs-hero-ctas { margin-top: 1.15rem; }
.cs-hero h1 {
  color: var(--cs-white);
  font-size: clamp(2.4rem, 7vw, 4.2rem);
  line-height: 1.04;
  text-transform: uppercase;
  letter-spacing: 0.005em;
  text-wrap: balance;
}
/* Legibility insurance: the scrim lightens to 0.18 on the photo side, and a
   tenant may upload a bright hero photo — a firm blue shadow keeps the white
   text AA regardless of what's behind it, without darkening the whole hero. */
.cs-hero h1, .cs-hero-sub, .cs-hero .cs-section-label {
  text-shadow: 0 1px 3px rgba(0, 30, 66, 0.65), 0 2px 20px rgba(0, 30, 66, 0.6);
}
.cs-hero h1 .cs-underline {
  /* gold stitch under the last words of the tagline */
  border-bottom: 4px solid var(--cs-gold);
  padding-bottom: 0.06em;
}
.cs-hero-sub {
  font-size: clamp(1.05rem, 2.5vw, 1.3rem);
  font-weight: 500;
  color: var(--cs-tan-light);
  max-width: 52ch;
}
/* Phone + an event card: the intro yields so the card's action survives the
   fold. A phone's real first screen is ~85% of the viewport once the browser's
   URL bar and nav bar take their cut (measured 2026-08-17 against a live
   tenant at 375x812: ~695px of page showed). Before this rule the title alone
   ran 120px of that budget in three lines, the card started at y=390, and its
   button landed at y=805 — a full screen of scrolling to reach the one thing
   the page asks for. Must sit AFTER `.cs-hero h1` above: same specificity, so
   source order decides. Phones only; a 768px tablet has the height to spare.
   The other half of the fix is the card's own button reorder further down. */
@media (max-width: 600px) {
  .cs-hero--with-event h1 { font-size: clamp(1.9rem, 6vw, 2.6rem); }
  /* The band's own breathing room, trimmed for the same budget. Unlike the
     type rule this saving is tenant-independent, which matters: a 5-line
     title or a 2-line venue can eat the type saving on its own, and a 667px
     phone (the SE class) only shows ~567px. Still clears the header's gold
     line, which is what the padding was tuned for. */
  .cs-hero--with-event .cs-hero-grid { padding-block: 1.5rem; gap: 1.15rem; }
}

/* Quiet, low-commitment secondary link (e.g. "Just have questions? Say
   hello…" under an intro paragraph): smaller than body text, underlined at
   rest per the public-page house rule, with enough vertical padding that the
   tap target clears the 44px phone ideal (padding does the work so the
   at-rest rhythm stays tight). */
.cs-quiet-link {
  font-size: 0.92rem;
  margin-top: 0.4rem;
}
.cs-quiet-link a {
  display: inline-block;
  padding-block: 0.7rem;
  text-decoration: underline;
}
/* On a blue band the default link color (`--cs-blue`) would render invisible
   against the blue background — same fix `.cs-on-blue .cs-section-label` already
   uses: swap to the same light tone `.cs-hero-sub` uses, which clears AA. */
.cs-on-blue .cs-quiet-link a { color: var(--cs-tan-light); }
.cs-hero-ctas { display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem; margin-top: 1.6rem; }
/* The hero's secondary CTA sits quieter — smaller, so the gold "Get in touch"
   primary leads decisively. Hierarchy comes from SIZE, not a washed-out color:
   the label stays white and the border stays legible so it clears WCAG against
   a bright hero photo (the scrim's contrast can't be guaranteed everywhere). */
.cs-hero-ctas .cs-btn-ghost {
  padding: 0.6rem 1.2rem; font-size: 0.88rem;
}

/* staggered load reveal (hero only; respect reduced motion) */
@media (prefers-reduced-motion: no-preference) {
  .cs-hero .cs-reveal {
    opacity: 0; transform: translateY(14px);
    animation: cs-rise 0.7s var(--ease-out) forwards;
  }
  .cs-hero .cs-reveal:nth-child(2) { animation-delay: 0.12s; }
  .cs-hero .cs-reveal:nth-child(3) { animation-delay: 0.24s; }
  .cs-hero .cs-reveal:nth-child(4) { animation-delay: 0.36s; }
}
@keyframes cs-rise { to { opacity: 1; transform: none; } }

/* ==========================================================================
   Content bands + badge cards
   ========================================================================== */
.cs-band { padding: clamp(2.8rem, 7vw, 4.5rem) 0; }
.cs-band-blue { background: var(--cs-blue); color: var(--cs-white); }
.cs-band-blue h1, .cs-band-blue h2, .cs-band-blue h3 { color: var(--cs-white); }
.cs-band-blue h1 { text-transform: uppercase; }
.cs-band-tan { background: var(--cs-tan-light); }

/* Band spacing modifiers (replace per-template inline padding). */
.cs-band--flush { padding: 0; }
.cs-band--tight-bottom { padding-bottom: 2rem; }

/* Layout utilities — centered band content + a centered reading measure, used
   by the home/join CTA strips and the form intro (was inline style="..."). */
.cs-center { text-align: center; }
/* `.cs-site p { margin: 0 0 1em }` (0,0,1,1) would otherwise zero the inline
   margins and pin a centered measure to the left — scope to .cs-site so the
   auto-centering wins. */
.cs-site .cs-measure { max-width: 52ch; margin-inline: auto; }
.cs-stack-top { margin-top: 1.2em; }
.cs-stack-card { margin-top: 1.5rem; }   /* gap above a full-width card under a split */
.cs-stack-sm { margin-top: 0.9rem; }     /* small top gap (e.g. a field after a checkbox) */

.cs-section-head { text-align: center; max-width: 640px; margin: 0 auto 2rem; }
.cs-section-head h1, .cs-section-head h2 { font-size: clamp(1.5rem, 4vw, 2.1rem); text-transform: uppercase; }

.cs-card {
  background: var(--cs-white);
  border-radius: 16px;
  box-shadow: var(--shadow-card);
  padding: 1.6rem 1.5rem;
  position: relative;
}
.cs-card::after {
  /* inner stitched border = patch */
  content: ""; position: absolute; inset: 7px;
  border: var(--stitch); border-radius: 11px;
  pointer-events: none; opacity: 0.45;
}
/* The last paragraph in a card carries no trailing gap (was inline
   style="margin-bottom:0" on the join cards). */
.cs-card > p:last-child { margin-bottom: 0; }

/* Inline link inside band/card body text -- the ONE tap-floor primitive:
   inline-block + padding-block lifts the hit area clear of the 24px floor
   without shrinking the body-text font size. New inline links use
   .cs-inline-link; the named variants below ride the same rule and add
   only their own deltas. */
.cs-inline-link, .cs-uniform-link, .cs-success-cal, .cs-reviews-link {
  display: inline-block; padding-block: 0.4rem;
}

.cs-split {
  display: grid; gap: 1.5rem; align-items: center;
}
@media (min-width: 880px) {
  .cs-split { grid-template-columns: 1fr 1fr; gap: 3rem; }
  /* Photo sits second by default; `.is-first` flips it ahead of the prose. */
  .cs-split > .cs-split-photo.is-first { order: -1; }
}
/* A pair of `.cs-card`s sharing a split (the join who/what-to-expect pair)
   reads as one balanced set only if they match height, regardless of which
   has more copy — stretch the row and let each card fill it. */
.cs-split--cards { align-items: stretch; }
.cs-split--cards .cs-card { height: 100%; }
.cs-split-photo img {
  width: 100%; height: 100%; max-height: 420px; object-fit: cover;
  border-radius: 18px; box-shadow: var(--shadow-card);
}
.cs-split-photo { position: relative; align-self: start; }
@media (min-width: 880px) {
  .cs-band-blue .cs-split-photo { position: sticky; top: 90px; }
}
.cs-split-photo::before {
  /* Offset frame behind the photo — the one decorative surface a tenant's own
     accent tints (defaults to gold, so no change unless a tenant sets one).
     Keeps the pack's color "within the Blue/Gold frame" per brand_guidelines. */
  content: ""; position: absolute; inset: 14px -10px -10px 14px;
  border: 3px solid var(--tenant-accent); border-radius: 18px; z-index: -1;
}

/* prose width for static/markdown blocks */
.cs-prose { max-width: 68ch; }
.cs-prose h2 { font-size: 1.25rem; margin-top: 1.6em; }
.cs-prose ul { padding-left: 1.2rem; }
/* Verbatim recitations (Scout Oath / Law) get a gold accent bar so they read
   as distinct quotations, not body copy — also breaks up the text wall. */
.cs-prose blockquote {
  margin: 0.5em 0 1.1em;
  padding: 0.15em 0 0.15em 1rem;
  border-left: 3px solid var(--cs-gold);
  font-weight: 500;
}
.cs-prose blockquote p { margin: 0; }

/* Progressive disclosure for long static explainers (the home program block):
   native <details>; the summary reads as a quiet text button with a chevron.
   Full content stays in the DOM (SEO / no-JS). */
.cs-more { margin-top: 1.1rem; }
.cs-more summary {
  display: inline-flex; align-items: center; gap: 0.5rem;
  cursor: pointer; list-style: none;
  min-height: 44px;                    /* tap-target floor */
  font-weight: 700; font-size: 0.95rem;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--cs-gold);
}
.cs-more summary::-webkit-details-marker { display: none; }
.cs-more summary::after {
  content: ""; width: 0.55em; height: 0.55em; flex: none;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-0.1em);
  transition: transform 0.2s var(--ease-out);
}
.cs-more[open] summary::after { transform: rotate(225deg) translateY(-0.1em); }
@media (prefers-reduced-motion: reduce) {
  .cs-more summary::after { transition: none; }
}
/* Underlined at rest: the summary sits near gold section labels and the
   chevron alone is too quiet a cue — it must read as a link without hover
   (touch has none). */
.cs-more summary { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
.cs-more summary:focus-visible { outline: 2px solid var(--cs-gold); outline-offset: 3px; border-radius: 2px; }
.cs-more[open] summary { margin-bottom: 0.4rem; }
/* On white/tan bands the gold summary would wash out; inherit the band's ink. */
.cs-band:not(.cs-band-blue) .cs-more summary { color: var(--cs-blue); }

/* ==========================================================================
   CTA panel (gold) — express interest
   ========================================================================== */
.cs-cta-panel {
  /* Warm radial highlight + gold-to-deep gradient gives the slab depth instead
     of one flat saturated fill; the blue top rule ties it to the event card. */
  background:
    radial-gradient(125% 145% at 50% -15%, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 55%),
    linear-gradient(168deg, var(--cs-gold) 0%, var(--cs-gold-deep) 100%);
  color: var(--cs-blue);
  border-radius: 20px;
  border-top: 5px solid var(--cs-blue);
  padding: clamp(2.1rem, 5vw, 3.1rem) clamp(1.5rem, 5vw, 3rem) clamp(1.9rem, 5vw, 2.9rem);
  text-align: center;
  position: relative;
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
/* Decorative trail-blaze diamond above the heading — echoes the Getting Started
   trail markers and gives the panel a composed top, not a bare headline. */
.cs-cta-panel::before {
  content: ""; display: block;
  width: 16px; height: 16px; margin: 0 auto 1rem;
  background: var(--cs-blue); transform: rotate(45deg);
  border-radius: 3px; box-shadow: 0 0 0 5px rgba(0, 63, 135, 0.14);
}
.cs-cta-panel::after {
  content: ""; position: absolute; inset: 9px;
  border: 2px dashed rgba(0, 63, 135, 0.4); border-radius: 14px;
  pointer-events: none;
}
.cs-cta-panel h2 { color: var(--cs-blue); text-transform: uppercase; margin-top: 0; }
.cs-cta-panel p { max-width: 46ch; margin-inline: auto; font-weight: 500; }
.cs-cta-panel .cs-btn { position: relative; z-index: 1; margin-top: 0.3rem; }

/* ==========================================================================
   Upcoming join-event CTA (auto; top of home) — the next Open House/kickoff,
   featured in-season or within JOIN_EVENT_CTA_WINDOW_DAYS. Built in
   agent/website/event_cta.py. A focused announcement card so it reads as
   "here's the next thing to come to", distinct from the gold express-interest
   panel lower down the page.
   ========================================================================== */
.cs-event-cta {
  background: var(--cs-blue);
  color: var(--cs-white);
  border-radius: 16px;
  border-top: 5px solid var(--cs-gold);
  /* The card sits blue-on-blue over the hero photo/scrim, so the blue-tinted
     card shadow alone barely separates it (worst when the hero photo is bright
     or the card stacks over the darkest scrim on mobile). A faint white hairline
     ring — drawn via box-shadow so it hugs the rounded corners and adds no
     layout — keeps the card reading as a distinct object on any background. */
  box-shadow: var(--shadow-card), 0 0 0 1px rgba(255, 255, 255, 0.16);
  padding: clamp(1.6rem, 3.4vw, 2.2rem) clamp(1.25rem, 3vw, 1.75rem);
  max-width: 580px;
  margin-inline: auto;
}
.cs-event-cta .cs-section-label { color: var(--cs-gold); margin-bottom: 0.4rem; }
.cs-event-cta h2 {
  color: var(--cs-white);
  text-transform: uppercase;
  font-size: clamp(1.18rem, 3vw, 1.5rem);
  margin: 0.1rem 0 0.7rem;
}
.cs-event-facts {
  margin: 0 0 0.75rem; padding: 0;
  display: grid; gap: 0.3rem;
}
.cs-event-facts > div { display: flex; gap: 0.75rem; align-items: baseline; }
.cs-event-facts dt {
  flex: none; min-width: 4.3rem;
  font: 700 0.72rem/1.5 var(--cs-font-display);
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--cs-gold);
}
.cs-event-facts dd { margin: 0; font-weight: 500; color: var(--cs-white); }
/* Keep the link INLINE (not inline-block): the row baseline-aligns the gold
   label to the value, and an inline-block's baseline is its LAST line — which
   would drop the "Where" label to the address's second line. Inline keeps the
   dd's baseline on its first line so the label sits beside the place name. */
.cs-event-facts dd a { color: inherit; text-decoration: underline; }
.cs-event-cta-note { max-width: 56ch; margin: 0 0 0.9rem; color: var(--cs-tan-light); }
/* Stacked (below 880px) the card is a full-width block on a phone, and reading
   order becomes scroll cost: teaser + note between the facts and the button
   pushed the action ~200px down, off the first screen. Flip it so the card
   reads what / when / where / act, with the teaser and the note underneath for
   whoever wants them. Visual order only — the DOM keeps its prose-then-action
   order, and neither moved block holds a focusable, so tab order is unchanged
   (the only focusable above the button, the Where directions link, keeps
   order 0 and stays put).

   The column flex also stretches the button to the card's width below 880 —
   deliberate on a phone, where a full-width target is the norm, and kept at
   601-879 so the card has one action shape rather than two.

   The two margin rules are not cosmetic: the note used to supply the gap above
   the button, and flex margins do not collapse, so without them the teaser's
   first line sits flush against the button's rounded edge (measured 0px at
   every stacked width) and the note's own bottom margin stacks onto the card
   padding, leaving the card bottom-heavy. */
@media (max-width: 879px) {
  .cs-event-cta { display: flex; flex-direction: column; }
  .cs-site .cs-event-cta-desc,
  .cs-event-cta-note { order: 1; }
  .cs-event-cta > .cs-btn { margin-bottom: 0.9rem; }  /* the note's old value */
  /* `.cs-site` scoped for the same reason the teaser below is: the bare
     `.cs-site p { margin: 0 0 1em }` reset (0,1,1) outranks a plain
     `.cs-event-cta-note` (0,1,0), so the unscoped version of this rule
     silently lost and left the card bottom-heavy. */
  .cs-site .cs-event-cta-note { margin-bottom: 0; }   /* now last; card pads it */
}
/* Public teaser (Task D3.4) — smaller and above the fixed prose note above;
   `.cs-site` scoped so it wins over the `.cs-site p { margin }` reset. */
.cs-site .cs-event-cta-desc { max-width: 56ch; margin: 0 0 0.5rem; font-size: 0.9rem; color: var(--cs-tan-light); }
/* Interactive elements sit on the blue card, so the default gold/blue focus ring
   would vanish into it — give everything on the card a white ring that reads on
   blue (covers the gold button and the Directions link alike). */
.cs-site .cs-event-cta :focus-visible {
  outline-color: var(--cs-white);
  outline-offset: 3px;
}

/* ==========================================================================
   Trail-marker steps (Getting Started)
   ========================================================================== */
/* Clears the sticky header (.cs-header) when scrolled to directly -- also
   covers the cost/uniform card jump-link targets in the tan cards band
   below (join-page conversion Task 2). */
#make-it-official, #cost, #uniform { scroll-margin-top: 5rem; }
.cs-steps { list-style: none; margin: 0 auto; padding: 0; max-width: 720px; }
.cs-step {
  display: grid; grid-template-columns: 52px 1fr; gap: 1.1rem;
  position: relative; padding-bottom: 1.9rem;
}
.cs-step:not(:last-child)::before {
  /* the trail: dashed connector between markers */
  content: ""; position: absolute; left: 25px; top: 56px; bottom: 4px;
  border-left: var(--stitch);
}
.cs-step-num {
  width: 52px; height: 52px; flex: none;
  display: grid; place-items: center;
  background: var(--cs-blue); color: var(--cs-gold);
  font-weight: 800; font-size: 1.25rem;
  border-radius: 50%;
  outline: var(--stitch); outline-offset: -6px;
}
.cs-step h3 { font-size: 1.08rem; margin-bottom: 0.25em; }
.cs-step p { margin-bottom: 0.4em; color: var(--cs-gray); }
.cs-step a { font-weight: 700; }
/* "We'll walk you through the rest…" reassurance under the steps list. */
.cs-steps-note { max-width: 60ch; margin: 0.5rem auto 0; text-align: center; color: var(--cs-gray); }

/* ==========================================================================
   Calendar
   ========================================================================== */
.cs-cal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.4rem;
}
.cs-cal-head h2 { margin: 0; text-transform: uppercase; }
/* The page title is an <h1> on the calendar page (page-level heading): the
   default view's warm fixed heading, or a look-back month label. */
.cs-cal-title { margin: 0; font-size: clamp(1.5rem, 4vw, 2.1rem); text-transform: uppercase; }
/* Month group heading over each list (default view has one per month).
   Scoped under .cs-site (0-2-0): the sitewide `.cs-site h2` heading reset
   (0-1-1) outranks a bare `.cs-cal-month` (0-1-0), which silently zeroed
   every earlier margin-only attempt at this break. Each month after the
   first opens with a stitch rule so the groups read as separate blocks. */
.cs-site .cs-cal-month {
  text-transform: uppercase; font-size: 1.35rem; letter-spacing: 0.08em;
  color: var(--cs-blue); margin: 1.8rem 0 0.7rem;
  padding-top: 1.4rem; border-top: var(--stitch);
}
.cs-site .cs-cal-month:first-of-type {
  margin-top: 0.4rem; padding-top: 0; border-top: 0;
}
.cs-cal-nav { display: flex; gap: 0.5rem; }
.cs-cal-nav a, .cs-cal-nav span {
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--cs-white); color: var(--cs-blue);
  border: 2px solid var(--cs-blue);
  font-weight: 800; text-decoration: none; font-size: 1.1rem;
}
.cs-cal-nav span { opacity: 0.25; border-color: var(--cs-gray); color: var(--cs-gray); }

/* Look-back affordances: "Back to upcoming" above a finished month, and the
   quiet "See what we've been up to" entry at the foot of the upcoming list. */
.cs-cal-back { margin: 0 0 1.2rem; }
.cs-cal-foot { margin-top: 1.6rem; }
.cs-cal-lookback { margin: 0 0 0.6rem; }
/* Both look-back links carry a 44px tap height (they are lone text links, not
   buttons, so the hit area needs padding to clear the phone floor). */
.cs-cal-back a, .cs-cal-lookback a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-weight: 700;
}

/* upcoming list */
.cs-event-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.8rem; }
/* A folded month keeps a little air between the summary and its first heading. */
.cs-cal-fold[open] .cs-cal-month:first-of-type { margin-top: 0.9rem; }
.cs-event-item {
  display: grid; grid-template-columns: 64px 1fr; gap: 1rem;
  background: var(--cs-white); border-radius: 14px;
  padding: 0.9rem 1rem; box-shadow: 0 1px 4px rgba(0, 42, 92, 0.10);
  align-items: center;
}
.cs-event-date {
  text-align: center; background: var(--cs-blue); color: var(--cs-white);
  border-radius: 10px; padding: 0.45rem 0.2rem; line-height: 1.1;
}
.cs-event-weekday {
  display: block; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; opacity: 0.85;
}
.cs-event-date b { display: block; font-size: 1.3rem; color: var(--cs-gold); }
.cs-event-date small {
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase;
}
.cs-event-item h3 { font-size: 1rem; margin: 0 0 0.15em; }
.cs-event-meta { font-size: 0.85rem; color: var(--cs-gray); margin: 0; }
.cs-event-dens { margin: 0.3em 0 0; display: flex; flex-wrap: wrap; gap: 0.3rem; }
.cs-den-tag {
  font-size: 0.65rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--cs-blue);
  background: rgba(0, 63, 135, 0.10); border-radius: 999px;
  padding: 0.12rem 0.55rem; white-space: nowrap;
}

/* Held dates the org has not confirmed: a dashed edge instead of the solid
   card shadow, plus an italic "(tentative)" after the name — the same tag the
   calendar PDF and the admin calendar use, so one word means one thing
   everywhere. Quiet, not alarming: the event is still worth reading, it just
   is not locked in. The footnote under the list says so in words. */
.cs-event-item.is-tentative {
  border: 1px dashed var(--cs-tan); box-shadow: none;
}
.cs-event-tentative {
  font-style: italic; font-weight: 400; font-size: 0.8rem;
  color: var(--cs-gray); white-space: nowrap;
}
.cs-cal-note { margin: 0 0 0.6rem; font-size: 0.85rem; color: var(--cs-gray); }

/* Completed events stay in the list (the org reads as alive) but as texture,
   not the message: a muted paper card, a gray date chip with a small check.
   Ink stays on AA-passing pairings (gray #515354 on white/tan-light; white on
   the gray chip) — the treatment is quiet, never a dropout. */
.cs-event-item.is-past { background: var(--cs-tan-light); box-shadow: none; }
.cs-event-item.is-past .cs-event-date { background: var(--cs-gray); }
.cs-event-item.is-past .cs-event-date b { color: var(--cs-white); }
.cs-event-item.is-past h3 { color: var(--cs-gray); }
.cs-event-check {
  display: block; margin-top: 0.1rem;
  font-size: 0.72rem; line-height: 1; color: var(--cs-gold);
}

.cs-empty {
  text-align: center; padding: 2.5rem 1rem; color: var(--cs-gray);
  background: var(--cs-white); border-radius: 14px;
}
.cs-empty p { margin: 0; }

/* Documents page: a quiet shelf. One row per file, link + why-you-need-it.
   --cs-tan is the existing divider token (see .cs-success-next above). */
.cs-site .cs-doc-intro { max-width: 62ch; }
.cs-site .cs-doc-list { list-style: none; margin: 24px 0 0; padding: 0; }
.cs-site .cs-doc-item { padding: 14px 0; border-top: 1px solid var(--cs-tan); }
.cs-site .cs-doc-item:last-child { border-bottom: 1px solid var(--cs-tan); }
/* inline-block + padding lifts the link's hit area past the 24px WCAG floor */
.cs-site .cs-doc-link { font-weight: 600; text-decoration: underline; display: inline-block; padding: 4px 0; }
.cs-site .cs-doc-meta { font-weight: 400; font-size: .82em; color: var(--cs-gray); white-space: nowrap; margin-left: 6px; text-decoration: none; }
.cs-site .cs-doc-desc { margin: 4px 0 0; max-width: 62ch; font-size: .95em; }

/* ==========================================================================
   Footer
   ========================================================================== */
.cs-footer {
  background: var(--cs-blue-dark);
  color: var(--cs-blue-pale);
  margin-top: clamp(2.5rem, 7vw, 4rem);
  border-top: 4px solid var(--cs-gold);
  font-size: 0.88rem;
}
.cs-site .cs-footer a { color: var(--cs-white); }
.cs-footer-grid {
  display: grid; gap: 1.6rem;
  padding: 2.2rem 0 1.4rem;
}
@media (min-width: 720px) {
  .cs-footer-grid { grid-template-columns: 1.4fr 1fr 1fr; }
}
.cs-footer h4 {
  color: var(--cs-gold); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; margin: 0 0 0.6rem;
}
.cs-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.15rem; }
/* Lift footer text links to a >=24px touch target (WCAG 2.2 target size) while
   keeping the column rhythm — the reduced gap above absorbs the added padding.
   The `p a` half covers the two mailto links in the contact column, which sit
   in paragraphs rather than the link lists and so kept an 18px target (probe
   fail, every public page, found 2026-08-17). `break-word` so a long tenant
   address still wraps inside the column now that it is inline-block.
   `.cs-reviews-link` is excluded: it is inline-flex with a gap so its ↗ glyph
   sits off the label, and forcing inline-block here made that gap inert
   (measured: the icon butted against the text). It already stands 37px tall,
   so it never needed the lift. */
.cs-footer li a,
.cs-footer p a:not(.cs-reviews-link) { display: inline-block; padding-block: 0.3rem; overflow-wrap: break-word; }
/* Phones: the footer links measured 33-36px tall; pad them to the 44px
   one-handed ideal where a thumb is what taps them. */
@media (max-width: 720px) {
  .cs-footer li a,
  .cs-footer p a:not(.cs-reviews-link) { padding-block: 0.6rem; }
}
.cs-footer-legal {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding: 1.1rem 0 1.6rem;
  display: flex; flex-wrap: wrap; gap: 0.9rem 1.6rem;
  align-items: center; justify-content: space-between;
  font-size: 0.78rem;
}
.cs-attribution { max-width: 52ch; opacity: 0.8; }
/* Platform attribution wordmark is a link to membercairn.com. Fade the whole
   unit slightly and brighten on hover/focus so it reads as clickable (the inner
   logo/text carry their own inline colors, so we animate the link, not them). */
.cs-powered-link {
  display: inline-flex;
  text-decoration: none;
  border-radius: 6px;
  opacity: 0.85;
  transition: opacity 0.15s ease;
}
.cs-powered-link:hover,
.cs-powered-link:focus-visible { opacity: 1; }
.cs-powered-link:focus-visible { outline: 2px solid var(--cs-gold); outline-offset: 3px; }

/* "Follow us" social row — icon pills in the identity column. Hidden entirely
   when no links are set (the template guards on website.social). */
.cs-footer-social { margin-top: 1.2rem; }
.cs-footer-social ul {
  display: flex; flex-wrap: wrap; gap: 0.6rem; /* overrides .cs-footer ul grid */
}
.cs-footer-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  transition: background 0.15s ease, color 0.15s ease;
}
.cs-footer-social a:hover,
.cs-footer-social a:focus-visible { background: var(--cs-gold); color: var(--cs-blue-dark); }
.cs-footer-social a:focus-visible { outline: 2px solid var(--cs-white); outline-offset: 2px; }
.cs-social-icon { width: 20px; height: 20px; display: block; }

/* Google reviews trust link — a quiet inline text link (home "Find us" band +
   footer) with a small external-link glyph. Inherits its band's link color
   (blue on white, white in the footer), so it reads as a soft secondary link,
   never a button. */
.cs-reviews-link {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.9rem; font-weight: 600; text-decoration: none;
}
.cs-reviews-link:hover, .cs-reviews-link:focus-visible { text-decoration: underline; }
.cs-ext-ico { width: 0.85em; height: 0.85em; flex: none; opacity: 0.8; }

/* Preview ribbon shown to admins on a not-yet-public page. */
.cs-preview-bar {
  background: var(--cs-red); color: #fff; text-align: center;
  padding: 0.55rem 1rem; font-weight: 700; font-size: 0.9rem;
}

/* legal pages */
.cs-legal-wrap { max-width: 72ch; margin-inline: auto; padding: 2.5rem 0; }
.cs-legal-wrap h1 { font-size: clamp(1.7rem, 5vw, 2.3rem); text-transform: uppercase; }

/* ==========================================================================
   Public forms (interest list / RSVP) — parchment cards on the trail band
   ========================================================================== */
.cs-form { max-width: 620px; margin-inline: auto; }
.cs-form .cs-section-head { margin-bottom: 1.4rem; }
.cs-form-intro { color: var(--cs-gray); margin: 0 auto 1.6rem; max-width: 60ch; text-align: center; }
/* "Fields marked * are required" — a quiet centered note tucked under the intro. */
.cs-form-required { text-align: center; margin-top: -0.8rem; }

/* Each logical group (parent / children / questions) is a parchment card. */
.cs-form-card {
  background: var(--cs-white);
  border-radius: 16px;
  box-shadow: var(--shadow-card);
  padding: 1.5rem 1.4rem;
  margin-bottom: 1.3rem;
}
.cs-form-card > h3 {
  font-size: 1.1rem; text-transform: uppercase; letter-spacing: 0.01em;
  margin: 0 0 0.9rem;
}
/* Reserve the Turnstile widget's rendered footprint so the async iframe paint
   doesn't reflow the form (jarring on a slow mobile connection). The managed
   widget renders ~300x65px; min-height holds the slot until it loads. */
.cf-turnstile { min-height: 65px; }
/* Turnstile's own wrapper: no card chrome (background/border/shadow) — an
   invisible/managed widget in an empty white card reads as a broken blank
   card before it paints. Reserve its footprint and match the form-card
   vertical rhythm without the card look. */
.cs-turnstile { min-height: 65px; margin-bottom: 1.3rem; }
/* Success headline: a warm sentence-case h1, not the uppercase section style. */
.cs-form-success-title { font-size: clamp(1.4rem, 4vw, 1.9rem); margin: 0.4rem 0 0.6rem; }

/* Thank-you momentum block: the next public event + a calendar link, set off
   from the confirmation by a quiet divider so it reads as "here's what's next"
   without competing with the primary "Back to site" action. */
.cs-success-next {
  margin-top: 1.4rem; padding-top: 1.3rem;
  border-top: 1px solid var(--cs-tan);
}
.cs-success-event { margin: 0.35rem 0 0.7rem; line-height: 1.5; }
.cs-success-cal-only { margin-top: 1.2rem; }
.cs-success-cal { font-weight: 600; }

/* "(optional)" marker — quiet, lowercase, never competes with the field label. */
.cs-optional { font-weight: 400; font-size: 0.85em; color: var(--cs-gray); }

/* Field label + control. Labels are blocks; checkboxes use .cs-check instead. */
.cs-field {
  display: block; margin: 0 0 0.9rem;
  font-weight: 700; font-size: 0.92rem; color: var(--cs-gray-dark);
}
.cs-field:last-child { margin-bottom: 0; }

.cs-form input[type="text"],
.cs-form input[type="email"],
.cs-form input[type="tel"],
.cs-form select,
.cs-form textarea {
  width: 100%; margin-top: 0.4rem;
  font-family: inherit; font-size: 1rem; font-weight: 400;
  color: var(--cs-gray-dark);
  background: var(--cs-white);
  padding: 0.68rem 0.8rem;
  border: 1.5px solid var(--cs-tan);
  border-radius: 10px;
  transition: border-color 0.15s var(--ease-out), box-shadow 0.15s var(--ease-out);
}
.cs-form textarea { resize: vertical; min-height: 5.5rem; }
.cs-form input:focus, .cs-form select:focus, .cs-form textarea:focus {
  outline: none;
  border-color: var(--cs-blue);
  box-shadow: 0 0 0 3px rgba(0, 63, 135, 0.15);
}
.cs-form input::placeholder, .cs-form textarea::placeholder { color: var(--cs-gray); opacity: 0.7; }

.cs-help { color: var(--cs-gray); font-size: 0.85rem; margin-top: 0.45rem; line-height: 1.45; }

/* Checkbox rows: box left, wrapping label right, comfortable tap target. */
.cs-check {
  display: flex; gap: 0.6rem; align-items: flex-start;
  margin-top: 0.9rem; padding: 0.25rem 0; font-weight: 500; font-size: 0.95rem; cursor: pointer;
}
.cs-check input[type="checkbox"] {
  flex: none; width: 1.5rem; height: 1.5rem; margin-top: 3px;
  accent-color: var(--cs-blue);
}

/* Child name + grade on one row, stacking on the narrowest phones. */
.cs-child-row { display: flex; gap: 0.6rem; margin-bottom: 0.6rem; }
.cs-child-row input[type="text"] { flex: 1 1 auto; margin-top: 0; }
.cs-child-row select { flex: 0 0 7rem; margin-top: 0; }
@media (max-width: 380px) {
  .cs-child-row { flex-wrap: wrap; }
  .cs-child-row select { flex-basis: 100%; }
}

/* "Add another child" — a quiet ghost button, not a primary action. */
.cs-add-row {
  margin-top: 0.4rem;
  font-family: inherit; font-weight: 700; font-size: 0.85rem;
  color: var(--cs-blue); background: transparent;
  border: 1.5px dashed var(--cs-blue-pale); border-radius: 999px;
  padding: 0.5rem 1.1rem; cursor: pointer;
  transition: border-color 0.15s var(--ease-out), background 0.15s var(--ease-out);
}
.cs-add-row:hover { border-color: var(--cs-blue); background: rgba(0, 63, 135, 0.05); }

.cs-form-errors {
  background: #fbe9e7; border: 1.5px solid var(--cs-red);
  color: #8a0c1a; border-radius: 12px;
  padding: 0.9rem 1.1rem; margin-bottom: 1.3rem;
}
.cs-form-errors strong { display: block; margin-bottom: 0.3rem; }
.cs-form-errors ul { margin: 0; padding-left: 1.2rem; }

/* The SMS/compliance fine print sits below the form: deliberately quiet so it
   never competes with the submit action. Muted (AA-passing on the tan band),
   small, tight leading. Content/placement unchanged — this is de-emphasis only. */
.cs-legal-note { color: var(--cs-gray); font-size: 0.78rem; line-height: 1.45; margin: 1.2rem 0; }

/* "What happens next" reassurance, just above the submit button: a quiet,
   centered muted line that sets an honest reply-time expectation. */
.cs-form-next {
  color: var(--cs-gray); font-size: 0.9rem; line-height: 1.5;
  text-align: center; margin: 0 auto 0.9rem; max-width: 52ch;
}

.cs-form-submit { width: 100%; margin-top: 0.4rem; }
@media (min-width: 520px) { .cs-form-submit { width: auto; min-width: 14rem; } }

/* Honeypot: off-screen, never shown to humans. */
.cs-honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ==========================================================================
   Catalog pages (front-door expansion): FAQ / leaders / gallery
   ========================================================================== */

/* FAQ list — each Q/A is a stitched card, like the join-step cards. */
.cs-faq-list { max-width: 720px; margin: 0 auto; padding: 0; display: grid; gap: 1rem; }
.cs-faq-item { margin: 0; }
.cs-faq-item dt { font-size: 1.05rem; font-weight: 800; color: var(--cs-blue); margin-bottom: 0.35em; }
.cs-faq-item dd { margin: 0; color: var(--cs-gray-dark); }

/* Leader roster — reuses .cs-card in a responsive grid. auto-fit (not
   auto-fill) collapses empty tracks, and justify-content: center keeps a
   short roster (1-2 leaders) reading as a centered cluster instead of
   left-hugging with a dead void beside it. */
.cs-card-grid {
  display: grid; gap: 1.3rem; align-items: start; justify-content: center;
  grid-template-columns: repeat(auto-fit, minmax(240px, 280px));
}
.cs-leader-card { text-align: center; }
.cs-leader-photo {
  width: 108px; height: 108px; margin: 0 auto 0.9rem;
  border-radius: 50%; object-fit: cover;
  outline: var(--stitch); outline-offset: -6px;
}
/* First-initial fallback when a leader has no photo — same footprint as
   .cs-leader-photo so a photo-less card holds the grid row's height, styled
   off the header's .cs-brand-mark gold circle. */
.cs-leader-mono {
  width: 108px; height: 108px; margin: 0 auto 0.9rem;
  display: grid; place-items: center;
  background: var(--cs-gold); color: var(--cs-blue);
  font-weight: 800; font-size: 2.6rem; line-height: 1;
  border-radius: 50%;
  outline: var(--stitch); outline-offset: -6px;
}
.cs-leader-card h3 { font-size: 1.1rem; margin-bottom: 0.2em; }
.cs-card-sub { color: var(--cs-gray); font-weight: 600; font-size: 0.88rem; margin-bottom: 0.6em; }
.cs-card-contact { margin: 0.6em 0 0; font-size: 0.9rem; }
.cs-card-contact a { display: inline-block; padding: 0.15rem 0; }

/* Open volunteer roles — a quiet list under the "we could use a hand" band. */
.cs-open-roles {
  list-style: none; margin: 0 auto 1.6rem; padding: 0;
  max-width: 480px; display: grid; gap: 0.5rem;
  text-align: left;
}
.cs-open-roles li {
  background: var(--cs-white); border-radius: 10px;
  padding: 0.7rem 1rem; font-weight: 600;
  box-shadow: var(--shadow-card);
}

/* Photo gallery — masonry-ish responsive grid, captions read as patch labels. */
.cs-album-title { text-transform: uppercase; font-size: 1.1rem; margin: 2rem 0 1rem; }
.cs-album-title:first-child { margin-top: 0; }
.cs-gallery-grid {
  display: grid; gap: 0.9rem; justify-content: center;
  grid-template-columns: repeat(auto-fit, minmax(220px, 260px));
  margin-bottom: 1.6rem;
}
.cs-gallery-item { margin: 0; }
.cs-gallery-item img {
  /* height: auto overrides the width/height HTML attributes (a presentational
     hint the browser otherwise honors verbatim), letting aspect-ratio compute
     a uniform box regardless of the photo's real (often portrait) shape. */
  width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 12px; box-shadow: var(--shadow-card);
}
.cs-gallery-item figcaption {
  margin-top: 0.4rem; font-size: 0.85rem; color: var(--cs-gray);
}

/* An inline text link inside public prose: a 19px line box misses the 24px
   tap floor, so give it a padded box without changing the line rhythm. */
.cs-site .cs-inline-link { display: inline-block; padding: 4px 0; margin: -4px 0; }
